ipv4.rs 32 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018
  1. use super::*;
  2. #[rstest]
  3. #[case(Medium::Ethernet)]
  4. #[cfg(feature = "medium-ethernet")]
  5. fn test_any_ip_accept_arp(#[case] medium: Medium) {
  6. let mut buffer = [0u8; 64];
  7. #[allow(non_snake_case)]
  8. fn ETHERNET_FRAME_ARP(buffer: &mut [u8]) -> &[u8] {
  9. let ethernet_repr = EthernetRepr {
  10. src_addr: EthernetAddress::from_bytes(&[0x02, 0x02, 0x02, 0x02, 0x02, 0x03]),
  11. dst_addr: EthernetAddress::from_bytes(&[0x02, 0x02, 0x02, 0x02, 0x02, 0x02]),
  12. ethertype: EthernetProtocol::Arp,
  13. };
  14. let frame_repr = ArpRepr::EthernetIpv4 {
  15. operation: ArpOperation::Request,
  16. source_hardware_addr: EthernetAddress::from_bytes(&[
  17. 0x02, 0x02, 0x02, 0x02, 0x02, 0x03,
  18. ]),
  19. source_protocol_addr: Ipv4Address::from_bytes(&[192, 168, 1, 2]),
  20. target_hardware_addr: EthernetAddress::from_bytes(&[
  21. 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
  22. ]),
  23. target_protocol_addr: Ipv4Address::from_bytes(&[192, 168, 1, 3]),
  24. };
  25. let mut frame = EthernetFrame::new_unchecked(&mut buffer[..]);
  26. ethernet_repr.emit(&mut frame);
  27. let mut frame = ArpPacket::new_unchecked(&mut buffer[ethernet_repr.buffer_len()..]);
  28. frame_repr.emit(&mut frame);
  29. &buffer[..ethernet_repr.buffer_len() + frame_repr.buffer_len()]
  30. }
  31. let (mut iface, mut sockets, _) = setup(medium);
  32. assert!(iface
  33. .inner
  34. .process_ethernet(
  35. &mut sockets,
  36. PacketMeta::default(),
  37. ETHERNET_FRAME_ARP(buffer.as_mut()),
  38. &mut iface.fragments,
  39. )
  40. .is_none());
  41. // Accept any IP address
  42. iface.set_any_ip(true);
  43. assert!(iface
  44. .inner
  45. .process_ethernet(
  46. &mut sockets,
  47. PacketMeta::default(),
  48. ETHERNET_FRAME_ARP(buffer.as_mut()),
  49. &mut iface.fragments,
  50. )
  51. .is_some());
  52. }
  53. #[rstest]
  54. #[case(Medium::Ip)]
  55. #[cfg(feature = "medium-ip")]
  56. #[case(Medium::Ethernet)]
  57. #[cfg(feature = "medium-ethernet")]
  58. fn test_no_icmp_no_unicast(#[case] medium: Medium) {
  59. let (mut iface, mut sockets, _) = setup(medium);
  60. // Unknown Ipv4 Protocol
  61. //
  62. // Because the destination is the broadcast address
  63. // this should not trigger and Destination Unreachable
  64. // response. See RFC 1122 § 3.2.2.
  65. let repr = IpRepr::Ipv4(Ipv4Repr {
  66. src_addr: Ipv4Address([0x7f, 0x00, 0x00, 0x01]),
  67. dst_addr: Ipv4Address::BROADCAST,
  68. next_header: IpProtocol::Unknown(0x0c),
  69. payload_len: 0,
  70. hop_limit: 0x40,
  71. });
  72. let mut bytes = vec![0u8; 54];
  73. repr.emit(&mut bytes, &ChecksumCapabilities::default());
  74. let frame = Ipv4Packet::new_unchecked(&bytes[..]);
  75. // Ensure that the unknown protocol frame does not trigger an
  76. // ICMP error response when the destination address is a
  77. // broadcast address
  78. assert_eq!(
  79. iface.inner.process_ipv4(
  80. &mut sockets,
  81. PacketMeta::default(),
  82. &frame,
  83. &mut iface.fragments
  84. ),
  85. None
  86. );
  87. }
  88. #[rstest]
  89. #[case(Medium::Ip)]
  90. #[cfg(feature = "medium-ip")]
  91. #[case(Medium::Ethernet)]
  92. #[cfg(feature = "medium-ethernet")]
  93. fn test_icmp_error_no_payload(#[case] medium: Medium) {
  94. static NO_BYTES: [u8; 0] = [];
  95. let (mut iface, mut sockets, _device) = setup(medium);
  96. // Unknown Ipv4 Protocol with no payload
  97. let repr = IpRepr::Ipv4(Ipv4Repr {
  98. src_addr: Ipv4Address([0x7f, 0x00, 0x00, 0x02]),
  99. dst_addr: Ipv4Address([0x7f, 0x00, 0x00, 0x01]),
  100. next_header: IpProtocol::Unknown(0x0c),
  101. payload_len: 0,
  102. hop_limit: 0x40,
  103. });
  104. let mut bytes = vec![0u8; 34];
  105. repr.emit(&mut bytes, &ChecksumCapabilities::default());
  106. let frame = Ipv4Packet::new_unchecked(&bytes[..]);
  107. // The expected Destination Unreachable response due to the
  108. // unknown protocol
  109. let icmp_repr = Icmpv4Repr::DstUnreachable {
  110. reason: Icmpv4DstUnreachable::ProtoUnreachable,
  111. header: Ipv4Repr {
  112. src_addr: Ipv4Address([0x7f, 0x00, 0x00, 0x02]),
  113. dst_addr: Ipv4Address([0x7f, 0x00, 0x00, 0x01]),
  114. next_header: IpProtocol::Unknown(12),
  115. payload_len: 0,
  116. hop_limit: 64,
  117. },
  118. data: &NO_BYTES,
  119. };
  120. let expected_repr = Packet::new_ipv4(
  121. Ipv4Repr {
  122. src_addr: Ipv4Address([0x7f, 0x00, 0x00, 0x01]),
  123. dst_addr: Ipv4Address([0x7f, 0x00, 0x00, 0x02]),
  124. next_header: IpProtocol::Icmp,
  125. payload_len: icmp_repr.buffer_len(),
  126. hop_limit: 64,
  127. },
  128. IpPayload::Icmpv4(icmp_repr),
  129. );
  130. // Ensure that the unknown protocol triggers an error response.
  131. // And we correctly handle no payload.
  132. assert_eq!(
  133. iface.inner.process_ipv4(
  134. &mut sockets,
  135. PacketMeta::default(),
  136. &frame,
  137. &mut iface.fragments
  138. ),
  139. Some(expected_repr)
  140. );
  141. }
  142. #[rstest]
  143. #[case(Medium::Ip)]
  144. #[cfg(feature = "medium-ip")]
  145. #[case(Medium::Ethernet)]
  146. #[cfg(feature = "medium-ethernet")]
  147. fn test_local_subnet_broadcasts(#[case] medium: Medium) {
  148. let (mut iface, _, _device) = setup(medium);
  149. iface.update_ip_addrs(|addrs| {
  150. addrs.iter_mut().next().map(|addr| {
  151. *addr = IpCidr::Ipv4(Ipv4Cidr::new(Ipv4Address([192, 168, 1, 23]), 24));
  152. });
  153. });
  154. assert!(iface
  155. .inner
  156. .is_broadcast_v4(Ipv4Address([255, 255, 255, 255])));
  157. assert!(!iface
  158. .inner
  159. .is_broadcast_v4(Ipv4Address([255, 255, 255, 254])));
  160. assert!(iface.inner.is_broadcast_v4(Ipv4Address([192, 168, 1, 255])));
  161. assert!(!iface.inner.is_broadcast_v4(Ipv4Address([192, 168, 1, 254])));
  162. iface.update_ip_addrs(|addrs| {
  163. addrs.iter_mut().next().map(|addr| {
  164. *addr = IpCidr::Ipv4(Ipv4Cidr::new(Ipv4Address([192, 168, 23, 24]), 16));
  165. });
  166. });
  167. assert!(iface
  168. .inner
  169. .is_broadcast_v4(Ipv4Address([255, 255, 255, 255])));
  170. assert!(!iface
  171. .inner
  172. .is_broadcast_v4(Ipv4Address([255, 255, 255, 254])));
  173. assert!(!iface
  174. .inner
  175. .is_broadcast_v4(Ipv4Address([192, 168, 23, 255])));
  176. assert!(!iface
  177. .inner
  178. .is_broadcast_v4(Ipv4Address([192, 168, 23, 254])));
  179. assert!(!iface
  180. .inner
  181. .is_broadcast_v4(Ipv4Address([192, 168, 255, 254])));
  182. assert!(iface
  183. .inner
  184. .is_broadcast_v4(Ipv4Address([192, 168, 255, 255])));
  185. iface.update_ip_addrs(|addrs| {
  186. addrs.iter_mut().next().map(|addr| {
  187. *addr = IpCidr::Ipv4(Ipv4Cidr::new(Ipv4Address([192, 168, 23, 24]), 8));
  188. });
  189. });
  190. assert!(iface
  191. .inner
  192. .is_broadcast_v4(Ipv4Address([255, 255, 255, 255])));
  193. assert!(!iface
  194. .inner
  195. .is_broadcast_v4(Ipv4Address([255, 255, 255, 254])));
  196. assert!(!iface.inner.is_broadcast_v4(Ipv4Address([192, 23, 1, 255])));
  197. assert!(!iface.inner.is_broadcast_v4(Ipv4Address([192, 23, 1, 254])));
  198. assert!(!iface
  199. .inner
  200. .is_broadcast_v4(Ipv4Address([192, 255, 255, 254])));
  201. assert!(iface
  202. .inner
  203. .is_broadcast_v4(Ipv4Address([192, 255, 255, 255])));
  204. }
  205. #[rstest]
  206. #[case(Medium::Ip)]
  207. #[cfg(all(feature = "medium-ip", feature = "socket-udp"))]
  208. #[case(Medium::Ethernet)]
  209. #[cfg(all(feature = "medium-ethernet", feature = "socket-udp"))]
  210. fn test_icmp_error_port_unreachable(#[case] medium: Medium) {
  211. static UDP_PAYLOAD: [u8; 12] = [
  212. 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x2c, 0x20, 0x57, 0x6f, 0x6c, 0x64, 0x21,
  213. ];
  214. let (mut iface, mut sockets, _device) = setup(medium);
  215. let mut udp_bytes_unicast = vec![0u8; 20];
  216. let mut udp_bytes_broadcast = vec![0u8; 20];
  217. let mut packet_unicast = UdpPacket::new_unchecked(&mut udp_bytes_unicast);
  218. let mut packet_broadcast = UdpPacket::new_unchecked(&mut udp_bytes_broadcast);
  219. let udp_repr = UdpRepr {
  220. src_port: 67,
  221. dst_port: 68,
  222. };
  223. let ip_repr = IpRepr::Ipv4(Ipv4Repr {
  224. src_addr: Ipv4Address([0x7f, 0x00, 0x00, 0x02]),
  225. dst_addr: Ipv4Address([0x7f, 0x00, 0x00, 0x01]),
  226. next_header: IpProtocol::Udp,
  227. payload_len: udp_repr.header_len() + UDP_PAYLOAD.len(),
  228. hop_limit: 64,
  229. });
  230. // Emit the representations to a packet
  231. udp_repr.emit(
  232. &mut packet_unicast,
  233. &ip_repr.src_addr(),
  234. &ip_repr.dst_addr(),
  235. UDP_PAYLOAD.len(),
  236. |buf| buf.copy_from_slice(&UDP_PAYLOAD),
  237. &ChecksumCapabilities::default(),
  238. );
  239. let data = packet_unicast.into_inner();
  240. // The expected Destination Unreachable ICMPv4 error response due
  241. // to no sockets listening on the destination port.
  242. let icmp_repr = Icmpv4Repr::DstUnreachable {
  243. reason: Icmpv4DstUnreachable::PortUnreachable,
  244. header: Ipv4Repr {
  245. src_addr: Ipv4Address([0x7f, 0x00, 0x00, 0x02]),
  246. dst_addr: Ipv4Address([0x7f, 0x00, 0x00, 0x01]),
  247. next_header: IpProtocol::Udp,
  248. payload_len: udp_repr.header_len() + UDP_PAYLOAD.len(),
  249. hop_limit: 64,
  250. },
  251. data,
  252. };
  253. let expected_repr = Packet::new_ipv4(
  254. Ipv4Repr {
  255. src_addr: Ipv4Address([0x7f, 0x00, 0x00, 0x01]),
  256. dst_addr: Ipv4Address([0x7f, 0x00, 0x00, 0x02]),
  257. next_header: IpProtocol::Icmp,
  258. payload_len: icmp_repr.buffer_len(),
  259. hop_limit: 64,
  260. },
  261. IpPayload::Icmpv4(icmp_repr),
  262. );
  263. // Ensure that the unknown protocol triggers an error response.
  264. // And we correctly handle no payload.
  265. assert_eq!(
  266. iface
  267. .inner
  268. .process_udp(&mut sockets, PacketMeta::default(), false, ip_repr, data),
  269. Some(expected_repr)
  270. );
  271. let ip_repr = IpRepr::Ipv4(Ipv4Repr {
  272. src_addr: Ipv4Address([0x7f, 0x00, 0x00, 0x02]),
  273. dst_addr: Ipv4Address::BROADCAST,
  274. next_header: IpProtocol::Udp,
  275. payload_len: udp_repr.header_len() + UDP_PAYLOAD.len(),
  276. hop_limit: 64,
  277. });
  278. // Emit the representations to a packet
  279. udp_repr.emit(
  280. &mut packet_broadcast,
  281. &ip_repr.src_addr(),
  282. &IpAddress::Ipv4(Ipv4Address::BROADCAST),
  283. UDP_PAYLOAD.len(),
  284. |buf| buf.copy_from_slice(&UDP_PAYLOAD),
  285. &ChecksumCapabilities::default(),
  286. );
  287. // Ensure that the port unreachable error does not trigger an
  288. // ICMP error response when the destination address is a
  289. // broadcast address and no socket is bound to the port.
  290. assert_eq!(
  291. iface.inner.process_udp(
  292. &mut sockets,
  293. PacketMeta::default(),
  294. false,
  295. ip_repr,
  296. packet_broadcast.into_inner(),
  297. ),
  298. None
  299. );
  300. }
  301. #[rstest]
  302. #[case(Medium::Ip)]
  303. #[cfg(feature = "medium-ip")]
  304. #[case(Medium::Ethernet)]
  305. #[cfg(feature = "medium-ethernet")]
  306. fn test_handle_ipv4_broadcast(#[case] medium: Medium) {
  307. use crate::wire::{Icmpv4Packet, Icmpv4Repr};
  308. let (mut iface, mut sockets, _device) = setup(medium);
  309. let our_ipv4_addr = iface.ipv4_addr().unwrap();
  310. let src_ipv4_addr = Ipv4Address([127, 0, 0, 2]);
  311. // ICMPv4 echo request
  312. let icmpv4_data: [u8; 4] = [0xaa, 0x00, 0x00, 0xff];
  313. let icmpv4_repr = Icmpv4Repr::EchoRequest {
  314. ident: 0x1234,
  315. seq_no: 0xabcd,
  316. data: &icmpv4_data,
  317. };
  318. // Send to IPv4 broadcast address
  319. let ipv4_repr = Ipv4Repr {
  320. src_addr: src_ipv4_addr,
  321. dst_addr: Ipv4Address::BROADCAST,
  322. next_header: IpProtocol::Icmp,
  323. hop_limit: 64,
  324. payload_len: icmpv4_repr.buffer_len(),
  325. };
  326. // Emit to ip frame
  327. let mut bytes = vec![0u8; ipv4_repr.buffer_len() + icmpv4_repr.buffer_len()];
  328. let frame = {
  329. ipv4_repr.emit(
  330. &mut Ipv4Packet::new_unchecked(&mut bytes[..]),
  331. &ChecksumCapabilities::default(),
  332. );
  333. icmpv4_repr.emit(
  334. &mut Icmpv4Packet::new_unchecked(&mut bytes[ipv4_repr.buffer_len()..]),
  335. &ChecksumCapabilities::default(),
  336. );
  337. Ipv4Packet::new_unchecked(&bytes[..])
  338. };
  339. // Expected ICMPv4 echo reply
  340. let expected_icmpv4_repr = Icmpv4Repr::EchoReply {
  341. ident: 0x1234,
  342. seq_no: 0xabcd,
  343. data: &icmpv4_data,
  344. };
  345. let expected_ipv4_repr = Ipv4Repr {
  346. src_addr: our_ipv4_addr,
  347. dst_addr: src_ipv4_addr,
  348. next_header: IpProtocol::Icmp,
  349. hop_limit: 64,
  350. payload_len: expected_icmpv4_repr.buffer_len(),
  351. };
  352. let expected_packet =
  353. Packet::new_ipv4(expected_ipv4_repr, IpPayload::Icmpv4(expected_icmpv4_repr));
  354. assert_eq!(
  355. iface.inner.process_ipv4(
  356. &mut sockets,
  357. PacketMeta::default(),
  358. &frame,
  359. &mut iface.fragments
  360. ),
  361. Some(expected_packet)
  362. );
  363. }
  364. #[rstest]
  365. #[case(Medium::Ethernet)]
  366. #[cfg(feature = "medium-ethernet")]
  367. fn test_handle_valid_arp_request(#[case] medium: Medium) {
  368. let (mut iface, mut sockets, _device) = setup(medium);
  369. let mut eth_bytes = vec![0u8; 42];
  370. let local_ip_addr = Ipv4Address([0x7f, 0x00, 0x00, 0x01]);
  371. let remote_ip_addr = Ipv4Address([0x7f, 0x00, 0x00, 0x02]);
  372. let local_hw_addr = EthernetAddress([0x02, 0x02, 0x02, 0x02, 0x02, 0x02]);
  373. let remote_hw_addr = EthernetAddress([0x52, 0x54, 0x00, 0x00, 0x00, 0x00]);
  374. let repr = ArpRepr::EthernetIpv4 {
  375. operation: ArpOperation::Request,
  376. source_hardware_addr: remote_hw_addr,
  377. source_protocol_addr: remote_ip_addr,
  378. target_hardware_addr: EthernetAddress::default(),
  379. target_protocol_addr: local_ip_addr,
  380. };
  381. let mut frame = EthernetFrame::new_unchecked(&mut eth_bytes);
  382. frame.set_dst_addr(EthernetAddress::BROADCAST);
  383. frame.set_src_addr(remote_hw_addr);
  384. frame.set_ethertype(EthernetProtocol::Arp);
  385. let mut packet = ArpPacket::new_unchecked(frame.payload_mut());
  386. repr.emit(&mut packet);
  387. // Ensure an ARP Request for us triggers an ARP Reply
  388. assert_eq!(
  389. iface.inner.process_ethernet(
  390. &mut sockets,
  391. PacketMeta::default(),
  392. frame.into_inner(),
  393. &mut iface.fragments
  394. ),
  395. Some(EthernetPacket::Arp(ArpRepr::EthernetIpv4 {
  396. operation: ArpOperation::Reply,
  397. source_hardware_addr: local_hw_addr,
  398. source_protocol_addr: local_ip_addr,
  399. target_hardware_addr: remote_hw_addr,
  400. target_protocol_addr: remote_ip_addr
  401. }))
  402. );
  403. // Ensure the address of the requester was entered in the cache
  404. assert_eq!(
  405. iface.inner.lookup_hardware_addr(
  406. MockTxToken,
  407. &IpAddress::Ipv4(local_ip_addr),
  408. &IpAddress::Ipv4(remote_ip_addr),
  409. &mut iface.fragmenter,
  410. ),
  411. Ok((HardwareAddress::Ethernet(remote_hw_addr), MockTxToken))
  412. );
  413. }
  414. #[rstest]
  415. #[case(Medium::Ethernet)]
  416. #[cfg(feature = "medium-ethernet")]
  417. fn test_handle_other_arp_request(#[case] medium: Medium) {
  418. let (mut iface, mut sockets, _device) = setup(medium);
  419. let mut eth_bytes = vec![0u8; 42];
  420. let remote_ip_addr = Ipv4Address([0x7f, 0x00, 0x00, 0x02]);
  421. let remote_hw_addr = EthernetAddress([0x52, 0x54, 0x00, 0x00, 0x00, 0x00]);
  422. let repr = ArpRepr::EthernetIpv4 {
  423. operation: ArpOperation::Request,
  424. source_hardware_addr: remote_hw_addr,
  425. source_protocol_addr: remote_ip_addr,
  426. target_hardware_addr: EthernetAddress::default(),
  427. target_protocol_addr: Ipv4Address([0x7f, 0x00, 0x00, 0x03]),
  428. };
  429. let mut frame = EthernetFrame::new_unchecked(&mut eth_bytes);
  430. frame.set_dst_addr(EthernetAddress::BROADCAST);
  431. frame.set_src_addr(remote_hw_addr);
  432. frame.set_ethertype(EthernetProtocol::Arp);
  433. let mut packet = ArpPacket::new_unchecked(frame.payload_mut());
  434. repr.emit(&mut packet);
  435. // Ensure an ARP Request for someone else does not trigger an ARP Reply
  436. assert_eq!(
  437. iface.inner.process_ethernet(
  438. &mut sockets,
  439. PacketMeta::default(),
  440. frame.into_inner(),
  441. &mut iface.fragments
  442. ),
  443. None
  444. );
  445. // Ensure the address of the requester was NOT entered in the cache
  446. assert_eq!(
  447. iface.inner.lookup_hardware_addr(
  448. MockTxToken,
  449. &IpAddress::Ipv4(Ipv4Address([0x7f, 0x00, 0x00, 0x01])),
  450. &IpAddress::Ipv4(remote_ip_addr),
  451. &mut iface.fragmenter,
  452. ),
  453. Err(DispatchError::NeighborPending)
  454. );
  455. }
  456. #[rstest]
  457. #[case(Medium::Ethernet)]
  458. #[cfg(feature = "medium-ethernet")]
  459. fn test_arp_flush_after_update_ip(#[case] medium: Medium) {
  460. let (mut iface, mut sockets, _device) = setup(medium);
  461. let mut eth_bytes = vec![0u8; 42];
  462. let local_ip_addr = Ipv4Address([0x7f, 0x00, 0x00, 0x01]);
  463. let remote_ip_addr = Ipv4Address([0x7f, 0x00, 0x00, 0x02]);
  464. let local_hw_addr = EthernetAddress([0x02, 0x02, 0x02, 0x02, 0x02, 0x02]);
  465. let remote_hw_addr = EthernetAddress([0x52, 0x54, 0x00, 0x00, 0x00, 0x00]);
  466. let repr = ArpRepr::EthernetIpv4 {
  467. operation: ArpOperation::Request,
  468. source_hardware_addr: remote_hw_addr,
  469. source_protocol_addr: remote_ip_addr,
  470. target_hardware_addr: EthernetAddress::default(),
  471. target_protocol_addr: Ipv4Address([0x7f, 0x00, 0x00, 0x01]),
  472. };
  473. let mut frame = EthernetFrame::new_unchecked(&mut eth_bytes);
  474. frame.set_dst_addr(EthernetAddress::BROADCAST);
  475. frame.set_src_addr(remote_hw_addr);
  476. frame.set_ethertype(EthernetProtocol::Arp);
  477. {
  478. let mut packet = ArpPacket::new_unchecked(frame.payload_mut());
  479. repr.emit(&mut packet);
  480. }
  481. // Ensure an ARP Request for us triggers an ARP Reply
  482. assert_eq!(
  483. iface.inner.process_ethernet(
  484. &mut sockets,
  485. PacketMeta::default(),
  486. frame.into_inner(),
  487. &mut iface.fragments
  488. ),
  489. Some(EthernetPacket::Arp(ArpRepr::EthernetIpv4 {
  490. operation: ArpOperation::Reply,
  491. source_hardware_addr: local_hw_addr,
  492. source_protocol_addr: local_ip_addr,
  493. target_hardware_addr: remote_hw_addr,
  494. target_protocol_addr: remote_ip_addr
  495. }))
  496. );
  497. // Ensure the address of the requester was entered in the cache
  498. assert_eq!(
  499. iface.inner.lookup_hardware_addr(
  500. MockTxToken,
  501. &IpAddress::Ipv4(local_ip_addr),
  502. &IpAddress::Ipv4(remote_ip_addr),
  503. &mut iface.fragmenter,
  504. ),
  505. Ok((HardwareAddress::Ethernet(remote_hw_addr), MockTxToken))
  506. );
  507. // Update IP addrs to trigger ARP cache flush
  508. let local_ip_addr_new = Ipv4Address([0x7f, 0x00, 0x00, 0x01]);
  509. iface.update_ip_addrs(|addrs| {
  510. addrs.iter_mut().next().map(|addr| {
  511. *addr = IpCidr::Ipv4(Ipv4Cidr::new(local_ip_addr_new, 24));
  512. });
  513. });
  514. // ARP cache flush after address change
  515. assert!(!iface.inner.has_neighbor(&IpAddress::Ipv4(remote_ip_addr)));
  516. }
  517. #[rstest]
  518. #[case(Medium::Ip)]
  519. #[cfg(all(feature = "socket-icmp", feature = "medium-ip"))]
  520. #[case(Medium::Ethernet)]
  521. #[cfg(all(feature = "socket-icmp", feature = "medium-ethernet"))]
  522. fn test_icmpv4_socket(#[case] medium: Medium) {
  523. use crate::wire::Icmpv4Packet;
  524. let (mut iface, mut sockets, _device) = setup(medium);
  525. let rx_buffer = icmp::PacketBuffer::new(vec![icmp::PacketMetadata::EMPTY], vec![0; 24]);
  526. let tx_buffer = icmp::PacketBuffer::new(vec![icmp::PacketMetadata::EMPTY], vec![0; 24]);
  527. let icmpv4_socket = icmp::Socket::new(rx_buffer, tx_buffer);
  528. let socket_handle = sockets.add(icmpv4_socket);
  529. let ident = 0x1234;
  530. let seq_no = 0x5432;
  531. let echo_data = &[0xff; 16];
  532. let socket = sockets.get_mut::<icmp::Socket>(socket_handle);
  533. // Bind to the ID 0x1234
  534. assert_eq!(socket.bind(icmp::Endpoint::Ident(ident)), Ok(()));
  535. // Ensure the ident we bound to and the ident of the packet are the same.
  536. let mut bytes = [0xff; 24];
  537. let mut packet = Icmpv4Packet::new_unchecked(&mut bytes[..]);
  538. let echo_repr = Icmpv4Repr::EchoRequest {
  539. ident,
  540. seq_no,
  541. data: echo_data,
  542. };
  543. echo_repr.emit(&mut packet, &ChecksumCapabilities::default());
  544. let icmp_data = &*packet.into_inner();
  545. let ipv4_repr = Ipv4Repr {
  546. src_addr: Ipv4Address::new(0x7f, 0x00, 0x00, 0x02),
  547. dst_addr: Ipv4Address::new(0x7f, 0x00, 0x00, 0x01),
  548. next_header: IpProtocol::Icmp,
  549. payload_len: 24,
  550. hop_limit: 64,
  551. };
  552. // Open a socket and ensure the packet is handled due to the listening
  553. // socket.
  554. assert!(!sockets.get_mut::<icmp::Socket>(socket_handle).can_recv());
  555. // Confirm we still get EchoReply from `smoltcp` even with the ICMP socket listening
  556. let echo_reply = Icmpv4Repr::EchoReply {
  557. ident,
  558. seq_no,
  559. data: echo_data,
  560. };
  561. let ipv4_reply = Ipv4Repr {
  562. src_addr: ipv4_repr.dst_addr,
  563. dst_addr: ipv4_repr.src_addr,
  564. ..ipv4_repr
  565. };
  566. assert_eq!(
  567. iface
  568. .inner
  569. .process_icmpv4(&mut sockets, ipv4_repr, icmp_data),
  570. Some(Packet::new_ipv4(ipv4_reply, IpPayload::Icmpv4(echo_reply)))
  571. );
  572. let socket = sockets.get_mut::<icmp::Socket>(socket_handle);
  573. assert!(socket.can_recv());
  574. assert_eq!(
  575. socket.recv(),
  576. Ok((
  577. icmp_data,
  578. IpAddress::Ipv4(Ipv4Address::new(0x7f, 0x00, 0x00, 0x02))
  579. ))
  580. );
  581. }
  582. #[rstest]
  583. #[case(Medium::Ip)]
  584. #[cfg(all(feature = "proto-igmp", feature = "medium-ip"))]
  585. #[case(Medium::Ethernet)]
  586. #[cfg(all(feature = "proto-igmp", feature = "medium-ethernet"))]
  587. fn test_handle_igmp(#[case] medium: Medium) {
  588. fn recv_igmp(
  589. device: &mut crate::tests::TestingDevice,
  590. timestamp: Instant,
  591. ) -> Vec<(Ipv4Repr, IgmpRepr)> {
  592. let caps = device.capabilities();
  593. let checksum_caps = &caps.checksum;
  594. recv_all(device, timestamp)
  595. .iter()
  596. .filter_map(|frame| {
  597. let ipv4_packet = match caps.medium {
  598. #[cfg(feature = "medium-ethernet")]
  599. Medium::Ethernet => {
  600. let eth_frame = EthernetFrame::new_checked(frame).ok()?;
  601. Ipv4Packet::new_checked(eth_frame.payload()).ok()?
  602. }
  603. #[cfg(feature = "medium-ip")]
  604. Medium::Ip => Ipv4Packet::new_checked(&frame[..]).ok()?,
  605. #[cfg(feature = "medium-ieee802154")]
  606. Medium::Ieee802154 => todo!(),
  607. };
  608. let ipv4_repr = Ipv4Repr::parse(&ipv4_packet, checksum_caps).ok()?;
  609. let ip_payload = ipv4_packet.payload();
  610. let igmp_packet = IgmpPacket::new_checked(ip_payload).ok()?;
  611. let igmp_repr = IgmpRepr::parse(&igmp_packet).ok()?;
  612. Some((ipv4_repr, igmp_repr))
  613. })
  614. .collect::<Vec<_>>()
  615. }
  616. let groups = [
  617. Ipv4Address::new(224, 0, 0, 22),
  618. Ipv4Address::new(224, 0, 0, 56),
  619. ];
  620. let (mut iface, mut sockets, mut device) = setup(medium);
  621. // Join multicast groups
  622. let timestamp = Instant::ZERO;
  623. for group in &groups {
  624. iface
  625. .join_multicast_group(&mut device, *group, timestamp)
  626. .unwrap();
  627. }
  628. let reports = recv_igmp(&mut device, timestamp);
  629. assert_eq!(reports.len(), 2);
  630. for (i, group_addr) in groups.iter().enumerate() {
  631. assert_eq!(reports[i].0.next_header, IpProtocol::Igmp);
  632. assert_eq!(reports[i].0.dst_addr, *group_addr);
  633. assert_eq!(
  634. reports[i].1,
  635. IgmpRepr::MembershipReport {
  636. group_addr: *group_addr,
  637. version: IgmpVersion::Version2,
  638. }
  639. );
  640. }
  641. // General query
  642. let timestamp = Instant::ZERO;
  643. const GENERAL_QUERY_BYTES: &[u8] = &[
  644. 0x46, 0xc0, 0x00, 0x24, 0xed, 0xb4, 0x00, 0x00, 0x01, 0x02, 0x47, 0x43, 0xac, 0x16, 0x63,
  645. 0x04, 0xe0, 0x00, 0x00, 0x01, 0x94, 0x04, 0x00, 0x00, 0x11, 0x64, 0xec, 0x8f, 0x00, 0x00,
  646. 0x00, 0x00, 0x02, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  647. 0x00,
  648. ];
  649. {
  650. // Transmit GENERAL_QUERY_BYTES into loopback
  651. let tx_token = device.transmit(timestamp).unwrap();
  652. tx_token.consume(GENERAL_QUERY_BYTES.len(), |buffer| {
  653. buffer.copy_from_slice(GENERAL_QUERY_BYTES);
  654. });
  655. }
  656. // Trigger processing until all packets received through the
  657. // loopback have been processed, including responses to
  658. // GENERAL_QUERY_BYTES. Therefore `recv_all()` would return 0
  659. // pkts that could be checked.
  660. iface.socket_ingress(&mut device, &mut sockets);
  661. // Leave multicast groups
  662. let timestamp = Instant::ZERO;
  663. for group in &groups {
  664. iface
  665. .leave_multicast_group(&mut device, *group, timestamp)
  666. .unwrap();
  667. }
  668. let leaves = recv_igmp(&mut device, timestamp);
  669. assert_eq!(leaves.len(), 2);
  670. for (i, group_addr) in groups.iter().cloned().enumerate() {
  671. assert_eq!(leaves[i].0.next_header, IpProtocol::Igmp);
  672. assert_eq!(leaves[i].0.dst_addr, Ipv4Address::MULTICAST_ALL_ROUTERS);
  673. assert_eq!(leaves[i].1, IgmpRepr::LeaveGroup { group_addr });
  674. }
  675. }
  676. #[rstest]
  677. #[case(Medium::Ip)]
  678. #[cfg(all(feature = "socket-raw", feature = "medium-ip"))]
  679. #[case(Medium::Ethernet)]
  680. #[cfg(all(feature = "socket-raw", feature = "medium-ethernet"))]
  681. fn test_raw_socket_no_reply(#[case] medium: Medium) {
  682. use crate::wire::{IpVersion, UdpPacket, UdpRepr};
  683. let (mut iface, mut sockets, _) = setup(medium);
  684. let packets = 1;
  685. let rx_buffer =
  686. raw::PacketBuffer::new(vec![raw::PacketMetadata::EMPTY; packets], vec![0; 48 * 1]);
  687. let tx_buffer = raw::PacketBuffer::new(
  688. vec![raw::PacketMetadata::EMPTY; packets],
  689. vec![0; 48 * packets],
  690. );
  691. let raw_socket = raw::Socket::new(IpVersion::Ipv4, IpProtocol::Udp, rx_buffer, tx_buffer);
  692. sockets.add(raw_socket);
  693. let src_addr = Ipv4Address([127, 0, 0, 2]);
  694. let dst_addr = Ipv4Address([127, 0, 0, 1]);
  695. const PAYLOAD_LEN: usize = 10;
  696. let udp_repr = UdpRepr {
  697. src_port: 67,
  698. dst_port: 68,
  699. };
  700. let mut bytes = vec![0xff; udp_repr.header_len() + PAYLOAD_LEN];
  701. let mut packet = UdpPacket::new_unchecked(&mut bytes[..]);
  702. udp_repr.emit(
  703. &mut packet,
  704. &src_addr.into(),
  705. &dst_addr.into(),
  706. PAYLOAD_LEN,
  707. |buf| fill_slice(buf, 0x2a),
  708. &ChecksumCapabilities::default(),
  709. );
  710. let ipv4_repr = Ipv4Repr {
  711. src_addr,
  712. dst_addr,
  713. next_header: IpProtocol::Udp,
  714. hop_limit: 64,
  715. payload_len: udp_repr.header_len() + PAYLOAD_LEN,
  716. };
  717. // Emit to frame
  718. let mut bytes = vec![0u8; ipv4_repr.buffer_len() + udp_repr.header_len() + PAYLOAD_LEN];
  719. let frame = {
  720. ipv4_repr.emit(
  721. &mut Ipv4Packet::new_unchecked(&mut bytes),
  722. &ChecksumCapabilities::default(),
  723. );
  724. udp_repr.emit(
  725. &mut UdpPacket::new_unchecked(&mut bytes[ipv4_repr.buffer_len()..]),
  726. &src_addr.into(),
  727. &dst_addr.into(),
  728. PAYLOAD_LEN,
  729. |buf| fill_slice(buf, 0x2a),
  730. &ChecksumCapabilities::default(),
  731. );
  732. Ipv4Packet::new_unchecked(&bytes[..])
  733. };
  734. assert_eq!(
  735. iface.inner.process_ipv4(
  736. &mut sockets,
  737. PacketMeta::default(),
  738. &frame,
  739. &mut iface.fragments
  740. ),
  741. None
  742. );
  743. }
  744. #[rstest]
  745. #[case(Medium::Ip)]
  746. #[cfg(all(feature = "socket-raw", feature = "socket-udp", feature = "medium-ip"))]
  747. #[case(Medium::Ethernet)]
  748. #[cfg(all(
  749. feature = "socket-raw",
  750. feature = "socket-udp",
  751. feature = "medium-ethernet"
  752. ))]
  753. fn test_raw_socket_with_udp_socket(#[case] medium: Medium) {
  754. use crate::socket::udp;
  755. use crate::wire::{IpEndpoint, IpVersion, UdpPacket, UdpRepr};
  756. static UDP_PAYLOAD: [u8; 5] = [0x48, 0x65, 0x6c, 0x6c, 0x6f];
  757. let (mut iface, mut sockets, _) = setup(medium);
  758. let udp_rx_buffer = udp::PacketBuffer::new(vec![udp::PacketMetadata::EMPTY], vec![0; 15]);
  759. let udp_tx_buffer = udp::PacketBuffer::new(vec![udp::PacketMetadata::EMPTY], vec![0; 15]);
  760. let udp_socket = udp::Socket::new(udp_rx_buffer, udp_tx_buffer);
  761. let udp_socket_handle = sockets.add(udp_socket);
  762. // Bind the socket to port 68
  763. let socket = sockets.get_mut::<udp::Socket>(udp_socket_handle);
  764. assert_eq!(socket.bind(68), Ok(()));
  765. assert!(!socket.can_recv());
  766. assert!(socket.can_send());
  767. let packets = 1;
  768. let raw_rx_buffer =
  769. raw::PacketBuffer::new(vec![raw::PacketMetadata::EMPTY; packets], vec![0; 48 * 1]);
  770. let raw_tx_buffer = raw::PacketBuffer::new(
  771. vec![raw::PacketMetadata::EMPTY; packets],
  772. vec![0; 48 * packets],
  773. );
  774. let raw_socket = raw::Socket::new(
  775. IpVersion::Ipv4,
  776. IpProtocol::Udp,
  777. raw_rx_buffer,
  778. raw_tx_buffer,
  779. );
  780. sockets.add(raw_socket);
  781. let src_addr = Ipv4Address([127, 0, 0, 2]);
  782. let dst_addr = Ipv4Address([127, 0, 0, 1]);
  783. let udp_repr = UdpRepr {
  784. src_port: 67,
  785. dst_port: 68,
  786. };
  787. let mut bytes = vec![0xff; udp_repr.header_len() + UDP_PAYLOAD.len()];
  788. let mut packet = UdpPacket::new_unchecked(&mut bytes[..]);
  789. udp_repr.emit(
  790. &mut packet,
  791. &src_addr.into(),
  792. &dst_addr.into(),
  793. UDP_PAYLOAD.len(),
  794. |buf| buf.copy_from_slice(&UDP_PAYLOAD),
  795. &ChecksumCapabilities::default(),
  796. );
  797. let ipv4_repr = Ipv4Repr {
  798. src_addr,
  799. dst_addr,
  800. next_header: IpProtocol::Udp,
  801. hop_limit: 64,
  802. payload_len: udp_repr.header_len() + UDP_PAYLOAD.len(),
  803. };
  804. // Emit to frame
  805. let mut bytes = vec![0u8; ipv4_repr.buffer_len() + udp_repr.header_len() + UDP_PAYLOAD.len()];
  806. let frame = {
  807. ipv4_repr.emit(
  808. &mut Ipv4Packet::new_unchecked(&mut bytes),
  809. &ChecksumCapabilities::default(),
  810. );
  811. udp_repr.emit(
  812. &mut UdpPacket::new_unchecked(&mut bytes[ipv4_repr.buffer_len()..]),
  813. &src_addr.into(),
  814. &dst_addr.into(),
  815. UDP_PAYLOAD.len(),
  816. |buf| buf.copy_from_slice(&UDP_PAYLOAD),
  817. &ChecksumCapabilities::default(),
  818. );
  819. Ipv4Packet::new_unchecked(&bytes[..])
  820. };
  821. assert_eq!(
  822. iface.inner.process_ipv4(
  823. &mut sockets,
  824. PacketMeta::default(),
  825. &frame,
  826. &mut iface.fragments
  827. ),
  828. None
  829. );
  830. // Make sure the UDP socket can still receive in presence of a Raw socket that handles UDP
  831. let socket = sockets.get_mut::<udp::Socket>(udp_socket_handle);
  832. assert!(socket.can_recv());
  833. assert_eq!(
  834. socket.recv(),
  835. Ok((
  836. &UDP_PAYLOAD[..],
  837. IpEndpoint::new(src_addr.into(), 67).into()
  838. ))
  839. );
  840. }
  841. #[rstest]
  842. #[case(Medium::Ip)]
  843. #[cfg(all(feature = "socket-udp", feature = "medium-ip"))]
  844. #[case(Medium::Ethernet)]
  845. #[cfg(all(feature = "socket-udp", feature = "medium-ethernet"))]
  846. fn test_icmp_reply_size(#[case] medium: Medium) {
  847. use crate::wire::IPV4_MIN_MTU as MIN_MTU;
  848. const MAX_PAYLOAD_LEN: usize = 528;
  849. let (mut iface, mut sockets, _device) = setup(medium);
  850. let src_addr = Ipv4Address([192, 168, 1, 1]);
  851. let dst_addr = Ipv4Address([192, 168, 1, 2]);
  852. // UDP packet that if not tructated will cause a icmp port unreachable reply
  853. // to exceed the minimum mtu bytes in length.
  854. let udp_repr = UdpRepr {
  855. src_port: 67,
  856. dst_port: 68,
  857. };
  858. let mut bytes = vec![0xff; udp_repr.header_len() + MAX_PAYLOAD_LEN];
  859. let mut packet = UdpPacket::new_unchecked(&mut bytes[..]);
  860. udp_repr.emit(
  861. &mut packet,
  862. &src_addr.into(),
  863. &dst_addr.into(),
  864. MAX_PAYLOAD_LEN,
  865. |buf| fill_slice(buf, 0x2a),
  866. &ChecksumCapabilities::default(),
  867. );
  868. let ip_repr = Ipv4Repr {
  869. src_addr,
  870. dst_addr,
  871. next_header: IpProtocol::Udp,
  872. hop_limit: 64,
  873. payload_len: udp_repr.header_len() + MAX_PAYLOAD_LEN,
  874. };
  875. let payload = packet.into_inner();
  876. let expected_icmp_repr = Icmpv4Repr::DstUnreachable {
  877. reason: Icmpv4DstUnreachable::PortUnreachable,
  878. header: ip_repr,
  879. data: &payload[..MAX_PAYLOAD_LEN],
  880. };
  881. let expected_ip_repr = Ipv4Repr {
  882. src_addr: dst_addr,
  883. dst_addr: src_addr,
  884. next_header: IpProtocol::Icmp,
  885. hop_limit: 64,
  886. payload_len: expected_icmp_repr.buffer_len(),
  887. };
  888. assert_eq!(
  889. expected_ip_repr.buffer_len() + expected_icmp_repr.buffer_len(),
  890. MIN_MTU
  891. );
  892. assert_eq!(
  893. iface.inner.process_udp(
  894. &mut sockets,
  895. PacketMeta::default(),
  896. false,
  897. ip_repr.into(),
  898. payload,
  899. ),
  900. Some(Packet::new_ipv4(
  901. expected_ip_repr,
  902. IpPayload::Icmpv4(expected_icmp_repr)
  903. ))
  904. );
  905. }