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