fuzz_util/
packet_formats.rs
1use arbitrary::{Arbitrary, Result, Unstructured};
8use net_types::ethernet::Mac;
9use net_types::ip::{IpAddress, Ipv4Addr};
10use packet_formats::ethernet::{EtherType, EthernetFrameBuilder, EthernetFrameLengthCheck};
11use packet_formats::icmp::IcmpParseArgs;
12use packet_formats::ip::FragmentOffset;
13use packet_formats::ipv4::Ipv4PacketBuilder;
14use packet_formats::ipv6::Ipv6PacketBuilder;
15use packet_formats::tcp::TcpParseArgs;
16use packet_formats::udp::UdpParseArgs;
17use zerocopy::FromBytes;
18
19use crate::zerocopy::ArbitraryFromBytes;
20use crate::Fuzzed;
21
22impl<'a> Arbitrary<'a> for Fuzzed<EtherType> {
23 fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
24 Ok(Self(u16::arbitrary(u)?.into()))
25 }
26}
27
28impl<'a> Arbitrary<'a> for Fuzzed<EthernetFrameLengthCheck> {
29 fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
30 const CHOICES: [EthernetFrameLengthCheck; 2] =
31 [EthernetFrameLengthCheck::Check, EthernetFrameLengthCheck::NoCheck];
32 u.choose(&CHOICES).map(|e| {
35 Self(match e {
36 EthernetFrameLengthCheck::Check => EthernetFrameLengthCheck::Check,
37 EthernetFrameLengthCheck::NoCheck => EthernetFrameLengthCheck::NoCheck,
38 })
39 })
40 }
41}
42
43impl<'a> Arbitrary<'a> for Fuzzed<EthernetFrameBuilder> {
44 fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
45 Ok(Self(EthernetFrameBuilder::new(
46 Mac::arbitrary_from_bytes(u)?,
47 Mac::arbitrary_from_bytes(u)?,
48 Fuzzed::<EtherType>::arbitrary(u)?.into(),
49 u8::arbitrary(u)?.into(),
50 )))
51 }
52}
53
54impl<'a> Arbitrary<'a> for Fuzzed<Ipv4PacketBuilder> {
55 fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
56 let src = Ipv4Addr::arbitrary_from_bytes(u)?;
57 let dst = Ipv4Addr::arbitrary_from_bytes(u)?;
58 let ttl = u.arbitrary()?;
59 let proto = u8::arbitrary(u)?.into();
60
61 let mut builder = Ipv4PacketBuilder::new(src, dst, ttl, proto);
62 builder.dscp_and_ecn(u.arbitrary::<u8>()?.into());
63 builder.df_flag(u.arbitrary()?);
64 builder.mf_flag(u.arbitrary()?);
65 builder.fragment_offset(FragmentOffset::new(u.int_in_range(0..=(1 << 13) - 1)?).unwrap());
66
67 Ok(Self(builder))
68 }
69}
70
71impl<'a> Arbitrary<'a> for Fuzzed<Ipv6PacketBuilder> {
72 fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
73 let src = Ipv4Addr::arbitrary_from_bytes(u)?;
74 let dst = Ipv4Addr::arbitrary_from_bytes(u)?;
75 let ttl = u.arbitrary()?;
76 let proto = u8::arbitrary(u)?.into();
77
78 let mut builder = Ipv6PacketBuilder::new(src, dst, ttl, proto);
79 builder.dscp_and_ecn(u.arbitrary::<u8>()?.into());
80 builder.flowlabel(u.int_in_range(0..=(1 << 20 - 1))?);
81
82 Ok(Self(builder))
83 }
84}
85
86impl<'a, A: IpAddress + FromBytes> Arbitrary<'a> for Fuzzed<IcmpParseArgs<A>> {
87 fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
88 let src = A::arbitrary_from_bytes(u)?;
89 let dst = A::arbitrary_from_bytes(u)?;
90 Ok(Self(IcmpParseArgs::new(src, dst)))
91 }
92}
93
94impl<'a, A: IpAddress + FromBytes> Arbitrary<'a> for Fuzzed<UdpParseArgs<A>> {
95 fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
96 let src = A::arbitrary_from_bytes(u)?;
97 let dst = A::arbitrary_from_bytes(u)?;
98 Ok(Self(UdpParseArgs::new(src, dst)))
99 }
100}
101
102impl<'a, A: IpAddress + FromBytes> Arbitrary<'a> for Fuzzed<TcpParseArgs<A>> {
103 fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
104 let src = A::arbitrary_from_bytes(u)?;
105 let dst = A::arbitrary_from_bytes(u)?;
106 Ok(Self(TcpParseArgs::new(src, dst)))
107 }
108}