【 本文仅供学习交流使用,请勿用于其他用途!!! 】
首先将无线网卡设为混杂模式
ifconfig wlan0 down iw dev wlan0 set type monitor ifconfig wlan0 up
使用wireshark抓个包看下,如下图:
可以看到,wireshark抓到的包在MAC帧前面有个Radiotap结构体,这里直接参考网址【http://www.radiotap.org/】,可以发现,Radiotap是Kernel附带的一个包头,简单起见,这里就不搜kernel了,直接用Radiotap结构体把头部解析出来,并且跳过去。
#pragma pack(1) /* http://www.radiotap.org/ */ typedef struct { /** * @it_version: radiotap version, always 0 */ uint8_t it_version; /** * @it_pad: padding (or alignment) */ uint8_t it_pad; /** * @it_len: overall radiotap header length */ uint16_t it_len; /** * @it_present: (first) present word */ uint32_t it_present; }ieee80211_radiotap_header; #pragma pack()
那么现在可以抓包了:
/* socket设置为raw模式 */ int sock = socket(PF_PACKET, SOCK_RAW, htons(0x03));//ETH_P_ALL if(sock < 0) { perror("Raw Socket Alloc"); return; } #define MAX_REV_BUFFER 1024 BYTE rev_buffer[MAX_REV_BUFFER]; int skipLen = 26;/* radiotap 默认长度为26 */ while (1) { int rev_num = recvfrom(sock, rev_buffer, MAX_REV_BUFFER, 0, NULL, NULL); ieee80211_radiotap_header *pHeader = (ieee80211_radiotap_header *)rev_buffer; skipLen = pHeader->it_len; if(len >= MAX_REV_BUFFER) { continue; } if(rev_num > skipLen) { ParesePacket(rev_buffer + skipLen, rev_num - skipLen); } } close(sock);