PERFORCE change 87499 for review
Sam Leffler
sam at FreeBSD.org
Wed Nov 30 04:18:35 GMT 2005
http://perforce.freebsd.org/chv.cgi?CH=87499
Change 87499 by sam at 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 */
More information about the p4-projects
mailing list