src/vrrpv2.rs
author Sunil Nimmagadda <sunil@nimmagadda.net>
Wed, 17 Jan 2024 15:23:51 +0530
changeset 20 fd3474f42783
parent 19 1567e8a5a0cb
child 21 17afb5ba9c2b
permissions -rw-r--r--
Replace nom with std::io::Cursor std::io::Cursor suffices to parse the packet.
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 {
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
    86
        return Err(VRRPv2Error::InvalidVersion);
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 {
16
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
    89
        return Err(VRRPv2Error::InvalidType);
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
    };
20
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
   115
    let mut ip_addrs = Vec::new();
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 {
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
   167
    let mut sum: u32 = 0;
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
   168
    for chunk in bytes.chunks(2) {
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
   169
        // Left over byte if any
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
   170
        if chunk.len() == 1 {
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
   171
            sum += u32::from(chunk[0]);
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
   172
        } else {
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
   173
            sum += u32::from(u16::from_be_bytes(chunk.try_into().unwrap()));
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
   174
        }
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
   175
    }
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
   176
    while (sum >> 16) > 0 {
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
   177
        sum = (sum & 0xffff) + (sum >> 16);
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
    !(sum as u16)
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
   180
}
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
   181
8
e4cad4eba60b Implement a VRRPv2 packet parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 7
diff changeset
   182
#[test]
e4cad4eba60b Implement a VRRPv2 packet parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 7
diff changeset
   183
fn test_incomplete_bytes() {
e4cad4eba60b Implement a VRRPv2 packet parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 7
diff changeset
   184
    let bytes = [0x21, 0x01];
16
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
   185
    assert_eq!(from_bytes(&bytes), Err(VRRPv2Error::ParseError));
8
e4cad4eba60b Implement a VRRPv2 packet parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 7
diff changeset
   186
}
e4cad4eba60b Implement a VRRPv2 packet parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 7
diff changeset
   187
e4cad4eba60b Implement a VRRPv2 packet parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 7
diff changeset
   188
#[test]
16
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
   189
fn test_invalid_version() {
8
e4cad4eba60b Implement a VRRPv2 packet parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 7
diff changeset
   190
    let bytes = [
20
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
   191
        0x20, 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
   192
        0x0, 0x0, 0x0,
8
e4cad4eba60b Implement a VRRPv2 packet parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 7
diff changeset
   193
    ];
18
2470a15711b1 Fix clippy warnings.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 17
diff changeset
   194
    assert_eq!(from_bytes(&bytes), Err(VRRPv2Error::InvalidVersion));
16
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
   195
}
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
   196
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
   197
#[test]
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
   198
fn test_invalid_type() {
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
   199
    let bytes = [
20
fd3474f42783 Replace nom with std::io::Cursor
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 19
diff changeset
   200
        0x31, 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
   201
        0x0, 0x0, 0x0,
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
   202
    ];
18
2470a15711b1 Fix clippy warnings.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 17
diff changeset
   203
    assert_eq!(from_bytes(&bytes), Err(VRRPv2Error::InvalidType));
8
e4cad4eba60b Implement a VRRPv2 packet parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 7
diff changeset
   204
}
e4cad4eba60b Implement a VRRPv2 packet parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 7
diff changeset
   205
e4cad4eba60b Implement a VRRPv2 packet parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 7
diff changeset
   206
#[test]
e4cad4eba60b Implement a VRRPv2 packet parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 7
diff changeset
   207
fn test_invalid_auth_type() {
e4cad4eba60b Implement a VRRPv2 packet parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 7
diff changeset
   208
    let bytes = [
e4cad4eba60b Implement a VRRPv2 packet parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 7
diff changeset
   209
        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
   210
        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
   211
    ];
16
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
   212
    assert_eq!(from_bytes(&bytes), Err(VRRPv2Error::InvalidAuthType));
8
e4cad4eba60b Implement a VRRPv2 packet parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 7
diff changeset
   213
}
e4cad4eba60b Implement a VRRPv2 packet parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 7
diff changeset
   214
e4cad4eba60b Implement a VRRPv2 packet parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 7
diff changeset
   215
#[test]
e4cad4eba60b Implement a VRRPv2 packet parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 7
diff changeset
   216
fn test_invalid_checksum() {
10
aef7eb135a0c Validate checksum.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 8
diff changeset
   217
    let bytes = [
aef7eb135a0c Validate checksum.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 8
diff changeset
   218
        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
   219
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
aef7eb135a0c Validate checksum.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 8
diff changeset
   220
    ];
16
8c8be538d0e6 Refactor parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 13
diff changeset
   221
    assert_eq!(from_bytes(&bytes), Err(VRRPv2Error::InvalidChecksum));
8
e4cad4eba60b Implement a VRRPv2 packet parser.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 7
diff changeset
   222
}
17
90d097c9ea62 Rectify checksum calculation.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 16
diff changeset
   223
90d097c9ea62 Rectify checksum calculation.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 16
diff changeset
   224
#[test]
90d097c9ea62 Rectify checksum calculation.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 16
diff changeset
   225
fn test_checksum() {
90d097c9ea62 Rectify checksum calculation.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 16
diff changeset
   226
    let bytes = [0x00, 0x01, 0xf2, 0x03, 0xf4, 0xf5, 0xf6, 0xf7];
90d097c9ea62 Rectify checksum calculation.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 16
diff changeset
   227
    assert_eq!(checksum(&bytes), 0x220d);
90d097c9ea62 Rectify checksum calculation.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 16
diff changeset
   228
}
90d097c9ea62 Rectify checksum calculation.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 16
diff changeset
   229
90d097c9ea62 Rectify checksum calculation.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 16
diff changeset
   230
#[test]
90d097c9ea62 Rectify checksum calculation.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 16
diff changeset
   231
fn test_checksum_singlebyte() {
90d097c9ea62 Rectify checksum calculation.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 16
diff changeset
   232
    let bytes = [0; 1];
90d097c9ea62 Rectify checksum calculation.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 16
diff changeset
   233
    assert_eq!(checksum(&bytes), 0xffff);
90d097c9ea62 Rectify checksum calculation.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 16
diff changeset
   234
}
90d097c9ea62 Rectify checksum calculation.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 16
diff changeset
   235
90d097c9ea62 Rectify checksum calculation.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 16
diff changeset
   236
#[test]
90d097c9ea62 Rectify checksum calculation.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 16
diff changeset
   237
fn test_checksum_twobytes() {
90d097c9ea62 Rectify checksum calculation.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 16
diff changeset
   238
    let bytes = [0x00, 0xff];
90d097c9ea62 Rectify checksum calculation.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 16
diff changeset
   239
    assert_eq!(checksum(&bytes), 0xff00);
90d097c9ea62 Rectify checksum calculation.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 16
diff changeset
   240
}
90d097c9ea62 Rectify checksum calculation.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 16
diff changeset
   241
90d097c9ea62 Rectify checksum calculation.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 16
diff changeset
   242
#[test]
90d097c9ea62 Rectify checksum calculation.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 16
diff changeset
   243
fn test_checksum_another() {
90d097c9ea62 Rectify checksum calculation.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 16
diff changeset
   244
    let bytes = [0xe3, 0x4f, 0x23, 0x96, 0x44, 0x27, 0x99, 0xf3];
90d097c9ea62 Rectify checksum calculation.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 16
diff changeset
   245
    assert_eq!(checksum(&bytes), 0x1aff);
90d097c9ea62 Rectify checksum calculation.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 16
diff changeset
   246
}