本文为《深入理解Android Wi-Fi、NFC和GPS卷》读书笔记,Android源码为Android 5.1

wpa_supplicant 是一个开源软件项目,它实现了 Station 对无线网络进行管理和控制的功能。
main函数分析

android-5.1/external/wpa_supplicant_8/wpa_supplicant/main.c

int main(int argc, char *argv[])
{int c, i;struct wpa_interface *ifaces, *iface;int iface_count, exitcode = -1;struct wpa_params params;struct wpa_global *global;//Android 平台中, 下面这个函数的实现在 os_unix.c 中。 Android 对其做了一些修改,主要是权限方面的设置防止某些情况下被破解者利用权限漏洞以获取 root 权限if (os_program_init())return -1;os_memset(¶ms, 0, sizeof(params));params.wpa_debug_level = MSG_INFO;iface = ifaces = os_zalloc(sizeof(struct wpa_interface));if (ifaces == NULL)return -1;iface_count = 1;wpa_supplicant_fd_workaround(1);  //输入输出重定向到 /dev/null 设备for (;;) {   //参数解析c = getopt(argc, argv,"b:Bc:C:D:de:f:g:G:hi:I:KLm:No:O:p:P:qsTtuvW");if (c < 0)break;switch (c) {case 'b':iface->bridge_ifname = optarg;break;case 'B':params.daemonize++;break;case 'c'://指定配置文件名。注意,该参数赋值给了 wpa_interface 中的变量iface->confname = optarg;break;case 'C':iface->ctrl_interface = optarg;break;case 'D'://指定 driver 名称iface->driver = optarg;break;case 'd':
#ifdef CONFIG_NO_STDOUT_DEBUGprintf("Debugging disabled with ""CONFIG_NO_STDOUT_DEBUG=y build time ""option.\n");goto out;
#else /* CONFIG_NO_STDOUT_DEBUG */params.wpa_debug_level--;break;
#endif /* CONFIG_NO_STDOUT_DEBUG */case 'e'://指定初始随机数文件,用于后续随机数的生成params.entropy_file = optarg;break;
#ifdef CONFIG_DEBUG_FILEcase 'f':params.wpa_debug_file_path = optarg;break;
#endif /* CONFIG_DEBUG_FILE */case 'g':params.ctrl_interface = optarg;break;case 'G':params.ctrl_interface_group = optarg;break;case 'h':usage();exitcode = 0;goto out;case 'i'://指定网络设备接口名iface->ifname = optarg;break;case 'I':iface->confanother = optarg;break;case 'K':params.wpa_debug_show_keys++;break;case 'L':license();exitcode = 0;goto out;
#ifdef CONFIG_P2Pcase 'm':iface->conf_p2p_dev = optarg;break;
#endif /* CONFIG_P2P */case 'o':params.override_driver = optarg;break;case 'O':params.override_ctrl_interface = optarg;break;case 'p':iface->driver_param = optarg;break;case 'P':os_free(params.pid_file);params.pid_file = os_rel2abs_path(optarg);break;case 'q':params.wpa_debug_level++;break;
#ifdef CONFIG_DEBUG_SYSLOGcase 's':params.wpa_debug_syslog++;break;
#endif /* CONFIG_DEBUG_SYSLOG */
#ifdef CONFIG_DEBUG_LINUX_TRACINGcase 'T':params.wpa_debug_tracing++;break;
#endif /* CONFIG_DEBUG_LINUX_TRACING */case 't':params.wpa_debug_timestamp++;break;
#ifdef CONFIG_DBUScase 'u':params.dbus_ctrl_interface = 1;break;
#endif /* CONFIG_DBUS */case 'v':printf("%s\n", wpa_supplicant_version);exitcode = 0;goto out;case 'W':params.wait_for_monitor++;break;case 'N':iface_count++;iface = os_realloc_array(ifaces, iface_count,sizeof(struct wpa_interface));if (iface == NULL)goto out;ifaces = iface;iface = &ifaces[iface_count - 1]; os_memset(iface, 0, sizeof(*iface));break;default:usage();exitcode = 0;goto out;}}exitcode = 0;//关键函数:根据传入的参数,创建并初始化一个 wpa_global 对象global = wpa_supplicant_init(¶ms);if (global == NULL) {wpa_printf(MSG_ERROR, "Failed to initialize wpa_supplicant");exitcode = -1;goto out;} else {wpa_printf(MSG_INFO, "Successfully initialized ""wpa_supplicant");}for (i = 0; exitcode == 0 && i < iface_count; i++) {struct wpa_supplicant *wpa_s;if ((ifaces[i].confname == NULL &&ifaces[i].ctrl_interface == NULL) ||ifaces[i].ifname == NULL) {if (iface_count == 1 && (params.ctrl_interface ||params.dbus_ctrl_interface))break;usage();exitcode = -1;break;}//WPAS 支持操作多个无线网络设备,此处需将它们一一添加到WPAS中//WPAS 内部将初始化这些设备wpa_s = wpa_supplicant_add_iface(global, &ifaces[i]);if (wpa_s == NULL) {exitcode = -1;break;}
#ifdef CONFIG_P2Pif (wpa_s->global->p2p == NULL &&(wpa_s->drv_flags &WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE) &&wpas_p2p_add_p2pdev_interface(wpa_s, iface->conf_p2p_dev) <0)exitcode = -1;
#endif /* CONFIG_P2P */}//Android 平台中, wpa_supplicant 通过 select 或 epoll 方式实现多路 I/O 复用。if (exitcode == 0)exitcode = wpa_supplicant_run(global);wpa_supplicant_deinit(global);out:wpa_supplicant_fd_workaround(0);os_free(ifaces);os_free(params.pid_file);os_program_deinit();return exitcode;
}

