src/vrrpv2.rs
author Sunil Nimmagadda <sunil@nimmagadda.net>
Thu, 01 Feb 2024 16:51:45 +0530
changeset 25 72c4d898c478
parent 23 1bfa6fd5b5f9
child 26 4ad31d279c35
permissions -rw-r--r--
Move to as_chunks. Fuzz testing needs a nightly, so let's move to nightly everywhere.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
20
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
     1
use std::io::Read;
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
     2
use std::io::{self, Cursor};
7
e3058ceb81cc Module to parse(unimplemented) VRRPv2 packet.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
     3
use std::net::Ipv4Addr;
e3058ceb81cc Module to parse(unimplemented) VRRPv2 packet.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
     4
16
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
     5
/// A VRRP version 2 packet.
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
     6
///
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
     7
/// Packet format
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
     8
///
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
     9
///  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
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
    10
/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
    11
/// |Version| Type  | Virtual Rtr ID|   Priority    | Count IP Addrs|
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
    12
/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
    13
/// |   Auth Type   |   Adver Int   |          Checksum             |
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
    14
/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
    15
/// |                         IP Address (1)                        |
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
    16
/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
    17
/// |                            .                                  |
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
    18
/// |                            .                                  |
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
    19
/// |                            .                                  |
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
    20
/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
    21
/// |                         IP Address (n)                        |
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
    22
/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
    23
/// |                     Authentication Data (1)                   |
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
    24
/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
    25
/// |                     Authentication Data (2)                   |
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
    26
/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
    27
#[derive(Debug, PartialEq)]
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
    28
pub struct VRRPv2 {
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
    29
    pub virtual_router_id: u8,
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
    30
    pub priority: u8,
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
    31
    pub count_ip_addrs: u8,
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
    32
    pub auth_type: VRRPv2AuthType,
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
    33
    pub advertisement_interval: u8,
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
    34
    pub checksum: u16,
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
    35
    pub ip_addrs: Vec<Ipv4Addr>,
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
    36
}
7
e3058ceb81cc Module to parse(unimplemented) VRRPv2 packet.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    37
8
e4cad4eba60b Implement a VRRPv2 packet parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 7
diff changeset
    38
#[derive(Debug, Clone, PartialEq)]
e4cad4eba60b Implement a VRRPv2 packet parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 7
diff changeset
    39
pub enum VRRPv2Error {
16
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
    40
    InvalidAuthType,
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
    41
    InvalidChecksum,
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
    42
    InvalidType,
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
    43
    InvalidVersion,
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
    44
    ParseError,
7
e3058ceb81cc Module to parse(unimplemented) VRRPv2 packet.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    45
}
e3058ceb81cc Module to parse(unimplemented) VRRPv2 packet.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    46
8
e4cad4eba60b Implement a VRRPv2 packet parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 7
diff changeset
    47
#[derive(Debug, PartialEq)]
7
e3058ceb81cc Module to parse(unimplemented) VRRPv2 packet.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    48
pub enum VRRPv2AuthType {
e3058ceb81cc Module to parse(unimplemented) VRRPv2 packet.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    49
    VRRPv2AuthNoAuth = 0x00,
e3058ceb81cc Module to parse(unimplemented) VRRPv2 packet.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    50
    VRRPv2AuthReserved1 = 0x01,
e3058ceb81cc Module to parse(unimplemented) VRRPv2 packet.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    51
    VRRPv2AuthReserved2 = 0x02,
e3058ceb81cc Module to parse(unimplemented) VRRPv2 packet.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    52
}
e3058ceb81cc Module to parse(unimplemented) VRRPv2 packet.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    53
20
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
    54
trait ByteReader {
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
    55
    fn read_u8(&mut self) -> io::Result<u8>;
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
    56
    fn read_u16(&mut self) -> io::Result<u16>;
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
    57
    fn read_u32(&mut self) -> io::Result<u32>;
8
e4cad4eba60b Implement a VRRPv2 packet parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 7
diff changeset
    58
}
e4cad4eba60b Implement a VRRPv2 packet parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 7
diff changeset
    59
20
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
    60
