wpa_supplicant 2.0版源代码阅读(2) ---- L2_packet模块

2. L2_packet模块

    L2_packet模块是wpa_supplicant软件中实现EAPOL帧的收发功能的模块。L2即网络协议层的数据链路层。wpa_supplicant针对不同的OS系统,采用了不同的抓包技术实现。windows平台采用NDIS协议驱动抓包技术,linux平台采用packet socket抓包技术。

    该模块的实现代码在目录wpa_supplicant/src/l2_packet中。

l2_packet_linux.c是linux系统下的收发EAPOL帧实现。

l2_packet_ndis.c是windows系统下使用ndisuio协议驱动实现收发EAPOL帧实现。

l2_packet_pcap是windows系统下使用winpcap协议驱动实现EAPOL收发,采用轮询的方式抓包。

l2_packet_winpcap是windows系统下使用winpcap协议驱动实现EAPOL收发,采用接收线程的方式抓包。相比l2_packet_pcap抓包,接收EAPOL帧的延迟从100ms降到了3ms。

l2_packet.h是api接口声明和struct l2_packet_data声明头文件。

2.1 l2_packet主要的接口函数说明

2.1.1 l2_packet_init

struct l2_packet_data * l2_packet_init(
    const char *ifname, const u8 *own_addr, unsigned short protocol,
    void (*rx_callback)(void *ctx, const u8 *src_addr,
                const u8 *buf, size_t len),
    void *rx_callback_ctx, int l2_hdr);
ifname: 网络设备名;

own_addr: mac地址

protocol:协议类型或者以太类型。如抓取EAPOL帧,以太类型为0x888E。

rx_callback: 接收到EAPOL帧的回调处理函数。

ctx:上面回调处理函数的回调参数。

l2_hrd:收发数据是否包含l2层以太头。通常设置为0,不包含。

l2_packet_init()函数在wpa_supplicant初始化时候调用。

2.1.2 l2_packet_deinit

wpa_supplicant退出或清除时调用,释放相关资源。

2.1.3 l2_packet_send

向驱动发送EAPOL帧接口函数。

2.1.4 l2_packet_notify_auth_start

该函数接口的实现只在l2_packet_winpcap中实现,因其采用创建一个线程抓包,所以在无线联网关联成功之后,唤醒l2_packet接收线程,准备获取EAPOL帧。

2.2 l2_packet模块的初始化

     wpa_supplicnat在初始化阶段调用l2_packet_init()函数。函数调用关系如下:

main --> wpa_supplicant_add_iface() --> wpa_supplicant_init_iface() -->wpa_supplicant_driver_init() --> wpa_supplicant_update_mac_addr() --> l2_packet_init()

int wpa_supplicant_update_mac_addr(struct wpa_supplicant *wpa_s)
{
	if (wpa_s->driver->send_eapol) {              
		const u8 *addr = wpa_drv_get_mac_addr(wpa_s);
		if (addr)
			os_memcpy(wpa_s->own_addr, addr, ETH_ALEN);
	} else if (!(wpa_s->drv_flags &
		     WPA_DRIVER_FLAGS_P2P_DEDICATED_INTERFACE)) {
		l2_packet_deinit(wpa_s->l2);
		wpa_s->l2 = l2_packet_init(wpa_s->ifname,
					   wpa_drv_get_mac_addr(wpa_s),
					   ETH_P_EAPOL,
					   wpa_supplicant_rx_eapol, wpa_s, 0);
		if (wpa_s->l2 == NULL)
			return -1;
	} else {
		const u8 *addr = wpa_drv_get_mac_addr(wpa_s);
		if (addr)
			os_memcpy(wpa_s->own_addr, addr, ETH_ALEN);
	}

	if (wpa_s->l2 && l2_packet_get_own_addr(wpa_s->l2, wpa_s->own_addr)) {
		wpa_msg(wpa_s, MSG_ERROR, "Failed to get own L2 address");
		return -1;
	}

	wpa_dbg(wpa_s, MSG_DEBUG, "Own MAC address: " MACSTR,
		MAC2STR(wpa_s->own_addr));
	wpa_sm_set_own_addr(wpa_s->wpa, wpa_s->own_addr);

	return 0;
}
1) wpa_s->drv->send_eapol函数指针是针对某些在嵌入式系统(非wince和linux)上采用wpa_supplicant开发使用的,在这种开发环境下,wpa_supplicant与无线驱动的EAPOL帧的收发可以直接交互,wpa_supplicnat直接调用注册的send_eapol函数把EAPOL帧发送到无线驱动。在linux和windows开发环境下,则不用设置send_eapol函数指针。

2)  (!(wpa_s->drv_flags &  WPA_DRIVER_FLAGS_P2P_DEDICATED_INTERFACE) 是判断驱动支持的功能标记,通常的无线驱动不支持WPA_DRIVER_FLAGS_P2

  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值