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:
- Data from packet dissector looks really weird Claudio Lavecchia (Jun 29)
- <Possible follow-ups>
- Re: Data from packet dissector looks really weird alex medvedev (Jun 29)