viernes, 1 de noviembre de 2013

Talking to a router in RIP version 1 using a C program in linux part 1

This time I have a small router with the following config down below. What we will do is to have a linux machine talking RIPv1 to a router. It is a Cisco 2500 in 12.1.

Router#sh ru                                                                  
Building configuration...                                                    
                                                                             
Current configuration:                                                        
!                                                                            
version 12.1                                                                  
service timestamps debug uptime                                              
service timestamps log uptime                                                
no service password-encryption                                                
!                                                                            
hostname Router                                                              
!                                                                            
enable password yourpassword                                                        
!                                                                            
!                                                                            
!                                                                            
!                                                                            
!                                                                            
ip subnet-zero                                                                
!                                                                            
!                                                                            
!                                                                            
interface Loopback0                                                          
 ip address 10.10.10.10 255.255.255.0                                        
 no ip split-horizon                                                          
!                                                                            
interface Ethernet0                                                          
 ip address 192.168.2.2 255.255.255.0                                        
!                                                                            
interface Ethernet1                                                          
 no ip address                                                                
 shutdown                                                                    
!                                                                            
interface Serial0                                                            
 no ip address                                                                
 shutdown                                                                    
!                                                                            
interface Serial1                                                            
 no ip address                                                                
 shutdown                                                                    
!                                                                            
router rip                                                                    
 version 1                                                                    
 network 10.0.0.0                                                            
 network 192.168.1.0                                                          
 network 192.168.2.0                                                          
!                                                                            
ip classless                                                                  
no ip http server                                                            
!                                                                            
!                                                                            
!                                                                            
line con 0                                                                    
 transport input none                                                        
line aux 0                                                                    
line vty 0 4                                                                  
 password yourpassword                                                              
 login                                                                        
!                                                                            
end

The router is having RIP and a 192.168.2.0 net in that process.

The linux machine is configure this way:

linux-edfh:/home/ghgv/Escritorio/programs # ifconfig
eth0      Link encap:Ethernet  HWaddr 90:2B:34:9B:28:F8
          inet addr:192.168.1.101  Bcast:192.168.1.255  Mask:255.255.255.0
          inet6 addr: fe80::922b:34ff:fe9b:28f8/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:103049 errors:0 dropped:75 overruns:0 frame:0
          TX packets:77727 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:119197344 (113.6 Mb)  TX bytes:10324905 (9.8 Mb)
          Interrupt:42

eth1      Link encap:Ethernet  HWaddr 00:A0:FF:FF:58:33
          inet addr:192.168.2.1  Bcast:192.168.2.255  Mask:255.255.255.0
          inet6 addr: fe80::2a0:ffff:feff:5833/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:57 errors:0 dropped:13 overruns:0 frame:0
          TX packets:185 errors:1518 dropped:0 overruns:0 carrier:3036
          collisions:25806 txqueuelen:1000
          RX bytes:7446 (7.2 Kb)  TX bytes:559247 (546.1 Kb)
          Interrupt:20 Base address:0xbf00

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:27 errors:0 dropped:0 overruns:0 frame:0
          TX packets:27 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:3711 (3.6 Kb)  TX bytes:3711 (3.6 Kb)

The router is connecting to the eth1 as they are in the same network.

Make sure you can ping to each other.

ghgv@linux-edfh:~/Escritorio/programs> ping 192.168.2.1
PING 192.168.2.1 (192.168.2.1) 56(84) bytes of data.
64 bytes from 192.168.2.1: icmp_seq=1 ttl=64 time=0.045 ms
64 bytes from 192.168.2.1: icmp_seq=2 ttl=64 time=0.035 ms
^C
--- 192.168.2.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.035/0.040/0.045/0.005 ms
ghgv@linux-edfh:~/Escritorio/programs> ping 192.168.2.2
PING 192.168.2.2 (192.168.2.2) 56(84) bytes of data.
64 bytes from 192.168.2.2: icmp_seq=1 ttl=255 time=4.82 ms
64 bytes from 192.168.2.2: icmp_seq=2 ttl=255 time=2.31 ms
64 bytes from 192.168.2.2: icmp_seq=3 ttl=255 time=2.35 ms
^Z
[1]+  Detenido                ping 192.168.2.2

Now, what we need is a program able to send packets in UDP mode (RIP runs on top of UDP) and send a packet. 

I found this program that sends a UDP packet over the network. The only important thing is to calculate the pseudo-header of UDP to be able to run it properly. Otherwise, I think the packet does not pass through the linux kernel to be seen by WireShark.

/*
   Copyright 2010 Gabriel Serme

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
*/
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

