I am writing a Delphi (Pascal) app that will do some custom parsing of a .pcap file. The .pcap file is written by Wireshare/winpcap. I found C++ sample code for parsing the .pcap file, and I converted the C++ structs to Delphi records. And I've got my app mostly done. But, one thing that I'm just not getting... The headers for the Ethernet header, IP header and TCP header comes out to 54 bytes, assuming of course the packet in question is an Ethernet TCP/IP packet. Which is all I am working with. So, if the pcap record header incl_len is, for example, 60, then, the TCP payload would be 6 bytes, no? Well, no, or at least it seems not necessarily. In Wireshark, you can display columns of "length" and "info". And within the "info" column, it tells you things like the sequence number, the ack number, etc. And it tells you the "len". But, I'm seeing some rows with a "length" of 60 with a "len" of 6, as I would expect. But other rows of "length" of 60 may have len = 1 or 2 or 3, etc. Moreover, it seems that the "len" value, wherever it comes from, is the correct value for the usable data in the packet. If the len seems like it should be, say, 6 (in my example of length of 60) then if len is less than 6, then the additional bytes are just garbage or superfluous. Or maybe they have some meaning that is beyond my understanding. So, here is my question: where the heck is Wireshark getting "len" from? As far as the "length", that does seem to be the incl_len. But, for the "len", I can't find it from any of the values in the headers. As I said, I would think it would be length-54 (assuming Ethernet TCP/IP) and it often is. But it often isn't and I haven't a clue where len is coming from but I need it. Thanks. asked 19 Nov '12, 05:45 PaulJ |
One Answer:
Cool, someone else besides me using Delphi to parse trace files... If a packet has 54 bytes (14 Ethernet header, 20 IP header, 20 TCP header) and no TCP payload it would be too short to be a valid ethernet frame, which needs to be 60 bytes plus FCS = 64 Bytes. To achieve the minimum length, the frame is padded on the ethernet layer by 6 bytes. You can deduct the TCP payload length from taking the IP total length minus the IP and TCP header length. By the way, you only see packets with a length of 54 bytes if you're capturing on the system that is sending them, because Wireshark/Dumppcap will "pick them up" before the network card has done the padding. You can verify this by capturing on the other machine - it will show you the packets including padding. Oh, and Wireshark does not keep the FCS, which is why you'll see 60 bytes instead of 64. answered 19 Nov '12, 05:52 Jasper ♦♦ edited 19 Nov '12, 05:58 Ah, so, there is padding if the packet is less than a minimum length. But, I'm not seeing in what you say as to how to find out how much the padding is. When you say to "deduct the TCP payload length from taking the IP total length minus the IP and TCP header length", well, that, so far, seems to give me the size including the padding. I need the len, the length of actual data. I absolutely have to have this information for my app to work. I am getting data stretched across multiple frames that are being sent by Telnet. I sometimes get 1 or 2 or 3 bytes of usable data. My app needs to stitch it together. I can't stitch it if I don't know how much padding there is. (19 Nov '12, 11:54) PaulJ I converted your "answer" to a comment as that's how this site works, please read the FAQ for details. (19 Nov '12, 13:36) grahamb ♦ take a look at the following packet:
The frame length is 60 byte. The IP header starts at byte 0x0e(45 00 ..). The IP total length is 43 bytes. The IP header is 20 bytes and the TCP header is 20 bytes as well. So: 43-20-20 = 3 bytes TCP payload and 3 bytes padding (00 00 00). Telnet data is starting at position 0x36 = 0x0e (IP start) + 0x14 (20 bytes IP header) + 0x14 (20 bytes TCP header). (19 Nov '12, 13:54) Kurt Knochner ♦ Ah, okay. I was looking looking for something that would be, say, 57 (3 bytes payload with 54 bytes in headers) instead of 43, which doesn't include the Ethernet header. Now, I see. Thanks! (19 Nov '12, 14:27) PaulJ You're welcome. (19 Nov '12, 14:31) Kurt Knochner ♦ |
Can you not just call a C library such as libpcap/WinPcap from Delphi? That's a lot easier than trying to read pcap files yourself (and than trying to read pcap-ng files as well, given that pcap-ng is the default output format of Wireshark 1.8.0 and later).
Note, BTW, that if, in a 1000-byte TCP segment over IPv4 over Ethernet, with 14 bytes of Ethernet header, 20 bytes of IPv4 header (with no options), 20 bytes of TCP header (with no options), and 1000 bytes of data, if incl_len is 128 and orig_len is 1054 (as it should be), using incl_len would not correctly indicate the TCP payload.