好记性不如铅笔头

C && C++, 编程

Linux下使用无线网卡嗅探802.11MAC帧

【 本文仅供学习交流使用,请勿用于其他用途!!! 】

首先将无线网卡设为混杂模式

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);