twitst4tz

twitter statistics web application
Log | Files | Refs | README | LICENSE

ipaddr.js (19333B)


      1 (function() {
      2   var expandIPv6, ipaddr, ipv4Part, ipv4Regexes, ipv6Part, ipv6Regexes, matchCIDR, root, zoneIndex;
      3 
      4   ipaddr = {};
      5 
      6   root = this;
      7 
      8   if ((typeof module !== "undefined" && module !== null) && module.exports) {
      9     module.exports = ipaddr;
     10   } else {
     11     root['ipaddr'] = ipaddr;
     12   }
     13 
     14   matchCIDR = function(first, second, partSize, cidrBits) {
     15     var part, shift;
     16     if (first.length !== second.length) {
     17       throw new Error("ipaddr: cannot match CIDR for objects with different lengths");
     18     }
     19     part = 0;
     20     while (cidrBits > 0) {
     21       shift = partSize - cidrBits;
     22       if (shift < 0) {
     23         shift = 0;
     24       }
     25       if (first[part] >> shift !== second[part] >> shift) {
     26         return false;
     27       }
     28       cidrBits -= partSize;
     29       part += 1;
     30     }
     31     return true;
     32   };
     33 
     34   ipaddr.subnetMatch = function(address, rangeList, defaultName) {
     35     var k, len, rangeName, rangeSubnets, subnet;
     36     if (defaultName == null) {
     37       defaultName = 'unicast';
     38     }
     39     for (rangeName in rangeList) {
     40       rangeSubnets = rangeList[rangeName];
     41       if (rangeSubnets[0] && !(rangeSubnets[0] instanceof Array)) {
     42         rangeSubnets = [rangeSubnets];
     43       }
     44       for (k = 0, len = rangeSubnets.length; k < len; k++) {
     45         subnet = rangeSubnets[k];
     46         if (address.kind() === subnet[0].kind()) {
     47           if (address.match.apply(address, subnet)) {
     48             return rangeName;
     49           }
     50         }
     51       }
     52     }
     53     return defaultName;
     54   };
     55 
     56   ipaddr.IPv4 = (function() {
     57     function IPv4(octets) {
     58       var k, len, octet;
     59       if (octets.length !== 4) {
     60         throw new Error("ipaddr: ipv4 octet count should be 4");
     61       }
     62       for (k = 0, len = octets.length; k < len; k++) {
     63         octet = octets[k];
     64         if (!((0 <= octet && octet <= 255))) {
     65           throw new Error("ipaddr: ipv4 octet should fit in 8 bits");
     66         }
     67       }
     68       this.octets = octets;
     69     }
     70 
     71     IPv4.prototype.kind = function() {
     72       return 'ipv4';
     73     };
     74 
     75     IPv4.prototype.toString = function() {
     76       return this.octets.join(".");
     77     };
     78 
     79     IPv4.prototype.toNormalizedString = function() {
     80       return this.toString();
     81     };
     82 
     83     IPv4.prototype.toByteArray = function() {
     84       return this.octets.slice(0);
     85     };
     86 
     87     IPv4.prototype.match = function(other, cidrRange) {
     88       var ref;
     89       if (cidrRange === void 0) {
     90         ref = other, other = ref[0], cidrRange = ref[1];
     91       }
     92       if (other.kind() !== 'ipv4') {
     93         throw new Error("ipaddr: cannot match ipv4 address with non-ipv4 one");
     94       }
     95       return matchCIDR(this.octets, other.octets, 8, cidrRange);
     96     };
     97 
     98     IPv4.prototype.SpecialRanges = {
     99       unspecified: [[new IPv4([0, 0, 0, 0]), 8]],
    100       broadcast: [[new IPv4([255, 255, 255, 255]), 32]],
    101       multicast: [[new IPv4([224, 0, 0, 0]), 4]],
    102       linkLocal: [[new IPv4([169, 254, 0, 0]), 16]],
    103       loopback: [[new IPv4([127, 0, 0, 0]), 8]],
    104       carrierGradeNat: [[new IPv4([100, 64, 0, 0]), 10]],
    105       "private": [[new IPv4([10, 0, 0, 0]), 8], [new IPv4([172, 16, 0, 0]), 12], [new IPv4([192, 168, 0, 0]), 16]],
    106       reserved: [[new IPv4([192, 0, 0, 0]), 24], [new IPv4([192, 0, 2, 0]), 24], [new IPv4([192, 88, 99, 0]), 24], [new IPv4([198, 51, 100, 0]), 24], [new IPv4([203, 0, 113, 0]), 24], [new IPv4([240, 0, 0, 0]), 4]]
    107     };
    108 
    109     IPv4.prototype.range = function() {
    110       return ipaddr.subnetMatch(this, this.SpecialRanges);
    111     };
    112 
    113     IPv4.prototype.toIPv4MappedAddress = function() {
    114       return ipaddr.IPv6.parse("::ffff:" + (this.toString()));
    115     };
    116 
    117     IPv4.prototype.prefixLengthFromSubnetMask = function() {
    118       var cidr, i, k, octet, stop, zeros, zerotable;
    119       zerotable = {
    120         0: 8,
    121         128: 7,
    122         192: 6,
    123         224: 5,
    124         240: 4,
    125         248: 3,
    126         252: 2,
    127         254: 1,
    128         255: 0
    129       };
    130       cidr = 0;
    131       stop = false;
    132       for (i = k = 3; k >= 0; i = k += -1) {
    133         octet = this.octets[i];
    134         if (octet in zerotable) {
    135           zeros = zerotable[octet];
    136           if (stop && zeros !== 0) {
    137             return null;
    138           }
    139           if (zeros !== 8) {
    140             stop = true;
    141           }
    142           cidr += zeros;
    143         } else {
    144           return null;
    145         }
    146       }
    147       return 32 - cidr;
    148     };
    149 
    150     return IPv4;
    151 
    152   })();
    153 
    154   ipv4Part = "(0?\\d+|0x[a-f0-9]+)";
    155 
    156   ipv4Regexes = {
    157     fourOctet: new RegExp("^" + ipv4Part + "\\." + ipv4Part + "\\." + ipv4Part + "\\." + ipv4Part + "$", 'i'),
    158     longValue: new RegExp("^" + ipv4Part + "$", 'i')
    159   };
    160 
    161   ipaddr.IPv4.parser = function(string) {
    162     var match, parseIntAuto, part, shift, value;
    163     parseIntAuto = function(string) {
    164       if (string[0] === "0" && string[1] !== "x") {
    165         return parseInt(string, 8);
    166       } else {
    167         return parseInt(string);
    168       }
    169     };
    170     if (match = string.match(ipv4Regexes.fourOctet)) {
    171       return (function() {
    172         var k, len, ref, results;
    173         ref = match.slice(1, 6);
    174         results = [];
    175         for (k = 0, len = ref.length; k < len; k++) {
    176           part = ref[k];
    177           results.push(parseIntAuto(part));
    178         }
    179         return results;
    180       })();
    181     } else if (match = string.match(ipv4Regexes.longValue)) {
    182       value = parseIntAuto(match[1]);
    183       if (value > 0xffffffff || value < 0) {
    184         throw new Error("ipaddr: address outside defined range");
    185       }
    186       return ((function() {
    187         var k, results;
    188         results = [];
    189         for (shift = k = 0; k <= 24; shift = k += 8) {
    190           results.push((value >> shift) & 0xff);
    191         }
    192         return results;
    193       })()).reverse();
    194     } else {
    195       return null;
    196     }
    197   };
    198 
    199   ipaddr.IPv6 = (function() {
    200     function IPv6(parts, zoneId) {
    201       var i, k, l, len, part, ref;
    202       if (parts.length === 16) {
    203         this.parts = [];
    204         for (i = k = 0; k <= 14; i = k += 2) {
    205           this.parts.push((parts[i] << 8) | parts[i + 1]);
    206         }
    207       } else if (parts.length === 8) {
    208         this.parts = parts;
    209       } else {
    210         throw new Error("ipaddr: ipv6 part count should be 8 or 16");
    211       }
    212       ref = this.parts;
    213       for (l = 0, len = ref.length; l < len; l++) {
    214         part = ref[l];
    215         if (!((0 <= part && part <= 0xffff))) {
    216           throw new Error("ipaddr: ipv6 part should fit in 16 bits");
    217         }
    218       }
    219       if (zoneId) {
    220         this.zoneId = zoneId;
    221       }
    222     }
    223 
    224     IPv6.prototype.kind = function() {
    225       return 'ipv6';
    226     };
    227 
    228     IPv6.prototype.toString = function() {
    229       return this.toNormalizedString().replace(/((^|:)(0(:|$))+)/, '::');
    230     };
    231 
    232     IPv6.prototype.toRFC5952String = function() {
    233       var bestMatchIndex, bestMatchLength, match, regex, string;
    234       regex = /((^|:)(0(:|$)){2,})/g;
    235       string = this.toNormalizedString();
    236       bestMatchIndex = 0;
    237       bestMatchLength = -1;
    238       while ((match = regex.exec(string))) {
    239         if (match[0].length > bestMatchLength) {
    240           bestMatchIndex = match.index;
    241           bestMatchLength = match[0].length;
    242         }
    243       }
    244       if (bestMatchLength < 0) {
    245         return string;
    246       }
    247       return string.substring(0, bestMatchIndex) + '::' + string.substring(bestMatchIndex + bestMatchLength);
    248     };
    249 
    250     IPv6.prototype.toByteArray = function() {
    251       var bytes, k, len, part, ref;
    252       bytes = [];
    253       ref = this.parts;
    254       for (k = 0, len = ref.length; k < len; k++) {
    255         part = ref[k];
    256         bytes.push(part >> 8);
    257         bytes.push(part & 0xff);
    258       }
    259       return bytes;
    260     };
    261 
    262     IPv6.prototype.toNormalizedString = function() {
    263       var addr, part, suffix;
    264       addr = ((function() {
    265         var k, len, ref, results;
    266         ref = this.parts;
    267         results = [];
    268         for (k = 0, len = ref.length; k < len; k++) {
    269           part = ref[k];
    270           results.push(part.toString(16));
    271         }
    272         return results;
    273       }).call(this)).join(":");
    274       suffix = '';
    275       if (this.zoneId) {
    276         suffix = '%' + this.zoneId;
    277       }
    278       return addr + suffix;
    279     };
    280 
    281     IPv6.prototype.toFixedLengthString = function() {
    282       var addr, part, suffix;
    283       addr = ((function() {
    284         var k, len, ref, results;
    285         ref = this.parts;
    286         results = [];
    287         for (k = 0, len = ref.length; k < len; k++) {
    288           part = ref[k];
    289           results.push(part.toString(16).padStart(4, '0'));
    290         }
    291         return results;
    292       }).call(this)).join(":");
    293       suffix = '';
    294       if (this.zoneId) {
    295         suffix = '%' + this.zoneId;
    296       }
    297       return addr + suffix;
    298     };
    299 
    300     IPv6.prototype.match = function(other, cidrRange) {
    301       var ref;
    302       if (cidrRange === void 0) {
    303         ref = other, other = ref[0], cidrRange = ref[1];
    304       }
    305       if (other.kind() !== 'ipv6') {
    306         throw new Error("ipaddr: cannot match ipv6 address with non-ipv6 one");
    307       }
    308       return matchCIDR(this.parts, other.parts, 16, cidrRange);
    309     };
    310 
    311     IPv6.prototype.SpecialRanges = {
    312       unspecified: [new IPv6([0, 0, 0, 0, 0, 0, 0, 0]), 128],
    313       linkLocal: [new IPv6([0xfe80, 0, 0, 0, 0, 0, 0, 0]), 10],
    314       multicast: [new IPv6([0xff00, 0, 0, 0, 0, 0, 0, 0]), 8],
    315       loopback: [new IPv6([0, 0, 0, 0, 0, 0, 0, 1]), 128],
    316       uniqueLocal: [new IPv6([0xfc00, 0, 0, 0, 0, 0, 0, 0]), 7],
    317       ipv4Mapped: [new IPv6([0, 0, 0, 0, 0, 0xffff, 0, 0]), 96],
    318       rfc6145: [new IPv6([0, 0, 0, 0, 0xffff, 0, 0, 0]), 96],
    319       rfc6052: [new IPv6([0x64, 0xff9b, 0, 0, 0, 0, 0, 0]), 96],
    320       '6to4': [new IPv6([0x2002, 0, 0, 0, 0, 0, 0, 0]), 16],
    321       teredo: [new IPv6([0x2001, 0, 0, 0, 0, 0, 0, 0]), 32],
    322       reserved: [[new IPv6([0x2001, 0xdb8, 0, 0, 0, 0, 0, 0]), 32]]
    323     };
    324 
    325     IPv6.prototype.range = function() {
    326       return ipaddr.subnetMatch(this, this.SpecialRanges);
    327     };
    328 
    329     IPv6.prototype.isIPv4MappedAddress = function() {
    330       return this.range() === 'ipv4Mapped';
    331     };
    332 
    333     IPv6.prototype.toIPv4Address = function() {
    334       var high, low, ref;
    335       if (!this.isIPv4MappedAddress()) {
    336         throw new Error("ipaddr: trying to convert a generic ipv6 address to ipv4");
    337       }
    338       ref = this.parts.slice(-2), high = ref[0], low = ref[1];
    339       return new ipaddr.IPv4([high >> 8, high & 0xff, low >> 8, low & 0xff]);
    340     };
    341 
    342     IPv6.prototype.prefixLengthFromSubnetMask = function() {
    343       var cidr, i, k, part, stop, zeros, zerotable;
    344       zerotable = {
    345         0: 16,
    346         32768: 15,
    347         49152: 14,
    348         57344: 13,
    349         61440: 12,
    350         63488: 11,
    351         64512: 10,
    352         65024: 9,
    353         65280: 8,
    354         65408: 7,
    355         65472: 6,
    356         65504: 5,
    357         65520: 4,
    358         65528: 3,
    359         65532: 2,
    360         65534: 1,
    361         65535: 0
    362       };
    363       cidr = 0;
    364       stop = false;
    365       for (i = k = 7; k >= 0; i = k += -1) {
    366         part = this.parts[i];
    367         if (part in zerotable) {
    368           zeros = zerotable[part];
    369           if (stop && zeros !== 0) {
    370             return null;
    371           }
    372           if (zeros !== 16) {
    373             stop = true;
    374           }
    375           cidr += zeros;
    376         } else {
    377           return null;
    378         }
    379       }
    380       return 128 - cidr;
    381     };
    382 
    383     return IPv6;
    384 
    385   })();
    386 
    387   ipv6Part = "(?:[0-9a-f]+::?)+";
    388 
    389   zoneIndex = "%[0-9a-z]{1,}";
    390 
    391   ipv6Regexes = {
    392     zoneIndex: new RegExp(zoneIndex, 'i'),
    393     "native": new RegExp("^(::)?(" + ipv6Part + ")?([0-9a-f]+)?(::)?(" + zoneIndex + ")?$", 'i'),
    394     transitional: new RegExp(("^((?:" + ipv6Part + ")|(?:::)(?:" + ipv6Part + ")?)") + (ipv4Part + "\\." + ipv4Part + "\\." + ipv4Part + "\\." + ipv4Part) + ("(" + zoneIndex + ")?$"), 'i')
    395   };
    396 
    397   expandIPv6 = function(string, parts) {
    398     var colonCount, lastColon, part, replacement, replacementCount, zoneId;
    399     if (string.indexOf('::') !== string.lastIndexOf('::')) {
    400       return null;
    401     }
    402     zoneId = (string.match(ipv6Regexes['zoneIndex']) || [])[0];
    403     if (zoneId) {
    404       zoneId = zoneId.substring(1);
    405       string = string.replace(/%.+$/, '');
    406     }
    407     colonCount = 0;
    408     lastColon = -1;
    409     while ((lastColon = string.indexOf(':', lastColon + 1)) >= 0) {
    410       colonCount++;
    411     }
    412     if (string.substr(0, 2) === '::') {
    413       colonCount--;
    414     }
    415     if (string.substr(-2, 2) === '::') {
    416       colonCount--;
    417     }
    418     if (colonCount > parts) {
    419       return null;
    420     }
    421     replacementCount = parts - colonCount;
    422     replacement = ':';
    423     while (replacementCount--) {
    424       replacement += '0:';
    425     }
    426     string = string.replace('::', replacement);
    427     if (string[0] === ':') {
    428       string = string.slice(1);
    429     }
    430     if (string[string.length - 1] === ':') {
    431       string = string.slice(0, -1);
    432     }
    433     parts = (function() {
    434       var k, len, ref, results;
    435       ref = string.split(":");
    436       results = [];
    437       for (k = 0, len = ref.length; k < len; k++) {
    438         part = ref[k];
    439         results.push(parseInt(part, 16));
    440       }
    441       return results;
    442     })();
    443     return {
    444       parts: parts,
    445       zoneId: zoneId
    446     };
    447   };
    448 
    449   ipaddr.IPv6.parser = function(string) {
    450     var addr, k, len, match, octet, octets, zoneId;
    451     if (ipv6Regexes['native'].test(string)) {
    452       return expandIPv6(string, 8);
    453     } else if (match = string.match(ipv6Regexes['transitional'])) {
    454       zoneId = match[6] || '';
    455       addr = expandIPv6(match[1].slice(0, -1) + zoneId, 6);
    456       if (addr.parts) {
    457         octets = [parseInt(match[2]), parseInt(match[3]), parseInt(match[4]), parseInt(match[5])];
    458         for (k = 0, len = octets.length; k < len; k++) {
    459           octet = octets[k];
    460           if (!((0 <= octet && octet <= 255))) {
    461             return null;
    462           }
    463         }
    464         addr.parts.push(octets[0] << 8 | octets[1]);
    465         addr.parts.push(octets[2] << 8 | octets[3]);
    466         return {
    467           parts: addr.parts,
    468           zoneId: addr.zoneId
    469         };
    470       }
    471     }
    472     return null;
    473   };
    474 
    475   ipaddr.IPv4.isIPv4 = ipaddr.IPv6.isIPv6 = function(string) {
    476     return this.parser(string) !== null;
    477   };
    478 
    479   ipaddr.IPv4.isValid = function(string) {
    480     var e;
    481     try {
    482       new this(this.parser(string));
    483       return true;
    484     } catch (error1) {
    485       e = error1;
    486       return false;
    487     }
    488   };
    489 
    490   ipaddr.IPv4.isValidFourPartDecimal = function(string) {
    491     if (ipaddr.IPv4.isValid(string) && string.match(/^(0|[1-9]\d*)(\.(0|[1-9]\d*)){3}$/)) {
    492       return true;
    493     } else {
    494       return false;
    495     }
    496   };
    497 
    498   ipaddr.IPv6.isValid = function(string) {
    499     var addr, e;
    500     if (typeof string === "string" && string.indexOf(":") === -1) {
    501       return false;
    502     }
    503     try {
    504       addr = this.parser(string);
    505       new this(addr.parts, addr.zoneId);
    506       return true;
    507     } catch (error1) {
    508       e = error1;
    509       return false;
    510     }
    511   };
    512 
    513   ipaddr.IPv4.parse = function(string) {
    514     var parts;
    515     parts = this.parser(string);
    516     if (parts === null) {
    517       throw new Error("ipaddr: string is not formatted like ip address");
    518     }
    519     return new this(parts);
    520   };
    521 
    522   ipaddr.IPv6.parse = function(string) {
    523     var addr;
    524     addr = this.parser(string);
    525     if (addr.parts === null) {
    526       throw new Error("ipaddr: string is not formatted like ip address");
    527     }
    528     return new this(addr.parts, addr.zoneId);
    529   };
    530 
    531   ipaddr.IPv4.parseCIDR = function(string) {
    532     var maskLength, match, parsed;
    533     if (match = string.match(/^(.+)\/(\d+)$/)) {
    534       maskLength = parseInt(match[2]);
    535       if (maskLength >= 0 && maskLength <= 32) {
    536         parsed = [this.parse(match[1]), maskLength];
    537         Object.defineProperty(parsed, 'toString', {
    538           value: function() {
    539             return this.join('/');
    540           }
    541         });
    542         return parsed;
    543       }
    544     }
    545     throw new Error("ipaddr: string is not formatted like an IPv4 CIDR range");
    546   };
    547 
    548   ipaddr.IPv4.subnetMaskFromPrefixLength = function(prefix) {
    549     var filledOctetCount, j, octets;
    550     prefix = parseInt(prefix);
    551     if (prefix < 0 || prefix > 32) {
    552       throw new Error('ipaddr: invalid IPv4 prefix length');
    553     }
    554     octets = [0, 0, 0, 0];
    555     j = 0;
    556     filledOctetCount = Math.floor(prefix / 8);
    557     while (j < filledOctetCount) {
    558       octets[j] = 255;
    559       j++;
    560     }
    561     if (filledOctetCount < 4) {
    562       octets[filledOctetCount] = Math.pow(2, prefix % 8) - 1 << 8 - (prefix % 8);
    563     }
    564     return new this(octets);
    565   };
    566 
    567   ipaddr.IPv4.broadcastAddressFromCIDR = function(string) {
    568     var cidr, error, i, ipInterfaceOctets, octets, subnetMaskOctets;
    569     try {
    570       cidr = this.parseCIDR(string);
    571       ipInterfaceOctets = cidr[0].toByteArray();
    572       subnetMaskOctets = this.subnetMaskFromPrefixLength(cidr[1]).toByteArray();
    573       octets = [];
    574       i = 0;
    575       while (i < 4) {
    576         octets.push(parseInt(ipInterfaceOctets[i], 10) | parseInt(subnetMaskOctets[i], 10) ^ 255);
    577         i++;
    578       }
    579       return new this(octets);
    580     } catch (error1) {
    581       error = error1;
    582       throw new Error('ipaddr: the address does not have IPv4 CIDR format');
    583     }
    584   };
    585 
    586   ipaddr.IPv4.networkAddressFromCIDR = function(string) {
    587     var cidr, error, i, ipInterfaceOctets, octets, subnetMaskOctets;
    588     try {
    589       cidr = this.parseCIDR(string);
    590       ipInterfaceOctets = cidr[0].toByteArray();
    591       subnetMaskOctets = this.subnetMaskFromPrefixLength(cidr[1]).toByteArray();
    592       octets = [];
    593       i = 0;
    594       while (i < 4) {
    595         octets.push(parseInt(ipInterfaceOctets[i], 10) & parseInt(subnetMaskOctets[i], 10));
    596         i++;
    597       }
    598       return new this(octets);
    599     } catch (error1) {
    600       error = error1;
    601       throw new Error('ipaddr: the address does not have IPv4 CIDR format');
    602     }
    603   };
    604 
    605   ipaddr.IPv6.parseCIDR = function(string) {
    606     var maskLength, match, parsed;
    607     if (match = string.match(/^(.+)\/(\d+)$/)) {
    608       maskLength = parseInt(match[2]);
    609       if (maskLength >= 0 && maskLength <= 128) {
    610         parsed = [this.parse(match[1]), maskLength];
    611         Object.defineProperty(parsed, 'toString', {
    612           value: function() {
    613             return this.join('/');
    614           }
    615         });
    616         return parsed;
    617       }
    618     }
    619     throw new Error("ipaddr: string is not formatted like an IPv6 CIDR range");
    620   };
    621 
    622   ipaddr.isValid = function(string) {
    623     return ipaddr.IPv6.isValid(string) || ipaddr.IPv4.isValid(string);
    624   };
    625 
    626   ipaddr.parse = function(string) {
    627     if (ipaddr.IPv6.isValid(string)) {
    628       return ipaddr.IPv6.parse(string);
    629     } else if (ipaddr.IPv4.isValid(string)) {
    630       return ipaddr.IPv4.parse(string);
    631     } else {
    632       throw new Error("ipaddr: the address has neither IPv6 nor IPv4 format");
    633     }
    634   };
    635 
    636   ipaddr.parseCIDR = function(string) {
    637     var e;
    638     try {
    639       return ipaddr.IPv6.parseCIDR(string);
    640     } catch (error1) {
    641       e = error1;
    642       try {
    643         return ipaddr.IPv4.parseCIDR(string);
    644       } catch (error1) {
    645         e = error1;
    646         throw new Error("ipaddr: the address has neither IPv6 nor IPv4 CIDR format");
    647       }
    648     }
    649   };
    650 
    651   ipaddr.fromByteArray = function(bytes) {
    652     var length;
    653     length = bytes.length;
    654     if (length === 4) {
    655       return new ipaddr.IPv4(bytes);
    656     } else if (length === 16) {
    657       return new ipaddr.IPv6(bytes);
    658     } else {
    659       throw new Error("ipaddr: the binary input is neither an IPv6 nor IPv4 address");
    660     }
    661   };
    662 
    663   ipaddr.process = function(string) {
    664     var addr;
    665     addr = this.parse(string);
    666     if (addr.kind() === 'ipv6' && addr.isIPv4MappedAddress()) {
    667       return addr.toIPv4Address();
    668     } else {
    669       return addr;
    670     }
    671   };
    672 
    673 }).call(this);