rust_rsm/net_ext/
arp.rs

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    //从一个完整的以太网报文导入
40    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    //转换成一段EthernetPacket
108    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     //转换成一段EthernetPacket
122     pub fn to_arp_payload(&mut self)->Vec<u8> {
123        return self.generate_arp_payload();
124    }
125    //生成ARP Payload Packet
126    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    //判断是否是免费ARP
141    pub fn is_gratuitous_arp(&self)->bool {
142        return self.operation==ArpOperation::ARP_OP_REQ && self.arp_tpa.eq(&self.arp_spa);
143    }
144    //是否ARP通告,包括响应和免费ARP
145    pub fn is_arp_announcement(&self)->bool {
146        return self.operation==ArpOperation::ARP_OP_RESP || self.is_gratuitous_arp()
147    }
148    //是否普通的ARP请求
149    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