Date: Thu, 28 Oct 2004 15:07:48 EDT From: "Rogier R. Mulhuijzen" <lists@bsdchicks.com> To: freebsd-current@freebsd.org Cc: wpaul@freebsd.org Subject: [PATCH] added WEP authmode shared to NDISulator Message-ID: <BasiliX-1.1.0-109899046841814384aabff@artemis.drwilco.net>
next in thread | raw e-mail | index | archive | help
[-- Attachment #1 --] To make the NDISulator do Shared authmode (pretty much required to do WEP it seems, at least on the AP I use): http://bsdchicks.com/patches/if_ndis.patch It includes my previous patch that makes wicontrol -L and dstumbler work. However, I think this one should not be put into FreeBSD at all. Seems to me like net80211 should be patched to make this something universal. I'll spend some time on that in the near future. Unless the way I did this is the way drivers should do it. Comments? In the meanwhile, anyone who wants to use the NDISulator with a WEP enabled network, like me, can abuse this patch. Greetings, DocWilco [-- Attachment #2 --] --- sys/dev/if_ndis/if_ndis.c.orig Wed Oct 27 17:01:55 2004 +++ sys/dev/if_ndis/if_ndis.c Thu Oct 28 19:41:03 2004 @@ -107,6 +107,7 @@ 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_ioctl_authmode (struct ifnet *, u_long, caddr_t); static void ndis_init (void *); static void ndis_stop (struct ndis_softc *); static void ndis_watchdog (struct ifnet *); @@ -1554,7 +1555,14 @@ ic->ic_wep_mode = IEEE80211_WEP_8021X; } #endif - arg = NDIS_80211_AUTHMODE_OPEN; + switch (sc->ndis_80211_authmode) { + case IEEE80211_AUTH_SHARED: + arg = NDIS_80211_AUTHMODE_SHARED; + break; + case IEEE80211_AUTH_OPEN: + default: + arg = NDIS_80211_AUTHMODE_OPEN; + } } else { arg = NDIS_80211_WEPSTAT_DISABLED; len = sizeof(arg); @@ -1565,10 +1573,8 @@ len = sizeof(arg); rval = ndis_set_info(sc, OID_802_11_AUTHENTICATION_MODE, &arg, &len); -#ifdef notyet if (rval) device_printf (sc->ndis_dev, "set auth failed: %d\n", rval); -#endif #ifdef notyet /* Set network type. */ @@ -1911,6 +1917,7 @@ struct ndis_softc *sc = ifp->if_softc; struct ifreq *ifr = (struct ifreq *) data; int i, error = 0; + struct ieee80211req *ireq; /*NDIS_LOCK(sc);*/ @@ -1980,6 +1987,15 @@ error = ENOTTY; if (error != ENOTTY) break; + case SIOCG80211: + case SIOCS80211: + if (sc->ndis_80211 && NDIS_INITIALIZED(sc)) { + ireq = (struct ieee80211req *) data; + if (ireq->i_type == IEEE80211_IOC_AUTHMODE) { + error = ndis_ioctl_authmode(ifp, command, data); + break; + } + } default: sc->ndis_skip = 1; if (sc->ndis_80211) { @@ -2011,7 +2027,9 @@ ndis_80211_bssid_list_ex *bl; ndis_wlan_bssid_ex *wb; struct wi_apinfo *api; - int error, i, j, len, maxaps; + struct wi_scan_p2_hdr *p2; + struct wi_scan_res *res; + int error, i, j, k, len, maxaps; sc = ifp->if_softc; ifr = (struct ifreq *)data; @@ -2073,6 +2091,75 @@ free(bl, M_DEVBUF); error = copyout(&wreq, ifr->ifr_data, sizeof(wreq)); break; + case WI_RID_SCAN_RES: + len = 0; + error = ndis_set_info(sc, OID_802_11_BSSID_LIST_SCAN, + NULL, &len); + if (error == 0) + tsleep(&error, PPAUSE|PCATCH, "ssidscan", hz * 2); + 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; + } + + k = 0; + p2 = (struct wi_scan_p2_hdr *)wreq.wi_val; + res = (void *)&p2[1]; + wb = bl->nblx_bssid; + while ((caddr_t)(res + 1) < (caddr_t)(&wreq + 1) && + k < bl->nblx_items) { + bzero(res, sizeof(*res)); + bcopy(&wb->nwbx_macaddr, &res->wi_bssid, + sizeof(res->wi_bssid)); + res->wi_ssid_len = wb->nwbx_ssid.ns_ssidlen; + bcopy(&wb->nwbx_ssid.ns_ssid, &res->wi_ssid, + res->wi_ssid_len); + if (wb->nwbx_privacy) { + res->wi_capinfo |= IEEE80211_CAPINFO_PRIVACY; + } + /* XXX Where can we get noise information? */ + res->wi_signal = wb->nwbx_rssi + 149; /* XXX */ + res->wi_chan = + ieee80211_mhz2ieee(wb->nwbx_config.nc_dsconfig / + 1000, 0); + /* In "auto" infrastructure mode, this is useless. */ + if (wb->nwbx_netinfra == NDIS_80211_NET_INFRA_IBSS) + res->wi_capinfo |= IEEE80211_CAPINFO_IBSS; + if (wb->nwbx_len > sizeof(ndis_wlan_bssid)) { + j = sizeof(ndis_80211_rates_ex); + /* handle other extended things */ + } else + j = sizeof(ndis_80211_rates); + for (i = res->wi_rate = 0; i < j; i++) + res->wi_rate = MAX(res->wi_rate, + wb->nwbx_supportedrates[i]); + memcpy(res->wi_srates, wb->nwbx_supportedrates, + MIN(j, 10)); + if (j < 10) + res->wi_srates[j] = 0; + res->wi_rsvd = 0; + res++; + wb = (ndis_wlan_bssid_ex *)((char *)wb + wb->nwbx_len); + k++; + } + p2->wi_rsvd = 0; + p2->wi_reason = k; + wreq.wi_len = (sizeof(*p2) + sizeof(*res) * k) / 2; + /* + * XXX: this is _so_ hackish, should probably be fixed in + * wicontrol. That uses a < to compare wi_len to the record + * length. It should probably use <= and be sensible. + */ + wreq.wi_len++; + free(bl, M_DEVBUF); + error = copyout(&wreq, ifr->ifr_data, sizeof(wreq)); + break; default: error = ENOTTY; break; @@ -2115,6 +2202,32 @@ break; } return (error); +} + +static int +ndis_ioctl_authmode(ifp, command, data) + struct ifnet *ifp; + u_long command; + caddr_t data; +{ + struct ndis_softc *sc = ifp->if_softc; + struct ieee80211req *ireq; + + ireq = (struct ieee80211req *) data; + if (command == SIOCG80211) { + ireq->i_val = sc->ndis_80211_authmode; + return 0; + } else { + switch (ireq->i_val) { + case IEEE80211_AUTH_OPEN: + case IEEE80211_AUTH_SHARED: + sc->ndis_80211_authmode = ireq->i_val; + ndis_setstate_80211(sc); + return 0; + default: + return EINVAL; + } + } } static void --- sys/dev/if_ndis/if_ndisvar.h.orig Thu Oct 28 20:16:10 2004 +++ sys/dev/if_ndis/if_ndisvar.h Thu Oct 28 19:23:52 2004 @@ -116,6 +116,7 @@ uint32_t ndis_filter; int ndis_if_flags; int ndis_skip; + uint16_t ndis_80211_authmode; #if __FreeBSD_version < 502113 struct sysctl_ctx_list ndis_ctx;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?BasiliX-1.1.0-109899046841814384aabff>
