117 lines
3.8 KiB
JavaScript
117 lines
3.8 KiB
JavaScript
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 = {
|
||
connect: await Ip.checkIPv6WithTcp(ipv6Address),
|
||
address: parts[1].split("/")[0],
|
||
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 |