diff --git a/src/ubus.c b/src/ubus.c index 635aa2546fd1e1b0cbf48e744e105dfc377aba89..a3d3372f719994b4c241a1f0a1282201246a8a7d 100644 --- a/src/ubus.c +++ b/src/ubus.c @@ -886,7 +886,21 @@ int hostmngr_ubus_show_hosts(struct ubus_context *ctx, struct ubus_object *obj, blobmsg_add_string(&bb, "address_source", he->ipv4_type_dhcp ? "DHCP": "Static"); blobmsg_add_u32(&bb, "lease_time_remaining", 0); - blobmsg_add_string(&bb, "interface_type", interface_type2str(he->type)); + /* + * For inactive (history) entries the stored neigh_type might be + * missing or incorrect – e.g. hosts added through ARP before they + * ever associated, or history imported from an older version that + * did not record the correct media type. Fall back to heuristics + * based on the remembered interface name so that Wi-Fi stations do + * not end up being shown as "Ethernet". + */ + if (he->type == NEIGH_TYPE_WIFI) { + blobmsg_add_string(&bb, "interface_type", "Wi-Fi"); + } else if (is_wifi_interface(he->ifname) == 1) { + blobmsg_add_string(&bb, "interface_type", "Wi-Fi"); + } else { + blobmsg_add_string(&bb, "interface_type", "Ethernet"); + } if (he->is1905_link) { blobmsg_add_u8(&bb, "is1905", true); hwaddr_ntoa(he->aladdr, alstr); diff --git a/src/wifi_api.c b/src/wifi_api.c index c40999d14fa8369ebd2332027a311bd62668b0cb..2836e7b7d9c12bc2574e7c2db74d66782fcd643f 100644 --- a/src/wifi_api.c +++ b/src/wifi_api.c @@ -101,6 +101,29 @@ int is_wifi_interface(const char *ifname) } } + /* + * Some wireless drivers (e.g. proprietary full-MAC chips or + * vendor-specific cfg80211 implementations) do not create the + * phy80211 symlink, but they still expose the historic + * /wireless directory under the interface path. Check for this + * directory as an additional heuristic. + */ + memset(&s, 0, sizeof(struct stat)); + snprintf(path, sizeof(path), "/sys/class/net/%s/wireless", ifname); + if (stat(path, &s) == 0 && S_ISDIR(s.st_mode)) + return 1; + + /* + * As a last resort, query libwifi for the interface mode – if the + * call succeeds, we can safely assume the interface is Wi-Fi even + * when the above sysfs heuristics failed. + */ + { + enum wifi_mode mode; + if (wifi_get_mode(ifname, &mode) == 0) + return 1; + } + return 0; }