address插件 - 获取ip, ipv6, mac(未完善)

186 阅读2分钟

github.com/node-module…

'use strict';

// 操作系统
var os = require('os');

// 文件系统
var fs = require('fs');

// 子进程
var child = require('child_process');

// 默认关键文件夹
var DEFAULT_RESOLV_FILE = '/etc/resolv.conf';

// 获取接口名称  linux默认为“eth”,MAC默认为“en”, window默认为null。
function getInterfaceName() {
  var val = 'eth'; // 默认为linux

  var platform = os.platform(); // 返回操作系统识别符
  
  if (platform === 'darwin') val = 'en'; // mac系统
  else if (platform === 'win32') val = null; // window系统

  return val;
}

function getIfconfigCMD() {
  // window
  if (os.platform() === 'win32') return 'ipconfig/all';

  // 其他
  return '/sbin/ifconfig';
}

/**
 * 获取全部地址
 *
 * @param {String} [interfaceName] 接口名称,linux默认为“eth”,MAC默认为“en”, window默认为null。
 * @param {Function(err, addr)} callback
 *  - {Object} addr {
 *    - {String} ip
 *    - {String} ipv6
 *    - {String} mac
 *  }
 */
function address(interfaceName, callback) {
  // interfaceName可以为回调函数,如果为函数就赋值给callback并且设置为null
  if (typeof interfaceName === 'function') {
    callback = interfaceName;
    interfaceName = null;
  }

  // 获取所有地址:IPv4, IPv6和MAC
  var addr = {
    ip: address.ip(interfaceName),
    ipv6: address.ipv6(interfaceName),
    mac: null
  };

  // 获取mac
  address.mac(interfaceName, function (err, mac) {
    if (mac) {
      addr.mac = mac;
    }

    // 回调输出参数
    callback(err, addr);
  });
}

// 获取网络地址匹配的第一个对象
address.interface = function (family, name) {
  // 包含有关每个网络接口的信息
  // address:一个字符串,用于指定分配的网络地址,即IPv4或IPv6 /
  // netmask:一个字符串,指定IPv4或IPv6网络掩码。
  // family:指定Family的字符串,值为IPv4或IPv6之一。
  // mac:一个字符串,指定网络接口的MAC地址。
  // internal:布尔值,如果接口为环回一则为true,否则为false。
  // scopeid:一个数字,指定IPv6的作用域ID。
  // cidr:一个字符串,用于指定分配的IPv4或IPv6地址以及CIDR表示法中的路由前缀。如果网络掩码无效,则将其设置为null。
  var interfaces = os.networkInterfaces();

  // 获取系统标识
  name = name || getInterfaceName();

  // 默认IPv4
  family = family || 'IPv4';

  for (var i = -1; i < 8; i++) {
    var interfaceName = name + (i >= 0 ? i : ''); // mac === en  en1 en2 ...

    var items = interfaces[interfaceName]; // 获取所有(mac的话就是en)开头的网络接口信息

    if (items) {
      for (var j = 0; j < items.length; j++) {
        var item = items[j];
        if (item.family === family) return item; // 如果匹配family(IPv4或者IPv6),就返回该对象
      }
    }
  }

  // 没有操作系统
  if (!name) {
    // 过滤127.0.0.1,得到第一个IP
    for (var k in interfaces) {
      var items = interfaces[k];
      for (var i = 0; i < items.length; i++) {
        var item = items[i];
        if (item.family === family && item.address !== '127.0.0.1') return item; // 如果匹配family(IPv4或者IPv6)并且地址不等于127.0.0.1,就返回该对象
      }
    }
  }

  return;
};

/**
 *  获取当前IPv4的ip地址
 *
 * @param {String} [interfaceName] 接口名称,linux默认为“eth”,MAC默认为“en”。
 * @return {String} 网络地址, IP 地址
 */
address.ip = function (interfaceName) {
  // 获取family为IPv4的第一个网络接口对象
  var item = address.interface('IPv4', interfaceName);
  // 返回ip地址
  return item && item.address;
};

/**
 * 获取当前机器IPv6
 *
 * @param {String} [interfaceName] interface name, default is 'eth' on linux, 'en' on mac os.
 * @return {String} IP address
 */
address.ipv6 = function (interfaceName) {
  // 获取family为IPv6的第一个网络接口对象
  var item = address.interface('IPv6', interfaceName);
  // 返回ip地址
  return item && item.address;
};






// osx start line 'en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500'
// linux start line 'eth0      Link encap:Ethernet  HWaddr 00:16:3E:00:0A:29  '
var MAC_OSX_START_LINE = /^(\w+)\:\s+flags=/;
var MAC_LINUX_START_LINE = /^(\w+)\s{2,}link encap:\w+/i;

// ether 78:ca:39:b0:e6:7d
// HWaddr 00:16:3E:00:0A:29
var MAC_RE = address.MAC_RE = /(?:ether|HWaddr)\s+((?:[a-z0-9]{2}\:){5}[a-z0-9]{2})/i;

// osx: inet 192.168.2.104 netmask 0xffffff00 broadcast 192.168.2.255
// linux: inet addr:10.125.5.202  Bcast:10.125.15.255  Mask:255.255.240.0
var MAC_IP_RE = address.MAC_IP_RE = /inet\s(?:addr\:)?(\d+\.\d+\.\d+\.\d+)/;

function getMAC(content, interfaceName, matchIP) {
  var lines = content.split('\n');
  for (var i = 0; i < lines.length; i++) {
    var line = lines[i].trimRight();
    var m = MAC_OSX_START_LINE.exec(line) || MAC_LINUX_START_LINE.exec(line);
    if (!m) {
      continue;
    }

    // check interface name
    var name = m[1];
    if (name.indexOf(interfaceName) !== 0) {
      continue;
    }

    var ip = null;
    var mac = null;
    var match = MAC_RE.exec(line);
    if (match) {
      mac = match[1];
    }

    i++;
    while (true) {
      line = lines[i];
      if (!line || MAC_OSX_START_LINE.exec(line) || MAC_LINUX_START_LINE.exec(line)) {
        i--;
        break; // hit next interface, handle next interface
      }
      if (!mac) {
        match = MAC_RE.exec(line);
        if (match) {
          mac = match[1];
        }
      }

      if (!ip) {
        match = MAC_IP_RE.exec(line);
        if (match) {
          ip = match[1];
        }
      }