tcpdump mailing list archives

Data from packet dissector looks really weird


From: "Claudio Lavecchia" <Claudio.Lavecchia () eurecom fr>
Date: Tue, 29 Jun 2004 11:58:16 +0200

Hello everybody,
 
I am writing a packet dissector using libpcap and I have a nasty bug that is
giving me hard times. I would be glad if someone could explain me what is
going on.
 
I use libpcap 0.7.2 and run my packet dissector on two different
environments (redhat 7.3 and Familiar Linux) but the results I observe are
exactly the same.
 
The structures I use to capture my packets are as follows:
 
#define ETHERNET_HDR_SIZE       14

/* Ethernet header */  
struct sniff_ethernet {
        u_char  ether_dhost[ETHER_ADDR_LEN];    // Destination host address 
        u_char  ether_shost[ETHER_ADDR_LEN];    // Source host address 
        u_short ether_type;                                     // IP? ARP?
RARP? etc 
}
 
struct sniff_ip
{ 
 u_int8_t ip_vhl;  /* header length, version */
#define IP_V(ip) (((ip)->ip_vhl & 0xf0) >> 4)
#define IP_HL(ip) ((ip)->ip_vhl & 0x0f)
 u_int8_t ip_tos;  /* type of service */
 u_int16_t ip_len;  /* total length */
 u_int16_t ip_id;  /* identification */
 u_int16_t ip_off;  /* fragment offset field */
#define IP_DF 0x4000   /* dont fragment flag */
#define IP_MF 0x2000   /* more fragments flag */
#define IP_OFFMASK 0x1fff  /* mask for fragmenting bits */
 u_int8_t ip_ttl;  /* time to live */
 u_int8_t ip_p;  /* protocol */
 u_int16_t ip_sum;  /* checksum */
 struct in_addr ip_src,ip_dst; /* source and dest address */
};
 
typedef u_int32_t tcp_seq; 
/* TCP header */
struct sniff_tcp {
        u_short th_sport;                       /* source port */
        u_short th_dport;                       /* destination port */
        tcp_seq th_seq;                         /* sequence number */
        tcp_seq th_ack;                         /* acknowledgement number */
 
        #if BYTE_ORDER == LITTLE_ENDIAN
                u_int   th_x2:4,                /* (unused) */
                        th_off:4;               /* data offset */
        #endif
        #if BYTE_ORDER == BIG_ENDIAN
                u_int   th_off:4,               /* data offset */
                        th_x2:4;                /* (unused) */
        #endif
        u_char  th_flags;
        #define TH_FIN  0x01
        #define TH_SYN  0x02
        #define TH_RST  0x04
        #define TH_PUSH 0x08
        #define TH_ACK  0x10
        #define TH_URG  0x20
        #define TH_ECE  0x40
        #define TH_CWR  0x80
        #define TH_FLAGS
(TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG|TH_ECE|TH_CWR)
        u_short th_win;                         /* window */
        u_short th_sum;                         /* checksum */
        u_short th_urp;                         /* urgent pointer */
};
 
In my packet dissector code I do open a sniffing session in the standard way
(pcap_lookupnet, pcap_next etc.): 
 
Then I have a processing function that takes the sniffed packet as a
parameter and does what follows:
 
int process_packet(u_char *packet)
{
...
  /* Define pointers for packet's attributes */
 const struct sniff_ethernet *ethernet;  /* The ethernet header */ 
 
 const struct sniff_ip *ip;                /* The IP header */
 const struct sniff_tcp *tcp;            /* The TCP header */
 const char *payload;                    /* Packet payload */
 
 int size_ethernet = ETHERNET_HDR_SIZE;
 int size_ip = sizeof(struct sniff_ip);
 int size_tcp = sizeof(struct sniff_tcp);
 
 char *src_ip_address;             /* The source IP address*/
 char *dst_ip_address;             /* The destination IP address*/
 char *src_mac_address;         /* The source MAC address */
 char *dst_mac_address;         /* The destination MAC address */
 
 /* The ethernet type  */
 u_short ethernet_type;

 /* This pointer points to the beginning of the ethernet packet */
 ethernet = (struct sniff_ethernet*)(packet);
 
 printf("Packet %s\n",packet); //claudio debug
 printf("ethernet header size =  %d\n",size_ethernet); 
 printf("ip header size =  %d\n",size_ip); 
 printf("tcp header size =  %d\n",size_tcp); 
 
 /* Interesting portion of the ethernet header */
 ethernet_type = ntohs(ethernet->ether_type);
 
 printf("Ethernet type %d\n",ethernet_type);
 
/* LOOK AT THIS CAREFULLY!!!*/ 
 src_mac_address = ether_ntoa(ethernet->ether_shost);
 dst_mac_address = ether_ntoa(ethernet->ether_dhost);
 
 /* Check if the sniffed packet is an IP packet */
 if (ethernet_type == IP)
 {
   ip = (struct sniff_ip*)(packet + size_ethernet);
   tcp = (struct sniff_tcp*)(packet + size_ethernet + size_ip);
   // The payload represents the application data 
   payload = (u_char *)(packet + size_ethernet + size_ip + size_tcp);
 
    /* LOOK AT THIS CAREFULLY!!!*/ 
   /* Print ethernet header information */
   printf("\tETH H:src add:: %s\n", src_mac_address);
   printf("\tETH H:dst add:: %s\n", dst_mac_address);
   printf("\tETH H.:type  :: %d\n", ethernet_type);
   /* Print IP header information*/
   printf("\tIP H:src add :: %s:%d\n", inet_ntoa(ip->ip_src),
ntohs(tcp->th_sport));
   printf("\tIP H:dst add :: %s:%d\n", inet_ntoa(ip->ip_dst),
ntohs(tcp->th_dport));
 
   printf("VERY STRANGE!!!\n\tSRC IP --%s--\n\tDST IP
--%s--\n",inet_ntoa(ip->ip_src),inet_ntoa(ip->ip_dst),local_ip_address);
   printf("VERY STRANGE!!!\n\tSRC MAC --%s--\n\tDST MAC
--%s--\n",ether_ntoa(ethernet->ether_shost),ether_ntoa(ethernet->ether_dhost
),local_mac_address);
  }
 ....
 }
 
Now I use a packet generator based on libnet libraries to check what I did,
I generate  a packet that has a source IP address equal to 1.1.1.1 and a
destination IP address equal to 2.2.2.2, the source and destination MAC are
generated by the packet generator, according to Ethereal capture, they are:
DST MAC=32:32:3a:32:32:3a SRC MAC=31:31:3a:31:31:3a, now the output of my
packet dissector is:
 
 ethernet header size =  14
 ip header size =  20
 tcp header size =  20
 Ethernet type 2048
 ETH H:src add:: 32:32:3a:32:32:3a
 ETH H:dst add:: 32:32:3a:32:32:3a
 ETH H.:type  :: 2048
 IP H:src add :: 1.1.1.1:4369
 IP H:dst add :: 2.2.2.2:8738
 Payload: 
VERY STRANGE!!!
 SRC IP --1.1.1.1--
 DST IP --1.1.1.1--
VERY STRANGE!!!
 SRC MAC --31:31:3a:31:31:3a--
 DST MAC --31:31:3a:31:31:3a--
 
Analysys: in the first printf, source MAC is not correct, it seems to be
overwritten by dst MAC. In the first printf IPs are correct. In the second
printf, it seems that DST MAC is not correct and it seems to be overwritten
by src MAC. In the second printf SRC IP seems to overwrite dst IP, too. 
 
Please, does anyone have a clue? I am going crazy :(
 
Claudio

Current thread: