Processing incorrect mac addresses from 802.11 frames with pcap

ⅰ亾dé卋堺 提交于 2019-12-06 10:17:04

You're doing several things wrong.

The first thing you're doing wrong is declaring the radiotap header as a structure with more fields than it_version, it_pad, it_len, and it_present. There is absolutely no guarantee that on in arbitrary radiotap header there will, for example, be a 64-bit MAC_timestamp field following the it_present field. You have to look at the it_present field to see which of the fields in the header are actually present. See the radiotap Web site for details on how to process a radiotap header.

Comparing the values of the fields against 0 (or NULL) does not work - if a field isn't present, it simply isn't present.

Your code might happen to work with particular versions of drivers for particular networking adapters on particular OSes, but it might fail if the driver is changed or if you run on a machine with a different type of adapter (for example, Atheros vs. Broadcom adapters on Macs) or if you try to run this on a different operating system (Linux, for example).

If you expect this code to run on a big-endian machine, you will also need to fetch fields from the radiotap header more carefully, as they're all little-endian. (The #define in your code is not sufficient for that.)

Except for the byte-order issue, which would show up on a Mac only if you're running on a PowerPC Mac, you are correctly skipping past the radiotap header, so that's not the issue.

Also, the MAC timestamp is a 64-bit integer, and on a 32-bit machine it'd have to be printed with %llu rather than %u.

You should also be checking for errors. pcap_create() and pcap_activate() are presumably not failing if you're seeing packets, so that's probably not the immediate problem, but you should check for failure anyway. The pcap_set_ routines are also probably not failing, at least not on Wi-Fi devices, but you should check anyway.

If you're going to assume packets are 802.11+radiotap packets, you should probably at least check to make sure the return value of pcap_datalink() is DLT_IEEE802_11_RADIO and fail if it's not. While you're at it, add a newline to the end of the message printed for the link-layer type.

But the main think you're doing wrong is capturing no more than 30 bytes of every packet! When you do pcap_set_snaplen(descr,30);, you're saying "don't capture any more than 30 bytes"; the radiotap header is probably longer than that, so you're not even going to get all of the radiotap header, much less getting any of the 802.11 header.

If you want to capture the entire packet, just leave the pcap_set_snaplen() call out.

Oh, and if you want to be really careful, make sure, when you're looking at the radiotap and 802.11 header, that you haven't gone past pkthdr->caplen.

That also means your loop that checks pkthdr->len should check pkthdr->caplen AND should either start with packet[0] or should subtract rh->it_len from pkthdr->caplen (as you should have checked to make sure rh->it_len is greater than or equal to pkthdr->caplen while or before you parsed the radiotap header, the result of that subtraction will be positive). The snapshot length includes all pseudo-headers such as the radiotap header.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!