UNPKG

@aikidosec/firewall

Version:

Zen by Aikido is an embedded Application Firewall that autonomously protects Node.js apps against common and critical attacks, provides rate limiting, detects malicious traffic (including bots), and more.

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;