File size: 2,088 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 |
// 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
}; |