1#![allow(non_snake_case)]
2#![allow(non_upper_case_globals)]
3#![allow(non_camel_case_types)]
4use super::*;
5use super::mac_addr::mac_addr_t;
6use std::net::{IpAddr};
7use std::fmt;
8use crate::common::errcode;
9
10
11#[derive(Copy, Clone, Eq, PartialEq)]
13pub struct ethernet_packet_info_t {
14 l3_offset: u16, l4_offset: u16, payload_offset:u16,total_len:u16,
18 pub dst_mac: mac_addr_t,
19 pub src_mac: mac_addr_t,
20 pub vlan_layers: u8, pub vlans: [u16; 2],
22 pub ether_type: u16,
23 pub mpls_label: u32,
24 pub arp_op:u16,
25 pub arp_sha: mac_addr_t,
26 pub arp_tha: mac_addr_t,
27 pub ip_hdr_len: u16,
28 pub ip_payload_len: u16,
29 pub ip_ttl: u8,
30 pub src_ip: IpAddr,
31 pub dst_ip: IpAddr,
32 pub ip_proto: u8,
33 pub tp_src: u16, pub tp_dst: u16, }
36
37
38impl ethernet_packet_info_t {
39 pub fn new_zero() -> ethernet_packet_info_t {
40 let info:ethernet_packet_info_t=unsafe { std::mem::zeroed::<ethernet_packet_info_t>() };
41 return info;
42 }
43
44 fn parse_transport(pkt: &[u8], ip_proto: u8, info: &mut ethernet_packet_info_t) {
46 if pkt.len()<UDP_HDR_SIZE {
47 return;
48 }
49 unsafe {
50 match ip_proto {
51 IpProtos::Ip_Proto_TCP => {
52 info.tp_src = ((*pkt.get_unchecked(0) as u16) << 8) + *pkt.get_unchecked(1) as u16;
53 info.tp_dst = ((*pkt.get_unchecked(2) as u16) << 8) + *pkt.get_unchecked(3) as u16;
54 let tcp_hdr_len=((pkt[12] & 0xF0)>>4)*4;
55 info.payload_offset=info.l4_offset+tcp_hdr_len as u16;
56 }
57 IpProtos::Ip_Proto_UDP => {
58 info.tp_src = ((*pkt.get_unchecked(0) as u16) << 8) + *pkt.get_unchecked(1) as u16;
59 info.tp_dst = ((*pkt.get_unchecked(2) as u16) << 8) + *pkt.get_unchecked(3) as u16;
60 info.payload_offset=info.l4_offset+8;
61 },
62 IpProtos::Ip_Proto_SCTP => {
63 info.tp_src = ((*pkt.get_unchecked(0) as u16) << 8) + *pkt.get_unchecked(1) as u16;
64 info.tp_dst = ((*pkt.get_unchecked(2) as u16) << 8) + *pkt.get_unchecked(3) as u16;
65 info.payload_offset=info.l4_offset+12;
66 }
67 _ => (),
68 }
69 }
70 }
71 fn parse_ipv4(ipv4: &[u8], info: &mut ethernet_packet_info_t) {
72 if ipv4.len()<IPV4_HDR_SIZE {
73 return;
74 }
75 let mut cur_idx = 0;
76 unsafe {
77 info.ip_hdr_len = ((*ipv4.get_unchecked(0) & 0x0F) * 4) as u16;
78
79 info.ip_payload_len = ((*ipv4.get_unchecked(2) as u16) << 8) + *ipv4.get_unchecked(3) as u16;
80 if info.ip_hdr_len<IPV4_HDR_SIZE as u16 || info.ip_payload_len>ipv4.len() as u16 {
81 return
82 }
83 info.ip_ttl = *ipv4.get_unchecked(8);
84 info.ip_proto = *ipv4.get_unchecked(9);
85 cur_idx += 12;
86
87 info.src_ip = IpAddr::from([
88 *ipv4.get_unchecked(cur_idx),
89 *ipv4.get_unchecked(cur_idx + 1),
90 *ipv4.get_unchecked(cur_idx + 2),
91 *ipv4.get_unchecked(cur_idx + 3),
92 ]);
93 info.dst_ip = IpAddr::from([
94 *ipv4.get_unchecked(cur_idx + 4),
95 *ipv4.get_unchecked(cur_idx + 5),
96 *ipv4.get_unchecked(cur_idx + 6),
97 *ipv4.get_unchecked(cur_idx + 7),
98 ]);
99 info.l4_offset = info.l3_offset+info.ip_hdr_len;
100 info.payload_offset=info.l4_offset;
101 if ipv4.len()>=info.ip_hdr_len as usize + UDP_HDR_SIZE {
102 Self::parse_transport(&ipv4[info.ip_hdr_len as usize..], info.ip_proto, info);
103 }
104
105 }
106
107 }
108
109 fn parse_ipv6(ipv6: &[u8], info: &mut ethernet_packet_info_t) {
110 if ipv6.len()<IPV6_HDR_SIZE {
111 return;
112 }
113 info.ip_hdr_len = IPV6_HDR_SIZE as u16;
114 info.ip_payload_len = unsafe { ((*ipv6.get_unchecked(4) as u16) << 8) + *ipv6.get_unchecked(5) as u16};
115 if info.ip_payload_len>ipv6.len() as u16 {
116 return
117 }
118 info.ip_proto = ipv6[6];
119 info.ip_ttl = ipv6[7];
120 let mut ipaddr: [u8; 16] = [0; 16];
121 ipaddr.copy_from_slice(&ipv6[8..24]);
122
123 info.src_ip = IpAddr::from(ipaddr);
124 ipaddr.copy_from_slice(&ipv6[24..40]);
125 info.dst_ip = IpAddr::from(ipaddr);
126 info.l4_offset = info.l3_offset+info.ip_hdr_len;
127 info.payload_offset=info.l4_offset;
128 Self::parse_transport(&ipv6[info.ip_hdr_len as usize..], info.ip_proto, info);
129 }
130
131 fn parse_arp(arp: &[u8], info: &mut ethernet_packet_info_t) {
132 if arp.len()<ARP_PACKET_SIZE {
133 return;
134 }
135 info.arp_sha = mac_addr_t::new(arp[8], arp[9], arp[10], arp[11], arp[12], arp[13]);
136 info.arp_tha = mac_addr_t::new(arp[18], arp[19], arp[20], arp[21], arp[22], arp[23]);
137 info.src_ip = IpAddr::from([arp[14],arp[15],arp[16],arp[17]]);
138 info.dst_ip = IpAddr::from([arp[24],arp[25],arp[26],arp[27]]);
139 info.arp_op = ((arp[6] as u16) <<8 )+arp[7] as u16;
140 }
141
142 pub fn from_ethernet_packet(packet: &[u8]) -> Result<Self,errcode::RESULT> {
144 let pkt_len = packet.len();
145 if packet.len()<ETHERNET_HDR_SIZE {
146 return Err(errcode::ERROR_INVALID_MSG);
147 }
148 let mut pkt_info = Self::new_zero();
149 pkt_info.total_len = pkt_len as u16;
150 pkt_info.dst_mac = mac_addr_t::from_slice(packet);
151 pkt_info.src_mac = mac_addr_t::from_slice(&packet[MAC_ADDR_SIZE..]);
152
153 let ether_type: u16 = unsafe { ((*packet.get_unchecked(12) as u16) << 8) + *packet.get_unchecked(13) as u16 };
154 let mut cur_ptr: usize = ETHERNET_HDR_SIZE;
155 unsafe {
156 pkt_info.ether_type = match ether_type {
157 EthernetTypes::Ethernet_Vlan => {
158 if pkt_len<ETHERNET_HDR_SIZE+4 {
159 return Err(errcode::ERROR_INVALID_MSG);
160 }
161 pkt_info.vlan_layers = 1;
162 pkt_info.vlans[0] = ((*packet.get_unchecked(cur_ptr) as u16) << 8) + *packet.get_unchecked(cur_ptr + 1) as u16;
163 cur_ptr += 4;
164 ((*packet.get_unchecked(cur_ptr - 2) as u16) << 8) + *packet.get_unchecked(cur_ptr - 1) as u16
165 }
166 EthernetTypes::Ethernet_SVlan => {
167 if pkt_len<ETHERNET_HDR_SIZE+4*2 {
168 return Err(errcode::ERROR_INVALID_MSG);
169 }
170 pkt_info.vlan_layers = 2;
171 pkt_info.vlans[0] = ((*packet.get_unchecked(cur_ptr) as u16) << 8) + *packet.get_unchecked(cur_ptr + 1) as u16;
172 pkt_info.vlans[1] = ((*packet.get_unchecked(cur_ptr + 4) as u16) << 8) + *packet.get_unchecked(cur_ptr + 5) as u16;
173 cur_ptr += 8;
174 ((*packet.get_unchecked(cur_ptr - 2) as u16) << 8) + *packet.get_unchecked(cur_ptr - 1) as u16
175 }
176 _ => ether_type,
177 };
178 pkt_info.l3_offset = cur_ptr as u16;
179 pkt_info.payload_offset=pkt_info.l3_offset;
180 if cur_ptr>=pkt_len {
181 return Err(errcode::ERROR_INVALID_MSG);
182 }
183 }
184 match pkt_info.ether_type {
185 EthernetTypes::Ethernet_Ipv4 => Self::parse_ipv4(&packet[cur_ptr..], &mut pkt_info),
186 EthernetTypes::Ethernet_Ipv6 => Self::parse_ipv6(&packet[cur_ptr..], &mut pkt_info),
187 EthernetTypes::Ethernet_ARP => Self::parse_arp(&packet[cur_ptr..], &mut pkt_info),
188 _ => (),
189 }
190
191 return Ok(pkt_info);
192 }
193
194 pub fn get_payload_offset(&self)->Result<u16,errcode::RESULT> {
195 if self.payload_offset>0 {
196 return Ok(self.payload_offset)
197 }
198 Err(errcode::ERROR_INVALID_MSG)
199 }
200 pub fn get_l3_hdr_offset(&self)->Result<u16,errcode::RESULT> {
201 return Ok(self.l3_offset)
202 }
203
204 pub fn get_l4_hdr_offset(&self)->Result<u16,errcode::RESULT> {
205 if self.ether_type==EthernetTypes::Ethernet_Ipv4 || self.ether_type==EthernetTypes::Ethernet_Ipv6 {
206 return Ok(self.l4_offset)
207 }
208 Err(errcode::ERROR_INVALID_MSG)
209 }
210
211 pub fn to_string(&self)->String {
212 format!("total_len={},ether_type={:#x},src_mac={},dst_mac={},vlan={},
213 ip_hdr_len={},src_ip={},dst_ip={},ip_proto={},ip_payload_len={},tp_src={},tp_dst={}",
214 self.total_len,self.ether_type,self.src_mac,self.dst_mac,self.vlans[0],
215 self.ip_hdr_len,self.src_ip, self.dst_ip,self.ip_proto,self.ip_payload_len,
216 self.tp_src,self.tp_dst)
217 }
218
219}
220
221impl fmt::Display for ethernet_packet_info_t {
222 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
223 write!(f,"total_len={},ether_type={:#x},src_mac={},dst_mac={},vlan={},
224 ip_hdr_len={},src_ip={},dst_ip={},ip_proto={},ip_payload_len={},tp_src={},tp_dst={}",
225 self.total_len,self.ether_type,self.src_mac,self.dst_mac,self.vlans[0],
226 self.ip_hdr_len,self.src_ip, self.dst_ip,self.ip_proto,self.ip_payload_len,
227 self.tp_src,self.tp_dst)
228 }
229}