// ipUtils.js /** * 解析 IPv4 数据包的目标地址 * @param {Buffer} packet - IP 数据包 * @returns {string} 目标 IP 地址 */ function parseDestinationIP(packet) { // IP 头部长度 (通常是 20 字节) const headerLength = (packet[0] & 0x0F) * 4; // 检查是否有足够的字节来解析 IP 头部 if (packet.length < headerLength + 4) { throw new Error('数据包太短,无法解析目标 IP'); } // 目标 IP 地址在 IP 头部的第 16-19 字节 const destIP = `${packet[16]}.${packet[17]}.${packet[18]}.${packet[19]}`; return destIP; } /** * 解析 IPv4 数据包的目标端口 (适用于 TCP/UDP) * @param {Buffer} packet - IP 数据包 * @returns {number} 目标端口号 */ function parseDestinationPort(packet) { // IP 头部长度 const headerLength = (packet[0] & 0x0F) * 4; // 检查协议 (6 = TCP, 17 = UDP) const protocol = packet[9]; // TCP/UDP 头部中的端口字段位置 if (protocol === 6 || protocol === 17) { // 检查是否有足够的字节来解析端口 if (packet.length < headerLength + 4) { throw new Error('数据包太短,无法解析目标端口'); } // 目标端口在 TCP/UDP 头部的第 2-3 字节 const destPort = (packet[headerLength + 2] << 8) + packet[headerLength + 3]; return destPort; } // 对于其他协议返回默认端口 0 return 0; } /** * 验证是否为有效的 IPv4 数据包 * @param {Buffer} packet - 待验证的数据包 * @returns {boolean} 是否为有效的 IPv4 数据包 */ function isValidIPv4Packet(packet) { // 检查数据包是否为空 if (!packet || packet.length < 20) { return false; } // 检查 IP 版本 (应该是 4) const version = (packet[0] >> 4) & 0x0F; if (version !== 4) { return false; } // 检查 IP 头部长度 const headerLength = (packet[0] & 0x0F) * 4; if (headerLength < 20 || headerLength > packet.length) { return false; } return true; } module.exports = { parseDestinationIP, parseDestinationPort, isValidIPv4Packet };