impl<T: AsRef<[u8]>> ByteReader for Cursor<T> {
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
    61
    fn read_u8(&mut self) -> io::Result<u8> {
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
    62
        let mut buffer = [0; 1];
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
    63
        self.read_exact(&mut buffer)?;
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
    64
        Ok(u8::from_be_bytes(buffer))
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
    65
    }
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
    66
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
    67
    fn read_u16(&mut self) -> io::Result<u16> {
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
    68
        let mut buffer = [0; 2];
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
    69
        self.read_exact(&mut buffer)?;
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
    70
        Ok(u16::from_be_bytes(buffer))
16
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
    71
    }
20
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
    72
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
    73
    fn read_u32(&mut self) -> io::Result<u32> {
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
    74
        let mut buffer = [0; 4];
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
    75
        self.read_exact(&mut buffer)?;
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
    76
        Ok(u32::from_be_bytes(buffer))
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
    77
    }
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
    78
}
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
    79
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
    80
fn parse(bytes: &[u8]) -> Result<VRRPv2, VRRPv2Error> {
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
    81
    let mut rdr = Cursor::new(bytes);
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
    82
    let Ok(vertype) = rdr.read_u8() else {
16
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
    83
        return Err(VRRPv2Error::ParseError);
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
    84
    };
20
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
    85
    if (vertype & 0xF) != 1 {
21
17afb5ba9c2b Still confused by lsb/msb.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 20
diff changeset
    86
        return Err(VRRPv2Error::InvalidType);
20
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
    87
    }
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
    88
    if (vertype >> 4) != 2 {
21
17afb5ba9c2b Still confused by lsb/msb.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 20
diff changeset
    89
        return Err(VRRPv2Error::InvalidVersion);
16
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
    90
    }
20
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
    91
    let Ok(virtual_router_id) = rdr.read_u8() else {
16
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
    92
        return Err(VRRPv2Error::ParseError);
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
    93
    };
20
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
    94
    let Ok(priority) = rdr.read_u8() else {
16
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
    95
        return Err(VRRPv2Error::ParseError);
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
    96
    };
20
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
    97
    let Ok(count_ip_addrs) = rdr.read_u8() else {
16
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
    98
        return Err(VRRPv2Error::ParseError);
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
    99
    };
20
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
   100
    let Ok(auth_type) = rdr.read_u8() else {
16
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
   101
        return Err(VRRPv2Error::ParseError);
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
   102
    };
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
   103
    let auth_type = match auth_type {
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
   104
        0 => VRRPv2AuthType::VRRPv2AuthNoAuth,
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
   105
        1 => VRRPv2AuthType::VRRPv2AuthReserved1,
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
   106
        2 => VRRPv2AuthType::VRRPv2AuthReserved2,
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
   107
        _ => return Err(VRRPv2Error::InvalidAuthType),
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
   108
    };
20
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
   109
    let Ok(advertisement_interval) = rdr.read_u8() else {
16
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
   110
        return Err(VRRPv2Error::ParseError);
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
   111
    };
20
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
   112
    let Ok(checksum) = rdr.read_u16() else {
16
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
   113
        return Err(VRRPv2Error::ParseError);
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
   114
    };
23
1bfa6fd5b5f9 Use with_capacity as it's known by now.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 22
diff changeset
   115
    let mut ip_addrs = Vec::with_capacity(count_ip_addrs as usize);
20
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
   116
    for _i in 0..count_ip_addrs {
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
   117
        let Ok(b) = rdr.read_u32() else {
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
   118
            return Err(VRRPv2Error::ParseError);
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
   119
        };
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
   120
        ip_addrs.push(Ipv4Addr::from(b));
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
   121
    }
16
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
   122
    Ok(VRRPv2 {
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
   123
        virtual_router_id,
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
   124
        priority,
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
   125
        count_ip_addrs,
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
   126
        auth_type,
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
   127
        advertisement_interval,
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
   128
        checksum,
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
   129
        ip_addrs,
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
   130
    })
7
e3058ceb81cc Module to parse(unimplemented) VRRPv2 packet.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   131
}
8
e4cad4eba60b Implement a VRRPv2 packet parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 7
diff changeset
   132
