1use crate::net::MacAddr;
22use crate::packets::types::u16be;
23use crate::packets::{EtherTypes, Ethernet, Internal, Packet};
24use crate::{ensure, SizeOf};
25use anyhow::{anyhow, Result};
26use std::fmt;
27use std::net::Ipv4Addr;
28use std::ptr::NonNull;
29
30pub struct Arp<H: HardwareAddr, P: ProtocolAddr> {
87 envelope: Ethernet,
88 header: NonNull<ArpHeader<H, P>>,
89 offset: usize,
90}
91
92impl<H: HardwareAddr, P: ProtocolAddr> Arp<H, P> {
93 #[inline]
94 fn header(&self) -> &ArpHeader<H, P> {
95 unsafe { self.header.as_ref() }
96 }
97
98 #[inline]
99 fn header_mut(&mut self) -> &mut ArpHeader<H, P> {
100 unsafe { self.header.as_mut() }
101 }
102
103 #[inline]
105 pub fn hardware_type(&self) -> HardwareType {
106 HardwareType::new(self.header().hardware_type.into())
107 }
108
109 #[inline]
111 fn set_hardware_type(&mut self, hardware_type: HardwareType) {
112 self.header_mut().hardware_type = hardware_type.0.into()
113 }
114
115 #[inline]
117 pub fn protocol_type(&self) -> ProtocolType {
118 ProtocolType::new(self.header().protocol_type.into())
119 }
120
121 #[inline]
123 fn set_protocol_type(&mut self, protocol_type: ProtocolType) {
124 self.header_mut().protocol_type = protocol_type.0.into()
125 }
126
127 #[inline]
129 pub fn hardware_addr_len(&self) -> u8 {
130 self.header().hardware_addr_len
131 }
132
133 #[inline]
135 fn set_hardware_addr_len(&mut self, len: u8) {
136 self.header_mut().hardware_addr_len = len
137 }
138
139 #[inline]
141 pub fn protocol_addr_len(&self) -> u8 {
142 self.header().protocol_addr_len
143 }
144
145 #[inline]
147 fn set_protocol_addr_len(&mut self, len: u8) {
148 self.header_mut().protocol_addr_len = len
149 }
150
151 #[inline]
153 pub fn operation_code(&self) -> OperationCode {
154 OperationCode::new(self.header().operation_code.into())
155 }
156
157 #[inline]
159 pub fn set_operation_code(&mut self, code: OperationCode) {
160 self.header_mut().operation_code = code.0.into()
161 }
162
163 #[inline]
165 pub fn sender_hardware_addr(&self) -> H {
166 self.header().sender_hardware_addr
167 }
168
169 #[inline]
171 pub fn set_sender_hardware_addr(&mut self, addr: H) {
172 self.header_mut().sender_hardware_addr = addr
173 }
174
175 #[inline]
177 pub fn sender_protocol_addr(&self) -> P {
178 self.header().sender_protocol_addr
179 }
180
181 #[inline]
183 pub fn set_sender_protocol_addr(&mut self, addr: P) {
184 self.header_mut().sender_protocol_addr = addr
185 }
186
187 #[inline]
189 pub fn target_hardware_addr(&self) -> H {
190 self.header().target_hardware_addr
191 }
192
193 #[inline]
195 pub fn set_target_hardware_addr(&mut self, addr: H) {
196 self.header_mut().target_hardware_addr = addr
197 }
198
199 #[inline]
201 pub fn target_protocol_addr(&self) -> P {
202 self.header().target_protocol_addr
203 }
204
205 #[inline]
207 pub fn set_target_protocol_addr(&mut self, addr: P) {
208 self.header_mut().target_protocol_addr = addr
209 }
210}
211
212impl<H: HardwareAddr, P: ProtocolAddr> fmt::Debug for Arp<H, P> {
213 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
214 f.debug_struct("arp")
215 .field("hardware_type", &format!("{}", self.hardware_type()))
216 .field("protocol_type", &format!("{}", self.protocol_type()))
217 .field("hardware_addr_len", &self.hardware_addr_len())
218 .field("protocol_addr_len", &self.protocol_addr_len())
219 .field("operation_code", &format!("{}", self.operation_code()))
220 .field(
221 "sender_hardware_addr",
222 &format!("{}", self.sender_hardware_addr()),
223 )
224 .field(
225 "sender_protocol_addr",
226 &format!("{}", self.sender_protocol_addr()),
227 )
228 .field(
229 "target_hardware_addr",
230 &format!("{}", self.target_hardware_addr()),
231 )
232 .field(
233 "target_protocol_addr",
234 &format!("{}", self.target_protocol_addr()),
235 )
236 .field("$offset", &self.offset())
237 .field("$len", &self.len())
238 .field("$header_len", &self.header_len())
239 .finish()
240 }
241}
242
243impl<H: HardwareAddr, P: ProtocolAddr> Packet for Arp<H, P> {
244 type Envelope = Ethernet;
246
247 #[inline]
248 fn envelope(&self) -> &Self::Envelope {
249 &self.envelope
250 }
251
252 #[inline]
253 fn envelope_mut(&mut self) -> &mut Self::Envelope {
254 &mut self.envelope
255 }
256
257 #[inline]
258 fn offset(&self) -> usize {
259 self.offset
260 }
261
262 #[inline]
263 fn header_len(&self) -> usize {
264 ArpHeader::<H, P>::size_of()
265 }
266
267 #[inline]
268 unsafe fn clone(&self, internal: Internal) -> Self {
269 Arp {
270 envelope: self.envelope.clone(internal),
271 header: self.header,
272 offset: self.offset,
273 }
274 }
275
276 #[inline]
292 fn try_parse(envelope: Self::Envelope, _internal: Internal) -> Result<Self> {
293 ensure!(
294 envelope.ether_type() == EtherTypes::Arp,
295 anyhow!("not an ARP packet.")
296 );
297
298 let mbuf = envelope.mbuf();
299 let offset = envelope.payload_offset();
300 let header = mbuf.read_data(offset)?;
301
302 let packet = Arp {
303 envelope,
304 header,
305 offset,
306 };
307
308 ensure!(
309 packet.hardware_type() == H::addr_type(),
310 anyhow!(
311 "hardware type {} does not match expected {}.",
312 packet.hardware_type(),
313 H::addr_type()
314 )
315 );
316 ensure!(
317 packet.protocol_type() == P::addr_type(),
318 anyhow!(
319 "protocol type {} does not match expected {}.",
320 packet.protocol_type(),
321 P::addr_type()
322 )
323 );
324 ensure!(
325 packet.hardware_addr_len() == H::size_of() as u8,
326 anyhow!(
327 "hardware address length {} does not match expected {}.",
328 packet.hardware_addr_len(),
329 H::size_of()
330 )
331 );
332 ensure!(
333 packet.protocol_addr_len() == P::size_of() as u8,
334 anyhow!(
335 "protocol address length {} does not match expected {}.",
336 packet.protocol_addr_len(),
337 P::size_of()
338 )
339 );
340
341 Ok(packet)
342 }
343
344 #[inline]
357 fn try_push(mut envelope: Self::Envelope, _internal: Internal) -> Result<Self> {
358 let offset = envelope.payload_offset();
359 let mbuf = envelope.mbuf_mut();
360
361 mbuf.extend(offset, ArpHeader::<H, P>::size_of())?;
362 let header = mbuf.write_data(offset, &ArpHeader::<H, P>::default())?;
363
364 envelope.set_ether_type(EtherTypes::Arp);
365
366 let mut packet = Arp {
367 envelope,
368 header,
369 offset,
370 };
371
372 packet.set_hardware_type(H::addr_type());
373 packet.set_protocol_type(P::addr_type());
374 packet.set_hardware_addr_len(H::size_of() as u8);
375 packet.set_protocol_addr_len(P::size_of() as u8);
376
377 Ok(packet)
378 }
379
380 #[inline]
381 fn deparse(self) -> Self::Envelope {
382 self.envelope
383 }
384}
385
386#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
393#[repr(C, packed)]
394pub struct HardwareType(u16);
395
396impl HardwareType {
397 pub fn new(value: u16) -> Self {
399 HardwareType(value)
400 }
401}
402
403#[allow(non_snake_case)]
405#[allow(non_upper_case_globals)]
406pub mod HardwareTypes {
407 use super::HardwareType;
408
409 pub const Ethernet: HardwareType = HardwareType(0x0001);
411}
412
413impl fmt::Display for HardwareType {
414 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
415 write!(
416 f,
417 "{}",
418 match *self {
419 HardwareTypes::Ethernet => "Ethernet".to_string(),
420 _ => {
421 let t = self.0;
422 format!("0x{:04x}", t)
423 }
424 }
425 )
426 }
427}
428
429#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
436#[repr(C, packed)]
437pub struct ProtocolType(u16);
438
439impl ProtocolType {
440 pub fn new(value: u16) -> Self {
442 ProtocolType(value)
443 }
444}
445
446#[allow(non_snake_case)]
448#[allow(non_upper_case_globals)]
449pub mod ProtocolTypes {
450 use super::ProtocolType;
451
452 pub const Ipv4: ProtocolType = ProtocolType(0x0800);
454}
455
456impl fmt::Display for ProtocolType {
457 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
458 write!(
459 f,
460 "{}",
461 match *self {
462 ProtocolTypes::Ipv4 => "IPv4".to_string(),
463 _ => {
464 let t = self.0;
465 format!("0x{:04x}", t)
466 }
467 }
468 )
469 }
470}
471
472#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
479#[repr(C, packed)]
480pub struct OperationCode(u16);
481
482impl OperationCode {
483 pub fn new(value: u16) -> Self {
485 OperationCode(value)
486 }
487}
488
489#[allow(non_snake_case)]
491#[allow(non_upper_case_globals)]
492pub mod OperationCodes {
493 use super::OperationCode;
494
495 pub const Request: OperationCode = OperationCode(1);
497 pub const Reply: OperationCode = OperationCode(2);
499 pub const RequestReverse: OperationCode = OperationCode(3);
501 pub const ReplyReverse: OperationCode = OperationCode(4);
503}
504
505impl fmt::Display for OperationCode {
506 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
507 write!(
508 f,
509 "{}",
510 match *self {
511 OperationCodes::Request => "Request".to_string(),
512 OperationCodes::Reply => "Reply".to_string(),
513 OperationCodes::RequestReverse => "Request reverse".to_string(),
514 OperationCodes::ReplyReverse => "Reply reverse".to_string(),
515 _ => {
516 let t = self.0;
517 format!("0x{:04x}", t)
518 }
519 }
520 )
521 }
522}
523
524pub trait HardwareAddr: SizeOf + Copy + fmt::Display {
526 fn addr_type() -> HardwareType;
528
529 fn default() -> Self;
534}
535
536impl SizeOf for MacAddr {
537 fn size_of() -> usize {
538 6
539 }
540}
541
542impl HardwareAddr for MacAddr {
543 fn addr_type() -> HardwareType {
544 HardwareTypes::Ethernet
545 }
546
547 fn default() -> Self {
548 Default::default()
549 }
550}
551
552pub trait ProtocolAddr: SizeOf + Copy + fmt::Display {
554 fn addr_type() -> ProtocolType;
556
557 fn default() -> Self;
562}
563
564impl SizeOf for Ipv4Addr {
565 fn size_of() -> usize {
566 4
567 }
568}
569
570impl ProtocolAddr for Ipv4Addr {
571 fn addr_type() -> ProtocolType {
572 ProtocolTypes::Ipv4
573 }
574
575 fn default() -> Self {
576 Ipv4Addr::UNSPECIFIED
577 }
578}
579
580pub type Arp4 = Arp<MacAddr, Ipv4Addr>;
582
583#[allow(missing_debug_implementations)]
585#[derive(Copy, SizeOf)]
586#[repr(C, packed)]
587struct ArpHeader<H: HardwareAddr, P: ProtocolAddr> {
588 hardware_type: u16be,
589 protocol_type: u16be,
590 hardware_addr_len: u8,
591 protocol_addr_len: u8,
592 operation_code: u16be,
593 sender_hardware_addr: H,
594 sender_protocol_addr: P,
595 target_hardware_addr: H,
596 target_protocol_addr: P,
597}
598
599impl<H: HardwareAddr, P: ProtocolAddr> Clone for ArpHeader<H, P> {
600 fn clone(&self) -> Self {
601 ArpHeader {
602 hardware_type: self.hardware_type,
603 protocol_type: self.protocol_type,
604 hardware_addr_len: self.hardware_addr_len,
605 protocol_addr_len: self.protocol_addr_len,
606 operation_code: self.operation_code,
607 sender_hardware_addr: self.sender_hardware_addr,
608 sender_protocol_addr: self.sender_protocol_addr,
609 target_hardware_addr: self.target_hardware_addr,
610 target_protocol_addr: self.target_protocol_addr,
611 }
612 }
613}
614
615impl<H: HardwareAddr, P: ProtocolAddr> Default for ArpHeader<H, P> {
616 fn default() -> Self {
617 ArpHeader {
618 hardware_type: u16be::default(),
619 protocol_type: u16be::default(),
620 hardware_addr_len: 0,
621 protocol_addr_len: 0,
622 operation_code: u16be::default(),
623 sender_hardware_addr: H::default(),
624 sender_protocol_addr: P::default(),
625 target_hardware_addr: H::default(),
626 target_protocol_addr: P::default(),
627 }
628 }
629}
630
631#[cfg(test)]
632mod tests {
633 use super::*;
634 use crate::testils::byte_arrays::ARP4_PACKET;
635 use crate::Mbuf;
636
637 #[test]
638 fn size_of_arp_header() {
639 assert_eq!(28, ArpHeader::<MacAddr, Ipv4Addr>::size_of());
640 }
641
642 #[capsule::test]
643 fn parse_arp_packet() {
644 let packet = Mbuf::from_bytes(&ARP4_PACKET).unwrap();
645 let ethernet = packet.parse::<Ethernet>().unwrap();
646 let arp4 = ethernet.parse::<Arp4>().unwrap();
647
648 assert_eq!(HardwareTypes::Ethernet, arp4.hardware_type());
649 assert_eq!(ProtocolTypes::Ipv4, arp4.protocol_type());
650 assert_eq!(6, arp4.hardware_addr_len());
651 assert_eq!(4, arp4.protocol_addr_len());
652 assert_eq!(OperationCodes::Request, arp4.operation_code());
653 assert_eq!("00:00:00:00:00:01", arp4.sender_hardware_addr().to_string());
654 assert_eq!("139.133.217.110", arp4.sender_protocol_addr().to_string());
655 assert_eq!("00:00:00:00:00:00", arp4.target_hardware_addr().to_string());
656 assert_eq!("139.133.233.2", arp4.target_protocol_addr().to_string());
657 }
658
659 #[capsule::test]
660 fn push_arp_packet() {
661 let packet = Mbuf::new().unwrap();
662 let ethernet = packet.push::<Ethernet>().unwrap();
663 let mut arp4 = ethernet.push::<Arp4>().unwrap();
664
665 assert_eq!(ArpHeader::<MacAddr, Ipv4Addr>::size_of(), arp4.len());
666
667 assert_eq!(HardwareTypes::Ethernet, arp4.hardware_type());
669 assert_eq!(ProtocolTypes::Ipv4, arp4.protocol_type());
670 assert_eq!(6, arp4.hardware_addr_len());
671 assert_eq!(4, arp4.protocol_addr_len());
672
673 arp4.set_operation_code(OperationCodes::Reply);
675 assert_eq!(OperationCodes::Reply, arp4.operation_code());
676 arp4.set_sender_hardware_addr(MacAddr::new(0, 0, 0, 0, 0, 1));
677 assert_eq!("00:00:00:00:00:01", arp4.sender_hardware_addr().to_string());
678 arp4.set_sender_protocol_addr(Ipv4Addr::new(10, 0, 0, 1));
679 assert_eq!("10.0.0.1", arp4.sender_protocol_addr().to_string());
680 arp4.set_target_hardware_addr(MacAddr::new(0, 0, 0, 0, 0, 2));
681 assert_eq!("00:00:00:00:00:02", arp4.target_hardware_addr().to_string());
682 arp4.set_target_protocol_addr(Ipv4Addr::new(10, 0, 0, 2));
683 assert_eq!("10.0.0.2", arp4.target_protocol_addr().to_string());
684
685 assert_eq!(EtherTypes::Arp, arp4.envelope().ether_type());
687 }
688}