Skip to content

Commit

Permalink
simplify icmp and arp typing
Browse files Browse the repository at this point in the history
  • Loading branch information
drunkirishcoder committed Jan 9, 2022
1 parent c7c9f1d commit b1e9b9d
Show file tree
Hide file tree
Showing 34 changed files with 194 additions and 215 deletions.
63 changes: 30 additions & 33 deletions core/src/packets/arp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ use std::ptr::NonNull;
/// defined by *P Length*.
///
/// [IETF RFC 826]: https://tools.ietf.org/html/rfc826
pub struct Arp<E: Datalink, H: HardwareAddr, P: ProtocolAddr> {
pub struct Arp<E: Datalink = Ethernet, H: HardwareAddr = MacAddr, P: ProtocolAddr = Ipv4Addr> {
envelope: E,
header: NonNull<ArpHeader<H, P>>,
offset: usize,
Expand Down Expand Up @@ -528,9 +528,6 @@ impl ProtocolAddr for Ipv4Addr {
}
}

/// A type alias for an Ethernet IPv4 ARP packet.
pub type Arp4 = Arp<Ethernet, MacAddr, Ipv4Addr>;

/// ARP header.
#[allow(missing_debug_implementations)]
#[derive(Copy, SizeOf)]
Expand Down Expand Up @@ -583,7 +580,7 @@ impl<H: HardwareAddr, P: ProtocolAddr> Default for ArpHeader<H, P> {
mod tests {
use super::*;
use crate::packets::Mbuf;
use crate::testils::byte_arrays::ARP4_PACKET;
use crate::testils::byte_arrays::ARP_PACKET;

#[test]
fn size_of_arp_header() {
Expand All @@ -592,48 +589,48 @@ mod tests {

#[capsule::test]
fn parse_arp_packet() {
let packet = Mbuf::from_bytes(&ARP4_PACKET).unwrap();
let packet = Mbuf::from_bytes(&ARP_PACKET).unwrap();
let ethernet = packet.parse::<Ethernet>().unwrap();
let arp4 = ethernet.parse::<Arp4>().unwrap();
let arp = ethernet.parse::<Arp>().unwrap();

assert_eq!(HardwareTypes::Ethernet, arp4.hardware_type());
assert_eq!(EtherTypes::Ipv4, arp4.protocol_type());
assert_eq!(6, arp4.hardware_addr_len());
assert_eq!(4, arp4.protocol_addr_len());
assert_eq!(OperationCodes::Request, arp4.operation_code());
assert_eq!("00:00:00:00:00:01", arp4.sender_hardware_addr().to_string());
assert_eq!("139.133.217.110", arp4.sender_protocol_addr().to_string());
assert_eq!("00:00:00:00:00:00", arp4.target_hardware_addr().to_string());
assert_eq!("139.133.233.2", arp4.target_protocol_addr().to_string());
assert_eq!(HardwareTypes::Ethernet, arp.hardware_type());
assert_eq!(EtherTypes::Ipv4, arp.protocol_type());
assert_eq!(6, arp.hardware_addr_len());
assert_eq!(4, arp.protocol_addr_len());
assert_eq!(OperationCodes::Request, arp.operation_code());
assert_eq!("00:00:00:00:00:01", arp.sender_hardware_addr().to_string());
assert_eq!("139.133.217.110", arp.sender_protocol_addr().to_string());
assert_eq!("00:00:00:00:00:00", arp.target_hardware_addr().to_string());
assert_eq!("139.133.233.2", arp.target_protocol_addr().to_string());
}

#[capsule::test]
fn push_arp_packet() {
let packet = Mbuf::new().unwrap();
let ethernet = packet.push::<Ethernet>().unwrap();
let mut arp4 = ethernet.push::<Arp4>().unwrap();
let mut arp = ethernet.push::<Arp>().unwrap();

assert_eq!(ArpHeader::<MacAddr, Ipv4Addr>::size_of(), arp4.len());
assert_eq!(ArpHeader::<MacAddr, Ipv4Addr>::size_of(), arp.len());

// make sure types are set properly
assert_eq!(HardwareTypes::Ethernet, arp4.hardware_type());
assert_eq!(EtherTypes::Ipv4, arp4.protocol_type());
assert_eq!(6, arp4.hardware_addr_len());
assert_eq!(4, arp4.protocol_addr_len());
assert_eq!(HardwareTypes::Ethernet, arp.hardware_type());
assert_eq!(EtherTypes::Ipv4, arp.protocol_type());
assert_eq!(6, arp.hardware_addr_len());
assert_eq!(4, arp.protocol_addr_len());

// check the setters
arp4.set_operation_code(OperationCodes::Reply);
assert_eq!(OperationCodes::Reply, arp4.operation_code());
arp4.set_sender_hardware_addr(MacAddr::new(0, 0, 0, 0, 0, 1));
assert_eq!("00:00:00:00:00:01", arp4.sender_hardware_addr().to_string());
arp4.set_sender_protocol_addr(Ipv4Addr::new(10, 0, 0, 1));
assert_eq!("10.0.0.1", arp4.sender_protocol_addr().to_string());
arp4.set_target_hardware_addr(MacAddr::new(0, 0, 0, 0, 0, 2));
assert_eq!("00:00:00:00:00:02", arp4.target_hardware_addr().to_string());
arp4.set_target_protocol_addr(Ipv4Addr::new(10, 0, 0, 2));
assert_eq!("10.0.0.2", arp4.target_protocol_addr().to_string());
arp.set_operation_code(OperationCodes::Reply);
assert_eq!(OperationCodes::Reply, arp.operation_code());
arp.set_sender_hardware_addr(MacAddr::new(0, 0, 0, 0, 0, 1));
assert_eq!("00:00:00:00:00:01", arp.sender_hardware_addr().to_string());
arp.set_sender_protocol_addr(Ipv4Addr::new(10, 0, 0, 1));
assert_eq!("10.0.0.1", arp.sender_protocol_addr().to_string());
arp.set_target_hardware_addr(MacAddr::new(0, 0, 0, 0, 0, 2));
assert_eq!("00:00:00:00:00:02", arp.target_hardware_addr().to_string());
arp.set_target_protocol_addr(Ipv4Addr::new(10, 0, 0, 2));
assert_eq!("10.0.0.2", arp.target_protocol_addr().to_string());

// make sure the ether type is fixed
assert_eq!(EtherTypes::Arp, arp4.envelope().ether_type());
assert_eq!(EtherTypes::Arp, arp.envelope().ether_type());
}
}
6 changes: 3 additions & 3 deletions core/src/packets/ethernet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,7 @@ impl SizeOf for EthernetHeader {
#[cfg(test)]
mod tests {
use super::*;
use crate::testils::byte_arrays::{IPV4_UDP_PACKET, VLAN_DOT1Q_PACKET, VLAN_QINQ_PACKET};
use crate::testils::byte_arrays::{UDP4_PACKET, VLAN_DOT1Q_PACKET, VLAN_QINQ_PACKET};

#[test]
fn size_of_ethernet_header() {
Expand All @@ -508,7 +508,7 @@ mod tests {

#[capsule::test]
fn parse_ethernet_packet() {
let packet = Mbuf::from_bytes(&IPV4_UDP_PACKET).unwrap();
let packet = Mbuf::from_bytes(&UDP4_PACKET).unwrap();
let ethernet = packet.parse::<Ethernet>().unwrap();

assert_eq!("00:00:00:00:00:01", ethernet.dst().to_string());
Expand Down Expand Up @@ -542,7 +542,7 @@ mod tests {

#[capsule::test]
fn swap_addresses() {
let packet = Mbuf::from_bytes(&IPV4_UDP_PACKET).unwrap();
let packet = Mbuf::from_bytes(&UDP4_PACKET).unwrap();
let mut ethernet = packet.parse::<Ethernet>().unwrap();
ethernet.swap_addresses();

Expand Down
7 changes: 3 additions & 4 deletions core/src/packets/icmp/v4/echo_reply.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
*/

use crate::packets::icmp::v4::{Icmpv4, Icmpv4Message, Icmpv4Packet, Icmpv4Type, Icmpv4Types};
use crate::packets::ip::v4::Ipv4Packet;
use crate::packets::ip::v4::{Ipv4, Ipv4Packet};
use crate::packets::types::u16be;
use crate::packets::{Internal, Packet, SizeOf};
use anyhow::Result;
Expand Down Expand Up @@ -47,7 +47,7 @@ use std::ptr::NonNull;
///
/// [IETF RFC 792]: https://tools.ietf.org/html/rfc792
#[derive(Icmpv4Packet)]
pub struct EchoReply<E: Ipv4Packet> {
pub struct EchoReply<E: Ipv4Packet = Ipv4> {
icmp: Icmpv4<E>,
body: NonNull<EchoReplyBody>,
}
Expand Down Expand Up @@ -222,7 +222,6 @@ struct EchoReplyBody {
mod tests {
use super::*;
use crate::packets::ethernet::Ethernet;
use crate::packets::ip::v4::Ipv4;
use crate::packets::Mbuf;

#[test]
Expand All @@ -235,7 +234,7 @@ mod tests {
let packet = Mbuf::new().unwrap();
let ethernet = packet.push::<Ethernet>().unwrap();
let ip4 = ethernet.push::<Ipv4>().unwrap();
let mut echo = ip4.push::<EchoReply<Ipv4>>().unwrap();
let mut echo = ip4.push::<EchoReply>().unwrap();

assert_eq!(4, echo.header_len());
assert_eq!(EchoReplyBody::size_of(), echo.payload_len());
Expand Down
7 changes: 3 additions & 4 deletions core/src/packets/icmp/v4/echo_request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
*/

use crate::packets::icmp::v4::{Icmpv4, Icmpv4Message, Icmpv4Packet, Icmpv4Type, Icmpv4Types};
use crate::packets::ip::v4::Ipv4Packet;
use crate::packets::ip::v4::{Ipv4, Ipv4Packet};
use crate::packets::types::u16be;
use crate::packets::{Internal, Packet, SizeOf};
use anyhow::Result;
Expand Down Expand Up @@ -48,7 +48,7 @@ use std::ptr::NonNull;
///
/// [IETF RFC 792]: https://tools.ietf.org/html/rfc792
#[derive(Icmpv4Packet)]
pub struct EchoRequest<E: Ipv4Packet> {
pub struct EchoRequest<E: Ipv4Packet = Ipv4> {
icmp: Icmpv4<E>,
body: NonNull<EchoRequestBody>,
}
Expand Down Expand Up @@ -223,7 +223,6 @@ struct EchoRequestBody {
mod tests {
use super::*;
use crate::packets::ethernet::Ethernet;
use crate::packets::ip::v4::Ipv4;
use crate::packets::Mbuf;

#[test]
Expand All @@ -236,7 +235,7 @@ mod tests {
let packet = Mbuf::new().unwrap();
let ethernet = packet.push::<Ethernet>().unwrap();
let ip4 = ethernet.push::<Ipv4>().unwrap();
let mut echo = ip4.push::<EchoRequest<Ipv4>>().unwrap();
let mut echo = ip4.push::<EchoRequest>().unwrap();

assert_eq!(4, echo.header_len());
assert_eq!(EchoRequestBody::size_of(), echo.payload_len());
Expand Down
25 changes: 12 additions & 13 deletions core/src/packets/icmp/v4/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ pub use self::time_exceeded::*;
pub use capsule_macros::Icmpv4Packet;

use crate::ensure;
use crate::packets::ip::v4::Ipv4Packet;
use crate::packets::ip::v4::{Ipv4, Ipv4Packet};
use crate::packets::ip::ProtocolNumbers;
use crate::packets::types::u16be;
use crate::packets::{checksum, Internal, Packet, SizeOf};
Expand Down Expand Up @@ -72,7 +72,7 @@ use std::ptr::NonNull;
///
/// [IETF RFC 792]: https://tools.ietf.org/html/rfc792
/// [`Icmpv4Message`]: Icmpv4Message
pub struct Icmpv4<E: Ipv4Packet> {
pub struct Icmpv4<E: Ipv4Packet = Ipv4> {
envelope: E,
header: NonNull<Icmpv4Header>,
offset: usize,
Expand Down Expand Up @@ -449,9 +449,8 @@ pub trait Icmpv4Packet {
mod tests {
use super::*;
use crate::packets::ethernet::Ethernet;
use crate::packets::ip::v4::Ipv4;
use crate::packets::Mbuf;
use crate::testils::byte_arrays::{ICMPV4_PACKET, IPV4_UDP_PACKET};
use crate::testils::byte_arrays::{ICMPV4_PACKET, UDP4_PACKET};

#[test]
fn size_of_icmpv4_header() {
Expand All @@ -463,15 +462,15 @@ mod tests {
let packet = Mbuf::from_bytes(&ICMPV4_PACKET).unwrap();
let ethernet = packet.parse::<Ethernet>().unwrap();
let ip4 = ethernet.parse::<Ipv4>().unwrap();
let icmp4 = ip4.parse::<Icmpv4<Ipv4>>().unwrap();
let icmp4 = ip4.parse::<Icmpv4>().unwrap();

// parses the generic header
assert_eq!(Icmpv4Types::EchoRequest, icmp4.msg_type());
assert_eq!(0, icmp4.code());
assert_eq!(0x2a5c, icmp4.checksum());

// downcasts to specific message
let echo = icmp4.downcast::<EchoRequest<Ipv4>>().unwrap();
let echo = icmp4.downcast::<EchoRequest>().unwrap();
assert_eq!(Icmpv4Types::EchoRequest, echo.msg_type());
assert_eq!(0, echo.code());
assert_eq!(0x2a5c, echo.checksum());
Expand All @@ -480,34 +479,34 @@ mod tests {

// also can one-step parse
let ip4 = echo.deparse();
assert!(ip4.parse::<EchoRequest<Ipv4>>().is_ok());
assert!(ip4.parse::<EchoRequest>().is_ok());
}

#[capsule::test]
fn parse_wrong_icmpv4_type() {
let packet = Mbuf::from_bytes(&ICMPV4_PACKET).unwrap();
let ethernet = packet.parse::<Ethernet>().unwrap();
let ip4 = ethernet.parse::<Ipv4>().unwrap();
let icmp4 = ip4.parse::<Icmpv4<Ipv4>>().unwrap();
let icmp4 = ip4.parse::<Icmpv4>().unwrap();

assert!(icmp4.downcast::<EchoReply<Ipv4>>().is_err());
assert!(icmp4.downcast::<EchoReply>().is_err());
}

#[capsule::test]
fn parse_non_icmpv4_packet() {
let packet = Mbuf::from_bytes(&IPV4_UDP_PACKET).unwrap();
let packet = Mbuf::from_bytes(&UDP4_PACKET).unwrap();
let ethernet = packet.parse::<Ethernet>().unwrap();
let ip4 = ethernet.parse::<Ipv4>().unwrap();

assert!(ip4.parse::<Icmpv4<Ipv4>>().is_err());
assert!(ip4.parse::<Icmpv4>().is_err());
}

#[capsule::test]
fn compute_checksum() {
let packet = Mbuf::from_bytes(&ICMPV4_PACKET).unwrap();
let ethernet = packet.parse::<Ethernet>().unwrap();
let ip4 = ethernet.parse::<Ipv4>().unwrap();
let mut icmp4 = ip4.parse::<Icmpv4<Ipv4>>().unwrap();
let mut icmp4 = ip4.parse::<Icmpv4>().unwrap();

let expected = icmp4.checksum();
// no payload change but force a checksum recompute anyway
Expand All @@ -521,6 +520,6 @@ mod tests {
let ethernet = packet.push::<Ethernet>().unwrap();
let ip4 = ethernet.push::<Ipv4>().unwrap();

assert!(ip4.push::<Icmpv4<Ipv4>>().is_err());
assert!(ip4.push::<Icmpv4>().is_err());
}
}
16 changes: 7 additions & 9 deletions core/src/packets/icmp/v4/redirect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@
*/

use crate::packets::icmp::v4::{Icmpv4, Icmpv4Message, Icmpv4Packet, Icmpv4Type, Icmpv4Types};
use crate::packets::ip::v4::Ipv4Packet;
use crate::packets::ip::v4::IPV4_MIN_MTU;
use crate::packets::ip::v4::{Ipv4, Ipv4Packet, IPV4_MIN_MTU};
use crate::packets::{Internal, Packet, SizeOf};
use anyhow::Result;
use std::fmt;
Expand All @@ -44,7 +43,7 @@ use std::ptr::NonNull;
///
/// [IETF RFC 792]: https://tools.ietf.org/html/rfc792
#[derive(Icmpv4Packet)]
pub struct Redirect<E: Ipv4Packet> {
pub struct Redirect<E: Ipv4Packet = Ipv4> {
icmp: Icmpv4<E>,
body: NonNull<RedirectBody>,
}
Expand Down Expand Up @@ -219,9 +218,8 @@ impl Default for RedirectBody {
mod tests {
use super::*;
use crate::packets::ethernet::Ethernet;
use crate::packets::ip::v4::Ipv4;
use crate::packets::Mbuf;
use crate::testils::byte_arrays::IPV4_TCP_PACKET;
use crate::testils::byte_arrays::TCP4_PACKET;

#[test]
fn size_of_redirect_body() {
Expand All @@ -230,12 +228,12 @@ mod tests {

#[capsule::test]
fn push_and_set_redirect() {
let packet = Mbuf::from_bytes(&IPV4_TCP_PACKET).unwrap();
let packet = Mbuf::from_bytes(&TCP4_PACKET).unwrap();
let ethernet = packet.parse::<Ethernet>().unwrap();
let ip4 = ethernet.parse::<Ipv4>().unwrap();
let tcp_len = ip4.payload_len();

let mut redirect = ip4.push::<Redirect<Ipv4>>().unwrap();
let mut redirect = ip4.push::<Redirect>().unwrap();

assert_eq!(4, redirect.header_len());
assert_eq!(RedirectBody::size_of() + tcp_len, redirect.payload_len());
Expand All @@ -260,7 +258,7 @@ mod tests {
let packet = Mbuf::from_bytes(&[42; 100]).unwrap();
let ethernet = packet.push::<Ethernet>().unwrap();
let ip4 = ethernet.push::<Ipv4>().unwrap();
let mut redirect = ip4.push::<Redirect<Ipv4>>().unwrap();
let mut redirect = ip4.push::<Redirect>().unwrap();
assert!(redirect.data_len() > IPV4_MIN_MTU);

redirect.reconcile_all();
Expand All @@ -273,7 +271,7 @@ mod tests {
let packet = Mbuf::from_bytes(&[42; 50]).unwrap();
let ethernet = packet.push::<Ethernet>().unwrap();
let ip4 = ethernet.push::<Ipv4>().unwrap();
let mut redirect = ip4.push::<Redirect<Ipv4>>().unwrap();
let mut redirect = ip4.push::<Redirect>().unwrap();
assert!(redirect.data_len() < IPV4_MIN_MTU);

redirect.reconcile_all();
Expand Down
Loading

0 comments on commit b1e9b9d

Please sign in to comment.