19
1567e8a5a0cb Recover a lost doc test.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 18
diff changeset
   133
/// Parse and validate a byte array to construct a VRRPv2 struct.
1567e8a5a0cb Recover a lost doc test.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 18
diff changeset
   134
///
1567e8a5a0cb Recover a lost doc test.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 18
diff changeset
   135
/// # Examples
1567e8a5a0cb Recover a lost doc test.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 18
diff changeset
   136
///
1567e8a5a0cb Recover a lost doc test.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 18
diff changeset
   137
/// ```
1567e8a5a0cb Recover a lost doc test.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 18
diff changeset
   138
/// use vrrpd::vrrpv2::VRRPv2;
1567e8a5a0cb Recover a lost doc test.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 18
diff changeset
   139
/// use vrrpd::vrrpv2::VRRPv2AuthType;
1567e8a5a0cb Recover a lost doc test.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 18
diff changeset
   140
/// use vrrpd::vrrpv2::from_bytes;
1567e8a5a0cb Recover a lost doc test.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 18
diff changeset
   141
/// use std::net::Ipv4Addr;
1567e8a5a0cb Recover a lost doc test.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 18
diff changeset
   142
///
1567e8a5a0cb Recover a lost doc test.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 18
diff changeset
   143
/// let bytes = [
1567e8a5a0cb Recover a lost doc test.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 18
diff changeset
   144
///    0x21, 0x01, 0x64, 0x01, 0x00, 0x01, 0xba, 0x52, 0xc0, 0xa8, 0x00, 0x01, 0x00, 0x00, 0x00,
1567e8a5a0cb Recover a lost doc test.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 18
diff changeset
   145
///    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1567e8a5a0cb Recover a lost doc test.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 18
diff changeset
   146
/// ];
1567e8a5a0cb Recover a lost doc test.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 18
diff changeset
   147
/// let expected = VRRPv2 {
1567e8a5a0cb Recover a lost doc test.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 18
diff changeset
   148
///     virtual_router_id: 1,
1567e8a5a0cb Recover a lost doc test.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 18
diff changeset
   149
///     priority: 100,
1567e8a5a0cb Recover a lost doc test.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 18
diff changeset
   150
///     count_ip_addrs: 1,
1567e8a5a0cb Recover a lost doc test.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 18
diff changeset
   151
///     auth_type: VRRPv2AuthType::VRRPv2AuthNoAuth,
1567e8a5a0cb Recover a lost doc test.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 18
diff changeset
   152
///     checksum: 47698,
1567e8a5a0cb Recover a lost doc test.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 18
diff changeset
   153
///     advertisement_interval: 1,
1567e8a5a0cb Recover a lost doc test.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 18
diff changeset
   154
///     ip_addrs: vec![Ipv4Addr::from([192, 168, 0, 1])],
1567e8a5a0cb Recover a lost doc test.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 18
diff changeset
   155
/// };
1567e8a5a0cb Recover a lost doc test.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 18
diff changeset
   156
/// assert_eq!(from_bytes(&bytes), Ok(expected));
1567e8a5a0cb Recover a lost doc test.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 18
diff changeset
   157
/// ```
8
e4cad4eba60b Implement a VRRPv2 packet parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 7
diff changeset
   158
pub fn from_bytes(bytes: &[u8]) -> Result<VRRPv2, VRRPv2Error> {
16
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
   159
    let vrrpv2 = parse(bytes)?;
17
90d097c9ea62 Rectify checksum calculation.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 16
diff changeset
   160
    if checksum(bytes) != 0 {
16
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
   161
        return Err(VRRPv2Error::InvalidChecksum);
8
e4cad4eba60b Implement a VRRPv2 packet parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 7
diff changeset
   162
    }
16
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
   163
    Ok(vrrpv2)
8
e4cad4eba60b Implement a VRRPv2 packet parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 7
diff changeset
   164
}
e4cad4eba60b Implement a VRRPv2 packet parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 7
diff changeset
   165
20
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
   166
