Date: Wed, 30 Nov 2005 04:17:58 GMT From: Sam Leffler <sam@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 87499 for review Message-ID: <200511300417.jAU4HwL5084417@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=87499 Change 87499 by sam@sam_ebb on 2005/11/30 04:17:13 handle ap's that beacon both wpa and rsn: o record both ie's o add new ioctl to return both (existing ioctl cannot handle it but is kept for compatbility) Affected files ... .. //depot/projects/wifi/sys/net80211/ieee80211_input.c#70 edit .. //depot/projects/wifi/sys/net80211/ieee80211_ioctl.c#54 edit .. //depot/projects/wifi/sys/net80211/ieee80211_ioctl.h#32 edit .. //depot/projects/wifi/sys/net80211/ieee80211_node.c#70 edit .. //depot/projects/wifi/sys/net80211/ieee80211_node.h#36 edit .. //depot/projects/wifi/sys/net80211/ieee80211_scan.h#5 edit .. //depot/projects/wifi/sys/net80211/ieee80211_scan_sta.c#8 edit Differences ... ==== //depot/projects/wifi/sys/net80211/ieee80211_input.c#70 (text+ko) ==== @@ -1919,7 +1919,7 @@ #define ISREASSOC(_st) ((_st) == IEEE80211_FC0_SUBTYPE_REASSOC_RESP) struct ieee80211_frame *wh; u_int8_t *frm, *efrm; - u_int8_t *ssid, *rates, *xrates, *wpa, *wme, *ath; + u_int8_t *ssid, *rates, *xrates, *wpa, *rsn, *wme, *ath; int reassoc, resp, allocbs; u_int8_t rate; @@ -2015,7 +2015,7 @@ scan.erp = frm[2]; break; case IEEE80211_ELEMID_RSN: - scan.wpa = frm; + scan.rsn = frm; break; case IEEE80211_ELEMID_VENDOR: if (iswpaoui(frm)) @@ -2371,7 +2371,7 @@ case IEEE80211_FC0_SUBTYPE_ASSOC_REQ: case IEEE80211_FC0_SUBTYPE_REASSOC_REQ: { u_int16_t capinfo, lintval; - struct ieee80211_rsnparms rsn; + struct ieee80211_rsnparms rsnparms; u_int8_t reason; if (ic->ic_opmode != IEEE80211_M_HOSTAP || @@ -2411,7 +2411,7 @@ lintval = le16toh(*(u_int16_t *)frm); frm += 2; if (reassoc) frm += 6; /* ignore current AP info */ - ssid = rates = xrates = wpa = wme = ath = NULL; + ssid = rates = xrates = wpa = rsn = wme = ath = NULL; while (frm < efrm) { switch (*frm) { case IEEE80211_ELEMID_SSID: @@ -2425,7 +2425,7 @@ break; /* XXX verify only one of RSN and WPA ie's? */ case IEEE80211_ELEMID_RSN: - wpa = frm; + rsn = frm; break; case IEEE80211_ELEMID_VENDOR: if (iswpaoui(frm)) @@ -2453,8 +2453,21 @@ ic->ic_stats.is_rx_assoc_notauth++; return; } - /* assert right associstion security credentials */ - if (wpa == NULL && (ic->ic_flags & IEEE80211_F_WPA)) { + /* assert right association security credentials */ + switch (ic->ic_flags & IEEE80211_F_WPA) { + case IEEE80211_F_WPA1: + if (wpa == NULL) + goto badwparsn; + break; + case IEEE80211_F_WPA2: + if (rsn == NULL) + goto badwparsn; + break; + case IEEE80211_F_WPA1|IEEE80211_F_WPA2: + if (wpa != NULL || rsn != NULL) + break; + /* fall thru... */ + badwparsn: IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC | IEEE80211_MSG_WPA, "[%s] no WPA/RSN IE in association request\n", @@ -2463,23 +2476,22 @@ IEEE80211_FC0_SUBTYPE_DEAUTH, IEEE80211_REASON_RSN_REQUIRED); ieee80211_node_leave(ic, ni); - /* XXX distinguish WPA/RSN? */ ic->ic_stats.is_rx_assoc_badwpaie++; return; } - if (wpa != NULL) { + if (wpa != NULL || rsn != NULL) { /* - * Parse WPA information element. Note that + * Parse WPA/RSN information element. Note that * we initialize the param block from the node * state so that information in the IE overrides * our defaults. The resulting parameters are * installed below after the association is assured. */ - rsn = ni->ni_rsn; + rsnparms = ni->ni_rsn; if (wpa[0] != IEEE80211_ELEMID_RSN) - reason = ieee80211_parse_wpa(ic, wpa, &rsn, wh); + reason = ieee80211_parse_wpa(ic, wpa, &rsnparms, wh); else - reason = ieee80211_parse_rsn(ic, wpa, &rsn, wh); + reason = ieee80211_parse_rsn(ic, wpa, &rsnparms, wh); if (reason != 0) { IEEE80211_SEND_MGMT(ic, ni, IEEE80211_FC0_SUBTYPE_DEAUTH, reason); @@ -2493,9 +2505,9 @@ "[%s] %s ie: mc %u/%u uc %u/%u key %u caps 0x%x\n", ether_sprintf(wh->i_addr2), wpa[0] != IEEE80211_ELEMID_RSN ? "WPA" : "RSN", - rsn.rsn_mcastcipher, rsn.rsn_mcastkeylen, - rsn.rsn_ucastcipher, rsn.rsn_ucastkeylen, - rsn.rsn_keymgmt, rsn.rsn_caps); + rsnparms.rsn_mcastcipher, rsnparms.rsn_mcastkeylen, + rsnparms.rsn_ucastcipher, rsnparms.rsn_ucastkeylen, + rsnparms.rsn_keymgmt, rsnparms.rsn_caps); } /* discard challenge after association */ if (ni->ni_challenge != NULL) { @@ -2545,11 +2557,11 @@ ni->ni_fhindex = ic->ic_bss->ni_fhindex; if (wpa != NULL) { /* - * Record WPA/RSN parameters for station, mark + * Record WPA parameters for station, mark * node as using WPA and record information element * for applications that require it. */ - ni->ni_rsn = rsn; + ni->ni_rsn = rsnparms; ieee80211_saveie(&ni->ni_wpa_ie, wpa); } else if (ni->ni_wpa_ie != NULL) { /* @@ -2558,6 +2570,21 @@ FREE(ni->ni_wpa_ie, M_80211_NODE); ni->ni_wpa_ie = NULL; } + if (rsn != NULL) { + /* + * Record RSN parameters for station, mark + * node as using WPA and record information element + * for applications that require it. + */ + ni->ni_rsn = rsnparms; + ieee80211_saveie(&ni->ni_rsn_ie, rsn); + } else if (ni->ni_wpa_ie != NULL) { + /* + * Flush any state from a previous association. + */ + FREE(ni->ni_rsn_ie, M_80211_NODE); + ni->ni_rsn_ie = NULL; + } if (wme != NULL) { /* * Record WME parameters for station, mark node ==== //depot/projects/wifi/sys/net80211/ieee80211_ioctl.c#54 (text+ko) ==== @@ -181,10 +181,10 @@ } static int -ieee80211_ioctl_getwpaie(struct ieee80211com *ic, struct ieee80211req *ireq) +ieee80211_ioctl_getwpaie(struct ieee80211com *ic, struct ieee80211req *ireq, int req) { struct ieee80211_node *ni; - struct ieee80211req_wpaie wpaie; + struct ieee80211req_wpaie2 wpaie; int error; if (ireq->i_len < IEEE80211_ADDR_LEN) @@ -202,9 +202,29 @@ ielen = sizeof(wpaie.wpa_ie); memcpy(wpaie.wpa_ie, ni->ni_wpa_ie, ielen); } + if (req == IEEE80211_IOC_WPAIE2) { + memset(wpaie.rsn_ie, 0, sizeof(wpaie.rsn_ie)); + if (ni->ni_rsn_ie != NULL) { + int ielen = ni->ni_rsn_ie[1] + 2; + if (ielen > sizeof(wpaie.rsn_ie)) + ielen = sizeof(wpaie.rsn_ie); + memcpy(wpaie.rsn_ie, ni->ni_rsn_ie, ielen); + } + if (ireq->i_len > sizeof(struct ieee80211req_wpaie2)) + ireq->i_len = sizeof(struct ieee80211req_wpaie2); + } else { + /* compatibility op, may overwrite wpa ie */ + /* XXX check ic_flags? */ + if (ni->ni_rsn_ie != NULL) { + int ielen = ni->ni_rsn_ie[1] + 2; + if (ielen > sizeof(wpaie.wpa_ie)) + ielen = sizeof(wpaie.wpa_ie); + memcpy(wpaie.wpa_ie, ni->ni_rsn_ie, ielen); + } + if (ireq->i_len > sizeof(struct ieee80211req_wpaie)) + ireq->i_len = sizeof(struct ieee80211req_wpaie); + } ieee80211_free_node(ni); - if (ireq->i_len > sizeof(wpaie)) - ireq->i_len = sizeof(wpaie); return copyout(&wpaie, ireq->i_data, ireq->i_len); } @@ -245,6 +265,8 @@ *ielen = 0; if (se->se_wpa_ie != NULL) *ielen += 2+se->se_wpa_ie[1]; + if (se->se_rsn_ie != NULL) + *ielen += 2+se->se_rsn_ie[1]; if (se->se_wme_ie != NULL) *ielen += 2+se->se_wme_ie[1]; if (se->se_ath_ie != NULL) @@ -302,6 +324,10 @@ memcpy(cp, se->se_wpa_ie, 2+se->se_wpa_ie[1]); cp += 2+se->se_wpa_ie[1]; } + if (se->se_rsn_ie != NULL) { + memcpy(cp, se->se_rsn_ie, 2+se->se_rsn_ie[1]); + cp += 2+se->se_rsn_ie[1]; + } if (se->se_wme_ie != NULL) { memcpy(cp, se->se_wme_ie, 2+se->se_wme_ie[1]); cp += 2+se->se_wme_ie[1]; @@ -361,6 +387,8 @@ *ielen = 0; if (ni->ni_wpa_ie != NULL) *ielen += 2+ni->ni_wpa_ie[1]; + if (ni->ni_rsn_ie != NULL) + *ielen += 2+ni->ni_rsn_ie[1]; if (ni->ni_wme_ie != NULL) *ielen += 2+ni->ni_wme_ie[1]; if (ni->ni_ath_ie != NULL) @@ -440,6 +468,10 @@ memcpy(cp, ni->ni_wpa_ie, 2+ni->ni_wpa_ie[1]); cp += 2+ni->ni_wpa_ie[1]; } + if (ni->ni_rsn_ie != NULL) { + memcpy(cp, ni->ni_rsn_ie, 2+ni->ni_rsn_ie[1]); + cp += 2+ni->ni_rsn_ie[1]; + } if (ni->ni_wme_ie != NULL) { memcpy(cp, ni->ni_wme_ie, 2+ni->ni_wme_ie[1]); cp += 2+ni->ni_wme_ie[1]; @@ -767,7 +799,10 @@ ireq->i_data, ireq->i_len); break; case IEEE80211_IOC_WPAIE: - error = ieee80211_ioctl_getwpaie(ic, ireq); + error = ieee80211_ioctl_getwpaie(ic, ireq, ireq->i_type); + break; + case IEEE80211_IOC_WPAIE2: + error = ieee80211_ioctl_getwpaie(ic, ireq, ireq->i_type); break; case IEEE80211_IOC_SCAN_RESULTS: error = ieee80211_ioctl_getscanresults(ic, ireq); @@ -1044,6 +1079,7 @@ return error; switch (mlme.im_op) { case IEEE80211_MLME_ASSOC: + /* XXX ibss/ahdemo */ if (ic->ic_opmode == IEEE80211_M_STA) { struct scanlookup lookup; ==== //depot/projects/wifi/sys/net80211/ieee80211_ioctl.h#32 (text+ko) ==== @@ -281,9 +281,14 @@ /* * Retrieve the WPA/RSN information element for an associated station. */ -struct ieee80211req_wpaie { +struct ieee80211req_wpaie { /* old version w/ only one ie */ + u_int8_t wpa_macaddr[IEEE80211_ADDR_LEN]; + u_int8_t wpa_ie[IEEE80211_MAX_OPT_IE]; +}; +struct ieee80211req_wpaie2 { u_int8_t wpa_macaddr[IEEE80211_ADDR_LEN]; u_int8_t wpa_ie[IEEE80211_MAX_OPT_IE]; + u_int8_t rsn_ie[IEEE80211_MAX_OPT_IE]; }; /* @@ -458,6 +463,7 @@ #define IEEE80211_IOC_ROAM_RATE_11G 71 /* tx rate threshold in 11g */ #define IEEE80211_IOC_MCAST_RATE 72 /* tx rate for mcast frames */ #define IEEE80211_IOC_FRAGTHRESHOLD 73 /* tx fragmentation threshold */ +#define IEEE80211_IOC_WPAIE2 74 /* WPA+RSN info elements */ /* * Scan result data returned for IEEE80211_IOC_SCAN_RESULTS. ==== //depot/projects/wifi/sys/net80211/ieee80211_node.c#70 (text+ko) ==== @@ -591,6 +591,8 @@ ni->ni_noise = se->se_noise; if (se->se_wpa_ie != NULL) ieee80211_saveie(&ni->ni_wpa_ie, se->se_wpa_ie); + if (se->se_rsn_ie != NULL) + ieee80211_saveie(&ni->ni_rsn_ie, se->se_rsn_ie); if (se->se_wme_ie != NULL) ieee80211_saveie(&ni->ni_wme_ie, se->se_wme_ie); if (se->se_ath_ie != NULL) @@ -699,6 +701,8 @@ ic->ic_node_cleanup(ni); if (ni->ni_wpa_ie != NULL) FREE(ni->ni_wpa_ie, M_80211_NODE); + if (ni->ni_rsn_ie != NULL) + FREE(ni->ni_rsn_ie, M_80211_NODE); if (ni->ni_wme_ie != NULL) FREE(ni->ni_wme_ie, M_80211_NODE); if (ni->ni_ath_ie != NULL) @@ -920,6 +924,8 @@ ieee80211_saveie(&ni->ni_wme_ie, sp->wme); if (sp->wpa != NULL) ieee80211_saveie(&ni->ni_wpa_ie, sp->wpa); + if (sp->rsn != NULL) + ieee80211_saveie(&ni->ni_rsn_ie, sp->rsn); if (sp->ath != NULL) ieee80211_saveath(ni, sp->ath); ==== //depot/projects/wifi/sys/net80211/ieee80211_node.h#36 (text+ko) ==== @@ -115,7 +115,8 @@ u_int16_t ni_txpower; /* current transmit power */ u_int16_t ni_vlan; /* vlan tag */ u_int32_t *ni_challenge; /* shared-key challenge */ - u_int8_t *ni_wpa_ie; /* captured WPA/RSN ie */ + u_int8_t *ni_wpa_ie; /* captured WPA ie */ + u_int8_t *ni_rsn_ie; /* captured RSN ie */ u_int8_t *ni_wme_ie; /* captured WME ie */ u_int8_t *ni_ath_ie; /* captured Atheros ie */ u_int16_t ni_txseqs[17]; /* tx seq per-tid */ ==== //depot/projects/wifi/sys/net80211/ieee80211_scan.h#5 (text+ko) ==== @@ -136,6 +136,7 @@ u_int8_t *xrates; u_int8_t *doth; u_int8_t *wpa; + u_int8_t *rsn; u_int8_t *wme; u_int8_t *ath; }; @@ -165,7 +166,8 @@ int8_t se_rssi; /* avg'd recv ssi */ int8_t se_noise; /* noise floor */ u_int8_t se_dtimperiod; /* DTIM period */ - u_int8_t *se_wpa_ie; /* captured WPA/RSN ie */ + u_int8_t *se_wpa_ie; /* captured WPA ie */ + u_int8_t *se_rsn_ie; /* captured RSN ie */ u_int8_t *se_wme_ie; /* captured WME ie */ u_int8_t *se_ath_ie; /* captured Atheros ie */ u_int se_age; /* age of entry (0 on create) */ ==== //depot/projects/wifi/sys/net80211/ieee80211_scan_sta.c#8 (text+ko) ==== @@ -275,6 +275,7 @@ } saveie(&ise->se_wme_ie, sp->wme); saveie(&ise->se_wpa_ie, sp->wpa); + saveie(&ise->se_rsn_ie, sp->rsn); saveie(&ise->se_ath_ie, sp->ath); /* clear failure count after STA_FAIL_AGE passes */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200511300417.jAU4HwL5084417>