1 配置文件
conf文件作为wpa_supplicant的配置文件,一般叫做 wpa_supplicant.conf 。其中存储着wpa_supplicant的运行参数和以保存的网络列表。
conf文件的路径,通过启动wpa_supplicant时的 –c 参数传入,初始化过程中赋值到wpa_s->confname,然后将数据读入wpa_s->conf中。
wpa_supplicant的所有参数都定义在struct wpa_config中
struct wpa_config {
//config文件中,存储所有network节点的链表
struct wpa_ssid *ssid;
//按照priority排列的network节点
struct wpa_ssid **pssid;
//*pssid的长度
int num_prio;
/** * cred - Head of the credential list * * This is the head for the list of all the configured credentials. */
struct wpa_cred *cred;
//EAP版本,WPAS支持到2
int eapol_version;
//1---wpas负责扫描和选择网络
//0、2---驱动负责扫描和连接
int ap_scan;
//bgscan - Background scan and roaming parameters or %NULL if none
char *bgscan;
//disable_scan_offload - Disable automatic offloading of scan requests
//驱动可以自行sche_scan,设置为1,disable驱动的功能
int disable_scan_offload;
// ctrl_interface - Parameters for the control interface
//结构名称例如wlan0
char *ctrl_interface;
//ctrl_interface_group - Control interface group (DEPRECATED)
char *ctrl_interface_group;
//fast_reauth - EAP fast re-authentication (session resumption)
//默认是1 disable,设置为0 disable该功能,
int fast_reauth;
//opensc_engine_path - Path to the OpenSSL engine for opensc
char *opensc_engine_path;
//pkcs11_engine_path - Path to the OpenSSL engine for PKCS#11
char *pkcs11_engine_path;
//pkcs11_module_path - Path to the OpenSSL OpenSC/PKCS#11 module
char *pkcs11_module_path;
//pcsc_reader - PC/SC reader name prefix
char *pcsc_reader;
// pcsc_pin - PIN for USIM, GSM SIM, and smartcards
char *pcsc_pin;
//external_sim - Use external processing for SIM/USIM operations
int external_sim;
//driver_param - Driver interface parameters
//如果有的话,通过struct wpa_driver_ops::set_param()执行
char *driver_param;
//dot11RSNAConfigPMKLifetime - Maximum lifetime of a PMK
unsigned int dot11RSNAConfigPMKLifetime;
// dot11RSNAConfigPMKReauthThreshold - PMK re-authentication threshold
unsigned int dot11RSNAConfigPMKReauthThreshold;
//dot11RSNAConfigSATimeout - Security association timeout
unsigned int dot11RSNAConfigSATimeout;
//update_config - Is wpa_supplicant allowed to update configuration/
int update_config;
//blobs - Configuration blobs
struct wpa_config_blob *blobs;
// uuid - Universally Unique IDentifier (UUID; see RFC 4122) for WPS
u8 uuid[16];
//device_name - Device Name (WPS)
char *device_name;
//manufacturer - Manufacturer (WPS)
//The manufacturer of the device (up to 64 ASCII characters)
char *manufacturer;
// model_name - Model Name (WPS)
//Model of the device (up to 32 ASCII characters)
char *model_name;
//model_number - Model Number (WPS)
//Additional device description (up to 32 ASCII characters)
char *model_number;
//serial_number - Serial Number (WPS)
//Serial number of the device (up to 32 characters)
char *serial_number;
//device_type - Primary Device Type (WPS)
u8 device_type[WPS_DEV_TYPE_LEN];
//config_methods - Config Methods(WPS)
char *config_methods;
//os_version - OS Version (WPS)
//4-octet operating system version number
u8 os_version[4];
//country - Country code(ISO/IEC alpha2)
char country[2];
/** * wps_cred_processing - Credential processing * * 0 = process received credentials internally * 1 = do not process received credentials; just pass them over * ctrl_iface to external program(s) * 2 = process received credentials internally and pass them over * ctrl_iface to external program(s) */
int wps_cred_processing;
#define MAX_SEC_DEVICE_TYPES 5
/** * sec_device_types - Secondary Device Types (P2P) */
u8 sec_device_type[MAX_SEC_DEVICE_TYPES][WPS_DEV_TYPE_LEN];
int num_sec_device_types;
int p2p_listen_reg_class;
int p2p_listen_channel;
int p2p_oper_reg_class;
int p2p_oper_channel;
int p2p_go_intent;
char *p2p_ssid_postfix;
int persistent_reconnect;
int p2p_intra_bss;
unsigned int num_p2p_pref_chan;
struct p2p_channel *p2p_pref_chan;
struct wpa_freq_range_list p2p_no_go_freq;
int p2p_add_cli_chan;
int p2p_ignore_shared_freq;
int p2p_optimize_listen_chan;
struct wpabuf *wps_vendor_ext_m1;
//wps_vendor_ext - Vendor extension attributes in WPS
//MAX_WPS_VENDOR_EXT = 10
struct wpabuf *wps_vendor_ext[MAX_WPS_VENDOR_EXT];
// p2p_group_idle - Maximum idle time in seconds for P2P group
//超过该时间(秒),将关闭数据
int p2p_group_idle;
//p2p_passphrase_len - Passphrase length (8..63) for P2P GO
//GO产生的随机秘钥的长度(8~63)
unsigned int p2p_passphrase_len;
//bss_max_count - Maximum number of BSS entries to keep in memory
//存储的bss最大个数
unsigned int bss_max_count;
//bss_expiration_age - BSS entry age after which it can be expired
//bss超期时间秒(bss 被remnove后的时间),
unsigned int bss_expiration_age;
//bss_expiration_scan_count - Expire BSS after number of scans
//bss经过几次扫描不到,被remove
unsigned int bss_expiration_scan_count;
//filter_ssids - SSID-based scan result filtering
//0--disable, 1--enable
int filter_ssids;
//filter_rssi - RSSI-based scan result filtering
//0--disable, -n--去掉scan_res中<-ndb的bss
int filter_rssi;
//max_num_sta - Maximum number of STAs in an AP/P2P GO
unsigned int max_num_sta;
// freq_list - Array of allowed scan frequencies or %NULL for all
//允许扫描的频率列表
int *freq_list;
//scan_cur_freq - Whether to scan only the current channel,只扫描当前频率
int scan_cur_freq;
//changed_parameters - Bitmap of changed parameters since last update
unsigned int changed_parameters;
//disassoc_low_ack - Disassocicate stations with massive packet loss
//因丢包导致关联失败的station个数
int disassoc_low_ack;
//interworking - Whether Interworking (IEEE 802.11u) is enabled
int interworking;
//access_network_type - Access Network Type
//interworking=1时,该项起作用,取值0~15
int access_network_type;
//hessid - Homogenous ESS identifier 80211u相关
u8 hessid[ETH_ALEN];
//hs20 - Hotspot 2.0
int hs20;
//pbc_in_m1 - AP mode WPS probing workaround for PBC with Windows 7
int pbc_in_m1;
//autoscan - Automatic scan parameters or %NULL if none,文档中有介绍
//<autoscan module name>:<module parameters>
char *autoscan;
//NFC相关
int wps_nfc_pw_from_config;
int wps_nfc_dev_pw_id;
struct wpabuf *wps_nfc_dh_pubkey;
struct wpabuf *wps_nfc_dh_privkey;
struct wpabuf *wps_nfc_dev_pw;
/** * ext_password_backend - External password backend or %NULL if none * * format: <backend name>[:<optional backend parameters>] */
char *ext_password_backend;
/* * p2p_go_max_inactivity - Timeout in seconds to detect STA inactivity * * This timeout value is used in P2P GO mode to clean up * inactive stations. * By default: 300 seconds. */
int p2p_go_max_inactivity;
struct hostapd_wmm_ac_params wmm_ac_params[4];
// auto_interworking - Whether to use network selection automatically
int auto_interworking;
//p2p_go_ht40 - Default mode for HT40 enable when operating as GO.
int p2p_go_ht40;
// p2p_go_vht - Default mode for VHT enable when operating as GO
int p2p_go_vht;
int p2p_disabled;
//p2p_no_group_iface - Whether group interfaces can be used
int p2p_no_group_iface;
//okc - Whether to enable opportunistic key caching by default
int okc;
//pmf - Whether to enable/require PMF by default。默认值为0
//ieee80211w=1 or ieee80211w=2 parameter. pmf=1/2 can be used to change
enum mfp_options pmf;
//sae_groups - Preference list of enabled groups for SAE
int *sae_groups;
// dtim_period - Default DTIM period in Beacon intervals
int dtim_period;
// beacon_int - Default Beacon interval in TU
int beacon_int;
//ap_vendor_elements: Vendor specific elements for Beacon/ProbeResp
struct wpabuf *ap_vendor_elements;
//ignore_old_scan_res - Ignore scan results older than request
int ignore_old_scan_res;
//sched_scan_interval - schedule scan interval
unsigned int sched_scan_interval;
//tdls_external_control - External control for TDLS setup requests
int tdls_external_control;
u8 ip_addr_go[4];
u8 ip_addr_mask[4];
u8 ip_addr_start[4];
u8 ip_addr_end[4];
//osu_dir - OSU provider information directory
char *osu_dir;
//wowlan_triggers - Wake-on-WLAN triggers
char *wowlan_triggers;
//p2p_search_delay - Extra delay between concurrent search iterations
unsigned int p2p_search_delay;
//key_mgmt_offload - Use key managment offload
int key_mgmt_offload;
};
2. network节点
conf文件中每一个network节点都是一个保存的网络,在android手机扫描结果界面中可以直接点击连接该网络,形式如下
network={
ssid=”ASUS”
psk=”**”
key_mgmt=WPA-PSK
priority=6
}
上述节点中存储了网络的名称(ssid),密码(psk),加密方式(WPA_PSK),优先级(priority)
WIFI网络有多种加密方式,每种加密方式(wpa_psk,wep,open,wapi,各种eap等)的节点书写方式都不同,具体可以参考源代码中wpa_supplicant.conf文件
wpa_supplicant.conf
每一个network节点解析后会生成一个struct wpa_ssid,结构体中顶一个多种字段,以满足不同加密方式的需求。
//wpa_supplicant.conf中的网络节点都会生成一个wps_ssid的结构体
struct wpa_ssid{
//链表指针,链表头存放在struct wpa_config->ssid
struct wpa_ssid *next;
//按照priority组成的链表,链表头在struct wpa_config->pssid
struct wpa_ssid *pnext;
//每个网络节点都会有一个id,当通过control interface创建时,通过config文件读取时,都会赋予一个id
int id;
//每个network初始的priority的值是0,当select该bss时,priority会升高
//收到扫描结果时,按照priority由高到低匹配,
//当priority相同时,会按照安全协议,信号强度匹配
//注意:AP采用scan_ssid=1 和 ap_scan=2 时,按照config文件中的顺序(wpa_config->ssid)匹配
int priority;
//网络标识,可以包含任何字符,
u8 *ssid;
size_t ssid_len;
//如果有该值,是该bssid的AP关联时会用到
//如果disabled == 2,该值为GO的mac
u8 bssid[ETH_ALEN];
//对于该network,bssid是否被配置
int bssid_set;
//GO的mac地址
u8 go_p2p_dev_addr[ETH_ALEN];
//psk - WPA pre-shared key (256 bits)通过passphrase项的sha生成
u8 psk[32];
//Whether PSK field is configured
int psk_set;
//如果包含该项,那么连接时采用ssid和passphrase,长度为8~63字符
char *passphrase;
//存储PSK的文件路径
char *ext_psk;
//pairwise_cipher - Bitfield of allowed pairwise ciphers, WPA_CIPHER_*
int pairwise_cipher;
//group_cipher - Bitfield of allowed group ciphers, WPA_CIPHER_*
int group_cipher;
//Bitfield of allowed key management protocols WPA_KEY_MGMT_*
int key_mgmt;
//背景扫描的间隔(秒),0----disable, -1----使用驱动中默认值
int bg_scan_period;
//Bitfield of allowed protocols, WPA_PROTO_*
int proto;
//Bitfield of allowed authentication algorithms(算法)WPA_AUTH_ALG_*
int auth_alg;
//放BSS设置为隐藏时,使用该项值写入到Probe Requests,
//当某些驱动不支持扫描隐藏网络时,设置ap_mode=2
int scan_ssid;
**EAP相关
//Bit field of IEEE 802.1X/EAPOL options (EAPOL_FLAG_*)
int eapol_flags;
//eap - EAP peer configuration for this network
struct eap_peer_config eap;
**WEP相关
//wep密码 NUM_WEP_KEYS=4 MAX_WEP_KEY_LEN=16
u8 wep_key[NUM_WEP_KEYS][MAX_WEP_KEY_LEN];
size_t wep_key_len[NUM_WEP_KEYS];
//wep_tx_keyidx - Default key index for TX frames using WEP
int wep_tx_keyidx;
//什么是proactive key caching?
//1---使能, 0--禁用
//与 PMK, PMKSA, RSN有关
int proactive_key_caching;
/** * mixed_cell - Whether mixed cells are allowed * * This option can be used to configure whether so called mixed cells, * i.e., networks that use both plaintext and encryption in the same * SSID, are allowed. This is disabled (0) by default. Enable by * setting this to 1. */
int mixed_cell;
#ifdef IEEE8021X_EAPOL
//leap - Number of EAP methods using LEAP
//LEAP是一种EAP认证,android wifi界面不支持
int leap;
//non_leap - Number of EAP methods not using LEAP
int non_leap;
//eap_workaround - EAP workarounds enabled
//跳过关联失败的eap server
unsigned int eap_workaround;
#endif /* IEEE8021X_EAPOL */
//WPAS模式
enum wpas_mode {
WPAS_MODE_INFRA = 0, //征程station模式
WPAS_MODE_IBSS = 1, //IBSS网络,只用station不需要AP组成
WPAS_MODE_AP = 2, //AP, softap
WPAS_MODE_P2P_GO = 3, //P2P GO
WPAS_MODE_P2P_GROUP_FORMATION = 4, //不能通过config文件设置
} mode;
//0---该network可用
//1---该network不可用,可通过 ctrl_iface启用
//2---该network包含P2P参数
int disabled;
//WPS网络连接之前,设置该值disable,连接完,取消,
int disabled_for_connect;
/** * peerkey - Whether PeerKey handshake for direct links is allowed * * This is only used when both RSN/WPA2 and IEEE 802.11e (QoS) are * enabled. * * 0 = disabled (default) * 1 = enabled */
int peerkey;
//id_str - Network identifier string for external scripts
char *id_str;
#ifdef CONFIG_IEEE80211W
//ieee80211w - Whether management frame protection is enabled
enum mfp_options ieee80211w;
{
NO_MGMT_FRAME_PROTECTION = 0,
MGMT_FRAME_PROTECTION_OPTIONAL = 1,
MGMT_FRAME_PROTECTION_REQUIRED = 2,
};
#endif /* CONFIG_IEEE80211W */
int frequency;
int ht40;
int vht;
//wpa_ptk_rekey - Maximum lifetime for PTK in seconds
//PSK生存时间
int wpa_ptk_rekey;
//该network的扫描频率,如果设置了该值,对于该network,只扫描该频率
int *scan_freq;
//bgscan 背景扫描设置,参数格式:
//<bgscan module name>:<module parameters>
char *bgscan;
//wpas 在 AP模式时,设置隐藏SSID
//0--disable, 1--beacon中ssid长度为0,不对probe request做回应, 2 beacon中ssid内容为‘0’,不对probe request做回应
int ignore_broadcast_ssid;
//如果设置了该项,当接收到扫描结果时,如果频率列表不配皮,不在select该bss
int *freq_list;
//p2p_client_list - List of P2P Clients in a persistent group (GO)
//GC的mac地址列表
u8 *p2p_client_list;
//num_p2p_clients - Number of entries in p2p_client_list
size_t num_p2p_clients;
#define P2P_MAX_STORED_CLIENTS 100
//struct psk_list_entry) 链表头
struct dl_list psk_list;
struct psk_list_entry {
struct dl_list list;
u8 addr[ETH_ALEN];
u8 psk[32];
u8 p2p;
};
//p2p_group - Network generated as a P2P group (config文件不可配置)
int p2p_group;
//p2p_persistent_group - Whether this is a persistent group
int p2p_persistent_group;
//temporary - Whether this network is temporary and not to be saved
int temporary;
//export_keys - Whether keys may be exported
int export_keys;
#ifdef CONFIG_HT_OVERRIDES
//disable_ht - Disable HT (高吞吐率模式)(IEEE 802.11n) for this network
int disable_ht;
//disable_ht40 - Disable HT40 for this network
int disable_ht40;
//disable_sgi - Disable SGI(帧间隔) (Short Guard Interval) for this network
int disable_sgi;
//disable_ldpc - Disable LDPC(一种编码方式) for this network
int disable_ldpc;
//ht40_intolerant(不容许) - Indicate 40 MHz intolerant for this network
int ht40_intolerant;
//disable_max_amsdu - Disable MAX A-MSDU
//MSDU一个报文,disable该项,amsdu为3839B,enable则为7935B,
//-1则不做任何设置
int disable_max_amsdu;
//ampdu_factor - Maximum A-MPDU Length Exponen
//Value: 0-3, see 7.3.2.56.3 in IEEE Std 802.11n-2009.
int ampdu_factor;
/* ampdu_density - Minimum A-MPDU Start Spacing * Value: 0-7, see 7.3.2.56.3 in IEEE Std 802.11n-2009.*/
int ampdu_density;
/* ht_mcs - Allowed HT-MCS rates, in ASCII hex: ffff0000... * By default (empty string): Use whatever the OS has configured.*/
char *ht_mcs;
#endif /* CONFIG_HT_OVERRIDES */
#ifdef CONFIG_VHT_OVERRIDES
/* disable_vht - Disable VHT (束波成型)(IEEE 802.11ac) for this network*/
int disable_vht;
//vht_capa - VHT capabilities to use
unsigned int vht_capa;
//vht_capa_mask - mask for VHT capabilities
unsigned int vht_capa_mask;
int vht_rx_mcs_nss_1, vht_rx_mcs_nss_2,
vht_rx_mcs_nss_3, vht_rx_mcs_nss_4,
vht_rx_mcs_nss_5, vht_rx_mcs_nss_6,
vht_rx_mcs_nss_7, vht_rx_mcs_nss_8;
int vht_tx_mcs_nss_1, vht_tx_mcs_nss_2,
vht_tx_mcs_nss_3, vht_tx_mcs_nss_4,
vht_tx_mcs_nss_5, vht_tx_mcs_nss_6,
vht_tx_mcs_nss_7, vht_tx_mcs_nss_8;
#endif /* CONFIG_VHT_OVERRIDES */
/* ap_max_inactivity - Timeout in seconds to detect STA's inactivity * This timeout value is used in AP mode to clean up inactive stations. * By default: 300 seconds. */
int ap_max_inactivity;
AP模式
/* dtim_period - DTIM period in Beacon intervals * dtim,间隔多个beacon帧中包含tim信息,tim用于通知station AP有其暂存帧 * By default: 2 */
int dtim_period;
//beacon_int - Beacon interval (default: 100 TU)
int beacon_int;
//auth_failures - Number of consecutive authentication failures
unsigned int auth_failures;
// disabled_until - Network block disabled until this time if non-zero
struct os_reltime disabled_until;
void *parent_cred;
int macsec_policy;
//HS20相关,
int update_identifier;
unsigned int wps_run;
}
3. 操作方法
在conf文件中,可以定义3种节点,
wpa_ssid 对应 network ={ }节点:
wpa_cred 对应 cred = { }节点
wpa_config_blob 对应参数blob-base64-,
主要介绍wpas_ssid(network ={ })的作用,其余两个android还没见过
在conf文件中,是按照 项=值 的对应关系对应的,
network ={ }中的项和值得对应关系存储在全局变量数组ssid_fields中
其余的全局设置项存储在global_fields中
3.1 wpa_config_read读取参数
//name----conf文件的路径
//cfgp----之前的config数据
//有两个全局数组比较重要, ssid_fields存放network节点的所有可设置值, global_fields存放搜有conf中全局的可设置项
struct wpa_config * wpa_config_read(const char *name, struct wpa_config *cfgp)
{
//buf存放conf中一行的数据,最长不能超过512
char buf[512], *pos;
//生成一个空的config结构体,里面有一些参数提前设置好默认值
struct wpa_config *config = wpa_config_alloc_empty(NULL, NULL);
//打开文件
FILE *f = fopen(name, "r");
//循环获取文件中一行
while (wpa_config_get_line(buf, sizeof(buf), f, &line, &pos)) {
//network={
if (os_strcmp(pos, "network={") == 0) {
//检测到"network={",进一步读取网络节点的内容
struct wpa_ssid *ssid = wpa_config_read_network(f, &line, id++);
{
//设置网络节点中一些参数的默认值
wpa_config_set_network_defaults(ssid);
//获取每一行的内容,通过‘=’匹配,前面是项名称,后是值
while (wpa_config_get_line(buf, sizeof(buf), f, line, &pos)) {
//int wpa_config_set(struct wpa_ssid *ssid, const char *var, const char *value, int line)
//ssid中对应项的值,ssid_fields全局数组中,定义了每一项的name,获取值方式
wpa_config_set(ssid, pos, pos2, *line)
}
//获取完一个network,对内部的信息进行升级
//1.如果设置了passphrase和psk_set,利用sha1生成wpa psk
wpa_config_validate_network(ssid, *line);
}
//将生成的ssid加入到conf->pssid链表中
wpa_config_add_prio_network(config, ssid)
}
//cred={
else if (os_strcmp(pos, "cred={") == 0) {
cred = wpa_config_read_cred(f, &line, cred_id++);
}
//blob-base64-
else if (os_strncmp(pos, "blob-base64-", 12) == 0) {
if (wpa_config_process_blob(config, f, &line, pos + 12)
}
//获取conf中的全局参数,存储在全局数组global_fields
else if (wpa_config_process_global(config, pos, line) < 0) {
}
}
}
3.2 wpa_config_write写入参数
int wpa_config_write(const char *name, struct wpa_config *config)
{
FILE *f;
//写入全局项
wpa_config_write_global(f, config);
//写入cred节点
for (cred = config->cred; cred; cred = cred->next) {
wpa_config_write_cred(f, cred);
}
//存储network节点
for (ssid = config->ssid; ssid; ssid = ssid->next) {
if (ssid->key_mgmt == WPA_KEY_MGMT_WPS || ssid->temporary)
continue; /* do not save temporary networks */
if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt) && !ssid->psk_set && !ssid->passphrase)
continue; /* do not save invalid network */
wpa_config_write_network(f, ssid);
}
//写入blob值
for (blob = config->blobs; blob; blob = blob->next) {
ret = wpa_config_write_blob(f, blob);
}
}
3.3 wpa_config_add_network添加网络
调用该函数后,会返回一个预先设置好id的ssid指针
struct wpa_ssid * wpa_config_add_network(struct wpa_config *config)
{
//遍历得到config->ssid中最大的id + 1
//生成一个空的ssid节点,并添加到config->ssid链表中
ssid->id = id;
//更新pssid链表
wpa_config_update_prio_list(config);
return ssid;
}
- wpa_config_get_network获取一个network节点
通过id值获取conf->ssid链表的中network元素
struct wpa_ssid * wpa_config_get_network(struct wpa_config *config, int id)
{ struct wpa_ssid *ssid = config->ssid;
while (ssid) {
if (id == ssid->id)
break;
}
3.4wpa_config_remove_network删除一个network节点
通过id值删除network
int wpa_config_remove_network(struct wpa_config *config, int id)
{
//通过获取config->ssid链表中id值匹配的ssid元素
struct wpa_ssid *ssid = config->ssid;
while (ssid) {
if (id == ssid->id)
break;
}
//从链表中删除
//更新pssid列表
wpa_config_update_prio_list(config);
//释放空间
wpa_config_free_ssid(ssid);
}
3.5wpa_config_set设置network中某项的值
//由外部控制 framework或者wpa_cli
int wpa_config_set(struct wpa_ssid *ssid, const char *var, const char *value, int line);