Index: sys/net80211/ieee80211_node.c =================================================================== --- sys/net80211/ieee80211_node.c +++ sys/net80211/ieee80211_node.c @@ -33,10 +33,11 @@ #include #include +#include #include #include #include - +#include #include #include @@ -831,6 +832,63 @@ ieee80211_runtask(ic, &ic->ic_chw_task); } +static void +ieee80211_devctl_notify_assoc_status(struct ieee80211vap *vap, + struct ieee80211_node *ni, const char *status) +{ + struct sbuf sb; + const uint8_t *p; + int i, len; + bool printable; + + if (sbuf_new(&sb, NULL, 0, SBUF_AUTOEXTEND | SBUF_NOWAIT) == NULL) + return; + + sbuf_printf(&sb, "vap=%s", vap->iv_ifp->if_xname); + + len = ni->ni_esslen; + printable = true; + for (i = 0, p = ni->ni_essid; i < len; i++, p++) { + if (*p < ' ' || *p > 0x7e) { + printable = false; + break; + } + } + + if (printable) { + sbuf_printf(&sb, " ssid=\""); + devctl_safe_quote_sb_len(&sb, ni->ni_essid, ni->ni_esslen); + sbuf_printf(&sb, "\""); + } else { + sbuf_printf(&sb, " ssid=0x"); + for (i = 0, p = ni->ni_essid; i < len; i++, p++) { + sbuf_printf(&sb, "%02x", *p); + } + } + + sbuf_printf(&sb, " bssid=\"%s\"", ether_sprintf(ni->ni_bssid)); + if (sbuf_finish(&sb) == 0) + devctl_notify("net80211", "sta", status, sbuf_data(&sb)); + sbuf_delete(&sb); +} + +static void +ieee80211_devctl_notify_assoc(struct ieee80211vap *vap, + struct ieee80211_node *ni) +{ + + ieee80211_devctl_notify_assoc_status(vap, ni, "assoc"); +} + +static void +ieee80211_devctl_notify_disassoc(struct ieee80211vap *vap, + struct ieee80211_node *ni) +{ + + ieee80211_devctl_notify_assoc_status(vap, ni, "disassoc"); +} + + /* * Join the specified IBSS/BSS network. The node is assumed to * be passed in with a held reference. @@ -1036,6 +1094,7 @@ ieee80211_node_setuptxparms(ni); ieee80211_ratectl_node_init(ni); + ieee80211_devctl_notify_assoc(vap, ni); return ieee80211_sta_join1(ieee80211_ref_node(ni)); } @@ -1050,6 +1109,7 @@ struct ieee80211com *ic = ni->ni_ic; ic->ic_node_cleanup(ni); + ieee80211_devctl_notify_disassoc(ni->ni_vap, ni); ieee80211_notify_node_leave(ni); }