Files
IPV6/utils/ip.js
编码猿 a9d0dcb074
All checks were successful
continuous-integration/drone/push Build is passing
local
2025-09-09 10:37:04 +08:00

118 lines
3.9 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const net = require('net');
class Ip {
static async parseNetworkInfo(output) {
// 初始化结果对象
const result = {
interface: '',
flags: [],
mtu: '',
state: '',
ipv6Addresses: []
};
// 按行分割输入
const lines = output.split('\n').map(line => line.trim());
// 解析第一行的基本信息
if (lines.length > 0) {
const firstLineParts = lines[0].split(/\s+/);
// 提取接口名称
result.interface = firstLineParts[1].replace(':', '');
// 提取标志
if (firstLineParts[2] && firstLineParts[2].startsWith('<') && firstLineParts[2].endsWith('>')) {
result.flags = firstLineParts[2].slice(1, -1).split(',');
}
// 提取MTU
const mtuIndex = firstLineParts.indexOf('mtu');
if (mtuIndex !== -1 && mtuIndex + 1 < firstLineParts.length) {
result.mtu = firstLineParts[mtuIndex + 1];
}
// 提取状态
const stateIndex = firstLineParts.indexOf('state');
if (stateIndex !== -1 && stateIndex + 1 < firstLineParts.length) {
result.state = firstLineParts[stateIndex + 1];
}
}
// 解析IPv6地址信息
let currentIpv6 = null;
for (let i = 1; i < lines.length; i++) {
const line = lines[i];
if (line.startsWith('inet6')) {
// 如果有当前正在处理的IPv6地址先保存
if (currentIpv6) {
result.ipv6Addresses.push(currentIpv6);
}
// 开始解析新的IPv6地址
const parts = line.split(/\s+/);
const ipv6Address = parts[1].split("/")[0]
currentIpv6 = {
local: ipv6Address.includes("fe80"),
connect: await Ip.checkIPv6WithTcp(ipv6Address),
address: ipv6Address,
scope: parts[2].replace('scope', ''),
properties: parts.slice(3),
validLft: '',
preferredLft: ''
};
} else if (currentIpv6 && line.includes('valid_lft')) {
// 解析有效期信息
const lftParts = line.split(/\s+/);
currentIpv6.validLft = lftParts[0].replace('valid_lft', '');
currentIpv6.preferredLft = lftParts[1].replace('preferred_lft', '');
}
}
// 添加最后一个IPv6地址
if (currentIpv6) {
result.ipv6Addresses.push(currentIpv6);
}
return result;
}
/**
* 检测IPv6地址是否可访问通过尝试建立TCP连接
* @param {string} ipv6 - 要检测的IPv6地址
* @param {number} port - 目标端口,默认 21100
* @param {number} timeout - 超时时间毫秒默认1000
* @returns {Promise<boolean>} - 是否可访问
*/
static checkIPv6WithTcp(ipv6, port = 21100, timeout = 1000) {
return new Promise((resolve) => {
// 验证IPv6格式
if (!net.isIPv6(ipv6)) {
resolve(false);
return;
}
const socket = new net.Socket({ family: 6 }); // 指定IPv6
// 设置超时
const timer = setTimeout(() => {
socket.destroy();
resolve(false);
}, timeout);
// 尝试连接
socket.connect(port, ipv6, () => {
clearTimeout(timer);
socket.destroy();
resolve(true);
});
// 错误处理
socket.on('error', () => {
clearTimeout(timer);
resolve(false);
});
});
}
}
module.exports = Ip