1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
use super::{Header, HEADER_SIZE, IncomingPacket};
use crate::security::Secret;

use sha2::Sha256;
use hmac::{Hmac, Mac};
type HmacSha256 = Hmac<Sha256>;

pub struct RawPacket {
    buffer: [u8; 1500],
    length: usize,
}

impl RawPacket {
    pub fn new(buffer: [u8; 1500], length: usize) -> Self {
        Self {
            buffer,
            length,
        }
    }

    pub fn get_header<'a>(&'a self) -> &'a Header {
        use std::mem::transmute;

        let ptr = &self.buffer as *const _;
        let reference = unsafe { transmute(ptr) };
        reference
    }

    pub fn get_header_mut<'a>(&'a mut self) -> &'a mut Header {
        use std::mem::transmute;

        let ptr = &mut self.buffer as *mut _;
        let reference = unsafe { transmute(ptr) };
        reference
    }

    pub fn get_buffer(&self) -> &[u8] {
        &self.buffer[0..self.length]
    }

    pub fn get_buffer_mut(&mut self) -> &mut [u8] {
        &mut self.buffer[0..self.length]
    }

    pub fn get_body(&self) -> &[u8] {
        &self.buffer[HEADER_SIZE..self.length]
    }

    pub fn get_body_mut(&mut self) -> &mut [u8] {
        &mut self.buffer[HEADER_SIZE..self.length]
    }

    pub fn verify(self, secret: &Secret) -> Option<IncomingPacket> {
        if self.length < HEADER_SIZE {
            return None;
        }

        let mut mac = HmacSha256::new_varkey(secret.get_bytes()).expect("HmacSha256 can take a key of any size");
        let body_length = self.get_header().body_length as usize;

        mac.input(&self.buffer[32..HEADER_SIZE + body_length]);
        let is_valid = mac.verify(&self.buffer[0..32]).is_ok();

        if is_valid {
            Some(IncomingPacket::from_raw_packet(self))
        } else {
            None
        }
    }
}