ipv4.rs 31 KB

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