net_parser_rs/layer3/
arp.rs1use crate::Error;
2use crate::common::{MacAddress, MAC_LENGTH};
3
4use arrayref::array_ref;
5use nom::*;
6
7#[derive(Clone, Copy, Debug)]
8pub struct Arp {
9 pub sender_ip: std::net::IpAddr,
10 pub sender_mac: MacAddress,
11 pub target_ip: std::net::IpAddr,
12 pub target_mac: MacAddress,
13 pub operation: u16,
14}
15
16const ADDRESS_LENGTH: usize = 4;
17fn to_ip_address(i: &[u8]) -> std::net::IpAddr {
18 let ipv4 = std::net::Ipv4Addr::from(array_ref![i, 0, ADDRESS_LENGTH].clone());
19 std::net::IpAddr::V4(ipv4)
20}
21
22named!(
23 ipv4_address<&[u8], std::net::IpAddr>,
24 map!(take!(ADDRESS_LENGTH), to_ip_address)
25);
26
27fn to_mac_address(i: &[u8]) -> MacAddress {
28 let mac_addr = MacAddress(array_ref![i, 0, MAC_LENGTH].clone());
29 mac_addr
30}
31
32named!(
33 mac_address<MacAddress>,
34 map!(take!(MAC_LENGTH), to_mac_address)
35);
36
37impl Arp {
38 pub fn new(
39 sender_ip: std::net::Ipv4Addr,
40 sender_mac: [u8; MAC_LENGTH],
41 target_ip: std::net::Ipv4Addr,
42 target_mac: [u8; MAC_LENGTH],
43 operation: u16,
44 ) -> Arp {
45 Arp {
46 sender_ip: std::net::IpAddr::V4(sender_ip),
47 sender_mac: MacAddress(sender_mac),
48 target_ip: std::net::IpAddr::V4(target_ip),
49 target_mac: MacAddress(target_mac),
50 operation,
51 }
52 }
53
54 pub fn parse(input: &[u8]) -> Result<(&[u8], Arp), Error> {
55 do_parse!(
56 input,
57 _hardware_type: be_u16 >>
58 _protocol_type: be_u16 >>
59 _hardware_address_length: be_u8 >>
60 _protocol_address_length: be_u8 >>
61 operation: be_u16 >>
62 sender_hardware_address: mac_address >> sender_protocol_address: ipv4_address >> target_hardware_address: mac_address >>
65 target_protocol_address: ipv4_address >>
66 (
67 Arp {
68 sender_ip: sender_protocol_address,
69 sender_mac: sender_hardware_address,
70 target_ip: target_protocol_address,
71 target_mac: target_hardware_address,
72 operation: operation
73 }
74 )
75 ).map_err(Error::from)
76 }
77}
78
79#[cfg(test)]
80mod tests {
81 use super::*;
82
83 const RAW_DATA: &'static [u8] = &[
84 0x00u8, 0x01u8, 0x08u8, 0x00u8, 0x06u8, 0x04u8, 0x00u8, 0x01u8, 0x00u8, 0x0au8, 0xdcu8, 0x64u8, 0x85u8, 0xc2u8, 0xc0u8, 0xa8u8, 0x59u8, 0x01u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0xc0u8, 0xa8u8, 0x59u8, 0x02u8, ];
95
96 #[test]
97 fn parse_arp() {
98 let (rem, l3) = Arp::parse(RAW_DATA).expect("Unable to parse");
99
100 assert!(rem.is_empty());
101 assert_eq!(
102 l3.sender_ip,
103 "192.168.89.1"
104 .parse::<std::net::IpAddr>()
105 .expect("Could not parse ip address")
106 );
107 assert_eq!(
108 format!("{}", l3.sender_mac),
109 "00:0a:dc:64:85:c2".to_string()
110 );
111 assert_eq!(
112 l3.target_ip,
113 "192.168.89.2"
114 .parse::<std::net::IpAddr>()
115 .expect("Could not parse ip address")
116 );
117 assert_eq!(
118 format!("{}", l3.target_mac),
119 "00:00:00:00:00:00".to_string()
120 );
121 assert_eq!(l3.operation, 1u16);
122 }
123}