s2w / src /utils /ipUtils.js
dvc890's picture
Upload 11 files
3c8ff75 verified
// 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
};