in src/dumbo/src/pdu/arp.rs [351:505]
fn test_eth_ipv4_arp_frame() {
let mut a = [0u8; 1000];
let mut bad_array = [0u8; 1];
let sha = MacAddr::parse_str("01:23:45:67:89:ab").unwrap();
let tha = MacAddr::parse_str("cd:ef:01:23:45:67").unwrap();
let spa = Ipv4Addr::new(10, 1, 2, 3);
let tpa = Ipv4Addr::new(10, 4, 5, 6);
// Slice is too short.
assert_eq!(
EthIPv4ArpFrame::request_from_bytes(bad_array.as_ref()).unwrap_err(),
Error::SliceExactLen
);
// Slice is too short.
assert_eq!(
EthIPv4ArpFrame::write_reply(bad_array.as_mut(), sha, spa, tha, tpa).unwrap_err(),
Error::SliceExactLen
);
// Slice is too long.
assert_eq!(
EthIPv4ArpFrame::write_reply(a.as_mut(), sha, spa, tha, tpa).unwrap_err(),
Error::SliceExactLen
);
// We write a valid ARP reply to the specified slice.
{
let f = EthIPv4ArpFrame::write_reply(&mut a[..ETH_IPV4_FRAME_LEN], sha, spa, tha, tpa)
.unwrap();
// This is a bit redundant given the following tests, but assert away!
assert_eq!(f.htype(), HTYPE_ETHERNET);
assert_eq!(f.ptype(), ETHERTYPE_IPV4);
assert_eq!(f.hlen(), MAC_ADDR_LEN as u8);
assert_eq!(f.plen(), IPV4_ADDR_LEN as u8);
assert_eq!(f.operation(), OPER_REPLY);
assert_eq!(f.sha(), sha);
assert_eq!(f.spa(), spa);
assert_eq!(f.tha(), tha);
assert_eq!(f.tpa(), tpa);
}
// Now let's try to parse a request.
// Slice is too long.
assert_eq!(
EthIPv4ArpFrame::request_from_bytes(a.as_ref()).unwrap_err(),
Error::SliceExactLen
);
// The length is fine now, but the operation is a reply instead of request.
assert_eq!(
EthIPv4ArpFrame::request_from_bytes(&a[..ETH_IPV4_FRAME_LEN]).unwrap_err(),
Error::Operation
);
// TODO: The following test code is way more verbose than it should've been. Make it
// prettier at some point.
// Let's write a valid request.
EthIPv4ArpFrame::write_raw(
&mut a[..ETH_IPV4_FRAME_LEN],
HTYPE_ETHERNET,
ETHERTYPE_IPV4,
MAC_ADDR_LEN as u8,
IPV4_ADDR_LEN as u8,
OPER_REQUEST,
sha,
spa,
tha,
tpa,
)
.unwrap();
assert!(EthIPv4ArpFrame::request_from_bytes(&a[..ETH_IPV4_FRAME_LEN]).is_ok());
// Now we start writing invalid requests. We've already tried with an invalid operation.
// Invalid htype.
EthIPv4ArpFrame::write_raw(
&mut a[..ETH_IPV4_FRAME_LEN],
HTYPE_ETHERNET + 1,
ETHERTYPE_IPV4,
MAC_ADDR_LEN as u8,
IPV4_ADDR_LEN as u8,
OPER_REQUEST,
sha,
spa,
tha,
tpa,
)
.unwrap();
assert_eq!(
EthIPv4ArpFrame::request_from_bytes(&a[..ETH_IPV4_FRAME_LEN]).unwrap_err(),
Error::HType
);
// Invalid ptype.
EthIPv4ArpFrame::write_raw(
&mut a[..ETH_IPV4_FRAME_LEN],
HTYPE_ETHERNET,
ETHERTYPE_IPV4 + 1,
MAC_ADDR_LEN as u8,
IPV4_ADDR_LEN as u8,
OPER_REQUEST,
sha,
spa,
tha,
tpa,
)
.unwrap();
assert_eq!(
EthIPv4ArpFrame::request_from_bytes(&a[..ETH_IPV4_FRAME_LEN]).unwrap_err(),
Error::PType
);
// Invalid hlen.
EthIPv4ArpFrame::write_raw(
&mut a[..ETH_IPV4_FRAME_LEN],
HTYPE_ETHERNET,
ETHERTYPE_IPV4,
MAC_ADDR_LEN as u8 + 1,
IPV4_ADDR_LEN as u8,
OPER_REQUEST,
sha,
spa,
tha,
tpa,
)
.unwrap();
assert_eq!(
EthIPv4ArpFrame::request_from_bytes(&a[..ETH_IPV4_FRAME_LEN]).unwrap_err(),
Error::HLen
);
// Invalid plen.
EthIPv4ArpFrame::write_raw(
&mut a[..ETH_IPV4_FRAME_LEN],
HTYPE_ETHERNET,
ETHERTYPE_IPV4,
MAC_ADDR_LEN as u8,
IPV4_ADDR_LEN as u8 + 1,
OPER_REQUEST,
sha,
spa,
tha,
tpa,
)
.unwrap();
assert_eq!(
EthIPv4ArpFrame::request_from_bytes(&a[..ETH_IPV4_FRAME_LEN]).unwrap_err(),
Error::PLen
);
}