generated from Dicken/dickendock
67 lines
2.1 KiB
TypeScript
67 lines
2.1 KiB
TypeScript
import { soapRequest, type DigestAuthOptions } from "./digestAuth.js";
|
|
|
|
const SERVICE_TYPE = "urn:dslforum-org:service:Hosts:1";
|
|
|
|
function actionEnvelope(action: string, params: Record<string, string | number> = {}): string {
|
|
const args = Object.entries(params)
|
|
.map(([key, value]) => `<${key}>${value}</${key}>`)
|
|
.join("");
|
|
|
|
return (
|
|
`<?xml version="1.0" encoding="utf-8"?>` +
|
|
`<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" ` +
|
|
`s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">` +
|
|
`<s:Body><u:${action} xmlns:u="${SERVICE_TYPE}">${args}</u:${action}></s:Body>` +
|
|
`</s:Envelope>`
|
|
);
|
|
}
|
|
|
|
function extractTag(xml: string, tag: string): string | null {
|
|
const match = xml.match(new RegExp(`<${tag}>([^<]*)</${tag}>`, "i"));
|
|
return match ? match[1] : null;
|
|
}
|
|
|
|
export interface FritzBoxHost {
|
|
ip: string;
|
|
mac: string | null;
|
|
hostname: string;
|
|
online: boolean;
|
|
}
|
|
|
|
/**
|
|
* Liest die vollständige Geräteliste der FritzBox über die TR-064-Aktionen
|
|
* GetHostNumberOfEntries + GetGenericHostEntry (urn:dslforum-org:service:Hosts:1).
|
|
*/
|
|
export async function fetchFritzBoxHosts(options: DigestAuthOptions): Promise<FritzBoxHost[]> {
|
|
const countXml = await soapRequest(
|
|
options,
|
|
`${SERVICE_TYPE}#GetHostNumberOfEntries`,
|
|
actionEnvelope("GetHostNumberOfEntries")
|
|
);
|
|
const countStr = extractTag(countXml, "NewHostNumberOfEntries");
|
|
const count = countStr ? parseInt(countStr, 10) : 0;
|
|
|
|
const hosts: FritzBoxHost[] = [];
|
|
|
|
for (let index = 0; index < count; index++) {
|
|
const entryXml = await soapRequest(
|
|
options,
|
|
`${SERVICE_TYPE}#GetGenericHostEntry`,
|
|
actionEnvelope("GetGenericHostEntry", { NewIndex: index })
|
|
);
|
|
|
|
const ip = extractTag(entryXml, "NewIPAddress");
|
|
const hostname = extractTag(entryXml, "NewHostName");
|
|
if (!ip || !hostname) continue; // inaktive/unvollständige Einträge überspringen
|
|
|
|
hosts.push({
|
|
ip,
|
|
mac: extractTag(entryXml, "NewMACAddress"),
|
|
hostname,
|
|
online: extractTag(entryXml, "NewActive") === "1",
|
|
});
|
|
}
|
|
|
|
return hosts;
|
|
}
|