pax_global_header00006660000000000000000000000064140316576220014520gustar00rootroot0000000000000052 comment=cfc331d64edcb5d09237d8e0f407370d6af6d235 node-netmask-2.0.2/000077500000000000000000000000001403165762200141065ustar00rootroot00000000000000node-netmask-2.0.2/.gitignore000066400000000000000000000000571403165762200161000ustar00rootroot00000000000000node_modules/ package-lock.json lib/netmask.js node-netmask-2.0.2/.npmignore000066400000000000000000000000061403165762200161010ustar00rootroot00000000000000.git* node-netmask-2.0.2/CHANGELOG.md000066400000000000000000000044041403165762200157210ustar00rootroot00000000000000## v2.0.1 (Mar 29, 2021) ### IMPORTANT: Security Fix > This version contains an important security fix. If you are using netmask `<=2.0.0`, please upgrade to `2.0.1` or above. * Rewrite byte parsing without using JS `parseInt()`([commit](https://github.com/rs/node-netmask/commit/3f19a056c4eb808ea4a29f234274c67bc5a848f4)) * This is [CVE-2021-29418](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-29418). ### Bugfixes * Add checks on spaces before and after bytes * This will now throw an exception when spaces are present like ' 1.2.3.4' or '1. 2.3.4' or '1.2.3.4 '. ### Internal Changes * Avoid some useless memory allocations * New Mocha testing suite, thanks @kaoudis [#36](https://github.com/rs/node-netmask/pull/36) ## v2.0.0 (Mar 19, 2021) ### Breaking Change Previous API was treating IPs with less than for bytes as IP with a netmask of the size of the provided bytes (1=8, 2=16, 3=24) and was interpreting the IP as if it was completed with 0s on the right side. *Proper IP parsing for these is to consider missing bytes as being 0s on the left side.* Mask size is no longer infered by the number of bytes provided. This means that the input `216.240` will no longer be interpreted as `216.240.0.0/16`, but as `0.0.216.240/32`, as per convention. See [the change](https://github.com/rs/node-netmask/commit/9f9fc38c6db1a682d23289b5c9dc2009d957a00b). ### Bugfixes * Fix improper parsing of hex bytes ## v1.1.0 (Mar 18, 2021) ### IMPORTANT: Security Fix > This version contains an important security fix. If you are using netmask `<=1.0.6`, please upgrade to `1.1.0` or above. * Fix improper parsing of octal bytes ([commit](https://github.com/rs/node-netmask/commit/4678fd840ad0b4730dbad2d415712c0782e886cc)) * This is [CVE-2021-28918](https://sick.codes/sick-2021-011). * See also the [npm advisory](https://www.npmjs.com/advisories/1658) ### Other Changes * Performance: Avoid large allocations when provided large netmasks (like `/8`) * Thanks @dschenkelman [#34](https://github.com/rs/node-netmask/pull/34) ## v1.0.6 (May 30, 2016) * Changes before this release are not documented here. Please see [the commit list](https://github.com/rs/node-netmask/commits/master) or the [compare view](https://github.com/rs/node-netmask/compare/1.0.5...rs:1.0.6). node-netmask-2.0.2/CREDITS.md000066400000000000000000000025641403165762200155340ustar00rootroot00000000000000Credits ======= These credits refer to the contributors to this repository: [@rs](https://github.com/rs) - maintainer [@ryanrolds](https://github.com/ryanrolds) - Now with 0.4.x support. #2 [@palmerabollo](https://github.com/palmerabollo) - Expressions "1.2.3.4/" are not valid #6 [@steve-jansen](https://github.com/steve-jansen) - fixes typo in readme.md #7 [@jksdua](https://github.com/jksdua) - Added forEach helper to allow looping through usable IP addresses #9 [@gmiroshnykov](https://github.com/gmiroshnykov) - Tiny typo fix #10 [@TooTallNate](https://github.com/TooTallNate) - package: move "coffee-script" to devDependencies #11, README: fix small typo #12 [@yorkie](https://github.com/yorkie) - more rigid check for Netmask.constructor #13 [@runk](https://github.com/runk) - fix contains method for netmasks #18 [@yvesago](https://github.com/yvesago) - a patch with mocha test to fix /31 and /32 block.contains #20 [@meteormatt](https://github.com/meteormatt) - The comment in README.md is wrong #22 [@dschenkelman](https://github.com/dschenkelman) - Avoid large memory allocations when doing forEach in case netmask is large (e.g. /8) #34 [@sickcodes](https://github.com/sickcodes), [@kaoudis](https://github.com/kaoudis), [@Koroeskohr](https://github.com/Koroeskohr), [@nicksahler](https://github.com/nicksahler) - adds CREDITS, plus mocha tests for transpiled node #36 node-netmask-2.0.2/README.md000066400000000000000000000075371403165762200154010ustar00rootroot00000000000000Netmask ======= The Netmask class parses and understands IPv4 CIDR blocks so they can be explored and compared. This module is highly inspired by Perl [Net::Netmask](http://search.cpan.org/dist/Net-Netmask/) module. Synopsis -------- ```js var Netmask = require('netmask').Netmask var block = new Netmask('10.0.0.0/12'); block.base; // 10.0.0.0 block.mask; // 255.240.0.0 block.bitmask; // 12 block.hostmask; // 0.15.255.255 block.broadcast; // 10.15.255.255 block.size; // 1048576 block.first; // 10.0.0.1 block.last; // 10.15.255.254 block.contains('10.0.8.10'); // true block.contains('10.8.0.10'); // true block.contains('192.168.1.20'); // false block.forEach(function(ip, long, index)); block.next() // Netmask('10.16.0.0/12') ``` Constructing ------------ Netmask objects are created with an IP address and optionally a mask. There are many forms that are recognized: ``` '216.240.32.0/24' // The preferred form. '216.240.32.0/255.255.255.0' '216.240.32.0', '255.255.255.0' '216.240.32.0', 0xffffff00 '216.240.32.4' // A /32 block. '0330.0360.040.04' // Octal form '0xd8.0xf0.0x20.0x4' // Hex form ``` API --- - `.base`: The base address of the network block as a string (eg: 216.240.32.0). Base does not give an indication of the size of the network block. - `.mask`: The netmask as a string (eg: 255.255.255.0). - `.hostmask`: The host mask which is the opposite of the netmask (eg: 0.0.0.255). - `.bitmask`: The netmask as a number of bits in the network portion of the address for this block (eg: 24). - `.size`: The number of IP addresses in a block (eg: 256). - `.broadcast`: The blocks broadcast address (eg: 192.168.1.0/24 => 192.168.1.255) - `.first`, `.last`: First and last useable address - `.contains(ip or block)`: Returns a true if the IP number `ip` is part of the network. That is, a true value is returned if `ip` is between `base` and `broadcast`. If a Netmask object or a block is given, it returns true only of the given block fits inside the network. - `.forEach(fn)`: Similar to the Array prototype method. It loops through all the useable addresses, ie between `first` and `last`. - `.next(count)`: Without a `count`, return the next block of the same size after the current one. With a count, return the Nth block after the current one. A count of -1 returns the previous block. Undef will be returned if out of legal address space. - `.toString()`: The netmask in base/bitmask format (e.g., '216.240.32.0/24') Installation ------------ $ npm install netmask Run all tests (vows plus mocha) ------------------------------- $ npm test License ------- (The MIT License) Copyright (c) 2011 Olivier Poitrey Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. node-netmask-2.0.2/example/000077500000000000000000000000001403165762200155415ustar00rootroot00000000000000node-netmask-2.0.2/example/ipcalc.coffee000066400000000000000000000006721403165762200201520ustar00rootroot00000000000000Netmask = require('netmask').Netmask ip = process.argv[2] netmask = new Netmask(ip) out = console.log out "Address: #{ip.split('/', 1)[0]}" out "Netmask: #{netmask.mask} = #{netmask.bitmask}" out "Wildcard: #{netmask.hostmask}" out "=>" out "Network: #{netmask.base}/#{netmask.bitmask}" out "HostMin: #{netmask.first}" out "HostMax: #{netmask.last}" out "Broadcast: #{netmask.broadcast}" out "Hosts/Net: #{netmask.size}" out netmask.next()node-netmask-2.0.2/lib/000077500000000000000000000000001403165762200146545ustar00rootroot00000000000000node-netmask-2.0.2/lib/netmask.coffee000066400000000000000000000132151403165762200174710ustar00rootroot00000000000000long2ip = (long) -> a = (long & (0xff << 24)) >>> 24; b = (long & (0xff << 16)) >>> 16; c = (long & (0xff << 8)) >>> 8; d = long & 0xff; return [a, b, c, d].join('.') ip2long = (ip) -> b = [] for i in [0..3] if ip.length == 0 break if i > 0 if ip[0] != '.' throw new Error('Invalid IP') ip = ip.substring(1) [n, c] = atob(ip) ip = ip.substring(c) b.push(n) if ip.length != 0 throw new Error('Invalid IP') switch b.length when 1 # Long input notation if b[0] > 0xFFFFFFFF throw new Error('Invalid IP') return b[0] >>> 0 when 2 # Class A notation if b[0] > 0xFF or b[1] > 0xFFFFFF throw new Error('Invalid IP') return (b[0] << 24 | b[1]) >>> 0 when 3 # Class B notation if b[0] > 0xFF or b[1] > 0xFF or b[2] > 0xFFFF throw new Error('Invalid IP') return (b[0] << 24 | b[1] << 16 | b[2]) >>> 0 when 4 # Dotted quad notation if b[0] > 0xFF or b[1] > 0xFF or b[2] > 0xFF or b[3] > 0xFF throw new Error('Invalid IP') return (b[0] << 24 | b[1] << 16 | b[2] << 8 | b[3]) >>> 0 else throw new Error('Invalid IP') chr = (b) -> return b.charCodeAt(0) chr0 = chr('0') chra = chr('a') chrA = chr('A') atob = (s) -> n = 0 base = 10 dmax = '9' i = 0 if s.length > 1 and s[i] == '0' if s[i+1] == 'x' or s[i+1] == 'X' i += 2 base = 16 else if '0' <= s[i+1] and s[i+1] <= '9' i++ base = 8 dmax = '7' start = i while i < s.length if '0' <= s[i] and s[i] <= dmax n = (n*base + (chr(s[i])-chr0)) >>> 0 else if base == 16 if 'a' <= s[i] and s[i] <= 'f' n = (n*base + (10+chr(s[i])-chra)) >>> 0 else if 'A' <= s[i] and s[i] <= 'F' n = (n*base + (10+chr(s[i])-chrA)) >>> 0 else break else break if n > 0xFFFFFFFF throw new Error('too large') i++ if i == start throw new Error('empty octet') return [n, i] class Netmask constructor: (net, mask) -> throw new Error("Missing `net' parameter") unless typeof net is 'string' unless mask # try to find the mask in the net (i.e.: 1.2.3.4/24 or 1.2.3.4/255.255.255.0) [net, mask] = net.split('/', 2) unless mask mask = 32 if typeof mask is 'string' and mask.indexOf('.') > -1 # Compute bitmask, the netmask as a number of bits in the network portion of the address for this block (eg.: 24) try @maskLong = ip2long(mask) catch error throw new Error("Invalid mask: #{mask}") for i in [32..0] if @maskLong == (0xffffffff << (32 - i)) >>> 0 @bitmask = i break else if mask or mask == 0 # The mask was passed as bitmask, compute the mask as long from it @bitmask = parseInt(mask, 10) @maskLong = 0 if @bitmask > 0 @maskLong = (0xffffffff << (32 - @bitmask)) >>> 0 else throw new Error("Invalid mask: empty") try @netLong = (ip2long(net) & @maskLong) >>> 0 catch error throw new Error("Invalid net address: #{net}") throw new Error("Invalid mask for ip4: #{mask}") unless @bitmask <= 32 # The number of IP address in the block (eg.: 254) @size = Math.pow(2, 32 - @bitmask) # The address of the network block as a string (eg.: 216.240.32.0) @base = long2ip(@netLong) # The netmask as a string (eg.: 255.255.255.0) @mask = long2ip(@maskLong) # The host mask, the opposite of the netmask (eg.: 0.0.0.255) @hostmask = long2ip(~@maskLong) # The first usable address of the block @first = if @bitmask <= 30 then long2ip(@netLong + 1) else @base # The last usable address of the block @last = if @bitmask <= 30 then long2ip(@netLong + @size - 2) else long2ip(@netLong + @size - 1) # The block's broadcast address: the last address of the block (eg.: 192.168.1.255) @broadcast = if @bitmask <= 30 then long2ip(@netLong + @size - 1) # Returns true if the given ip or netmask is contained in the block contains: (ip) -> if typeof ip is 'string' and (ip.indexOf('/') > 0 or ip.split('.').length isnt 4) ip = new Netmask(ip) if ip instanceof Netmask return @contains(ip.base) and @contains((ip.broadcast || ip.last)) else return (ip2long(ip) & @maskLong) >>> 0 == ((@netLong & @maskLong)) >>> 0 # Returns the Netmask object for the block which follow this one next: (count=1) -> return new Netmask(long2ip(@netLong + (@size * count)), @mask) forEach: (fn) -> # this implementation is not idiomatic but avoids large memory allocations (2 arrays, one for range and one for the results) in cases when then netmask is large long = ip2long(@first) lastLong = ip2long(@last) index = 0 while long <= lastLong fn long2ip(long), long, index index++ long++ return # Returns the complete netmask formatted as `base/bitmask` toString: -> return @base + "/" + @bitmask exports.ip2long = ip2long exports.long2ip = long2ip exports.Netmask = Netmask node-netmask-2.0.2/package.json000066400000000000000000000016061403165762200163770ustar00rootroot00000000000000{ "author": "Olivier Poitrey ", "name": "netmask", "description": "Parse and lookup IP network blocks", "version": "2.0.2", "homepage": "https://github.com/rs/node-netmask", "bugs": "https://github.com/rs/node-netmask/issues", "license": "MIT", "repository": { "type": "git", "url": "git://github.com/rs/node-netmask.git" }, "keywords": [ "net", "mask", "ip", "network", "cidr", "netmask", "subnet", "ipcalc" ], "main": "./lib/netmask", "scripts": { "prepublish": "coffee -c lib/*.coffee", "test": "coffee -c lib/*.coffee && vows --spec test/* && mocha tests/*" }, "engines": { "node": ">= 0.4.0" }, "devDependencies": { "coffee-script": ">=1.2.0", "mocha": "^8.3.2", "vows": "*" } } node-netmask-2.0.2/test/000077500000000000000000000000001403165762200150655ustar00rootroot00000000000000node-netmask-2.0.2/test/badnets.coffee000066400000000000000000000040371403165762200176620ustar00rootroot00000000000000vows = require 'vows' assert = require 'assert' Netmask = require('../lib/netmask').Netmask shouldFailWithError = (msg) -> context = topic: -> try return new Netmask(@context.name) catch e return e 'should fail': (e) -> assert.ok isError(e), "is an Error object #{e}" "with error `#{msg}'": (e) -> assert.ok e.message?.toLowerCase().indexOf(msg.toLowerCase()) > -1, "'#{e.message}' =~ #{msg}" return context isError = (e) -> return typeof e == 'object' and Object.prototype.toString.call(e) == '[object Error]' vows.describe('IPs with bytes greater than 255') .addBatch '209.256.68.22/255.255.224.0': shouldFailWithError 'Invalid net' '209.180.68.22/256.255.224.0': shouldFailWithError 'Invalid mask' '209.500.70.33/19': shouldFailWithError 'Invalid net' '140.999.82': shouldFailWithError 'Invalid net' '899.174': shouldFailWithError 'Invalid net' '209.157.65536/19': shouldFailWithError 'Invalid net' '209.300.64.0.10': shouldFailWithError 'Invalid net' 'garbage': shouldFailWithError 'Invalid net' .export(module) vows.describe('Invalid IP format') .addBatch ' 1.2.3.4': shouldFailWithError 'Invalid net' ' 1.2.3.4': shouldFailWithError 'Invalid net' '1. 2.3.4': shouldFailWithError 'Invalid net' '1.2. 3.4': shouldFailWithError 'Invalid net' '1.2.3. 4': shouldFailWithError 'Invalid net' '1.2.3.4 ': shouldFailWithError 'Invalid net' '1 .2.3.4': shouldFailWithError 'Invalid net' '018.0.0.0': shouldFailWithError 'Invalid net' '08.0.0.0': shouldFailWithError 'Invalid net' '0xfg.0.0.0': shouldFailWithError 'Invalid net' .export(module) vows.describe('Ranges that are a power-of-two big, but are not legal blocks') .addBatch '218.0.0.0/221.255.255.255': shouldFailWithError 'Invalid mask' '218.0.0.4/218.0.0.11': shouldFailWithError 'Invalid mask' .export(module) node-netmask-2.0.2/test/netmasks.coffee000066400000000000000000000147201403165762200200670ustar00rootroot00000000000000vows = require 'vows' assert = require 'assert' util = require 'util' Netmask = require('../lib/netmask').Netmask fixtures = [ # addr mask base newmask bitmask ['209.157.68.22/255.255.224.0', null, '209.157.64.0', '255.255.224.0', 19] ['209.157.68.22', '255.255.224.0', '209.157.64.0', '255.255.224.0', 19] ['209.157.70.33/19', null, '209.157.64.0', '255.255.224.0', 19] ['209.157.70.33', null, '209.157.70.33', '255.255.255.255', 32] ['140.174.82', null, '140.174.0.82', '255.255.255.255', 32] ['140.174', null, '140.0.0.174', '255.255.255.255', 32] ['10', null, '0.0.0.10', '255.255.255.255', 32] ['10/8', null, '0.0.0.0', '255.0.0.0', 8] ['209.157.64/19', null, '209.157.0.0', '255.255.224.0', 19] ['216.140.48.16/32', null, '216.140.48.16', '255.255.255.255', 32] ['209.157/17', null, '209.0.0.0', '255.255.128.0', 17] ['0.0.0.0/0', null, '0.0.0.0', '0.0.0.0', 0] ['0xffffffff', null, '255.255.255.255', '255.255.255.255', 32] ['1.1', null, '1.0.0.1', '255.255.255.255', 32] ['1.0xffffff', null, '1.255.255.255', '255.255.255.255', 32] ['1.2.3', null, '1.2.0.3', '255.255.255.255', 32] ['1.2.0xffff', null, '1.2.255.255', '255.255.255.255', 32] ] contexts = [] fixtures.forEach (fixture) -> [addr, mask, base, newmask, bitmask] = fixture context = topic: -> new Netmask(addr, mask) context["base is `#{base}'"] = (block) -> assert.equal block.base, base context["mask is `#{newmask}'"] = (block) -> assert.equal block.mask, newmask context["bitmask is `#{bitmask}'"] = (block) -> assert.equal block.bitmask, bitmask context["toString is `#{base}/`#{bitmask}'"] = (block) -> assert.equal block.toString(), block.base + "/" + block.bitmask contexts["for #{addr}" + (if mask then " with #{mask}" else '')] = context vows.describe('Netmaks parsing').addBatch(contexts).export(module) vows.describe('Netmask contains IP') .addBatch 'block 192.168.1.0/24': topic: -> new Netmask('192.168.1.0/24') 'contains IP 192.168.1.0': (block) -> assert.ok block.contains('192.168.1.0') 'contains IP 192.168.1.255': (block) -> assert.ok block.contains('192.168.1.255') 'contains IP 192.168.1.63': (block) -> assert.ok block.contains('192.168.1.63') 'does not contain IP 192.168.0.255': (block) -> assert.ok not block.contains('192.168.0.255') 'does not contain IP 192.168.2.0': (block) -> assert.ok not block.contains('192.168.2.0') 'does not contain IP 10.168.2.0': (block) -> assert.ok not block.contains('10.168.2.0') 'does not contain IP 209.168.2.0': (block) -> assert.ok not block.contains('209.168.2.0') 'contains block 192.168.1.0/24': (block) -> assert.ok block.contains('192.168.1.0/24') 'contains block 192.168.1 (0.192.168.10)': (block) -> assert.ok not block.contains('192.168.1') 'does not contains block 192.168.1.128/25': (block) -> assert.ok block.contains('192.168.1.128/25') 'does not contain block 192.168.1.0/23': (block) -> assert.ok not block.contains('192.168.1.0/23') 'does not contain block 192.168.2.0/24': (block) -> assert.ok not block.contains('192.168.2.0/24') 'toString equals 192.168.1.0/24': (block) -> assert.equal block.toString(), '192.168.1.0/24' 'block 192.168.0.0/24': topic: -> new Netmask('192.168.0.0/24') 'does not contain block 192.168 (0.0.192.168)': (block) -> assert.ok not block.contains('192.168') 'does not contain block 192.168.0.0/16': (block) -> assert.ok not block.contains('192.168.0.0/16') 'block 31.0.0.0/8': topic: -> new Netmask('31.0.0.0/8') 'contains IP 31.5.5.5': (block) -> assert.ok block.contains('31.5.5.5') 'does not contain IP 031.5.5.5 (25.5.5.5)': (block) -> assert.ok not block.contains('031.5.5.5') 'does not contain IP 0x31.5.5.5 (49.5.5.5)': (block) -> assert.ok not block.contains('0x31.5.5.5') 'does not contain IP 0X31.5.5.5 (49.5.5.5)': (block) -> assert.ok not block.contains('0X31.5.5.5') 'block 127.0.0.0/8': topic: -> new Netmask('127.0.0.0/8') 'contains IP 127.0.0.2': (block) -> assert.ok block.contains('127.0.0.2') 'contains IP 0177.0.0.2 (127.0.0.2)': (block) -> assert.ok block.contains('0177.0.0.2') 'contains IP 0x7f.0.0.2 (127.0.0.2)': (block) -> assert.ok block.contains('0x7f.0.0.2') 'does not contains IP 127 (0.0.0.127)': (block) -> assert.ok not block.contains('127') 'does not contains IP 0177 (0.0.0.127)': (block) -> assert.ok not block.contains('0177') 'block 0.0.0.0/24': topic: -> new Netmask('0.0.0.0/0') 'contains IP 0.0.0.0': (block) -> assert.ok block.contains('0.0.0.0') 'contains IP 0': (block) -> assert.ok block.contains('0') 'contains IP 10 (0.0.0.10)': (block) -> assert.ok block.contains('10') 'contains IP 010 (0.0.0.8)': (block) -> assert.ok block.contains('010') 'contains IP 0x10 (0.0.0.16)': (block) -> assert.ok block.contains('0x10') .export(module) vows.describe('Netmask forEach') .addBatch 'block 192.168.1.0/24': topic: -> new Netmask('192.168.1.0/24') 'should loop through all ip addresses': (block) -> called = 0 block.forEach (ip, long, index) -> called = index assert.equal (called + 1), 254 'block 192.168.1.0/23': topic: -> new Netmask('192.168.1.0/23') 'should loop through all ip addresses': (block) -> called = 0 block.forEach (ip, long, index) -> called = index assert.equal (called + 1), 510 .export(module)node-netmask-2.0.2/tests/000077500000000000000000000000001403165762200152505ustar00rootroot00000000000000node-netmask-2.0.2/tests/netmask.js000066400000000000000000000066231403165762200172570ustar00rootroot00000000000000/* It is important to test our Javascript output as well as our coffeescript, * since code that is transpiled may be slightly different in effect from the * original. * * Run these tests (against lib/netmask.js, not lib/netmask.coffee directly) * using mocha, after re-generating lib/netmask.js including your changes: * * mocha tests/netmask.js */ const assert = require('assert'); const Netmask = require('../').Netmask; describe('Netmask', () => { describe('can build a block', () => { let block = new Netmask('10.1.2.0/24'); it('should contain a sub-block', () => { let block1 = new Netmask('10.1.2.10/29'); assert(block.contains(block1)); }); it('should contain another sub-block', () => { let block2 = new Netmask('10.1.2.10/31'); assert(block.contains(block2)); }); it('should contain a third sub-block', () => { let block3 = new Netmask('10.1.2.20/32'); assert(block.contains(block3)); }); }); describe('when presented with an octet which is not a number', () => { let block = new Netmask('192.168.0.0/29') it('should throw', () => { assert.throws(() => block.contains('192.168.~.4'), Error); }); }); describe('can handle hexadecimal, octal, & decimal octets in input IP', () => { let block1 = new Netmask('31.0.0.0/19'); let block2 = new Netmask('127.0.0.0/8'); let block3 = new Netmask('255.0.0.1/12'); let block4 = new Netmask('10.0.0.1/8'); let block5 = new Netmask('1.0.0.1/4'); describe('octal', () => { it('block 31.0.0.0/19 does not contain 031.0.5.5', () => { assert(!block1.contains('031.0.5.5')); }); it('block 127.0.0.0/8 contains 0177.0.0.2 (127.0.0.2)', () => { assert(block2.contains('0177.0.0.2')); }); it('block 255.0.0.1/12 does not contain 0255.0.0.2 (173.0.0.2)', () => { assert(!block3.contains('0255.0.0.2')); }); it('block 10.0.0.1/8 contains 012.0.0.255 (10.0.0.255)', () => { assert(block4.contains('012.0.0.255')); }); it('block 1.0.0.1/4 contains 01.02.03.04', () => { assert(block5.contains('01.02.03.04')); }); }); describe('hexadecimal', () => { it('block 31.0.0.0/19 does not contain 0x31.0.5.5', () => { assert(!block1.contains('0x31.0.5.5')); }); it('block 127.0.0.0/8 contains 0x7f.0.0.0x2 (127.0.0.2)', () => { assert(block2.contains('0x7f.0.0.0x2')); }); it('block 255.0.0.1/12 contains 0xff.0.0.2', () => { assert(block3.contains('0xff.0.0.2')); }); it('block 10.0.0.1/8 does not contain 0x10.0.0.255', () => { assert(!block4.contains('0x10.0.0.255')); }); it('block 1.0.0.1/4 contains 0x1.0x2.0x3.0x4', () => { assert(block5.contains('0x1.0x2.0x3.0x4')); }); }); describe('decimal', () => { it('block 31.0.0.0/19 contains 31.0.5.5', () => { assert(block1.contains('31.0.5.5')); }); it('block 127.0.0.0/8 does not contain 128.0.0.2', () =>{ assert(!block2.contains('128.0.0.2')); }); it('block 255.0.0.1/12 contains 255.0.0.2', () => { assert(block3.contains('255.0.0.2')); }); it('block 10.0.0.1/8 contains 10.0.0.255', () => { assert(block4.contains('10.0.0.255')); }); it('block 1.0.0.1/4 contains 1.2.3.4', () => { assert(block5.contains('1.2.3.4')); }); }); }); });