您的位置:首页 > 理论基础 > 数据结构算法

答一位网友的hostapd问题,欢迎各位指正

2010-09-07 23:16 344 查看
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。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