"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/index.ts var src_exports = {}; __export(src_exports, { ip: () => ip_exports, netstat: () => netstat_exports }); module.exports = __toCommonJS(src_exports); // src/ip/index.ts var ip_exports = {}; __export(ip_exports, { IPV4_REGEX: () => IPV4_REGEX, IPV6_REGEX: () => IPV6_REGEX, MAC_REGEX: () => MAC_REGEX, dropDevice: () => dropDevice, fromLong: () => fromLong, generateIP: () => generateIP, getIPFamily: () => getIPFamily, getIPVersion: () => getIPVersion, isLoopback: () => isLoopback, isPrivateIP: () => isPrivateIP, isPublicIP: () => isPublicIP, isValidCIDR: () => isValidCIDR, isValidIP: () => isValidIP, isValidIPv4: () => isValidIPv4, isValidIPv6: () => isValidIPv6, isValidMacAddress: () => isValidMacAddress, link: () => link_exports, parseCIDR: () => parseCIDR, route: () => route_exports, toLong: () => toLong }); // src/ip/link.ts var link_exports = {}; __export(link_exports, { add: () => add, del: () => del, list: () => list }); // src/utils/exec-shell.ts var import_p_safe = require("p-safe"); // src/errors.ts var ShellError = class extends Error { exitCode; constructor(message, exitCode) { super(message); this.exitCode = exitCode; } }; // src/utils/exec-shell.ts async function execShell(cmd) { return (0, import_p_safe.trySafe)(async () => { const { execa } = await import("execa"); const res = await execa(cmd.join(" "), { shell: true }); const success = res.exitCode === 0; const [stdout, stderr] = [res.stdout, res.stderr].map((s) => s.trim()); if (success || stdout && stdout !== "") { return { data: { output: stdout, exitCode: res.exitCode } }; } return { error: new ShellError(stderr, res.exitCode) }; }); } // src/ip/link.ts async function add(params) { const args = [ "ip", "link", "add", ...Object.entries(params).map(([key, value]) => `${key.toLowerCase()} ${value}`) ]; return execShell(args); } async function del(params) { const args = [ "ip", "link", "delete", ...Object.entries(params).map(([key, value]) => `${key.toLowerCase()} ${value}`) ]; return execShell(args); } async function list(params = {}) { const args = [ "ip", "link", "show", ...Object.entries(params).map(([key, value]) => `${key.toLowerCase()} ${value}`) ]; const { error, data } = await execShell(args); if (error) { throw error; } const lines = data.output.match(/^\d+:(.*|(?:\n\s)+)+/gm); const links = []; for (const line of lines) { const link = parseLink(line); if (link) { links.push(link); } } return links; } function parseLink(line) { if (!line) { return void 0; } const parts = line.replace(/\n$/, " ").split(/\s+/).slice(1); if (parts.length < 6) { return void 0; } const link = { name: parts[0].slice(0, -1), flags: parts[1].slice(1, -1).split(","), qdisc: "", state: "", mode: "", group: "", qlen: void 0, mtu: -1, address: void 0, broadcast: void 0 }; for (const part of parts.slice(2)) { const next = parts[parts.indexOf(part) + 1]; if (part in link) { link[part] = next.match(/^\d+$/) ? +next : next; } if (part.startsWith("link/") && isValidMacAddress(next)) { link.address = next; } if (part === "brd") { link.broadcast = next; } } return link; } // src/ip/route.ts var route_exports = {}; __export(route_exports, { defaultRoute: () => defaultRoute, list: () => list2 }); async function list2() { const { error, data } = await execShell(["ip", "route", "list"]); if (error) { throw error; } const lines = data.output.split("\n"); const routes = []; for (const line of lines) { const route = parseRoute(line); if (route) { routes.push(route); } } return routes; } async function defaultRoute() { const routes = await list2(); return routes.find((r) => r.destination === "default"); } function parseRoute(line) { const parts = line.trim().split(" "); if (parts.length < 2) { return void 0; } const route = { destination: "", via: null, dev: "", proto: "", src: "", metric: 0, scope: null }; if (parts[0] === "default") { route.destination = parts[0]; parts.splice(0, 1); } if (parts[0].match(/^\d+\.\d+\.\d+\.\d+\/\d+$/)) { route.destination = parts[0]; parts.shift(); } if (parts[0] === "via") { route.via = parts[1]; parts.splice(0, 2); } if (parts[0] === "dev") { route.dev = parts[1]; parts.splice(0, 2); } if (parts[0] === "proto") { route.proto = parts[1]; parts.splice(0, 2); } if (parts[0] === "scope") { route.scope = parts[1]; parts.splice(0, 2); } if (parts[0] === "src") { route.src = parts[1]; parts.splice(0, 2); } if (parts[0] === "metric") { route.metric = parseInt(parts[1], 10); parts.splice(0, 2); } return route; } // src/ip/index.ts async function dropDevice(name) { const { error } = await del({ name }); if (error) { throw error; } } var IPV4_REGEX = /^(\d{1,3}\.){3}\d{1,3}$/; var IPV6_REGEX = /^(::)?(((\d{1,3}\.){3}(\d{1,3}){1})?([0-9a-f]){0,4}:{0,2}){1,8}(::)?$/i; var MAC_REGEX = /^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$/; function isValidIP(ip) { return isValidIPv4(ip) || isValidIPv6(ip); } function isValidIPv4(ip) { return IPV4_REGEX.test(ip); } function isValidIPv6(ip) { return IPV6_REGEX.test(ip); } function isValidCIDR(cidr) { const parts = cidr.split("/"); return isValidIP(parts[0]) && parts[1] && !isNaN(+parts[1]); } function parseCIDR(cidr) { if (!isValidCIDR(cidr)) { throw new Error(`Invalid CIDR: ${cidr}`); } const parts = cidr.split("/"); return { ip: parts[0], mask: +parts[1] }; } function getIPFamily(ip) { if (ip.includes("/")) { const { ip: ipPart } = parseCIDR(ip); ip = ipPart; } if (isValidIPv4(ip)) { return "IPv4"; } if (isValidIPv6(ip)) { return "IPv6"; } throw new Error(`Not a valid IP address: ${ip}`); } function getIPVersion(ip) { return getIPFamily(ip) === "IPv4" ? 4 : 6; } function isLoopback(addr) { return /^(::f{4}:)?127\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})/.test(addr) || /^0177\./.test(addr) || /^0x7f\./i.test(addr) || /^fe80::1$/i.test(addr) || /^::1(\/[0-9]{1,3})?$/.test(addr) || /^::$/.test(addr); } function isPrivateIP(addr) { if (isLoopback(addr)) { return true; } if (addr.includes("/")) { addr = parseCIDR(addr).ip; } const version = getIPVersion(addr); if (version === 4) { return /^(127\.)|(10\.)|(172\.1[6-9]\.)|(172\.2[0-9]\.)|(172\.3[0-1]\.)|(192\.168\.)/.test( addr ); } return /^(::f{4}:)?10\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$/i.test(addr) || /^(::f{4}:)?192\.168\.([0-9]{1,3})\.([0-9]{1,3})$/i.test(addr) || /^(::f{4}:)?172\.(1[6-9]|2\d|30|31)\.([0-9]{1,3})\.([0-9]{1,3})$/i.test(addr) || /^(::f{4}:)?169\.254\.([0-9]{1,3})\.([0-9]{1,3})$/i.test(addr) || /^f[cd][0-9a-f]{2}:/i.test(addr) || /^fe80:/i.test(addr) || /^::1$/.test(addr) || /^::$/.test(addr); } function isPublicIP(addr) { return !isPrivateIP(addr); } function toLong(ip) { return ip.split(".").reduce((acc, octet, index) => acc + parseInt(octet, 10) * 256 ** (3 - index), 0); } function fromLong(num) { const octets = []; for (let i = 3; i >= 0; i--) { octets.push(Math.floor(num / 256 ** i)); num %= 256 ** i; } return octets.join("."); } function* generateIP(cidr) { const { ip: baseIP, mask } = parseCIDR(cidr); if (mask === 32) { yield baseIP; return; } const hostBits = 32 - mask; const maxHosts = 2 ** hostBits; const currentIP = toLong(baseIP); for (let i = 1; i < maxHosts - 1; i++) { yield fromLong(currentIP + i); } } function isValidMacAddress(mac) { return MAC_REGEX.test(mac); } // src/netstat/index.ts var netstat_exports = {}; __export(netstat_exports, { activeConnections: () => activeConnections, allocatedPorts: () => allocatedPorts }); // src/utils/array.ts function removeDuplicate(d) { const final = []; for (const item of d) { if (!final.includes(item)) { final.push(item); } } return final; } // src/netstat/index.ts async function activeConnections() { const { error, data } = await execShell(["netstat", "-tuapn"]); if (error) { throw error; } const lines = data.output.split("\n"); const ports = []; for (const line of lines) { const match = /^(\w+)\s+(\d+)\s+(\d+)\s+((?:::)?(?:(?:(?:\d{1,3}\.){3}(?:\d{1,3}){1})?[0-9a-f]{0,4}:{0,2}){1,8}(?:::)?)\s+((?:::)?(?:(?:(?:\d{1,3}\.){3}(?:\d{1,3}){1})?[0-9a-f]{0,4}:{0,2}){1,8}(?:::)?\*?)\s+(\w+)?\s+(.*)$/.exec( line ); if (match) { const port = match[4].split(":").at(-1); const address = match[4].replace(`:${port}`, ""); const connection = { protocol: match[1], recvQ: Number(match[2]), sendQ: Number(match[3]), address, port: Number(port), state: match[6] ? match[6].trim() : void 0, program: match[7].trim() }; ports.push(connection); } } return ports; } async function allocatedPorts() { const cns = await activeConnections(); return removeDuplicate(cns.map((cn) => cn.port)); } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { ip, netstat });