-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Attached is a patch to enable scan support for the ndisulator following the recent changes to the ieee80211 layer and to the ifconfig(8) utility. It could probably use some more testing as I don't have access to many APs, but it's working fine here with 4 APs in range. Any feedback, positive or negative, would be greatly appreciated. Steph -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.0 (FreeBSD) Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org iD8DBQFB+wEVmdOXtTCX/nsRArL6AJ9bPLgNEQ1c+D/D1TrC+8ls5INPYgCg5w+d JiXqrg6jt/e6ZBt28ndKL5g= =kn6d -----END PGP SIGNATURE----- Index: if_ndis.c =================================================================== RCS file: /home/FreeBSD/ncvs/src/sys/dev/if_ndis/if_ndis.c,v retrieving revision 1.76 diff -u -r1.76 if_ndis.c --- if_ndis.c 24 Jan 2005 18:18:12 -0000 1.76 +++ if_ndis.c 29 Jan 2005 02:55:59 -0000 _at__at_ -107,6 +107,8 _at__at_ static int ndis_ioctl (struct ifnet *, u_long, caddr_t); static int ndis_wi_ioctl_get (struct ifnet *, u_long, caddr_t); static int ndis_wi_ioctl_set (struct ifnet *, u_long, caddr_t); +static int ndis_80211_ioctl_get (struct ifnet *, u_long, caddr_t); +static int ndis_80211_ioctl_set (struct ifnet *, u_long, caddr_t); static void ndis_init (void *); static void ndis_stop (struct ndis_softc *); static void ndis_watchdog (struct ifnet *); _at__at_ -1973,6 +1975,18 _at__at_ ifp->if_hwassist = 0; ndis_set_offload(sc); break; + case SIOCG80211: + if (sc->ndis_80211) + error = ndis_80211_ioctl_get(ifp, command, data); + else + error = ENOTTY; + break; + case SIOCS80211: + if (sc->ndis_80211) + error = ndis_80211_ioctl_set(ifp, command, data); + else + error = ENOTTY; + break; case SIOCGIFGENERIC: case SIOCSIFGENERIC: if (sc->ndis_80211 && NDIS_INITIALIZED(sc)) { _at__at_ -2121,6 +2135,119 _at__at_ return (error); } +static int +ndis_80211_ioctl_get(struct ifnet *ifp, u_long command, caddr_t data) +{ + struct ndis_softc *sc; + struct ieee80211req *ireq; + ndis_80211_bssid_list_ex *bl; + ndis_wlan_bssid_ex *wb; + struct ieee80211req_scan_result *sr, *bsr; + int error, len, i, j; + char *cp; + + sc = ifp->if_softc; + ireq = (struct ieee80211req *) data; + + switch (ireq->i_type) { + case IEEE80211_IOC_SCAN_RESULTS: + len = 0; + error = ndis_get_info(sc, OID_802_11_BSSID_LIST, NULL, &len); + if (error != ENOSPC) + break; + bl = malloc(len, M_DEVBUF, M_WAITOK | M_ZERO); + error = ndis_get_info(sc, OID_802_11_BSSID_LIST, bl, &len); + if (error) { + free(bl, M_DEVBUF); + break; + } + sr = bsr = malloc(ireq->i_len, M_DEVBUF, M_WAITOK | M_ZERO); + wb = bl->nblx_bssid; + len = 0; + for (i = 0; i < bl->nblx_items; i++) { + /* + * Check if we have enough space left for this ap + */ + j = roundup(sizeof(*sr) + wb->nwbx_ssid.ns_ssidlen + + wb->nwbx_ielen - sizeof(struct ndis_80211_fixed_ies), + sizeof(uint32_t)); + if (len + j > ireq->i_len) + break; + bcopy(&wb->nwbx_macaddr, &sr->isr_bssid, sizeof(sr->isr_bssid)); + if (wb->nwbx_privacy) + sr->isr_capinfo |= IEEE80211_CAPINFO_PRIVACY; + sr->isr_rssi = wb->nwbx_rssi + 200; + sr->isr_freq = wb->nwbx_config.nc_dsconfig / 1000; + sr->isr_intval = wb->nwbx_config.nc_beaconperiod; + switch (wb->nwbx_netinfra) { + case NDIS_80211_NET_INFRA_IBSS: + sr->isr_capinfo |= IEEE80211_CAPINFO_IBSS; + break; + case NDIS_80211_NET_INFRA_BSS: + sr->isr_capinfo |= IEEE80211_CAPINFO_ESS; + break; + } + for (j = 0; j < sizeof(sr->isr_rates); j++) { + /* XXX - check units */ + if (wb->nwbx_supportedrates[j] == 0) + break; + sr->isr_rates[j] = wb->nwbx_supportedrates[j] & 0x7f; + } + sr->isr_nrates = j; + sr->isr_ssid_len = wb->nwbx_ssid.ns_ssidlen; + cp = (char *)sr + sizeof(*sr); + bcopy(&wb->nwbx_ssid.ns_ssid, cp, sr->isr_ssid_len); + cp += sr->isr_ssid_len; + sr->isr_ie_len = wb->nwbx_ielen + - sizeof(struct ndis_80211_fixed_ies); + bcopy((char *)wb->nwbx_ies + sizeof(struct ndis_80211_fixed_ies), + cp, sr->isr_ie_len); + sr->isr_len = roundup(sizeof(*sr) + sr->isr_ssid_len + + sr->isr_ie_len, sizeof(uint32_t)); + len += sr->isr_len; + sr = (struct ieee80211req_scan_result *)((char *)sr + sr->isr_len); + wb = (ndis_wlan_bssid_ex *)((char *)wb + wb->nwbx_len); + } + ireq->i_len = len; + error = copyout(bsr, ireq->i_data, len); + free(bl, M_DEVBUF); + free(bsr, M_DEVBUF); + break; + default: + error = ieee80211_ioctl(&sc->ic, command, data); + } + + return(error); +} + +static int +ndis_80211_ioctl_set(struct ifnet *ifp, u_long command, caddr_t data) +{ + struct ndis_softc *sc; + struct ieee80211req *ireq; + int error, len; + + sc = ifp->if_softc; + ireq = (struct ieee80211req *) data; + + switch (ireq->i_type) { + case IEEE80211_IOC_SCAN_REQ: + len = 0; + error = ndis_set_info(sc, OID_802_11_BSSID_LIST_SCAN, NULL, &len); + tsleep(&error, PPAUSE|PCATCH, "ssidscan", hz * 2); + rt_ieee80211msg(ifp, RTM_IEEE80211_SCAN, NULL, 0); + break; + default: + error = ieee80211_ioctl(&sc->ic, command, data); + if (error == ENETRESET) { + ndis_setstate_80211(sc); + error = 0; + } + } + + return(error); +} + static void ndis_watchdog(ifp) struct ifnet *ifp;Received on Sat Jan 29 2005 - 02:20:55 UTC
This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:38:27 UTC