views:

197

answers:

2

I have a simple node.js program running on my machine and I want to get local IP address of PC on which is my program running. How do I get it with node.js?

+4  A: 

Your local IP is always 127.0.0.1.

Then there is the network IP, which you can get from ifconfig (*nix) or ipconfig (win). This is only useful within the local network.

Then there is your external/public IP, which you can only get if you can somehow ask the router for it, or you can setup an external service which returns the client IP address whenever it gets a request. There are also other such services in existence, like whatismyip.com.

In some cases (for instance if you have a WAN connection) the network IP and the public IP are the same, and can both be used externally to reach your computer.

If your network and public IPs are different, you may need to have your network router forward all incoming connections to your network ip.

Tor Valamo
Does that mean that to get the network address in nodejs you need to make a system call to `ifconfig` or `ipconfig` and parse the response string?
Pumbaa80
@Pumbaa80 - Pretty much, unless your network card has some drivers you can call. Also if you have several network cards (or adapters, like hamachi), there is no way you can just call a function of sorts and get one IP which is _THE_ IP. So parsing it and interpreting the output of of `ifconfig` is pretty much the only way.
Tor Valamo
+1  A: 

Here is a snippet of node.js code that will parse the output of ifconfig and (asynchronously) return the first IP address found:

(tested on MacOS Snow Leopard only; hope it works on linux too)

var getNetworkIP = (function () {
    var ignoreRE = /^(127\.0\.0\.1|::1|fe80(:1)?::1(%.*)?)$/i;

    var exec = require('child_process').exec;
    var cached;    
    var command;
    var filterRE;

    switch (process.platform) {
    // TODO: implement for OSs without ifconfig command
    case 'darwin':
         command = 'ifconfig';
         filterRE = /\binet\s+([^\s]+)/g;
         // filterRE = /\binet6\s+([^\s]+)/g; // IPv6
         break;
    default:
         command = 'ifconfig';
         filterRE = /\binet\b[^:]+:\s*([^\s]+)/g;
         // filterRE = /\binet6[^:]+:\s*([^\s]+)/g; // IPv6
         break;
    }

    return function (callback, bypassCache) {
         // get cached value
        if (cached && !bypassCache) {
            callback(null, cached);
            return;
        }
        // system call
        exec(command, function (error, stdout, sterr) {
            var ips = [];
            // extract IPs
            var matches = stdout.match(filterRE);
            // JS has no lookbehind REs, so we need a trick
            for (var i = 0; i < matches.length; i++) {
                ips.push(matches[i].replace(filterRE, '$1'));
            }

            // filter BS
            for (var i = 0, l = ips.length; i < l; i++) {
                if (!ignoreRE.test(ips[i])) {
                    //if (!error) {
                        cached = ips[i];
                    //}
                    callback(error, ips[i]);
                    return;
                }
            }
            // nothing found
            callback(error, null);
        });
    };
})();

Usage example:

getNetworkIP(function (error, ip) {
    console.log(ip);
    if (error) {
        console.log('error:', error);
    }
}, false);

If the second parameter is true, the function will exec a system call every time; otherwise the cached value is used.

Pumbaa80