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;
 }