Add driver for OpenBSD net80211 layer
authorMark Kettenis <kettenis@openbsd.org>
Sun, 3 Feb 2013 19:16:29 +0000 (21:16 +0200)
committerJouni Malinen <j@w1.fi>
Sun, 3 Feb 2013 19:16:29 +0000 (21:16 +0200)
Very basic support for OpenBSD.  No support for scanning yet, so this needs
ap_scan=0 and expects that the user has configured the interface manually
using ifconfig(8).

Signed-hostap: Mark Kettenis <kettenis@openbsd.org>

src/drivers/driver_openbsd.c [new file with mode: 0644]
src/drivers/drivers.c
src/drivers/drivers.mak
src/drivers/drivers.mk

diff --git a/src/drivers/driver_openbsd.c b/src/drivers/driver_openbsd.c
new file mode 100644 (file)
index 0000000..e94eda0
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+ * Driver interaction with OpenBSD net80211 layer
+ * Copyright (c) 2013, Mark Kettenis
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#include "includes.h"
+#include <sys/ioctl.h>
+
+#include <net/if.h>
+#include <net80211/ieee80211.h>
+#include <net80211/ieee80211_crypto.h>
+#include <net80211/ieee80211_ioctl.h>
+
+#include "common.h"
+#include "driver.h"
+
+struct openbsd_driver_data {
+       char ifname[IFNAMSIZ + 1];
+       void *ctx;
+
+       int sock;                       /* open socket for 802.11 ioctls */
+};
+
+
+static int
+wpa_driver_openbsd_get_ssid(void *priv, u8 *ssid)
+{
+       struct openbsd_driver_data *drv = priv;
+       struct ieee80211_nwid nwid;
+       struct ifreq ifr;
+
+       os_memset(&ifr, 0, sizeof(ifr));
+       os_strlcpy(ifr.ifr_name, drv->ifname, sizeof(ifr.ifr_name));
+       ifr.ifr_data = (void *)&nwid;
+       if (ioctl(drv->sock, SIOCG80211NWID, &ifr) < 0 ||
+           nwid.i_len > IEEE80211_NWID_LEN)
+               return -1;
+
+       os_memcpy(ssid, nwid.i_nwid, nwid.i_len);
+       return nwid.i_len;
+}
+
+static int
+wpa_driver_openbsd_get_bssid(void *priv, u8 *bssid)
+{
+       struct openbsd_driver_data *drv = priv;
+       struct ieee80211_bssid id;
+
+       os_strlcpy(id.i_name, drv->ifname, sizeof(id.i_name));
+       if (ioctl(drv->sock, SIOCG80211BSSID, &id) < 0)
+               return -1;
+
+       os_memcpy(bssid, id.i_bssid, IEEE80211_ADDR_LEN);
+       return 0;
+}
+
+
+static int
+wpa_driver_openbsd_get_capa(void *priv, struct wpa_driver_capa *capa)
+{
+       os_memset(capa, 0, sizeof(*capa));
+       capa->flags = WPA_DRIVER_FLAGS_4WAY_HANDSHAKE;
+       return 0;
+}
+
+
+static int
+wpa_driver_openbsd_set_key(const char *ifname, void *priv, enum wpa_alg alg,
+           const unsigned char *addr, int key_idx, int set_tx, const u8 *seq,
+           size_t seq_len, const u8 *key, size_t key_len)
+{
+       struct openbsd_driver_data *drv = priv;
+       struct ieee80211_keyavail keyavail;
+
+       if (alg != WPA_ALG_PMK || key_len > IEEE80211_PMK_LEN)
+               return -1;
+
+       memset(&keyavail, 0, sizeof(keyavail));
+       os_strlcpy(keyavail.i_name, drv->ifname, sizeof(keyavail.i_name));
+       if (wpa_driver_openbsd_get_bssid(priv, keyavail.i_macaddr) < 0)
+               return -1;
+       memcpy(keyavail.i_key, key, key_len);
+
+       if (ioctl(drv->sock, SIOCS80211KEYAVAIL, &keyavail) < 0)
+               return -1;
+
+       return 0;
+}
+
+static void *
+wpa_driver_openbsd_init(void *ctx, const char *ifname)
+{
+       struct openbsd_driver_data *drv;
+
+       drv = os_zalloc(sizeof(*drv));
+       if (drv == NULL)
+               return NULL;
+
+       drv->sock = socket(PF_INET, SOCK_DGRAM, 0);
+       if (drv->sock < 0)
+               goto fail;
+
+       drv->ctx = ctx;
+       os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname));
+
+       return drv;
+
+fail:
+       os_free(drv);
+       return NULL;
+}
+
+
+static void
+wpa_driver_openbsd_deinit(void *priv)
+{
+       struct openbsd_driver_data *drv = priv;
+
+       close(drv->sock);
+       os_free(drv);
+}
+
+
+const struct wpa_driver_ops wpa_driver_openbsd_ops = {
+       .name = "openbsd",
+       .desc = "OpenBSD 802.11 support",
+       .get_ssid = wpa_driver_openbsd_get_ssid,
+       .get_bssid = wpa_driver_openbsd_get_bssid,
+       .get_capa = wpa_driver_openbsd_get_capa,
+       .set_key = wpa_driver_openbsd_set_key,
+       .init = wpa_driver_openbsd_init,
+       .deinit = wpa_driver_openbsd_deinit,
+};
index a92eddf..1d0ff6e 100644 (file)
@@ -24,6 +24,9 @@ extern struct wpa_driver_ops wpa_driver_madwifi_ops; /* driver_madwifi.c */
 #ifdef CONFIG_DRIVER_BSD
 extern struct wpa_driver_ops wpa_driver_bsd_ops; /* driver_bsd.c */
 #endif /* CONFIG_DRIVER_BSD */
