]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/wpa/src/drivers/driver_openbsd.c
Update hostapd/wpa_supplicant to 2.8 to fix multiple vulnerabilities.
[FreeBSD/FreeBSD.git] / contrib / wpa / src / drivers / driver_openbsd.c
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));
65         capa->flags = WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_PSK |
66                       WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_8021X;
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 };