learning_network_protocols/src/lib/utils/protocols/ipv4.js

63 lines
1.5 KiB
JavaScript

function calculateIPv4Checksum(buffer) {
const ihl = (buffer[0] & 0x0f) * 4;
let sum = 0;
for (let i = 0; i < ihl; i += 2) {
if (i === 10) continue;
sum += (buffer[i] << 8) | buffer[i + 1];
}
while (sum >> 16) {
sum = (sum & 0xffff) + (sum >> 16);
}
return (~sum) & 0xffff;
}
export function updateIPv4Buffer(buffer) {
const updated = new Uint8Array(buffer);
updated[10] = 0x00;
updated[11] = 0x00;
const checksum = calculateIPv4Checksum(updated);
updated[10] = (checksum >> 8) & 0xff;
updated[11] = checksum & 0xff;
return updated;
}
export function formatIPv4Address(bytes) {
if (bytes.length < 4) return 'N/A';
return `${bytes[0]}.${bytes[1]}.${bytes[2]}.${bytes[3]}`;
}
export function formatIPv4Protocol(proto) {
const protocols = {
1: 'ICMP',
6: 'TCP',
17: 'UDP',
47: 'GRE',
50: 'ESP',
51: 'AH',
89: 'OSPF',
132: 'SCTP',
};
const name = protocols[proto] ?? 'Unknown';
return `${name} (${proto} / 0x${proto.toString(16).padStart(2, '0').toUpperCase()})`;
}
export function formatVersionIHL(byte) {
const version = (byte >> 4) & 0x0f;
const ihl = (byte & 0x0f) * 4;
return `IPv${version}, Header Length: ${ihl} bytes`;
}
export function formatFlagsFragment(bytes) {
if (bytes.length < 2) return 'N/A';
const raw = (bytes[0] << 8) | bytes[1];
const df = (raw >> 14) & 1;
const mf = (raw >> 13) & 1;
const offset = raw & 0x1fff;
return `DF=${df}, MF=${mf}, Offset=${offset}`;
}