📄 large-scan-results-r1626.patch
字号:
diff -ru madwifi-ng/net80211/ieee80211_scan.c madwifi-ng-1626-patched/net80211/ieee80211_scan.c
--- madwifi-ng/net80211/ieee80211_scan.c 2006-06-03 01:07:01.000000000 -0700
+++ madwifi-ng-1626-patched/net80211/ieee80211_scan.c 2006-06-03 03:38:06.000000000 -0700
@@ -922,14 +922,17 @@
/*
* Iterate over the contents of the scan cache.
*/
-void
+int
ieee80211_scan_iterate(struct ieee80211com *ic,
ieee80211_scan_iter_func *f, void *arg)
{
- struct ieee80211_scan_state *ss = ic->ic_scan;
-
- if (ss->ss_ops != NULL)
- ss->ss_ops->scan_iterate(ss, f, arg);
+ int res = 0;
+ struct ieee80211_scan_state *ss = ic->ic_scan;
+
+ if (ss->ss_ops != NULL) {
+ res = ss->ss_ops->scan_iterate(ss, f, arg);
+ }
+ return res;
}
/*
Only in madwifi-ng-1626-patched/net80211: ieee80211_scan.c.patched
diff -ru madwifi-ng/net80211/ieee80211_scan.h madwifi-ng-1626-patched/net80211/ieee80211_scan.h
--- madwifi-ng/net80211/ieee80211_scan.h 2006-06-03 01:07:01.000000000 -0700
+++ madwifi-ng-1626-patched/net80211/ieee80211_scan.h 2006-06-03 00:23:24.000000000 -0700
@@ -113,8 +113,8 @@
void ieee80211_scan_flush(struct ieee80211com *);
struct ieee80211_scan_entry;
-typedef void ieee80211_scan_iter_func(void *, const struct ieee80211_scan_entry *);
-void ieee80211_scan_iterate(struct ieee80211com *, ieee80211_scan_iter_func, void *);
+typedef int ieee80211_scan_iter_func(void *, const struct ieee80211_scan_entry *);
+int ieee80211_scan_iterate(struct ieee80211com *, ieee80211_scan_iter_func, void *);
/*
* Parameters supplied when adding/updating an entry in a
@@ -205,7 +205,7 @@
void (*scan_assoc_success)(struct ieee80211_scan_state *,
const u_int8_t macaddr[IEEE80211_ADDR_LEN]);
/* iterate over entries in the scan cache */
- void (*scan_iterate)(struct ieee80211_scan_state *,
+ int (*scan_iterate)(struct ieee80211_scan_state *,
ieee80211_scan_iter_func *, void *);
/* default action to take when found scan match */
int (*scan_default)(struct ieee80211vap *,
diff -ru madwifi-ng/net80211/ieee80211_scan_ap.c madwifi-ng-1626-patched/net80211/ieee80211_scan_ap.c
--- madwifi-ng/net80211/ieee80211_scan_ap.c 2006-06-03 01:07:01.000000000 -0700
+++ madwifi-ng-1626-patched/net80211/ieee80211_scan_ap.c 2006-06-03 00:26:04.000000000 -0700
@@ -367,11 +367,12 @@
/* XXX is there anything meaningful to do? */
}
-static void
+static int
ap_iterate(struct ieee80211_scan_state *ss,
ieee80211_scan_iter_func *f, void *arg)
{
/* NB: nothing meaningful we can do */
+ return 0;
}
static void
diff -ru madwifi-ng/net80211/ieee80211_scan_sta.c madwifi-ng-1626-patched/net80211/ieee80211_scan_sta.c
--- madwifi-ng/net80211/ieee80211_scan_sta.c 2006-06-03 01:07:01.000000000 -0700
+++ madwifi-ng-1626-patched/net80211/ieee80211_scan_sta.c 2006-06-03 03:37:02.000000000 -0700
@@ -1050,13 +1050,14 @@
* Iterate over the entries in the scan cache, invoking
* the callback function on each one.
*/
-static void
+static int
sta_iterate(struct ieee80211_scan_state *ss,
ieee80211_scan_iter_func *f, void *arg)
{
struct sta_table *st = ss->ss_priv;
struct sta_entry *se;
u_int gen;
+ int res = 0;
spin_lock(&st->st_scanlock);
gen = st->st_scangen++;
@@ -1068,13 +1069,22 @@
/* update public state */
se->base.se_age = jiffies - se->se_lastupdate;
spin_unlock(&st->st_lock);
- (*f)(arg, &se->base);
+ res = (*f)(arg, &se->base);
+
+ if(res != 0) {
+ /* We probably ran out of buffer space. */
+ goto done;
+ }
goto restart;
}
}
+
spin_unlock(&st->st_lock);
+ done:
spin_unlock(&st->st_scanlock);
+
+ return res;
}
static void
diff -ru madwifi-ng/net80211/ieee80211_wireless.c madwifi-ng-1626-patched/net80211/ieee80211_wireless.c
--- madwifi-ng/net80211/ieee80211_wireless.c 2006-06-03 01:07:01.000000000 -0700
+++ madwifi-ng-1626-patched/net80211/ieee80211_wireless.c 2006-06-03 03:29:10.000000000 -0700
@@ -1338,14 +1338,14 @@
int i;
};
-static void
+static int
waplist_cb(void *arg, const struct ieee80211_scan_entry *se)
{
struct waplistreq *req = arg;
int i = req->i;
if (i >= IW_MAX_AP)
- return;
+ return 0;
req->addr[i].sa_family = ARPHRD_ETHER;
if (req->vap->iv_opmode == IEEE80211_M_HOSTAP)
IEEE80211_ADDR_COPY(req->addr[i].sa_data, se->se_macaddr);
@@ -1353,6 +1353,8 @@
IEEE80211_ADDR_COPY(req->addr[i].sa_data, se->se_bssid);
set_quality(&req->qual[i], se->se_rssi);
req->i = i + 1;
+
+ return 0;
}
static int
@@ -1435,13 +1437,14 @@
int mode;
};
-static void
+static int
giwscan_cb(void *arg, const struct ieee80211_scan_entry *se)
{
struct iwscanreq *req = arg;
struct ieee80211vap *vap = req->vap;
char *current_ev = req->current_ev;
char *end_buf = req->end_buf;
+ char *last_ev;
#if WIRELESS_EXT > 14
char buf[64 * 2 + 30];
#endif
@@ -1450,12 +1453,13 @@
int j;
if (current_ev >= end_buf)
- return;
+ return E2BIG;
/* WPA/!WPA sort criteria */
if ((req->mode != 0) ^ (se->se_wpa_ie != NULL))
- return;
+ return 0;
memset(&iwe, 0, sizeof(iwe));
+ last_ev = current_ev;
iwe.cmd = SIOCGIWAP;
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
if (vap->iv_opmode == IEEE80211_M_HOSTAP)
@@ -1464,7 +1468,12 @@
IEEE80211_ADDR_COPY(iwe.u.ap_addr.sa_data, se->se_bssid);
current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_ADDR_LEN);
+ /* We ran out of space in the buffer. */
+ if (last_ev == current_ev)
+ return E2BIG;
+
memset(&iwe, 0, sizeof(iwe));
+ last_ev = current_ev;
iwe.cmd = SIOCGIWESSID;
iwe.u.data.flags = 1;
if (vap->iv_opmode == IEEE80211_M_HOSTAP) {
@@ -1478,29 +1487,49 @@
end_buf, &iwe, (char *) se->se_ssid+2);
}
+ /* We ran out of space in the buffer. */
+ if (last_ev == current_ev)
+ return E2BIG;
+
if (se->se_capinfo & (IEEE80211_CAPINFO_ESS|IEEE80211_CAPINFO_IBSS)) {
memset(&iwe, 0, sizeof(iwe));
+ last_ev = current_ev;
iwe.cmd = SIOCGIWMODE;
iwe.u.mode = se->se_capinfo & IEEE80211_CAPINFO_ESS ?
IW_MODE_MASTER : IW_MODE_ADHOC;
current_ev = iwe_stream_add_event(current_ev,
end_buf, &iwe, IW_EV_UINT_LEN);
+
+ /* We ran out of space in the buffer. */
+ if (last_ev == current_ev)
+ return E2BIG;
}
memset(&iwe, 0, sizeof(iwe));
+ last_ev = current_ev;
iwe.cmd = SIOCGIWFREQ;
iwe.u.freq.m = se->se_chan->ic_freq * 100000;
iwe.u.freq.e = 1;
current_ev = iwe_stream_add_event(current_ev,
end_buf, &iwe, IW_EV_FREQ_LEN);
+ /* We ran out of space in the buffer. */
+ if (last_ev == current_ev)
+ return E2BIG;
+
memset(&iwe, 0, sizeof(iwe));
+ last_ev = current_ev;
iwe.cmd = IWEVQUAL;
set_quality(&iwe.u.qual, se->se_rssi);
current_ev = iwe_stream_add_event(current_ev,
end_buf, &iwe, IW_EV_QUAL_LEN);
+ /* We ran out of space in the buffer */
+ if (last_ev == current_ev)
+ return E2BIG;
+
memset(&iwe, 0, sizeof(iwe));
+ last_ev = current_ev;
iwe.cmd = SIOCGIWENCODE;
if (se->se_capinfo & IEEE80211_CAPINFO_PRIVACY)
iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
@@ -1509,7 +1538,12 @@
iwe.u.data.length = 0;
current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, "");
+ /* We ran out of space in the buffer. */
+ if (last_ev == current_ev)
+ return E2BIG;
+
memset(&iwe, 0, sizeof(iwe));
+ last_ev = current_ev;
iwe.cmd = SIOCGIWRATE;
current_val = current_ev + IW_EV_LCP_LEN;
/* NB: not sorted, does it matter? */
@@ -1532,17 +1566,28 @@
}
}
/* remove fixed header if no rates were added */
- if ((current_val - current_ev) > IW_EV_LCP_LEN)
+ if ((current_val - current_ev) > IW_EV_LCP_LEN) {
current_ev = current_val;
+ } else {
+ /* We ran out of space in the buffer. */
+ if (last_ev == current_ev)
+ return E2BIG;
+ }
#if WIRELESS_EXT > 14
memset(&iwe, 0, sizeof(iwe));
+ last_ev = current_ev;
iwe.cmd = IWEVCUSTOM;
snprintf(buf, sizeof(buf), "bcn_int=%d", se->se_intval);
iwe.u.data.length = strlen(buf);
current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, buf);
+ /* We ran out of space in the buffer. */
+ if (last_ev == current_ev)
+ return E2BIG;
+
if (se->se_rsn_ie != NULL) {
+ last_ev = current_ev;
#ifdef IWEVGENIE
memset(&iwe, 0, sizeof(iwe));
memcpy(buf, se->se_rsn_ie, se->se_rsn_ie[1] + 2);
@@ -1557,12 +1602,18 @@
se->se_rsn_ie, se->se_rsn_ie[1] + 2,
rsn_leader, sizeof(rsn_leader) - 1);
#endif
- if (iwe.u.data.length != 0)
+ if (iwe.u.data.length != 0) {
current_ev = iwe_stream_add_point(current_ev, end_buf,
&iwe, buf);
+
+ /* We ran out of space in the buffer */
+ if (last_ev == current_ev)
+ return E2BIG;
+ }
}
if (se->se_wpa_ie != NULL) {
+ last_ev = current_ev;
#ifdef IWEVGENIE
memset(&iwe, 0, sizeof(iwe));
memcpy(buf, se->se_wpa_ie, se->se_wpa_ie[1] + 2);
@@ -1576,36 +1627,56 @@
se->se_wpa_ie, se->se_wpa_ie[1] + 2,
wpa_leader, sizeof(wpa_leader) - 1);
#endif
- if (iwe.u.data.length != 0)
+ if (iwe.u.data.length != 0) {
current_ev = iwe_stream_add_point(current_ev, end_buf,
&iwe, buf);
+
+ /* We ran out of space in the buffer. */
+ if (last_ev == current_ev)
+ return E2BIG;
+ }
+
}
if (se->se_wme_ie != NULL) {
static const char wme_leader[] = "wme_ie=";
memset(&iwe, 0, sizeof(iwe));
+ last_ev = current_ev;
iwe.cmd = IWEVCUSTOM;
iwe.u.data.length = encode_ie(buf, sizeof(buf),
se->se_wme_ie, se->se_wme_ie[1] + 2,
wme_leader, sizeof(wme_leader) - 1);
- if (iwe.u.data.length != 0)
+ if (iwe.u.data.length != 0) {
current_ev = iwe_stream_add_point(current_ev, end_buf,
&iwe, buf);
+
+ /* We ran out of space in the buffer. */
+ if (last_ev == current_ev)
+ return E2BIG;
+ }
}
if (se->se_ath_ie != NULL) {
static const char ath_leader[] = "ath_ie=";
memset(&iwe, 0, sizeof(iwe));
+ last_ev = current_ev;
iwe.cmd = IWEVCUSTOM;
iwe.u.data.length = encode_ie(buf, sizeof(buf),
se->se_ath_ie, se->se_ath_ie[1] + 2,
ath_leader, sizeof(ath_leader) - 1);
- if (iwe.u.data.length != 0)
+ if (iwe.u.data.length != 0) {
current_ev = iwe_stream_add_point(current_ev, end_buf,
&iwe, buf);
+
+ /* We ran out of space in the buffer. */
+ if (last_ev == current_ev)
+ return E2BIG;
+ }
}
#endif /* WIRELESS_EXT > 14 */
req->current_ev = current_ev;
+
+ return 0;
}
static int
@@ -1615,12 +1686,20 @@
struct ieee80211vap *vap = dev->priv;
struct ieee80211com *ic = vap->iv_ic;
struct iwscanreq req;
+ int res = 0;
req.vap = vap;
req.current_ev = extra;
- req.end_buf = extra + IW_SCAN_MAX_DATA;
+ if (data->length == 0) {
+ req.end_buf = extra + IW_SCAN_MAX_DATA;
+ } else {
+ req.end_buf = extra + data->length;
+ }
/*
+ * NB: This is no longer needed, as long as the caller supports
+ * large scan results.
+ *
* Do two passes to ensure WPA/non-WPA scan candidates
* are sorted to the front. This is a hack to deal with
* the wireless extensions capping scan results at
@@ -1630,12 +1709,19 @@
* guarantee we won't overflow anyway.
*/
req.mode = vap->iv_flags & IEEE80211_F_WPA;
- ieee80211_scan_iterate(ic, giwscan_cb, &req);
- req.mode = req.mode ? 0 : IEEE80211_F_WPA;
- ieee80211_scan_iterate(ic, giwscan_cb, &req);
+ res = ieee80211_scan_iterate(ic, giwscan_cb, &req);
+ if (res == 0) {
+ req.mode = req.mode ? 0 : IEEE80211_F_WPA;
+ res = ieee80211_scan_iterate(ic, giwscan_cb, &req);
+ }
data->length = req.current_ev - extra;
- return 0;
+
+ if (res != 0) {
+ return -res;
+ }
+
+ return res;
}
#endif /* SIOCGIWSCAN */
@@ -2823,20 +2909,22 @@
/*
* Match mac address and any ssid.
*/
-static void
+static int
mlmelookup(void *arg, const struct ieee80211_scan_entry *se)
{
struct scanlookup *look = arg;
if (!IEEE80211_ADDR_EQ(look->mac, se->se_macaddr))
- return;
+ return 0;
if (look->esslen != 0) {
if (se->se_ssid[1] != look->esslen)
- return;
+ return 0;
if (memcmp(look->essid, se->se_ssid + 2, look->esslen))
- return;
+ return 0;
}
look->se = se;
+
+ return 0;
}
static int
@@ -3340,16 +3428,18 @@
se->se_ssid[1] + *ielen, sizeof(u_int32_t));
}
-static void
+static int
get_scan_space(void *arg, const struct ieee80211_scan_entry *se)
{
struct scanreq *req = arg;
int ielen;
req->space += scan_space(se, &ielen);
+
+ return 0;
}
-static void
+static int
get_scan_result(void *arg, const struct ieee80211_scan_entry *se)
{
struct scanreq *req = arg;
@@ -3358,8 +3448,10 @@
u_int8_t *cp;
len = scan_space(se, &ielen);
- if (len > req->space)
- return;
+ if (len > req->space) {
+ printk("[madwifi] %s() : Not enough space.\n", __FUNCTION__);
+ return 0;
+ }
sr = req->sr;
memset(sr, 0, sizeof(*sr));
@@ -3403,6 +3495,8 @@
req->space -= len;
req->sr = (struct ieee80211req_scan_result *)(((u_int8_t *)sr) + len);
+
+ return 0;
}
static int
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -