UNPKG

@aikidosec/firewall

Version:

Zen by Aikido is an embedded Web Application Firewall that autonomously protects Node.js apps against common and critical attacks

144 lines (143 loc) 4.58 kB
"use strict"; // Based on https://github.com/demskie/netparser // MIT License - Copyright (c) 2019 alex Object.defineProperty(exports, "__esModule", { value: true }); exports.Network = void 0; const parse = require("./parse"); const Address_1 = require("./Address"); const BEFORE = -1; const EQUALS = 0; const AFTER = 1; class Network { constructor(network) { this.addr = new Address_1.Address(); this.netbits = -1; if (network) { const net = parse.network(network); if (net) { this.addr.setBytes(net.bytes); this.netbits = net.cidr; } } } destroy() { if (!this.addr.isValid()) { this.addr.destroy(); } this.netbits = -1; return this; } cidr() { if (this.isValid()) { return this.netbits; } return Number.NaN; } isValid() { return this.addr.isValid() && this.netbits !== -1; } duplicate() { const network = new Network(); if (this.isValid()) { network.addr.setBytes(this.addr.bytes().slice()); network.netbits = this.netbits; } return network; } next() { this.addr.increase(this.netbits); return this; } setCIDR(cidr) { if (!this.addr.isValid()) { this.destroy(); } else { cidr = Math.floor(cidr); if (cidr >= 0 && cidr <= this.addr.bytes().length * 8) { this.netbits = cidr; } else { this.destroy(); } } return this; } compare(network) { // check that both networks are valid if (!this.isValid() || !network.isValid()) return null; // compare addresses const cmp = this.addr.compare(network.addr); if (cmp !== EQUALS) return cmp; // compare subnet mask length if (this.netbits < network.netbits) return BEFORE; if (this.netbits > network.netbits) return AFTER; // otherwise they must be equal return EQUALS; } contains(network) { // check that both networks are valid if (!this.isValid() || !network.isValid()) return false; // ensure that both IPs are of the same type if (this.addr.bytes().length !== network.addr.bytes().length) return false; // handle edge cases if (this.netbits === 0) return true; if (network.netbits === 0) return false; // our base address should be less than or equal to the other base address if (this.addr.compare(network.addr) === AFTER) return false; // get the next network address for both const next = this.duplicate().next(); const otherNext = network.duplicate().next(); // handle edge case where our next network address overflows if (!next.isValid()) return true; // our address should be more than or equal to the other address if (next.addr.compare(otherNext.addr) === BEFORE) return false; // must be a child subnet return true; } adjacent(network) { // check that both networks are valid if (!this.isValid() || !network.isValid()) return false; // ensure that both IPs are of the same type if (this.addr.bytes().length !== network.addr.bytes().length) return false; // handle edge cases if (this.netbits === 0 || network.netbits == 0) return true; const cmp = this.addr.compare(network.addr); if (cmp === EQUALS) return false; // ensure that alpha addr contains the baseAddress that comes first let alpha, bravo; if (cmp === BEFORE) { alpha = this.duplicate().next(); bravo = network; } else { alpha = network.duplicate().next(); // eslint-disable-next-line @typescript-eslint/no-this-alias bravo = this; } // if alpha overflows then an adjacency is not possible if (!alpha.isValid()) return false; // alpha addr should equal bravo for them to be perfectly adjacent if (alpha.addr.compare(bravo.addr) === EQUALS) return true; // otherwise we aren't adjacent return false; } } exports.Network = Network;