#define LEN 512

typedef unsigned short u16;
typedef unsigned long u32;

//2nd
unsigned short csum (unsigned short *buf, int nwords);
uint16_t udp_checksum(const struct iphdr  *ip,
        const struct udphdr *udp,
        const uint16_t *buf);



int main(int argc, char * argv[])
{

#  if __BYTE_ORDER == __LITTLE_ENDIAN //reverse per 8 bits
    printf("little endian\n");
#else
    printf("big endian\n");
#endif

    if(argc != 5)
    {
        printf("- Usage %s <IP source> <port source> <IP dest> <port dest>\n", argv[0]);
        exit(1);
    }else{
        printf ("Args : \n"
                "\tip source : %s:%s\n"
                "\tip dest : %s:%s\n", 
                argv[1], argv[2], argv[3], argv[4]);
    }
    int PSOURCE = atoi (argv[2]);
    int PDEST = atoi(argv[4]);
    char *SOURCE = argv[1];
    char *DEST = argv[3];
    char * ANSWER = argv[5];
    int s;
    struct sockaddr_in daddr, saddr, answerip;
    char packet[LEN];
    /* point the iphdr to the beginning of the packet */
    struct iphdr *ip = (struct iphdr *)packet;  
    struct udphdr *udp = (struct udphdr *)((void *) ip + sizeof(struct iphdr));
    struct dnshdr *dns = (struct dnshdr *)((void *) udp + sizeof(struct udphdr));

    if ((s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) {
        perror("error:");
        exit(EXIT_FAILURE);
    }

    daddr.sin_family = AF_INET;
    saddr.sin_family = AF_INET;
    daddr.sin_port = htons(PDEST); 
    saddr.sin_port = htons(PSOURCE); 
    saddr.sin_addr.s_addr=inet_addr("192.168.2.1");
daddr.sin_addr.s_addr=inet_addr("192.168.2.2");
    //inet_pton(AF_INET, SOURCE, (struct in_addr *)&saddr.sin_addr);
//inet_pton(AF_INET, DEST,   (struct in_addr *)&daddr.sin_addr);
    
memset(daddr.sin_zero, 0, sizeof(daddr.sin_zero));
    memset(saddr.sin_zero, 0, sizeof(saddr.sin_zero));
    memset(udp, 0, sizeof(struct udphdr));
    memset(ip, 0, sizeof(struct iphdr));

    ip->ihl = 5; //header length
    ip->version = 4;
    ip->tos = 0x0;
    ip->id = 0;
    ip->frag_off = htons(0x4000); /* DF */
    ip->ttl = 64; /* default value */
    ip->protocol = 17; //IPPROTO_RAW; /* protocol at L4 */
    ip->check = 0; /* not needed in iphdr */
    ip->saddr = saddr.sin_addr.s_addr;
    ip->daddr = daddr.sin_addr.s_addr;

    udp->source = htons(PSOURCE);
    udp->dest = htons (PDEST);

    int sizedata = 100;
    memset(((void *) udp) + sizeof(struct udphdr), 'S', sizedata);

    int sizeudpdata = sizeof(struct udphdr) + sizedata;
    ip->tot_len = htons(sizeudpdata + sizeof(struct iphdr)); /* 16 byte value */
    udp->len = htons(sizeudpdata);

    udp->check = udp_checksum(ip,udp,udp);
    printf ("Checksum : 0x%x\n", udp->check);
    printf ("Sizes :  \n\t[+] iphdr %d"
  "\n\t[+] udphdr %d\n",
            sizeof(struct iphdr), sizeof(struct udphdr));
    printf ("Total size : %d\n", sizeudpdata);

    int optval = 1;

    if (setsockopt(s, IPPROTO_IP, IP_HDRINCL, &optval, sizeof(int))
            < 0)
        perror ("IP HDRINCL");

    while(1) {
        int sizepacket = sizeof(struct iphdr) + sizeudpdata;
        if (sendto(s, (char *)packet, sizepacket, 0, (struct sockaddr *)&daddr, (socklen_t)sizeof(daddr)) < 0)
            perror("packet send error:");
        else
            printf("Sent packet\n");
        sleep(5);
    }
    exit(EXIT_SUCCESS);
}

//http://www.linuxquestions.org/questions/linux-networking-3/udp-checksum-algorithm-845618/
//modified by Gabriel Serme
struct pseudo_hdr {
    u_int32_t source;
    u_int32_t dest;s
    u_int8_t zero; //reserved, check http://www.rhyshaden.com/udp.htm
    u_int8_t protocol;
    u_int16_t udp_length;
};

uint16_t udp_checksum(const struct iphdr  *ip,
        const struct udphdr *udp,
        const uint16_t *buf)
{
    //take in account padding if necessary
    int calculated_length = ntohs(udp->len)%2 == 0 ? ntohs(udp->len) : ntohs(udp->len) + 1;

    struct pseudo_hdr ps_hdr = {0};
    bzero (&ps_hdr, sizeof(struct pseudo_hdr));
    uint8_t data[sizeof(struct pseudo_hdr) + calculated_length];
    bzero (data, sizeof(struct pseudo_hdr) + calculated_length );

    ps_hdr.source = ip->saddr;
    ps_hdr.dest = ip->daddr;
    ps_hdr.protocol = IPPROTO_UDP; //17
    ps_hdr.udp_length = udp->len;

    memcpy(data, &ps_hdr, sizeof(struct pseudo_hdr));
    memcpy(data + sizeof(struct pseudo_hdr), buf, ntohs(udp->len) ); //the remaining bytes are set to 0

    return csum((uint16_t *)data, sizeof(data)/2);/*
   Copyright 2010 Gabriel Serme

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
*/
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

#define LEN 512

typedef unsigned short u16;
typedef unsigned long u32;

//2nd
unsigned short csum (unsigned short *buf, int nwords);
uint16_t udp_checksum(const struct iphdr  *ip,
        const struct udphdr *udp,
        const uint16_t *buf);



int main(int argc, char * argv[])
{

#  if __BYTE_ORDER == __LITTLE_ENDIAN //reverse per 8 bits
    printf("little endian\n");
#else
    printf("big endian\n");
#endif

    if(argc != 5)
    {
        printf("- Usage %s <IP source> <port source> <IP dest> <port dest>\n", argv[0]);
        exit(1);
    }else{
        printf ("Args : \n"
                "\tip source : %s:%s\n"
                "\tip dest : %s:%s\n", 
                argv[1], argv[2], argv[3], argv[4]);
    }
    int PSOURCE = atoi (argv[2]);
    int PDEST = atoi(argv[4]);
    char *SOURCE = argv[1];
    char *DEST = argv[3];
    char * ANSWER = argv[5];
    int s;
    struct sockaddr_in daddr, saddr, answerip;
    char packet[LEN];
    /* point the iphdr to the beginning of the packet */
    struct iphdr *ip = (struct iphdr *)packet;  
    struct udphdr *udp = (struct udphdr *)((void *) ip + sizeof(struct iphdr));
    struct dnshdr *dns = (struct dnshdr *)((void *) udp + sizeof(struct udphdr));

    if ((s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) {
        perror("error:");
        exit(EXIT_FAILURE);
    }

    daddr.sin_family = AF_INET;
    saddr.sin_family = AF_INET;
    daddr.sin_port = htons(PDEST); 
    saddr.sin_port = htons(PSOURCE); 
    saddr.sin_addr.s_addr=inet_addr("192.168.2.1");
daddr.sin_addr.s_addr=inet_addr("192.168.2.2");
    //inet_pton(AF_INET, SOURCE, (struct in_addr *)&saddr.sin_addr);
//inet_pton(AF_INET, DEST,   (struct in_addr *)&daddr.sin_addr);
    
memset(daddr.sin_zero, 0, sizeof(daddr.sin_zero));
    memset(saddr.sin_zero, 0, sizeof(saddr.sin_zero));
    memset(udp, 0, sizeof(struct udphdr));
    memset(ip, 0, sizeof(struct iphdr));

    ip->ihl = 5; //header length
    ip->version = 4;
    ip->tos = 0x0;
    ip->id = 0;
    ip->frag_off = htons(0x4000); /* DF */
    ip->ttl = 64; /* default value */
    ip->protocol = 17; //IPPROTO_RAW; /* protocol at L4 */
    ip->check = 0; /* not needed in iphdr */
    ip->saddr = saddr.sin_addr.s_addr;
    ip->daddr = daddr.sin_addr.s_addr;

    udp->source = htons(PSOURCE);
    udp->dest = htons (PDEST);

    int sizedata = 100;
    memset(((void *) udp) + sizeof(struct udphdr), 'S', sizedata);

    int sizeudpdata = sizeof(struct udphdr) + sizedata;
    ip->tot_len = htons(sizeudpdata + sizeof(struct iphdr)); /* 16 byte value */
    udp->len = htons(sizeudpdata);

    udp->check = udp_checksum(ip,udp,udp);
    printf ("Checksum : 0x%x\n", udp->check);
    printf ("Sizes :  \n\t[+] iphdr %d"
  "\n\t[+] udphdr %d\n",
            sizeof(struct iphdr), sizeof(struct udphdr));
    printf ("Total size : %d\n", sizeudpdata);

    int optval = 1;

    if (setsockopt(s, IPPROTO_IP, IP_HDRINCL, &optval, sizeof(int))
            < 0)
        perror ("IP HDRINCL");

    while(1) {
        int sizepacket = sizeof(struct iphdr) + sizeudpdata;
        if (sendto(s, (char *)packet, sizepacket, 0, (struct sockaddr *)&daddr, (socklen_t)sizeof(daddr)) < 0)
            perror("packet send error:");
        else
            printf("Sent packet\n");
        sleep(5);
    }
    exit(EXIT_SUCCESS);
}

//http://www.linuxquestions.org/questions/linux-networking-3/udp-checksum-algorithm-845618/
//modified by Gabriel Serme
struct pseudo_hdr {
    u_int32_t source;
    u_int32_t dest;
    u_int8_t zero; //reserved, check http://www.rhyshaden.com/udp.htm
    u_int8_t protocol;
    u_int16_t udp_length;
};

uint16_t udp_checksum(const struct iphdr  *ip,
        const struct udphdr *udp,
        const uint16_t *buf)
{
    //take in account padding if necessary
    int calculated_length = ntohs(udp->len)%2 == 0 ? ntohs(udp->len) : ntohs(udp->len) + 1;

    struct pseudo_hdr ps_hdr = {0};
    bzero (&ps_hdr, sizeof(struct pseudo_hdr));
    uint8_t data[sizeof(struct pseudo_hdr) + calculated_length];
    bzero (data, sizeof(struct pseudo_hdr) + calculated_length );

    ps_hdr.source = ip->saddr;
    ps_hdr.dest = ip->daddr;
    ps_hdr.protocol = IPPROTO_UDP; //17
    ps_hdr.udp_length = udp->len;

    memcpy(data, &ps_hdr, sizeof(struct pseudo_hdr));
    memcpy(data + sizeof(struct pseudo_hdr), buf, ntohs(udp->len) ); //the remaining bytes are set to 0

    return csum((uint16_t *)data, sizeof(data)/2);
}

/* Not my code */
unsigned short csum (unsigned short *buf, int nwords)
{/*
   Copyright 2010 Gabriel Serme

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
*/
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

#define LEN 512

typedef unsigned short u16;
typedef unsigned long u32;

//2nd
unsigned short csum (unsigned short *buf, int nwords);
uint16_t udp_checksum(const struct iphdr  *ip,
        const struct udphdr *udp,
        const uint16_t *buf);



int main(int argc, char * argv[])
{

#  if __BYTE_ORDER == __LITTLE_ENDIAN //reverse per 8 bits
    printf("little endian\n");
#else
    printf("big endian\n");
#endif

    if(argc != 5)
    {
        printf("- Usage %s <IP source> <port source> <IP dest> <port dest>\n", argv[0]);
        exit(1);
    }else{
        printf ("Args : \n"
                "\tip source : %s:%s\n"
                "\tip dest : %s:%s\n", 
                argv[1], argv[2], argv[3], argv[4]);
    }
    int PSOURCE = atoi (argv[2]);
    int PDEST = atoi(argv[4]);
    char *SOURCE = argv[1];
    char *DEST = argv[3];
    char * ANSWER = argv[5];
    int s;
    struct sockaddr_in daddr, saddr, answerip;
    char packet[LEN];
    /* point the iphdr to the beginning of the packet */
    struct iphdr *ip = (struct iphdr *)packet;  
    struct udphdr *udp = (struct udphdr *)((void *) ip + sizeof(struct iphdr));
    struct dnshdr *dns = (struct dnshdr *)((void *) udp + sizeof(struct udphdr));

    if ((s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) {
        perror("error:");
        exit(EXIT_FAILURE);
    }

    daddr.sin_family = AF_INET;
    saddr.sin_family = AF_INET;
    daddr.sin_port = htons(PDEST); 
    saddr.sin_port = htons(PSOURCE); 
    saddr.sin_addr.s_addr=inet_addr("192.168.2.1");
daddr.sin_addr.s_addr=inet_addr("192.168.2.2");
    //inet_pton(AF_INET, SOURCE, (struct in_addr *)&saddr.sin_addr);
//inet_pton(AF_INET, DEST,   (struct in_addr *)&daddr.sin_addr);
    
memset(daddr.sin_zero, 0, sizeof(daddr.sin_zero));
    memset(saddr.sin_zero, 0, sizeof(saddr.sin_zero));
    memset(udp, 0, sizeof(struct udphdr));
    memset(ip, 0, sizeof(struct iphdr));

    ip->ihl = 5; //header length
    ip->version = 4;
    ip->tos = 0x0;
    ip->id = 0;
    ip->frag_off = htons(0x4000); /* DF */
    ip->ttl = 64; /* default value */
    ip->protocol = 17; //IPPROTO_RAW; /* protocol at L4 */
    ip->check = 0; /* not needed in iphdr */
    ip->saddr = saddr.sin_addr.s_addr;
    ip->daddr = daddr.sin_addr.s_addr;

    udp->source = htons(PSOURCE);
    udp->dest = htons (PDEST);

    int sizedata = 100;
    memset(((void *) udp) + sizeof(struct udphdr), 'S', sizedata);

    int sizeudpdata = sizeof(struct udphdr) + sizedata;
    ip->tot_len = htons(sizeudpdata + sizeof(struct iphdr)); /* 16 byte value */
    udp->len = htons(sizeudpdata);

    udp->check = udp_checksum(ip,udp,udp);
    printf ("Checksum : 0x%x\n", udp->check);
    printf ("Sizes :  \n\t[+] iphdr %d"
  "\n\t[+] udphdr %d\n",
            sizeof(struct iphdr), sizeof(struct udphdr));
    printf ("Total size : %d\n", sizeudpdata);

    int optval = 1;

    if (setsockopt(s, IPPROTO_IP, IP_HDRINCL, &optval, sizeof(int))
            < 0)
        perror ("IP HDRINCL");

    while(1) {
        int sizepacket = sizeof(struct iphdr) + sizeudpdata;
        if (sendto(s, (char *)packet, sizepacket, 0, (struct sockaddr *)&daddr, (socklen_t)sizeof(daddr)) < 0)
            perror("packet send error:");
        else
            printf("Sent packet\n");
        sleep(5);
    }
    exit(EXIT_SUCCESS);
}

//http://www.linuxquestions.org/questions/linux-networking-3/udp-checksum-algorithm-845618/
//modified by Gabriel Serme
struct pseudo_hdr {
    u_int32_t source;
    u_int32_t dest;
    u_int8_t zero; //reserved, check http://www.rhyshaden.com/udp.htm
    u_int8_t protocol;
    u_int16_t udp_length;
};

uint16_t udp_checksum(const struct iphdr  *ip,
        const struct udphdr *udp,
        const uint16_t *buf)
{
    //take in account padding if necessary
    int calculated_length = ntohs(udp->len)%2 == 0 ? ntohs(udp->len) : ntohs(udp->len) + 1;

    struct pseudo_hdr ps_hdr = {0};
    bzero (&ps_hdr, sizeof(struct pseudo_hdr));
    uint8_t data[sizeof(struct pseudo_hdr) + calculated_length];
    bzero (data, sizeof(struct pseudo_hdr) + calculated_length );

    ps_hdr.source = ip->saddr;
    ps_hdr.dest = ip->daddr;
    ps_hdr.protocol = IPPROTO_UDP; //17
    ps_hdr.udp_length = udp->len;

    memcpy(data, &ps_hdr, sizeof(struct pseudo_hdr));
    memcpy(data + sizeof(struct pseudo_hdr), buf, ntohs(udp->len) ); //the remaining bytes are set to 0

    return csum((uint16_t *)data, sizeof(data)/2);
}

/* Not my code */
unsigned short csum (unsigned short *buf, int nwords)
{
    unsigned long sum;

    for (sum = 0; nwords > 0; nwords--)
        sum += *buf++;

    sum = (sum >> 16) + (sum & 0xffff);
    sum += (sum >> 16);
    return ~sum;
}

    unsigned long sum;

    for (sum = 0; nwords > 0; nwords--)
        sum += *buf++;

    sum = (sum >> 16) + (sum & 0xffff);
    sum += (sum >> 16);
    return ~sum;
}

}

/* Not my code */
unsigned short csum (unsigned short *buf, int nwords)
{
    unsigned long sum;

    for (sum = 0; nwords > 0; nwords--)
        sum += *buf++;

    sum = (sum >> 16) + (sum & 0xffff);
    sum += (sum >> 16);
    return ~sum;
}

I am writing the IP source and destination addresses directly. I do not know why the 

//inet_pton(AF_INET, SOURCE, (struct in_addr *)&saddr.sin_addr);

sets the wrong destination address. Anyway, I get:


You can see that the archive is made up os "S"s. So, it is not useful at this point but we will improve it. So that we can send a RIP packet.


No hay comentarios:

Publicar un comentario