UNPKG

@chainsafe/netmask

Version:

Typescript implementation of netmask filtering

59 lines (54 loc) 1.75 kB
import { parseIP } from "@chainsafe/is-ip/parse"; import { cidrMask, parseCidr } from "./cidr.js"; import { containsIp, maskIp } from "./ip.js"; import { ipToString, maskToHex, simpleMaskLength } from "./util.js"; export class IpNet { public readonly network: Uint8Array; public readonly mask: Uint8Array; /** * * @param ipOrCidr either network ip or full cidr address * @param mask in case ipOrCidr is network this can be either mask in decimal format or as ip address */ constructor(ipOrCidr: string, mask?: string | number) { if (mask == null) { ({ network: this.network, mask: this.mask } = parseCidr(ipOrCidr)); } else { const ipResult = parseIP(ipOrCidr); if (ipResult == null) { throw new Error("Failed to parse network"); } mask = String(mask); const m = parseInt(mask, 10); if ( Number.isNaN(m) || String(m).length !== mask.length || m < 0 || m > ipResult.length * 8 ) { const maskResult = parseIP(mask); if (maskResult == null) { throw new Error("Failed to parse mask"); } this.mask = maskResult; } else { this.mask = cidrMask(m, 8 * ipResult.length); } this.network = maskIp(ipResult, this.mask); } } /** * Checks if netmask contains ip address * @param ip * @returns */ contains(ip: Uint8Array | number[] | string): boolean { return containsIp({ network: this.network, mask: this.mask }, ip); } /**Serializes back to string format */ toString(): string { const l = simpleMaskLength(this.mask); const mask = l !== -1 ? String(l) : maskToHex(this.mask); return ipToString(this.network) + "/" + mask; } }