From owner-p4-projects@FreeBSD.ORG Fri Dec 29 12:15:54 2006 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 9ED4316A5EF; Fri, 29 Dec 2006 12:15:54 +0000 (UTC) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id B8D5016A82F for ; Fri, 29 Dec 2006 11:45:34 +0000 (UTC) (envelope-from sam@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [69.147.83.41]) by mx1.freebsd.org (Postfix) with ESMTP id E03D513C48A for ; Fri, 29 Dec 2006 11:45:14 +0000 (UTC) (envelope-from sam@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.6/8.13.6) with ESMTP id kBT7Z7Mb074853 for ; Fri, 29 Dec 2006 07:35:07 GMT (envelope-from sam@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.6/8.13.4/Submit) id kBT7Z7QM074840 for perforce@freebsd.org; Fri, 29 Dec 2006 07:35:07 GMT (envelope-from sam@freebsd.org) Date: Fri, 29 Dec 2006 07:35:07 GMT Message-Id: <200612290735.kBT7Z7QM074840@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to sam@freebsd.org using -f From: Sam Leffler To: Perforce Change Reviews Cc: Subject: PERFORCE change 112271 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 29 Dec 2006 12:15:54 -0000 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;