企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
前面讲了的初始,这一节将介绍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之间是相互联系的。