// networkService.js const net = require('net'); const dgram = require('dgram'); const { exec } = require('child_process'); const { promisify } = require('util'); const execAsync = promisify(exec); /** * 创建一个不会被TUN设备捕获的TCP连接 * @param {string} host - 目标主机 * @param {number} port - 目标端口 * @returns {net.Socket} TCP套接字 */ function createProtectedTCPConnection(host, port) { console.log(`创建受保护的TCP连接到 ${host}:${port}`); // 创建TCP套接字 const socket = new net.Socket(); // 设置连接选项,尝试避免路由循环 socket.setNoDelay(true); socket.setTimeout(10000); // 10秒超时 // 尝试设置SOCKET选项来避免路由循环 try { // 在某些系统上,可以设置SOCK_NO_CHECK_V4来避免路由循环 // 注意:这个选项在Node.js中可能不可用 socket.setKeepAlive(true, 1000); } catch (error) { console.warn('设置TCP套接字选项时出错:', error.message); } // 连接到目标主机 socket.connect(port, host, () => { console.log(`已连接到 ${host}:${port}`); }); return socket; } /** * 创建一个不会被TUN设备捕获的UDP套接字 * @returns {dgram.Socket} UDP套接字 */ function createProtectedUDPSocket() { console.log('创建受保护的UDP套接字'); // 创建UDP套接字 const socket = dgram.createSocket('udp4'); return socket; } /** * 通过系统命令发送ICMP数据包(避免路由循环) * @param {string} destinationIP - 目标IP地址 * @param {Buffer} packet - ICMP数据包 * @returns {Promise} */ async function sendICMPPacketViaSystem(destinationIP, packet) { console.log(`通过系统命令发送ICMP数据包到 ${destinationIP}`); try { // 将数据包保存到临时文件 const fs = require('fs'); const path = require('path'); const tempDir = '/tmp'; const tempFile = path.join(tempDir, `icmp_packet_${Date.now()}.bin`); // 写入数据包到临时文件 fs.writeFileSync(tempFile, packet); // 使用hping3或ping命令发送ICMP数据包 // 注意:这需要安装hping3工具 const command = `hping3 -0 -c 1 -d ${packet.length} -E ${tempFile} ${destinationIP}`; console.log(`执行命令: ${command}`); const { stdout, stderr } = await execAsync(command); if (stderr) { console.warn('发送ICMP数据包时的警告:', stderr); } console.log('ICMP数据包发送结果:', stdout); // 清理临时文件 fs.unlinkSync(tempFile); } catch (error) { console.error('通过系统命令发送ICMP数据包时出错:', error.message); // 回退到普通UDP发送 console.log('回退到普通UDP发送'); const client = dgram.createSocket('udp4'); client.send(packet, 0, packet.length, 7, destinationIP, (err) => { if (err) { console.error('发送ICMP数据包时出错:', err.message); } else { console.log(`ICMP数据包已发送到 ${destinationIP}:7`); } client.close(); }); } } /** * 检查是否为本地地址 * @param {string} ip - IP地址 * @returns {boolean} 是否为本地地址 */ function isLocalAddress(ip) { // 检查是否为本地回环地址 if (ip.startsWith('127.') || ip === 'localhost') { return true; } // 检查是否为私有地址范围 if (ip.startsWith('10.') || ip.startsWith('192.168.') || (ip.startsWith('172.') && parseInt(ip.split('.')[1]) >= 16 && parseInt(ip.split('.')[1]) <= 31)) { return true; } return false; } /** * 获取默认网关 * @returns {Promise} 默认网关IP地址 */ async function getDefaultGateway() { return new Promise((resolve, reject) => { require('child_process').exec('route get default | grep gateway | awk \'{print $2}\'', (error, stdout, stderr) => { if (error) { reject(error); } else { const gateway = stdout.trim(); resolve(gateway); } }); }); } /** * 获取网络接口信息 * @returns {Promise} 网络接口列表 */ async function getNetworkInterfaces() { return new Promise((resolve, reject) => { require('child_process').exec('ifconfig -l', (error, stdout, stderr) => { if (error) { reject(error); } else { const interfaces = stdout.trim().split(' '); resolve(interfaces); } }); }); } module.exports = { createProtectedTCPConnection, createProtectedUDPSocket, isLocalAddress, getDefaultGateway, getNetworkInterfaces };