first commit
This commit is contained in:
117
utils/ip.js
Normal file
117
utils/ip.js
Normal file
@@ -0,0 +1,117 @@
|
||||
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
|
||||
Reference in New Issue
Block a user