8

How do you check whether a given IP is internal or not using only javascript?

For example if you are given an IP of 192.168.1.1 the script should validate this and alert if this is an internal or external IP.

Tim
  • 4,414
  • 4
  • 35
  • 49
Sreehari
  • 515
  • 3
  • 11
  • 27
  • 3
    What definition of "internal" are you using? Do you mean the [private ranges](http://en.wikipedia.org/wiki/IP_address#IPv4_private_addresses)? If so, it's a trivial split-the-string and check the range. Do you only need to handle IPv4, or do you need to handle IPv6 as well? – T.J. Crowder Dec 20 '12 at 10:06

5 Answers5

19

If you mean private just make sure it's in one of the following ranges:

Private IP address ranges

The ranges and the amount of usable IP's are as follows:

10.0.0.0 - 10.255.255.255 Addresses: 16,777,216

172.16.0.0 - 172.31.255.255 Addresses: 1,048,576

192.168.0.0 - 192.168.255.255 Addresses: 65,536

Function like this should help:

function isPrivateIP(ip) {
   var parts = ip.split('.');
   return parts[0] === '10' || 
      (parts[0] === '172' && (parseInt(parts[1], 10) >= 16 && parseInt(parts[1], 10) <= 31)) || 
      (parts[0] === '192' && parts[1] === '168');
}
Ulflander
  • 648
  • 5
  • 15
Minko Gechev
  • 25,304
  • 9
  • 61
  • 68
11

You could use ipaddr.js library and check whether it returns "private":

const ipaddrJs = require('ipaddr.js');
ipaddrJs.parse('192.168.5.1').range()
> 'private'

https://github.com/whitequark/ipaddr.js/blob/master/lib/ipaddr.js

And if you use Node.js, take a look here: https://www.npmjs.com/package/ipaddr.js

Lukasz Czerwinski
  • 13,499
  • 10
  • 55
  • 65
  • 1
    I was searching and searching for something like this. I'm so glad you shared this answer. – Slbox Feb 21 '21 at 00:24
5

Internal IPs are the following:

10.0.0.0 - 10.255.255.255
172.16.0.0 - 172.31.255.255
192.168.0.0 - 192.168.255.255

Write the correct regexes for them.

/10\.\d+\.\d+\.\d+/
/192\.168\.\d+\.\d+/

I leave it to you to find out the correct regex for the 172.xxx range.

Florian Margaine
  • 58,730
  • 15
  • 91
  • 116
1

Try this one!

  var id = "10.10.10.10";
  if (/^(10)\.(.*)\.(.*)\.(.*)$/.test(id)){
    //10.x.x.x
  }else if (/^(172)\.(1[6-9]|2[0-9]|3[0-1])\.(.*)\.(.*)$/.test(id)){
    //172.16.x.x - 172.31.255.255
  }else if (/^(192)\.(168)\.(.*)\.(.*)$/.test(id)){
    //192.168.x.x
  }else {
    //else
  }
Laquio
  • 39
  • 3
0

To include IPv6 addresses and check any IP address with one function you could use the following:

    var net = require('net') // requires node.js
    ipIsPrivate(ip) {
        if (ip.substring(0,7) === "::ffff:")
            ip = ip.substring(7);

        if (net.isIPv4(ip)) {
            //         10.0.0.0 - 10.255.255.255        ||   172.16.0.0 - 172.31.255.255                          ||    192.168.0.0 - 192.168.255.255
            return  /^(10)\.(.*)\.(.*)\.(.*)$/.test(ip) || /^(172)\.(1[6-9]|2[0-9]|3[0-1])\.(.*)\.(.*)$/.test(ip) || /^(192)\.(168)\.(.*)\.(.*)$/.test(ip)
        }
        
        // else: ip is IPv6
        const firstWord = ip.split(":").find(el => !!el); //get first not empty word
            
        // The original IPv6 Site Local addresses (fec0::/10) are deprecated. Range: fec0 - feff
        if (/^fe[c-f][0-f]$/.test(firstWord))
            return true;

        // These days Unique Local Addresses (ULA) are used in place of Site Local.
        // Range: fc00 - fcff
        else if (/^fc[0-f]{2}$/.test(firstWord))
            return true;
            
        // Range: fd00 - fcff
        else if (/^fd[0-f]{2}$/.test(firstWord))
            return true;

        // Link local addresses (prefixed with fe80) are not routable
        else if (firstWord === "fe80")
            return true;
        
        // Discard Prefix
        else if (firstWord === "100")
            return true;
            
        // Any other IP address is not Unique Local Address (ULA)
        return false;
    }

If the check should include localhost (127.0.0.1, ::ffff:127.0.0.1 and ::1) use:

    var net = require('net') // requires node.js
    ipIsPrivateOrLocalhost(ip) {
        if (ip.substring(0,7) === "::ffff:")
            ip = ip.substring(7);

        if (net.isIPv4(ip)) {
            // check localhost
            if (ip === '127.0.0.1')
                return true;

            //         10.0.0.0 - 10.255.255.255        ||   172.16.0.0 - 172.31.255.255                          ||    192.168.0.0 - 192.168.255.255
            return  /^(10)\.(.*)\.(.*)\.(.*)$/.test(ip) || /^(172)\.(1[6-9]|2[0-9]|3[0-1])\.(.*)\.(.*)$/.test(ip) || /^(192)\.(168)\.(.*)\.(.*)$/.test(ip)
        }
        
        // else: ip is IPv6
        const firstWord = ip.split(":").find(el => !!el); //get first not empty word

        // equivalent of 127.0.0.1 in IPv6
        if (ip === "::1")
            return true;
            
        // The original IPv6 Site Local addresses (fec0::/10) are deprecated. Range: fec0 - feff
        else if (/^fe[c-f][0-f]$/.test(firstWord))
            return true;

        // These days Unique Local Addresses (ULA) are used in place of Site Local.
        // Range: fc00 - fcff
        else if (/^fc[0-f]{2}$/.test(firstWord))
            return true;
            
        // Range: fd00 - fcff
        else if (/^fd[0-f]{2}$/.test(firstWord))
            return true;

        // Link local addresses (prefixed with fe80) are not routable
        else if (firstWord === "fe80")
            return true;
        
        // Discard Prefix
        else if (firstWord === "100")
            return true;
            
        // Any other IP address is not Unique Local Address (ULA)
        return false;
    }

Builds upon Minko Gechev answer and this implementation to check for private IPv6 addresses in C#