I've started using this at 35C3, and it mostly works for me. The one thing it doesn't handle for me is when I change the lladdr, but I have some ideas for it.
I fixed the whitespace, and changed the main bit to use a switch instead of an if elseif dance. This is what I am running right now, what do you think? Index: Makefile =================================================================== RCS file: /cvs/openbsd/ports/security/wpa_supplicant/Makefile,v retrieving revision 1.39 diff -u -p -u -p -r1.39 Makefile --- Makefile 24 Oct 2018 17:16:19 -0000 1.39 +++ Makefile 20 Dec 2018 19:37:31 -0000 @@ -3,7 +3,7 @@ COMMENT= IEEE 802.1X supplicant DISTNAME= wpa_supplicant-2.6 -REVISION= 4 +REVISION= 5 CATEGORIES= security net HOMEPAGE= http://w1.fi/wpa_supplicant/ Index: patches/patch-src_drivers_driver_openbsd_c =================================================================== RCS file: /cvs/openbsd/ports/security/wpa_supplicant/patches/patch-src_drivers_driver_openbsd_c,v retrieving revision 1.5 diff -u -p -u -p -r1.5 patch-src_drivers_driver_openbsd_c --- patches/patch-src_drivers_driver_openbsd_c 17 May 2016 08:29:27 -0000 1.5 +++ patches/patch-src_drivers_driver_openbsd_c 24 Dec 2018 22:46:25 -0000 @@ -1,24 +1,159 @@ $OpenBSD: patch-src_drivers_driver_openbsd_c,v 1.5 2016/05/17 08:29:27 dcoppa Exp $ -Fix includes +Fix includes and react to NWID changes and suspend/resume. ---- src/drivers/driver_openbsd.c.orig Sun Sep 27 21:02:05 2015 -+++ src/drivers/driver_openbsd.c Mon Sep 28 09:51:53 2015 -@@ -9,13 +9,14 @@ +Index: src/drivers/driver_openbsd.c +--- src/drivers/driver_openbsd.c.orig ++++ src/drivers/driver_openbsd.c +@@ -9,19 +9,34 @@ #include "includes.h" #include <sys/ioctl.h> +#include "common.h" +#include "driver.h" ++#include "eloop.h" + ++#include <sys/socket.h> #include <net/if.h> +#include <net/if_var.h> ++#include <net/route.h> #include <net80211/ieee80211.h> #include <net80211/ieee80211_crypto.h> #include <net80211/ieee80211_ioctl.h> -- + -#include "common.h" -#include "driver.h" ++#define RTM_READSZ 2048 struct openbsd_driver_data { - char ifname[IFNAMSIZ + 1]; +- char ifname[IFNAMSIZ + 1]; + void *ctx; + +- int sock; /* open socket for 802.11 ioctls */ ++ char ifname[IFNAMSIZ + 1]; ++ int ifindex; /* Ifindex of the configured interface */ ++ ++ int sock; /* open socket for 802.11 ioctls */ ++ int rtsock; /* routing socket for interface state messages */ ++ ++ /* These fields are used to track the last seen (and associated) access point ++ to determine whether we should kick off an association event */ ++ int nwid_len; /* Length of last seen SSID (as per routing message) */ ++ char nwid[IEEE80211_NWID_LEN]; /* Last seen SSID (as per routing message) */ ++ char addr[IEEE80211_ADDR_LEN]; /* Last seen BSSID (as per routing message) */ + }; + + +@@ -90,6 +105,78 @@ wpa_driver_openbsd_set_key(const char *ifname, void *p + return 0; + } + ++static void ++wpa_driver_openbsd_event_receive(int sock, void *global, void *sock_ctx) ++{ ++ struct openbsd_driver_data *drv = sock_ctx; ++ struct rt_msghdr *rtm; ++ struct if_ieee80211_data *ifie; ++ char *rtmmsg; ++ ssize_t n; ++ ++ rtmmsg = os_zalloc(RTM_READSZ); ++ if (rtmmsg == NULL) { ++ wpa_printf(MSG_ERROR, "Can't allocate space for routing message"); ++ return; ++ } ++ ++ do { ++ n = read(sock, rtmmsg, RTM_READSZ); ++ } while (n == -1 && errno == EINTR); ++ ++ if (n == -1) ++ goto done; ++ ++ rtm = (struct rt_msghdr *)rtmmsg; ++ ++ if ((size_t)n < sizeof(rtm->rtm_msglen) || ++ n < rtm->rtm_msglen || ++ rtm->rtm_version != RTM_VERSION) ++ goto done; ++ ++ if (rtm->rtm_index != drv->ifindex) ++ goto done; ++ ++ switch (rtm->rtm_type) { ++ case RTM_80211INFO: ++ ifie = &((struct if_ieee80211_msghdr *)rtm)->ifim_ifie; ++ ++ if ((ifie->ifie_nwid_len != drv->nwid_len) || ++ (os_memcmp(drv->nwid, ifie->ifie_nwid, ++ ifie->ifie_nwid_len) != 0) || ++ (os_memcmp(drv->addr, ifie->ifie_addr, ++ IEEE80211_ADDR_LEN) != 0)) { ++ os_memcpy(drv->addr, ifie->ifie_addr, ++ IEEE80211_ADDR_LEN); ++ ++ os_memcpy(drv->nwid, ifie->ifie_nwid, ++ ifie->ifie_nwid_len); ++ drv->nwid_len = ifie->ifie_nwid_len; ++ ++ /* Emit ASSOC event */ ++ wpa_supplicant_event(drv->ctx, EVENT_ASSOC, NULL); ++ } ++ break; ++ case RTM_IFINFO: ++ /* This is here so we can react to suspend/resume. ++ * ++ * This is a bit rough, sometimes there are two or more ++ * IFINFOs notifying us that the device just got "up" ++ * again. It doesn't seem to hurt to issue multiple ++ * EVENT_ASSOC in those cases though. ++ */ ++ if (rtm->rtm_flags & RTF_UP) ++ wpa_supplicant_event(drv->ctx, EVENT_ASSOC, NULL); ++ break; ++ default: ++ ;; ++ } ++ ++ ++done: ++ os_free(rtmmsg); ++} ++ + static void * + wpa_driver_openbsd_init(void *ctx, const char *ifname) + { +@@ -103,9 +190,21 @@ wpa_driver_openbsd_init(void *ctx, const char *ifname) + if (drv->sock < 0) + goto fail; + ++ drv->rtsock = socket(PF_ROUTE, SOCK_RAW, AF_UNSPEC); ++ if (drv->rtsock < 0) ++ goto fail; ++ + drv->ctx = ctx; + os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname)); + ++ drv->ifindex = if_nametoindex(drv->ifname); ++ if (drv->ifindex == 0) /* No interface with that name */ ++ goto fail; ++ ++ drv->nwid_len = wpa_driver_openbsd_get_ssid(drv, drv->nwid); ++ wpa_driver_openbsd_get_bssid(drv, drv->addr); ++ ++ eloop_register_read_sock(drv->rtsock, wpa_driver_openbsd_event_receive, NULL, drv); + return drv; + + fail: +@@ -119,7 +218,11 @@ wpa_driver_openbsd_deinit(void *priv) + { + struct openbsd_driver_data *drv = priv; + ++ eloop_unregister_read_sock(drv->rtsock); ++ + close(drv->sock); ++ close(drv->rtsock); ++ + os_free(drv); + } + On 2018 Dec 13 (Thu) at 19:30:11 +0100 (+0100), Gregor Best wrote: : :Hi Mikolaj et al, : :Mikolaj Kucharski <[email protected]> writes: : :> :> Here is debug output of one day session, with suspend in the middle :> when going home, back to work and home again. :> [...] :> Tomorrow I may give you example of above log when walking around the :> office, to compare events while switching APs. :> [...] : :That'd be good, thank you. : :> The other day I did testing by walking around and it works most of the :> time, however there is a race somewhere, as while I was walking around :> I sometimes ended up without connection and ifconfig(8) at the same :> time was showing: :> :> status: active :> ieee80211: join lighthouse chan 100 bssid <random-ap-close> <level>dBm wpaprotos wpa2 wpaakms 802.1x wpaciphers ccmp wpagroupcipher ccmp :> :> like network should work, but it didn't and connection was totally :> offline. : :> This is very empirical, but it looked to me, when I walked :> slower to give wpa_supplicant time to reassoc with each access point on :> the way it all worked. When I got bored and walked faster, passing by :> multiple APs on the way and with reassocs happening one after another, :> before previous assoc was able to finish and me finally stopping, I :> ended up with iwn0 card with status active, but no connectivity. :> Restarting slaacd(8) or dhclient(8) was not helping as problem was layer :> below them. :> [...] : :Yeah, I've got the feeling that wpa_supplicant really doesn't like :getting poked while it's doing its thing. Maybe I've got to work on the :timing here a bit or sort of deduplicate ASSOC events after multiple :IFINFO/802INFO are received. : :> [...] :> I think your diff makes sense and with handling of RTM_IFINFO it's good :> progress in correct direction. I even took your diff and tested with :> latest wpa_supplicant 2.7 and it works there too. :> [...] : :That is good to hear. I'm planning on sending this upstream as soon as :we've agreed it's more or less working. : :> [...] :> If you would like to see any specific info tomorrow, please let me know :> I will try to arrange something. After that I'll go offline for family :> time. :> [...] : :I'm afraid I don't have anything more specific I could ask you to test. :Thanks a bunch for your help this far. I'll just have to walk around my :university some time next week, I'm not at work then anyway :) : :> [...] :>> ++ if (rtm->rtm_type == RTM_80211INFO) { :>> ++ printf("RTM_80211INFO received\n"); :> :> This printf(3) should be removed or changed into wpa_printf(). For my tests :> I've used wpa_printf(MSG_DEBUG, ...), which I think is good enough balance :> of being not noisy in logs by default, but still providing info when there :> is a need via debug flag to the cli. However this is your call and giving :> the current sparsity of debug log lines in this c-file, I would just remove :> it. :> [...] : :Absolutely. This was an oversight that I wanted to remove before sending :out the patch. Same for the weird indentation :) : :-- : Gregor -- If someone had told me I would be Pope one day, I would have studied harder. -- Pope John Paul I
