xref: /freebsd/contrib/wpa/src/drivers/driver_openbsd.c (revision c1d255d3ffdbe447de3ab875bf4e7d7accc5bfc5)
15b9c547cSRui Paulo /*
25b9c547cSRui Paulo  * Driver interaction with OpenBSD net80211 layer
35b9c547cSRui Paulo  * Copyright (c) 2013, Mark Kettenis
45b9c547cSRui Paulo  *
55b9c547cSRui Paulo  * This software may be distributed under the terms of the BSD license.
65b9c547cSRui Paulo  * See README for more details.
75b9c547cSRui Paulo  */
85b9c547cSRui Paulo 
95b9c547cSRui Paulo #include "includes.h"
105b9c547cSRui Paulo #include <sys/ioctl.h>
115b9c547cSRui Paulo 
125b9c547cSRui Paulo #include <net/if.h>
135b9c547cSRui Paulo #include <net80211/ieee80211.h>
145b9c547cSRui Paulo #include <net80211/ieee80211_crypto.h>
155b9c547cSRui Paulo #include <net80211/ieee80211_ioctl.h>
165b9c547cSRui Paulo 
175b9c547cSRui Paulo #include "common.h"
185b9c547cSRui Paulo #include "driver.h"
195b9c547cSRui Paulo 
205b9c547cSRui Paulo struct openbsd_driver_data {
215b9c547cSRui Paulo 	char ifname[IFNAMSIZ + 1];
225b9c547cSRui Paulo 	void *ctx;
235b9c547cSRui Paulo 
245b9c547cSRui Paulo 	int sock;			/* open socket for 802.11 ioctls */
255b9c547cSRui Paulo };
265b9c547cSRui Paulo 
275b9c547cSRui Paulo 
285b9c547cSRui Paulo static int
wpa_driver_openbsd_get_ssid(void * priv,u8 * ssid)295b9c547cSRui Paulo wpa_driver_openbsd_get_ssid(void *priv, u8 *ssid)
305b9c547cSRui Paulo {
315b9c547cSRui Paulo 	struct openbsd_driver_data *drv = priv;
325b9c547cSRui Paulo 	struct ieee80211_nwid nwid;
335b9c547cSRui Paulo 	struct ifreq ifr;
345b9c547cSRui Paulo 
355b9c547cSRui Paulo 	os_memset(&ifr, 0, sizeof(ifr));
365b9c547cSRui Paulo 	os_strlcpy(ifr.ifr_name, drv->ifname, sizeof(ifr.ifr_name));
375b9c547cSRui Paulo 	ifr.ifr_data = (void *)&nwid;
385b9c547cSRui Paulo 	if (ioctl(drv->sock, SIOCG80211NWID, &ifr) < 0 ||
395b9c547cSRui Paulo 	    nwid.i_len > IEEE80211_NWID_LEN)
405b9c547cSRui Paulo 		return -1;
415b9c547cSRui Paulo 
425b9c547cSRui Paulo 	os_memcpy(ssid, nwid.i_nwid, nwid.i_len);
435b9c547cSRui Paulo 	return nwid.i_len;
445b9c547cSRui Paulo }
455b9c547cSRui Paulo 
465b9c547cSRui Paulo static int
wpa_driver_openbsd_get_bssid(void * priv,u8 * bssid)475b9c547cSRui Paulo wpa_driver_openbsd_get_bssid(void *priv, u8 *bssid)
485b9c547cSRui Paulo {
495b9c547cSRui Paulo 	struct openbsd_driver_data *drv = priv;
505b9c547cSRui Paulo 	struct ieee80211_bssid id;
515b9c547cSRui Paulo 
525b9c547cSRui Paulo 	os_strlcpy(id.i_name, drv->ifname, sizeof(id.i_name));
535b9c547cSRui Paulo 	if (ioctl(drv->sock, SIOCG80211BSSID, &id) < 0)
545b9c547cSRui Paulo 		return -1;
555b9c547cSRui Paulo 
565b9c547cSRui Paulo 	os_memcpy(bssid, id.i_bssid, IEEE80211_ADDR_LEN);
575b9c547cSRui Paulo 	return 0;
585b9c547cSRui Paulo }
595b9c547cSRui Paulo 
605b9c547cSRui Paulo 
615b9c547cSRui Paulo static int
wpa_driver_openbsd_get_capa(void * priv,struct wpa_driver_capa * capa)625b9c547cSRui Paulo wpa_driver_openbsd_get_capa(void *priv, struct wpa_driver_capa *capa)
635b9c547cSRui Paulo {
645b9c547cSRui Paulo 	os_memset(capa, 0, sizeof(*capa));
654bc52338SCy Schubert 	capa->flags = WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_PSK |
664bc52338SCy Schubert 		      WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_8021X;
675b9c547cSRui Paulo 	return 0;
685b9c547cSRui Paulo }
695b9c547cSRui Paulo 
705b9c547cSRui Paulo 
715b9c547cSRui Paulo static int
wpa_driver_openbsd_set_key(void * priv,struct wpa_driver_set_key_params * params)72*c1d255d3SCy Schubert wpa_driver_openbsd_set_key(void *priv, struct wpa_driver_set_key_params *params)
735b9c547cSRui Paulo {
745b9c547cSRui Paulo 	struct openbsd_driver_data *drv = priv;
755b9c547cSRui Paulo 	struct ieee80211_keyavail keyavail;
76*c1d255d3SCy Schubert 	enum key_flag key_flag = params->key_flag;
77*c1d255d3SCy Schubert 	const u8 *key = params->key;
78*c1d255d3SCy Schubert 	size_t key_len = params->key_len;
795b9c547cSRui Paulo 
80*c1d255d3SCy Schubert 	if (key_len > IEEE80211_PMK_LEN ||
81*c1d255d3SCy Schubert 	    (key_flag & KEY_FLAG_PMK_MASK) != KEY_FLAG_PMK) {
825b9c547cSRui Paulo 		return -1;
835b9c547cSRui Paulo 
845b9c547cSRui Paulo 	memset(&keyavail, 0, sizeof(keyavail));
855b9c547cSRui Paulo 	os_strlcpy(keyavail.i_name, drv->ifname, sizeof(keyavail.i_name));
865b9c547cSRui Paulo 	if (wpa_driver_openbsd_get_bssid(priv, keyavail.i_macaddr) < 0)
875b9c547cSRui Paulo 		return -1;
885b9c547cSRui Paulo 	memcpy(keyavail.i_key, key, key_len);
895b9c547cSRui Paulo 
905b9c547cSRui Paulo 	if (ioctl(drv->sock, SIOCS80211KEYAVAIL, &keyavail) < 0)
915b9c547cSRui Paulo 		return -1;
925b9c547cSRui Paulo 
935b9c547cSRui Paulo 	return 0;
945b9c547cSRui Paulo }
955b9c547cSRui Paulo 
965b9c547cSRui Paulo static void *
975b9c547cSRui Paulo wpa_driver_openbsd_init(void *ctx, const char *ifname)
985b9c547cSRui Paulo {
995b9c547cSRui Paulo 	struct openbsd_driver_data *drv;
1005b9c547cSRui Paulo 
1015b9c547cSRui Paulo 	drv = os_zalloc(sizeof(*drv));
1025b9c547cSRui Paulo 	if (drv == NULL)
1035b9c547cSRui Paulo 		return NULL;
1045b9c547cSRui Paulo 
1055b9c547cSRui Paulo 	drv->sock = socket(PF_INET, SOCK_DGRAM, 0);
1065b9c547cSRui Paulo 	if (drv->sock < 0)
1075b9c547cSRui Paulo 		goto fail;
1085b9c547cSRui Paulo 
1095b9c547cSRui Paulo 	drv->ctx = ctx;
1105b9c547cSRui Paulo 	os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname));
1115b9c547cSRui Paulo 
1125b9c547cSRui Paulo 	return drv;
1135b9c547cSRui Paulo 
1145b9c547cSRui Paulo fail:
1155b9c547cSRui Paulo 	os_free(drv);
1165b9c547cSRui Paulo 	return NULL;
1175b9c547cSRui Paulo }
1185b9c547cSRui Paulo 
1195b9c547cSRui Paulo 
1205b9c547cSRui Paulo static void
1215b9c547cSRui Paulo wpa_driver_openbsd_deinit(void *priv)
1225b9c547cSRui Paulo {
1235b9c547cSRui Paulo 	struct openbsd_driver_data *drv = priv;
1245b9c547cSRui Paulo 
1255b9c547cSRui Paulo 	close(drv->sock);
1265b9c547cSRui Paulo 	os_free(drv);
1275b9c547cSRui Paulo }
1285b9c547cSRui Paulo 
1295b9c547cSRui Paulo 
1305b9c547cSRui Paulo const struct wpa_driver_ops wpa_driver_openbsd_ops = {
1315b9c547cSRui Paulo 	.name = "openbsd",
1325b9c547cSRui Paulo 	.desc = "OpenBSD 802.11 support",
1335b9c547cSRui Paulo 	.get_ssid = wpa_driver_openbsd_get_ssid,
1345b9c547cSRui Paulo 	.get_bssid = wpa_driver_openbsd_get_bssid,
1355b9c547cSRui Paulo 	.get_capa = wpa_driver_openbsd_get_capa,
1365b9c547cSRui Paulo 	.set_key = wpa_driver_openbsd_set_key,
1375b9c547cSRui Paulo 	.init = wpa_driver_openbsd_init,
1385b9c547cSRui Paulo 	.deinit = wpa_driver_openbsd_deinit,
1395b9c547cSRui Paulo };
140