fn checksum(bytes: &[u8]) -> u16 {
25
72c4d898c478 Move to as_chunks.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 23
diff changeset
   167
    let (chunks, remainder) = bytes.as_chunks::<2>();
72c4d898c478 Move to as_chunks.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 23
diff changeset
   168
    let mut sum = chunks
72c4d898c478 Move to as_chunks.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 23
diff changeset
   169
        .iter()
72c4d898c478 Move to as_chunks.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 23
diff changeset
   170
        .fold(0, |acc, x| acc + u32::from(u16::from_be_bytes(*x)));
72c4d898c478 Move to as_chunks.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 23
diff changeset
   171
    if !remainder.is_empty() {
72c4d898c478 Move to as_chunks.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 23
diff changeset
   172
        sum += u32::from(remainder[0]);
20
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
   173
    }
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
   174
    while (sum >> 16) > 0 {
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
   175
        sum = (sum & 0xffff) + (sum >> 16);
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
   176
    }
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
   177
    !(sum as u16)
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
   178
}
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
   179
8
e4cad4eba60b Implement a VRRPv2 packet parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 7
diff changeset
   180
#[test]
e4cad4eba60b Implement a VRRPv2 packet parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 7
diff changeset
   181
fn test_incomplete_bytes() {
e4cad4eba60b Implement a VRRPv2 packet parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 7
diff changeset
   182
    let bytes = [0x21, 0x01];
16
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
   183
    assert_eq!(from_bytes(&bytes), Err(VRRPv2Error::ParseError));
8
e4cad4eba60b Implement a VRRPv2 packet parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 7
diff changeset
   184
}
e4cad4eba60b Implement a VRRPv2 packet parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 7
diff changeset
   185
e4cad4eba60b Implement a VRRPv2 packet parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 7
diff changeset
   186
#[test]
16
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
   187
fn test_invalid_version() {
8
e4cad4eba60b Implement a VRRPv2 packet parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 7
diff changeset
   188
    let bytes = [
21
17afb5ba9c2b Still confused by lsb/msb.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 20
diff changeset
   189
        0x31, 0x1, 0x2a, 0x0, 0x0, 0x1, 0xb5, 0xfd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
16
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
   190
        0x0, 0x0, 0x0,
8
e4cad4eba60b Implement a VRRPv2 packet parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 7
diff changeset
   191
    ];
18
2470a15711b1 Fix clippy warnings.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 17
diff changeset
   192
    assert_eq!(from_bytes(&bytes), Err(VRRPv2Error::InvalidVersion));
16
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
   193
}
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
   194
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
   195
#[test]
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
   196
fn test_invalid_type() {
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
   197
    let bytes = [
21
17afb5ba9c2b Still confused by lsb/msb.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 20
diff changeset
   198
        0x20, 0x2a, 0x64, 0x1, 0x0, 0x1, 0xaa, 0x29, 0xc0, 0xa8, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0,
16
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
   199
        0x0, 0x0, 0x0,
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
   200
    ];
18
2470a15711b1 Fix clippy warnings.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 17
diff changeset
   201
    assert_eq!(from_bytes(&bytes), Err(VRRPv2Error::InvalidType));
8
e4cad4eba60b Implement a VRRPv2 packet parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 7
diff changeset
   202
}
e4cad4eba60b Implement a VRRPv2 packet parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 7
diff changeset
   203
e4cad4eba60b Implement a VRRPv2 packet parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 7
diff changeset
   204
#[test]
e4cad4eba60b Implement a VRRPv2 packet parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 7
diff changeset
   205
fn test_invalid_auth_type() {
e4cad4eba60b Implement a VRRPv2 packet parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 7
diff changeset
   206
    let bytes = [
e4cad4eba60b Implement a VRRPv2 packet parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 7
diff changeset
   207
        0x21, 0x01, 0x64, 0x01, 0x03, 0x01, 0xba, 0x52, 0xc0, 0xa8, 0x00, 0x01, 0x00, 0x00, 0x00,
e4cad4eba60b Implement a VRRPv2 packet parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 7
diff changeset
   208
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
e4cad4eba60b Implement a VRRPv2 packet parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 7
diff changeset
   209
    ];
16
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
   210
    assert_eq!(from_bytes(&bytes), Err(VRRPv2Error::InvalidAuthType));
8
e4cad4eba60b Implement a VRRPv2 packet parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 7
diff changeset
   211
}
e4cad4eba60b Implement a VRRPv2 packet parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 7
diff changeset
   212
