1#![allow(non_camel_case_types)]
2#![allow(non_snake_case)]
3#![allow(non_upper_case_globals)]
4
5use super::*;
6use super::mac_addr::mac_addr_t;
7use std::{net::Ipv4Addr};
8
9pub mod ArpOperation {
10 pub const ARP_OP_REQ:u16 = 1;
11 pub const ARP_OP_RESP:u16 = 2;
12 pub const ARP_OP_REQ_REVERSE:u16 = 3;
13 pub const ARP_OP_RESP_REVERSE:u16 = 4;
14}
15pub mod ArpHardwareTypes {
16 pub const HARDWARE_ETHERNET:u16=1;
17 pub const HARDWARE_IEEE802:u16=6;
18 pub const HARDWARE_HDLC:u16=17;
19
20}
21#[derive(Clone)]
22pub struct Arp {
23 pub dst_mac:mac_addr_t,
24 pub src_mac:mac_addr_t,
25 pub ethernet_type:u16,
26 pub vlan_id:u16,
27 pub hardware_type: u16,
28 pub protocol_type: u16,
29 pub hw_addr_len: u8,
30 pub proto_addr_len: u8,
31 pub operation: u16,
32 pub arp_sha: mac_addr_t,
33 pub arp_spa: Ipv4Addr,
34 pub arp_tha: mac_addr_t,
35 pub arp_tpa: Ipv4Addr,
36}
37
38impl Arp {
39 pub fn from_packet(pkt:&[u8])->Option<Arp> {
41 if pkt.len()< ARP_PACKET_SIZE+ETHERNET_HDR_SIZE {
42 return None;
43 }
44 let mut arp_pkt = Self::new(ArpOperation::ARP_OP_REQ,&mac_addr_t::new_broadcast(),&mac_addr_t::new_broadcast());
45 arp_pkt.dst_mac = mac_addr_t::new(
46 pkt[0], pkt[1], pkt[2], pkt[3], pkt[4], pkt[5],
47 );
48 arp_pkt.src_mac = mac_addr_t::new(
49 pkt[6], pkt[7], pkt[8], pkt[9], pkt[10], pkt[11],
50 );
51 let ether_type: u16 = ((pkt[12] as u16) << 8) + pkt[13] as u16;
52 let mut payload_idx = 14;
53 if ether_type == EthernetTypes::Ethernet_Vlan {
54 arp_pkt.vlan_id = ((pkt[14] as u16) << 8) + pkt[15] as u16;
55 arp_pkt.ethernet_type = ((pkt[16] as u16) << 8) + pkt[17] as u16;
56 payload_idx+=4;
57 } else {
58 arp_pkt.ethernet_type = ether_type;
59 }
60 if arp_pkt.ethernet_type!=EthernetTypes::Ethernet_ARP {
61 return None;
62 }
63 Self::parse_arp(&mut arp_pkt, &pkt[payload_idx..]);
64 return Some(arp_pkt);
65
66 }
67 pub fn new(arp_op:u16,dst_mac:&mac_addr_t,src_mac:&mac_addr_t)->Arp {
68 return Arp {
69 dst_mac:dst_mac.clone(),
70 src_mac:src_mac.clone(),
71 ethernet_type:EthernetTypes::Ethernet_ARP,
72 vlan_id:0,
73 hardware_type:ArpHardwareTypes::HARDWARE_ETHERNET,
74 protocol_type:EthernetTypes::Ethernet_Ipv4,
75 hw_addr_len:MAC_ADDR_SIZE as u8,
76 proto_addr_len:IPV4_ADDR_LEN as u8,
77 operation:arp_op,
78 arp_sha:src_mac.clone(),
79 arp_spa:Ipv4Addr::from([0,0,0,0]),
80 arp_tha:dst_mac.clone(),
81 arp_tpa:Ipv4Addr::from([0,0,0,0]),
82 };
83 }
84 pub fn set_tpa(&mut self,ipv4:&Ipv4Addr) {
85 self.arp_tpa = ipv4.clone();
86 }
87
88 pub fn set_spa(&mut self,ipv4:&Ipv4Addr) {
89 self.arp_spa = ipv4.clone();
90 }
91
92 fn parse_arp(arp:&mut Arp,pkt: &[u8]) {
93 if pkt.len()<ARP_PACKET_SIZE {
94 return;
95 }
96 arp.hardware_type = pkt[1] as u16 + ((pkt[0] as u16) << 8);
97 arp.protocol_type = pkt[3] as u16 + ((pkt[2] as u16) << 8);
98 arp.hw_addr_len = pkt[4];
99 arp.proto_addr_len = pkt[5];
100 arp.arp_sha = mac_addr_t::new(pkt[8], pkt[9], pkt[10], pkt[11], pkt[12], pkt[13]);
101 arp.arp_tha = mac_addr_t::new(pkt[18], pkt[19], pkt[20], pkt[21], pkt[22], pkt[23]);
102 arp.arp_spa = Ipv4Addr::from([pkt[14],pkt[15],pkt[16],pkt[17]]);
103 arp.arp_tpa = Ipv4Addr::from([pkt[24],pkt[25],pkt[26],pkt[27]]);
104 arp.operation = ((pkt[6] as u16) <<8 )+pkt[7] as u16;
105 }
106
107 pub fn to_ethernet_packet(&mut self)->Vec<u8> {
109 let mut pVec:Vec<u8>=Vec::new();
110 pVec.extend_from_slice(&self.dst_mac.to_slice());
111 pVec.extend_from_slice(&self.src_mac.to_slice());
112 if self.vlan_id>0 {
113 pVec.extend_from_slice(&EthernetTypes::Ethernet_Vlan.to_be_bytes()[..]);
114 pVec.extend_from_slice(&self.vlan_id.to_be_bytes()[..]);
115 }
116 pVec.extend_from_slice(&self.ethernet_type.to_be_bytes()[..]);
117 pVec.extend_from_slice(&self.generate_arp_payload().as_slice());
118 return pVec;
119 }
120
121 pub fn to_arp_payload(&mut self)->Vec<u8> {
123 return self.generate_arp_payload();
124 }
125 fn generate_arp_payload(&self)->Vec<u8> {
127 let mut pVec:Vec<u8>=Vec::new();
128 pVec.extend_from_slice(&self.hardware_type.to_be_bytes()[..]);
129 pVec.extend_from_slice(&self.protocol_type.to_be_bytes()[..]);
130 pVec.push(self.hw_addr_len);
131 pVec.push(self.proto_addr_len);
132 pVec.extend_from_slice(&self.operation.to_be_bytes()[..]);
133 pVec.extend_from_slice(&self.arp_sha.to_slice());
134 pVec.extend_from_slice(&self.arp_spa.octets()[..]);
135 pVec.extend_from_slice(&self.arp_tha.to_slice());
136 pVec.extend_from_slice(&self.arp_tpa.octets()[..]);
137 return pVec;
138 }
139
140 pub fn is_gratuitous_arp(&self)->bool {
142 return self.operation==ArpOperation::ARP_OP_REQ && self.arp_tpa.eq(&self.arp_spa);
143 }
144 pub fn is_arp_announcement(&self)->bool {
146 return self.operation==ArpOperation::ARP_OP_RESP || self.is_gratuitous_arp()
147 }
148 pub fn is_arp_request(&self)-> bool {
150 return self.operation==ArpOperation::ARP_OP_REQ && !self.is_gratuitous_arp()
151 }
152
153 pub fn to_string(&self)->String {
154 format!("dst_mac:{},src_mac:{},ether_type:{:#02x},vlan_id:{},hardware_type={},proto_type={:#0x},
155 hw_len={},proto_len={},arp_op:{},sha:{},spa:{},tha:{},tpa:{}",
156 self.dst_mac,self.src_mac,self.ethernet_type,self.vlan_id,self.hardware_type,self.protocol_type,
157 self.hw_addr_len,self.proto_addr_len,self.operation,self.arp_sha,self.arp_spa,
158 self.arp_tha,self.arp_tpa)
159 }
160}
161