1. 程序在哪里加載了配置文件呢? 在哪里設進去了呢?
main 中hostapd_interface_init? 調用 hostapd_init ,conf = interfaces->config_read_cb(hapd_iface->config_fname);? 其實config_read_cb 指向hostapd_config_read 函數,它將配置文件(config_fname)中的配置選項讀取到 conf 對象中,便后面使用。
hostapd_interface_init有調用hostapd_setup_interface 將config里面的值設置進進程里面。
2.中斷處理函數在哪里注冊? 注冊了哪些中斷處理函數呢?
在main函數的開始,定義了一個對象: struct hostapd_interfaces interfaces
這個對象在整個程序中起到一定貫穿作用,我們來看看hostapd_global_init()中對中斷注冊函數的調用(這個調用其他版本也可能在別的地方):
~~~
eloop_register_signal_terminate(handle_term, interfaces);
~~~
這里分成了兩部分,handle_term將調用函數
~~~
static void handle_term(int sig, void *eloop_ctx, void *signal_ctx)
{
wpa_printf(MSG_DEBUG, "Signal %d received - terminating", sig);
eloop_terminate();
}
void eloop_terminate(void)
{
eloop.terminate = 1;
}
~~~
這里將terminate 置1,在后面能夠引起 eloop_run中的while循環退出,而interfaces部分,將會在eloop_register_signal函數中賦值給 eloop.signal.user_data,以便中斷處理函數調用,同時將eloop.pending_terminate 置1。
3.socket在哪里創建的呢? socket文件描述符集怎么實現select監聽, ioctl控制呢?
main 中hostapd_interface_init? 調用 hostapd_init, hapd_inface-> ctrl_inface_init = hostapd_ctrl_inface_init, 其實調用的是hostapd_ctrl_inface_init函數,這個函數的重要性就不強調了,因為它在數據 收發中起到關鍵的作用。
hostapd_ctrl_inface_init函數使用了socket函數(注意第一個選項是PF_UNIX)、bind函數、connect函數、eloop_register_read_sock函數等直接和 l2_packet_linux.c 相關。
接著eloop_run函數while循環中將使用select對socket進行監聽,示意圖如下。

4.數據包是怎么發送接收的呢?
l2_packet_send 和 l2_packet_receive這兩個函數在 src/ l2_packet/ l2_packet_linux.c 中, l2_packet_init 函數中使用ioctrl監聽數據,然后通過socket將數據發送出去。
5.那么hostapd進程是怎么樣和madwifi進行交互的呢?? 將在后面madwifi部分介紹了
6.驅動是在什么時候加載進內核的呢?
main 中hostapd_interface_init? 調用hostapd_driver_init,里面有一句hapd->driver->hapd_init(hapd, ¶ms),將會調用 src/ driver / dirver_madwifi.c 中的 madwifi_init函數。
Madwifi_init 調用了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。
l2_packet_init里面調用了int eloop_register_read_sock(int sock, eloop_sock_handler handler, void *eloop_data, void *user_data)
這里handler即l2_packet_receive,最后通過
static int eloop_sock_table_add_sock(struct eloop_sock_table *table, int sock, eloop_sock_handler handler,? void *eloop_data, void *user_data)
將socket可讀消息的handler回調函數設為了l2_packet_receive。
再一次看這個,當select到read-sock有消息時,最終call到這里
static void l2_packet_receive(int sock, void *eloop_ctx, void *sock_ctx)
到這里hostapd這個程序寫的差不多了,里面好多東西都是參考或者說是copy?? [點擊打開鏈接](http://blog.csdn.net/njzhujinhua/article/category/2442809) 這里的,作為一個菜鳥深知理解的還不夠到位,寫這些東西也花了好幾天時間,主要是為了加強自己的學習效果,里面肯定有錯誤的地方,希望能夠得到指正。
接下來將寫一篇hostapd的整體梳理,給自己一個完整的交代吧。
??