From c954afc889d835c06f9b250a2b01a633d3fa99a8 Mon Sep 17 00:00:00 2001 From: Eduard Wisch Date: Sun, 16 Aug 2026 23:11:08 +0200 Subject: [PATCH] DHCP-Server auch an der Kabeldose ermitteln linkInfo() nutzt jetzt LinkProperties.getDhcpServerAddress() (ab Android 11) fuer JEDEN Anschlusstyp, und zwar VOR dem alten WLAN-Pfad. Bisher kam die Angabe nur aus WifiManager.dhcpInfo - deprecated und nur fuer WLAN. An einer Netzwerkdose blieb sie deshalb leer, obwohl das Geraet seine Adresse sichtbar per DHCP bezogen hat. Fuer ein Abnahmeprotokoll ist "von welchem Server kommt die Adresse" aber gerade an der Dose die interessante Frage (zweiter Router im Netz, vergessener Testserver). Die Lease-DAUER gibt es auf diesem Weg nicht - sie steckt nur im deprecated DhcpInfo und nur fuer WLAN. Sie zu erfinden oder als 0 zu schreiben waere eine Falschaussage; genau so hat "0" schon einmal als "0 DHCP-Server (!)" in Rot in einem ausgelieferten Kundendokument gestanden. Neu: dhcpQuelle ('system' | 'wlan') nach dem Muster von prefixQuelle in getLocalSubnet. Ohne diese Angabe ist im Nachhinein nicht zu klaeren, ob ein fehlender Wert an der Leitung lag oder an der Android-Version. Der Debug-Selbsttest zeigt jetzt zusaetzlich alle Anschluesse mit IP, Gateway, DHCP-Server (samt Quelle), Lease und Geschwindigkeit - im Emulator bestaetigt: "wlan0 (wifi) [Standardroute] - IP 10.0.2.16/24 - Gateway 10.0.2.2 - DHCP-Server 10.0.2.2 (system) - Lease 86400 s". Der Wert kommt also ueber die neue API, nicht ueber den WLAN-Fallback. Co-Authored-By: Claude Opus 5 (1M context) --- .../netdiag/NetDiagScannerPlugin.kt | 41 ++++++++++++++++++- src/lib/messfelder.ts | 3 ++ src/lib/types.ts | 9 +++- src/routes/debug/+page.svelte | 16 ++++++++ 4 files changed, 67 insertions(+), 2 deletions(-) diff --git a/android/app/src/main/java/de/data_it_solution/netdiag/NetDiagScannerPlugin.kt b/android/app/src/main/java/de/data_it_solution/netdiag/NetDiagScannerPlugin.kt index 45eeb90..59903f9 100644 --- a/android/app/src/main/java/de/data_it_solution/netdiag/NetDiagScannerPlugin.kt +++ b/android/app/src/main/java/de/data_it_solution/netdiag/NetDiagScannerPlugin.kt @@ -1946,6 +1946,40 @@ class NetDiagScannerPlugin : Plugin() { (type == "ethernet" && ifLower.matches(Regex("eth[1-9].*"))) if (isUsb) obj.put("isUsbEthernet", true) + /* + * DHCP-Server: moderne API zuerst, für JEDEN Anschlusstyp. + * + * `WifiManager.dhcpInfo` (weiter unten) gibt es nur für WLAN und + * ist deprecated — an einer Netzwerkdose blieb die Angabe deshalb + * leer, obwohl das Gerät seine Adresse sichtbar per DHCP bezogen + * hat. Für ein Abnahmeprotokoll ist „von welchem Server kommt die + * Adresse" aber gerade an der Dose die interessante Frage (zweiter + * Router im Netz, vergessener Testserver). + * + * `getDhcpServerAddress()` gibt es ab API 30. Bewusst VOR dem + * WLAN-Pfad: so läuft der Normalfall über die unterstützte API, + * und der alte Pfad füllt nur noch, was diese nicht liefert. + * + * Die Lease-DAUER gibt es hier nicht — sie steckt nur im + * deprecated DhcpInfo und nur für WLAN. Sie zu erfinden oder als + * 0 zu schreiben wäre eine Falschaussage im Protokoll; „0" hat + * genau so schon einmal als „0 DHCP-Server (!)" in Rot in einem + * ausgelieferten Kundendokument gestanden. + */ + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + val srvIp = lp.dhcpServerAddress?.hostAddress + if (!srvIp.isNullOrEmpty() && srvIp != "0.0.0.0") { + obj.put("dhcpServer", srvIp) + // Quelle mitliefern wie bei `prefixQuelle` in + // getLocalSubnet(): sonst ist später nicht mehr + // nachvollziehbar, ob die Angabe von der + // unterstützten API oder aus dem alten WLAN-Pfad + // stammt — und damit auch nicht, ob sie an einer + // Kabeldose überhaupt zu erwarten war. + obj.put("dhcpQuelle", "system") + } + } + // Link-Speed-Quellen if (type == "wifi") { try { @@ -1965,7 +1999,11 @@ class NetDiagScannerPlugin : Plugin() { } @Suppress("DEPRECATION") val dhcp = wifi.dhcpInfo if (dhcp != null && dhcp.serverAddress != 0) { - obj.put("dhcpServer", intToIp(dhcp.serverAddress)) + // Nur füllen, was die moderne API oben nicht liefert + if (!obj.has("dhcpServer")) { + obj.put("dhcpServer", intToIp(dhcp.serverAddress)) + obj.put("dhcpQuelle", "wlan") + } if (dhcp.leaseDuration > 0) obj.put("leaseSec", dhcp.leaseDuration) } } catch (_: Exception) { /* WLAN-Info nicht greifbar */ } @@ -1973,6 +2011,7 @@ class NetDiagScannerPlugin : Plugin() { val mbps = readEthernetSpeed(iface) if (mbps != null) obj.put("linkSpeedMbps", mbps) } + arr.put(obj) } resolve(call, JSObject().put("links", arr)) diff --git a/src/lib/messfelder.ts b/src/lib/messfelder.ts index ebe11ca..06570e8 100644 --- a/src/lib/messfelder.ts +++ b/src/lib/messfelder.ts @@ -65,6 +65,9 @@ const FELDER: Record = { // Netz / DHCP / Dose server: { label: 'DHCP-Server' }, dhcpServer: { label: 'DHCP-Server' }, + // 'system' = vom Betriebssystem gemeldet (jeder Anschlusstyp), 'wlan' = alter + // WLAN-Weg. Steht im Protokoll, damit ein fehlender Wert einordenbar bleibt. + dhcpQuelle: { label: 'Quelle der DHCP-Angabe' }, lease: { label: 'Lease-Dauer', einheit: 's' }, leaseSec: { label: 'Lease-Dauer', einheit: 's' }, gateway: { label: 'Gateway' }, diff --git a/src/lib/types.ts b/src/lib/types.ts index a3e5a2c..40b3e9a 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -121,8 +121,15 @@ export interface LinkInfo { prefixLength?: number; gateway?: string; dns?: string[]; - /** DHCP-Server (nur für WLAN ermittelbar) */ + /** DHCP-Server, von dem dieser Anschluss seine Adresse bezogen hat */ dhcpServer?: string; + /** + * Woher die DHCP-Angabe stammt: 'system' = LinkProperties (ab API 30, gilt + * für jeden Anschlusstyp), 'wlan' = das deprecated DhcpInfo (nur WLAN, dafür + * mit Lease-Dauer). Ohne diese Angabe ist im Nachhinein nicht zu klären, ob + * ein fehlender Wert an der Leitung lag oder an der Android-Version. + */ + dhcpQuelle?: 'system' | 'wlan'; leaseSec?: number; /** Verbindungsgeschwindigkeit in Mbit/s — WLAN: linkSpeed; Ethernet: /sys/class/net//speed */ linkSpeedMbps?: number; diff --git a/src/routes/debug/+page.svelte b/src/routes/debug/+page.svelte index 5e7409e..bbee92d 100644 --- a/src/routes/debug/+page.svelte +++ b/src/routes/debug/+page.svelte @@ -2,6 +2,7 @@ import AppHeader from '$lib/components/AppHeader.svelte'; import { debugLog } from '$lib/debuglog.svelte'; import { internetKetteTool } from '$lib/tools/internet/internetkette'; + import { scanner } from '$lib/scanner'; import type { Protocol } from '$lib/types'; /* @@ -28,6 +29,19 @@ protocol: {} as unknown as Protocol, }); const res = r.result as Record; + // Anschlussdaten dazu: DHCP-Server, Lease und Link-Speed sieht man sonst + // nur im IP-Test, und der braucht ein Protokoll (also einen Server). + const { links } = await scanner.linkInfo(); + const anschluesse = links.map((l) => + [ + `${l.iface} (${l.type})${l.isDefault ? ' [Standardroute]' : ''}`, + l.ipv4 ? `IP ${l.ipv4}/${l.prefixLength ?? '?'}` : 'keine IP', + l.gateway ? `Gateway ${l.gateway}` : 'kein Gateway', + `DHCP-Server ${l.dhcpServer ?? 'nicht ermittelbar'}${l.dhcpQuelle ? ` (${l.dhcpQuelle})` : ''}`, + `Lease ${l.leaseSec !== undefined ? l.leaseSec + ' s' : 'nicht ermittelbar'}`, + l.linkSpeedMbps ? `${l.linkSpeedMbps} Mbit/s` : 'Geschwindigkeit unbekannt', + ].join(' · '), + ); selbsttest = { laeuft: false, label: r.label, @@ -37,6 +51,8 @@ `Fehlerglied: ${res.fehlerglied}`, ...(res.systemUrteil ? [String(res.systemUrteil)] : []), ...(res.hinweis ? [String(res.hinweis)] : []), + '— Anschlüsse —', + ...anschluesse, ], }; } catch (e) {