Ticket #509: madwifi-large-scan-results.patch
| File madwifi-large-scan-results.patch, 12.5 kB (added by Chris.Hessing@utah.edu, 6 years ago) |
|---|
-
madwifi-ng/net80211/ieee80211_scan_ap.c
old new 367 367 /* XXX is there anything meaningful to do? */ 368 368 } 369 369 370 static void370 static int 371 371 ap_iterate(struct ieee80211_scan_state *ss, 372 372 ieee80211_scan_iter_func *f, void *arg) 373 373 { 374 374 /* NB: nothing meaningful we can do */ 375 return 0; 375 376 } 376 377 377 378 static void -
madwifi-ng/net80211/ieee80211_scan.c
old new 922 922 /* 923 923 * Iterate over the contents of the scan cache. 924 924 */ 925 void 925 int 926 926 ieee80211_scan_iterate(struct ieee80211com *ic, 927 927 ieee80211_scan_iter_func *f, void *arg) 928 928 { 929 int res = 0; 929 930 struct ieee80211_scan_state *ss = ic->ic_scan; 930 931 931 932 if (ss->ss_ops != NULL) 932 ss->ss_ops->scan_iterate(ss, f, arg); 933 { 934 res = ss->ss_ops->scan_iterate(ss, f, arg); 935 printk("scan iterate returned %d\n", res); 936 } 937 return res; 933 938 } 934 939 935 940 /* -
madwifi-ng/net80211/ieee80211_scan.h
old new 113 113 void ieee80211_scan_flush(struct ieee80211com *); 114 114 115 115 struct ieee80211_scan_entry; 116 typedef voidieee80211_scan_iter_func(void *, const struct ieee80211_scan_entry *);117 voidieee80211_scan_iterate(struct ieee80211com *, ieee80211_scan_iter_func, void *);116 typedef int ieee80211_scan_iter_func(void *, const struct ieee80211_scan_entry *); 117 int ieee80211_scan_iterate(struct ieee80211com *, ieee80211_scan_iter_func, void *); 118 118 119 119 /* 120 120 * Parameters supplied when adding/updating an entry in a … … 205 205 void (*scan_assoc_success)(struct ieee80211_scan_state *, 206 206 const u_int8_t macaddr[IEEE80211_ADDR_LEN]); 207 207 /* iterate over entries in the scan cache */ 208 void(*scan_iterate)(struct ieee80211_scan_state *,209 ieee80211_scan_iter_func *, void *);208 int (*scan_iterate)(struct ieee80211_scan_state *, 209 ieee80211_scan_iter_func *, void *); 210 210 /* default action to take when found scan match */ 211 211 int (*scan_default)(struct ieee80211vap *, 212 212 const struct ieee80211_scan_entry *); -
madwifi-ng/net80211/ieee80211_scan_sta.c
old new 1040 1040 * Iterate over the entries in the scan cache, invoking 1041 1041 * the callback function on each one. 1042 1042 */ 1043 static void1043 static int 1044 1044 sta_iterate(struct ieee80211_scan_state *ss, 1045 1045 ieee80211_scan_iter_func *f, void *arg) 1046 1046 { 1047 1047 struct sta_table *st = ss->ss_priv; 1048 1048 struct sta_entry *se; 1049 1049 u_int gen; 1050 int res = 0; 1050 1051 1051 1052 spin_lock_bh(&st->st_scanlock); 1052 1053 gen = st->st_scangen++; … … 1058 1059 /* update public state */ 1059 1060 se->base.se_age = jiffies - se->se_lastupdate; 1060 1061 spin_unlock(&st->st_lock); 1061 (*f)(arg, &se->base); 1062 res = (*f)(arg, &se->base); 1063 1064 if (res != 0) 1065 { 1066 // We probably ran out of buffer space. 1067 goto done; 1068 } 1062 1069 goto restart; 1063 1070 } 1064 1071 } 1072 1065 1073 spin_unlock(&st->st_lock); 1066 1074 1075 done: 1067 1076 spin_unlock_bh(&st->st_scanlock); 1077 1078 return res; 1068 1079 } 1069 1080 1070 1081 static void -
madwifi-ng/net80211/ieee80211_wireless.c
old new 1330 1330 int i; 1331 1331 }; 1332 1332 1333 static void1333 static int 1334 1334 waplist_cb(void *arg, const struct ieee80211_scan_entry *se) 1335 1335 { 1336 1336 struct waplistreq *req = arg; 1337 1337 int i = req->i; 1338 1338 1339 1339 if (i >= IW_MAX_AP) 1340 return ;1340 return 0; 1341 1341 req->addr[i].sa_family = ARPHRD_ETHER; 1342 1342 if (req->vap->iv_opmode == IEEE80211_M_HOSTAP) 1343 1343 IEEE80211_ADDR_COPY(req->addr[i].sa_data, se->se_macaddr); … … 1345 1345 IEEE80211_ADDR_COPY(req->addr[i].sa_data, se->se_bssid); 1346 1346 set_quality(&req->qual[i], se->se_rssi); 1347 1347 req->i = i + 1; 1348 1349 return 0; 1348 1350 } 1349 1351 1350 1352 static int … … 1427 1429 int mode; 1428 1430 }; 1429 1431 1430 static void1432 static int 1431 1433 giwscan_cb(void *arg, const struct ieee80211_scan_entry *se) 1432 1434 { 1433 1435 struct iwscanreq *req = arg; 1434 1436 struct ieee80211vap *vap = req->vap; 1435 1437 char *current_ev = req->current_ev; 1436 1438 char *end_buf = req->end_buf; 1439 char *last_ev; 1437 1440 #if WIRELESS_EXT > 14 1438 1441 char buf[64 * 2 + 30]; 1439 1442 #endif … … 1442 1445 int j; 1443 1446 1444 1447 if (current_ev >= end_buf) 1445 return; 1448 return E2BIG; 1449 1446 1450 /* WPA/!WPA sort criteria */ 1447 1451 if ((req->mode != 0) ^ (se->se_wpa_ie != NULL)) 1448 return ;1452 return 0; 1449 1453 1450 1454 memset(&iwe, 0, sizeof(iwe)); 1455 last_ev = current_ev; 1451 1456 iwe.cmd = SIOCGIWAP; 1452 1457 iwe.u.ap_addr.sa_family = ARPHRD_ETHER; 1453 1458 if (vap->iv_opmode == IEEE80211_M_HOSTAP) … … 1456 1461 IEEE80211_ADDR_COPY(iwe.u.ap_addr.sa_data, se->se_bssid); 1457 1462 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_ADDR_LEN); 1458 1463 1464 // We ran out of space in the buffer. 1465 if (last_ev == current_ev) 1466 return E2BIG; 1467 1459 1468 memset(&iwe, 0, sizeof(iwe)); 1469 last_ev = current_ev; 1460 1470 iwe.cmd = SIOCGIWESSID; 1461 1471 iwe.u.data.flags = 1; 1462 1472 if (vap->iv_opmode == IEEE80211_M_HOSTAP) { … … 1470 1480 end_buf, &iwe, (char *) se->se_ssid+2); 1471 1481 } 1472 1482 1483 // We ran out of space in the buffer. 1484 if (last_ev == current_ev) 1485 return E2BIG; 1486 1473 1487 if (se->se_capinfo & (IEEE80211_CAPINFO_ESS|IEEE80211_CAPINFO_IBSS)) { 1474 1488 memset(&iwe, 0, sizeof(iwe)); 1489 last_ev = current_ev; 1475 1490 iwe.cmd = SIOCGIWMODE; 1476 1491 iwe.u.mode = se->se_capinfo & IEEE80211_CAPINFO_ESS ? 1477 1492 IW_MODE_MASTER : IW_MODE_ADHOC; 1478 1493 current_ev = iwe_stream_add_event(current_ev, 1479 1494 end_buf, &iwe, IW_EV_UINT_LEN); 1495 1496 // We ran out of space in the buffer. 1497 if (last_ev == current_ev) 1498 return E2BIG; 1480 1499 } 1481 1500 1482 1501 memset(&iwe, 0, sizeof(iwe)); 1502 last_ev = current_ev; 1483 1503 iwe.cmd = SIOCGIWFREQ; 1484 1504 iwe.u.freq.m = se->se_chan->ic_freq * 100000; 1485 1505 iwe.u.freq.e = 1; 1486 1506 current_ev = iwe_stream_add_event(current_ev, 1487 1507 end_buf, &iwe, IW_EV_FREQ_LEN); 1488 1508 1509 // We ran out of space in the buffer. 1510 if (last_ev == current_ev) 1511 return E2BIG; 1512 1489 1513 memset(&iwe, 0, sizeof(iwe)); 1514 last_ev = current_ev; 1490 1515 iwe.cmd = IWEVQUAL; 1491 1516 set_quality(&iwe.u.qual, se->se_rssi); 1492 1517 current_ev = iwe_stream_add_event(current_ev, 1493 1518 end_buf, &iwe, IW_EV_QUAL_LEN); 1494 1519 1520 // We ran out of space in the buffer. 1521 if (last_ev == current_ev) 1522 return E2BIG; 1523 1495 1524 memset(&iwe, 0, sizeof(iwe)); 1525 last_ev = current_ev; 1496 1526 iwe.cmd = SIOCGIWENCODE; 1497 1527 if (se->se_capinfo & IEEE80211_CAPINFO_PRIVACY) 1498 1528 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; … … 1501 1531 iwe.u.data.length = 0; 1502 1532 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, ""); 1503 1533 1534 // We ran out of space in the buffer. 1535 if (last_ev == current_ev) 1536 return E2BIG; 1537 1504 1538 memset(&iwe, 0, sizeof(iwe)); 1539 last_ev = current_ev; 1505 1540 iwe.cmd = SIOCGIWRATE; 1506 1541 current_val = current_ev + IW_EV_LCP_LEN; 1507 1542 /* NB: not sorted, does it matter? */ … … 1525 1560 } 1526 1561 /* remove fixed header if no rates were added */ 1527 1562 if ((current_val - current_ev) > IW_EV_LCP_LEN) 1563 { 1528 1564 current_ev = current_val; 1565 } 1566 else 1567 { 1568 // We ran out of space in the buffer. 1569 if (last_ev == current_ev) 1570 return E2BIG; 1571 } 1529 1572 1530 1573 #if WIRELESS_EXT > 14 1531 1574 memset(&iwe, 0, sizeof(iwe)); 1575 last_ev = current_ev; 1532 1576 iwe.cmd = IWEVCUSTOM; 1533 1577 snprintf(buf, sizeof(buf), "bcn_int=%d", se->se_intval); 1534 1578 iwe.u.data.length = strlen(buf); 1535 1579 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, buf); 1536 1580 1581 // We ran out of space in the buffer. 1582 if (last_ev == current_ev) 1583 return E2BIG; 1584 1537 1585 if (se->se_rsn_ie != NULL) { 1538 1586 static const char rsn_leader[] = "rsn_ie="; 1539 1587 1540 1588 memset(&iwe, 0, sizeof(iwe)); 1589 last_ev = current_ev; 1541 1590 iwe.cmd = IWEVCUSTOM; 1542 1591 if (se->se_rsn_ie[0] == IEEE80211_ELEMID_RSN) 1543 1592 iwe.u.data.length = encode_ie(buf, sizeof(buf), 1544 1593 se->se_rsn_ie, se->se_rsn_ie[1] + 2, 1545 1594 rsn_leader, sizeof(rsn_leader) - 1); 1546 1595 if (iwe.u.data.length != 0) 1596 { 1547 1597 current_ev = iwe_stream_add_point(current_ev, end_buf, 1548 1598 &iwe, buf); 1599 1600 // We ran out of space in the buffer. 1601 if (last_ev == current_ev) 1602 return E2BIG; 1603 } 1549 1604 } 1550 1605 if (se->se_wpa_ie != NULL) { 1551 1606 static const char wpa_leader[] = "wpa_ie="; 1552 1607 1553 1608 memset(&iwe, 0, sizeof(iwe)); 1609 last_ev = current_ev; 1554 1610 iwe.cmd = IWEVCUSTOM; 1555 1611 iwe.u.data.length = encode_ie(buf, sizeof(buf), 1556 1612 se->se_wpa_ie, se->se_wpa_ie[1] + 2, 1557 1613 wpa_leader, sizeof(wpa_leader) - 1); 1558 1614 if (iwe.u.data.length != 0) 1615 { 1559 1616 current_ev = iwe_stream_add_point(current_ev, end_buf, 1560 1617 &iwe, buf); 1618 1619 // We ran out of space in the buffer. 1620 if (last_ev == current_ev) 1621 return E2BIG; 1622 } 1561 1623 } 1562 1624 if (se->se_wme_ie != NULL) { 1563 1625 static const char wme_leader[] = "wme_ie="; 1564 1626 1565 1627 memset(&iwe, 0, sizeof(iwe)); 1628 last_ev = current_ev; 1566 1629 iwe.cmd = IWEVCUSTOM; 1567 1630 iwe.u.data.length = encode_ie(buf, sizeof(buf), 1568 1631 se->se_wme_ie, se->se_wme_ie[1] + 2, 1569 1632 wme_leader, sizeof(wme_leader) - 1); 1570 1633 if (iwe.u.data.length != 0) 1634 { 1571 1635 current_ev = iwe_stream_add_point(current_ev, end_buf, 1572 1636 &iwe, buf); 1637 1638 // We ran out of space in the buffer. 1639 if (last_ev == current_ev) 1640 return E2BIG; 1641 } 1573 1642 } 1574 1643 if (se->se_ath_ie != NULL) { 1575 1644 static const char ath_leader[] = "ath_ie="; 1576 1645 1577 1646 memset(&iwe, 0, sizeof(iwe)); 1647 last_ev = current_ev; 1578 1648 iwe.cmd = IWEVCUSTOM; 1579 1649 iwe.u.data.length = encode_ie(buf, sizeof(buf), 1580 1650 se->se_ath_ie, se->se_ath_ie[1] + 2, 1581 1651 ath_leader, sizeof(ath_leader) - 1); 1582 1652 if (iwe.u.data.length != 0) 1653 { 1583 1654 current_ev = iwe_stream_add_point(current_ev, end_buf, 1584 1655 &iwe, buf); 1656 1657 // We ran out of space in the buffer. 1658 if (last_ev == current_ev) 1659 return E2BIG; 1660 } 1585 1661 } 1586 1662 #endif /* WIRELESS_EXT > 14 */ 1587 1663 req->current_ev = current_ev; 1664 1665 return 0; 1588 1666 } 1589 1667 1590 1668 static int … … 1594 1672 struct ieee80211vap *vap = dev->priv; 1595 1673 struct ieee80211com *ic = vap->iv_ic; 1596 1674 struct iwscanreq req; 1675 int res = 0; 1597 1676 1598 1677 req.vap = vap; 1599 1678 req.current_ev = extra; 1600 req.end_buf = extra + IW_SCAN_MAX_DATA; 1679 if (data->length == 0) 1680 { 1681 req.end_buf = extra + IW_SCAN_MAX_DATA; 1682 } 1683 else 1684 { 1685 req.end_buf = extra + data->length; 1686 } 1601 1687 1602 1688 /* 1689 * XXX -- This is no longer needed, as long as the caller supports 1690 * large scan results. - CH 1691 * 1603 1692 * Do two passes to ensure WPA/non-WPA scan candidates 1604 1693 * are sorted to the front. This is a hack to deal with 1605 1694 * the wireless extensions capping scan results at … … 1609 1698 * guarantee we won't overflow anyway. 1610 1699 */ 1611 1700 req.mode = vap->iv_flags & IEEE80211_F_WPA; 1612 ieee80211_scan_iterate(ic, giwscan_cb, &req); 1613 req.mode = req.mode ? 0 : IEEE80211_F_WPA; 1614 ieee80211_scan_iterate(ic, giwscan_cb, &req); 1701 res = ieee80211_scan_iterate(ic, giwscan_cb, &req); 1702 if (res == 0) 1703 { 1704 req.mode = req.mode ? 0 : IEEE80211_F_WPA; 1705 res = ieee80211_scan_iterate(ic, giwscan_cb, &req); 1706 } 1615 1707 1616 1708 data->length = req.current_ev - extra; 1617 return 0; 1709 1710 if (res != 0) 1711 { 1712 return -res; 1713 } 1714 return res; 1618 1715 } 1619 1716 #endif /* SIOCGIWSCAN */ 1620 1717 … … 2802 2899 /* 2803 2900 * Match mac address and any ssid. 2804 2901 */ 2805 static void2902 static int 2806 2903 mlmelookup(void *arg, const struct ieee80211_scan_entry *se) 2807 2904 { 2808 2905 struct scanlookup *look = arg; 2809 2906 2810 2907 if (!IEEE80211_ADDR_EQ(look->mac, se->se_macaddr)) 2811 return ;2908 return 0; 2812 2909 if (look->esslen != 0) { 2813 2910 if (se->se_ssid[1] != look->esslen) 2814 return ;2911 return 0; 2815 2912 if (memcmp(look->essid, se->se_ssid + 2, look->esslen)) 2816 return ;2913 return 0; 2817 2914 } 2818 2915 look->se = se; 2916 2917 return 0; 2819 2918 } 2820 2919 2821 2920 static int … … 3319 3418 se->se_ssid[1] + *ielen, sizeof(u_int32_t)); 3320 3419 } 3321 3420 3322 static void3421 static int 3323 3422 get_scan_space(void *arg, const struct ieee80211_scan_entry *se) 3324 3423 { 3325 3424 struct scanreq *req = arg; 3326 3425 int ielen; 3327 3426 3328 3427 req->space += scan_space(se, &ielen); 3428 3429 return 0; 3329 3430 } 3330 3431 3331 static void3432 static int 3332 3433 get_scan_result(void *arg, const struct ieee80211_scan_entry *se) 3333 3434 { 3334 3435 struct scanreq *req = arg; … … 3338 3439 3339 3440 len = scan_space(se, &ielen); 3340 3441 if (len > req->space) 3341 return; 3442 { 3443 printk("[madwifi] %s() : Not enough space.\n", __FUNCTION__); 3444 return 0; 3445 } 3342 3446 3343 3447 sr = req->sr; 3344 3448 memset(sr, 0, sizeof(*sr)); … … 3382 3486 3383 3487 req->space -= len; 3384 3488 req->sr = (struct ieee80211req_scan_result *)(((u_int8_t *)sr) + len); 3489 3490 return 0; 3385 3491 } 3386 3492 3387 3493 static int
