File Explorer

/proc/4/root/var/lang/lib/node_modules/npm/node_modules/ip-address/dist

This explorer reads the filesystem of the server it runs on, so /workspace/user isn't present here. Browsing and the terminal still work against this server's own disk from /.

ipv4.js18.0 KB · 485 lines
"use strict";/* eslint-disable no-param-reassign */var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {    if (k2 === undefined) k2 = k;    var desc = Object.getOwnPropertyDescriptor(m, k);    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {      desc = { enumerable: true, get: function() { return m[k]; } };    }    Object.defineProperty(o, k2, desc);}) : (function(o, m, k, k2) {    if (k2 === undefined) k2 = k;    o[k2] = m[k];}));var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {    Object.defineProperty(o, "default", { enumerable: true, value: v });}) : function(o, v) {    o["default"] = v;});var __importStar = (this && this.__importStar) || function (mod) {    if (mod && mod.__esModule) return mod;    var result = {};    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);    __setModuleDefault(result, mod);    return result;};Object.defineProperty(exports, "__esModule", { value: true });exports.Address4 = void 0;const common = __importStar(require("./common"));const constants = __importStar(require("./v4/constants"));const address_error_1 = require("./address-error");const isCorrect4 = common.isCorrect(constants.BITS);/** * Represents an IPv4 address * @param {string} address - An IPv4 address string */class Address4 {    constructor(address) {        this.groups = constants.GROUPS;        this.parsedAddress = [];        this.parsedSubnet = '';        this.subnet = '/32';        this.subnetMask = 32;        this.v4 = true;        /**         * Returns true if the address is correct, false otherwise         * @returns {Boolean}         */        this.isCorrect = isCorrect4;        /**         * Returns true if the given address is in the subnet of the current address         * @returns {boolean}         */        this.isInSubnet = common.isInSubnet;        this.address = address;        const subnet = constants.RE_SUBNET_STRING.exec(address);        if (subnet) {            this.parsedSubnet = subnet[0].replace('/', '');            this.subnetMask = parseInt(this.parsedSubnet, 10);            this.subnet = `/${this.subnetMask}`;            if (this.subnetMask < 0 || this.subnetMask > constants.BITS) {                throw new address_error_1.AddressError('Invalid subnet mask.');            }            address = address.replace(constants.RE_SUBNET_STRING, '');        }        this.addressMinusSuffix = address;        this.parsedAddress = this.parse(address);    }    /**     * Returns true if the given string is a valid IPv4 address (with optional     * CIDR subnet), false otherwise. Host bits in the subnet portion are     * allowed (e.g. `192.168.1.5/24` is valid); for strict network-address     * validation compare `correctForm()` to `startAddress().correctForm()`,     * or use `networkForm()`.     */    static isValid(address) {        try {            // eslint-disable-next-line no-new            new Address4(address);            return true;        }        catch (e) {            return false;        }    }    /**     * Parses an IPv4 address string into its four octet groups and stores the     * result on `this.parsedAddress`. Called automatically by the constructor;     * you typically don't need to call it directly. Throws `AddressError` if     * the input is not a valid IPv4 address.     */    parse(address) {        const groups = address.split('.');        if (!address.match(constants.RE_ADDRESS)) {            throw new address_error_1.AddressError('Invalid IPv4 address.');        }        return groups;    }    /**     * Returns the address in correct form: octets joined with `.` and any     * leading zeros stripped (e.g. `192.168.1.1`). For IPv4 this matches the     * canonical dotted-decimal representation.     */    correctForm() {        return this.parsedAddress.map((part) => parseInt(part, 10)).join('.');    }    /**     * Construct an `Address4` from an address and a dotted-decimal subnet     * mask given as separate strings (e.g. as returned by Node's     * `os.networkInterfaces()`). Throws `AddressError` if the mask is     * non-contiguous (e.g. `255.0.255.0`).     * @example     * var address = Address4.fromAddressAndMask('192.168.1.1', '255.255.255.0');     * address.subnetMask; // 24     */    static fromAddressAndMask(address, mask) {        const bits = common.prefixLengthFromMask(new Address4(mask).bigInt(), constants.BITS);        return new Address4(`${address}/${bits}`);    }    /**     * Construct an `Address4` from an address and a Cisco-style wildcard mask     * given as separate strings (e.g. `0.0.0.255` for a `/24`). The wildcard     * mask is the bitwise inverse of the subnet mask. Throws `AddressError`     * if the mask is non-contiguous (e.g. `0.255.0.255`).     * @example     * var address = Address4.fromAddressAndWildcardMask('10.0.0.1', '0.0.0.255');     * address.subnetMask; // 24     */    static fromAddressAndWildcardMask(address, wildcardMask) {        const wildcard = new Address4(wildcardMask).bigInt();        const allOnes = (BigInt(1) << BigInt(constants.BITS)) - BigInt(1);        // eslint-disable-next-line no-bitwise        const mask = wildcard ^ allOnes;        const bits = common.prefixLengthFromMask(mask, constants.BITS);        return new Address4(`${address}/${bits}`);    }    /**     * Construct an `Address4` from a wildcard pattern with trailing `*`     * octets. The number of trailing wildcards determines the prefix     * length: each `*` represents 8 bits.     *     * Only trailing whole-octet wildcards are supported. Partial-octet     * wildcards (e.g. `192.168.0.1*`) and interior wildcards (e.g.     * `192.*.0.1`) throw `AddressError`.     * @example     * Address4.fromWildcard('192.168.0.*').subnet;   // '/24'     * Address4.fromWildcard('192.168.*.*').subnet;   // '/16'     * Address4.fromWildcard('*.*.*.*').subnet;       // '/0'     */    static fromWildcard(input) {        const groups = input.split('.');        if (groups.length !== constants.GROUPS) {            throw new address_error_1.AddressError('Wildcard pattern must have 4 octets');        }        let firstWildcard = -1;        for (let i = 0; i < groups.length; i++) {            if (groups[i] === '*') {                if (firstWildcard === -1) {                    firstWildcard = i;                }            }            else if (firstWildcard !== -1) {                throw new address_error_1.AddressError('Wildcard `*` must only appear in trailing octets (e.g. `192.168.0.*`)');            }        }        const trailing = firstWildcard === -1 ? 0 : groups.length - firstWildcard;        const replaced = groups.map((g) => (g === '*' ? '0' : g));        const subnetBits = constants.BITS - trailing * 8;        return new Address4(`${replaced.join('.')}/${subnetBits}`);    }    /**     * Converts a hex string to an IPv4 address object. Accepts 8 hex digits     * with optional `:` separators (e.g. `'7f000001'` or `'7f:00:00:01'`).     * Throws `AddressError` for any other length or for non-hex characters.     * @param {string} hex - a hex string to convert     * @returns {Address4}     */    static fromHex(hex) {        const stripped = hex.replace(/:/g, '');        if (!/^[0-9a-fA-F]{8}$/.test(stripped)) {            throw new address_error_1.AddressError('IPv4 hex must be exactly 8 hex digits');        }        const groups = [];        for (let i = 0; i < 8; i += 2) {            groups.push(parseInt(stripped.slice(i, i + 2), 16));        }        return new Address4(groups.join('.'));    }    /**     * Converts an integer into a IPv4 address object. The integer must be a     * non-negative safe integer in the range `[0, 2**32 - 1]`; otherwise     * `AddressError` is thrown.     * @param {integer} integer - a number to convert     * @returns {Address4}     */    static fromInteger(integer) {        if (!Number.isInteger(integer) || integer < 0 || integer > 0xffffffff) {            throw new address_error_1.AddressError('IPv4 integer must be in the range 0 to 2**32 - 1');        }        return Address4.fromHex(integer.toString(16).padStart(8, '0'));    }    /**     * Return an address from in-addr.arpa form     * @param {string} arpaFormAddress - an 'in-addr.arpa' form ipv4 address     * @returns {Adress4}     * @example     * var address = Address4.fromArpa(42.2.0.192.in-addr.arpa.)     * address.correctForm(); // '192.0.2.42'     */    static fromArpa(arpaFormAddress) {        // remove ending ".in-addr.arpa." or just "."        const leader = arpaFormAddress.replace(/(\.in-addr\.arpa)?\.$/, '');        const address = leader.split('.').reverse().join('.');        return new Address4(address);    }    /**     * Converts an IPv4 address object to a hex string     * @returns {String}     */    toHex() {        return this.parsedAddress.map((part) => common.stringToPaddedHex(part)).join(':');    }    /**     * Converts an IPv4 address object to an array of bytes.     *     * To get a Node.js `Buffer`, wrap the result: `Buffer.from(address.toArray())`.     * @returns {Array}     */    toArray() {        return this.parsedAddress.map((part) => parseInt(part, 10));    }    /**     * Converts an IPv4 address object to an IPv6 address group     * @returns {String}     */    toGroup6() {        const output = [];        let i;        for (i = 0; i < constants.GROUPS; i += 2) {            output.push(`${common.stringToPaddedHex(this.parsedAddress[i])}${common.stringToPaddedHex(this.parsedAddress[i + 1])}`);        }        return output.join(':');    }    /**     * Returns the address as a `bigint`     * @returns {bigint}     */    bigInt() {        return BigInt(`0x${this.parsedAddress.map((n) => common.stringToPaddedHex(n)).join('')}`);    }    /**     * Helper function getting start address.     * @returns {bigint}     */    _startAddress() {        return BigInt(`0b${this.mask() + '0'.repeat(constants.BITS - this.subnetMask)}`);    }    /**     * The first address in the range given by this address' subnet.     * Often referred to as the Network Address.     * @returns {Address4}     */    startAddress() {        return Address4.fromBigInt(this._startAddress());    }    /**     * The first host address in the range given by this address's subnet ie     * the first address after the Network Address     * @returns {Address4}     */    startAddressExclusive() {        const adjust = BigInt('1');        return Address4.fromBigInt(this._startAddress() + adjust);    }    /**     * Helper function getting end address.     * @returns {bigint}     */    _endAddress() {        return BigInt(`0b${this.mask() + '1'.repeat(constants.BITS - this.subnetMask)}`);    }    /**     * The last address in the range given by this address' subnet     * Often referred to as the Broadcast     * @returns {Address4}     */    endAddress() {        return Address4.fromBigInt(this._endAddress());    }    /**     * The last host address in the range given by this address's subnet ie     * the last address prior to the Broadcast Address     * @returns {Address4}     */    endAddressExclusive() {        const adjust = BigInt('1');        return Address4.fromBigInt(this._endAddress() - adjust);    }    /**     * The dotted-decimal form of the subnet mask, e.g. `255.255.240.0` for     * a `/20`. Returns an `Address4`; call `.correctForm()` for the string.     * @returns {Address4}     */    subnetMaskAddress() {        return Address4.fromBigInt(BigInt(`0b${'1'.repeat(this.subnetMask)}${'0'.repeat(constants.BITS - this.subnetMask)}`));    }    /**     * The Cisco-style wildcard mask, e.g. `0.0.0.255` for a `/24`. This is     * the bitwise inverse of `subnetMaskAddress()`. Returns an `Address4`;     * call `.correctForm()` for the string.     * @returns {Address4}     */    wildcardMask() {        return Address4.fromBigInt(BigInt(`0b${'0'.repeat(this.subnetMask)}${'1'.repeat(constants.BITS - this.subnetMask)}`));    }    /**     * The network address in CIDR string form, e.g. `192.168.1.0/24` for     * `192.168.1.5/24`. For an address with no explicit subnet the prefix is     * `/32`, e.g. `networkForm()` on `192.168.1.5` returns `192.168.1.5/32`.     * @returns {string}     */    networkForm() {        return `${this.startAddress().correctForm()}/${this.subnetMask}`;    }    /**     * Converts a BigInt to a v4 address object. The value must be in the     * range `[0, 2**32 - 1]`; otherwise `AddressError` is thrown.     * @param {bigint} bigInt - a BigInt to convert     * @returns {Address4}     */    static fromBigInt(bigInt) {        if (bigInt < 0n || bigInt > 0xffffffffn) {            throw new address_error_1.AddressError('IPv4 BigInt must be in the range 0 to 2**32 - 1');        }        return Address4.fromHex(bigInt.toString(16).padStart(8, '0'));    }    /**     * Convert a byte array to an Address4 object.     *     * To convert from a Node.js `Buffer`, spread it: `Address4.fromByteArray([...buf])`.     * @param {Array<number>} bytes - an array of 4 bytes (0-255)     * @returns {Address4}     */    static fromByteArray(bytes) {        if (bytes.length !== 4) {            throw new address_error_1.AddressError('IPv4 addresses require exactly 4 bytes');        }        // Validate that all bytes are within valid range (0-255)        for (let i = 0; i < bytes.length; i++) {            if (!Number.isInteger(bytes[i]) || bytes[i] < 0 || bytes[i] > 255) {                throw new address_error_1.AddressError('All bytes must be integers between 0 and 255');            }        }        return this.fromUnsignedByteArray(bytes);    }    /**     * Convert an unsigned byte array to an Address4 object     * @param {Array<number>} bytes - an array of 4 unsigned bytes (0-255)     * @returns {Address4}     */    static fromUnsignedByteArray(bytes) {        if (bytes.length !== 4) {            throw new address_error_1.AddressError('IPv4 addresses require exactly 4 bytes');        }        const address = bytes.join('.');        return new Address4(address);    }    /**     * Returns the first n bits of the address, defaulting to the     * subnet mask     * @returns {String}     */    mask(mask) {        if (mask === undefined) {            mask = this.subnetMask;        }        return this.getBitsBase2(0, mask);    }    /**     * Returns the bits in the given range as a base-2 string     * @returns {string}     */    getBitsBase2(start, end) {        return this.binaryZeroPad().slice(start, end);    }    /**     * Return the reversed ip6.arpa form of the address     * @param {Object} options     * @param {boolean} options.omitSuffix - omit the "in-addr.arpa" suffix     * @returns {String}     */    reverseForm(options) {        if (!options) {            options = {};        }        const reversed = this.correctForm().split('.').reverse().join('.');        if (options.omitSuffix) {            return reversed;        }        return `${reversed}.in-addr.arpa.`;    }    /**     * Returns true if the given address is a multicast address     * @returns {boolean}     */    isMulticast() {        return this.isInSubnet(MULTICAST_V4);    }    /**     * Returns true if the address is in one of the [RFC 1918](https://datatracker.ietf.org/doc/html/rfc1918) private address ranges (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`).     * @returns {boolean}     */    isPrivate() {        return PRIVATE_V4.some((subnet) => this.isInSubnet(subnet));    }    /**     * Returns true if the address is in the loopback range `127.0.0.0/8` ([RFC 1122](https://datatracker.ietf.org/doc/html/rfc1122)).     * @returns {boolean}     */    isLoopback() {        return this.isInSubnet(LOOPBACK_V4);    }    /**     * Returns true if the address is in the link-local range `169.254.0.0/16` ([RFC 3927](https://datatracker.ietf.org/doc/html/rfc3927)).     * @returns {boolean}     */    isLinkLocal() {        return this.isInSubnet(LINK_LOCAL_V4);    }    /**     * Returns true if the address is the unspecified address `0.0.0.0`.     * @returns {boolean}     */    isUnspecified() {        return this.isInSubnet(UNSPECIFIED_V4);    }    /**     * Returns true if the address is the limited broadcast address `255.255.255.255` ([RFC 919](https://datatracker.ietf.org/doc/html/rfc919)).     * @returns {boolean}     */    isBroadcast() {        return this.isInSubnet(BROADCAST_V4);    }    /**     * Returns true if the address is in the carrier-grade NAT range `100.64.0.0/10` ([RFC 6598](https://datatracker.ietf.org/doc/html/rfc6598)).     * @returns {boolean}     */    isCGNAT() {        return this.isInSubnet(CGNAT_V4);    }    /**     * Returns a zero-padded base-2 string representation of the address     * @returns {string}     */    binaryZeroPad() {        if (this._binaryZeroPad === undefined) {            this._binaryZeroPad = this.bigInt().toString(2).padStart(constants.BITS, '0');        }        return this._binaryZeroPad;    }    /**     * Groups an IPv4 address for inclusion at the end of an IPv6 address     * @returns {String}     */    groupForV6() {        const segments = this.parsedAddress;        return this.address.replace(constants.RE_ADDRESS, `<span class="hover-group group-v4 group-6">${segments            .slice(0, 2)            .join('.')}</span>.<span class="hover-group group-v4 group-7">${segments            .slice(2, 4)            .join('.')}</span>`);    }}exports.Address4 = Address4;const MULTICAST_V4 = new Address4('224.0.0.0/4');const PRIVATE_V4 = [    new Address4('10.0.0.0/8'),    new Address4('172.16.0.0/12'),    new Address4('192.168.0.0/16'),];const LOOPBACK_V4 = new Address4('127.0.0.0/8');const LINK_LOCAL_V4 = new Address4('169.254.0.0/16');const UNSPECIFIED_V4 = new Address4('0.0.0.0/32');const BROADCAST_V4 = new Address4('255.255.255.255/32');const CGNAT_V4 = new Address4('100.64.0.0/10');//# sourceMappingURL=ipv4.js.map