-1

I'm trying to capture and process 802.11 traffic in monitor mode. I'm able to catch it with tcpdump but I'm not able to process it with libpcap. I would need to pass then all packets to deep packet inspection method which is working great with ethernet packets. So my problem is that I can open dump file, read radio tap header and check that it's the same length as wireshark shows. After that I'm trying to read ether type and I get some unknown value. I couldn't find any information about returned 0x4500 so I assume that I should move pointer somewhere else but I'm not familiar with such type of programming and I'm asking if anyone can check my cap file and code in order to tell me what's wrong? My point tis to know where data and header are located in packet in order to send data to DPI.

P.S. I'm sitting here with this problem today for 10h, yesterday for about 14. I've done a lot of googling. Please help me with it.

Files at my server:

cap: click

code: click

Maciej Bielski
  • 129
  • 1
  • 4
  • Have you checked all your other structures ? e.g. your wifi_header doesn't at all match the IEE802.11 protocol that wireshark decodes, that's directly after the radiotap header. also 0x4500 is likely from the IP header(that's directly after the ethertype field), so you might be off by 2 bytes somewhere. – nos Sep 07 '15 at 18:44
  • Thank you nos for your reply :) All because "size_80211 += 2;". Now I'm able to see IP's. I'll check tomorrow morning if this code works well with DPI. One more time thanks ;) – Maciej Bielski Sep 07 '15 at 21:26
  • You're not off by 2 bytes because of `size_80211 += 2;`, you're off because of structure padding. See my answer; removing `size_80211 += 2;` will only compensate for the incorrect LLC header length for QoS frames, not for non-QoS frames, for which you aren't adding the additional 2 bytes in the first place. –  Sep 07 '15 at 21:35

1 Answers1

1

The LLC header:

struct snap_llc_header           
{
    u_int8_t    dsap; 
    u_int8_t    ssap;
    u_int8_t    ctl;
    u_int16_t   org; 
    u_int8_t    org2;
    u_int16_t   ether_type; /* ethernet type */              
};

is wrong. C compilers will, by default, attempt to properly align integral and floating-point values longer than 1 byte on the appropriate boundary; this means that the u_int16_t values will be aligned on 2-byte boundaries, with added padding.

Therefore, the structure will actually look like:

struct snap_llc_header           
{
    u_int8_t    dsap; 
    u_int8_t    ssap;
    u_int8_t    ctl;
    u_int8_t    pad1;
    u_int16_t   org; 
    u_int8_t    org2;
    u_int8_t    pad2;
    u_int16_t   ether_type; /* ethernet type */              
};

and it will be 2 bytes longer than an actual 802.2 LLC+SNAP header.

The quick-and-dirty fix, which will work only with GCC and GCC-compatible compilers, is to mark the structure as "packed", so that the values won't be aligned:

struct snap_llc_header           
{
    u_int8_t    dsap; 
    u_int8_t    ssap;
    u_int8_t    ctl;
    u_int8_t    pad1;
    u_int16_t   org; 
    u_int8_t    org2;
    u_int8_t    pad2;
    u_int16_t   ether_type; /* ethernet type */              
} __attribute__((packed));

If you want to make this work on compilers that don't support the GCC __attribute__((packed)) extension, you'll have to do more work.

(Note also that your code is assuming that it's running on a little-endian machine - if you're running it on a personal computer, it probably is, but if you're running it on a non-x86 and non-ARM server, it probably isn't. It's also assuming that it can safely refer to unaligned data - if you're running it on something other than a SPARC machine, it probably can, but if you're running it on a SPARC machine, it can't. Fixing that involves still more work.)

(Another potential issue is that if the 802.11 frames were captured from an Atheros network device, there might be some padding between the 802.11 header and the payload; see the "frame has padding between 802.11 header and payload (to 32-bit boundary)" flag in the radiotap flags field. That, unfortunately, will require you to parse the radiotap header.)

(And if you want to handle packets other than data frames with a SNAP header, you will need to check the DSAP and SSAP and, if they're not both 0xAA, process them without the 3-byte OUI and 2-byte protocol ID of the SNAP header. If they are both 0xAA, note that the 2-byte protocol ID is an Ethernet type only if all three bytes of the OUI are zero.)

  • Thank you @Guy Harris! I'm at last able to monitor my whole network :) It's great how quick pcap community responds for each question ;) – Maciej Bielski Sep 08 '15 at 12:44