diff --git a/.changeset/long-berries-clean.md b/.changeset/long-berries-clean.md new file mode 100644 index 0000000..00fb8c1 --- /dev/null +++ b/.changeset/long-berries-clean.md @@ -0,0 +1,5 @@ +--- +'lan-network': minor +--- + +Add `noProbe` and `noDhcp` options diff --git a/src/index.ts b/src/index.ts index c255314..e38066e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -9,7 +9,14 @@ import { } from './network'; import type { GatewayAssignment } from './types'; -export async function lanNetwork(): Promise { +export interface NetworkOptions { + noProbe?: boolean; + noDhcp?: boolean; +} + +export async function lanNetwork( + opts?: NetworkOptions +): Promise { // Get IPv4 network assignments, sorted by: // - external first // - LAN-reserved IP range priority @@ -24,33 +31,37 @@ export async function lanNetwork(): Promise { // First, we attempt to probe the default route to a publicly routed IP // This will generally fail if there's no route, e.g. if the network is offline - try { - const defaultRoute = await probeDefaultRoute(); - // If this route matches a known assignment, return it without a gateway - if ( - (assignment = matchAssignment(assignments, defaultRoute)) && - !isInternal(assignment) - ) { - return assignment; + if (!opts?.noProbe) { + try { + const defaultRoute = await probeDefaultRoute(); + // If this route matches a known assignment, return it without a gateway + if ( + (assignment = matchAssignment(assignments, defaultRoute)) && + !isInternal(assignment) + ) { + return assignment; + } + } catch { + // Ignore errors, since we have a fallback method } - } catch { - // Ignore errors, since we have a fallback method } // Second, attempt to discover a gateway's DHCP network // Because without a gateway we won't get a reply, we do this in parallel - const discoveries = await Promise.allSettled( - assignments.map(assignment => { - // For each assignment, we send a DHCPDISCOVER packet to its network mask - return dhcpDiscover(assignment); - }) - ); - for (const discovery of discoveries) { - // The first discovered gateway is returned, if it matches an assignment - if (discovery.status === 'fulfilled' && discovery.value) { - const dhcpRoute = discovery.value; - if ((assignment = matchAssignment(assignments, dhcpRoute))) { - return assignment; + if (!opts?.noDhcp) { + const discoveries = await Promise.allSettled( + assignments.map(assignment => { + // For each assignment, we send a DHCPDISCOVER packet to its network mask + return dhcpDiscover(assignment); + }) + ); + for (const discovery of discoveries) { + // The first discovered gateway is returned, if it matches an assignment + if (discovery.status === 'fulfilled' && discovery.value) { + const dhcpRoute = discovery.value; + if ((assignment = matchAssignment(assignments, dhcpRoute))) { + return assignment; + } } } } @@ -60,11 +71,15 @@ export async function lanNetwork(): Promise { return { ...assignments[0], gateway: null }; } -export function lanNetworkSync(): GatewayAssignment { +export function lanNetworkSync(opts?: NetworkOptions): GatewayAssignment { const subprocessPath = require.resolve('lan-network/subprocess'); const { error, status, stdout } = spawnSync( process.execPath, - [subprocessPath], + [ + subprocessPath, + opts?.noProbe ? '--no-probe' : null, + opts?.noDhcp ? '--no-dhcp' : null, + ].filter((x): x is string => !!x), { shell: false, timeout: 500, diff --git a/src/subprocess.ts b/src/subprocess.ts index 8e499bc..eb18e2e 100644 --- a/src/subprocess.ts +++ b/src/subprocess.ts @@ -1,7 +1,10 @@ import { lanNetwork } from './index'; async function output() { - const assignment = await lanNetwork(); + const assignment = await lanNetwork({ + noProbe: process.argv.includes('--no-probe'), + noDhcp: process.argv.includes('--no-dhcp'), + }); process.stdout.write(JSON.stringify(assignment)); process.exit(0); }