Mirror: Best-effort discovery of the machine's local network using just Node.js dgram sockets

fix: check subnet for dhcp discovery (#12)

* fix: check subnet for dhcp discovery

* Add changeset

---------

Co-authored-by: Phil Pluckthun <phil@kitten.sh>

Changed files
+37 -1
.changeset
src
+5
.changeset/shaggy-walls-argue.md
···
+
---
+
'lan-network': patch
+
---
+
+
Compare subnet-masked addresses before accepting DHCP discover message
+14
src/__tests__/network.test.ts
···
toIpStr,
interfaceAssignments,
matchAssignment,
+
isSameSubnet,
} from '../network';
describe(parseMacStr, () => {
···
expect(toIpStr(parseIpStr(addr))).toBe(addr);
}
);
+
});
+
+
describe(isSameSubnet, () => {
+
it('returns true for same subnet', () => {
+
expect(isSameSubnet('192.168.1.1', '192.168.1.2', '255.255.255.0')).toBe(
+
true
+
);
+
});
+
it('returns false for different subnet', () => {
+
expect(isSameSubnet('192.168.1.1', '192.168.2.1', '255.255.255.0')).toBe(
+
false
+
);
+
});
});
describe(interfaceAssignments, () => {
+7 -1
src/dhcp.ts
···
import { randomBytes } from 'node:crypto';
import { createSocket } from 'node:dgram';
-
import { parseIpStr, toIpStr, parseMacStr } from './network';
+
import { parseIpStr, toIpStr, parseMacStr, isSameSubnet } from './network';
import type { NetworkAssignment } from './types';
class DHCPTimeoutError extends TypeError {
···
const socket = createSocket(
{ type: 'udp4', reuseAddr: true },
(_msg, rinfo) => {
+
if (
+
!isSameSubnet(rinfo.address, assignment.address, assignment.netmask)
+
) {
+
return;
+
}
+
clearTimeout(timeout);
resolve(rinfo.address);
socket.close();
+11
src/network.ts
···
return addr[3] | (addr[2] << 8) | (addr[1] << 16) | (addr[0] << 24);
};
+
export const isSameSubnet = (
+
addrA: string,
+
addrB: string,
+
netmask: string
+
): boolean => {
+
const rawAddrA = parseIpStr(addrA);
+
const rawAddrB = parseIpStr(addrB);
+
const rawMask = parseIpStr(netmask);
+
return (rawAddrA & rawMask) === (rawAddrB & rawMask);
+
};
+
export const toIpStr = (addr: number): string => {
const MASK = (1 << 8) - 1;
let ipStr = '';