├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── index.d.ts ├── index.js ├── package.json └── test └── test.js /.gitignore: -------------------------------------------------------------------------------- 1 | #### joe made this: https://goel.io/joe 2 | 3 | #####=== Node ===##### 4 | 5 | # Logs 6 | logs 7 | *.log 8 | 9 | # Runtime data 10 | pids 11 | *.pid 12 | *.seed 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 21 | .grunt 22 | 23 | # node-waf configuration 24 | .lock-wscript 25 | 26 | # Compiled binary addons (http://nodejs.org/api/addons.html) 27 | build/Release 28 | 29 | # Dependency directory 30 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git- 31 | node_modules 32 | 33 | # Debug log from npm 34 | npm-debug.log 35 | 36 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "0.12" 4 | - "0.11" 5 | - "0.10" 6 | - "iojs" 7 | - "node" 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Daniel Compton 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # IP Range Check 2 | 3 | [![Build Status](https://travis-ci.org/danielcompton/ip-range-check.svg?branch=master)](https://travis-ci.org/danielcompton/ip-range-check) 4 | 5 | [![NPM](https://nodei.co/npm/ip-range-check.png?downloads=true&downloadRank=true&stars=true)](https://www.npmjs.com/package/ip-range-check) 6 | 7 | This module lets you check if an IP matches one or more IP's or [CIDR](http://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing) ranges. It handles IPv6, IPv4, and IPv4-mapped over IPv6 addresses. 8 | 9 | It accepts either: 10 | 11 | * A single CIDR or IP string, e.g. `"125.19.23.0/24"`, or `"2001:cdba::3257:9652"`, or `"62.230.58.1"` 12 | * An array of CIDR and/or IP strings, e.g. `["125.19.23.0/24", "2001:cdba::3257:9652", "62.230.58.1"]` 13 | 14 | Importantly, it cannot match an IPv4 address to an IPv6 CIDR or vice versa, (IPv4-mapped IPv6 addresses notwithstanding). 15 | 16 | ## Installing 17 | 18 | ```sh 19 | npm install ip-range-check --save 20 | ``` 21 | 22 | ## IPv4 23 | 24 | ```js 25 | var ipRangeCheck = require("ip-range-check"); 26 | 27 | // Checks CIDR 28 | ipRangeCheck("192.168.1.1", "102.1.5.2/24") 29 | // > false 30 | ipRangeCheck("192.168.1.1", "192.168.1.0/24") 31 | // > true 32 | 33 | // Checks if IP matches string 34 | ipRangeCheck("192.168.1.1", "192.168.1.1") 35 | // > true 36 | 37 | // Checks array of CIDR's and string 38 | ipRangeCheck("192.168.1.1", ["102.1.5.2/24", "192.168.1.0/24", "106.1.180.84"]) 39 | // > true 40 | 41 | // Compare IPv6 with IPv4 42 | ipRangeCheck("195.58.1.62", ["::1/128", "125.92.12.53"]) 43 | // > false 44 | 45 | ``` 46 | 47 | ## IPv6 48 | 49 | ```js 50 | var ipRangeCheck = require("ip-range-check"); 51 | 52 | // Handles IPv6 in the same fashion as IPv4 53 | ipRangeCheck("::1", "::2/128") 54 | // > false 55 | ipRangeCheck("::1", ["::2", "::3/128"]) 56 | // > false 57 | ipRangeCheck("2001:cdba::3257:9652", "2001:cdba::3257:9652/128") 58 | // > true 59 | 60 | // IPv4-mapped IPv6 addresses are automatically converted back to IPv4 addresses 61 | // and will match against IPv4 CIDR/IP's. 62 | ipRangeCheck("0:0:0:0:0:FFFF:222.1.41.90", "222.1.41.0/24") 63 | // > true 64 | 65 | // IPv6 addresses/CIDR's are normalised 66 | ipRangeCheck("2001:cdba:0000:0000:0000:0000:3257:9652", ["2001:cdba::3257:9652"]) 67 | // > true 68 | ``` 69 | 70 | ## Developing 71 | 72 | To run the tests: 73 | 74 | ``` 75 | npm test 76 | ``` 77 | -------------------------------------------------------------------------------- /index.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {string} addr 4 | * @param {(string | string[])} range 5 | * @returns {boolean} 6 | */ 7 | declare function check_many_cidrs( 8 | addr: string, 9 | range: string | string[] 10 | ): boolean; 11 | 12 | declare namespace check_many_cidrs {} 13 | 14 | declare module "ip-range-check" { 15 | export = check_many_cidrs; 16 | } 17 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | var ipaddr = require("ipaddr.js"); 2 | 3 | module.exports = check_many_cidrs; 4 | 5 | function check_many_cidrs(addr, range) { 6 | if (typeof (range) === "string") { 7 | return check_single_cidr(addr, range) 8 | } 9 | else if (typeof (range) === "object") //list 10 | { 11 | var ip_is_in_range = false; 12 | for (var i = 0; i < range.length; i++) { 13 | if (check_single_cidr(addr, range[i])) { 14 | ip_is_in_range = true; 15 | break 16 | } 17 | } 18 | return ip_is_in_range; 19 | } 20 | } 21 | 22 | function check_single_cidr(addr, cidr) { 23 | try { 24 | var parsed_addr = ipaddr.process(addr); 25 | if (cidr.indexOf('/') === -1) { 26 | var parsed_cidr_as_ip = ipaddr.process(cidr); 27 | if ((parsed_addr.kind() === "ipv6") && (parsed_cidr_as_ip.kind() === "ipv6")){ 28 | return (parsed_addr.toNormalizedString() === parsed_cidr_as_ip.toNormalizedString()) 29 | } 30 | return (parsed_addr.toString() == parsed_cidr_as_ip.toString()) 31 | } 32 | else { 33 | var parsed_range = ipaddr.parseCIDR(cidr); 34 | return parsed_addr.match(parsed_range) 35 | } 36 | } 37 | catch (e) { 38 | return false 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ip-range-check", 3 | "version": "0.2.0", 4 | "description": "Check whether an IP(v4 or v6) is in an CIDR range", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "./node_modules/mocha/bin/mocha" 8 | }, 9 | "types": "index.d.ts", 10 | "files": [ 11 | "index.js", 12 | "index.d.ts" 13 | ], 14 | "repository": { 15 | "type": "git", 16 | "url": "git+https://github.com/danielcompton/ip-range-check.git" 17 | }, 18 | "keywords": [ 19 | "ip", 20 | "ipv6", 21 | "IP", 22 | "Address", 23 | "CIDR", 24 | "range" 25 | ], 26 | "author": "Daniel Compton (http://danielcompton.net)", 27 | "license": "MIT", 28 | "bugs": { 29 | "url": "https://github.com/danielcompton/ip-range-check/issues" 30 | }, 31 | "homepage": "https://github.com/danielcompton/ip-range-check#readme", 32 | "dependencies": { 33 | "ipaddr.js": "^1.0.1" 34 | }, 35 | "devDependencies": { 36 | "mocha": "^2.2.5" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /test/test.js: -------------------------------------------------------------------------------- 1 | var assert = require("assert"); 2 | var ipRangeCheck = require("../index"); 3 | 4 | 5 | describe("IP Range check", function () { 6 | describe("for IPv6", function () { 7 | it("should fail when the IP is not in the range", function () { 8 | assert.equal(false, ipRangeCheck("::1", "::2/128")); 9 | assert.equal(false, ipRangeCheck("::1", ["::2", "::3/128"])); 10 | }); 11 | 12 | it("should succeed when the IP is in the range", function () { 13 | assert.equal(true, ipRangeCheck("::1", "::1")); 14 | assert.equal(true, ipRangeCheck("::1", ["::1"])); 15 | assert.equal(true, ipRangeCheck("2001:cdba::3257:9652", "2001:cdba::3257:9652/128")) 16 | }); 17 | 18 | it("an array of the same CIDRs should be the same as one CIDR string", function () { 19 | assert.equal(ipRangeCheck("::1", "::1"), ipRangeCheck("::1", ["::1", "::1", "::1"])); 20 | }); 21 | 22 | it("should handle IPv6 synonyms", function () { 23 | assert.equal(true, ipRangeCheck("2001:cdba:0000:0000:0000:0000:3257:9652", "2001:cdba:0:0:0:0:3257:9652")); 24 | assert.equal(true, ipRangeCheck("2001:cdba:0000:0000:0000:0000:3257:9652", "2001:cdba::3257:9652")); 25 | assert.equal(true, ipRangeCheck("2001:cdba:0:0:0:0:3257:9652", "2001:cdba:0000:0000:0000:0000:3257:9652/128")); 26 | }) 27 | }); 28 | 29 | describe("for Ipv4", function () { 30 | it("should fail when the IP is not in the range", function () { 31 | assert.equal(false, ipRangeCheck("102.1.5.0", "102.1.5.1")) 32 | }); 33 | 34 | it("should succeed when the IP is in the range", function () { 35 | assert.equal(true, ipRangeCheck("102.1.5.0", "102.1.5.0")); 36 | assert.equal(true, ipRangeCheck("102.1.5.92", "102.1.5.0/24")); 37 | assert.equal(true, ipRangeCheck("192.168.1.1", ["102.1.5.0/24", "192.168.1.0/24"])); 38 | for (var i = 0; i <= 255; i++) { 39 | assert.equal(true, ipRangeCheck("102.1.5." + i, "102.1.5.0/24")) 40 | } 41 | }); 42 | 43 | describe("transmitted over IPv6", function(){ 44 | it("should match IPv4 CIDR", function () { 45 | assert.equal(true, ipRangeCheck("0:0:0:0:0:FFFF:222.1.41.90", "222.1.41.90")); 46 | assert.equal(true, ipRangeCheck("0:0:0:0:0:FFFF:222.1.41.90", "222.1.41.0/24")); 47 | }) 48 | }); 49 | }); 50 | 51 | describe("for mixed types", function () { 52 | it("should fail when comparing IPv6 with IPv4", function () { 53 | assert.equal(false, ipRangeCheck("::5", "102.1.1.2")); 54 | assert.equal(false, ipRangeCheck("::1", "0.0.0.1")); 55 | assert.equal(false, ipRangeCheck("195.58.1.62", "::1/128")) 56 | }) 57 | }) 58 | }); 59 | --------------------------------------------------------------------------------