wpa_config_read分析
路径为:external\wpa_supplicant_8\wpa_supplicant\config_file.c
struct wpa_config * wpa_config_read(const char *name, struct wpa_config *cfgp)
{
FILE *f;
char buf[512], *pos;
int errors = 0, line = 0;
struct wpa_ssid *ssid, *tail = NULL, *head = NULL;
struct wpa_cred *cred, *cred_tail = NULL, *cred_head = NULL;
struct wpa_config *config;/*配置文件在代码中对应的数据结构*/
int id = 0;
int cred_id = 0;
if (name == NULL)
return NULL;
if (cfgp)
config = cfgp;
else
config = wpa_config_alloc_empty(NULL, NULL);
if (config == NULL) {
wpa_printf(MSG_ERROR, "Failed to allocate config file "
"structure");
return NULL;
}
head = config->ssid;
cred_head = config->cred;
wpa_printf(MSG_DEBUG, "Reading configuration file '%s'", name);
f = fopen(name, "r");
if (f == NULL) {
wpa_printf(MSG_ERROR, "Failed to open config file '%s', "
"error: %s", name, strerror(errno));
os_free(config);
return NULL;
}
while (wpa_config_get_line(buf, sizeof(buf), f, &line, &pos)) {
if (os_strcmp(pos, "network={") == 0) {
/*读取配置文件中的network项, 并将其转化成一个wpa_ssid类型的对象*/
ssid = wpa_config_read_network(f, &line, id++);
if (ssid == NULL) {
wpa_printf(MSG_ERROR, "Line %d: failed to "
"parse network block.", line);
errors++;
continue;
}
if (head == NULL) {/*wpa_ssid通过next成员变量构成了一个单项链表*/
head = tail = ssid;
} else {
tail->next = ssid;
tail = ssid;
}
/*network项属于配置文件的一部分, 故wpa_ssid对象也包含在wpa_config对象中*/
if (wpa_config_add_prio_network(config, ssid)) {
wpa_printf(MSG_ERROR, "Line %d: failed to add "
"network block to priority list.",
line);
errors++;
continue;
}
} else if (os_strcmp(pos, "cred={") == 0) {
cred = wpa_config_read_cred(f, &line, cred_id++);
if (cred == NULL) {
wpa_printf(MSG_ERROR, "Line %d: failed to "
"parse cred block.", line);
errors++;
continue;
}
if (cred_head == NULL) {
cred_head = cred_tail = cred;
} else {
cred_tail->next = cred;
cred_tail = cred;
}
#ifndef CONFIG_NO_CONFIG_BLOBS
} else if (os_strncmp(pos, "blob-base64-", 12) == 0) {
if (wpa_config_process_blob(config, f, &line, pos + 12)
< 0) {
wpa_printf(MSG_ERROR, "Line %d: failed to "
"process blob.", line);
errors++;
continue;
}
#endif /* CONFIG_NO_CONFIG_BLOBS */
} else if (wpa_config_process_global(config, pos, line) < 0) {
wpa_printf(MSG_ERROR, "Line %d: Invalid configuration "
"line '%s'.", line, pos);
errors++;
continue;
}
}
fclose(f);
config->ssid = head;
wpa_config_debug_dump_networks(config);
config->cred = cred_head;
#ifndef WPA_IGNORE_CONFIG_ERRORS
if (errors) {
wpa_config_free(config);
config = NULL;
head = NULL;
}
#endif /* WPA_IGNORE_CONFIG_ERRORS */
return config;
}
wpa_config和wpa_ssid这两个数据结构都是配置文件中的信息在代码中的反映. 可以查看wpa_suppilcant.conf配置模板文件来了解各个配置项的含义.
wpa_supplicant_init_iface分析
static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s,
struct wpa_interface *iface)
{
...
/*将wpa_interface中的ifname复制到wpa_supplicant的ifname变量中*/
os_strlcpy(wpa_s->ifname, iface->ifname, sizeof(wpa_s->ifname));
...
/* 下面这两个函数和EAPOL状态机相关 RSNA Supplicant Key Management - INITIALIZE */
eapol_sm_notify_portEnabled(wpa_s->eapol, FALSE);
eapol_sm_notify_portValid(wpa_s->eapol, FALSE);
...
}
wpa_supplicant_set_driver会根据driver(wlan驱动)名找到wpa_drivers数组中的nl80211指定的wpa_supplicant中driver的对象wpa_driver_nl80211_ops,然后调用它的global_init函数.
路径:external\wpa_supplicant_8\src\drivers\driver_nl80211.c