hostapd wpa_supplicant madwifi详细分析(四)——interface的初始化


        前面讲了的初始,这一节将介绍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;
        
        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之间是相互联系的。

你可能感兴趣的:(wireless,无线局域网开发)