import { isIpInCidr } from
"../shared/net/ip.js" ;
import { listExternalInterfaceAddresses, readNetworkInterfaces } from
"./network-interfaces.js" ;
export type TailnetAddresses = {
ipv4: string[];
ipv6: string[];
};
const TAILNET_IPV4_CIDR =
"100.64.0.0/10" ;
const TAILNET_IPV6_CIDR =
"fd7a:115c:a1e0::/48" ;
export
function isTailnetIPv4(address: string):
boolean {
// Tailscale IPv4 range: 100.64.0.0/10
// https://tailscale.com/kb/1015/100.x-addresses
return isIpInCidr(address, TAILNET_IPV4_CIDR);
}
function isTailnetIPv6(address: string):
boolean {
// Tailscale IPv6 ULA prefix: fd7a:115c:a1e0::/48
// (stable across tailnets; nodes get per-device suffixes)
return isIpInCidr(address, TAILNET_IPV6_CIDR);
}
export
function listTailnetAddresses(): TailnetAddresses {
const ipv4: string[] = [];
const ipv6: string[] = [];
for (
const { address, family } of listExternalInterfaceAddresses(readNetworkInterfaces(
))) {
if (family === "IPv4" && isTailnetIPv4(address)) {
ipv4.push(address);
}
if (family === "IPv6" && isTailnetIPv6(address)) {
ipv6.push(address);
}
}
return { ipv4: [...new Set(ipv4)], ipv6: [...new Set(ipv6)] };
}
export function pickPrimaryTailnetIPv4(): string | undefined {
return listTailnetAddresses().ipv4[0 ];
}
export function pickPrimaryTailnetIPv6(): string | undefined {
return listTailnetAddresses().ipv6[0 ];
}
Messung V0.5 in Prozent C=92 H=92 G=91
¤ Dauer der Verarbeitung: 0.10 Sekunden
(vorverarbeitet am 2026-06-09)
¤
*© Formatika GbR, Deutschland