driver_openbsd.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  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. #include "includes.h"
  9. #include <sys/ioctl.h>
  10. #include <net/if.h>
  11. #include <net80211/ieee80211.h>
  12. #include <net80211/ieee80211_crypto.h>
  13. #include <net80211/ieee80211_ioctl.h>
  14. #include "common.h"
  15. #include "driver.h"
  16. struct openbsd_driver_data {
  17. char ifname[IFNAMSIZ + 1];
  18. void *ctx;
  19. int sock; /* open socket for 802.11 ioctls */
  20. };
  21. static int
  22. wpa_driver_openbsd_get_ssid(void *priv, u8 *ssid)
  23. {
  24. struct openbsd_driver_data *drv = priv;
  25. struct ieee80211_nwid nwid;
  26. struct ifreq ifr;
  27. os_memset(&ifr, 0, sizeof(ifr));
  28. os_strlcpy(ifr.ifr_name, drv->ifname, sizeof(ifr.ifr_name));
  29. ifr.ifr_data = (void *)&nwid;
  30. if (ioctl(drv->sock, SIOCG80211NWID, &ifr) < 0 ||
  31. nwid.i_len > IEEE80211_NWID_LEN)
  32. return -1;
  33. os_memcpy(ssid, nwid.i_nwid, nwid.i_len);
  34. return nwid.i_len;
  35. }
  36. static int
  37. wpa_driver_openbsd_get_bssid(void *priv, u8 *bssid)
  38. {
  39. struct openbsd_driver_data *drv = priv;
  40. struct ieee80211_bssid id;
  41. os_strlcpy(id.i_name, drv->ifname, sizeof(id.i_name));
  42. if (ioctl(drv->sock, SIOCG80211BSSID, &id) < 0)
  43. return -1;
  44. os_memcpy(bssid, id.i_bssid, IEEE80211_ADDR_LEN);
  45. return 0;
  46. }
  47. static int
  48. wpa_driver_openbsd_get_capa(void *priv, struct wpa_driver_capa *capa)
  49. {
  50. os_memset(capa, 0, sizeof(*capa));
  51. capa->flags = WPA_DRIVER_FLAGS_4WAY_HANDSHAKE;
  52. return 0;
  53. }
  54. static int
  55. wpa_driver_openbsd_set_key(const char *ifname, void *priv, enum wpa_alg alg,
  56. const unsigned char *addr, int key_idx, int set_tx, const u8 *seq,
  57. size_t seq_len, const u8 *key, size_t key_len)
  58. {
  59. struct openbsd_driver_data *drv = priv;
  60. struct ieee80211_keyavail keyavail;
  61. if (alg != WPA_ALG_PMK || key_len > IEEE80211_PMK_LEN)
  62. return -1;
  63. memset(&keyavail, 0, sizeof(keyavail));
  64. os_strlcpy(keyavail.i_name, drv->ifname, sizeof(keyavail.i_name));
  65. if (wpa_driver_openbsd_get_bssid(priv, keyavail.i_macaddr) < 0)
  66. return -1;
  67. memcpy(keyavail.i_key, key, key_len);
  68. if (ioctl(drv->sock, SIOCS80211KEYAVAIL, &keyavail) < 0)
  69. return -1;
  70. return 0;
  71. }
  72. static void *
  73. wpa_driver_openbsd_init(void *ctx, const char *ifname)
  74. {
  75. struct openbsd_driver_data *drv;
  76. drv = os_zalloc(sizeof(*drv));
  77. if (drv == NULL)
  78. return NULL;
  79. drv->sock = socket(PF_INET, SOCK_DGRAM, 0);
  80. if (drv->sock < 0)
  81. goto fail;
  82. drv->ctx = ctx;
  83. os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname));
  84. return drv;
  85. fail:
  86. os_free(drv);
  87. return NULL;
  88. }
  89. static void
  90. wpa_driver_openbsd_deinit(void *priv)
  91. {
  92. struct openbsd_driver_data *drv = priv;
  93. close(drv->sock);
  94. os_free(drv);
  95. }
  96. const struct wpa_driver_ops wpa_driver_openbsd_ops = {
  97. .name = "openbsd",
  98. .desc = "OpenBSD 802.11 support",
  99. .get_ssid = wpa_driver_openbsd_get_ssid,
  100. .get_bssid = wpa_driver_openbsd_get_bssid,
  101. .get_capa = wpa_driver_openbsd_get_capa,
  102. .set_key = wpa_driver_openbsd_set_key,
  103. .init = wpa_driver_openbsd_init,
  104. .deinit = wpa_driver_openbsd_deinit,
  105. };