Date: Fri, 29 Dec 2006 07:35:07 GMT From: Sam Leffler <sam@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 112271 for review Message-ID: <200612290735.kBT7Z7QM074840@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=112271 Change 112271 by sam@sam_ebb on 2006/12/29 07:34:08 bring compat code into the new world order Affected files ... .. //depot/projects/wifi/sys/net80211/ieee80211_ioctl.c#61 edit Differences ... ==== //depot/projects/wifi/sys/net80211/ieee80211_ioctl.c#61 (text+ko) ==== @@ -260,6 +260,7 @@ return error; } +#define COMPAT_FREEBSD6 #ifdef COMPAT_FREEBSD6 #define IEEE80211_IOC_SCAN_RESULTS_OLD 24 @@ -281,86 +282,120 @@ /* variable length SSID followed by IE data */ }; +struct oscanreq { + struct scan_result_old *sr; + size_t space; +}; + +static size_t +old_scan_space(const struct ieee80211_scan_entry *se, int *ielen) +{ + size_t len; + + *ielen = 0; + if (se->se_wpa_ie != NULL) + *ielen += 2+se->se_wpa_ie[1]; + if (se->se_wme_ie != NULL) + *ielen += 2+se->se_wme_ie[1]; + /* + * NB: ie's can be no more than 255 bytes and the max 802.11 + * packet is <3Kbytes so we are sure this doesn't overflow + * 16-bits; if this is a concern we can drop the ie's. + */ + len = sizeof(struct scan_result_old) + se->se_ssid[1] + *ielen; + return roundup(len, sizeof(u_int32_t)); +} + static void -old_get_scan_result(struct scan_result_old *sr, - const struct ieee80211_node *ni) +old_get_scan_space(void *arg, const struct ieee80211_scan_entry *se) +{ + struct oscanreq *req = arg; + int ielen; + + req->space += old_scan_space(se, &ielen); +} + +static void +old_get_scan_result(void *arg, const struct ieee80211_scan_entry *se) { - struct ieee80211com *ic = ni->ni_ic; - u_int ielen; + struct oscanreq *req = arg; + struct scan_result_old *sr; + int ielen, len, nr, nxr; + u_int8_t *cp; + + len = old_scan_space(se, &ielen); + if (len > req->space) + return; + sr = req->sr; memset(sr, 0, sizeof(*sr)); - sr->isr_ssid_len = ni->ni_esslen; - ielen = 0; - if (ni->ni_wpa_ie != NULL) - ielen += 2+ni->ni_wpa_ie[1]; - if (ni->ni_wme_ie != NULL) - ielen += 2+ni->ni_wme_ie[1]; + sr->isr_ssid_len = se->se_ssid[1]; /* NB: beware of overflow, isr_ie_len is 8 bits */ sr->isr_ie_len = (ielen > 255 ? 0 : ielen); - sr->isr_len = sizeof(*sr) + sr->isr_ssid_len + sr->isr_ie_len; - sr->isr_len = roundup(sr->isr_len, sizeof(u_int32_t)); - if (ni->ni_chan != IEEE80211_CHAN_ANYC) { - sr->isr_freq = ni->ni_chan->ic_freq; - sr->isr_flags = ni->ni_chan->ic_flags; + sr->isr_len = len; + sr->isr_freq = se->se_chan->ic_freq; + sr->isr_flags = se->se_chan->ic_flags; + sr->isr_rssi = se->se_rssi; + sr->isr_noise = se->se_noise; + sr->isr_intval = se->se_intval; + sr->isr_capinfo = se->se_capinfo; + sr->isr_erp = se->se_erp; + IEEE80211_ADDR_COPY(sr->isr_bssid, se->se_bssid); + nr = min(se->se_rates[1], IEEE80211_RATE_MAXSIZE); + memcpy(sr->isr_rates, se->se_rates+2, nr); + nxr = min(se->se_xrates[1], IEEE80211_RATE_MAXSIZE - nr); + memcpy(sr->isr_rates+nr, se->se_xrates+2, nxr); + sr->isr_nrates = nr + nxr; + + cp = (u_int8_t *)(sr+1); + memcpy(cp, se->se_ssid+2, sr->isr_ssid_len); + cp += sr->isr_ssid_len; + if (sr->isr_ie_len) { + if (se->se_wpa_ie != NULL) { + memcpy(cp, se->se_wpa_ie, 2+se->se_wpa_ie[1]); + cp += 2+se->se_wpa_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]; + } } - sr->isr_rssi = ic->ic_node_getrssi(ni); - sr->isr_intval = ni->ni_intval; - sr->isr_capinfo = ni->ni_capinfo; - sr->isr_erp = ni->ni_erp; - IEEE80211_ADDR_COPY(sr->isr_bssid, ni->ni_bssid); - sr->isr_nrates = ni->ni_rates.rs_nrates; - if (sr->isr_nrates > 15) - sr->isr_nrates = 15; - memcpy(sr->isr_rates, ni->ni_rates.rs_rates, sr->isr_nrates); + + req->space -= len; + req->sr = (struct scan_result_old *)(((u_int8_t *)sr) + len); } static int old_getscanresults(struct ieee80211com *ic, struct ieee80211req *ireq) { - union { - struct scan_result_old res; - char data[512]; /* XXX shrink? */ - } u; - struct scan_result_old *sr = &u.res; - struct ieee80211_node_table *nt; - struct ieee80211_node *ni; - int error, space; - u_int8_t *p, *cp; + struct oscanreq req; + int error; + + if (ireq->i_len < sizeof(struct scan_result_old)) + return EFAULT; - p = ireq->i_data; - space = ireq->i_len; error = 0; - /* XXX locking */ - nt = &ic->ic_scan; - TAILQ_FOREACH(ni, &nt->nt_node, ni_list) { - /* NB: skip pre-scan node state */ - if (ni->ni_chan == IEEE80211_CHAN_ANYC) - continue; - old_get_scan_result(sr, ni); - if (sr->isr_len > sizeof(u)) - continue; /* XXX */ - if (space < sr->isr_len) - break; - cp = (u_int8_t *)(sr+1); - memcpy(cp, ni->ni_essid, ni->ni_esslen); - cp += ni->ni_esslen; - if (sr->isr_ie_len) { - if (ni->ni_wpa_ie != NULL) { - memcpy(cp, ni->ni_wpa_ie, 2+ni->ni_wpa_ie[1]); - cp += 2+ni->ni_wpa_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]; - } - } - error = copyout(sr, p, sr->isr_len); - if (error) - break; - p += sr->isr_len; - space -= sr->isr_len; - } - ireq->i_len -= space; + req.space = 0; + ieee80211_scan_iterate(ic, old_get_scan_space, &req); + if (req.space > ireq->i_len) + req.space = ireq->i_len; + if (req.space > 0) { + size_t space; + void *p; + + space = req.space; + /* XXX M_WAITOK after driver lock released */ + MALLOC(p, void *, space, M_TEMP, M_NOWAIT | M_ZERO); + if (p == NULL) + return ENOMEM; + req.sr = p; + ieee80211_scan_iterate(ic, old_get_scan_result, &req); + ireq->i_len = space - req.space; + error = copyout(p, ireq->i_data, ireq->i_len); + FREE(p, M_TEMP); + } else + ireq->i_len = 0; + return error; } #endif /* COMPAT_FREEBSD6 */ @@ -970,6 +1005,11 @@ case IEEE80211_IOC_WPAIE2: error = ieee80211_ioctl_getwpaie(ic, ireq, ireq->i_type); break; +#ifdef COMPAT_FREEBSD6 + case IEEE80211_IOC_SCAN_RESULTS_OLD: + error = old_getscanresults(ic, ireq); + break; +#endif case IEEE80211_IOC_SCAN_RESULTS: error = ieee80211_ioctl_getscanresults(ic, ireq); break;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200612290735.kBT7Z7QM074840>