Loading docs/changes.txt +2 −1 Original line number Diff line number Diff line Loading @@ -579,4 +579,5 @@ blockcheck: fix broken dns cache 73.5 nfqws2: fix broken l7proto profile rediscovery nfqws: fix broken l7proto profile rediscovery nfqws: backport from nfqws2 nl80211 ssid discovery fix for newer kernels nfq/darkmagic.c +118 −34 Original line number Diff line number Diff line Loading @@ -1870,9 +1870,9 @@ bool rawsend_queue(struct rawpacket_tailhead *q) // linux-specific wlan retrieval implementation typedef void netlink_prepare_nlh_cb_t(struct nlmsghdr *nlh); typedef void netlink_prepare_nlh_cb_t(struct nlmsghdr *nlh, void *param); static bool netlink_genl_simple_transact(struct mnl_socket* nl, uint16_t type, uint16_t flags, uint8_t cmd, uint8_t version, netlink_prepare_nlh_cb_t cb_prepare_nlh, mnl_cb_t cb_data, void *data) static bool netlink_genl_simple_transact(struct mnl_socket* nl, uint16_t type, uint16_t flags, uint8_t cmd, uint8_t version, netlink_prepare_nlh_cb_t cb_prepare_nlh, void *prepare_data, mnl_cb_t cb_data, void *data) { char buf[MNL_SOCKET_BUFFER_SIZE]; struct nlmsghdr *nlh; Loading @@ -1887,7 +1887,7 @@ static bool netlink_genl_simple_transact(struct mnl_socket* nl, uint16_t type, u genl->cmd = cmd; genl->version = version; if (cb_prepare_nlh) cb_prepare_nlh(nlh); if (cb_prepare_nlh) cb_prepare_nlh(nlh, prepare_data); if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) { Loading @@ -1911,7 +1911,7 @@ static bool netlink_genl_simple_transact(struct mnl_socket* nl, uint16_t type, u return false; } static void wlan_id_prepare(struct nlmsghdr *nlh) static void wlan_id_prepare(struct nlmsghdr *nlh, void *param) { mnl_attr_put_strz(nlh, CTRL_ATTR_FAMILY_NAME, "nl80211"); } Loading Loading @@ -1943,7 +1943,7 @@ static int wlan_id_cb(const struct nlmsghdr *nlh, void *data) static uint16_t wlan_get_family_id(struct mnl_socket* nl) { uint16_t id; return netlink_genl_simple_transact(nl, GENL_ID_CTRL, NLM_F_REQUEST | NLM_F_ACK, CTRL_CMD_GETFAMILY, 1, wlan_id_prepare, wlan_id_cb, &id) ? id : 0; return netlink_genl_simple_transact(nl, GENL_ID_CTRL, NLM_F_REQUEST | NLM_F_ACK, CTRL_CMD_GETFAMILY, 1, wlan_id_prepare, NULL, wlan_id_cb, &id) ? id : 0; } static int wlan_info_attr_cb(const struct nlattr *attr, void *data) Loading Loading @@ -1978,42 +1978,130 @@ static int wlan_info_attr_cb(const struct nlattr *attr, void *data) } return MNL_CB_OK; } struct wlan_info_req { struct wlan_interface_collection *wc; bool bReqSSID; }; static int wlan_info_cb(const struct nlmsghdr *nlh, void *data) { int ret; struct wlan_interface_collection *wc = (struct wlan_interface_collection*)data; if (wc->count>=WLAN_INTERFACE_MAX) return MNL_CB_OK; memset(wc->wlan+wc->count,0,sizeof(wc->wlan[0])); ret = mnl_attr_parse(nlh, sizeof(struct genlmsghdr), wlan_info_attr_cb, wc->wlan+wc->count); if (ret>=0 && *wc->wlan[wc->count].ifname && wc->wlan[wc->count].ifindex) struct wlan_info_req *wr = (struct wlan_info_req*)data; if (wr->wc->count>=WLAN_INTERFACE_MAX) return MNL_CB_OK; memset(wr->wc->wlan + wr->wc->count,0,sizeof(struct wlan_interface)); ret = mnl_attr_parse(nlh, sizeof(struct genlmsghdr), wlan_info_attr_cb, wr->wc->wlan + wr->wc->count); if (ret>=0 && (!wr->bReqSSID || *wr->wc->wlan[wr->wc->count].ssid) && *wr->wc->wlan[wr->wc->count].ifname && wr->wc->wlan[wr->wc->count].ifindex) wr->wc->count++; return ret; } static bool wlan_info(struct mnl_socket* nl, uint16_t wlan_family_id, struct wlan_interface_collection* w, bool bReqSSID) { if (*wc->wlan[wc->count].ssid) wc->count++; else struct wlan_info_req req = { .bReqSSID = bReqSSID, .wc = w }; return netlink_genl_simple_transact(nl, wlan_family_id, NLM_F_REQUEST | NLM_F_ACK | NLM_F_DUMP, NL80211_CMD_GET_INTERFACE, 0, NULL, NULL, wlan_info_cb, &req); } static void scan_prepare(struct nlmsghdr *nlh, void *param) { // sometimes nl80211 does not return SSID but wireless ext does int wext_fd = socket(AF_INET, SOCK_DGRAM, 0); if (wext_fd!=-1) { struct iwreq req; snprintf(req.ifr_ifrn.ifrn_name,sizeof(req.ifr_ifrn.ifrn_name),"%s",wc->wlan[wc->count].ifname); req.u.essid.pointer = wc->wlan[wc->count].ssid; req.u.essid.length = sizeof(wc->wlan[wc->count].ssid); req.u.essid.flags = 0; if (ioctl(wext_fd, SIOCGIWESSID, &req)!=-1) if (*wc->wlan[wc->count].ssid) wc->count++; close(wext_fd); mnl_attr_put_u32(nlh, NL80211_ATTR_IFINDEX, *(int*)param); } static uint8_t *find_ie(uint8_t *buf, size_t len, uint8_t ie) { while (len>=2) { if (len<(2+buf[1])) break; if (buf[0]==ie) return buf; buf+=buf[1]+2; len-=buf[1]+2; } return NULL; } static int scan_info_attr_cb(const struct nlattr *attr, void *data) { struct wlan_interface *wlan = (struct wlan_interface *)data; const struct nlattr *nested; uint8_t *payload, *ie; uint16_t payload_len; bool ok; switch(mnl_attr_get_type(attr)) { case NL80211_ATTR_IFINDEX: if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) { DLOG_PERROR("mnl_attr_validate"); return MNL_CB_ERROR; } wlan->ifindex = mnl_attr_get_u32(attr); if (!if_indextoname(wlan->ifindex, wlan->ifname)) DLOG_PERROR("if_indextoname"); break; case NL80211_ATTR_BSS: if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0) { DLOG_PERROR("mnl_attr_validate"); return MNL_CB_ERROR; } ok = false; mnl_attr_for_each_nested(nested, attr) { if (mnl_attr_get_type(nested)==NL80211_BSS_STATUS) { uint32_t status = mnl_attr_get_u32(nested); if (status==NL80211_BSS_STATUS_ASSOCIATED || status==NL80211_BSS_STATUS_AUTHENTICATED || status==NL80211_BSS_STATUS_IBSS_JOINED) { ok=1; break; } } } if (!ok) break; mnl_attr_for_each_nested(nested, attr) { switch(mnl_attr_get_type(nested)) { case NL80211_BSS_INFORMATION_ELEMENTS: payload_len = mnl_attr_get_payload_len(nested); payload = mnl_attr_get_payload(nested); ie = find_ie(payload,payload_len,0); if (ie) { uint8_t l = ie[1]; if (l>=(sizeof(wlan->ssid))) l=sizeof(wlan->ssid)-1; memcpy(wlan->ssid,ie+2,l); wlan->ssid[l]=0; } break; } } break; } return MNL_CB_OK; } static int scan_info_cb(const struct nlmsghdr *nlh, void *data) { int ret; struct wlan_interface_collection *wc = (struct wlan_interface_collection*)data; if (wc->count>=WLAN_INTERFACE_MAX) return MNL_CB_OK; memset(wc->wlan+wc->count,0,sizeof(wc->wlan[0])); ret = mnl_attr_parse(nlh, sizeof(struct genlmsghdr), scan_info_attr_cb, wc->wlan+wc->count); if (ret>=0 && *wc->wlan[wc->count].ssid && *wc->wlan[wc->count].ifname && wc->wlan[wc->count].ifindex) wc->count++; return ret; } static bool wlan_info(struct mnl_socket* nl, uint16_t wlan_family_id, struct wlan_interface_collection* w) static bool scan_info(struct mnl_socket* nl, uint16_t wlan_family_id, struct wlan_interface_collection* w) { return netlink_genl_simple_transact(nl, wlan_family_id, NLM_F_REQUEST | NLM_F_ACK | NLM_F_DUMP, NL80211_CMD_GET_INTERFACE, 0, NULL, wlan_info_cb, w); struct wlan_interface_collection wc_all = { .count = 0 }; // wlan_info does not return ssid since kernel 5.19 // it's used to enumerate all wifi interfaces then call scan_info on each if (!wlan_info(nl, wlan_family_id, &wc_all, false)) return false; for(int i=0;i<wc_all.count;i++) if (!netlink_genl_simple_transact(nl, wlan_family_id, NLM_F_REQUEST | NLM_F_ACK | NLM_F_DUMP, NL80211_CMD_GET_SCAN, 0, scan_prepare, (void*)&wc_all.wlan[i].ifindex, scan_info_cb, w)) return false; return true; } static bool wlan_init80211(struct mnl_socket** nl) { if (!(*nl = mnl_socket_open(NETLINK_GENERIC))) Loading Loading @@ -2047,7 +2135,7 @@ static bool wlan_info_rate_limited(struct mnl_socket* nl, uint16_t wlan_family_i // do not purge too often to save resources if (wlan_info_last != now) { bres = wlan_info(nl,wlan_family_id,w); bres = scan_info(nl,wlan_family_id,w); wlan_info_last = now; } return bres; Loading @@ -2073,10 +2161,6 @@ bool wlan_info_init(void) } return true; } bool wlan_info_get(void) { return wlan_info(nl_wifi, id_nl80211, &wlans); } bool wlan_info_get_rate_limited(void) { return wlan_info_rate_limited(nl_wifi, id_nl80211, &wlans); Loading nfq/darkmagic.h +0 −1 Original line number Diff line number Diff line Loading @@ -298,7 +298,6 @@ extern struct wlan_interface_collection wlans; void wlan_info_deinit(void); bool wlan_info_init(void); bool wlan_info_get(void); bool wlan_info_get_rate_limited(void); const char *wlan_ssid_search_ifname(const char *ifname); const char *wlan_ssid_search_ifidx(int ifidx); Loading Loading
docs/changes.txt +2 −1 Original line number Diff line number Diff line Loading @@ -579,4 +579,5 @@ blockcheck: fix broken dns cache 73.5 nfqws2: fix broken l7proto profile rediscovery nfqws: fix broken l7proto profile rediscovery nfqws: backport from nfqws2 nl80211 ssid discovery fix for newer kernels
nfq/darkmagic.c +118 −34 Original line number Diff line number Diff line Loading @@ -1870,9 +1870,9 @@ bool rawsend_queue(struct rawpacket_tailhead *q) // linux-specific wlan retrieval implementation typedef void netlink_prepare_nlh_cb_t(struct nlmsghdr *nlh); typedef void netlink_prepare_nlh_cb_t(struct nlmsghdr *nlh, void *param); static bool netlink_genl_simple_transact(struct mnl_socket* nl, uint16_t type, uint16_t flags, uint8_t cmd, uint8_t version, netlink_prepare_nlh_cb_t cb_prepare_nlh, mnl_cb_t cb_data, void *data) static bool netlink_genl_simple_transact(struct mnl_socket* nl, uint16_t type, uint16_t flags, uint8_t cmd, uint8_t version, netlink_prepare_nlh_cb_t cb_prepare_nlh, void *prepare_data, mnl_cb_t cb_data, void *data) { char buf[MNL_SOCKET_BUFFER_SIZE]; struct nlmsghdr *nlh; Loading @@ -1887,7 +1887,7 @@ static bool netlink_genl_simple_transact(struct mnl_socket* nl, uint16_t type, u genl->cmd = cmd; genl->version = version; if (cb_prepare_nlh) cb_prepare_nlh(nlh); if (cb_prepare_nlh) cb_prepare_nlh(nlh, prepare_data); if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) { Loading @@ -1911,7 +1911,7 @@ static bool netlink_genl_simple_transact(struct mnl_socket* nl, uint16_t type, u return false; } static void wlan_id_prepare(struct nlmsghdr *nlh) static void wlan_id_prepare(struct nlmsghdr *nlh, void *param) { mnl_attr_put_strz(nlh, CTRL_ATTR_FAMILY_NAME, "nl80211"); } Loading Loading @@ -1943,7 +1943,7 @@ static int wlan_id_cb(const struct nlmsghdr *nlh, void *data) static uint16_t wlan_get_family_id(struct mnl_socket* nl) { uint16_t id; return netlink_genl_simple_transact(nl, GENL_ID_CTRL, NLM_F_REQUEST | NLM_F_ACK, CTRL_CMD_GETFAMILY, 1, wlan_id_prepare, wlan_id_cb, &id) ? id : 0; return netlink_genl_simple_transact(nl, GENL_ID_CTRL, NLM_F_REQUEST | NLM_F_ACK, CTRL_CMD_GETFAMILY, 1, wlan_id_prepare, NULL, wlan_id_cb, &id) ? id : 0; } static int wlan_info_attr_cb(const struct nlattr *attr, void *data) Loading Loading @@ -1978,42 +1978,130 @@ static int wlan_info_attr_cb(const struct nlattr *attr, void *data) } return MNL_CB_OK; } struct wlan_info_req { struct wlan_interface_collection *wc; bool bReqSSID; }; static int wlan_info_cb(const struct nlmsghdr *nlh, void *data) { int ret; struct wlan_interface_collection *wc = (struct wlan_interface_collection*)data; if (wc->count>=WLAN_INTERFACE_MAX) return MNL_CB_OK; memset(wc->wlan+wc->count,0,sizeof(wc->wlan[0])); ret = mnl_attr_parse(nlh, sizeof(struct genlmsghdr), wlan_info_attr_cb, wc->wlan+wc->count); if (ret>=0 && *wc->wlan[wc->count].ifname && wc->wlan[wc->count].ifindex) struct wlan_info_req *wr = (struct wlan_info_req*)data; if (wr->wc->count>=WLAN_INTERFACE_MAX) return MNL_CB_OK; memset(wr->wc->wlan + wr->wc->count,0,sizeof(struct wlan_interface)); ret = mnl_attr_parse(nlh, sizeof(struct genlmsghdr), wlan_info_attr_cb, wr->wc->wlan + wr->wc->count); if (ret>=0 && (!wr->bReqSSID || *wr->wc->wlan[wr->wc->count].ssid) && *wr->wc->wlan[wr->wc->count].ifname && wr->wc->wlan[wr->wc->count].ifindex) wr->wc->count++; return ret; } static bool wlan_info(struct mnl_socket* nl, uint16_t wlan_family_id, struct wlan_interface_collection* w, bool bReqSSID) { if (*wc->wlan[wc->count].ssid) wc->count++; else struct wlan_info_req req = { .bReqSSID = bReqSSID, .wc = w }; return netlink_genl_simple_transact(nl, wlan_family_id, NLM_F_REQUEST | NLM_F_ACK | NLM_F_DUMP, NL80211_CMD_GET_INTERFACE, 0, NULL, NULL, wlan_info_cb, &req); } static void scan_prepare(struct nlmsghdr *nlh, void *param) { // sometimes nl80211 does not return SSID but wireless ext does int wext_fd = socket(AF_INET, SOCK_DGRAM, 0); if (wext_fd!=-1) { struct iwreq req; snprintf(req.ifr_ifrn.ifrn_name,sizeof(req.ifr_ifrn.ifrn_name),"%s",wc->wlan[wc->count].ifname); req.u.essid.pointer = wc->wlan[wc->count].ssid; req.u.essid.length = sizeof(wc->wlan[wc->count].ssid); req.u.essid.flags = 0; if (ioctl(wext_fd, SIOCGIWESSID, &req)!=-1) if (*wc->wlan[wc->count].ssid) wc->count++; close(wext_fd); mnl_attr_put_u32(nlh, NL80211_ATTR_IFINDEX, *(int*)param); } static uint8_t *find_ie(uint8_t *buf, size_t len, uint8_t ie) { while (len>=2) { if (len<(2+buf[1])) break; if (buf[0]==ie) return buf; buf+=buf[1]+2; len-=buf[1]+2; } return NULL; } static int scan_info_attr_cb(const struct nlattr *attr, void *data) { struct wlan_interface *wlan = (struct wlan_interface *)data; const struct nlattr *nested; uint8_t *payload, *ie; uint16_t payload_len; bool ok; switch(mnl_attr_get_type(attr)) { case NL80211_ATTR_IFINDEX: if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) { DLOG_PERROR("mnl_attr_validate"); return MNL_CB_ERROR; } wlan->ifindex = mnl_attr_get_u32(attr); if (!if_indextoname(wlan->ifindex, wlan->ifname)) DLOG_PERROR("if_indextoname"); break; case NL80211_ATTR_BSS: if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0) { DLOG_PERROR("mnl_attr_validate"); return MNL_CB_ERROR; } ok = false; mnl_attr_for_each_nested(nested, attr) { if (mnl_attr_get_type(nested)==NL80211_BSS_STATUS) { uint32_t status = mnl_attr_get_u32(nested); if (status==NL80211_BSS_STATUS_ASSOCIATED || status==NL80211_BSS_STATUS_AUTHENTICATED || status==NL80211_BSS_STATUS_IBSS_JOINED) { ok=1; break; } } } if (!ok) break; mnl_attr_for_each_nested(nested, attr) { switch(mnl_attr_get_type(nested)) { case NL80211_BSS_INFORMATION_ELEMENTS: payload_len = mnl_attr_get_payload_len(nested); payload = mnl_attr_get_payload(nested); ie = find_ie(payload,payload_len,0); if (ie) { uint8_t l = ie[1]; if (l>=(sizeof(wlan->ssid))) l=sizeof(wlan->ssid)-1; memcpy(wlan->ssid,ie+2,l); wlan->ssid[l]=0; } break; } } break; } return MNL_CB_OK; } static int scan_info_cb(const struct nlmsghdr *nlh, void *data) { int ret; struct wlan_interface_collection *wc = (struct wlan_interface_collection*)data; if (wc->count>=WLAN_INTERFACE_MAX) return MNL_CB_OK; memset(wc->wlan+wc->count,0,sizeof(wc->wlan[0])); ret = mnl_attr_parse(nlh, sizeof(struct genlmsghdr), scan_info_attr_cb, wc->wlan+wc->count); if (ret>=0 && *wc->wlan[wc->count].ssid && *wc->wlan[wc->count].ifname && wc->wlan[wc->count].ifindex) wc->count++; return ret; } static bool wlan_info(struct mnl_socket* nl, uint16_t wlan_family_id, struct wlan_interface_collection* w) static bool scan_info(struct mnl_socket* nl, uint16_t wlan_family_id, struct wlan_interface_collection* w) { return netlink_genl_simple_transact(nl, wlan_family_id, NLM_F_REQUEST | NLM_F_ACK | NLM_F_DUMP, NL80211_CMD_GET_INTERFACE, 0, NULL, wlan_info_cb, w); struct wlan_interface_collection wc_all = { .count = 0 }; // wlan_info does not return ssid since kernel 5.19 // it's used to enumerate all wifi interfaces then call scan_info on each if (!wlan_info(nl, wlan_family_id, &wc_all, false)) return false; for(int i=0;i<wc_all.count;i++) if (!netlink_genl_simple_transact(nl, wlan_family_id, NLM_F_REQUEST | NLM_F_ACK | NLM_F_DUMP, NL80211_CMD_GET_SCAN, 0, scan_prepare, (void*)&wc_all.wlan[i].ifindex, scan_info_cb, w)) return false; return true; } static bool wlan_init80211(struct mnl_socket** nl) { if (!(*nl = mnl_socket_open(NETLINK_GENERIC))) Loading Loading @@ -2047,7 +2135,7 @@ static bool wlan_info_rate_limited(struct mnl_socket* nl, uint16_t wlan_family_i // do not purge too often to save resources if (wlan_info_last != now) { bres = wlan_info(nl,wlan_family_id,w); bres = scan_info(nl,wlan_family_id,w); wlan_info_last = now; } return bres; Loading @@ -2073,10 +2161,6 @@ bool wlan_info_init(void) } return true; } bool wlan_info_get(void) { return wlan_info(nl_wifi, id_nl80211, &wlans); } bool wlan_info_get_rate_limited(void) { return wlan_info_rate_limited(nl_wifi, id_nl80211, &wlans); Loading
nfq/darkmagic.h +0 −1 Original line number Diff line number Diff line Loading @@ -298,7 +298,6 @@ extern struct wlan_interface_collection wlans; void wlan_info_deinit(void); bool wlan_info_init(void); bool wlan_info_get(void); bool wlan_info_get_rate_limited(void); const char *wlan_ssid_search_ifname(const char *ifname); const char *wlan_ssid_search_ifidx(int ifidx); Loading