Skip to content

Commit bb309e5

Browse files
committed
feat: add ICMP parser
1 parent 1f7059b commit bb309e5

File tree

1 file changed

+74
-0
lines changed
  • src/net/parser/raw/protocols

1 file changed

+74
-0
lines changed

src/net/parser/raw/protocols/icmp.rs

+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
use crate::net::parser::raw::protocols::ProtocolParser;
2+
use crate::net::parser::raw::RawProtocolHeader;
3+
4+
pub struct IcmpParser;
5+
6+
impl ProtocolParser for IcmpParser {
7+
fn protocol_number() -> u8 {
8+
1 // ICMP protocol number
9+
}
10+
11+
fn parse_packet(payload: &[u8], _protocol_number: u8) -> Option<RawProtocolHeader> {
12+
// ICMP header format:
13+
// 0 1 2 3
14+
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
15+
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16+
// | Type | Code | Checksum |
17+
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
18+
// | Data |
19+
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
20+
21+
if payload.len() < 4 {
22+
return None;
23+
}
24+
25+
let icmp_type = payload[0];
26+
let icmp_code = payload[1];
27+
// Checksum is at payload[2..4] but we don't validate it here
28+
29+
Some(
30+
RawProtocolHeader::new(
31+
None,
32+
None,
33+
icmp_type as u16, // Using type as src_port
34+
icmp_code as u16, // Using code as dst_port
35+
Self::protocol_number(),
36+
payload.len() as u16,
37+
if payload.len() > 4 {
38+
Some(payload[4..].to_vec())
39+
} else {
40+
None
41+
},
42+
)
43+
.with_raw_packet(payload.to_vec())
44+
.with_flags(icmp_type)
45+
.with_version(icmp_code),
46+
)
47+
}
48+
}
49+
50+
#[cfg(test)]
51+
mod tests {
52+
use super::*;
53+
54+
#[test]
55+
fn test_icmp_parser() {
56+
// Echo request (ping) packet
57+
let payload = &[
58+
8, // Type: Echo request
59+
0, // Code: 0
60+
0x00, 0x00, // Checksum (not validated in this test)
61+
0x12, 0x34, // Identifier
62+
0x56, 0x78, // Sequence number
63+
];
64+
65+
let result = IcmpParser::parse_packet(payload, IcmpParser::protocol_number());
66+
assert!(result.is_some());
67+
68+
let header = result.unwrap();
69+
assert_eq!(header.src_port, 8); // Echo request type
70+
assert_eq!(header.dst_port, 0); // Code 0
71+
assert_eq!(header.protocol, 1); // ICMP protocol
72+
assert_eq!(header.length, payload.len() as u16);
73+
}
74+
}

0 commit comments

Comments
 (0)