wpa_interface 用于描述一个无线网络设备。
android-5.1/external/wpa_supplicant_8/wpa_supplicant/wpa_supplicant_i.h

struct wpa_interface {/*** confname - Configuration name (file or profile) name** This can also be %NULL when a configuration file is not used. In* that case, ctrl_interface must be set to allow the interface to be* configured.*/const char *confname;/*** ctrl_interface - Control interface parameter** If a configuration file is not used, this variable can be used to* set the ctrl_interface parameter that would have otherwise been read* from the configuration file. If both confname and ctrl_interface are* set, ctrl_interface is used to override the value from configuration* file.*/const char *ctrl_interface;/*** driver - Driver interface name, or %NULL to use the default driver*/const char *driver;/*** driver_param - Driver interface parameters** If a configuration file is not used, this variable can be used to* set the driver_param parameters that would have otherwise been read* from the configuration file. If both confname and driver_param are* set, driver_param is used to override the value from configuration* file.*/const char *driver_param;/*** ifname - Interface name*/const char *ifname;/*** bridge_ifname - Optional bridge interface name** If the driver interface (ifname) is included in a Linux bridge* device, the bridge interface may need to be used for receiving EAPOL* frames. This can be enabled by setting this variable to enable* receiving of EAPOL frames from an additional interface.*/const char *bridge_ifname;
};

wpa_global 是一个全局性质的上下文信息。
android-5.1/external/wpa_supplicant_8/wpa_supplicant/wpa_supplicant_i.h

struct wpa_global {struct wpa_supplicant *ifaces;    //ifaces 变量指向一个 wpa_supplicant 对象。//系统中所有的 wpa_supplicant 对象将通过单项链表连接在一起,所以 ifaces 变量指向一个 wpa_supplicant 对象链表。 struct wpa_params params;struct ctrl_iface_global_priv *ctrl_iface;   //全局控制接口,如果设置该接口,其他 wpa_supplicant 设置的控制接口将被取代struct wpas_dbus_priv *dbus;void **drv_priv;            //drv_priv 包含 driver wrapper 所需要的全局上下文信息。size_t drv_count;          //代表当前编译到系统中的 driver wrapper 个数。struct os_time suspend_time;struct p2p_data *p2p;struct wpa_supplicant *p2p_init_wpa_s;struct wpa_supplicant *p2p_group_formation;u8 p2p_dev_addr[ETH_ALEN];struct dl_list p2p_srv_bonjour; /* struct p2p_srv_bonjour */struct dl_list p2p_srv_upnp; /* struct p2p_srv_upnp */int p2p_disabled;int cross_connection;struct wpa_freq_range *p2p_disallow_freq;unsigned int num_p2p_disallow_freq;enum wpa_conc_pref {WPA_CONC_PREF_NOT_SET,WPA_CONC_PREF_STA,WPA_CONC_PREF_P2P} conc_pref;unsigned int p2p_cb_on_scan_complete:1;#ifdef CONFIG_WIFI_DISPLAYint wifi_display;
#define MAX_WFD_SUBELEMS 10struct wpabuf *wfd_subelem[MAX_WFD_SUBELEMS];
#endif /* CONFIG_WIFI_DISPLAY */
};

wpa_supplicant 是WPAS的核心数据结构。 一个 Interface 对应有一个 wpa_supplicant 对象。

