3. ieee802_1x.c中,ieee802_1x_receive()函数是接受处理EAPOL帧的函数,我想知道他
里面的参数buf和length是如何有客户端接收到的,换句话说,我在这里调用这两个数据结
构,这两个数据时怎么得到了,是不是通过网卡驱动就得到了?、
答:
【1】与驱动相关结构定义及变量
以madwifi驱动为例,
hostapd/driver_madwifi.c
定义了wpa_driver_ops wpa_driver_madwifi_ops这个实际就是各个驱动给回调函数赋值,
注意init的设置
const struct wpa_driver_ops wpa_driver_madwifi_ops = {
.name = "madwifi",
.init = madwifi_init, //这里
.deinit = madwifi_deinit,
.set_ieee8021x = madwifi_set_ieee8021x,
.set_privacy = madwifi_set_privacy,
.set_encryption = madwifi_set_key,
.get_seqnum = madwifi_get_seqnum,
.flush = madwifi_flush,
.set_generic_elem = madwifi_set_opt_ie,
.wireless_event_init = madwifi_wireless_event_init,
.wireless_event_deinit = madwifi_wireless_event_deinit,
.sta_set_flags = madwifi_sta_set_flags,
.read_sta_data = madwifi_read_sta_driver_data,
.send_eapol = madwifi_send_eapol,
.sta_disassoc = madwifi_sta_disassoc,
.sta_deauth = madwifi_sta_deauth,
.set_ssid = madwifi_set_ssid,
.get_ssid = madwifi_get_ssid,
.set_countermeasures = madwifi_set_countermeasures,
.sta_clear_stats = madwifi_sta_clear_stats,
.commit = madwifi_commit,
.set_wps_beacon_ie = madwifi_set_wps_beacon_ie,
.set_wps_probe_resp_ie = madwifi_set_wps_probe_resp_ie,
};
而drivers.c中有
……
#ifdef CONFIG_DRIVER_MADWIFI
extern struct wpa_driver_ops wpa_driver_madwifi_ops; /* driver_madwifi.c */
#endif /* CONFIG_DRIVER_MADWIFI */
……
及
struct wpa_driver_ops *hostapd_drivers[] =
{
。。。。。。
#ifdef CONFIG_DRIVER_MADWIFI
&wpa_driver_madwifi_ops,
#endif /* CONFIG_DRIVER_MADWIFI */
。。。
NULL
};这里的hostapd_drivers就是当前支持的所有驱动了。对此config.c中也有使用。
【2】驱动初始化
static int setup_interface(struct hostapd_iface *iface)
{
struct hostapd_data *hapd = iface->bss[0];
。。。。。。
/*
* Initialize the driver interface and make sure that all BSSes get
* configured with a pointer to this driver interface.
*/
if (b[0] | b[1] | b[2] | b[3] | b[4] | b[5]) {
hapd->drv_priv = hostapd_driver_init_bssid(hapd, b);
} else {
hapd->drv_priv = hostapd_driver_init(hapd);
}
。。。。。。
}
static inline void *
hostapd_driver_init(struct hostapd_data *hapd)
{
if (hapd->driver == NULL || hapd->driver->init == NULL)
return NULL;
return hapd->driver->init(hapd);
}
由此从这里将要call 前面设置的madwifi的init函数madwifi_init。
Madwifi_init(hostapd/driver_madwifi.c line1313) call l2_packet_init() 该函数
有很多实现,参见src下的l2_packet目录。
譬如windows下可用的winpcap等。
这实际就是类似抓包的了,不过在链路层而已。
调用的时候
drv->sock_xmit = l2_packet_init(drv->iface, NULL, ETH_P_EAPOL,handle_read,
drv, 1);注册了handle_read。意思就是收到ETH_P_EAPOL协议帧后调用handle_read
handle_read实现如下
static void
handle_read(void *ctx, const u8 *src_addr, const u8 *buf, size_t len)
{
struct madwifi_driver_data *drv = ctx;
struct hostapd_data *hapd = drv->hapd;
struct sta_info *sta;
sta = ap_get_sta(hapd, src_addr);
if (!sta || !(sta->flags & WLAN_STA_ASSOC)) {
printf("Data frame from not associated STA %s/n",
ether_sprintf(src_addr));
/* XXX cannot happen */
return;
}
ieee802_1x_receive(hapd, src_addr, buf + sizeof(struct l2_ethhdr),
len - sizeof(struct l2_ethhdr));
}
在此,调用了你问的ieee802_1x_receive。