日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

wpa_supplicant与kernel的接口

發布時間:2025/4/16 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 wpa_supplicant与kernel的接口 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

2019獨角獸企業重金招聘Python工程師標準>>>

1. 接口定義實現wpa_drivers

?

??wpa_drivers的定義如下:

[cpp]?view plaincopy

  • struct?wpa_driver_ops?*wpa_drivers[]?=??

  • {??

  • #ifdef?CONFIG_DRIVER_WEXT??

  • ????&wpa_driver_wext_ops,??//?我的系統使用的這個老的接口??

  • #endif???

  • #ifdef?CONFIG_DRIVER_NL80211???//?現在流行的NL80211接口??

  • ????&wpa_driver_nl80211_ops,??

  • #endif???

  • #ifdef?CONFIG_DRIVER_HOSTAP??

  • ????&wpa_driver_hostap_ops,??

  • #endif???

  • #ifdef?CONFIG_DRIVER_MADWIFI??

  • ????&wpa_driver_madwifi_ops,??

  • #endif???

  • #ifdef?CONFIG_DRIVER_BROADCOM??

  • ????&wpa_driver_broadcom_ops,??

  • #endif???

  • #ifdef?CONFIG_DRIVER_BSD??

  • ????&wpa_driver_bsd_ops,??

  • #endif???

  • #ifdef?CONFIG_DRIVER_NDIS??

  • ????&wpa_driver_ndis_ops,??

  • #endif???

  • #ifdef?CONFIG_DRIVER_WIRED??

  • ????&wpa_driver_wired_ops,??

  • #endif???

  • #ifdef?CONFIG_DRIVER_TEST??

  • ????&wpa_driver_test_ops,??

  • #endif???

  • #ifdef?CONFIG_DRIVER_RALINK??

  • ????&wpa_driver_ralink_ops,??

  • #endif???

  • #ifdef?CONFIG_DRIVER_OSX??

  • ????&wpa_driver_osx_ops,??

  • #endif???

  • #ifdef?CONFIG_DRIVER_IPHONE??

  • ????&wpa_driver_iphone_ops,??

  • #endif???

  • #ifdef?CONFIG_DRIVER_ROBOSWITCH??

  • ????&wpa_driver_roboswitch_ops,??

  • #endif???

  • #ifdef?CONFIG_DRIVER_ATHEROS??

  • ????&wpa_driver_atheros_ops,??

  • #endif???

  • #ifdef?CONFIG_DRIVER_NONE??

  • ????&wpa_driver_none_ops,??

  • #endif???

  • ????NULL??

  • }; ?

  • ???具體選擇哪一個driver,由wpa_supplicant的命令參數決定,如我的如下:
    ???在init.myboard.rc中定義:

    ?

    [cpp]?view plaincopy

  • service?wpa_supplicant?/system/bin/wpa_supplicant?\??

  • ????-Dwext?-iwlan0?-c/data/misc/wifi/wpa_supplicant.conf??

  • ????#-Dnl80211?-iwlan0?-puse_p2p_group_interface=1?-e/data/misc/wifi/entropy.bin??

  • ????#???we?will?start?as?root?and?wpa_supplicant?will?switch?to?user?wifi??

  • ????#???after?setting?up?the?capabilities?required?for?WEXT??

  • ????#???user?wifi??

  • ????#???group?wifi?inet?keystore??

  • ????class?main??

  • ????socket?wpa_wlan0?dgram?660?wifi?wifi??

  • ????disabled??

  • ????oneshot ?

  • ???由上可見,我的選擇是wext, 即選擇了:wpa_driver_wext_ops。具體選擇在以下函數中實現,并最后保存在wpa_supplicant->driver中,以供在wpa_drv_scan中使用。

    ? 首先需要講解一下,在android4.0之后,wifi的工作方式基本都采用的是比較標準的nl80211方式,以前的wext方式現在使用的已經很少了,關于nl80211和wext的區別,小弟由于接觸的少,所以簡單的說兩句(有錯誤的請各位大大指正啊,萬謝!)

    ???wext:supplicant通過wext直接給wifi driver下命令,即不通過kernel,所以一般以wext工作的driver是不需要load cfg80211.ko的,這個cfg80211.ko就是kernel里面的wireless部分,主要對接supplicant和driver的。

    ???nl80211:supplicant的命令以nl80211的方式下給kernel,經過kernel再發送給driver,這樣子做的好處是 supplicant和driver之間的通訊方式更加標準話,是以后的主流方式,我后面講的driver都是以這種方式工作的。

    [cpp]?view plaincopy

  • static?int?wpa_supplicant_set_driver(struct?wpa_supplicant?*wpa_s,??

  • ?????????????????????const?char?*name)??

  • {??

  • ????int?i;??

  • ????size_t?len;??

  • ????const?char?*pos,?*driver?=?name;??

  • ??

  • ????if?(wpa_s?==?NULL)??

  • ????????return?-1;??

  • ??

  • ???????wpa_msg(wpa_s,MSG_ERROR,"***MY_WIFI:%s,name=%s\n",__FUNCTION__,name);??

  • ??????

  • ????if?(wpa_drivers[0]?==?NULL)?{??

  • ????????wpa_msg(wpa_s,?MSG_ERROR,?"No?driver?interfaces?build?into?"??

  • ????????????"wpa_supplicant");??

  • ????????return?-1;??

  • ????}??

  • ??

  • ????if?(name?==?NULL)?{??

  • ??????????

  • ????????wpa_s->driver?=?wpa_drivers[0];??

  • ????????wpa_s->global_drv_priv?=?wpa_s->global->drv_priv[0];??

  • ????????return?0;??

  • ????}??

  • ??

  • ????do?{??

  • ????????pos?=?os_strchr(driver,?',');??

  • ????????if?(pos)??

  • ????????????len?=?pos?-?driver;??

  • ????????else??

  • ????????????len?=?os_strlen(driver);??

  • ??

  • ????????for?(i?=?0;?wpa_drivers[i];?i++)?{??

  • ????????????if?(os_strlen(wpa_drivers[i]->name)?==?len?&&??

  • ????????????????os_strncmp(driver,?wpa_drivers[i]->name,?len)?==??

  • ????????????????0)?{??

  • ????????????????wpa_s->driver?=?wpa_drivers[i];??//?根據name進行匹配,并最后保存到wpa_supplicant->dirver中??

  • ????????????????wpa_s->global_drv_priv?=??

  • ????????????????????wpa_s->global->drv_priv[i];??

  • ????????????????return?0;??

  • ????????????}??

  • ????????}??

  • ??

  • ????????driver?=?pos?+?1;??

  • ????}?while?(pos);??

  • ??

  • ????wpa_msg(wpa_s,?MSG_ERROR,?"Unsupported?driver?'%s'",?name);??

  • ????return?-1;??

  • } ?

  • 2. 接口操作函數實現

    2.1 用戶態實現

    ??用戶態實現的操作函數如下:

    ??實現代碼見:/external/wpa_supplicant_8/wpa_supplicant/src/drivers/driver_wext.c

    ?

    [cpp]?view plaincopy

  • const?struct?wpa_driver_ops?wpa_driver_wext_ops?=?{??

  • ????.name?=?"wext",??

  • ????.desc?=?"Linux?wireless?extensions?(generic)",??

  • ????.get_bssid?=?wpa_driver_wext_get_bssid,??

  • ????.get_ssid?=?wpa_driver_wext_get_ssid,??

  • #ifdef?WAPI??

  • ????.set_wapi?=?wpa_driver_wext_set_wapi,??

  • #endif??

  • ????.set_key?=?wpa_driver_wext_set_key,??

  • ????.set_countermeasures?=?wpa_driver_wext_set_countermeasures,??

  • ????.scan2?=?wpa_driver_wext_scan,??

  • ????.get_scan_results2?=?wpa_driver_wext_get_scan_results,??

  • ????.deauthenticate?=?wpa_driver_wext_deauthenticate,??

  • ????.disassociate?=?wpa_driver_wext_disassociate,??

  • ????.associate?=?wpa_driver_wext_associate,??

  • ????.init?=?wpa_driver_wext_init,?//?初始ioctl?socket,?netlink?socket??

  • ????.deinit?=?wpa_driver_wext_deinit,??

  • ????.add_pmkid?=?wpa_driver_wext_add_pmkid,??

  • ????.remove_pmkid?=?wpa_driver_wext_remove_pmkid,??

  • ????.flush_pmkid?=?wpa_driver_wext_flush_pmkid,??

  • ????.get_capa?=?wpa_driver_wext_get_capa,??

  • ????.set_operstate?=?wpa_driver_wext_set_operstate,??

  • ????.get_radio_name?=?wext_get_radio_name,??

  • #ifdef?ANDROID??

  • ????.signal_poll?=?wpa_driver_signal_poll,??

  • ????.driver_cmd?=?wpa_driver_wext_driver_cmd,?//?對應驅動中的?cfg80211_wext_setpriv??

  • #endif??

  • }; ?

  • .driver_cmd處理以DRIVER開始的命令,如:

    ???DRIVER MACADDR

    ???DRIVER BTCOEXSCAN-STOP

    ???DRIVER RXFILTER-ADD 3

    ???DRIVER RXFILTER-START

    ???DRIVER RXFILTER-STOP

    ???DRIVER RXFILTER-REMOVE 2

    ???DRIVER RXFILTER-START

    ??DRIVER SETBAND 0

    ???DRIVER SCAN-ACTIVE

    ???DRIVER SCAN-PASSIVE

    ??執行流程如下所示:

    ???wpa_supplicant_ctrl_iface_process-> (根據命令字符串調用對應的函數)

    ????wpa_supplicant_driver_cmd->

    ?????wpa_drv_driver_cmd->

    ??????wpa_s->driver->driver_cmd->

    ???????wpa_driver_wext_driver_cmd-> (User)

    ??????...

    ???????cfg80211_wext_setpriv(Kernel)

    2.2 Kernel態實現 ???

    ???Kernel態實現的操作函數如下:

    ???實現代碼見:net/wireless/wext_compat.c

    ?

    [cpp]?view plaincopy

  • static?const?iw_handler?cfg80211_handlers[]?=?{??

  • ????[IW_IOCTL_IDX(SIOCGIWNAME)]?=?(iw_handler)?cfg80211_wext_giwname,??

  • ????[IW_IOCTL_IDX(SIOCSIWFREQ)]?=?(iw_handler)?cfg80211_wext_siwfreq,??

  • ????[IW_IOCTL_IDX(SIOCGIWFREQ)]?=?(iw_handler)?cfg80211_wext_giwfreq,??

  • ????[IW_IOCTL_IDX(SIOCSIWMODE)]?=?(iw_handler)?cfg80211_wext_siwmode,??

  • ????[IW_IOCTL_IDX(SIOCGIWMODE)]?=?(iw_handler)?cfg80211_wext_giwmode,??

  • ????[IW_IOCTL_IDX(SIOCGIWRANGE)]????=?(iw_handler)?cfg80211_wext_giwrange,??

  • ????[IW_IOCTL_IDX(SIOCSIWAP)]???=?(iw_handler)?cfg80211_wext_siwap,??

  • ????[IW_IOCTL_IDX(SIOCGIWAP)]???=?(iw_handler)?cfg80211_wext_giwap,??

  • ????[IW_IOCTL_IDX(SIOCSIWMLME)]?=?(iw_handler)?cfg80211_wext_siwmlme,??

  • ????[IW_IOCTL_IDX(SIOCSIWSCAN)]?=?(iw_handler)?cfg80211_wext_siwscan,??

  • ????[IW_IOCTL_IDX(SIOCGIWSCAN)]?=?(iw_handler)?cfg80211_wext_giwscan,??

  • ????[IW_IOCTL_IDX(SIOCSIWESSID)]????=?(iw_handler)?cfg80211_wext_siwessid,??

  • ????[IW_IOCTL_IDX(SIOCGIWESSID)]????=?(iw_handler)?cfg80211_wext_giwessid,??

  • ????[IW_IOCTL_IDX(SIOCSIWRATE)]?=?(iw_handler)?cfg80211_wext_siwrate,??

  • ????[IW_IOCTL_IDX(SIOCGIWRATE)]?=?(iw_handler)?cfg80211_wext_giwrate,??

  • ????[IW_IOCTL_IDX(SIOCSIWRTS)]??=?(iw_handler)?cfg80211_wext_siwrts,??

  • ????[IW_IOCTL_IDX(SIOCGIWRTS)]??=?(iw_handler)?cfg80211_wext_giwrts,??

  • ????[IW_IOCTL_IDX(SIOCSIWFRAG)]?=?(iw_handler)?cfg80211_wext_siwfrag,??

  • ????[IW_IOCTL_IDX(SIOCGIWFRAG)]?=?(iw_handler)?cfg80211_wext_giwfrag,??

  • ????[IW_IOCTL_IDX(SIOCSIWTXPOW)]????=?(iw_handler)?cfg80211_wext_siwtxpower,??

  • ????[IW_IOCTL_IDX(SIOCGIWTXPOW)]????=?(iw_handler)?cfg80211_wext_giwtxpower,??

  • ????[IW_IOCTL_IDX(SIOCSIWRETRY)]????=?(iw_handler)?cfg80211_wext_siwretry,??

  • ?..........................

  • ??

  • const?struct?iw_handler_def?cfg80211_wext_handler?=?{??

  • ????.num_standard???????=?ARRAY_SIZE(cfg80211_handlers),??

  • ????.standard???????=?cfg80211_handlers,??

  • ????.get_wireless_stats?=?cfg80211_wireless_stats,??

  • };??


  • 2.3 用戶態與Kernel態的交互

    ????用戶態向Kernel態發送請求時,通過ioctl來實現。

    ???Kernel態向用戶態發送事件通知,通過netlink來實現。

    ???其交互的初始化在wpa_driver_wext_init中實現,其代碼如下:

    ?

    [cpp]?view plaincopy

  • ??

  • void?*?wpa_driver_wext_init(void?*ctx,?const?char?*ifname)?//?我的ifname為wlan0??

  • {??

  • ????struct?wpa_driver_wext_data?*drv;??

  • ????struct?netlink_config?*cfg;??

  • ????struct?rfkill_config?*rcfg;??

  • ????char?path[128];??

  • ????struct?stat?buf;??

  • ??

  • ????????wpa_printf(MSG_ERROR,"***MY_WIFI:%s,ifname=%s\n",__FUNCTION__,ifname);??

  • ??????

  • ????drv?=?os_zalloc(sizeof(*drv));??

  • ????if?(drv?==?NULL)??

  • ????????return?NULL;??

  • ????drv->ctx?=?ctx;??

  • ????os_strlcpy(drv->ifname,?ifname,?sizeof(drv->ifname));??

  • ??

  • ????os_snprintf(path,?sizeof(path),?"/sys/class/net/%s/phy80211",?ifname);??

  • ????if?(stat(path,?&buf)?==?0)?{??

  • ????????wpa_printf(MSG_DEBUG,?"WEXT:?cfg80211-based?driver?detected");??

  • ????????drv->cfg80211?=?1;??

  • ????????wext_get_phy_name(drv);??

  • ????}??

  • ??

  • ????drv->ioctl_sock?=?socket(PF_INET,?SOCK_DGRAM,?0);??//?此drv->ioctl_sock用作為ioctl命令的fd??

  • ????if?(drv->ioctl_sock?<?0)?{??

  • ????????perror("socket(PF_INET,SOCK_DGRAM)");??

  • ????????goto?err1;??

  • ????}??

  • ??

  • ????cfg?=?os_zalloc(sizeof(*cfg));??

  • ????if?(cfg?==?NULL)??

  • ????????goto?err1;??

  • ????cfg->ctx?=?drv;??

  • ????cfg->newlink_cb?=?wpa_driver_wext_event_rtm_newlink;??

  • ????cfg->dellink_cb?=?wpa_driver_wext_event_rtm_dellink;??

  • ????drv->netlink?=?netlink_init(cfg);??//?初始化netlink,并注冊事件接收函數??

  • ????if?(drv->netlink?==?NULL)?{??

  • ????????os_free(cfg);??

  • ????????goto?err2;??

  • ????}??

  • ??

  • ????rcfg?=?os_zalloc(sizeof(*rcfg));??

  • ??

  • 其中參數ifname在/data/misc/wifi/wpa_supplicant.conf中被定義,如我的如下:

    [cpp]?view plaincopy

  • update_config=1??

  • ctrl_interface=wlan0??

  • eapol_version=1??

  • ap_scan=1??

  • fast_reauth=1 ?

  • 2.3.1 ioctl實現方案

    ???在用戶態可簡單執行一個ioctl(fd,cmd,...)命令即可。

    ???在Kernel態則是通過唯一的cmd (SIOCIWFIRST--SIOCIWLAST)?來進行區分,從而執行cfg80211_handlers中對應的函數。

    ???socket文件操作如下:

    ?

    [cpp]?view plaincopy

  • ??

  • ??

  • static?const?struct?file_operations?socket_file_ops?=?{??

  • ????.owner?=????THIS_MODULE,??

  • ????.llseek?=???no_llseek,??

  • ????.aio_read?=?sock_aio_read,??

  • ????.aio_write?=????sock_aio_write,??

  • ????.poll?=?????sock_poll,??

  • ????.unlocked_ioctl?=?sock_ioctl,?//?這個就是被執行的ioctl??

  • #ifdef?CONFIG_COMPAT??

  • ????.compat_ioctl?=?compat_sock_ioctl,??

  • #endif??

  • ????.mmap?=?????sock_mmap,??

  • ????.open?=?????sock_no_open,?????

  • ????.release?=??sock_close,??

  • ????.fasync?=???sock_fasync,??

  • ????.sendpage?=?sock_sendpage,??

  • ????.splice_write?=?generic_splice_sendpage,??

  • ????.splice_read?=??sock_splice_read,??

  • }; ?

  • 從sock_ioctl到iw_handler的執行注程如下所示:

    ?sock_ioctl->

    ??dev_ioctl->

    ???wext_handle_ioctl-> (把執行結果從kernel態copy到用戶態)

    ????wext_ioctl_dispatch->

    ?????wireless_process_ioctl->

    ???????1)?get_handler

    ???????2) ioctl_standard_call (執行cmd指定的iw_handler,并返回結果)?

    ?

    2.3.2 用戶態初始化netlink

    ?

    [cpp]?view plaincopy

  • struct?netlink_data?*?netlink_init(struct?netlink_config?*cfg)??

  • {??

  • ????struct?netlink_data?*netlink;??

  • ????struct?sockaddr_nl?local;??

  • ??

  • ????netlink?=?os_zalloc(sizeof(*netlink));??

  • ????if?(netlink?==?NULL)??

  • ????????return?NULL;??

  • ??

  • ????netlink->cfg?=?cfg;??

  • ??

  • ????netlink->sock?=?socket(PF_NETLINK,?SOCK_RAW,?NETLINK_ROUTE);??

  • ????if?(netlink->sock?<?0)?{??

  • ????????wpa_printf(MSG_ERROR,?"netlink:?Failed?to?open?netlink?"??

  • ???????????????"socket:?%s",?strerror(errno));??

  • ????????netlink_deinit(netlink);??

  • ????????return?NULL;??

  • ????}??

  • ??

  • ????os_memset(&local,?0,?sizeof(local));??

  • ????local.nl_family?=?AF_NETLINK;??

  • ????local.nl_groups?=?RTMGRP_LINK;??

  • ????if?(bind(netlink->sock,?(struct?sockaddr?*)?&local,?sizeof(local))?<?0)??

  • ????{??

  • ????????wpa_printf(MSG_ERROR,?"netlink:?Failed?to?bind?netlink?"??

  • ???????????????"socket:?%s",?strerror(errno));??

  • ????????netlink_deinit(netlink);??

  • ????????return?NULL;??

  • ????}??

  • ??

  • ????eloop_register_read_sock(netlink->sock,?netlink_receive,?netlink,??

  • ?????????????????NULL);??

  • ??

  • ????return?netlink;??

  • } ?

  • 2.3.3 用戶態netlink事件接收函數netlink_receive

    ?

    [cpp]?view plaincopy

  • static?void?netlink_receive(int?sock,?void?*eloop_ctx,?void?*sock_ctx)??

  • {??

  • ????struct?netlink_data?*netlink?=?eloop_ctx;??

  • ????char?buf[8192];??

  • ????int?left;??

  • ????struct?sockaddr_nl?from;??

  • ????socklen_t?fromlen;??

  • ????struct?nlmsghdr?*h;??

  • ????int?max_events?=?10;??

  • ??

  • try_again:??

  • ????fromlen?=?sizeof(from);??

  • ????left?=?recvfrom(sock,?buf,?sizeof(buf),?MSG_DONTWAIT,?//從netlink讀取事件??

  • ????????????(struct?sockaddr?*)?&from,?&fromlen);??

  • ????if?(left?<?0)?{??

  • ????????if?(errno?!=?EINTR?&&?errno?!=?EAGAIN)??

  • ????????????wpa_printf(MSG_INFO,?"netlink:?recvfrom?failed:?%s",??

  • ???????????????????strerror(errno));??

  • ????????return;??

  • ????}??

  • ??

  • ????h?=

  • } ?

  • 3. SCAN流程

    wpa_supplicant_ctrl_iface_process-> ( buf 內容為SCAN )

    ?wpa_supplicant_req_scan->wpa_supplicant_scan->wpa_supplicant_trigger_scan->wpa_drv_scan->wpa_s->driver->scan2->wpa_driver_wext_scan-> (Request the driver to initiate scan)wpa_driver_wext_combo_scan->ioctl(drv->ioctl_sock, SIOCSIWPRIV, &iwr)-> (User)...cfg80211_wext_setpriv (cmd=CSCAN S)->cfg80211_wext_siwscan->rdev->ops->scan (cfg80211_ops?mac80211_config_ops->scan)->ieee80211_scan->?ieee80211_request_scan->__ieee80211_start_scan->ieee80211_start_sw_scan-><1>?drv_sw_scan_start->local->ops->sw_scan_start(ieee80211_ops?ath9k_htc_ops->sw_scan_start)->ath9k_htc_sw_scan_start->?<2>?ieee80211_hw_config-> (set power level at maximum rate for scanning)drv_config->local->ops->config(?ieee80211_ops?ath9k_htc_ops->config)->?ath9k_htc_config->ath9k_htc_setpower(priv,ATH9K_PM_AWAKE)?<3> ?ieee80211_queue_delayed_work(&local->scan_work)->(注:INIT_DELAYED_WORK(&local->scan_work, ieee80211_scan_work))?ieee80211_scan_work-> (根據local當前狀態進行下一步工作,直到工作完成)__ieee80211_scan_completed-> (所有掃描的工作完成之后,調用此函數)drv_sw_scan_complete->local->ops->sw_scan_complete(?ieee80211_ops?ath9k_htc_ops->sw_scan_complete)ath9k_htc_sw_scan_complete


    轉載于:https://my.oschina.net/u/994235/blog/323261

    總結

    以上是生活随笔為你收集整理的wpa_supplicant与kernel的接口的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。