245 lines
8.9 KiB
Rust
245 lines
8.9 KiB
Rust
use nsc::sniffing::*;
|
|
|
|
use crate::headers::Protocol;
|
|
use nsc::sniffing::headers::PacketInfo;
|
|
use nsc::sniffing::headers::sniff_raw_packets;
|
|
|
|
#[test]
|
|
fn generic_typeck() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
|
let test_suite: [&[u8]; 10] = [
|
|
// 1. IPv4 TCP — 192.168.1.100:4832 → 93.184.216.34:443
|
|
&[
|
|
0x45, 0x00, 0x00, 0x28, 0x1A, 0x2B, 0x40, 0x00, 0x40, 0x06, 0x00, 0x00, 192, 168, 1,
|
|
100, // src ip
|
|
93, 184, 216, 34, // dst ip
|
|
0x12, 0xE0, // src port 4832
|
|
0x01, 0xBB, // dst port 443
|
|
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x02, 0xFF, 0xFF, 0x00, 0x00,
|
|
0x00, 0x00,
|
|
],
|
|
// 2. IPv4 UDP — 10.0.0.9:5353 → 224.0.0.251:5353 (mDNS)
|
|
&[
|
|
0x45, 0x00, 0x00, 0x30, 0x8A, 0xF0, 0x40, 0x00, 0x01, 0x11, 0x00, 0x00, 10, 0, 0, 9,
|
|
224, 0, 0, 251, 0x14, 0xE9, // src port 5353
|
|
0x14, 0xE9, // dst port 5353
|
|
0x00, 0x1C, 0x00, 0x00,
|
|
],
|
|
// 3. IPv4 UDP — 10.0.0.9:1024 → 8.8.8.8:53 (DNS)
|
|
&[
|
|
0x45, 0x00, 0x00, 0x3C, 0x00, 0x01, 0x00, 0x00, 0x40, 0x11, 0x00, 0x00, 10, 0, 0, 9, 8,
|
|
8, 8, 8, 0x04, 0x00, // src port 1024
|
|
0x00, 0x35, // dst port 53
|
|
0x00, 0x28, 0x00, 0x00,
|
|
],
|
|
// 4. IPv4 TCP — 10.0.0.5:54321 → 10.0.0.1:80 (HTTP)
|
|
&[
|
|
0x45, 0x00, 0x00, 0x28, 0x00, 0x02, 0x40, 0x00, 0x40, 0x06, 0x00, 0x00, 10, 0, 0, 5,
|
|
10, 0, 0, 1, 0xD4, 0x31, // src port 54321
|
|
0x00, 0x50, // dst port 80
|
|
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x02, 0xFF, 0xFF, 0x00, 0x00,
|
|
0x00, 0x00,
|
|
],
|
|
// 5. IPv4 TCP — 172.16.0.1:65535 → 172.16.0.2:8080
|
|
&[
|
|
0x45, 0x00, 0x00, 0x28, 0x00, 0x03, 0x40, 0x00, 0x40, 0x06, 0x00, 0x00, 172, 16, 0, 1,
|
|
172, 16, 0, 2, 0xFF, 0xFF, // src port 65535
|
|
0x1F, 0x90, // dst port 8080
|
|
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x02, 0xFF, 0xFF, 0x00, 0x00,
|
|
0x00, 0x00,
|
|
],
|
|
// 6. IPv4 with IHL=6 (24-byte header, has IP options)
|
|
// 10.0.0.1:9090 → 10.0.0.2:22 TCP
|
|
&[
|
|
0x46, 0x00, 0x00, 0x2C, 0x00, 0x04, 0x40, 0x00, 0x40, 0x06, 0x00, 0x00, 10, 0, 0, 1,
|
|
10, 0, 0, 2, 0x01, 0x02, 0x03, 0x04, // 4 bytes of IP options (padding)
|
|
0x23, 0x82, // src port 9090 (at byte 24, not 20!)
|
|
0x00, 0x16, // dst port 22
|
|
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x02, 0xFF, 0xFF, 0x00, 0x00,
|
|
0x00, 0x00,
|
|
],
|
|
// 7. IPv4 ICMP — unsupported protocol (proto=1)
|
|
// 10.0.0.9 → 10.0.0.1
|
|
&[
|
|
0x45, 0x00, 0x00, 0x1C, 0x00, 0x05, 0x00, 0x00, 0x40, 0x01, 0x00,
|
|
0x00, // protocol = 1 (ICMP)
|
|
10, 0, 0, 9, 10, 0, 0, 1, 0x08, 0x00, 0x00,
|
|
0x00, // ICMP echo request (will be read as "ports")
|
|
0x00, 0x01, 0x00, 0x01,
|
|
],
|
|
// 8. IPv6 TCP — [::1]:4000 → [2606:4700::1]:443
|
|
&[
|
|
0x60, 0x00, 0x00, 0x00, // version=6, traffic class, flow label
|
|
0x00, 0x14, // payload length = 20
|
|
0x06, // next header = 6 (TCP)
|
|
0x40, // hop limit = 64
|
|
// src ip: ::1 (bytes 8-23)
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x01, // dst ip: 2606:4700::1 (bytes 24-39)
|
|
0x26, 0x06, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x01, // TCP header (bytes 40+)
|
|
0x0F, 0xA0, // src port 4000
|
|
0x01, 0xBB, // dst port 443
|
|
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x02, 0xFF, 0xFF, 0x00, 0x00,
|
|
0x00, 0x00,
|
|
],
|
|
// 9. IPv6 UDP — [fd00::9]:1234 → [fd00::1]:53 (DNS)
|
|
&[
|
|
0x60, 0x00, 0x00, 0x00, 0x00, 0x08, // payload length = 8
|
|
0x11, // next header = 17 (UDP)
|
|
0x40, // src ip: fd00::9
|
|
0xFD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x09, // dst ip: fd00::1
|
|
0xFD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x01, // UDP header
|
|
0x04, 0xD2, // src port 1234
|
|
0x00, 0x35, // dst port 53
|
|
0x00, 0x08, 0x00, 0x00,
|
|
],
|
|
// 10. IPv6 ICMPv6 — unsupported (next header = 58)
|
|
// [fe80::1] → [ff02::1]
|
|
&[
|
|
0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3A, // next header = 58 (ICMPv6)
|
|
0xFF, // src ip: fe80::1
|
|
0xFE, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x01, // dst ip: ff02::1
|
|
0xFF, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x01, // ICMPv6 body (will be read as "ports" if you parse blindly)
|
|
0x80, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01,
|
|
],
|
|
];
|
|
// for test in test_suite {
|
|
// let abc = sniff_raw_packets(test);
|
|
// eprintln!("{:?}", abc);
|
|
// }
|
|
|
|
// [0] IPv4 TCP 192.168.1.100:4832 → 93.184.216.34:443
|
|
assert_eq!(
|
|
sniff_raw_packets(test_suite[0])?,
|
|
PacketInfo::V6 {
|
|
dns: false,
|
|
src_ip: [192, 168, 1, 100],
|
|
src_port: 4832,
|
|
dst_ip: [93, 184, 216, 34],
|
|
dst_port: 443,
|
|
protocol: Protocol::TCP
|
|
}
|
|
);
|
|
|
|
// [1] IPv4 UDP 10.0.0.9:5353 → 224.0.0.251:5353 (mDNS)
|
|
assert_eq!(
|
|
sniff_raw_packets(test_suite[1])?,
|
|
PacketInfo::V6 {
|
|
dns: false,
|
|
src_ip: [10, 0, 0, 9],
|
|
src_port: 5353,
|
|
dst_ip: [224, 0, 0, 251],
|
|
dst_port: 5353,
|
|
protocol: Protocol::UDP
|
|
}
|
|
);
|
|
|
|
// [2] IPv4 UDP 10.0.0.9:1024 → 8.8.8.8:53 (DNS)
|
|
assert_eq!(
|
|
sniff_raw_packets(test_suite[2])?,
|
|
PacketInfo::V6 {
|
|
dns: false,
|
|
src_ip: [10, 0, 0, 9],
|
|
src_port: 1024,
|
|
dst_ip: [8, 8, 8, 8],
|
|
dst_port: 53,
|
|
protocol: Protocol::UDP
|
|
}
|
|
);
|
|
|
|
// [3] IPv4 TCP 10.0.0.5:54321 → 10.0.0.1:80 (HTTP)
|
|
assert_eq!(
|
|
sniff_raw_packets(test_suite[3])?,
|
|
PacketInfo::V6 {
|
|
dns: false,
|
|
src_ip: [10, 0, 0, 5],
|
|
src_port: 54321,
|
|
dst_ip: [10, 0, 0, 1],
|
|
dst_port: 80,
|
|
protocol: Protocol::TCP
|
|
}
|
|
);
|
|
|
|
// [4] IPv4 TCP 172.16.0.1:65535 → 172.16.0.2:8080
|
|
assert_eq!(
|
|
sniff_raw_packets(test_suite[4])?,
|
|
PacketInfo::V6 {
|
|
dns: false,
|
|
src_ip: [172, 16, 0, 1],
|
|
src_port: 65535,
|
|
dst_ip: [172, 16, 0, 2],
|
|
dst_port: 8080,
|
|
protocol: Protocol::TCP
|
|
}
|
|
);
|
|
|
|
// [5] IPv4 TCP IHL=6 10.0.0.1:9090 → 10.0.0.2:22 (requires IHL-based offset)
|
|
assert_eq!(
|
|
sniff_raw_packets(test_suite[5])?,
|
|
PacketInfo::V6 {
|
|
dns: false,
|
|
src_ip: [10, 0, 0, 1],
|
|
src_port: 9090,
|
|
dst_ip: [10, 0, 0, 2],
|
|
dst_port: 22,
|
|
protocol: Protocol::TCP
|
|
}
|
|
);
|
|
|
|
// [6] IPv4 ICMP (unsupported, "ports" are just ICMP body bytes)
|
|
assert_eq!(
|
|
sniff_raw_packets(test_suite[6])?,
|
|
PacketInfo::V6 {
|
|
dns: false,
|
|
src_ip: [10, 0, 0, 9],
|
|
src_port: 2048,
|
|
dst_ip: [10, 0, 0, 1],
|
|
dst_port: 0,
|
|
protocol: Protocol::Unsupported(1)
|
|
}
|
|
);
|
|
|
|
// [7] IPv6 TCP [::1]:4000 → [2606:4700::1]:443
|
|
assert_eq!(
|
|
sniff_raw_packets(test_suite[7])?,
|
|
PacketInfo::V6 {
|
|
dns: false,
|
|
src_ip: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
|
|
src_port: 4000,
|
|
dst_ip: [0x26, 0x06, 0x47, 0x00, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
|
|
dst_port: 443,
|
|
protocol: Protocol::TCP
|
|
}
|
|
);
|
|
|
|
// [8] IPv6 UDP [fd00::9]:1234 → [fd00::1]:53 (requires fixing 17 => UDP)
|
|
assert_eq!(
|
|
sniff_raw_packets(test_suite[8])?,
|
|
PacketInfo::V6 {
|
|
dns: false,
|
|
src_ip: [0xFD, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9],
|
|
src_port: 1234,
|
|
dst_ip: [0xFD, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
|
|
dst_port: 53,
|
|
protocol: Protocol::UDP
|
|
}
|
|
);
|
|
|
|
// [9] IPv6 ICMPv6 (unsupported, "ports" are ICMPv6 body bytes)
|
|
assert_eq!(
|
|
sniff_raw_packets(test_suite[9])?,
|
|
PacketInfo::V6 {
|
|
dns: false,
|
|
src_ip: [0xFE, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
|
|
src_port: 32768,
|
|
dst_ip: [0xFF, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
|
|
dst_port: 0,
|
|
protocol: Protocol::Unsupported(58)
|
|
}
|
|
);
|
|
Ok(())
|
|
}
|