summaryrefslogtreecommitdiff
path: root/sys/dev/pcmcia
diff options
context:
space:
mode:
authorMarcus Glocker <mglocker@cvs.openbsd.org>2007-07-08 10:09:04 +0000
committerMarcus Glocker <mglocker@cvs.openbsd.org>2007-07-08 10:09:04 +0000
commite5364898169009014fea0c6cc8b2502881f83ffb (patch)
treebc1d8826618c308eefa89f7c62eb9904af775368 /sys/dev/pcmcia
parent3af16637fc581e5a3b3607fe9d38d4803cfb953b (diff)
Process scan command results. Enable 'ifconfig -M'.
Diffstat (limited to 'sys/dev/pcmcia')
-rw-r--r--sys/dev/pcmcia/if_malo.c132
-rw-r--r--sys/dev/pcmcia/if_malovar.h29
2 files changed, 155 insertions, 6 deletions
diff --git a/sys/dev/pcmcia/if_malo.c b/sys/dev/pcmcia/if_malo.c
index de695df2bc7..a4d252e665c 100644
--- a/sys/dev/pcmcia/if_malo.c
+++ b/sys/dev/pcmcia/if_malo.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_malo.c,v 1.21 2007/07/07 21:17:26 mglocker Exp $ */
+/* $OpenBSD: if_malo.c,v 1.22 2007/07/08 10:09:02 mglocker Exp $ */
/*
* Copyright (c) 2007 Marcus Glocker <mglocker@openbsd.org>
@@ -92,6 +92,8 @@ int cmalo_cmd_get_hwspec(struct malo_softc *);
int cmalo_cmd_rsp_hwspec(struct malo_softc *);
int cmalo_cmd_set_reset(struct malo_softc *);
int cmalo_cmd_set_scan(struct malo_softc *);
+int cmalo_cmd_rsp_scan(struct malo_softc *);
+int cmalo_parse_elements(struct malo_softc *, void *, int, int);
int cmalo_cmd_set_auth(struct malo_softc *);
int cmalo_cmd_set_snmp(struct malo_softc *, uint16_t);
int cmalo_cmd_set_radio(struct malo_softc *, uint16_t);
@@ -339,8 +341,10 @@ cmalo_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
{
struct malo_softc *sc = ifp->if_softc;
struct ieee80211com *ic = &sc->sc_ic;
+ struct ieee80211_nodereq_all *na;
+ struct ieee80211_nodereq *nr;
struct ifaddr *ifa;
- int s, error = 0;
+ int i, j, s, error = 0;
s = splnet();
@@ -362,6 +366,45 @@ cmalo_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
cmalo_stop(sc);
}
break;
+ case SIOCS80211SCAN:
+ cmalo_cmd_set_scan(sc);
+ break;
+ case SIOCG80211ALLNODES:
+ nr = NULL;
+ na = (struct ieee80211_nodereq_all *)data;
+
+ if ((nr = malloc(sizeof(*nr), M_DEVBUF, M_WAITOK)) == NULL)
+ break;
+
+ for (na->na_nodes = i = j = 0; i < sc->sc_networks_num &&
+ (na->na_size >= j + sizeof(struct ieee80211_nodereq));
+ i++) {
+ bzero(nr, sizeof(*nr));
+
+ IEEE80211_ADDR_COPY(nr->nr_macaddr,
+ sc->sc_networks[i].bssid);
+ IEEE80211_ADDR_COPY(nr->nr_bssid,
+ sc->sc_networks[i].bssid);
+ nr->nr_channel = sc->sc_networks[i].channel;
+ nr->nr_chan_flags = IEEE80211_CHAN_B; /* XXX */
+ nr->nr_rssi = sc->sc_networks[i].rssi;
+ nr->nr_max_rssi = 0; /* XXX */
+ nr->nr_nwid_len = strlen(sc->sc_networks[i].ssid);
+ bcopy(sc->sc_networks[i].ssid, nr->nr_nwid,
+ nr->nr_nwid_len);
+ nr->nr_intval = sc->sc_networks[i].beaconintvl;
+ nr->nr_capinfo = sc->sc_networks[i].capinfo;
+ nr->nr_flags |= IEEE80211_NODEREQ_AP;
+
+ bcopy(nr, (caddr_t)na->na_node + j,
+ sizeof(struct ieee80211_nodereq));
+ j += sizeof(struct ieee80211_nodereq);
+ na->na_nodes++;
+ }
+
+ if (nr)
+ free(nr, M_DEVBUF);
+ break;
default:
error = ieee80211_ioctl(ifp, cmd, data);
break;
@@ -594,8 +637,6 @@ cmalo_init(struct ifnet *ifp)
cmalo_cmd_set_snmp(sc, MALO_OID_SHORTRETRY);
cmalo_cmd_set_snmp(sc, MALO_OID_FRAGTRESH);
- cmalo_cmd_set_scan(sc);
-
//cmalo_cmd_set_assoc(sc);
/* device up */
@@ -1071,6 +1112,87 @@ cmalo_cmd_set_scan(struct malo_softc *sc)
}
int
+cmalo_cmd_rsp_scan(struct malo_softc *sc)
+{
+ struct malo_cmd_header *hdr = sc->sc_cmd;
+ struct malo_cmd_body_rsp_scan *body;
+ struct malo_cmd_body_rsp_scan_set *set;
+ uint16_t psize;
+ int i;
+
+ bzero(sc->sc_networks, sizeof(sc->sc_networks));
+ psize = sizeof(*hdr) + sizeof(*body);
+
+ body = (struct malo_cmd_body_rsp_scan *)(hdr + 1);
+
+ DPRINTF(1, "bufsize=%d, APs=%d\n", body->bufsize, body->numofset);
+ sc->sc_networks_num = body->numofset;
+
+ /* cycle through found networks */
+ for (i = 0; i < body->numofset; i++) {
+ set = (struct malo_cmd_body_rsp_scan_set *)(sc->sc_cmd + psize);
+
+ DPRINTF(1, "size=%d, bssid=%s, rssi=%d, beaconintvl=%d, "
+ "capinfo=0x%04x\n",
+ set->size, ether_sprintf(set->bssid), set->rssi,
+ set->beaconintvl, set->capinfo);
+
+ /* save scan results */
+ bcopy(set->bssid, sc->sc_networks[i].bssid, sizeof(set->bssid));
+ bcopy(set->timestamp, sc->sc_networks[i].timestamp,
+ sizeof(set->timestamp));
+ sc->sc_networks[i].rssi = set->rssi;
+ sc->sc_networks[i].beaconintvl = set->beaconintvl;
+ sc->sc_networks[i].capinfo = set->capinfo;
+ cmalo_parse_elements(sc, (set + 1),
+ set->size - (sizeof(*set) - sizeof(set->size)), i);
+
+ psize += (set->size + sizeof(set->size));
+ }
+
+ return (0);
+}
+
+int
+cmalo_parse_elements(struct malo_softc *sc, void *buf, int size, int pos)
+{
+ uint8_t eid, len;
+ int i;
+
+ DPRINTF(2, "element_size=%d, element_pos=%d\n", size, pos);
+
+ for (i = 0; i < size; ) {
+ eid = *(uint8_t *)(buf + i);
+ i++;
+ len = *(uint8_t *)(buf + i);
+ i++;
+ DPRINTF(2, "eid=%d, len=%d, ", eid, len);
+
+ switch (eid) {
+ case IEEE80211_ELEMID_SSID:
+ bcopy(buf + i, sc->sc_networks[pos].ssid, len);
+ DPRINTF(2, "ssid=%s\n", sc->sc_networks[pos].ssid);
+ break;
+ case IEEE80211_ELEMID_RATES:
+ bcopy(buf + i, sc->sc_networks[pos].rates, len);
+ DPRINTF(2, "rates\n", sc->sc_networks[pos].rates);
+ break;
+ case IEEE80211_ELEMID_DSPARMS:
+ sc->sc_networks[pos].channel = *(uint8_t *)(buf + i);
+ DPRINTF(2, "chnl=%d\n", sc->sc_networks[pos].channel);
+ break;
+ default:
+ DPRINTF(2, "unknown\n");
+ break;
+ }
+
+ i += len;
+ }
+
+ return (0);
+}
+
+int
cmalo_cmd_set_auth(struct malo_softc *sc)
{
struct malo_cmd_header *hdr = sc->sc_cmd;
@@ -1595,9 +1717,9 @@ cmalo_cmd_response(struct malo_softc *sc)
/* reset will not send back a response */
break;
case MALO_CMD_SCAN:
- /* do nothing */
DPRINTF(1, "%s: got scan cmd response\n",
sc->sc_dev.dv_xname);
+ cmalo_cmd_rsp_scan(sc);
break;
case MALO_CMD_AUTH:
/* do nothing */
diff --git a/sys/dev/pcmcia/if_malovar.h b/sys/dev/pcmcia/if_malovar.h
index 79e58fe9a0a..e80f161db04 100644
--- a/sys/dev/pcmcia/if_malovar.h
+++ b/sys/dev/pcmcia/if_malovar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_malovar.h,v 1.13 2007/06/30 12:08:57 mglocker Exp $ */
+/* $OpenBSD: if_malovar.h,v 1.14 2007/07/08 10:09:03 mglocker Exp $ */
/*
* Copyright (c) 2007 Marcus Glocker <mglocker@openbsd.org>
@@ -77,6 +77,19 @@ struct malo_cmd_body_scan {
/* malo_cmd_tlv_numprobes */
} __packed;
+struct malo_cmd_body_rsp_scan {
+ uint16_t bufsize;
+ uint8_t numofset;
+} __packed;
+struct malo_cmd_body_rsp_scan_set {
+ uint16_t size;
+ uint8_t bssid[ETHER_ADDR_LEN];
+ uint8_t rssi;
+ uint8_t timestamp[8];
+ uint16_t beaconintvl;
+ uint16_t capinfo;
+} __packed;
+
struct malo_cmd_body_auth {
uint8_t peermac[ETHER_ADDR_LEN];
uint8_t authtype;
@@ -263,6 +276,18 @@ struct malo_tx_desc {
uint8_t reserved[2];
} __packed;
+/* scanned networks */
+struct malo_networks {
+ uint8_t bssid[ETHER_ADDR_LEN];
+ uint8_t rssi;
+ uint8_t timestamp[8];
+ uint16_t beaconintvl;
+ uint16_t capinfo;
+ uint8_t ssid[32];
+ uint8_t rates[14];
+ uint8_t channel;
+} __packed;
+
/*
* Softc
*/
@@ -280,4 +305,6 @@ struct malo_softc {
uint8_t sc_cmd_running;
void *sc_data;
uint8_t sc_curchan;
+ int sc_networks_num;
+ struct malo_networks sc_networks[12];
};