使用node.js编写端口扫描工具(第三部分代码)

发布时间 2023-03-25 01:18:43作者: 项希盛

从host中提取IP地址列表

async function getIpList(host) {

  /**
   * 判断是否为域名
   * @param {string} host 主机名
   * @returns {boolean} 是否为域名
   */
  function isDomainName(host) {
    const domainRegex = /^([a-z0-9]+\.)+([a-z]{2,})+$/i;
    return domainRegex.test(host);
  }

  function isCIDR(host) {
    try {
      const aHost = host.split('/');
      const cidr = Number(aHost[1]);
      if (isNaN(cidr)) {
        return false;
      }
      if (cidr > 32 || cidr < 0) {
        return false;
      }
      const p = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
      if (!p.test(aHost[0])) {
        return false;
      }
      return [aHost[0], cidr];
    } catch (err) {
      return false;
    }
  }

  function ipCIDR(ip, cidr) {
    const mask = (0xFFFFFFFF << (32 - cidr)) >>> 0;
    const start = ip & mask;
    const end = start + (1 << (32 - cidr));
    const ips = [];

    for (let i = start; i < end; i++) {
      ips.push(intToIP(i));
    }

    return ips;
  }

  function ipToInt(ip) {
    return ip.split(".").reduce((acc, cur) => (acc << 8) + parseInt(cur), 0) >>> 0;
  }

  function intToIP(int) {
    return [(int >>> 24) & 0xff, (int >>> 16) & 0xff, (int >>> 8) & 0xff, int & 0xff].join(".");
  }

  try {
    // 如果是域名,则进行 DNS 解析
    if (isDomainName(host)) {
      const ipList = await dns.promises.resolve4(host);
      return ipList;
    }
  } catch (err) {
    console.error(`DNS 解析出错:${err}`);
    process.exit(1);
  }
  const cidr = isCIDR(host);
  if (cidr) {
    return ipCIDR(ipToInt(cidr[0]), cidr[1]);
  }
  return [host];
}

接下来看第四部分代码