e4cad4eba60b Implement a VRRPv2 packet parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 7
diff changeset
   213
#[test]
e4cad4eba60b Implement a VRRPv2 packet parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 7
diff changeset
   214
fn test_invalid_checksum() {
10
aef7eb135a0c Validate checksum.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 8
diff changeset
   215
    let bytes = [
aef7eb135a0c Validate checksum.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 8
diff changeset
   216
        0x21, 0x01, 0x64, 0x01, 0x00, 0x01, 0xbb, 0x52, 0xc0, 0xa8, 0x00, 0x01, 0x00, 0x00, 0x00,
aef7eb135a0c Validate checksum.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 8
diff changeset
   217
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
aef7eb135a0c Validate checksum.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 8
diff changeset
   218
    ];
16
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
   219
    assert_eq!(from_bytes(&bytes), Err(VRRPv2Error::InvalidChecksum));
8
e4cad4eba60b Implement a VRRPv2 packet parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 7
diff changeset
   220
}
17
90d097c9ea62 Rectify checksum calculation.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 16
diff changeset
   221
90d097c9ea62 Rectify checksum calculation.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 16
diff changeset
   222
#[test]
90d097c9ea62 Rectify checksum calculation.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 16
diff changeset
   223
fn test_checksum() {
90d097c9ea62 Rectify checksum calculation.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 16
diff changeset
   224
    let bytes = [0x00, 0x01, 0xf2, 0x03, 0xf4, 0xf5, 0xf6, 0xf7];
90d097c9ea62 Rectify checksum calculation.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 16
diff changeset
   225
    assert_eq!(checksum(&bytes), 0x220d);
90d097c9ea62 Rectify checksum calculation.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 16
diff changeset
   226
}
90d097c9ea62 Rectify checksum calculation.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 16
diff changeset
   227
90d097c9ea62 Rectify checksum calculation.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 16
diff changeset
   228
#[test]
90d097c9ea62 Rectify checksum calculation.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 16
diff changeset
   229
fn test_checksum_singlebyte() {
90d097c9ea62 Rectify checksum calculation.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 16
diff changeset
   230
    let bytes = [0; 1];
90d097c9ea62 Rectify checksum calculation.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 16
diff changeset
   231
    assert_eq!(checksum(&bytes), 0xffff);
90d097c9ea62 Rectify checksum calculation.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 16
diff changeset
   232
}
90d097c9ea62 Rectify checksum calculation.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 16
diff changeset
   233
90d097c9ea62 Rectify checksum calculation.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 16
diff changeset
   234
#[test]
90d097c9ea62 Rectify checksum calculation.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 16
diff changeset
   235
fn test_checksum_twobytes() {
90d097c9ea62 Rectify checksum calculation.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 16
diff changeset
   236
    let bytes = [0x00, 0xff];
90d097c9ea62 Rectify checksum calculation.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 16
diff changeset
   237
    assert_eq!(checksum(&bytes), 0xff00);
90d097c9ea62 Rectify checksum calculation.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 16
diff changeset
   238
}
90d097c9ea62 Rectify checksum calculation.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 16
diff changeset
   239
90d097c9ea62 Rectify checksum calculation.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 16
diff changeset
   240
#[test]
90d097c9ea62 Rectify checksum calculation.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 16
diff changeset
   241
fn test_checksum_another() {
90d097c9ea62 Rectify checksum calculation.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 16
diff changeset
   242
    let bytes = [0xe3, 0x4f, 0x23, 0x96, 0x44, 0x27, 0x99, 0xf3];
90d097c9ea62 Rectify checksum calculation.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 16
diff changeset
   243
    assert_eq!(checksum(&bytes), 0x1aff);
90d097c9ea62 Rectify checksum calculation.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 16
diff changeset
   244
}