📄 ieee80211_output.c.svn-base
字号:
} while (0) static const u_int8_t oui[4] = { WPA_OUI_BYTES, WPA_OUI_TYPE }; static const u_int8_t cipher_suite[][4] = { { WPA_OUI_BYTES, WPA_CSE_WEP40 }, /* NB: 40-bit */ { WPA_OUI_BYTES, WPA_CSE_TKIP }, { 0x00, 0x00, 0x00, 0x00 }, /* XXX WRAP */ { WPA_OUI_BYTES, WPA_CSE_CCMP }, { 0x00, 0x00, 0x00, 0x00 }, /* XXX CKIP */ { WPA_OUI_BYTES, WPA_CSE_NULL }, }; static const u_int8_t wep104_suite[4] = { WPA_OUI_BYTES, WPA_CSE_WEP104 }; static const u_int8_t key_mgt_unspec[4] = { WPA_OUI_BYTES, WPA_ASE_8021X_UNSPEC }; static const u_int8_t key_mgt_psk[4] = { WPA_OUI_BYTES, WPA_ASE_8021X_PSK }; const struct ieee80211_rsnparms *rsn = &vap->iv_bss->ni_rsn; u_int8_t *frm = ie; u_int8_t *selcnt; *frm++ = IEEE80211_ELEMID_VENDOR; *frm++ = 0; /* length filled in below */ memcpy(frm, oui, sizeof(oui)); /* WPA OUI */ frm += sizeof(oui); ADDSHORT(frm, WPA_VERSION); /* XXX filter out CKIP */ /* multicast cipher */ if (rsn->rsn_mcastcipher == IEEE80211_CIPHER_WEP && rsn->rsn_mcastkeylen >= 13) ADDSELECTOR(frm, wep104_suite); else ADDSELECTOR(frm, cipher_suite[rsn->rsn_mcastcipher]); /* unicast cipher list */ selcnt = frm; ADDSHORT(frm, 0); /* selector count */ if (rsn->rsn_ucastcipherset & (1 << IEEE80211_CIPHER_AES_CCM)) { selcnt[0]++; ADDSELECTOR(frm, cipher_suite[IEEE80211_CIPHER_AES_CCM]); } if (rsn->rsn_ucastcipherset & (1 << IEEE80211_CIPHER_TKIP)) { selcnt[0]++; ADDSELECTOR(frm, cipher_suite[IEEE80211_CIPHER_TKIP]); } /* authenticator selector list */ selcnt = frm; ADDSHORT(frm, 0); /* selector count */ if (rsn->rsn_keymgmtset & WPA_ASE_8021X_UNSPEC) { selcnt[0]++; ADDSELECTOR(frm, key_mgt_unspec); } if (rsn->rsn_keymgmtset & WPA_ASE_8021X_PSK) { selcnt[0]++; ADDSELECTOR(frm, key_mgt_psk); } /* optional capabilities */ if ((rsn->rsn_caps != 0) && (rsn->rsn_caps != RSN_CAP_PREAUTH)) ADDSHORT(frm, rsn->rsn_caps); /* calculate element length */ ie[1] = frm - ie - 2; KASSERT(ie[1] + 2 <= sizeof(struct ieee80211_ie_wpa), ("WPA IE too big, %u > %u", ie[1] + 2, (int)sizeof(struct ieee80211_ie_wpa))); return frm;#undef ADDSHORT#undef ADDSELECTOR#undef WPA_OUI_BYTES}static u_int8_t *ieee80211_setup_rsn_ie(struct ieee80211vap *vap, u_int8_t *ie){#define RSN_OUI_BYTES 0x00, 0x0f, 0xac#define ADDSHORT(frm, v) do { \ frm[0] = (v) & 0xff; \ frm[1] = (v) >> 8; \ frm += 2; \} while (0)#define ADDSELECTOR(frm, sel) do { \ memcpy(frm, sel, 4); \ frm += 4; \} while (0) static const u_int8_t cipher_suite[][4] = { { RSN_OUI_BYTES, RSN_CSE_WEP40 }, /* NB: 40-bit */ { RSN_OUI_BYTES, RSN_CSE_TKIP }, { RSN_OUI_BYTES, RSN_CSE_WRAP }, { RSN_OUI_BYTES, RSN_CSE_CCMP }, { 0x00, 0x00, 0x00, 0x00 }, /* XXX CKIP */ { RSN_OUI_BYTES, RSN_CSE_NULL }, }; static const u_int8_t wep104_suite[4] = { RSN_OUI_BYTES, RSN_CSE_WEP104 }; static const u_int8_t key_mgt_unspec[4] = { RSN_OUI_BYTES, RSN_ASE_8021X_UNSPEC }; static const u_int8_t key_mgt_psk[4] = { RSN_OUI_BYTES, RSN_ASE_8021X_PSK }; const struct ieee80211_rsnparms *rsn = &vap->iv_bss->ni_rsn; u_int8_t *frm = ie; u_int8_t *selcnt; *frm++ = IEEE80211_ELEMID_RSN; *frm++ = 0; /* length filled in below */ ADDSHORT(frm, RSN_VERSION); /* XXX filter out CKIP */ /* multicast cipher */ if (rsn->rsn_mcastcipher == IEEE80211_CIPHER_WEP && rsn->rsn_mcastkeylen >= 13) ADDSELECTOR(frm, wep104_suite); else ADDSELECTOR(frm, cipher_suite[rsn->rsn_mcastcipher]); /* unicast cipher list */ selcnt = frm; ADDSHORT(frm, 0); /* selector count */ if (rsn->rsn_ucastcipherset & (1 << IEEE80211_CIPHER_AES_CCM)) { selcnt[0]++; ADDSELECTOR(frm, cipher_suite[IEEE80211_CIPHER_AES_CCM]); } if (rsn->rsn_ucastcipherset & (1 << IEEE80211_CIPHER_TKIP)) { selcnt[0]++; ADDSELECTOR(frm, cipher_suite[IEEE80211_CIPHER_TKIP]); } /* authenticator selector list */ selcnt = frm; ADDSHORT(frm, 0); /* selector count */ if (rsn->rsn_keymgmtset & WPA_ASE_8021X_UNSPEC) { selcnt[0]++; ADDSELECTOR(frm, key_mgt_unspec); } if (rsn->rsn_keymgmtset & WPA_ASE_8021X_PSK) { selcnt[0]++; ADDSELECTOR(frm, key_mgt_psk); } /* capabilities */ ADDSHORT(frm, rsn->rsn_caps); /* XXX PMKID */ /* calculate element length */ ie[1] = frm - ie - 2; KASSERT(ie[1] + 2 <= sizeof(struct ieee80211_ie_wpa), ("RSN IE too big, %u > %u", ie[1] + 2, (int)sizeof(struct ieee80211_ie_wpa))); return frm;#undef ADDSELECTOR#undef ADDSHORT#undef RSN_OUI_BYTES}/* * Add a WPA/RSN element to a frame. */u_int8_t *ieee80211_add_wpa(u_int8_t *frm, struct ieee80211vap *vap){ KASSERT(vap->iv_flags & IEEE80211_F_WPA, ("no WPA/RSN!")); if (vap->iv_flags & IEEE80211_F_WPA2) frm = ieee80211_setup_rsn_ie(vap, frm); if (vap->iv_flags & IEEE80211_F_WPA1) frm = ieee80211_setup_wpa_ie(vap, frm); return frm;}#define WME_OUI_BYTES 0x00, 0x50, 0xf2/* * Add a WME Info element to a frame. */static u_int8_t *ieee80211_add_wme(u_int8_t *frm, struct ieee80211_node *ni){ static const u_int8_t oui[4] = { WME_OUI_BYTES, WME_OUI_TYPE }; struct ieee80211_ie_wme *ie = (struct ieee80211_ie_wme *)frm; struct ieee80211_wme_state *wme = &ni->ni_ic->ic_wme; struct ieee80211vap *vap = ni->ni_vap; *frm++ = IEEE80211_ELEMID_VENDOR; *frm++ = 0; /* length filled in below */ memcpy(frm, oui, sizeof(oui)); /* WME OUI */ frm += sizeof(oui); *frm++ = WME_INFO_OUI_SUBTYPE; /* OUI subtype */ *frm++ = WME_VERSION; /* protocol version */ /* QoS Info field depends on operating mode */ switch (vap->iv_opmode) { case IEEE80211_M_HOSTAP: *frm = wme->wme_bssChanParams.cap_info_count; if (IEEE80211_VAP_UAPSD_ENABLED(vap)) *frm |= WME_CAPINFO_UAPSD_EN; frm++; break; case IEEE80211_M_STA: *frm++ = vap->iv_uapsdinfo; break; default: *frm++ = 0; } ie->wme_len = frm - &ie->wme_oui[0]; return frm;}/* * Add a WME Parameter element to a frame. */u_int8_t *ieee80211_add_wme_param(u_int8_t *frm, struct ieee80211_wme_state *wme, int uapsd_enable){#define SM(_v, _f) (((_v) << _f##_S) & _f)#define ADDSHORT(frm, v) do { \ frm[0] = (v) & 0xff; \ frm[1] = (v) >> 8; \ frm += 2; \} while (0) static const u_int8_t oui[4] = { WME_OUI_BYTES, WME_OUI_TYPE }; struct ieee80211_wme_param *ie = (struct ieee80211_wme_param *)frm; int i; *frm++ = IEEE80211_ELEMID_VENDOR; *frm++ = 0; /* length filled in below */ memcpy(frm, oui, sizeof(oui)); /* WME OUI */ frm += sizeof(oui); *frm++ = WME_PARAM_OUI_SUBTYPE; /* OUI subtype */ *frm++ = WME_VERSION; /* protocol version */ *frm = wme->wme_bssChanParams.cap_info_count; if (uapsd_enable) *frm |= WME_CAPINFO_UAPSD_EN; frm++; *frm++ = 0; /* reserved field */ for (i = 0; i < WME_NUM_AC; i++) { const struct wmeParams *ac = &wme->wme_bssChanParams.cap_wmeParams[i]; *frm++ = SM(i, WME_PARAM_ACI) | SM(ac->wmep_acm, WME_PARAM_ACM) | SM(ac->wmep_aifsn, WME_PARAM_AIFSN); *frm++ = SM(ac->wmep_logcwmax, WME_PARAM_LOGCWMAX) | SM(ac->wmep_logcwmin, WME_PARAM_LOGCWMIN); ADDSHORT(frm, ac->wmep_txopLimit); } ie->param_len = frm - &ie->param_oui[0]; return frm;#undef ADDSHORT}#undef WME_OUI_BYTES/* * Add an Atheros Advanaced Capability element to a frame */u_int8_t *ieee80211_add_athAdvCap(u_int8_t *frm, u_int8_t capability, u_int16_t defaultKey){ static const u_int8_t oui[6] = {(ATH_OUI & 0xff), ((ATH_OUI >>8) & 0xff), ((ATH_OUI >> 16) & 0xff), ATH_OUI_TYPE, ATH_OUI_SUBTYPE, ATH_OUI_VERSION}; struct ieee80211_ie_athAdvCap *ie = (struct ieee80211_ie_athAdvCap *)frm; *frm++ = IEEE80211_ELEMID_VENDOR; *frm++ = 0; /* Length filled in below */ memcpy(frm, oui, sizeof(oui)); /* Atheros OUI, type, subtype, and version for adv capabilities */ frm += sizeof(oui); *frm++ = capability; /* Setup default key index in little endian byte order */ *frm++ = (defaultKey & 0xff); *frm++ = ((defaultKey >> 8) & 0xff); ie->athAdvCap_len = frm - &ie->athAdvCap_oui[0]; return frm;}/* * Add XR IE element to a frame */#ifdef ATH_SUPERG_XRu_int8_t *ieee80211_add_xr_param(u_int8_t *frm, struct ieee80211vap *vap){ static const u_int8_t oui[6] = {(ATH_OUI & 0xff), ((ATH_OUI >>8) & 0xff), ((ATH_OUI >> 16) & 0xff), ATH_OUI_TYPE_XR, ATH_OUI_SUBTYPE_XR, ATH_OUI_VER_XR}; struct ieee80211_xr_param *ie = (struct ieee80211_xr_param *)frm; *frm++ = IEEE80211_ELEMID_VENDOR; *frm++ = 0; /* Length filled in below */ memcpy(frm, oui, sizeof(oui)); /* Atheros OUI, type, subtype, and version for adv capabilities */ frm += sizeof(oui); *frm++ = 0; /* XR info */ /* copy the BSSIDs */ if (vap->iv_flags & IEEE80211_F_XR) { IEEE80211_ADDR_COPY(frm, vap->iv_xrvap->iv_bssid); /* Base BSSID */ frm += IEEE80211_ADDR_LEN; IEEE80211_ADDR_COPY(frm, vap->iv_bssid); /* XR BSSID */ frm += IEEE80211_ADDR_LEN; *(__le16 *)frm = htole16(vap->iv_bss->ni_intval); /* XR beacon interval */ frm += 2; *frm++ = vap->iv_xrvap->iv_ath_cap; /* Base mode capability */ *frm++ = vap->iv_ath_cap; /* XR mode capability */ } else { IEEE80211_ADDR_COPY(frm, vap->iv_bssid); frm += IEEE80211_ADDR_LEN; IEEE80211_ADDR_COPY(frm, vap->iv_xrvap->iv_bssid); frm += IEEE80211_ADDR_LEN; *(__le16 *)frm = htole16(vap->iv_bss->ni_intval); frm += 2; *frm++ = vap->iv_ath_cap; *frm++ = vap->iv_xrvap->iv_ath_cap; } ie->param_len = frm - &ie->param_oui[0]; return frm;}#endif/* * Send a probe request frame with the specified ssid * and any optional information element data. */intieee80211_send_probereq(struct ieee80211_node *ni, const u_int8_t sa[IEEE80211_ADDR_LEN], const u_int8_t da[IEEE80211_ADDR_LEN], const u_int8_t bssid[IEEE80211_ADDR_LEN], const u_int8_t *ssid, size_t ssidlen, const void *optie, size_t optielen){ struct ieee80211vap *vap = ni->ni_vap; struct ieee80211com *ic = ni->ni_ic; enum ieee80211_phymode mode; struct ieee80211_frame *wh; struct sk_buff *skb; u_int8_t *frm; /* * prreq frame format * [tlv] ssid * [tlv] supported rates * [tlv] extended supported rates * [tlv] user-specified IEs */ skb = ieee80211_getmgtframe(&frm, 2 + IEEE80211_NWID_LEN + 2 + IEEE80211_RATE_SIZE + 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE) + (optie != NULL ? optielen : 0) + vap->app_ie[IEEE80211_APPIE_FRAME_PROBE_REQ].length); if (skb == NULL) { vap->iv_stats.is_tx_nobuf++; return -ENOMEM; } frm = ieee80211_add_ssid(frm, ssid, ssidlen); mode = ieee80211_chan2mode(ic->ic_curchan); frm = ieee80211_add_rates(frm, &ic->ic_sup_rates[mode]); frm = ieee80211_add_xrates(frm, &ic->ic_sup_rates[mode]); if (optie != NULL) { memcpy(frm, optie, optielen); frm += optielen; } if (vap->app_ie[IEEE80211_APPIE_FRAME_PROBE_REQ].ie) { memcpy(frm, vap->app_ie[IEEE80211_APPIE_FRAME_PROBE_REQ].ie, vap->app_ie[IEEE80211_APPIE_FRAME_PROBE_REQ].length); frm += vap->app_ie[IEEE80211_APPIE_FRAME_PROBE_REQ].length; } skb_trim(skb, frm - skb->data); SKB_NI(skb) = ieee80211_ref_node(ni); wh = (struct ieee80211_frame *) skb_push(skb, sizeof(struct ieee80211_frame)); ieee80211_send_setup(vap, ni, wh, IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_REQ, sa, da, bssid); /* XXX power management? */ IEEE80211_NODE_STAT(ni, tx_probereq); IEEE80211_NODE_STAT(ni, tx_mgmt); IEEE80211_DPRINTF(vap, IEEE80211_MSG_DEBUG | IEEE80211_MSG_DUMPPKTS, "[" MAC_FMT "] send probe req on channel %u\n", MAC_ADDR(wh->i_addr1), ieee80211_chan2ieee(ic, ic->ic_curchan)); (void)ic->ic_mgtstart(ic, skb); return 0;}/* * Send a management frame. The node is for the destination (or ic_bss * when in station mode). Nodes other than ic_bss have their reference * count bumped to reflect our use for an indeterminate time. */intieee80211_send_mgmt(struct ieee80211_node *ni, int type, int arg){#define senderr(_x, _v) do { vap->iv_stats._v++; ret = _x; goto bad; } while (0) struct ieee80211vap *vap = ni->ni_vap; struct ieee80211com *ic = ni->ni_ic; struct sk_buff *skb; u_int8_t *frm; int frm_len; u_int16_t capinfo; ieee80211_keyix_t def_keyindex; int has_challenge, is_shared_key, ret, timer, status; KASSERT(ni != NULL, ("null node")); timer = 0; switch (type) { case IEEE80211_FC0_SUBTYPE_PROBE_RESP: /* * probe response frame format * [8] time stamp * [2] beacon interval * [2] capability information * [tlv] ssid * [tlv] supported rates * [7] FH/DS parameter set * [tlv] IBSS parameter set * [tlv] country code * [3] power constraint * [3] extended rate phy (ERP) * [tlv] extended supported rates * [tlv] WME parameters * [tlv] WPA/RSN parameters * [tlv] Atheros Advanced Capabilities * [tlv] AtherosXR parameters */ frm_len = 8 + sizeof(u_int16_t) + sizeof(u_int16_t) + 2 + IEEE80211_NWID_LEN + 2 + IEEE80211_RATE_SIZE + 7 /* max(7,3) */ /* XXX allocate max size */ + 2 + ic->ic_country_ie.country_len + 3 + 3 + 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -