tcpdump mailing list archives

Re: Output goes weird!


From: Guy Harris <guy () alum mit edu>
Date: Wed, 10 Sep 2003 19:15:53 -0700


On Sep 10, 2003, at 4:17 PM, Justin Robinson wrote:

I'm Capturing packets from an NNTP connection which is a text-based
protocol.
I'm expecting to see readable characters. When I run my C program on
FreeBSD, I get textual (readable) output for the first 50 lines or so....
and then all the characters go wierd!
What gets shown on screen doesn't even look like any kind of characters at all. It's just a mess. Even after I exit the program, the characters at the
shell prompt are still not readable and I have to close the terminal.

The exact same C program works fine in Linux for the exact same connection,
and all payloads are readable.

Can anyone suggest why my program is messing up the output, and why it
happens on FreeBSD and not Linux?

The output is written to the screen in the callback function for pcap_loop.
And here's the snippet that does it:

   /* The following loop writes each character in the payload to
      stdout */
   for (j = payloadOffset; (j < payloadOffset + payloadLength); j++) {
      putc(*payload, stdout);
      payload++;
   }

How are you computing payloadOffset and payloadLength?

And to what does "payload" point?

The packet data that libpcap supplies is raw packet data; you need to know the link-layer header type in those packets in order to get past the link-layer header. You get the link-layer header type from "pcap_datalink()".

Do NOT wire in an assumption about the link-layer header type; if you don't want to handle the full panoply of link-layer header types, then just check whether the value returned by "pcap_datalink()" is one you're willing to handle, and print an error and quit if it's not.

Also, do not assume that a given type of network will have the same link-layer type on all OSes. PPP devices, for example, get different types on different OSes - in particular, on the BSDs, a PPP device will be DLT_PPP (or perhaps DLT_PPP_BSDOS, on BSD/OS, or DLT_PPP_SERIAL on NetBSD), but, on Linux, at least with recent versions of libpcap, it'll be DLT_LINUX_SLL (on older versions, I forget what it was, but it still wasn't DLT_PPP - or, if it was, that was sometimes a lie, as there wasn't necessarily any PPP header there...).

If you're capturing on, for example, a PPP link, and you hard-coded into your program assumptions about the link-layer header, that could cause it to work correctly on a platform for which the hard-coded assumptions are correct, but to fail on a platform for which they aren't correct.

Once you've gotten past the link-layer header (and, if you're not using a filter to discard non-IP packets, checking it to see whether the packet is an IP packet), you need to handle the IP header. That part is platform-independent; at a minimum, you have to get the length of the header and skip past it and, if you're not using a filter to discard non-TCP packets (as NNTP runs over TCP), you need to check the header to see if the packet is a TCP packet.

Note also that you should look at the "total length" field in the IP header - it might indicate, especially on Ethernet, that there's extra padding at the end of the packet. Do not process that extra padding as if it were part of the TCP payload.

Once you've gotten past the IP header (and, if you're not using a filter to discard non-TCP packets, checking it to see whether the packet is a TCP packet), you have to handle the TCP header. That's also platform-independent; again, at minimum, you have to get the length of the header and skip past it and, if you're not using a filter to discard non-NNTP packets, check the port numbers to see if it's for whatever port you want to capture.

Once you've done all *that*, you have the TCP payload; print that as text, but, as Michael Richardson noted, make sure you handle non-printable characters at least semi-reasonably.

-
This is the TCPDUMP workers list. It is archived at
http://www.tcpdump.org/lists/workers/index.html
To unsubscribe use mailto:tcpdump-workers-request () tcpdump org?body=unsubscribe


Current thread: