wpa_supplicant-0.8源码解析
2015-11-06 17:23
711 查看
启动命令:wpa_supplicant -Dwext -iwlan0 -c /var/wpa_supplicant/wpa_supplicant.conf
创建了四个socket:
1. src/drivers/driver_wext.c -> wpa_driver_wext_init() -> drv->ioctl_sock =
socket(PF_INET, SOCK_DGRAM, 0)
2. src/drivers/netlink.c -> netlink_init() -> netlink->sock = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE)
3. src/l2_packet/l2_packet_linux.c -> l2_packet_init() -> l2->fd = socket(PF_PACKET, l2_hdr ? SOCK_RAW : SOCK_DGRAM, htons(protocol))
4. ctrl_iface_unix.c -> wpa_supplicant_ctrl_iface_init() -> priv->sock =
socket(PF_UNIX, SOCK_DGRAM, 0)
通过ioctl设置驱动参数:
【启动】
main()
global = wpa_supplicant_init(¶ms)
eap_register_methods()
eap_peer_wsc_register() // 注册EAP-WSC方法
struct eap_method *eap
eap = eap_peer_method_alloc("WSC")
eap->init = eap_wsc_init
eap_wsc_init(struct eap_sm *sm) 完成EAP状态机的初始化
eap->deinit = eap_wsc_deinit
eap->process = eap_wsc_process
eap_wsc_process() 处理接收到的WSC包
eap_peer_method_register(eap)
eloop_init()
random_init()
wpa_supplicant_global_ctrl_iface_init(global)
wpas_notify_supplicant_initialized(global)
global->drv_priv[i] = wpa_drivers[i]->global_init()
for (i = 0; exitcode == 0 && i < iface_count; i++)
wpa_supplicant_add_iface(global, &ifaces[i])
wpa_s = wpa_supplicant_alloc()
wpa_supplicant_init_iface(wpa_s, &t_iface)
wpa_s->conf = wpa_config_read(wpa_s->confname) /* 读配置文件 */
wpa_config_read_network() /* 解析network配置 */
wpa_config_process_global() /* 解析全局变量配置 */
wpa_supplicant_set_driver(wpa_s, driver) /* 设置diver接口函数 */
wpa_s->driver = wpa_drivers[i]
wpa_drv_init(wpa_s, wpa_s->ifname)
wpa_s->driver->init(wpa_s, ifname)
wpa_driver_wext_init()
/* 创建ioctl socket,用来设置驱动参数 */
drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0)
/* 创建netlink socket,用来监听内核事件,并注册到eloop */
drv->netlink = netlink_init(cfg)
netlink->sock = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE)
eloop_register_read_sock()
wpa_driver_wext_finish_drv_init()
linux_set_iface_flags(drv->ioctl_sock, drv->ifname, 1)
ioctl(sock,SIOCGIFFLAGS, &ifr)
ioctl(sock,SIOCSIFFLAGS, &ifr)
wpa_driver_wext_flush_pmkid(drv)
wpa_driver_wext_pmksa(drv, IW_PMKSA_FLUSH, NULL, NULL)
ioctl(drv->ioctl_sock,SIOCSIWPMKSA, &iwr)
wpa_driver_wext_set_mode(drv, 0)
ioctl(drv->ioctl_sock,SIOCSIWMODE, &iwr)
wpa_driver_wext_get_range(drv)
ioctl(drv->ioctl_sock,SIOCGIWRANGE, &iwr)
wpa_driver_wext_disconnect(drv)
ioctl(drv->ioctl_sock,SIOCGIWMODE, &iwr)
wpa_driver_wext_set_bssid(drv, null_bssid)
ioctl(drv->ioctl_sock,SIOCSIWAP, &iwr)
netlink_send_oper_ifla(drv->netlink, drv->ifindex, 1, IF_OPER_DORMANT)
ret = send(netlink->sock, &req, req.hdr.nlmsg_len, 0)
wpa_driver_wext_set_auth_param(drv, IW_AUTH_WPA_ENABLED, 1)
ioctl(drv->ioctl_sock,SIOCSIWAUTH, &iwr)
wpa_drv_set_param(wpa_s, wpa_s->conf->driver_param)
ifname = wpa_drv_get_ifname(wpa_s)
wpa_supplicant_init_wpa(wpa_s)
ctx = os_zalloc(sizeof(*ctx))
wpa_s->wpa =
wpa_sm_init(ctx) // 申请WPA SM内存
wpa_supplicant_driver_init(wpa_s)
/* 创建RAW socket,用来监听EAPOL帧,并注册到eloop,callback函数rtl871x_handle_read */
wpa_s->l2 = l2_packet_init(wpa_s->ifname,
wpa_drv_get_mac_addr(wpa_s),
ETH_P_EAPOL,
wpa_supplicant_rx_eapol,
wpa_s, 0)
l2->fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_EAPOL))
ioctl(l2->fd,SIOCGIFINDEX, &ifr)
ioctl(l2->fd,SIOCGIFHWADDR, &ifr)
eloop_register_read_sock()
wpa_clear_keys(wpa_s, NULL)
wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 0, 0, NULL, 0, NULL, 0)
wpa_s->driver->set_key() -> wpa_driver_wext_set_key()
wpa_driver_wext_set_key_ext()
ioctl(drv->ioctl_sock,SIOCSIWENCODEEXT, &iwr)
wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 1, 0, NULL, 0, NULL, 0)
wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 2, 0, NULL, 0, NULL, 0)
wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 3, 0, NULL, 0, NULL, 0)
wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 4, 0, NULL, 0, NULL, 0)
wpa_drv_set_countermeasures(wpa_s, 0)
wpa_s->driver->set_countermeasures() -> wpa_driver_wext_set_countermeasures()
wpa_driver_wext_set_auth_param()
ioctl(drv->ioctl_sock,SIOCSIWAUTH, &iwr)
wpa_drv_flush_pmkid(wpa_s)
wpa_s->driver->flush_pmkid() -> wpa_driver_wext_flush_pmkid()
wpa_driver_wext_pmksa()
ioctl(drv->ioctl_sock,SIOCSIWPMKSA, &iwr)
wpa_supplicant_req_scan(wpa_s, interface_count, 100000) // 发起SSID的扫描
eloop_is_timeout_registered(wpa_supplicant_scan, wpa_s, NULL)
eloop_cancel_timeout(wpa_supplicant_scan, wpa_s, NULL)
eloop_register_timeout(sec, usec, wpa_supplicant_scan, wpa_s, NULL)
/* 初始化WPS */
wpas_wps_init(wpa_s)
wps = os_zalloc(sizeof(*wps))
wps->cred_cb = wpa_supplicant_wps_cred // cred_cb在EAP-WSC模块解析credential属性集时使用
wps->event_cb = wpa_supplicant_wps_event // event_cb用于通知WSC模块发生的一些事件
wpas_wps_set_uuid(wpa_s, wps)
uuid_gen_mac_addr(wpa_s->own_addr, wps->uuid)
rcfg.pin_needed_cb = wpas_wps_pin_needed_cb
wps->registrar = wps_registrar_init(wps, &rcfg)
struct wps_registrar *reg = os_zalloc(sizeof(*reg))
reg->pin_needed_cb = cfg->pin_needed_cb
wps_set_ie(reg)
wpa_supplicant_init_eapol(wpa_s)
ctx = os_zalloc(sizeof(*ctx))
ctx->eapol_send = wpa_supplicant_eapol_send
ctx->port_cb = wpa_supplicant_port_cb
ctx->cb = wpa_supplicant_eapol_cb
wpa_s->eapol =
eapol_sm_init(ctx) // 申请EAPOL SM内存
sm = os_zalloc(sizeof(*sm))
sm->ctx = ctx
sm->eap =
eap_peer_sm_init(sm, &eapol_cb, sm->ctx->msg_ctx, &conf) // 申请EAP SM内存
sm = os_zalloc(sizeof(*sm))
eloop_register_timeout(1, 0, eapol_port_timers_tick, NULL, sm)
wpa_sm_set_eapol(wpa_s->wpa, wpa_s->eapol)
wpa_supplicant_ctrl_iface_init(wpa_s)
wpas_p2p_init(wpa_s->global, wpa_s)
wpa_bss_init(wpa_s)
wpas_notify_iface_added(wpa_s)
wpas_notify_network_added(wpa_s, ssid)
wpa_supplicant_run(global)
eloop_register_signal_terminate(wpa_supplicant_terminate, global)
eloop_register_signal_reconfig(wpa_supplicant_reconfig, global)
eloop_run()
How to Compile WPA_SUPPLICANT wit Wi-Fi Direct Support on Ubuntu 12.04/13.04/13.10/14.04
What is WPA_SUPPLICANT ?
wpa_supplicant is a daemon for wireless connection management on Andorid/Linux OS. You can check your laptop running will be using wpa_supplicant in background.
ps -aef | grep wpa_supplicant
Download
mkdir -p ~/work; cd ~/work;
wget http://hostap.epitest.fi/releases/wpa_supplicant-2.1.tar.gz
tar zxvf wpa_supplicant-2.1.tar.gz
cd wpa_supplicant-2.1/
cd wpa_supplicant/
Build Environment
Install compilations utilities such as gcc, make etc.
sudo apt-get update
sudo apt-get -y build-dep gcc-4.6 build-essential
P2P Configuration
cp defconfig .config
echo “” >> .config
echo “#Arun Kumar: Enabling Modules for Wi-Fi Direct aka P2P” >> .config
echo CONFIG_P2P=y >> .config
echo CONFIG_AP=y >> .config
echo CONFIG_WPS=y >> .config
Compilation & Installation
make
You may or may not get errors while compiling the source codes.I have faced following compilation errors and given corresponding solutions for the same as follows
Error#1
CC ../src/drivers/driver_wired.c
../src/drivers/driver_nl80211.c:25:31: fatal error: netlink/genl/genl.h: No such file or directory
compilation terminated.
make: *** [../src/drivers/driver_nl80211.o] Error 1
Solution #1
sudo apt-get -y install libssl-dev libnl-3-dev
echo CFLAGS +=-I/usr/include/libnl3/ >> .config
make
Error#2
../src/drivers/driver_nl80211.c:95:9: warning: passing argument 1 of ‘genl_ctrl_alloc_cache’ from incompatible pointer type [enabled by default]
/usr/include/libnl3/netlink/genl/ctrl.h:25:14: note: expected ‘struct nl_sock *’ but argument is of type ‘struct nl_handle *’
../src/drivers/driver_nl80211.c:95:9: error: too few arguments to function ‘genl_ctrl_alloc_cache’
/usr/include/libnl3/netlink/genl/ctrl.h:25:14: note: declared here
Solution #2
sudo apt-get install libnl-genl-3-dev
echo CONFIG_LIBNL32=y >> .config
make
Now compilation succeeded.
wpa_supplicant is really compiled
tulashi@arunx:~/work/wpa_supplicant-2.1/wpa_supplicant$ file wpa_supplicant
wpa_supplicant: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=0xd69c0b4bbafd67e19dfc86a66bfffdd10c2e2de8, not stripped
创建了四个socket:
1. src/drivers/driver_wext.c -> wpa_driver_wext_init() -> drv->ioctl_sock =
socket(PF_INET, SOCK_DGRAM, 0)
2. src/drivers/netlink.c -> netlink_init() -> netlink->sock = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE)
3. src/l2_packet/l2_packet_linux.c -> l2_packet_init() -> l2->fd = socket(PF_PACKET, l2_hdr ? SOCK_RAW : SOCK_DGRAM, htons(protocol))
4. ctrl_iface_unix.c -> wpa_supplicant_ctrl_iface_init() -> priv->sock =
socket(PF_UNIX, SOCK_DGRAM, 0)
通过ioctl设置驱动参数:
【启动】
main()
global = wpa_supplicant_init(¶ms)
eap_register_methods()
eap_peer_wsc_register() // 注册EAP-WSC方法
struct eap_method *eap
eap = eap_peer_method_alloc("WSC")
eap->init = eap_wsc_init
eap_wsc_init(struct eap_sm *sm) 完成EAP状态机的初始化
eap->deinit = eap_wsc_deinit
eap->process = eap_wsc_process
eap_wsc_process() 处理接收到的WSC包
eap_peer_method_register(eap)
eloop_init()
random_init()
wpa_supplicant_global_ctrl_iface_init(global)
wpas_notify_supplicant_initialized(global)
global->drv_priv[i] = wpa_drivers[i]->global_init()
for (i = 0; exitcode == 0 && i < iface_count; i++)
wpa_supplicant_add_iface(global, &ifaces[i])
wpa_s = wpa_supplicant_alloc()
wpa_supplicant_init_iface(wpa_s, &t_iface)
wpa_s->conf = wpa_config_read(wpa_s->confname) /* 读配置文件 */
wpa_config_read_network() /* 解析network配置 */
wpa_config_process_global() /* 解析全局变量配置 */
wpa_supplicant_set_driver(wpa_s, driver) /* 设置diver接口函数 */
wpa_s->driver = wpa_drivers[i]
wpa_drv_init(wpa_s, wpa_s->ifname)
wpa_s->driver->init(wpa_s, ifname)
wpa_driver_wext_init()
/* 创建ioctl socket,用来设置驱动参数 */
drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0)
/* 创建netlink socket,用来监听内核事件,并注册到eloop */
drv->netlink = netlink_init(cfg)
netlink->sock = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE)
eloop_register_read_sock()
wpa_driver_wext_finish_drv_init()
linux_set_iface_flags(drv->ioctl_sock, drv->ifname, 1)
ioctl(sock,SIOCGIFFLAGS, &ifr)
ioctl(sock,SIOCSIFFLAGS, &ifr)
wpa_driver_wext_flush_pmkid(drv)
wpa_driver_wext_pmksa(drv, IW_PMKSA_FLUSH, NULL, NULL)
ioctl(drv->ioctl_sock,SIOCSIWPMKSA, &iwr)
wpa_driver_wext_set_mode(drv, 0)
ioctl(drv->ioctl_sock,SIOCSIWMODE, &iwr)
wpa_driver_wext_get_range(drv)
ioctl(drv->ioctl_sock,SIOCGIWRANGE, &iwr)
wpa_driver_wext_disconnect(drv)
ioctl(drv->ioctl_sock,SIOCGIWMODE, &iwr)
wpa_driver_wext_set_bssid(drv, null_bssid)
ioctl(drv->ioctl_sock,SIOCSIWAP, &iwr)
netlink_send_oper_ifla(drv->netlink, drv->ifindex, 1, IF_OPER_DORMANT)
ret = send(netlink->sock, &req, req.hdr.nlmsg_len, 0)
wpa_driver_wext_set_auth_param(drv, IW_AUTH_WPA_ENABLED, 1)
ioctl(drv->ioctl_sock,SIOCSIWAUTH, &iwr)
wpa_drv_set_param(wpa_s, wpa_s->conf->driver_param)
ifname = wpa_drv_get_ifname(wpa_s)
wpa_supplicant_init_wpa(wpa_s)
ctx = os_zalloc(sizeof(*ctx))
wpa_s->wpa =
wpa_sm_init(ctx) // 申请WPA SM内存
wpa_supplicant_driver_init(wpa_s)
/* 创建RAW socket,用来监听EAPOL帧,并注册到eloop,callback函数rtl871x_handle_read */
wpa_s->l2 = l2_packet_init(wpa_s->ifname,
wpa_drv_get_mac_addr(wpa_s),
ETH_P_EAPOL,
wpa_supplicant_rx_eapol,
wpa_s, 0)
l2->fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_EAPOL))
ioctl(l2->fd,SIOCGIFINDEX, &ifr)
ioctl(l2->fd,SIOCGIFHWADDR, &ifr)
eloop_register_read_sock()
wpa_clear_keys(wpa_s, NULL)
wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 0, 0, NULL, 0, NULL, 0)
wpa_s->driver->set_key() -> wpa_driver_wext_set_key()
wpa_driver_wext_set_key_ext()
ioctl(drv->ioctl_sock,SIOCSIWENCODEEXT, &iwr)
wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 1, 0, NULL, 0, NULL, 0)
wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 2, 0, NULL, 0, NULL, 0)
wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 3, 0, NULL, 0, NULL, 0)
wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 4, 0, NULL, 0, NULL, 0)
wpa_drv_set_countermeasures(wpa_s, 0)
wpa_s->driver->set_countermeasures() -> wpa_driver_wext_set_countermeasures()
wpa_driver_wext_set_auth_param()
ioctl(drv->ioctl_sock,SIOCSIWAUTH, &iwr)
wpa_drv_flush_pmkid(wpa_s)
wpa_s->driver->flush_pmkid() -> wpa_driver_wext_flush_pmkid()
wpa_driver_wext_pmksa()
ioctl(drv->ioctl_sock,SIOCSIWPMKSA, &iwr)
wpa_supplicant_req_scan(wpa_s, interface_count, 100000) // 发起SSID的扫描
eloop_is_timeout_registered(wpa_supplicant_scan, wpa_s, NULL)
eloop_cancel_timeout(wpa_supplicant_scan, wpa_s, NULL)
eloop_register_timeout(sec, usec, wpa_supplicant_scan, wpa_s, NULL)
/* 初始化WPS */
wpas_wps_init(wpa_s)
wps = os_zalloc(sizeof(*wps))
wps->cred_cb = wpa_supplicant_wps_cred // cred_cb在EAP-WSC模块解析credential属性集时使用
wps->event_cb = wpa_supplicant_wps_event // event_cb用于通知WSC模块发生的一些事件
wpas_wps_set_uuid(wpa_s, wps)
uuid_gen_mac_addr(wpa_s->own_addr, wps->uuid)
rcfg.pin_needed_cb = wpas_wps_pin_needed_cb
wps->registrar = wps_registrar_init(wps, &rcfg)
struct wps_registrar *reg = os_zalloc(sizeof(*reg))
reg->pin_needed_cb = cfg->pin_needed_cb
wps_set_ie(reg)
wpa_supplicant_init_eapol(wpa_s)
ctx = os_zalloc(sizeof(*ctx))
ctx->eapol_send = wpa_supplicant_eapol_send
ctx->port_cb = wpa_supplicant_port_cb
ctx->cb = wpa_supplicant_eapol_cb
wpa_s->eapol =
eapol_sm_init(ctx) // 申请EAPOL SM内存
sm = os_zalloc(sizeof(*sm))
sm->ctx = ctx
sm->eap =
eap_peer_sm_init(sm, &eapol_cb, sm->ctx->msg_ctx, &conf) // 申请EAP SM内存
sm = os_zalloc(sizeof(*sm))
eloop_register_timeout(1, 0, eapol_port_timers_tick, NULL, sm)
wpa_sm_set_eapol(wpa_s->wpa, wpa_s->eapol)
wpa_supplicant_ctrl_iface_init(wpa_s)
wpas_p2p_init(wpa_s->global, wpa_s)
wpa_bss_init(wpa_s)
wpas_notify_iface_added(wpa_s)
wpas_notify_network_added(wpa_s, ssid)
wpa_supplicant_run(global)
eloop_register_signal_terminate(wpa_supplicant_terminate, global)
eloop_register_signal_reconfig(wpa_supplicant_reconfig, global)
eloop_run()
wpa_suplicant配置文件 ------------------------------------------------------------------ ctrl_interface=/var/run/wpa_supplicant update_config=1 uuid=109fa92f-1b8b-0000-0000-000000000000 device_name=1B8B manufacturer=ABC model_name=123 model_number=456 serial_number=12345 device_type=8-00101101-5 os_version=80000000 config_methods=virtual_display virtual_push_button keypad network={ ssid="DIRECT-ITDESKTOP-5VBHCUA3151" bssid=0e:8b:fd:e5:1b:50 psk=b3e0502a0e27d0bbb4c1de0ac058aeb44914598e55ba7a795562f1ec783a7460 proto=RSN key_mgmt=WPA-PSK auth_alg=OPEN } ------------------------------------------
How to Compile WPA_SUPPLICANT wit Wi-Fi Direct Support on Ubuntu 12.04/13.04/13.10/14.04
What is WPA_SUPPLICANT ?
wpa_supplicant is a daemon for wireless connection management on Andorid/Linux OS. You can check your laptop running will be using wpa_supplicant in background.
ps -aef | grep wpa_supplicant
Download
mkdir -p ~/work; cd ~/work;
wget http://hostap.epitest.fi/releases/wpa_supplicant-2.1.tar.gz
tar zxvf wpa_supplicant-2.1.tar.gz
cd wpa_supplicant-2.1/
cd wpa_supplicant/
Build Environment
Install compilations utilities such as gcc, make etc.
sudo apt-get update
sudo apt-get -y build-dep gcc-4.6 build-essential
P2P Configuration
cp defconfig .config
echo “” >> .config
echo “#Arun Kumar: Enabling Modules for Wi-Fi Direct aka P2P” >> .config
echo CONFIG_P2P=y >> .config
echo CONFIG_AP=y >> .config
echo CONFIG_WPS=y >> .config
Compilation & Installation
make
You may or may not get errors while compiling the source codes.I have faced following compilation errors and given corresponding solutions for the same as follows
Error#1
CC ../src/drivers/driver_wired.c
../src/drivers/driver_nl80211.c:25:31: fatal error: netlink/genl/genl.h: No such file or directory
compilation terminated.
make: *** [../src/drivers/driver_nl80211.o] Error 1
Solution #1
sudo apt-get -y install libssl-dev libnl-3-dev
echo CFLAGS +=-I/usr/include/libnl3/ >> .config
make
Error#2
../src/drivers/driver_nl80211.c:95:9: warning: passing argument 1 of ‘genl_ctrl_alloc_cache’ from incompatible pointer type [enabled by default]
/usr/include/libnl3/netlink/genl/ctrl.h:25:14: note: expected ‘struct nl_sock *’ but argument is of type ‘struct nl_handle *’
../src/drivers/driver_nl80211.c:95:9: error: too few arguments to function ‘genl_ctrl_alloc_cache’
/usr/include/libnl3/netlink/genl/ctrl.h:25:14: note: declared here
Solution #2
sudo apt-get install libnl-genl-3-dev
echo CONFIG_LIBNL32=y >> .config
make
Now compilation succeeded.
wpa_supplicant is really compiled
tulashi@arunx:~/work/wpa_supplicant-2.1/wpa_supplicant$ file wpa_supplicant
wpa_supplicant: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=0xd69c0b4bbafd67e19dfc86a66bfffdd10c2e2de8, not stripped
相关文章推荐
- 普通人
- java 实现连接池(mysql中,linux里面修改)
- ios多线程死锁解析
- 大道至简第六章。感受。
- Python核心编程读笔 2
- 简单选择排序
- 原创视频|手把手教你用Axure做一个微信高保真原型(一)
- ASP.NET常用的指令
- vi编辑器的使用方法
- 迭代器被设计成每次仅由一个线程使用。
- JQuery开发工具和插件
- 安卓 简单的ViewPager 滑屏
- linux apache服务器配置虚拟主机
- JPush中open Notification的不同通知跳转不同页面的处理
- 设计模式:备忘录模式扩展
- word文档标题级别批量更改——批量降级与升级实例
- AngularJS开发指南02:引导程序
- 联合体相关
- 使用Python调用R(一、环境搭建)
- ZooKeeper监控