]>
Commit | Line | Data |
---|---|---|
5f7ae5e6 MK |
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)); | |
436ee2fd AS |
65 | capa->flags = WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_PSK | |
66 | WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_8021X; | |
5f7ae5e6 MK |
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 | }; |