前面講了的初始,這一節將介紹interface的初始化
關于interface這個詞在這里具體指的是什么,開始的時候自己也很模糊,經過多次詢問和驗證,個人將這個interface理解為無線網卡物理口,即我們用ifconfig打印出的wifi0和wifi1這樣的接口。我們知道,hostapd的一個主要功能是將一個無線網卡切換成ap模式,讓它以server端的角色運行,能夠讓其他無線設備連接上來。現在的路由器一般都支持2.4G和5G兩種無線頻段,所以在硬件上自然會有兩塊無線網卡,那么在這兩塊無線網卡都運行的時候,能夠在ifconfig中看到wifi0和wifi1的狀態都是up的,使用ps -w | grep hostapd 也能夠查看到,hostapd到底使用的是哪個網卡的配置文件,到底啟動了那塊網卡。
這里需要辨別一下物理網卡口和空中接口的區別,空中接口多以ath0,ath1等字樣命名,它們作為無線用戶的接入點,可以創建多個,甚至多于網卡的數量,比如在路由器啟動guest network功能的時候,用iwconfig命令可以查看到4個空中接口,這些都可以作為用戶的接入點,他們主要是需要使用不同的用戶名和密碼進行認證,但最終數據包的處理還是經過實際的兩塊網卡進行的。
下面說一下,程序時怎么初始化interface的。
~~~
for (i = 0; i < interfaces.count; i++) {
interfaces.iface[i] = hostapd_interface_init(&interfaces,
argv[optind + i],
debug);
if (!interfaces.iface[i]) {
wpa_printf(MSG_ERROR, "Failed to initialize interface");
goto out;
}
}
~~~
這個循環控制變量i的值是由interfaces.count = argc - optind 獲得的,argc的值是所有傳入參數的個數加一,optind的值是選項的偏移數,初始值是1.? 比如
hostapd -B -e /etc/entropy? /etc/ath1.conf? /etc/ath0.conf
以這樣的參數運行hostapd時,argc=6?? optind=4,那么count的值將等于2,其實也可以這樣理解:argc - optind就是非選項參數的個數,比如上面 -B是不帶參數的選項,-e是帶一個參數/etc/entropy的選項,那么剩下的/etc/ath1.conf?? /etc/ath0.conf不是某個選項的參數,所以不需要經過getopt類似函數的處理,不會使optind的值加一,所以差計算后他們的個數是2.
接下來好好說一下hostapd_interface_init這個函數。
~~~
static struct hostapd_iface *
hostapd_interface_init(struct hapd_interfaces *interfaces,
const char *config_fname, int debug)
{
struct hostapd_iface *iface;
int k;
wpa_printf(MSG_ERROR, "Configuration file: %s", config_fname);
iface = hostapd_init(interfaces, config_fname);
if (!iface)
return NULL;
iface->interfaces = interfaces;
for (k = 0; k < debug; k++) {
if (iface->bss[0]->conf->logger_stdout_level > 0)
iface->bss[0]->conf->logger_stdout_level--;
}
if (iface->conf->bss[0]->iface[0] == '\0' &&
!hostapd_drv_none(iface->bss[0])) {
wpa_printf(MSG_ERROR, "Interface name not specified in %s",
config_fname);
hostapd_interface_deinit_free(iface);
return NULL;
}
return iface;
}
~~~
1.先看struct hostapd_iface 對interface的操作函數以及標示變量的封裝
~~~
struct hostapd_iface {
struct hapd_interfaces *interfaces;
void *owner;
char *config_fname; // 這里存放配置文件路徑和文件名
struct hostapd_config *conf; //將配置文件中的信息讀取后,將存放在這個結構體中
char phy[16]; /* Name of the PHY (radio) */ //無線網卡芯片名
enum hostapd_iface_state { //描述接口狀態
HAPD_IFACE_UNINITIALIZED,
HAPD_IFACE_DISABLED,
HAPD_IFACE_COUNTRY_UPDATE,
HAPD_IFACE_ACS,
HAPD_IFACE_HT_SCAN,
HAPD_IFACE_DFS,
HAPD_IFACE_ENABLED
} state;
size_t num_bss; //基礎服務集合個數
struct hostapd_data **bss; //存放bss數據
unsigned int wait_channel_update:1;
unsigned int cac_started:1;
/*
* When set, indicates that the driver will handle the AP
* teardown: delete global keys, station keys, and stations.
*/
unsigned int driver_ap_teardown:1;
int num_ap; /* number of entries in ap_list */
struct ap_info *ap_list; /* AP info list head */
struct ap_info *ap_hash[STA_HASH_SIZE];
unsigned int drv_flags;
/*
* A bitmap of supported protocols for probe response offload. See
* struct wpa_driver_capa in driver.h
*/
unsigned int probe_resp_offloads;
/* extended capabilities supported by the driver */
const u8 *extended_capa, *extended_capa_mask;
unsigned int extended_capa_len;
unsigned int drv_max_acl_mac_addrs;
struct hostapd_hw_modes *hw_features;
int num_hw_features;
struct hostapd_hw_modes *current_mode;
/* Rates that are currently used (i.e., filtered copy of
* current_mode->channels */
int num_rates;
struct hostapd_rate_data *current_rates;
int *basic_rates;
int freq;
u16 hw_flags;
/* Number of associated Non-ERP stations (i.e., stations using 802.11b
* in 802.11g BSS) */
int num_sta_non_erp;
/* Number of associated stations that do not support Short Slot Time */
int num_sta_no_short_slot_time;
/* Number of associated stations that do not support Short Preamble */
int num_sta_no_short_preamble;
int olbc; /* Overlapping Legacy BSS Condition */
/* Number of HT associated stations that do not support greenfield */
int num_sta_ht_no_gf;
/* Number of associated non-HT stations */
int num_sta_no_ht;
/* Number of HT associated stations 20 MHz */
int num_sta_ht_20mhz;
/* Number of HT40 intolerant stations */
int num_sta_ht40_intolerant;
/* Overlapping BSS information */
int olbc_ht;
u16 ht_op_mode;
/* surveying helpers */
/* number of channels surveyed */
unsigned int chans_surveyed;
/* lowest observed noise floor in dBm */
s8 lowest_nf;
unsigned int dfs_cac_ms;
struct os_reltime dfs_cac_start;
/* Latched with the actual secondary channel information and will be
* used while juggling between HT20 and HT40 modes. */
int secondary_ch;
#ifdef CONFIG_ACS
unsigned int acs_num_completed_scans;
#endif /* CONFIG_ACS */
void (*scan_cb)(struct hostapd_iface *iface);
int num_ht40_scan_tries;
~~~
2.hostapd_init()函數
~~~
struct hostapd_iface * hostapd_init(struct hapd_interfaces *interfaces,
const char *config_file)
{
struct hostapd_iface *hapd_iface = NULL;
struct hostapd_config *conf = NULL;
struct hostapd_data *hapd; //這個結構體很重要,存放了數據以及一些報文相關的操作和信息
size_t i;
hapd_iface = os_zalloc(sizeof(*hapd_iface));
if (hapd_iface == NULL)
goto fail;
hapd_iface->config_fname = os_strdup(config_file);
if (hapd_iface->config_fname == NULL)
goto fail;
<pre name="code" class="cpp">
interfaces->config_read_cb=hostapd_config_read
conf = interfaces->config_read_cb(hapd_iface->config_fname);
if (conf == NULL)
goto fail;
hapd_iface->conf = conf;
hapd_iface->num_bss = conf->num_bss;
hapd_iface->bss = os_calloc(conf->num_bss,
sizeof(struct hostapd_data *));
if (hapd_iface->bss == NULL)
goto fail;
for (i = 0; i < conf->num_bss; i++) {
hapd = hapd_iface->bss[i] =
hostapd_alloc_bss_data(hapd_iface, conf,
conf->bss[i]);
if (hapd == NULL)
goto fail;
hapd->msg_ctx = hapd;
}
return hapd_iface;
~~~
hostapd_init內以該interface的配置文件作為參數調用hostapd_config_read。并將讀取到的配置信息賦給成員變量struct hostapd_config *conf.
根據配置文件中bss的配置個數conf->num_bss的值通過調用hostapd_alloc_bss_data分配空間及相關設置,并對hapd_iface->bss[i]進行賦值,
其中hostapd_alloc_bss_data的定義為
static struct hostapd_data *hostapd_alloc_bss_data(struct hostapd_iface *hapd_iface, struct hostapd_config *conf, struct hostapd_bss_config *bss)
三個參數分別為本interface信息,本interface的配置信息,本interface配置信息中第i個bss的配置部分。
其中代碼 (struct hostapd_data *hapd)
hapd->iconf = conf;
hapd->conf = bss;
hapd->iface = hapd_iface;
使得hostapd_data中均有指向這幾個配置的指針了。
既有:
hapd_iface->bss[i]->iconf == hapd_iface->conf
hapd_iface->bss[i]->conf == &hapd_iface->conf->bss[i]
hapd_iface->bss[i]->iface == hapd_iface
所以struct hostapd_data,? struct hostapd_iface, struct hostapd_config, struct hostapd_bss_config之間是相互聯系的。