struct wpa_supplicant {struct wpa_global *global;struct wpa_supplicant *parent;struct wpa_supplicant *next;  //系统中所有 wpa_supplicant 对象都通过 next 变量链接在一起struct l2_packet_data *l2;struct l2_packet_data *l2_br;unsigned char own_addr[ETH_ALEN];char ifname[100];
#ifdef CONFIG_CTRL_IFACE_DBUSchar *dbus_path;
#endif /* CONFIG_CTRL_IFACE_DBUS */
#ifdef CONFIG_CTRL_IFACE_DBUS_NEWchar *dbus_new_path;char *dbus_groupobj_path;
#ifdef CONFIG_APchar *preq_notify_peer;
#endif /* CONFIG_AP */
#endif /* CONFIG_CTRL_IFACE_DBUS_NEW */char bridge_ifname[16];char *confname;struct wpa_config *conf;int countermeasures;os_time_t last_michael_mic_error;u8 bssid[ETH_ALEN];u8 pending_bssid[ETH_ALEN]; /* If wpa_state == WPA_ASSOCIATING, this* field contains the target BSSID. */int reassociate; /* reassociation requested */int disconnected; /* all connections disabled; i.e., do no reassociate* before this has been cleared */struct wpa_ssid *current_ssid;struct wpa_bss *current_bss;int ap_ies_from_associnfo;unsigned int assoc_freq;/* Selected configuration (based on Beacon/ProbeResp WPA IE) */int pairwise_cipher;int group_cipher;int key_mgmt;int wpa_proto;int mgmt_group_cipher;void *drv_priv; /* private data used by driver_ops */void *global_drv_priv;u8 *bssid_filter;size_t bssid_filter_count;/* previous scan was wildcard when interleaving between* wildcard scans and specific SSID scan when max_ssids=1 */int prev_scan_wildcard;struct wpa_ssid *prev_scan_ssid; /* previously scanned SSID;* NULL = not yet initialized (start* with wildcard SSID)* WILDCARD_SSID_SCAN = wildcard* SSID was used in the previous scan*/
#define WILDCARD_SSID_SCAN ((struct wpa_ssid *) 1)struct wpa_ssid *prev_sched_ssid; /* last SSID used in sched scan */int sched_scan_timeout;int sched_scan_interval;int first_sched_scan;int sched_scan_timed_out;void (*scan_res_handler)(struct wpa_supplicant *wpa_s,struct wpa_scan_results *scan_res);struct dl_list bss; /* struct wpa_bss::list */struct dl_list bss_id; /* struct wpa_bss::list_id */size_t num_bss;unsigned int bss_update_idx;unsigned int bss_next_id;/** Pointers to BSS entries in the order they were in the last scan* results.*/struct wpa_bss **last_scan_res;unsigned int last_scan_res_used;unsigned int last_scan_res_size;int last_scan_full;struct os_time last_scan;struct wpa_driver_ops *driver;int interface_removed; /* whether the network interface has been* removed */struct wpa_sm *wpa;struct eapol_sm *eapol;struct ctrl_iface_priv *ctrl_iface;enum wpa_states wpa_state;int scanning;int sched_scanning;int new_connection;int reassociated_connection;int eapol_received; /* number of EAPOL packets received after the* previous association event */struct scard_data *scard;
#ifdef PCSC_FUNCSchar imsi[20];int mnc_len;
#endif /* PCSC_FUNCS */unsigned char last_eapol_src[ETH_ALEN];int keys_cleared;struct wpa_blacklist *blacklist;int scan_req; /* manual scan request; this forces a scan even if there* are no enabled networks in the configuration */int scan_runs; /* number of scan runs since WPS was started */int *next_scan_freqs;int scan_interval; /* time in sec between scans to find suitable AP */int normal_scans; /* normal scans run before sched_scan */unsigned int drv_flags;unsigned int drv_enc;/** A bitmap of supported protocols for probe response offload. See* struct wpa_driver_capa in driver.h*/unsigned int probe_resp_offloads;int max_scan_ssids;int max_sched_scan_ssids;int sched_scan_supported;unsigned int max_match_sets;unsigned int max_remain_on_chan;unsigned int max_stations;int pending_mic_error_report;int pending_mic_error_pairwise;int mic_errors_seen; /* Michael MIC errors with the current PTK */struct wps_context *wps;int wps_success; /* WPS success event received */struct wps_er *wps_er;int blacklist_cleared;struct wpabuf *pending_eapol_rx;struct os_time pending_eapol_rx_time;u8 pending_eapol_rx_src[ETH_ALEN];struct ibss_rsn *ibss_rsn;int set_sta_uapsd;int sta_uapsd;int set_ap_uapsd;int ap_uapsd;#ifdef CONFIG_SMEstruct {u8 ssid[32];size_t ssid_len;int freq;u8 assoc_req_ie[200];size_t assoc_req_ie_len;int mfp;int ft_used;u8 mobility_domain[2];u8 *ft_ies;size_t ft_ies_len;u8 prev_bssid[ETH_ALEN];int prev_bssid_set;int auth_alg;int proto;int sa_query_count; /* number of pending SA Query requests;* 0 = no SA Query in progress */int sa_query_timed_out;u8 *sa_query_trans_id; /* buffer of WLAN_SA_QUERY_TR_ID_LEN ** sa_query_count octets of pending* SA Query transaction identifiers */struct os_time sa_query_start;u8 sched_obss_scan;u16 obss_scan_int;u16 bss_max_idle_period;} sme;
#endif /* CONFIG_SME */#ifdef CONFIG_APstruct hostapd_iface *ap_iface;void (*ap_configured_cb)(void *ctx, void *data);void *ap_configured_cb_ctx;void *ap_configured_cb_data;
#endif /* CONFIG_AP */unsigned int off_channel_freq;struct wpabuf *pending_action_tx;u8 pending_action_src[ETH_ALEN];u8 pending_action_dst[ETH_ALEN];u8 pending_action_bssid[ETH_ALEN];unsigned int pending_action_freq;int pending_action_no_cck;int pending_action_without_roc;void (*pending_action_tx_status_cb)(struct wpa_supplicant *wpa_s,unsigned int freq, const u8 *dst,const u8 *src, const u8 *bssid,const u8 *data, size_t data_len,enum offchannel_send_action_resultresult);unsigned int roc_waiting_drv_freq;int action_tx_wait_time;#ifdef CONFIG_P2Pstruct p2p_go_neg_results *go_params;int create_p2p_iface;u8 pending_interface_addr[ETH_ALEN];char pending_interface_name[100];int pending_interface_type;int p2p_group_idx;unsigned int pending_listen_freq;unsigned int pending_listen_duration;enum {NOT_P2P_GROUP_INTERFACE,P2P_GROUP_INTERFACE_PENDING,P2P_GROUP_INTERFACE_GO,P2P_GROUP_INTERFACE_CLIENT} p2p_group_interface;struct p2p_group *p2p_group;int p2p_long_listen; /* remaining time in long Listen state in ms */char p2p_pin[10];int p2p_wps_method;u8 p2p_auth_invite[ETH_ALEN];int p2p_sd_over_ctrl_iface;int p2p_in_provisioning;int pending_invite_ssid_id;int show_group_started;u8 go_dev_addr[ETH_ALEN];int pending_pd_before_join;u8 pending_join_iface_addr[ETH_ALEN];u8 pending_join_dev_addr[ETH_ALEN];int pending_join_wps_method;int p2p_join_scan_count;int auto_pd_scan_retry;int force_long_sd;u16 pending_pd_config_methods;enum {NORMAL_PD, AUTO_PD_GO_NEG, AUTO_PD_JOIN} pending_pd_use;/** Whether cross connection is disallowed by the AP to which this* interface is associated (only valid if there is an association).*/int cross_connect_disallowed;/** Whether this P2P group is configured to use cross connection (only* valid if this is P2P GO interface). The actual cross connect packet* forwarding may not be configured depending on the uplink status.*/int cross_connect_enabled;/* Whether cross connection forwarding is in use at the moment. */int cross_connect_in_use;/** Uplink interface name for cross connection*/char cross_connect_uplink[100];unsigned int sta_scan_pending:1;unsigned int p2p_auto_join:1;unsigned int p2p_auto_pd:1;unsigned int p2p_persistent_group:1;unsigned int p2p_fallback_to_go_neg:1;unsigned int p2p_pd_before_go_neg:1;unsigned int p2p_go_ht40:1;int p2p_persistent_go_freq;int p2p_persistent_id;int p2p_go_intent;int p2p_connect_freq;struct os_time p2p_auto_started;
#endif /* CONFIG_P2P */struct wpa_ssid *bgscan_ssid;const struct bgscan_ops *bgscan;void *bgscan_priv;const struct autoscan_ops *autoscan;struct wpa_driver_scan_params *autoscan_params;void *autoscan_priv;struct wpa_ssid *connect_without_scan;struct wps_ap_info *wps_ap;size_t num_wps_ap;int wps_ap_iter;int after_wps;int known_wps_freq;unsigned int wps_freq;int wps_fragment_size;int auto_reconnect_disabled;/* Channel preferences for AP/P2P GO use */int best_24_freq;int best_5_freq;int best_overall_freq;struct gas_query *gas;#ifdef CONFIG_INTERWORKINGunsigned int fetch_anqp_in_progress:1;unsigned int network_select:1;unsigned int auto_select:1;unsigned int auto_network_select:1;unsigned int fetch_all_anqp:1;
#endif /* CONFIG_INTERWORKING */unsigned int drv_capa_known;struct {struct hostapd_hw_modes *modes;u16 num_modes;u16 flags;} hw;int pno;/* WLAN_REASON_* reason codes. Negative if locally generated. */int disconnect_reason;struct ext_password_data *ext_pw;struct wpabuf *last_gas_resp;u8 last_gas_addr[ETH_ALEN];u8 last_gas_dialog_token;
};
struct ctrl_iface_global_priv {int sock; //用于通信的 socket 句柄u8 cookie[COOKIE_LEN];
};

