1 #![no_main]
2 use libfuzzer_sys::fuzz_target;
3 use smoltcp::{phy::ChecksumCapabilities, wire::*};
4 
5 #[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, arbitrary::Arbitrary)]
6 pub enum AddressFuzzer {
7     Absent,
8     Short([u8; 2]),
9     Extended([u8; 8]),
10 }
11 
12 impl From<AddressFuzzer> for Ieee802154Address {
from(val: AddressFuzzer) -> Self13     fn from(val: AddressFuzzer) -> Self {
14         match val {
15             AddressFuzzer::Absent => Ieee802154Address::Absent,
16             AddressFuzzer::Short(b) => Ieee802154Address::Short(b),
17             AddressFuzzer::Extended(b) => Ieee802154Address::Extended(b),
18         }
19     }
20 }
21 
22 #[derive(Debug, arbitrary::Arbitrary)]
23 struct SixlowpanPacketFuzzer<'a> {
24     data: &'a [u8],
25     ll_src_addr: Option<AddressFuzzer>,
26     ll_dst_addr: Option<AddressFuzzer>,
27 }
28 
29 fuzz_target!(|fuzz: SixlowpanPacketFuzzer| {
30     match SixlowpanPacket::dispatch(fuzz.data) {
31         Ok(SixlowpanPacket::FragmentHeader) => {
32             if let Ok(frame) = SixlowpanFragPacket::new_checked(fuzz.data) {
33                 if let Ok(repr) = SixlowpanFragRepr::parse(&frame) {
34                     let mut buffer = vec![0; repr.buffer_len()];
35                     let mut frame = SixlowpanFragPacket::new_unchecked(&mut buffer[..]);
36                     repr.emit(&mut frame);
37                 }
38             }
39         }
40         Ok(SixlowpanPacket::IphcHeader) => {
41             if let Ok(frame) = SixlowpanIphcPacket::new_checked(fuzz.data) {
42                 if let Ok(iphc_repr) = SixlowpanIphcRepr::parse(
43                     &frame,
44                     fuzz.ll_src_addr.map(Into::into),
45                     fuzz.ll_dst_addr.map(Into::into),
46                     &[],
47                 ) {
48                     let mut buffer = vec![0; iphc_repr.buffer_len()];
49                     let mut iphc_frame = SixlowpanIphcPacket::new_unchecked(&mut buffer[..]);
50                     iphc_repr.emit(&mut iphc_frame);
51 
52                     let payload = frame.payload();
53                     match iphc_repr.next_header {
54                         SixlowpanNextHeader::Compressed => {
55                             if let Ok(p) = SixlowpanNhcPacket::dispatch(payload) {
56                                 match p {
57                                     SixlowpanNhcPacket::ExtHeader => {
58                                         if let Ok(frame) =
59                                             SixlowpanExtHeaderPacket::new_checked(payload)
60                                         {
61                                             if let Ok(repr) = SixlowpanExtHeaderRepr::parse(&frame)
62                                             {
63                                                 let mut buffer = vec![0; repr.buffer_len()];
64                                                 let mut ext_header_frame =
65                                                     SixlowpanExtHeaderPacket::new_unchecked(
66                                                         &mut buffer[..],
67                                                     );
68                                                 repr.emit(&mut ext_header_frame);
69                                             }
70                                         }
71                                     }
72                                     SixlowpanNhcPacket::UdpHeader => {
73                                         if let Ok(frame) =
74                                             SixlowpanUdpNhcPacket::new_checked(payload)
75                                         {
76                                             if let Ok(repr) = SixlowpanUdpNhcRepr::parse(
77                                                 &frame,
78                                                 &iphc_repr.src_addr,
79                                                 &iphc_repr.dst_addr,
80                                             ) {
81                                                 let mut buffer = vec![
82                                                     0;
83                                                     repr.header_len()
84                                                         + frame.payload().len()
85                                                 ];
86                                                 let mut udp_packet =
87                                                     SixlowpanUdpNhcPacket::new_unchecked(
88                                                         &mut buffer[..],
89                                                     );
90                                                 repr.emit(
91                                                     &mut udp_packet,
92                                                     &iphc_repr.src_addr,
93                                                     &iphc_repr.dst_addr,
94                                                     frame.payload().len(),
95                                                     |b| b.copy_from_slice(frame.payload()),
96                                                 );
97                                             }
98                                         }
99                                     }
100                                 }
101                             }
102                         }
103                         SixlowpanNextHeader::Uncompressed(proto) => match proto {
104                             IpProtocol::HopByHop => {
105                                 if let Ok(frame) = Ipv6HopByHopHeader::new_checked(payload) {
106                                     if let Ok(repr) = Ipv6HopByHopRepr::parse(&frame) {
107                                         let mut buffer = vec![0; repr.buffer_len()];
108                                         let mut hop_by_hop_frame =
109                                             Ipv6HopByHopHeader::new_unchecked(&mut buffer[..]);
110                                         repr.emit(&mut hop_by_hop_frame);
111                                     }
112                                 }
113                             }
114                             IpProtocol::Icmp => {
115                                 if let Ok(frame) = Icmpv4Packet::new_checked(payload) {
116                                     if let Ok(repr) =
117                                         Icmpv4Repr::parse(&frame, &ChecksumCapabilities::default())
118                                     {
119                                         let mut buffer = vec![0; repr.buffer_len()];
120                                         let mut icmpv4_packet =
121                                             Icmpv4Packet::new_unchecked(&mut buffer[..]);
122                                         repr.emit(
123                                             &mut icmpv4_packet,
124                                             &ChecksumCapabilities::default(),
125                                         );
126                                     }
127                                 }
128                             }
129                             IpProtocol::Igmp => {
130                                 if let Ok(frame) = IgmpPacket::new_checked(payload) {
131                                     if let Ok(repr) = IgmpRepr::parse(&frame) {
132                                         let mut buffer = vec![0; repr.buffer_len()];
133                                         let mut frame = IgmpPacket::new_unchecked(&mut buffer[..]);
134                                         repr.emit(&mut frame);
135                                     }
136                                 }
137                             }
138                             IpProtocol::Tcp => {
139                                 if let Ok(frame) = TcpPacket::new_checked(payload) {
140                                     if let Ok(repr) = TcpRepr::parse(
141                                         &frame,
142                                         &iphc_repr.src_addr.into_address(),
143                                         &iphc_repr.dst_addr.into_address(),
144                                         &ChecksumCapabilities::default(),
145                                     ) {
146                                         let mut buffer = vec![0; repr.buffer_len()];
147                                         let mut frame = TcpPacket::new_unchecked(&mut buffer[..]);
148                                         repr.emit(
149                                             &mut frame,
150                                             &iphc_repr.src_addr.into_address(),
151                                             &iphc_repr.dst_addr.into_address(),
152                                             &ChecksumCapabilities::default(),
153                                         );
154                                     }
155                                 }
156                             }
157                             IpProtocol::Udp => {
158                                 if let Ok(frame) = UdpPacket::new_checked(payload) {
159                                     if let Ok(repr) = UdpRepr::parse(
160                                         &frame,
161                                         &iphc_repr.src_addr.into_address(),
162                                         &iphc_repr.dst_addr.into_address(),
163                                         &ChecksumCapabilities::default(),
164                                     ) {
165                                         let mut buffer =
166                                             vec![0; repr.header_len() + frame.payload().len()];
167                                         let mut packet = UdpPacket::new_unchecked(&mut buffer[..]);
168                                         repr.emit(
169                                             &mut packet,
170                                             &iphc_repr.src_addr.into_address(),
171                                             &iphc_repr.dst_addr.into_address(),
172                                             frame.payload().len(),
173                                             |b| b.copy_from_slice(frame.payload()),
174                                             &ChecksumCapabilities::default(),
175                                         );
176                                     }
177                                 }
178                             }
179                             IpProtocol::Ipv6Route => {
180                                 if let Ok(frame) = Ipv6RoutingHeader::new_checked(payload) {
181                                     if let Ok(repr) = Ipv6RoutingRepr::parse(&frame) {
182                                         let mut buffer = vec![0; repr.buffer_len()];
183                                         let mut packet = Ipv6RoutingHeader::new(&mut buffer[..]);
184                                         repr.emit(&mut packet);
185                                     }
186                                 }
187                             }
188                             IpProtocol::Ipv6Frag => {
189                                 if let Ok(frame) = Ipv6FragmentHeader::new_checked(payload) {
190                                     if let Ok(repr) = Ipv6FragmentRepr::parse(&frame) {
191                                         let mut buffer = vec![0; repr.buffer_len()];
192                                         let mut frame =
193                                             Ipv6FragmentHeader::new_unchecked(&mut buffer[..]);
194                                         repr.emit(&mut frame);
195                                     }
196                                 }
197                             }
198                             IpProtocol::Icmpv6 => {
199                                 if let Ok(packet) = Icmpv6Packet::new_checked(payload) {
200                                     if let Ok(repr) = Icmpv6Repr::parse(
201                                         &iphc_repr.src_addr.into_address(),
202                                         &iphc_repr.dst_addr.into_address(),
203                                         &packet,
204                                         &ChecksumCapabilities::default(),
205                                     ) {
206                                         let mut buffer = vec![0; repr.buffer_len()];
207                                         let mut packet =
208                                             Icmpv6Packet::new_unchecked(&mut buffer[..]);
209                                         repr.emit(
210                                             &iphc_repr.src_addr.into_address(),
211                                             &iphc_repr.dst_addr.into_address(),
212                                             &mut packet,
213                                             &ChecksumCapabilities::default(),
214                                         );
215                                     }
216                                 }
217                             }
218                             IpProtocol::Ipv6NoNxt => (),
219                             IpProtocol::Ipv6Opts => {
220                                 if let Ok(packet) = Ipv6Option::new_checked(payload) {
221                                     if let Ok(repr) = Ipv6OptionRepr::parse(&packet) {
222                                         let mut buffer = vec![0; repr.buffer_len()];
223                                         let mut packet = Ipv6Option::new_unchecked(&mut buffer[..]);
224                                         repr.emit(&mut packet);
225                                     }
226                                 }
227                             }
228                             IpProtocol::Unknown(_) => (),
229                         },
230                     };
231 
232                     let mut buffer = vec![0; iphc_repr.buffer_len()];
233 
234                     let mut frame = SixlowpanIphcPacket::new_unchecked(&mut buffer[..]);
235                     iphc_repr.emit(&mut frame);
236                 }
237             };
238         }
239         Err(_) => (),
240     }
241 });
242