icmp.rs 39 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153
  1. use core::cmp;
  2. #[cfg(feature = "async")]
  3. use core::task::Waker;
  4. use crate::phy::ChecksumCapabilities;
  5. #[cfg(feature = "async")]
  6. use crate::socket::WakerRegistration;
  7. use crate::socket::{Context, PollAt};
  8. use crate::storage::Empty;
  9. use crate::wire::IcmpRepr;
  10. #[cfg(feature = "proto-ipv4")]
  11. use crate::wire::{Icmpv4Packet, Icmpv4Repr, Ipv4Repr};
  12. #[cfg(feature = "proto-ipv6")]
  13. use crate::wire::{Icmpv6Packet, Icmpv6Repr, Ipv6Repr};
  14. use crate::wire::{IpAddress, IpListenEndpoint, IpProtocol, IpRepr};
  15. use crate::wire::{UdpPacket, UdpRepr};
  16. /// Error returned by [`Socket::bind`]
  17. #[derive(Debug, PartialEq, Eq, Clone, Copy)]
  18. #[cfg_attr(feature = "defmt", derive(defmt::Format))]
  19. pub enum BindError {
  20. InvalidState,
  21. Unaddressable,
  22. }
  23. impl core::fmt::Display for BindError {
  24. fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
  25. match self {
  26. BindError::InvalidState => write!(f, "invalid state"),
  27. BindError::Unaddressable => write!(f, "unaddressable"),
  28. }
  29. }
  30. }
  31. #[cfg(feature = "std")]
  32. impl std::error::Error for BindError {}
  33. /// Error returned by [`Socket::send`]
  34. #[derive(Debug, PartialEq, Eq, Clone, Copy)]
  35. #[cfg_attr(feature = "defmt", derive(defmt::Format))]
  36. pub enum SendError {
  37. Unaddressable,
  38. BufferFull,
  39. }
  40. impl core::fmt::Display for SendError {
  41. fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
  42. match self {
  43. SendError::Unaddressable => write!(f, "unaddressable"),
  44. SendError::BufferFull => write!(f, "buffer full"),
  45. }
  46. }
  47. }
  48. #[cfg(feature = "std")]
  49. impl std::error::Error for SendError {}
  50. /// Error returned by [`Socket::recv`]
  51. #[derive(Debug, PartialEq, Eq, Clone, Copy)]
  52. #[cfg_attr(feature = "defmt", derive(defmt::Format))]
  53. pub enum RecvError {
  54. Exhausted,
  55. }
  56. impl core::fmt::Display for RecvError {
  57. fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
  58. match self {
  59. RecvError::Exhausted => write!(f, "exhausted"),
  60. }
  61. }
  62. }
  63. #[cfg(feature = "std")]
  64. impl std::error::Error for RecvError {}
  65. /// Type of endpoint to bind the ICMP socket to. See [IcmpSocket::bind] for
  66. /// more details.
  67. ///
  68. /// [IcmpSocket::bind]: struct.IcmpSocket.html#method.bind
  69. #[derive(Debug, Default, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
  70. #[cfg_attr(feature = "defmt", derive(defmt::Format))]
  71. pub enum Endpoint {
  72. #[default]
  73. Unspecified,
  74. Ident(u16),
  75. Udp(IpListenEndpoint),
  76. }
  77. impl Endpoint {
  78. pub fn is_specified(&self) -> bool {
  79. match *self {
  80. Endpoint::Ident(_) => true,
  81. Endpoint::Udp(endpoint) => endpoint.port != 0,
  82. Endpoint::Unspecified => false,
  83. }
  84. }
  85. }
  86. /// An ICMP packet metadata.
  87. pub type PacketMetadata = crate::storage::PacketMetadata<IpAddress>;
  88. /// An ICMP packet ring buffer.
  89. pub type PacketBuffer<'a> = crate::storage::PacketBuffer<'a, IpAddress>;
  90. /// A ICMP socket
  91. ///
  92. /// An ICMP socket is bound to a specific [IcmpEndpoint] which may
  93. /// be a specific UDP port to listen for ICMP error messages related
  94. /// to the port or a specific ICMP identifier value. See [bind] for
  95. /// more details.
  96. ///
  97. /// [IcmpEndpoint]: enum.IcmpEndpoint.html
  98. /// [bind]: #method.bind
  99. #[derive(Debug)]
  100. pub struct Socket<'a> {
  101. rx_buffer: PacketBuffer<'a>,
  102. tx_buffer: PacketBuffer<'a>,
  103. /// The endpoint this socket is communicating with
  104. endpoint: Endpoint,
  105. /// The time-to-live (IPv4) or hop limit (IPv6) value used in outgoing packets.
  106. hop_limit: Option<u8>,
  107. #[cfg(feature = "async")]
  108. rx_waker: WakerRegistration,
  109. #[cfg(feature = "async")]
  110. tx_waker: WakerRegistration,
  111. }
  112. impl<'a> Socket<'a> {
  113. /// Create an ICMP socket with the given buffers.
  114. pub fn new(rx_buffer: PacketBuffer<'a>, tx_buffer: PacketBuffer<'a>) -> Socket<'a> {
  115. Socket {
  116. rx_buffer: rx_buffer,
  117. tx_buffer: tx_buffer,
  118. endpoint: Default::default(),
  119. hop_limit: None,
  120. #[cfg(feature = "async")]
  121. rx_waker: WakerRegistration::new(),
  122. #[cfg(feature = "async")]
  123. tx_waker: WakerRegistration::new(),
  124. }
  125. }
  126. /// Register a waker for receive operations.
  127. ///
  128. /// The waker is woken on state changes that might affect the return value
  129. /// of `recv` method calls, such as receiving data, or the socket closing.
  130. ///
  131. /// Notes:
  132. ///
  133. /// - Only one waker can be registered at a time. If another waker was previously registered,
  134. /// it is overwritten and will no longer be woken.
  135. /// - The Waker is woken only once. Once woken, you must register it again to receive more wakes.
  136. /// - "Spurious wakes" are allowed: a wake doesn't guarantee the result of `recv` has
  137. /// necessarily changed.
  138. #[cfg(feature = "async")]
  139. pub fn register_recv_waker(&mut self, waker: &Waker) {
  140. self.rx_waker.register(waker)
  141. }
  142. /// Register a waker for send operations.
  143. ///
  144. /// The waker is woken on state changes that might affect the return value
  145. /// of `send` method calls, such as space becoming available in the transmit
  146. /// buffer, or the socket closing.
  147. ///
  148. /// Notes:
  149. ///
  150. /// - Only one waker can be registered at a time. If another waker was previously registered,
  151. /// it is overwritten and will no longer be woken.
  152. /// - The Waker is woken only once. Once woken, you must register it again to receive more wakes.
  153. /// - "Spurious wakes" are allowed: a wake doesn't guarantee the result of `send` has
  154. /// necessarily changed.
  155. #[cfg(feature = "async")]
  156. pub fn register_send_waker(&mut self, waker: &Waker) {
  157. self.tx_waker.register(waker)
  158. }
  159. /// Return the time-to-live (IPv4) or hop limit (IPv6) value used in outgoing packets.
  160. ///
  161. /// See also the [set_hop_limit](#method.set_hop_limit) method
  162. pub fn hop_limit(&self) -> Option<u8> {
  163. self.hop_limit
  164. }
  165. /// Set the time-to-live (IPv4) or hop limit (IPv6) value used in outgoing packets.
  166. ///
  167. /// A socket without an explicitly set hop limit value uses the default [IANA recommended]
  168. /// value (64).
  169. ///
  170. /// # Panics
  171. ///
  172. /// This function panics if a hop limit value of 0 is given. See [RFC 1122 § 3.2.1.7].
  173. ///
  174. /// [IANA recommended]: https://www.iana.org/assignments/ip-parameters/ip-parameters.xhtml
  175. /// [RFC 1122 § 3.2.1.7]: https://tools.ietf.org/html/rfc1122#section-3.2.1.7
  176. pub fn set_hop_limit(&mut self, hop_limit: Option<u8>) {
  177. // A host MUST NOT send a datagram with a hop limit value of 0
  178. if let Some(0) = hop_limit {
  179. panic!("the time-to-live value of a packet must not be zero")
  180. }
  181. self.hop_limit = hop_limit
  182. }
  183. /// Bind the socket to the given endpoint.
  184. ///
  185. /// This function returns `Err(Error::Illegal)` if the socket was open
  186. /// (see [is_open](#method.is_open)), and `Err(Error::Unaddressable)`
  187. /// if `endpoint` is unspecified (see [is_specified]).
  188. ///
  189. /// # Examples
  190. ///
  191. /// ## Bind to ICMP Error messages associated with a specific UDP port:
  192. ///
  193. /// To [recv] ICMP error messages that are associated with a specific local
  194. /// UDP port, the socket may be bound to a given port using [IcmpEndpoint::Udp].
  195. /// This may be useful for applications using UDP attempting to detect and/or
  196. /// diagnose connection problems.
  197. ///
  198. /// ```
  199. /// use smoltcp::wire::IpListenEndpoint;
  200. /// use smoltcp::socket::icmp;
  201. /// # let rx_buffer = icmp::PacketBuffer::new(vec![icmp::PacketMetadata::EMPTY], vec![0; 20]);
  202. /// # let tx_buffer = icmp::PacketBuffer::new(vec![icmp::PacketMetadata::EMPTY], vec![0; 20]);
  203. ///
  204. /// let mut icmp_socket = // ...
  205. /// # icmp::Socket::new(rx_buffer, tx_buffer);
  206. ///
  207. /// // Bind to ICMP error responses for UDP packets sent from port 53.
  208. /// let endpoint = IpListenEndpoint::from(53);
  209. /// icmp_socket.bind(icmp::Endpoint::Udp(endpoint)).unwrap();
  210. /// ```
  211. ///
  212. /// ## Bind to a specific ICMP identifier:
  213. ///
  214. /// To [send] and [recv] ICMP packets that are not associated with a specific UDP
  215. /// port, the socket may be bound to a specific ICMP identifier using
  216. /// [IcmpEndpoint::Ident]. This is useful for sending and receiving Echo Request/Reply
  217. /// messages.
  218. ///
  219. /// ```
  220. /// use smoltcp::wire::IpListenEndpoint;
  221. /// use smoltcp::socket::icmp;
  222. /// # let rx_buffer = icmp::PacketBuffer::new(vec![icmp::PacketMetadata::EMPTY], vec![0; 20]);
  223. /// # let tx_buffer = icmp::PacketBuffer::new(vec![icmp::PacketMetadata::EMPTY], vec![0; 20]);
  224. ///
  225. /// let mut icmp_socket = // ...
  226. /// # icmp::Socket::new(rx_buffer, tx_buffer);
  227. ///
  228. /// // Bind to ICMP messages with the ICMP identifier 0x1234
  229. /// icmp_socket.bind(icmp::Endpoint::Ident(0x1234)).unwrap();
  230. /// ```
  231. ///
  232. /// [is_specified]: enum.IcmpEndpoint.html#method.is_specified
  233. /// [IcmpEndpoint::Ident]: enum.IcmpEndpoint.html#variant.Ident
  234. /// [IcmpEndpoint::Udp]: enum.IcmpEndpoint.html#variant.Udp
  235. /// [send]: #method.send
  236. /// [recv]: #method.recv
  237. pub fn bind<T: Into<Endpoint>>(&mut self, endpoint: T) -> Result<(), BindError> {
  238. let endpoint = endpoint.into();
  239. if !endpoint.is_specified() {
  240. return Err(BindError::Unaddressable);
  241. }
  242. if self.is_open() {
  243. return Err(BindError::InvalidState);
  244. }
  245. self.endpoint = endpoint;
  246. #[cfg(feature = "async")]
  247. {
  248. self.rx_waker.wake();
  249. self.tx_waker.wake();
  250. }
  251. Ok(())
  252. }
  253. /// Check whether the transmit buffer is full.
  254. #[inline]
  255. pub fn can_send(&self) -> bool {
  256. !self.tx_buffer.is_full()
  257. }
  258. /// Check whether the receive buffer is not empty.
  259. #[inline]
  260. pub fn can_recv(&self) -> bool {
  261. !self.rx_buffer.is_empty()
  262. }
  263. /// Return the maximum number packets the socket can receive.
  264. #[inline]
  265. pub fn packet_recv_capacity(&self) -> usize {
  266. self.rx_buffer.packet_capacity()
  267. }
  268. /// Return the maximum number packets the socket can transmit.
  269. #[inline]
  270. pub fn packet_send_capacity(&self) -> usize {
  271. self.tx_buffer.packet_capacity()
  272. }
  273. /// Return the maximum number of bytes inside the recv buffer.
  274. #[inline]
  275. pub fn payload_recv_capacity(&self) -> usize {
  276. self.rx_buffer.payload_capacity()
  277. }
  278. /// Return the maximum number of bytes inside the transmit buffer.
  279. #[inline]
  280. pub fn payload_send_capacity(&self) -> usize {
  281. self.tx_buffer.payload_capacity()
  282. }
  283. /// Check whether the socket is open.
  284. #[inline]
  285. pub fn is_open(&self) -> bool {
  286. self.endpoint != Endpoint::Unspecified
  287. }
  288. /// Enqueue a packet to be sent to a given remote address, and return a pointer
  289. /// to its payload.
  290. ///
  291. /// This function returns `Err(Error::Exhausted)` if the transmit buffer is full,
  292. /// `Err(Error::Truncated)` if the requested size is larger than the packet buffer
  293. /// size, and `Err(Error::Unaddressable)` if the remote address is unspecified.
  294. pub fn send(&mut self, size: usize, endpoint: IpAddress) -> Result<&mut [u8], SendError> {
  295. if endpoint.is_unspecified() {
  296. return Err(SendError::Unaddressable);
  297. }
  298. let packet_buf = self
  299. .tx_buffer
  300. .enqueue(size, endpoint)
  301. .map_err(|_| SendError::BufferFull)?;
  302. net_trace!("icmp:{}: buffer to send {} octets", endpoint, size);
  303. Ok(packet_buf)
  304. }
  305. /// Enqueue a packet to be send to a given remote address and pass the buffer
  306. /// to the provided closure. The closure then returns the size of the data written
  307. /// into the buffer.
  308. ///
  309. /// Also see [send](#method.send).
  310. pub fn send_with<F>(
  311. &mut self,
  312. max_size: usize,
  313. endpoint: IpAddress,
  314. f: F,
  315. ) -> Result<usize, SendError>
  316. where
  317. F: FnOnce(&mut [u8]) -> usize,
  318. {
  319. if endpoint.is_unspecified() {
  320. return Err(SendError::Unaddressable);
  321. }
  322. let size = self
  323. .tx_buffer
  324. .enqueue_with_infallible(max_size, endpoint, f)
  325. .map_err(|_| SendError::BufferFull)?;
  326. net_trace!("icmp:{}: buffer to send {} octets", endpoint, size);
  327. Ok(size)
  328. }
  329. /// Enqueue a packet to be sent to a given remote address, and fill it from a slice.
  330. ///
  331. /// See also [send](#method.send).
  332. pub fn send_slice(&mut self, data: &[u8], endpoint: IpAddress) -> Result<(), SendError> {
  333. let packet_buf = self.send(data.len(), endpoint)?;
  334. packet_buf.copy_from_slice(data);
  335. Ok(())
  336. }
  337. /// Dequeue a packet received from a remote endpoint, and return the `IpAddress` as well
  338. /// as a pointer to the payload.
  339. ///
  340. /// This function returns `Err(Error::Exhausted)` if the receive buffer is empty.
  341. pub fn recv(&mut self) -> Result<(&[u8], IpAddress), RecvError> {
  342. let (endpoint, packet_buf) = self.rx_buffer.dequeue().map_err(|_| RecvError::Exhausted)?;
  343. net_trace!(
  344. "icmp:{}: receive {} buffered octets",
  345. endpoint,
  346. packet_buf.len()
  347. );
  348. Ok((packet_buf, endpoint))
  349. }
  350. /// Dequeue a packet received from a remote endpoint, copy the payload into the given slice,
  351. /// and return the amount of octets copied as well as the `IpAddress`
  352. ///
  353. /// See also [recv](#method.recv).
  354. pub fn recv_slice(&mut self, data: &mut [u8]) -> Result<(usize, IpAddress), RecvError> {
  355. let (buffer, endpoint) = self.recv()?;
  356. let length = cmp::min(data.len(), buffer.len());
  357. data[..length].copy_from_slice(&buffer[..length]);
  358. Ok((length, endpoint))
  359. }
  360. /// Filter determining which packets received by the interface are appended to
  361. /// the given sockets received buffer.
  362. pub(crate) fn accepts(&self, cx: &mut Context, ip_repr: &IpRepr, icmp_repr: &IcmpRepr) -> bool {
  363. match (&self.endpoint, icmp_repr) {
  364. // If we are bound to ICMP errors associated to a UDP port, only
  365. // accept Destination Unreachable or Time Exceeded messages with
  366. // the data containing a UDP packet send from the local port we
  367. // are bound to.
  368. #[cfg(feature = "proto-ipv4")]
  369. (
  370. &Endpoint::Udp(endpoint),
  371. &IcmpRepr::Ipv4(
  372. Icmpv4Repr::DstUnreachable { data, header, .. }
  373. | Icmpv4Repr::TimeExceeded { data, header, .. },
  374. ),
  375. ) if endpoint.addr.is_none() || endpoint.addr == Some(ip_repr.dst_addr()) => {
  376. let packet = UdpPacket::new_unchecked(data);
  377. match UdpRepr::parse(
  378. &packet,
  379. &header.src_addr.into(),
  380. &header.dst_addr.into(),
  381. &cx.checksum_caps(),
  382. ) {
  383. Ok(repr) => endpoint.port == repr.src_port,
  384. Err(_) => false,
  385. }
  386. }
  387. #[cfg(feature = "proto-ipv6")]
  388. (
  389. &Endpoint::Udp(endpoint),
  390. &IcmpRepr::Ipv6(
  391. Icmpv6Repr::DstUnreachable { data, header, .. }
  392. | Icmpv6Repr::TimeExceeded { data, header, .. },
  393. ),
  394. ) if endpoint.addr.is_none() || endpoint.addr == Some(ip_repr.dst_addr()) => {
  395. let packet = UdpPacket::new_unchecked(data);
  396. match UdpRepr::parse(
  397. &packet,
  398. &header.src_addr.into(),
  399. &header.dst_addr.into(),
  400. &cx.checksum_caps(),
  401. ) {
  402. Ok(repr) => endpoint.port == repr.src_port,
  403. Err(_) => false,
  404. }
  405. }
  406. // If we are bound to a specific ICMP identifier value, only accept an
  407. // Echo Request/Reply with the identifier field matching the endpoint
  408. // port.
  409. #[cfg(feature = "proto-ipv4")]
  410. (
  411. &Endpoint::Ident(bound_ident),
  412. &IcmpRepr::Ipv4(Icmpv4Repr::EchoRequest { ident, .. }),
  413. )
  414. | (
  415. &Endpoint::Ident(bound_ident),
  416. &IcmpRepr::Ipv4(Icmpv4Repr::EchoReply { ident, .. }),
  417. ) => ident == bound_ident,
  418. #[cfg(feature = "proto-ipv6")]
  419. (
  420. &Endpoint::Ident(bound_ident),
  421. &IcmpRepr::Ipv6(Icmpv6Repr::EchoRequest { ident, .. }),
  422. )
  423. | (
  424. &Endpoint::Ident(bound_ident),
  425. &IcmpRepr::Ipv6(Icmpv6Repr::EchoReply { ident, .. }),
  426. ) => ident == bound_ident,
  427. _ => false,
  428. }
  429. }
  430. pub(crate) fn process(&mut self, _cx: &mut Context, ip_repr: &IpRepr, icmp_repr: &IcmpRepr) {
  431. match icmp_repr {
  432. #[cfg(feature = "proto-ipv4")]
  433. IcmpRepr::Ipv4(icmp_repr) => {
  434. net_trace!("icmp: receiving {} octets", icmp_repr.buffer_len());
  435. match self
  436. .rx_buffer
  437. .enqueue(icmp_repr.buffer_len(), ip_repr.src_addr())
  438. {
  439. Ok(packet_buf) => {
  440. icmp_repr.emit(
  441. &mut Icmpv4Packet::new_unchecked(packet_buf),
  442. &ChecksumCapabilities::default(),
  443. );
  444. }
  445. Err(_) => net_trace!("icmp: buffer full, dropped incoming packet"),
  446. }
  447. }
  448. #[cfg(feature = "proto-ipv6")]
  449. IcmpRepr::Ipv6(icmp_repr) => {
  450. net_trace!("icmp: receiving {} octets", icmp_repr.buffer_len());
  451. match self
  452. .rx_buffer
  453. .enqueue(icmp_repr.buffer_len(), ip_repr.src_addr())
  454. {
  455. Ok(packet_buf) => icmp_repr.emit(
  456. &ip_repr.src_addr(),
  457. &ip_repr.dst_addr(),
  458. &mut Icmpv6Packet::new_unchecked(packet_buf),
  459. &ChecksumCapabilities::default(),
  460. ),
  461. Err(_) => net_trace!("icmp: buffer full, dropped incoming packet"),
  462. }
  463. }
  464. }
  465. #[cfg(feature = "async")]
  466. self.rx_waker.wake();
  467. }
  468. pub(crate) fn dispatch<F, E>(&mut self, cx: &mut Context, emit: F) -> Result<(), E>
  469. where
  470. F: FnOnce(&mut Context, (IpRepr, IcmpRepr)) -> Result<(), E>,
  471. {
  472. let hop_limit = self.hop_limit.unwrap_or(64);
  473. let res = self.tx_buffer.dequeue_with(|remote_endpoint, packet_buf| {
  474. net_trace!(
  475. "icmp:{}: sending {} octets",
  476. remote_endpoint,
  477. packet_buf.len()
  478. );
  479. match *remote_endpoint {
  480. #[cfg(feature = "proto-ipv4")]
  481. IpAddress::Ipv4(dst_addr) => {
  482. let src_addr = match cx.get_source_address_ipv4(dst_addr) {
  483. Some(addr) => addr,
  484. None => {
  485. net_trace!(
  486. "icmp:{}: not find suitable source address, dropping",
  487. remote_endpoint
  488. );
  489. return Ok(());
  490. }
  491. };
  492. let packet = Icmpv4Packet::new_unchecked(&*packet_buf);
  493. let repr = match Icmpv4Repr::parse(&packet, &ChecksumCapabilities::ignored()) {
  494. Ok(x) => x,
  495. Err(_) => {
  496. net_trace!(
  497. "icmp:{}: malformed packet in queue, dropping",
  498. remote_endpoint
  499. );
  500. return Ok(());
  501. }
  502. };
  503. let ip_repr = IpRepr::Ipv4(Ipv4Repr {
  504. src_addr,
  505. dst_addr,
  506. next_header: IpProtocol::Icmp,
  507. payload_len: repr.buffer_len(),
  508. hop_limit: hop_limit,
  509. });
  510. emit(cx, (ip_repr, IcmpRepr::Ipv4(repr)))
  511. }
  512. #[cfg(feature = "proto-ipv6")]
  513. IpAddress::Ipv6(dst_addr) => {
  514. let src_addr = match cx.get_source_address_ipv6(dst_addr) {
  515. Some(addr) => addr,
  516. None => {
  517. net_trace!(
  518. "icmp:{}: not find suitable source address, dropping",
  519. remote_endpoint
  520. );
  521. return Ok(());
  522. }
  523. };
  524. let packet = Icmpv6Packet::new_unchecked(&*packet_buf);
  525. let repr = match Icmpv6Repr::parse(
  526. &src_addr.into(),
  527. &dst_addr.into(),
  528. &packet,
  529. &ChecksumCapabilities::ignored(),
  530. ) {
  531. Ok(x) => x,
  532. Err(_) => {
  533. net_trace!(
  534. "icmp:{}: malformed packet in queue, dropping",
  535. remote_endpoint
  536. );
  537. return Ok(());
  538. }
  539. };
  540. let ip_repr = IpRepr::Ipv6(Ipv6Repr {
  541. src_addr,
  542. dst_addr,
  543. next_header: IpProtocol::Icmpv6,
  544. payload_len: repr.buffer_len(),
  545. hop_limit: hop_limit,
  546. });
  547. emit(cx, (ip_repr, IcmpRepr::Ipv6(repr)))
  548. }
  549. }
  550. });
  551. match res {
  552. Err(Empty) => Ok(()),
  553. Ok(Err(e)) => Err(e),
  554. Ok(Ok(())) => {
  555. #[cfg(feature = "async")]
  556. self.tx_waker.wake();
  557. Ok(())
  558. }
  559. }
  560. }
  561. pub(crate) fn poll_at(&self, _cx: &mut Context) -> PollAt {
  562. if self.tx_buffer.is_empty() {
  563. PollAt::Ingress
  564. } else {
  565. PollAt::Now
  566. }
  567. }
  568. }
  569. #[cfg(test)]
  570. mod tests_common {
  571. pub use super::*;
  572. pub use crate::phy::DeviceCapabilities;
  573. pub use crate::wire::IpAddress;
  574. pub fn buffer(packets: usize) -> PacketBuffer<'static> {
  575. PacketBuffer::new(vec![PacketMetadata::EMPTY; packets], vec![0; 66 * packets])
  576. }
  577. pub fn socket(
  578. rx_buffer: PacketBuffer<'static>,
  579. tx_buffer: PacketBuffer<'static>,
  580. ) -> Socket<'static> {
  581. Socket::new(rx_buffer, tx_buffer)
  582. }
  583. pub const LOCAL_PORT: u16 = 53;
  584. pub static UDP_REPR: UdpRepr = UdpRepr {
  585. src_port: 53,
  586. dst_port: 9090,
  587. };
  588. pub static UDP_PAYLOAD: &[u8] = &[0xff; 10];
  589. }
  590. #[cfg(all(test, feature = "proto-ipv4"))]
  591. mod test_ipv4 {
  592. use super::tests_common::*;
  593. use crate::wire::{Icmpv4DstUnreachable, IpEndpoint, Ipv4Address};
  594. const REMOTE_IPV4: Ipv4Address = Ipv4Address([192, 168, 1, 2]);
  595. const LOCAL_IPV4: Ipv4Address = Ipv4Address([192, 168, 1, 1]);
  596. const LOCAL_END_V4: IpEndpoint = IpEndpoint {
  597. addr: IpAddress::Ipv4(LOCAL_IPV4),
  598. port: LOCAL_PORT,
  599. };
  600. static ECHOV4_REPR: Icmpv4Repr = Icmpv4Repr::EchoRequest {
  601. ident: 0x1234,
  602. seq_no: 0x5678,
  603. data: &[0xff; 16],
  604. };
  605. static LOCAL_IPV4_REPR: IpRepr = IpRepr::Ipv4(Ipv4Repr {
  606. src_addr: LOCAL_IPV4,
  607. dst_addr: REMOTE_IPV4,
  608. next_header: IpProtocol::Icmp,
  609. payload_len: 24,
  610. hop_limit: 0x40,
  611. });
  612. static REMOTE_IPV4_REPR: IpRepr = IpRepr::Ipv4(Ipv4Repr {
  613. src_addr: REMOTE_IPV4,
  614. dst_addr: LOCAL_IPV4,
  615. next_header: IpProtocol::Icmp,
  616. payload_len: 24,
  617. hop_limit: 0x40,
  618. });
  619. #[test]
  620. fn test_send_unaddressable() {
  621. let mut socket = socket(buffer(0), buffer(1));
  622. assert_eq!(
  623. socket.send_slice(b"abcdef", IpAddress::Ipv4(Ipv4Address::default())),
  624. Err(SendError::Unaddressable)
  625. );
  626. assert_eq!(socket.send_slice(b"abcdef", REMOTE_IPV4.into()), Ok(()));
  627. }
  628. #[test]
  629. fn test_send_dispatch() {
  630. let mut socket = socket(buffer(0), buffer(1));
  631. let mut cx = Context::mock();
  632. let checksum = ChecksumCapabilities::default();
  633. assert_eq!(
  634. socket.dispatch(&mut cx, |_, _| unreachable!()),
  635. Ok::<_, ()>(())
  636. );
  637. // This buffer is too long
  638. assert_eq!(
  639. socket.send_slice(&[0xff; 67], REMOTE_IPV4.into()),
  640. Err(SendError::BufferFull)
  641. );
  642. assert!(socket.can_send());
  643. let mut bytes = [0xff; 24];
  644. let mut packet = Icmpv4Packet::new_unchecked(&mut bytes);
  645. ECHOV4_REPR.emit(&mut packet, &checksum);
  646. assert_eq!(
  647. socket.send_slice(&*packet.into_inner(), REMOTE_IPV4.into()),
  648. Ok(())
  649. );
  650. assert_eq!(
  651. socket.send_slice(b"123456", REMOTE_IPV4.into()),
  652. Err(SendError::BufferFull)
  653. );
  654. assert!(!socket.can_send());
  655. assert_eq!(
  656. socket.dispatch(&mut cx, |_, (ip_repr, icmp_repr)| {
  657. assert_eq!(ip_repr, LOCAL_IPV4_REPR);
  658. assert_eq!(icmp_repr, ECHOV4_REPR.into());
  659. Err(())
  660. }),
  661. Err(())
  662. );
  663. // buffer is not taken off of the tx queue due to the error
  664. assert!(!socket.can_send());
  665. assert_eq!(
  666. socket.dispatch(&mut cx, |_, (ip_repr, icmp_repr)| {
  667. assert_eq!(ip_repr, LOCAL_IPV4_REPR);
  668. assert_eq!(icmp_repr, ECHOV4_REPR.into());
  669. Ok::<_, ()>(())
  670. }),
  671. Ok(())
  672. );
  673. // buffer is taken off of the queue this time
  674. assert!(socket.can_send());
  675. }
  676. #[test]
  677. fn test_set_hop_limit_v4() {
  678. let mut s = socket(buffer(0), buffer(1));
  679. let mut cx = Context::mock();
  680. let checksum = ChecksumCapabilities::default();
  681. let mut bytes = [0xff; 24];
  682. let mut packet = Icmpv4Packet::new_unchecked(&mut bytes);
  683. ECHOV4_REPR.emit(&mut packet, &checksum);
  684. s.set_hop_limit(Some(0x2a));
  685. assert_eq!(
  686. s.send_slice(&*packet.into_inner(), REMOTE_IPV4.into()),
  687. Ok(())
  688. );
  689. assert_eq!(
  690. s.dispatch(&mut cx, |_, (ip_repr, _)| {
  691. assert_eq!(
  692. ip_repr,
  693. IpRepr::Ipv4(Ipv4Repr {
  694. src_addr: LOCAL_IPV4,
  695. dst_addr: REMOTE_IPV4,
  696. next_header: IpProtocol::Icmp,
  697. payload_len: ECHOV4_REPR.buffer_len(),
  698. hop_limit: 0x2a,
  699. })
  700. );
  701. Ok::<_, ()>(())
  702. }),
  703. Ok(())
  704. );
  705. }
  706. #[test]
  707. fn test_recv_process() {
  708. let mut socket = socket(buffer(1), buffer(1));
  709. let mut cx = Context::mock();
  710. assert_eq!(socket.bind(Endpoint::Ident(0x1234)), Ok(()));
  711. assert!(!socket.can_recv());
  712. assert_eq!(socket.recv(), Err(RecvError::Exhausted));
  713. let checksum = ChecksumCapabilities::default();
  714. let mut bytes = [0xff; 24];
  715. let mut packet = Icmpv4Packet::new_unchecked(&mut bytes[..]);
  716. ECHOV4_REPR.emit(&mut packet, &checksum);
  717. let data = &*packet.into_inner();
  718. assert!(socket.accepts(&mut cx, &REMOTE_IPV4_REPR, &ECHOV4_REPR.into()));
  719. socket.process(&mut cx, &REMOTE_IPV4_REPR, &ECHOV4_REPR.into());
  720. assert!(socket.can_recv());
  721. assert!(socket.accepts(&mut cx, &REMOTE_IPV4_REPR, &ECHOV4_REPR.into()));
  722. socket.process(&mut cx, &REMOTE_IPV4_REPR, &ECHOV4_REPR.into());
  723. assert_eq!(socket.recv(), Ok((data, REMOTE_IPV4.into())));
  724. assert!(!socket.can_recv());
  725. }
  726. #[test]
  727. fn test_accept_bad_id() {
  728. let mut socket = socket(buffer(1), buffer(1));
  729. let mut cx = Context::mock();
  730. assert_eq!(socket.bind(Endpoint::Ident(0x1234)), Ok(()));
  731. let checksum = ChecksumCapabilities::default();
  732. let mut bytes = [0xff; 20];
  733. let mut packet = Icmpv4Packet::new_unchecked(&mut bytes);
  734. let icmp_repr = Icmpv4Repr::EchoRequest {
  735. ident: 0x4321,
  736. seq_no: 0x5678,
  737. data: &[0xff; 16],
  738. };
  739. icmp_repr.emit(&mut packet, &checksum);
  740. // Ensure that a packet with an identifier that isn't the bound
  741. // ID is not accepted
  742. assert!(!socket.accepts(&mut cx, &REMOTE_IPV4_REPR, &icmp_repr.into()));
  743. }
  744. #[test]
  745. fn test_accepts_udp() {
  746. let mut socket = socket(buffer(1), buffer(1));
  747. let mut cx = Context::mock();
  748. assert_eq!(socket.bind(Endpoint::Udp(LOCAL_END_V4.into())), Ok(()));
  749. let checksum = ChecksumCapabilities::default();
  750. let mut bytes = [0xff; 18];
  751. let mut packet = UdpPacket::new_unchecked(&mut bytes);
  752. UDP_REPR.emit(
  753. &mut packet,
  754. &REMOTE_IPV4.into(),
  755. &LOCAL_IPV4.into(),
  756. UDP_PAYLOAD.len(),
  757. |buf| buf.copy_from_slice(UDP_PAYLOAD),
  758. &checksum,
  759. );
  760. let data = &*packet.into_inner();
  761. let icmp_repr = Icmpv4Repr::DstUnreachable {
  762. reason: Icmpv4DstUnreachable::PortUnreachable,
  763. header: Ipv4Repr {
  764. src_addr: LOCAL_IPV4,
  765. dst_addr: REMOTE_IPV4,
  766. next_header: IpProtocol::Icmp,
  767. payload_len: 12,
  768. hop_limit: 0x40,
  769. },
  770. data: data,
  771. };
  772. let ip_repr = IpRepr::Ipv4(Ipv4Repr {
  773. src_addr: REMOTE_IPV4,
  774. dst_addr: LOCAL_IPV4,
  775. next_header: IpProtocol::Icmp,
  776. payload_len: icmp_repr.buffer_len(),
  777. hop_limit: 0x40,
  778. });
  779. assert!(!socket.can_recv());
  780. // Ensure we can accept ICMP error response to the bound
  781. // UDP port
  782. assert!(socket.accepts(&mut cx, &ip_repr, &icmp_repr.into()));
  783. socket.process(&mut cx, &ip_repr, &icmp_repr.into());
  784. assert!(socket.can_recv());
  785. let mut bytes = [0x00; 46];
  786. let mut packet = Icmpv4Packet::new_unchecked(&mut bytes[..]);
  787. icmp_repr.emit(&mut packet, &checksum);
  788. assert_eq!(
  789. socket.recv(),
  790. Ok((&*packet.into_inner(), REMOTE_IPV4.into()))
  791. );
  792. assert!(!socket.can_recv());
  793. }
  794. }
  795. #[cfg(all(test, feature = "proto-ipv6"))]
  796. mod test_ipv6 {
  797. use super::tests_common::*;
  798. use crate::wire::{Icmpv6DstUnreachable, IpEndpoint, Ipv6Address};
  799. const REMOTE_IPV6: Ipv6Address =
  800. Ipv6Address([0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2]);
  801. const LOCAL_IPV6: Ipv6Address =
  802. Ipv6Address([0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]);
  803. const LOCAL_END_V6: IpEndpoint = IpEndpoint {
  804. addr: IpAddress::Ipv6(LOCAL_IPV6),
  805. port: LOCAL_PORT,
  806. };
  807. static ECHOV6_REPR: Icmpv6Repr = Icmpv6Repr::EchoRequest {
  808. ident: 0x1234,
  809. seq_no: 0x5678,
  810. data: &[0xff; 16],
  811. };
  812. static LOCAL_IPV6_REPR: IpRepr = IpRepr::Ipv6(Ipv6Repr {
  813. src_addr: LOCAL_IPV6,
  814. dst_addr: REMOTE_IPV6,
  815. next_header: IpProtocol::Icmpv6,
  816. payload_len: 24,
  817. hop_limit: 0x40,
  818. });
  819. static REMOTE_IPV6_REPR: IpRepr = IpRepr::Ipv6(Ipv6Repr {
  820. src_addr: REMOTE_IPV6,
  821. dst_addr: LOCAL_IPV6,
  822. next_header: IpProtocol::Icmpv6,
  823. payload_len: 24,
  824. hop_limit: 0x40,
  825. });
  826. #[test]
  827. fn test_send_unaddressable() {
  828. let mut socket = socket(buffer(0), buffer(1));
  829. assert_eq!(
  830. socket.send_slice(b"abcdef", IpAddress::Ipv6(Ipv6Address::default())),
  831. Err(SendError::Unaddressable)
  832. );
  833. assert_eq!(socket.send_slice(b"abcdef", REMOTE_IPV6.into()), Ok(()));
  834. }
  835. #[test]
  836. fn test_send_dispatch() {
  837. let mut socket = socket(buffer(0), buffer(1));
  838. let mut cx = Context::mock();
  839. let checksum = ChecksumCapabilities::default();
  840. assert_eq!(
  841. socket.dispatch(&mut cx, |_, _| unreachable!()),
  842. Ok::<_, ()>(())
  843. );
  844. // This buffer is too long
  845. assert_eq!(
  846. socket.send_slice(&[0xff; 67], REMOTE_IPV6.into()),
  847. Err(SendError::BufferFull)
  848. );
  849. assert!(socket.can_send());
  850. let mut bytes = vec![0xff; 24];
  851. let mut packet = Icmpv6Packet::new_unchecked(&mut bytes);
  852. ECHOV6_REPR.emit(
  853. &LOCAL_IPV6.into(),
  854. &REMOTE_IPV6.into(),
  855. &mut packet,
  856. &checksum,
  857. );
  858. assert_eq!(
  859. socket.send_slice(&*packet.into_inner(), REMOTE_IPV6.into()),
  860. Ok(())
  861. );
  862. assert_eq!(
  863. socket.send_slice(b"123456", REMOTE_IPV6.into()),
  864. Err(SendError::BufferFull)
  865. );
  866. assert!(!socket.can_send());
  867. assert_eq!(
  868. socket.dispatch(&mut cx, |_, (ip_repr, icmp_repr)| {
  869. assert_eq!(ip_repr, LOCAL_IPV6_REPR);
  870. assert_eq!(icmp_repr, ECHOV6_REPR.into());
  871. Err(())
  872. }),
  873. Err(())
  874. );
  875. // buffer is not taken off of the tx queue due to the error
  876. assert!(!socket.can_send());
  877. assert_eq!(
  878. socket.dispatch(&mut cx, |_, (ip_repr, icmp_repr)| {
  879. assert_eq!(ip_repr, LOCAL_IPV6_REPR);
  880. assert_eq!(icmp_repr, ECHOV6_REPR.into());
  881. Ok::<_, ()>(())
  882. }),
  883. Ok(())
  884. );
  885. // buffer is taken off of the queue this time
  886. assert!(socket.can_send());
  887. }
  888. #[test]
  889. fn test_set_hop_limit() {
  890. let mut s = socket(buffer(0), buffer(1));
  891. let mut cx = Context::mock();
  892. let checksum = ChecksumCapabilities::default();
  893. let mut bytes = vec![0xff; 24];
  894. let mut packet = Icmpv6Packet::new_unchecked(&mut bytes);
  895. ECHOV6_REPR.emit(
  896. &LOCAL_IPV6.into(),
  897. &REMOTE_IPV6.into(),
  898. &mut packet,
  899. &checksum,
  900. );
  901. s.set_hop_limit(Some(0x2a));
  902. assert_eq!(
  903. s.send_slice(&*packet.into_inner(), REMOTE_IPV6.into()),
  904. Ok(())
  905. );
  906. assert_eq!(
  907. s.dispatch(&mut cx, |_, (ip_repr, _)| {
  908. assert_eq!(
  909. ip_repr,
  910. IpRepr::Ipv6(Ipv6Repr {
  911. src_addr: LOCAL_IPV6,
  912. dst_addr: REMOTE_IPV6,
  913. next_header: IpProtocol::Icmpv6,
  914. payload_len: ECHOV6_REPR.buffer_len(),
  915. hop_limit: 0x2a,
  916. })
  917. );
  918. Ok::<_, ()>(())
  919. }),
  920. Ok(())
  921. );
  922. }
  923. #[test]
  924. fn test_recv_process() {
  925. let mut socket = socket(buffer(1), buffer(1));
  926. let mut cx = Context::mock();
  927. assert_eq!(socket.bind(Endpoint::Ident(0x1234)), Ok(()));
  928. assert!(!socket.can_recv());
  929. assert_eq!(socket.recv(), Err(RecvError::Exhausted));
  930. let checksum = ChecksumCapabilities::default();
  931. let mut bytes = [0xff; 24];
  932. let mut packet = Icmpv6Packet::new_unchecked(&mut bytes[..]);
  933. ECHOV6_REPR.emit(
  934. &LOCAL_IPV6.into(),
  935. &REMOTE_IPV6.into(),
  936. &mut packet,
  937. &checksum,
  938. );
  939. let data = &*packet.into_inner();
  940. assert!(socket.accepts(&mut cx, &REMOTE_IPV6_REPR, &ECHOV6_REPR.into()));
  941. socket.process(&mut cx, &REMOTE_IPV6_REPR, &ECHOV6_REPR.into());
  942. assert!(socket.can_recv());
  943. assert!(socket.accepts(&mut cx, &REMOTE_IPV6_REPR, &ECHOV6_REPR.into()));
  944. socket.process(&mut cx, &REMOTE_IPV6_REPR, &ECHOV6_REPR.into());
  945. assert_eq!(socket.recv(), Ok((data, REMOTE_IPV6.into())));
  946. assert!(!socket.can_recv());
  947. }
  948. #[test]
  949. fn test_accept_bad_id() {
  950. let mut socket = socket(buffer(1), buffer(1));
  951. let mut cx = Context::mock();
  952. assert_eq!(socket.bind(Endpoint::Ident(0x1234)), Ok(()));
  953. let checksum = ChecksumCapabilities::default();
  954. let mut bytes = [0xff; 20];
  955. let mut packet = Icmpv6Packet::new_unchecked(&mut bytes);
  956. let icmp_repr = Icmpv6Repr::EchoRequest {
  957. ident: 0x4321,
  958. seq_no: 0x5678,
  959. data: &[0xff; 16],
  960. };
  961. icmp_repr.emit(
  962. &LOCAL_IPV6.into(),
  963. &REMOTE_IPV6.into(),
  964. &mut packet,
  965. &checksum,
  966. );
  967. // Ensure that a packet with an identifier that isn't the bound
  968. // ID is not accepted
  969. assert!(!socket.accepts(&mut cx, &REMOTE_IPV6_REPR, &icmp_repr.into()));
  970. }
  971. #[test]
  972. fn test_accepts_udp() {
  973. let mut socket = socket(buffer(1), buffer(1));
  974. let mut cx = Context::mock();
  975. assert_eq!(socket.bind(Endpoint::Udp(LOCAL_END_V6.into())), Ok(()));
  976. let checksum = ChecksumCapabilities::default();
  977. let mut bytes = [0xff; 18];
  978. let mut packet = UdpPacket::new_unchecked(&mut bytes);
  979. UDP_REPR.emit(
  980. &mut packet,
  981. &REMOTE_IPV6.into(),
  982. &LOCAL_IPV6.into(),
  983. UDP_PAYLOAD.len(),
  984. |buf| buf.copy_from_slice(UDP_PAYLOAD),
  985. &checksum,
  986. );
  987. let data = &*packet.into_inner();
  988. let icmp_repr = Icmpv6Repr::DstUnreachable {
  989. reason: Icmpv6DstUnreachable::PortUnreachable,
  990. header: Ipv6Repr {
  991. src_addr: LOCAL_IPV6,
  992. dst_addr: REMOTE_IPV6,
  993. next_header: IpProtocol::Icmpv6,
  994. payload_len: 12,
  995. hop_limit: 0x40,
  996. },
  997. data: data,
  998. };
  999. let ip_repr = IpRepr::Ipv6(Ipv6Repr {
  1000. src_addr: REMOTE_IPV6,
  1001. dst_addr: LOCAL_IPV6,
  1002. next_header: IpProtocol::Icmpv6,
  1003. payload_len: icmp_repr.buffer_len(),
  1004. hop_limit: 0x40,
  1005. });
  1006. assert!(!socket.can_recv());
  1007. // Ensure we can accept ICMP error response to the bound
  1008. // UDP port
  1009. assert!(socket.accepts(&mut cx, &ip_repr, &icmp_repr.into()));
  1010. socket.process(&mut cx, &ip_repr, &icmp_repr.into());
  1011. assert!(socket.can_recv());
  1012. let mut bytes = [0x00; 66];
  1013. let mut packet = Icmpv6Packet::new_unchecked(&mut bytes[..]);
  1014. icmp_repr.emit(
  1015. &LOCAL_IPV6.into(),
  1016. &REMOTE_IPV6.into(),
  1017. &mut packet,
  1018. &checksum,
  1019. );
  1020. assert_eq!(
  1021. socket.recv(),
  1022. Ok((&*packet.into_inner(), REMOTE_IPV6.into()))
  1023. );
  1024. assert!(!socket.can_recv());
  1025. }
  1026. }