深入理解 wpa_supplicant(一)相关推荐

  1. 深入理解wpa_supplicant

    转自:http://blog.csdn.net/innost/article/details/20862875 先感谢各位兄弟姐妹们的耐心等待.本书预计在3月中旬上市发售.从今天开始,我将在博客中连载 ...

  2. 深入理解 wpa_supplicant(四)

    本文为<深入理解Android Wi-Fi.NFC和GPS卷>读书笔记,Android源码为Android 5.1 android-5.1/external/wpa_supplicant_ ...

  3. 深入理解 wpa_supplicant(三)

    本文为<深入理解Android Wi-Fi.NFC和GPS卷>读书笔记,Android源码为Android 5.1 android-5.1/external/wpa_supplicant_ ...

  4. 深入理解 wpa_supplicant(二)

    本文为<深入理解Android Wi-Fi.NFC和GPS卷>读书笔记,Android源码为Android 5.1 struct wpa_global * wpa_supplicant_i ...

  5. Android wifi探究一:初步认识wpa_supplicant与wifi框架梳理

    http://blog.csdn.net/u011913612/article/details/52671436 平时和wifi打交道还算比较多吧,wifi出了问题就只能找大神解决,这是件很令人伤感的 ...

  6. [转载]Android wifi探究一:初步认识wpa_supplicant与wifi框架梳理

    平时和wifi打交道还算比较多吧,wifi出了问题就只能找大神解决,这是件很令人伤感的事情.所以就想自己分析下android源码中wifi的框架,以后wifi出了问题,自己也能尝试的解一解.分析过程必 ...

  7. cmd泛滥_与您的后泛滥同事见面:人工智能机器人

    cmd泛滥 Ready to swap your old cube-mate for a disembodied AI? IPsoft CEO Chetan Dube, creator of AI c ...

  8. 3.1-3.31推荐文章汇总

    3.1-3.31推荐文章汇总 [Eclipse AST]AST的创建   刘伟 Android WebKit HTML主资源加载过程   谭海燕 HTML5物理游戏开发 - 越野山地自行车(一)建立各 ...

  9. wpa_supplicant源码理解

    目录 1.配置文件: wpa_config 和 wpa_ssid结构 2.wpa_supplicant的目录介绍 1.配置文件: wpa_config 和 wpa_ssid结构 wpa_supplic ...

