netstack/packets/
mod.rs

1mod raw;
2mod header;
3mod incoming;
4mod outgoing;
5mod payload;
6
7pub use raw::*;
8pub use header::*;
9pub use incoming::*;
10pub use outgoing::*;
11pub use payload::*;
12
13#[derive(Debug, Eq, PartialEq, Copy, Clone)]
14pub enum PacketType {
15    Connection,
16    Payload,
17    Heartbeat,
18    Disconnect,
19    Disconnected,
20}
21
22impl PacketType {
23    pub fn from_u8(value: u8) -> Option<Self> {
24        match value {
25            0 => Some(Self::Connection),
26            1 => Some(Self::Payload),
27            2 => Some(Self::Heartbeat),
28            3 => Some(Self::Disconnect),
29            4 => Some(Self::Disconnected),
30            _ => None,
31        }
32    }
33
34    pub fn to_u8(&self) -> u8 {
35        match self {
36            Self::Connection => 0,
37            Self::Payload => 1,
38            Self::Heartbeat => 2,
39            Self::Disconnect => 3,
40            Self::Disconnected => 4,
41        }
42    }
43}
44
45#[cfg(test)]
46mod tests {
47    use super::*;
48
49    #[test]
50    fn sign_and_verify_packet() {
51        use std::io::{Read, Write};
52        use crate::security::Secret;
53
54        let secret = Secret::from_bytes([
55            0x2, 0x1, 0x2, 0x4, 0x8, 0x24, 0x2, 0x1,
56            0x2, 0x4, 0x8, 0x24, 0x2, 0x1, 0x2, 0x4,
57            0x8, 0x24, 0x2, 0x1, 0x2, 0x4, 0x8, 0x24,
58            0x2, 0x1, 0x2, 0x4, 0x8, 0x24, 0x0, 0x64]);
59        let mut outgoing = OutgoingPacket::new();
60
61        outgoing.write(&[0x1, 0x2, 0x3, 0x4, 0x5, 0x6]).expect("It writes into the buffer");
62
63        let buffer = outgoing.write_header_and_sign(15, 12, [0x3, 0x2, 0x1, 0x0], PacketType::Payload.to_u8(), &secret);
64
65        let mut incoming = buffer.verify(&secret).expect("The verification succeeds");
66
67        let mut read_into: [u8; 6] = [0; 6];
68        incoming.read(&mut read_into).expect("It reads into the buffer");
69
70        assert_eq!(read_into, [0x1, 0x2, 0x3, 0x4, 0x5, 0x6], "The body matches the written data");
71        assert_eq!(incoming.get_sequence_number(), 15);
72        assert_eq!(incoming.get_ack_sequence_number(), 12);
73        assert_eq!(incoming.get_ack_bits(), [0x3, 0x2, 0x1, 0x0]);
74        assert_eq!(incoming.get_packet_type(), Some(PacketType::Payload));
75        assert_eq!(incoming.get_body_length(), 6);
76    }
77
78    #[test]
79    fn it_rejects_a_tampered_packet() {
80        use std::io::Write;
81        use crate::security::Secret;
82
83        let secret = Secret::from_bytes([
84            0x2, 0x1, 0x2, 0x4, 0x8, 0x24, 0x2, 0x1,
85            0x2, 0x4, 0x8, 0x24, 0x2, 0x1, 0x2, 0x4,
86            0x8, 0x24, 0x2, 0x1, 0x2, 0x4, 0x8, 0x24,
87            0x2, 0x1, 0x2, 0x4, 0x8, 0x24, 0x0, 0x64]);
88        let mut outgoing = OutgoingPacket::new();
89
90        outgoing.write(&[0x1, 0x2, 0x3, 0x4, 0x5, 0x6]).expect("It writes into the buffer");
91
92        let mut buffer = outgoing.write_header_and_sign(0, 1, [0x0, 0x0, 0x0, 0x0], 1, &secret);
93
94        buffer.get_buffer_mut()[56] = 0x2;
95
96        assert!(buffer.verify(&secret).is_none(), "The packet is invalid");
97    }
98
99    #[test]
100    fn it_rejects_a_packet_signed_with_a_different_secret() {
101        use std::io::Write;
102        use crate::security::Secret;
103
104        let secret = Secret::from_bytes([
105            0x2, 0x1, 0x2, 0x4, 0x8, 0x24, 0x2, 0x1,
106            0x2, 0x4, 0x8, 0x24, 0x2, 0x1, 0x2, 0x4,
107            0x8, 0x24, 0x2, 0x1, 0x2, 0x4, 0x8, 0x24,
108            0x2, 0x1, 0x2, 0x4, 0x8, 0x24, 0x0, 0x64]);
109        let mut outgoing = OutgoingPacket::new();
110
111        outgoing.write(&[0x1, 0x2, 0x3, 0x4, 0x5, 0x6]).expect("It writes into the buffer");
112
113        let buffer = outgoing.write_header_and_sign(0, 1, [0x0, 0x0, 0x0, 0x0], 1, &secret);
114
115        let secret = Secret::from_bytes([
116            0x5, 0x1, 0x2, 0x4, 0x8, 0x24, 0x2, 0x1,
117            0x2, 0x4, 0x8, 0x24, 0x2, 0x1, 0x2, 0x4,
118            0x8, 0x24, 0x2, 0x1, 0x2, 0x4, 0x8, 0x24,
119            0x2, 0x1, 0x2, 0x4, 0x8, 0x24, 0x0, 0x64]);
120
121        assert!(buffer.verify(&secret).is_none(), "The packet is invalid");
122    }
123}