+#ifdef CONFIG_DRIVER_OPENBSD
+extern struct wpa_driver_ops wpa_driver_openbsd_ops; /* driver_openbsd.c */
+#endif /* CONFIG_DRIVER_OPENBSD */
 #ifdef CONFIG_DRIVER_NDIS
 extern struct wpa_driver_ops wpa_driver_ndis_ops; /* driver_ndis.c */
 #endif /* CONFIG_DRIVER_NDIS */
@@ -62,6 +65,9 @@ struct wpa_driver_ops *wpa_drivers[] =
 #ifdef CONFIG_DRIVER_BSD
        &wpa_driver_bsd_ops,
 #endif /* CONFIG_DRIVER_BSD */
+#ifdef CONFIG_DRIVER_OPENBSD
+       &wpa_driver_openbsd_ops,
+#endif /* CONFIG_DRIVER_OPENBSD */
 #ifdef CONFIG_DRIVER_NDIS
        &wpa_driver_ndis_ops,
 #endif /* CONFIG_DRIVER_NDIS */
index c7a98d3..68ff910 100644 (file)
@@ -55,6 +55,14 @@ CONFIG_L2_FREEBSD=y
 CONFIG_DNET_PCAP=y
 endif
 
+ifdef CONFIG_DRIVER_OPENBSD
+ifndef CONFIG_L2_PACKET
+CONFIG_L2_PACKET=freebsd
+endif
+DRV_CFLAGS += -DCONFIG_DRIVER_OPENBSD
+DRV_OBJS += ../src/drivers/driver_openbsd.o
+endif
+
 ifdef CONFIG_DRIVER_TEST
 DRV_CFLAGS += -DCONFIG_DRIVER_TEST
 DRV_OBJS += ../src/drivers/driver_test.o
index 23fcbb7..db8561a 100644 (file)
@@ -55,6 +55,14 @@ CONFIG_L2_FREEBSD=y
 CONFIG_DNET_PCAP=y
 endif
 
+ifdef CONFIG_DRIVER_OPENBSD
+ifndef CONFIG_L2_PACKET
+CONFIG_L2_PACKET=freebsd
+endif
+DRV_CFLAGS += -DCONFIG_DRIVER_OPENBSD
+DRV_OBJS += src/drivers/driver_openbsd.c
+endif
+
 ifdef CONFIG_DRIVER_TEST
 DRV_CFLAGS += -DCONFIG_DRIVER_TEST
 DRV_OBJS += src/drivers/driver_test.c