免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1513 | 回复: 0
打印 上一主题 下一主题

[网络子系统] 被动扫描问题求解 [复制链接]

求职 : 通讯/电信开
论坛徽章:
2
2015亚冠之鹿岛鹿角
日期:2015-07-08 11:58:2615-16赛季CBA联赛之佛山
日期:2015-12-21 17:28:04
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2015-11-25 17:10 |只看该作者 |倒序浏览
本帖最后由 九阳神功爱喝茶 于 2015-11-25 19:06 编辑

小弟最近在看主动扫描和被动扫描的ath9k源代码,遇到一个问题想和大家一起讨论下。
被动扫描是Client接收AP的beacon帧,然后对这个信道进行扫描,扫描之后获取该AP的BSS信息,保存下来,即完成了扫描过程;然后进入ieee80211_rx_mgmt_beacon函数,我分析了下其中的与创建连接有关的代码,如下:

  1. static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
  2.                                      struct ieee80211_mgmt *mgmt, size_t len,
  3.                                      struct ieee80211_rx_status *rx_status)
  4. {
  5.         struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
  6.         struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;
  7.         size_t baselen;
  8.         struct ieee802_11_elems elems;
  9.         struct ieee80211_local *local = sdata->local;
  10.         struct ieee80211_chanctx_conf *chanctx_conf;
  11.         struct ieee80211_channel *chan;
  12.         struct sta_info *sta;
  13.         u32 changed = 0;
  14.         bool erp_valid;
  15.         u8 erp_value = 0;
  16.         u32 ncrc;
  17.         u8 *bssid;
  18.         u8 deauth_buf[IEEE80211_DEAUTH_FRAME_LEN];

  19.         sdata_assert_lock(sdata);

  20.         /* Process beacon from the current BSS */
  21.         baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt;
  22.         if (baselen > len)
  23.                 return;

  24.         rcu_read_lock();
  25.         chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
  26.         if (!chanctx_conf) {
  27.                 rcu_read_unlock();
  28.                 return;
  29.         }

  30.         if (rx_status->freq != chanctx_conf->def.chan->center_freq) {
  31.                 rcu_read_unlock();
  32.                 return;
  33.         }
  34.         chan = chanctx_conf->def.chan;
  35.         rcu_read_unlock();

  36.        //也就是说第一次等到该AP的beacon帧
  37.         if (ifmgd->assoc_data && ifmgd->assoc_data->need_beacon &&
  38.             ether_addr_equal(mgmt->bssid, ifmgd->assoc_data->bss->bssid)) {
  39.                 ieee802_11_parse_elems(mgmt->u.beacon.variable,
  40.                                        len - baselen, false, &elems);

  41.                 ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems);
  42.                 if (elems.tim && !elems.parse_error) {
  43.                         const struct ieee80211_tim_ie *tim_ie = elems.tim;
  44.                         ifmgd->dtim_period = tim_ie->dtim_period;
  45.                 }
  46.                 ifmgd->have_beacon = true;
  47.                 ifmgd->assoc_data->need_beacon = false;
  48.                 if (local->hw.flags & IEEE80211_HW_TIMING_BEACON_ONLY) {
  49.                         sdata->vif.bss_conf.sync_tsf =
  50.                                 le64_to_cpu(mgmt->u.beacon.timestamp);
  51.                         sdata->vif.bss_conf.sync_device_ts =
  52.                                 rx_status->device_timestamp;
  53.                         if (elems.tim)
  54.                                 sdata->vif.bss_conf.sync_dtim_count =
  55.                                         elems.tim->dtim_count;
  56.                         else
  57.                                 sdata->vif.bss_conf.sync_dtim_count = 0;
  58.                 }
  59.                 /* continue assoc process */
  60.                 ifmgd->assoc_data->timeout = jiffies;
  61.                 ifmgd->assoc_data->timeout_started = true;
  62.                 run_again(sdata, ifmgd->assoc_data->timeout);
  63.                 return;
  64.         }
  65. //如果当前未连接或者说收到的BSSID与当前连接的BSSID不匹配,直接return。。。
  66.         if (!ifmgd->associated ||
  67.             !ether_addr_equal(mgmt->bssid, ifmgd->associated->bssid))
  68.                 return;
  69.         bssid = ifmgd->associated->bssid;

  70.         /* Track average RSSI from the Beacon frames of the current AP */
  71.         ifmgd->last_beacon_signal = rx_status->signal;
  72.         if (ifmgd->flags & IEEE80211_STA_RESET_SIGNAL_AVE) {
  73.                 ifmgd->flags &= ~IEEE80211_STA_RESET_SIGNAL_AVE;
  74.                 ifmgd->ave_beacon_signal = rx_status->signal * 16;
  75.                 ifmgd->last_cqm_event_signal = 0;
  76.                 ifmgd->count_beacon_signal = 1;
  77.                 ifmgd->last_ave_beacon_signal = 0;
  78.         } else {
  79.                 ifmgd->ave_beacon_signal =
  80.                         (IEEE80211_SIGNAL_AVE_WEIGHT * rx_status->signal * 16 +
  81.                          (16 - IEEE80211_SIGNAL_AVE_WEIGHT) *
  82.                          ifmgd->ave_beacon_signal) / 16;
  83.                 ifmgd->count_beacon_signal++;
  84.         }

  85.         if (ifmgd->rssi_min_thold != ifmgd->rssi_max_thold &&
  86.             ifmgd->count_beacon_signal >= IEEE80211_SIGNAL_AVE_MIN_COUNT) {
  87.                 int sig = ifmgd->ave_beacon_signal;
  88.                 int last_sig = ifmgd->last_ave_beacon_signal;

  89.                 /*
  90.                  * if signal crosses either of the boundaries, invoke callback
  91.                  * with appropriate parameters
  92.                  */
  93.                 if (sig > ifmgd->rssi_max_thold &&
  94.                     (last_sig <= ifmgd->rssi_min_thold || last_sig == 0)) {
  95.                         ifmgd->last_ave_beacon_signal = sig;
  96.                         drv_rssi_callback(local, sdata, RSSI_EVENT_HIGH);
  97.                 } else if (sig < ifmgd->rssi_min_thold &&
  98.                            (last_sig >= ifmgd->rssi_max_thold ||
  99.                            last_sig == 0)) {
  100.                         ifmgd->last_ave_beacon_signal = sig;
  101.                         drv_rssi_callback(local, sdata, RSSI_EVENT_LOW);
  102.                 }
  103.         }

  104.         if (bss_conf->cqm_rssi_thold &&
  105.             ifmgd->count_beacon_signal >= IEEE80211_SIGNAL_AVE_MIN_COUNT &&
  106.             !(sdata->vif.driver_flags & IEEE80211_VIF_SUPPORTS_CQM_RSSI)) {
  107.                 int sig = ifmgd->ave_beacon_signal / 16;
  108.                 int last_event = ifmgd->last_cqm_event_signal;
  109.                 int thold = bss_conf->cqm_rssi_thold;
  110.                 int hyst = bss_conf->cqm_rssi_hyst;
  111.                 if (sig < thold &&
  112.                     (last_event == 0 || sig < last_event - hyst)) {
  113.                         ifmgd->last_cqm_event_signal = sig;
  114.                         ieee80211_cqm_rssi_notify(
  115.                                 &sdata->vif,
  116.                                 NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW,
  117.                                 GFP_KERNEL);
  118.                 } else if (sig > thold &&
  119.                            (last_event == 0 || sig > last_event + hyst)) {
  120.                         ifmgd->last_cqm_event_signal = sig;
  121.                         ieee80211_cqm_rssi_notify(
  122.                                 &sdata->vif,
  123.                                 NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH,
  124.                                 GFP_KERNEL);
  125.                 }
  126.         }

  127.         if (ifmgd->flags & IEEE80211_STA_CONNECTION_POLL) {
  128.                 mlme_dbg_ratelimited(sdata,
  129.                                      "cancelling AP probe due to a received beacon\n");
  130.                 ieee80211_reset_ap_probe(sdata);
  131.         }

  132.         /*
  133.          * Push the beacon loss detection into the future since
  134.          * we are processing a beacon from the AP just now.
  135.          */
  136.         ieee80211_sta_reset_beacon_monitor(sdata);

  137.         ncrc = crc32_be(0, (void *)&mgmt->u.beacon.beacon_int, 4);
  138.         ncrc = ieee802_11_parse_elems_crc(mgmt->u.beacon.variable,
  139.                                           len - baselen, false, &elems,
  140.                                           care_about_ies, ncrc);

  141.         if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) {
  142.                 bool directed_tim = ieee80211_check_tim(elems.tim,
  143.                                                         elems.tim_len,
  144.                                                         ifmgd->aid);
  145.                 if (directed_tim) {
  146.                         if (local->hw.conf.dynamic_ps_timeout > 0) {
  147.                                 if (local->hw.conf.flags & IEEE80211_CONF_PS) {
  148.                                         local->hw.conf.flags &= ~IEEE80211_CONF_PS;
  149.                                         ieee80211_hw_config(local,
  150.                                                             IEEE80211_CONF_CHANGE_PS);
  151.                                 }
  152.                                 ieee80211_send_nullfunc(local, sdata, 0);
  153.                         } else if (!local->pspolling && sdata->u.mgd.powersave) {
  154.                                 local->pspolling = true;

  155.                                 /*
  156.                                  * Here is assumed that the driver will be
  157.                                  * able to send ps-poll frame and receive a
  158.                                  * response even though power save mode is
  159.                                  * enabled, but some drivers might require
  160.                                  * to disable power save here. This needs
  161.                                  * to be investigated.
  162.                                  */
  163.                                 ieee80211_send_pspoll(local, sdata);
  164.                         }
  165.                 }
  166.         }

  167.         if (sdata->vif.p2p) {
  168.                 struct ieee80211_p2p_noa_attr noa = {};
  169.                 int ret;

  170.                 ret = cfg80211_get_p2p_attr(mgmt->u.beacon.variable,
  171.                                             len - baselen,
  172.                                             IEEE80211_P2P_ATTR_ABSENCE_NOTICE,
  173.                                             (u8 *) &noa, sizeof(noa));
  174.                 if (ret >= 2) {
  175.                         if (sdata->u.mgd.p2p_noa_index != noa.index) {
  176.                                 /* valid noa_attr and index changed */
  177.                                 sdata->u.mgd.p2p_noa_index = noa.index;
  178.                                 memcpy(&bss_conf->p2p_noa_attr, &noa, sizeof(noa));
  179.                                 changed |= BSS_CHANGED_P2P_PS;
  180.                                 /*
  181.                                  * make sure we update all information, the CRC
  182.                                  * mechanism doesn't look at P2P attributes.
  183.                                  */
  184.                                 ifmgd->beacon_crc_valid = false;
  185.                         }
  186.                 } else if (sdata->u.mgd.p2p_noa_index != -1) {
  187.                         /* noa_attr not found and we had valid noa_attr before */
  188.                         sdata->u.mgd.p2p_noa_index = -1;
  189.                         memset(&bss_conf->p2p_noa_attr, 0, sizeof(bss_conf->p2p_noa_attr));
  190.                         changed |= BSS_CHANGED_P2P_PS;
  191.                         ifmgd->beacon_crc_valid = false;
  192.                 }
  193.         }

  194.         if (ncrc == ifmgd->beacon_crc && ifmgd->beacon_crc_valid)
  195.                 return;
  196.         ifmgd->beacon_crc = ncrc;
  197.         ifmgd->beacon_crc_valid = true;

  198.         ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems);

  199.         ieee80211_sta_process_chanswitch(sdata, rx_status->mactime,
  200.                                          &elems, true);

  201.         if (!(ifmgd->flags & IEEE80211_STA_DISABLE_WMM) &&
  202.             ieee80211_sta_wmm_params(local, sdata, elems.wmm_param,
  203.                                      elems.wmm_param_len))
  204.                 changed |= BSS_CHANGED_QOS;

  205.         /*
  206.          * If we haven't had a beacon before, tell the driver about the
  207.          * DTIM period (and beacon timing if desired) now.
  208.          */
  209.         if (!ifmgd->have_beacon) {
  210.                 /* a few bogus AP send dtim_period = 0 or no TIM IE */
  211.                 if (elems.tim)
  212.                         bss_conf->dtim_period = elems.tim->dtim_period ?: 1;
  213.                 else
  214.                         bss_conf->dtim_period = 1;

  215.                 if (local->hw.flags & IEEE80211_HW_TIMING_BEACON_ONLY) {
  216.                         sdata->vif.bss_conf.sync_tsf =
  217.                                 le64_to_cpu(mgmt->u.beacon.timestamp);
  218.                         sdata->vif.bss_conf.sync_device_ts =
  219.                                 rx_status->device_timestamp;
  220.                         if (elems.tim)
  221.                                 sdata->vif.bss_conf.sync_dtim_count =
  222.                                         elems.tim->dtim_count;
  223.                         else
  224.                                 sdata->vif.bss_conf.sync_dtim_count = 0;
  225.                 }

  226.                 changed |= BSS_CHANGED_BEACON_INFO;
  227.                 ifmgd->have_beacon = true;

  228.                 mutex_lock(&local->iflist_mtx);
  229.                 ieee80211_recalc_ps(local, -1);
  230.                 mutex_unlock(&local->iflist_mtx);

  231.                 ieee80211_recalc_ps_vif(sdata);
  232.         }

  233.         if (elems.erp_info) {
  234.                 erp_valid = true;
  235.                 erp_value = elems.erp_info[0];
  236.         } else {
  237.                 erp_valid = false;
  238.         }
  239.         changed |= ieee80211_handle_bss_capability(sdata,
  240.                         le16_to_cpu(mgmt->u.beacon.capab_info),
  241.                         erp_valid, erp_value);

  242.         mutex_lock(&local->sta_mtx);
  243.         sta = sta_info_get(sdata, bssid);

  244.         if (ieee80211_config_bw(sdata, sta, elems.ht_operation,
  245.                                 elems.vht_operation, bssid, &changed)) {
  246.                 mutex_unlock(&local->sta_mtx);
  247.                 ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH,
  248.                                        WLAN_REASON_DEAUTH_LEAVING,
  249.                                        true, deauth_buf);
  250.                 cfg80211_tx_mlme_mgmt(sdata->dev, deauth_buf,
  251.                                       sizeof(deauth_buf));
  252.                 return;
  253.         }

  254.         if (sta && elems.opmode_notif)
  255.                 ieee80211_vht_handle_opmode(sdata, sta, *elems.opmode_notif,
  256.                                             rx_status->band, true);
  257.         mutex_unlock(&local->sta_mtx);

  258.         if (elems.country_elem && elems.pwr_constr_elem &&
  259.             mgmt->u.probe_resp.capab_info &
  260.                                 cpu_to_le16(WLAN_CAPABILITY_SPECTRUM_MGMT))
  261.                 changed |= ieee80211_handle_pwr_constr(sdata, chan,
  262.                                                        elems.country_elem,
  263.                                                        elems.country_elem_len,
  264.                                                        elems.pwr_constr_elem);

  265.         ieee80211_bss_info_change_notify(sdata, changed);
  266. }
复制代码
还请各位大神指导下,小弟分析对吗?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP