From ce494339ef6540a55360b224ce7a5120967712f6 Mon Sep 17 00:00:00 2001 From: Klaxon Date: Tue, 28 Aug 2018 15:35:54 +1000 Subject: [PATCH] add parse IPv6 list --- src/core/lib/IP.mjs | 69 +++++++++++++++++++++++++++- src/core/operations/ParseIPRange.mjs | 9 ++-- 2 files changed, 73 insertions(+), 5 deletions(-) diff --git a/src/core/lib/IP.mjs b/src/core/lib/IP.mjs index 472759fa..bd1baa68 100644 --- a/src/core/lib/IP.mjs +++ b/src/core/lib/IP.mjs @@ -162,8 +162,8 @@ Total addresses in range: ${(((ip2 - ip1) >>> 0) + 1)} * @returns {string} */ export function ipv6HyphenatedRange(range, includeNetworkInfo) { - const ip1 = strToIpv6(range[1]), - ip2 = strToIpv6(range[14]), + const ip1 = strToIpv6(range[0].split("-")[0].trim()), + ip2 = strToIpv6(range[0].split("-")[1].trim()), total = new Array(128).fill(); let output = "", @@ -224,6 +224,51 @@ export function ipv4ListedRange(match, includeNetworkInfo, enumerateAddresses, a return ipv4HyphenatedRange(range, includeNetworkInfo, enumerateAddresses, allowLargeList); } +/** + * Parses a list of IPv6 addresses separated by a new line (\n) and displays information + * about it. + * + * @param {RegExp} list + * @param {boolean} includeNetworkInfo + * @returns {string} + */ +export function ipv6ListedRange(match, includeNetworkInfo) { + + var ipv6List = match[0].split("\n"); + ipv6List = ipv6List.filter(function(str) {return str.trim();}); + for (let i =0; i < ipv6List.length; i++){ + ipv6List[i] = ipv6List[i].trim(); + } + var ipv6CidrList = ipv6List.filter( function(a) { return a.includes("/")}); + + for (let i = 0; i < ipv6CidrList.length; i++) { + + let network = strToIpv6(ipv6CidrList[i].split("/")[0]); + let cidrRange = parseInt(ipv6CidrList[i].split("/")[1]); + + if (cidrRange < 0 || cidrRange > 127) { + return "IPv6 CIDR must be less than 128"; + } + + let cidrIp1 = new Array(8), + cidrIp2 = new Array(8); + + let mask = genIpv6Mask(cidrRange); + + for (let j = 0; j < 8; j++) { + cidrIp1[j] = network[j] & mask[j]; + cidrIp2[j] = cidrIp1[j] | (~mask[j] & 0x0000FFFF); + } + ipv6List.splice(ipv6List.indexOf(ipv6CidrList[i]),1); + ipv6List.push(ipv6ToStr(cidrIp1), ipv6ToStr(cidrIp2)); + } + ipv6List = ipv6List.sort(ipv6Compare); + let ip1 = ipv6List[0]; + let ip2 = ipv6List[ipv6List.length - 1]; + let range = [ip1 + " - " + ip2] + return ipv6HyphenatedRange(range, includeNetworkInfo); +} + /** * Converts an IPv4 address from string format to numerical format. * @@ -438,6 +483,26 @@ export function ipv4Compare(a, b) { return strToIpv4(a) - strToIpv4(b); } +/** + * Comparison operation for sorting of IPv6 addresses. + * + * @param {string} a + * @param {string} b + * @returns {number} + */ +export function ipv6Compare(a, b) { + + let a_ = strToIpv6(a), + b_ = strToIpv6(b); + + for (let i = 0; i < a_.length; i++){ + if (a_[i] != b_[i]){ + return a_[i] - b_[i]; + } + } + return 0; +} + const _LARGE_RANGE_ERROR = "The specified range contains more than 65,536 addresses. Running this query could crash your browser. If you want to run it, select the \"Allow large queries\" option. You are advised to turn off \"Auto Bake\" whilst editing large ranges."; /** diff --git a/src/core/operations/ParseIPRange.mjs b/src/core/operations/ParseIPRange.mjs index 93aff3ce..3a3bb1e6 100644 --- a/src/core/operations/ParseIPRange.mjs +++ b/src/core/operations/ParseIPRange.mjs @@ -6,7 +6,7 @@ import Operation from "../Operation"; import OperationError from "../errors/OperationError"; -import {ipv4CidrRange, ipv4HyphenatedRange, ipv4ListedRange, ipv6CidrRange, ipv6HyphenatedRange} from "../lib/IP"; +import {ipv4CidrRange, ipv4HyphenatedRange, ipv4ListedRange, ipv6CidrRange, ipv6HyphenatedRange, ipv6ListedRange} from "../lib/IP"; /** * Parse IP range operation @@ -21,7 +21,7 @@ class ParseIPRange extends Operation { this.name = "Parse IP range"; this.module = "JSBN"; - this.description = "Given a CIDR range (e.g. 10.0.0.0/24), hyphenated range (e.g. 10.0.0.0 - 10.0.1.0), or a list of IPs, (this operation provides network information and enumerates all IP addresses in the range.

IPv6 is supported but will not be enumerated"; + this.description = "Given a CIDR range (e.g. 10.0.0.0/24), hyphenated range (e.g. 10.0.0.0 - 10.0.1.0), or a list of IPs and CIDR ranges (new line separated), (this operation provides network information and enumerates all IP addresses in the range.

IPv6 is supported but will not be enumerated"; this.infoURL = "https://wikipedia.org/wiki/Subnetwork"; this.inputType = "string"; this.outputType = "string"; @@ -61,7 +61,8 @@ class ParseIPRange extends Operation { ipv4RangeRegex = /^\s*((?:\d{1,3}\.){3}\d{1,3})\s*-\s*((?:\d{1,3}\.){3}\d{1,3})\s*$/, ipv4ListRegex = /^\s*(((?:\d{1,3}\.){3}\d{1,3})(\/(\d\d?))?(\n|$)(\n*))*$/, ipv6CidrRegex = /^\s*(((?=.*::)(?!.*::.+::)(::)?([\dA-F]{1,4}:(:|\b)|){5}|([\dA-F]{1,4}:){6})((([\dA-F]{1,4}((?!\4)::|:\b|(?![\dA-F])))|(?!\3\4)){2}|(((2[0-4]|1\d|[1-9])?\d|25[0-5])\.?\b){4}))\/(\d\d?\d?)\s*$/i, - ipv6RangeRegex = /^\s*(((?=.*::)(?!.*::[^-]+::)(::)?([\dA-F]{1,4}:(:|\b)|){5}|([\dA-F]{1,4}:){6})((([\dA-F]{1,4}((?!\4)::|:\b|(?![\dA-F])))|(?!\3\4)){2}|(((2[0-4]|1\d|[1-9])?\d|25[0-5])\.?\b){4}))\s*-\s*(((?=.*::)(?!.*::.+::)(::)?([\dA-F]{1,4}:(:|\b)|){5}|([\dA-F]{1,4}:){6})((([\dA-F]{1,4}((?!\17)::|:\b|(?![\dA-F])))|(?!\16\17)){2}|(((2[0-4]|1\d|[1-9])?\d|25[0-5])\.?\b){4}))\s*$/i; + ipv6RangeRegex = /^\s*(((?=.*::)(?!.*::[^-]+::)(::)?([\dA-F]{1,4}:(:|\b)|){5}|([\dA-F]{1,4}:){6})((([\dA-F]{1,4}((?!\4)::|:\b|(?![\dA-F])))|(?!\3\4)){2}|(((2[0-4]|1\d|[1-9])?\d|25[0-5])\.?\b){4}))\s*-\s*(((?=.*::)(?!.*::.+::)(::)?([\dA-F]{1,4}:(:|\b)|){5}|([\dA-F]{1,4}:){6})((([\dA-F]{1,4}((?!\17)::|:\b|(?![\dA-F])))|(?!\16\17)){2}|(((2[0-4]|1\d|[1-9])?\d|25[0-5])\.?\b){4}))\s*$/i, + ipv6ListRegex = /^((((?=.*::)(?!.*::.+::)(::)?([\dA-F]{1,4}:(:|\b)|){5}|([\dA-F]{1,4}:){6})((([\dA-F]{1,4}((?!\4)::|:\b|(?![\dA-F])))|(?!\3\4)){2}|(((2[0-4]|1\d|[1-9])?\d|25[0-5])\.?\b){4}))(\/(\d\d?\d?))?(\n|$)(\n*))*$/ig; let match; if ((match = ipv4CidrRegex.exec(input))) { @@ -74,6 +75,8 @@ class ParseIPRange extends Operation { return ipv6CidrRange(match, includeNetworkInfo); } else if ((match = ipv6RangeRegex.exec(input))) { return ipv6HyphenatedRange(match, includeNetworkInfo); + } else if ((match = ipv6ListRegex.exec(input))) { + return ipv6ListedRange(match, includeNetworkInfo); } else { throw new OperationError("Invalid input.\n\nEnter either a CIDR range (e.g. 10.0.0.0/24) or a hyphenated range (e.g. 10.0.0.0 - 10.0.1.0). IPv6 also supported."); }