Re: [tcpdump-workers] libpcap: problem reading IP address
Thanks for helping me find out what's going on... although it's embarassing... :o( On Tuesday 23 April 2002 01:03 pm, Guy Harris wrote: Sounds as if something's off by 2 bytes. The Ethernet header size is 14 bytes; does int size_ethernet = sizeof(struct sniff_ethernet); Yes, however... The pcap file I was reading at home wasn't the same as what I was reading at work. At home I have a DSL connection and I had taken some traffic captures on my laptop which appended a PPPoE/PPP header. I ended up doing the following to read the IP addresses correctly: (the named constants are from netinet/if_ether.h) .. ethernet = (struct sniff_ethernet*)(packet); /* check ether type */ printf(\tEther encap: ); etherEncap = ntohs(ethernet-ether_type); switch(etherEncap) { case ETH_P_PPP_SES: printf(PPPoE (%#x)\n, etherEncap); /* following your recommendation */ /* well, maybe you'd recommend I do: ETH_HLEN+PPPOE_LEN */ etherLen = ETH_HLEN+8; .. I get the above ether/PPPoE header when I sniff eth0. When I sniff ppp0, Ethereal displays Linux cooked capture just below the frame statistics. This leads me to wanting to figure out how to detect and read those frames correctly. (I'll check tcpdump/Ethereal for hints... :o) ) On another note: I would suggest, instead, that you do *NOT* rely on data structures having the size, or layout that you'd expect them to have - assume that compilers may pad them to put fields on natural boundaries or to make the structure size a multiple of a natural alignment. Is this why tcpdump does the following? I was looking through the tcpdump-3.7.1 source, in print-ip.c (line 262-287) , there's the following section: .. #ifdef LBL_ALIGN /* * If the IP header is not aligned, copy into abuf. * This will never happen with BPF. It does happen raw packet * dumps from -r. */ if ((long)ip 3) { static u_char *abuf = NULL; static int didwarn = 0; if (abuf == NULL) { abuf = (u_char *)malloc(snaplen); if (abuf == NULL) error(ip_print: malloc); } memcpy((char *)abuf, (char *)ip, min(length, snaplen)); snapend += abuf - (u_char *)ip; packetp = abuf; ip = (struct ip *)abuf; /* We really want libpcap to give us aligned packets */ if (!didwarn) { warning(compensating for unaligned libpcap packets); ++didwarn; } } #endif .. It caught my attention and I was wondering why it was there. Thanks again for all of your help, -Nathan - This is the TCPDUMP workers list. It is archived at http://www.tcpdump.org/lists/workers/index.html To unsubscribe use mailto:[EMAIL PROTECTED]?body=unsubscribe
Re: [tcpdump-workers] libpcap: problem reading IP address
On Thu, Apr 25, 2002 at 02:55:29PM -0400, Nathan Jennings wrote: ethernet = (struct sniff_ethernet*)(packet); /* check ether type */ Yes, if you're going to be looking past the Ethernet header, you have to look at the Ethernet type. Take a look at print-ether.c in the tcpdump source to see the way tcpdump handles the Ethernet header. I get the above ether/PPPoE header when I sniff eth0. When I sniff ppp0, Ethereal displays Linux cooked capture just below the frame statistics. Yes, on Linux, libpcap punts on trying to figure out what the hell the link-layer headers look like (on some PPP devices, there's no PPP header, there's just an IP header; on others, there's a PPP header, which may or may not include the HDLC 0xff 0x03 header; on others, there may be various random amounts of random junk in front of the PPP header), so it just captures in cooked mode, which means the link-layer header isn't supplied. Instead, libpcap synthesizes a link-layer header from stuff provided by the socket code. This leads me to wanting to figure out how to detect and read those frames correctly. (I'll check tcpdump/Ethereal for hints... :o) ) See sll.h and print-sll.c in the tcpdump source for information on that synthesized header. I would suggest, instead, that you do *NOT* rely on data structures having the size, or layout that you'd expect them to have - assume that compilers may pad them to put fields on natural boundaries or to make the structure size a multiple of a natural alignment. Is this why tcpdump does the following? Yes. That's *also* why, as noted, it uses ETHER_HDRLEN, as defined in ether.h, rather than sizeof (struct ether_header) - the latter won't give 14 on at least some versions of GCC for ARM, for example, as those versions of GCC apparently pad some, if not all, structures to a multiple of 4 bytes. - This is the TCPDUMP workers list. It is archived at http://www.tcpdump.org/lists/workers/index.html To unsubscribe use mailto:[EMAIL PROTECTED]?body=unsubscribe
Re: [tcpdump-workers] libpcap: problem reading IP address
On Tue, Apr 23, 2002 at 12:45:05PM -0400, Nathan Jennings wrote: 1) I'm having a problem reading the correct source and dest. IP addresses. Below is an example: If the IP addresses are: Src: 1.2.3.4 Dst: 5.6.7.8 My code prints: Src: 3.4.5.6 Dst: 7.8.20.21 Sounds as if something's off by 2 bytes. The Ethernet header size is 14 bytes; the code in I used the example code from sniffer.c as a starting point: http://www.tcpdump.org/pcap.htm does int size_ethernet = sizeof(struct sniff_ethernet); Perhaps the compiler has, for some reason, decided to pad struct sniff_ethernet to 14 bytes. I would suggest doing int size_ethernet = 14; or, even better, doing #define SIZE_ETHERNET 14 and using SIZE_ETHERNET instead of size_ethernet. 2) Why does the sniff_ip struct above have the two #endif's together like below?: Because the sample code is buggy. You might want to send Tim Carstens e-mail about that. 3) When writing libpcap programs, are there any flags I should pass to gcc for structure alignment/packing purposes? I want to write them in a portable way. If you want to write the code in a portable way, you cannot rely on flags passed to gcc! Portable doesn't mean portable to every platform using GCC, it means portable. I would suggest, instead, that you do *NOT* rely on data structures having the size, or layout that you'd expect them to have - assume that compilers may pad them to put fields on natural boundaries or to make the structure size a multiple of a natural alignment. See, for example, the tcpdump source. ether.h defines ETHER_HDRLEN as 14, and print-ether.c uses ETHER_HDRLEN, rather than sizeof (struct ether_header), as the size of an Ethernet header. Similarly, the structures in print-isoclns.c tend to use u_char XXX[4], rather than some integral data type, for 4-byte quantities, as the packet layouts might not align fields on natural boundaries. - This is the TCPDUMP workers list. It is archived at http://www.tcpdump.org/lists/workers/index.html To unsubscribe use mailto:[EMAIL PROTECTED]?body=unsubscribe