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) {