Re: [tcpdump-workers] libpcap: problem reading IP address

2002-04-25 Thread Nathan Jennings

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

2002-04-25 Thread Guy Harris

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

2002-04-23 Thread Guy Harris

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