最新文章

  1. wpf学习笔记---初识xaml标签语言
  2. 组件skype服务器,Skype for Business Server 中的中介服务器组件
  3. 击败李世石后,人工智能转战医疗:用大数据诊断眼科疾病
  4. 关于SPECjAppServer评测,您应该知道的“故事”
  5. Hadoop入门基础教程 Hadoop之完全分布式环境搭建
  6. P60 ---AI 在P60 上的人应用
  7. Vmware虚拟机修改静态IP无法ping外网,以及eth0不见问题解决
  8. 转:WCF基础知识问与答
  9. 宽字符与Unicode
  10. windbg远程调试方法
  11. XCode5 文档下载地址
  12. 新西兰皇后镇-我眼中的西施
  13. 【NLP】自然语言处理的中间序列建模
  14. 笔记本过热、电脑cpu过热、限制CPU运行功率上限,轻松设置解决过热
  15. 细品这杯香浓的咖啡——阿里中间件高级专家沈询的Java之旅
  16. 8大蓝牙电路应用热门方案,快速简单实现近距离无线连接
  17. 如何设置跨网段共享打印机?
  18. Long和Integer相互转换
  19. 在培训机构花了好几万学Java,当了程序员还常被鄙视,这是招谁惹谁了?
  20. 《大道至简》第一章 编程的精义 伪代码

热门文章

  1. legend位置 pyecharts_实验|pyecharts数据可视化分析-1
  2. Android 获取手机系统信息
  3. Hibernate框架第二天
  4. jquery 实现Json节点的增删改查
  5. ActiveMQ—Queue与Topic区别
  6. SpringMVC工作环境搭建 配置文件
  7. 做技术到底可以做到哪种地步-技术为什么越走越窄 (转)
  8. Android——学习:线性布局权重分配
  9. JavaScript深拷贝Json
  10. OpenCV+python:霍夫变换与直线检测