File size: 4,601 Bytes
3c8ff75
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
// 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<void>}
 */
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<string>} 默认网关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<Array>} 网络接口列表
 */
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
};