Dmitry Shmidt | 4b9d52f | 2013-02-05 17:44:43 -0800 | [diff] [blame] | 1 | /* |
| 2 | * Driver interaction with OpenBSD net80211 layer |
| 3 | * Copyright (c) 2013, Mark Kettenis |
| 4 | * |
| 5 | * This software may be distributed under the terms of the BSD license. |
| 6 | * See README for more details. |
| 7 | */ |
| 8 | |
| 9 | #include "includes.h" |
| 10 | #include <sys/ioctl.h> |
| 11 | |
| 12 | #include <net/if.h> |
| 13 | #include <net80211/ieee80211.h> |
| 14 | #include <net80211/ieee80211_crypto.h> |
| 15 | #include <net80211/ieee80211_ioctl.h> |
| 16 | |
| 17 | #include "common.h" |
| 18 | #include "driver.h" |
| 19 | |
| 20 | struct openbsd_driver_data { |
| 21 | char ifname[IFNAMSIZ + 1]; |
| 22 | void *ctx; |
| 23 | |
| 24 | int sock; /* open socket for 802.11 ioctls */ |
| 25 | }; |
| 26 | |
| 27 | |
| 28 | static int |
| 29 | wpa_driver_openbsd_get_ssid(void *priv, u8 *ssid) |
| 30 | { |
| 31 | struct openbsd_driver_data *drv = priv; |
| 32 | struct ieee80211_nwid nwid; |
| 33 | struct ifreq ifr; |
| 34 | |
| 35 | os_memset(&ifr, 0, sizeof(ifr)); |
| 36 | os_strlcpy(ifr.ifr_name, drv->ifname, sizeof(ifr.ifr_name)); |
| 37 | ifr.ifr_data = (void *)&nwid; |
| 38 | if (ioctl(drv->sock, SIOCG80211NWID, &ifr) < 0 || |
| 39 | nwid.i_len > IEEE80211_NWID_LEN) |
| 40 | return -1; |
| 41 | |
| 42 | os_memcpy(ssid, nwid.i_nwid, nwid.i_len); |
| 43 | return nwid.i_len; |
| 44 | } |
| 45 | |
| 46 | static int |
| 47 | wpa_driver_openbsd_get_bssid(void *priv, u8 *bssid) |
| 48 | { |
| 49 | struct openbsd_driver_data *drv = priv; |
| 50 | struct ieee80211_bssid id; |
| 51 | |
| 52 | os_strlcpy(id.i_name, drv->ifname, sizeof(id.i_name)); |
| 53 | if (ioctl(drv->sock, SIOCG80211BSSID, &id) < 0) |
| 54 | return -1; |
| 55 | |
| 56 | os_memcpy(bssid, id.i_bssid, IEEE80211_ADDR_LEN); |
| 57 | return 0; |
| 58 | } |
| 59 | |
| 60 | |
| 61 | static int |
| 62 | wpa_driver_openbsd_get_capa(void *priv, struct wpa_driver_capa *capa) |
| 63 | { |
| 64 | os_memset(capa, 0, sizeof(*capa)); |
Hai Shalom | 74f70d4 | 2019-02-11 14:42:39 -0800 | [diff] [blame] | 65 | capa->flags = WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_PSK | |
| 66 | WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_8021X; |
Dmitry Shmidt | 4b9d52f | 2013-02-05 17:44:43 -0800 | [diff] [blame] | 67 | return 0; |
| 68 | } |
| 69 | |
| 70 | |
| 71 | static int |
| 72 | wpa_driver_openbsd_set_key(const char *ifname, void *priv, enum wpa_alg alg, |
| 73 | const unsigned char *addr, int key_idx, int set_tx, const u8 *seq, |
| 74 | size_t seq_len, const u8 *key, size_t key_len) |
| 75 | { |
| 76 | struct openbsd_driver_data *drv = priv; |
| 77 | struct ieee80211_keyavail keyavail; |
| 78 | |
| 79 | if (alg != WPA_ALG_PMK || key_len > IEEE80211_PMK_LEN) |
| 80 | return -1; |
| 81 | |
| 82 | memset(&keyavail, 0, sizeof(keyavail)); |
| 83 | os_strlcpy(keyavail.i_name, drv->ifname, sizeof(keyavail.i_name)); |
| 84 | if (wpa_driver_openbsd_get_bssid(priv, keyavail.i_macaddr) < 0) |
| 85 | return -1; |
| 86 | memcpy(keyavail.i_key, key, key_len); |
| 87 | |
| 88 | if (ioctl(drv->sock, SIOCS80211KEYAVAIL, &keyavail) < 0) |
| 89 | return -1; |
| 90 | |
| 91 | return 0; |
| 92 | } |
| 93 | |
| 94 | static void * |
| 95 | wpa_driver_openbsd_init(void *ctx, const char *ifname) |
| 96 | { |
| 97 | struct openbsd_driver_data *drv; |
| 98 | |
| 99 | drv = os_zalloc(sizeof(*drv)); |
| 100 | if (drv == NULL) |
| 101 | return NULL; |
| 102 | |
| 103 | drv->sock = socket(PF_INET, SOCK_DGRAM, 0); |
| 104 | if (drv->sock < 0) |
| 105 | goto fail; |
| 106 | |
| 107 | drv->ctx = ctx; |
| 108 | os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname)); |
| 109 | |
| 110 | return drv; |
| 111 | |
| 112 | fail: |
| 113 | os_free(drv); |
| 114 | return NULL; |
| 115 | } |
| 116 | |
| 117 | |
| 118 | static void |
| 119 | wpa_driver_openbsd_deinit(void *priv) |
| 120 | { |
| 121 | struct openbsd_driver_data *drv = priv; |
| 122 | |
| 123 | close(drv->sock); |
| 124 | os_free(drv); |
| 125 | } |
| 126 | |
| 127 | |
| 128 | const struct wpa_driver_ops wpa_driver_openbsd_ops = { |
| 129 | .name = "openbsd", |
| 130 | .desc = "OpenBSD 802.11 support", |
| 131 | .get_ssid = wpa_driver_openbsd_get_ssid, |
| 132 | .get_bssid = wpa_driver_openbsd_get_bssid, |
| 133 | .get_capa = wpa_driver_openbsd_get_capa, |
| 134 | .set_key = wpa_driver_openbsd_set_key, |
| 135 | .init = wpa_driver_openbsd_init, |
| 136 | .deinit = wpa_driver_openbsd_deinit, |
| 137 | }; |