icmp.rs 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895
  1. use core::cmp;
  2. #[cfg(feature = "async")]
  3. use core::task::Waker;
  4. use crate::{Error, Result};
  5. use crate::phy::ChecksumCapabilities;
  6. use crate::socket::{Socket, SocketMeta, SocketHandle, PollAt, Context};
  7. use crate::storage::{PacketBuffer, PacketMetadata};
  8. #[cfg(feature = "async")]
  9. use crate::socket::WakerRegistration;
  10. #[cfg(feature = "proto-ipv4")]
  11. use crate::wire::{Ipv4Address, Ipv4Repr, Icmpv4Packet, Icmpv4Repr};
  12. #[cfg(feature = "proto-ipv6")]
  13. use crate::wire::{Ipv6Address, Ipv6Repr, Icmpv6Packet, Icmpv6Repr};
  14. use crate::wire::IcmpRepr;
  15. use crate::wire::{UdpPacket, UdpRepr};
  16. use crate::wire::{IpAddress, IpEndpoint, IpProtocol, IpRepr};
  17. /// Type of endpoint to bind the ICMP socket to. See [IcmpSocket::bind] for
  18. /// more details.
  19. ///
  20. /// [IcmpSocket::bind]: struct.IcmpSocket.html#method.bind
  21. #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
  22. #[cfg_attr(feature = "defmt", derive(defmt::Format))]
  23. pub enum Endpoint {
  24. Unspecified,
  25. Ident(u16),
  26. Udp(IpEndpoint)
  27. }
  28. impl Endpoint {
  29. pub fn is_specified(&self) -> bool {
  30. match *self {
  31. Endpoint::Ident(_) => true,
  32. Endpoint::Udp(endpoint) => endpoint.port != 0,
  33. Endpoint::Unspecified => false
  34. }
  35. }
  36. }
  37. impl Default for Endpoint {
  38. fn default() -> Endpoint { Endpoint::Unspecified }
  39. }
  40. /// An ICMP packet metadata.
  41. pub type IcmpPacketMetadata = PacketMetadata<IpAddress>;
  42. /// An ICMP packet ring buffer.
  43. pub type IcmpSocketBuffer<'a> = PacketBuffer<'a, IpAddress>;
  44. /// A ICMP socket
  45. ///
  46. /// An ICMP socket is bound to a specific [IcmpEndpoint] which may
  47. /// be a sepecific UDP port to listen for ICMP error messages related
  48. /// to the port or a specific ICMP identifier value. See [bind] for
  49. /// more details.
  50. ///
  51. /// [IcmpEndpoint]: enum.IcmpEndpoint.html
  52. /// [bind]: #method.bind
  53. #[derive(Debug)]
  54. pub struct IcmpSocket<'a> {
  55. pub(crate) meta: SocketMeta,
  56. rx_buffer: IcmpSocketBuffer<'a>,
  57. tx_buffer: IcmpSocketBuffer<'a>,
  58. /// The endpoint this socket is communicating with
  59. endpoint: Endpoint,
  60. /// The time-to-live (IPv4) or hop limit (IPv6) value used in outgoing packets.
  61. hop_limit: Option<u8>,
  62. #[cfg(feature = "async")]
  63. rx_waker: WakerRegistration,
  64. #[cfg(feature = "async")]
  65. tx_waker: WakerRegistration,
  66. }
  67. impl<'a> IcmpSocket<'a> {
  68. /// Create an ICMP socket with the given buffers.
  69. pub fn new(rx_buffer: IcmpSocketBuffer<'a>,
  70. tx_buffer: IcmpSocketBuffer<'a>) -> IcmpSocket<'a> {
  71. IcmpSocket {
  72. meta: SocketMeta::default(),
  73. rx_buffer: rx_buffer,
  74. tx_buffer: tx_buffer,
  75. endpoint: Endpoint::default(),
  76. hop_limit: None,
  77. #[cfg(feature = "async")]
  78. rx_waker: WakerRegistration::new(),
  79. #[cfg(feature = "async")]
  80. tx_waker: WakerRegistration::new(),
  81. }
  82. }
  83. /// Register a waker for receive operations.
  84. ///
  85. /// The waker is woken on state changes that might affect the return value
  86. /// of `recv` method calls, such as receiving data, or the socket closing.
  87. ///
  88. /// Notes:
  89. ///
  90. /// - Only one waker can be registered at a time. If another waker was previously registered,
  91. /// it is overwritten and will no longer be woken.
  92. /// - The Waker is woken only once. Once woken, you must register it again to receive more wakes.
  93. /// - "Spurious wakes" are allowed: a wake doesn't guarantee the result of `recv` has
  94. /// necessarily changed.
  95. #[cfg(feature = "async")]
  96. pub fn register_recv_waker(&mut self, waker: &Waker) {
  97. self.rx_waker.register(waker)
  98. }
  99. /// Register a waker for send operations.
  100. ///
  101. /// The waker is woken on state changes that might affect the return value
  102. /// of `send` method calls, such as space becoming available in the transmit
  103. /// buffer, or the socket closing.
  104. ///
  105. /// Notes:
  106. ///
  107. /// - Only one waker can be registered at a time. If another waker was previously registered,
  108. /// it is overwritten and will no longer be woken.
  109. /// - The Waker is woken only once. Once woken, you must register it again to receive more wakes.
  110. /// - "Spurious wakes" are allowed: a wake doesn't guarantee the result of `send` has
  111. /// necessarily changed.
  112. #[cfg(feature = "async")]
  113. pub fn register_send_waker(&mut self, waker: &Waker) {
  114. self.tx_waker.register(waker)
  115. }
  116. /// Return the socket handle.
  117. #[inline]
  118. pub fn handle(&self) -> SocketHandle {
  119. self.meta.handle
  120. }
  121. /// Return the time-to-live (IPv4) or hop limit (IPv6) value used in outgoing packets.
  122. ///
  123. /// See also the [set_hop_limit](#method.set_hop_limit) method
  124. pub fn hop_limit(&self) -> Option<u8> {
  125. self.hop_limit
  126. }
  127. /// Set the time-to-live (IPv4) or hop limit (IPv6) value used in outgoing packets.
  128. ///
  129. /// A socket without an explicitly set hop limit value uses the default [IANA recommended]
  130. /// value (64).
  131. ///
  132. /// # Panics
  133. ///
  134. /// This function panics if a hop limit value of 0 is given. See [RFC 1122 § 3.2.1.7].
  135. ///
  136. /// [IANA recommended]: https://www.iana.org/assignments/ip-parameters/ip-parameters.xhtml
  137. /// [RFC 1122 § 3.2.1.7]: https://tools.ietf.org/html/rfc1122#section-3.2.1.7
  138. pub fn set_hop_limit(&mut self, hop_limit: Option<u8>) {
  139. // A host MUST NOT send a datagram with a hop limit value of 0
  140. if let Some(0) = hop_limit {
  141. panic!("the time-to-live value of a packet must not be zero")
  142. }
  143. self.hop_limit = hop_limit
  144. }
  145. /// Bind the socket to the given endpoint.
  146. ///
  147. /// This function returns `Err(Error::Illegal)` if the socket was open
  148. /// (see [is_open](#method.is_open)), and `Err(Error::Unaddressable)`
  149. /// if `endpoint` is unspecified (see [is_specified]).
  150. ///
  151. /// # Examples
  152. ///
  153. /// ## Bind to ICMP Error messages associated with a specific UDP port:
  154. ///
  155. /// To [recv] ICMP error messages that are associated with a specific local
  156. /// UDP port, the socket may be bound to a given port using [IcmpEndpoint::Udp].
  157. /// This may be useful for applications using UDP attempting to detect and/or
  158. /// diagnose connection problems.
  159. ///
  160. /// ```
  161. /// # use smoltcp::socket::{Socket, IcmpSocket, IcmpSocketBuffer, IcmpPacketMetadata};
  162. /// # let rx_buffer = IcmpSocketBuffer::new(vec![IcmpPacketMetadata::EMPTY], vec![0; 20]);
  163. /// # let tx_buffer = IcmpSocketBuffer::new(vec![IcmpPacketMetadata::EMPTY], vec![0; 20]);
  164. /// use smoltcp::wire::IpEndpoint;
  165. /// use smoltcp::socket::IcmpEndpoint;
  166. ///
  167. /// let mut icmp_socket = // ...
  168. /// # IcmpSocket::new(rx_buffer, tx_buffer);
  169. ///
  170. /// // Bind to ICMP error responses for UDP packets sent from port 53.
  171. /// let endpoint = IpEndpoint::from(53);
  172. /// icmp_socket.bind(IcmpEndpoint::Udp(endpoint)).unwrap();
  173. /// ```
  174. ///
  175. /// ## Bind to a specific ICMP identifier:
  176. ///
  177. /// To [send] and [recv] ICMP packets that are not associated with a specific UDP
  178. /// port, the socket may be bound to a specific ICMP identifier using
  179. /// [IcmpEndpoint::Ident]. This is useful for sending and receiving Echo Request/Reply
  180. /// messages.
  181. ///
  182. /// ```
  183. /// # use smoltcp::socket::{Socket, IcmpSocket, IcmpSocketBuffer, IcmpPacketMetadata};
  184. /// # let rx_buffer = IcmpSocketBuffer::new(vec![IcmpPacketMetadata::EMPTY], vec![0; 20]);
  185. /// # let tx_buffer = IcmpSocketBuffer::new(vec![IcmpPacketMetadata::EMPTY], vec![0; 20]);
  186. /// use smoltcp::socket::IcmpEndpoint;
  187. ///
  188. /// let mut icmp_socket = // ...
  189. /// # IcmpSocket::new(rx_buffer, tx_buffer);
  190. ///
  191. /// // Bind to ICMP messages with the ICMP identifier 0x1234
  192. /// icmp_socket.bind(IcmpEndpoint::Ident(0x1234)).unwrap();
  193. /// ```
  194. ///
  195. /// [is_specified]: enum.IcmpEndpoint.html#method.is_specified
  196. /// [IcmpEndpoint::Ident]: enum.IcmpEndpoint.html#variant.Ident
  197. /// [IcmpEndpoint::Udp]: enum.IcmpEndpoint.html#variant.Udp
  198. /// [send]: #method.send
  199. /// [recv]: #method.recv
  200. pub fn bind<T: Into<Endpoint>>(&mut self, endpoint: T) -> Result<()> {
  201. let endpoint = endpoint.into();
  202. if !endpoint.is_specified() {
  203. return Err(Error::Unaddressable);
  204. }
  205. if self.is_open() { return Err(Error::Illegal) }
  206. self.endpoint = endpoint;
  207. #[cfg(feature = "async")]
  208. {
  209. self.rx_waker.wake();
  210. self.tx_waker.wake();
  211. }
  212. Ok(())
  213. }
  214. /// Check whether the transmit buffer is full.
  215. #[inline]
  216. pub fn can_send(&self) -> bool {
  217. !self.tx_buffer.is_full()
  218. }
  219. /// Check whether the receive buffer is not empty.
  220. #[inline]
  221. pub fn can_recv(&self) -> bool {
  222. !self.rx_buffer.is_empty()
  223. }
  224. /// Return the maximum number packets the socket can receive.
  225. #[inline]
  226. pub fn packet_recv_capacity(&self) -> usize {
  227. self.rx_buffer.packet_capacity()
  228. }
  229. /// Return the maximum number packets the socket can transmit.
  230. #[inline]
  231. pub fn packet_send_capacity(&self) -> usize {
  232. self.tx_buffer.packet_capacity()
  233. }
  234. /// Return the maximum number of bytes inside the recv buffer.
  235. #[inline]
  236. pub fn payload_recv_capacity(&self) -> usize {
  237. self.rx_buffer.payload_capacity()
  238. }
  239. /// Return the maximum number of bytes inside the transmit buffer.
  240. #[inline]
  241. pub fn payload_send_capacity(&self) -> usize {
  242. self.tx_buffer.payload_capacity()
  243. }
  244. /// Check whether the socket is open.
  245. #[inline]
  246. pub fn is_open(&self) -> bool {
  247. self.endpoint != Endpoint::Unspecified
  248. }
  249. /// Enqueue a packet to be sent to a given remote address, and return a pointer
  250. /// to its payload.
  251. ///
  252. /// This function returns `Err(Error::Exhausted)` if the transmit buffer is full,
  253. /// `Err(Error::Truncated)` if the requested size is larger than the packet buffer
  254. /// size, and `Err(Error::Unaddressable)` if the remote address is unspecified.
  255. pub fn send(&mut self, size: usize, endpoint: IpAddress) -> Result<&mut [u8]> {
  256. if endpoint.is_unspecified() {
  257. return Err(Error::Unaddressable)
  258. }
  259. let packet_buf = self.tx_buffer.enqueue(size, endpoint)?;
  260. net_trace!("{}:{}: buffer to send {} octets",
  261. self.meta.handle, endpoint, size);
  262. Ok(packet_buf)
  263. }
  264. /// Enqueue a packet to be sent to a given remote address, and fill it from a slice.
  265. ///
  266. /// See also [send](#method.send).
  267. pub fn send_slice(&mut self, data: &[u8], endpoint: IpAddress) -> Result<()> {
  268. let packet_buf = self.send(data.len(), endpoint)?;
  269. packet_buf.copy_from_slice(data);
  270. Ok(())
  271. }
  272. /// Dequeue a packet received from a remote endpoint, and return the `IpAddress` as well
  273. /// as a pointer to the payload.
  274. ///
  275. /// This function returns `Err(Error::Exhausted)` if the receive buffer is empty.
  276. pub fn recv(&mut self) -> Result<(&[u8], IpAddress)> {
  277. let (endpoint, packet_buf) = self.rx_buffer.dequeue()?;
  278. net_trace!("{}:{}: receive {} buffered octets",
  279. self.meta.handle, endpoint, packet_buf.len());
  280. Ok((packet_buf, endpoint))
  281. }
  282. /// Dequeue a packet received from a remote endpoint, copy the payload into the given slice,
  283. /// and return the amount of octets copied as well as the `IpAddress`
  284. ///
  285. /// See also [recv](#method.recv).
  286. pub fn recv_slice(&mut self, data: &mut [u8]) -> Result<(usize, IpAddress)> {
  287. let (buffer, endpoint) = self.recv()?;
  288. let length = cmp::min(data.len(), buffer.len());
  289. data[..length].copy_from_slice(&buffer[..length]);
  290. Ok((length, endpoint))
  291. }
  292. /// Filter determining which packets received by the interface are appended to
  293. /// the given sockets received buffer.
  294. pub(crate) fn accepts(&self, cx: &Context, ip_repr: &IpRepr, icmp_repr: &IcmpRepr) -> bool {
  295. match (&self.endpoint, icmp_repr) {
  296. // If we are bound to ICMP errors associated to a UDP port, only
  297. // accept Destination Unreachable messages with the data containing
  298. // a UDP packet send from the local port we are bound to.
  299. #[cfg(feature = "proto-ipv4")]
  300. (&Endpoint::Udp(endpoint), &IcmpRepr::Ipv4(Icmpv4Repr::DstUnreachable { data, .. }))
  301. if endpoint.addr.is_unspecified() || endpoint.addr == ip_repr.dst_addr() => {
  302. let packet = UdpPacket::new_unchecked(data);
  303. match UdpRepr::parse(&packet, &ip_repr.src_addr(), &ip_repr.dst_addr(), &cx.caps.checksum) {
  304. Ok(repr) => endpoint.port == repr.src_port,
  305. Err(_) => false,
  306. }
  307. }
  308. #[cfg(feature = "proto-ipv6")]
  309. (&Endpoint::Udp(endpoint), &IcmpRepr::Ipv6(Icmpv6Repr::DstUnreachable { data, .. }))
  310. if endpoint.addr.is_unspecified() || endpoint.addr == ip_repr.dst_addr() => {
  311. let packet = UdpPacket::new_unchecked(data);
  312. match UdpRepr::parse(&packet, &ip_repr.src_addr(), &ip_repr.dst_addr(), &cx.caps.checksum) {
  313. Ok(repr) => endpoint.port == repr.src_port,
  314. Err(_) => false,
  315. }
  316. }
  317. // If we are bound to a specific ICMP identifier value, only accept an
  318. // Echo Request/Reply with the identifier field matching the endpoint
  319. // port.
  320. #[cfg(feature = "proto-ipv4")]
  321. (&Endpoint::Ident(bound_ident),
  322. &IcmpRepr::Ipv4(Icmpv4Repr::EchoRequest { ident, .. })) |
  323. (&Endpoint::Ident(bound_ident),
  324. &IcmpRepr::Ipv4(Icmpv4Repr::EchoReply { ident, .. })) =>
  325. ident == bound_ident,
  326. #[cfg(feature = "proto-ipv6")]
  327. (&Endpoint::Ident(bound_ident),
  328. &IcmpRepr::Ipv6(Icmpv6Repr::EchoRequest { ident, .. })) |
  329. (&Endpoint::Ident(bound_ident),
  330. &IcmpRepr::Ipv6(Icmpv6Repr::EchoReply { ident, .. })) =>
  331. ident == bound_ident,
  332. _ => false,
  333. }
  334. }
  335. pub(crate) fn process(&mut self, _cx: &Context, ip_repr: &IpRepr, icmp_repr: &IcmpRepr) -> Result<()> {
  336. match *icmp_repr {
  337. #[cfg(feature = "proto-ipv4")]
  338. IcmpRepr::Ipv4(ref icmp_repr) => {
  339. let packet_buf = self.rx_buffer.enqueue(icmp_repr.buffer_len(),
  340. ip_repr.src_addr())?;
  341. icmp_repr.emit(&mut Icmpv4Packet::new_unchecked(packet_buf),
  342. &ChecksumCapabilities::default());
  343. net_trace!("{}:{}: receiving {} octets",
  344. self.meta.handle, icmp_repr.buffer_len(), packet_buf.len());
  345. },
  346. #[cfg(feature = "proto-ipv6")]
  347. IcmpRepr::Ipv6(ref icmp_repr) => {
  348. let packet_buf = self.rx_buffer.enqueue(icmp_repr.buffer_len(),
  349. ip_repr.src_addr())?;
  350. icmp_repr.emit(&ip_repr.src_addr(), &ip_repr.dst_addr(),
  351. &mut Icmpv6Packet::new_unchecked(packet_buf),
  352. &ChecksumCapabilities::default());
  353. net_trace!("{}:{}: receiving {} octets",
  354. self.meta.handle, icmp_repr.buffer_len(), packet_buf.len());
  355. },
  356. }
  357. #[cfg(feature = "async")]
  358. self.rx_waker.wake();
  359. Ok(())
  360. }
  361. pub(crate) fn dispatch<F>(&mut self, _cx: &Context, emit: F) -> Result<()>
  362. where F: FnOnce((IpRepr, IcmpRepr)) -> Result<()>
  363. {
  364. let handle = self.meta.handle;
  365. let hop_limit = self.hop_limit.unwrap_or(64);
  366. self.tx_buffer.dequeue_with(|remote_endpoint, packet_buf| {
  367. net_trace!("{}:{}: sending {} octets",
  368. handle, remote_endpoint, packet_buf.len());
  369. match *remote_endpoint {
  370. #[cfg(feature = "proto-ipv4")]
  371. IpAddress::Ipv4(ipv4_addr) => {
  372. let packet = Icmpv4Packet::new_unchecked(&*packet_buf);
  373. let repr = Icmpv4Repr::parse(&packet, &ChecksumCapabilities::ignored())?;
  374. let ip_repr = IpRepr::Ipv4(Ipv4Repr {
  375. src_addr: Ipv4Address::default(),
  376. dst_addr: ipv4_addr,
  377. protocol: IpProtocol::Icmp,
  378. payload_len: repr.buffer_len(),
  379. hop_limit: hop_limit,
  380. });
  381. emit((ip_repr, IcmpRepr::Ipv4(repr)))
  382. },
  383. #[cfg(feature = "proto-ipv6")]
  384. IpAddress::Ipv6(ipv6_addr) => {
  385. let packet = Icmpv6Packet::new_unchecked(&*packet_buf);
  386. let src_addr = Ipv6Address::default();
  387. let repr = Icmpv6Repr::parse(&src_addr.into(), &ipv6_addr.into(), &packet, &ChecksumCapabilities::ignored())?;
  388. let ip_repr = IpRepr::Ipv6(Ipv6Repr {
  389. src_addr: src_addr,
  390. dst_addr: ipv6_addr,
  391. next_header: IpProtocol::Icmpv6,
  392. payload_len: repr.buffer_len(),
  393. hop_limit: hop_limit,
  394. });
  395. emit((ip_repr, IcmpRepr::Ipv6(repr)))
  396. },
  397. _ => Err(Error::Unaddressable)
  398. }
  399. })?;
  400. #[cfg(feature = "async")]
  401. self.tx_waker.wake();
  402. Ok(())
  403. }
  404. pub(crate) fn poll_at(&self, _cx: &Context) -> PollAt {
  405. if self.tx_buffer.is_empty() {
  406. PollAt::Ingress
  407. } else {
  408. PollAt::Now
  409. }
  410. }
  411. }
  412. impl<'a> Into<Socket<'a>> for IcmpSocket<'a> {
  413. fn into(self) -> Socket<'a> {
  414. Socket::Icmp(self)
  415. }
  416. }
  417. #[cfg(test)]
  418. mod tests_common {
  419. pub use crate::phy::DeviceCapabilities;
  420. pub use crate::wire::IpAddress;
  421. pub use super::*;
  422. pub fn buffer(packets: usize) -> IcmpSocketBuffer<'static> {
  423. IcmpSocketBuffer::new(vec![IcmpPacketMetadata::EMPTY; packets], vec![0; 66 * packets])
  424. }
  425. pub fn socket(rx_buffer: IcmpSocketBuffer<'static>,
  426. tx_buffer: IcmpSocketBuffer<'static>) -> IcmpSocket<'static> {
  427. IcmpSocket::new(rx_buffer, tx_buffer)
  428. }
  429. pub const LOCAL_PORT: u16 = 53;
  430. pub static UDP_REPR: UdpRepr = UdpRepr {
  431. src_port: 53,
  432. dst_port: 9090,
  433. };
  434. pub static UDP_PAYLOAD: &[u8] = &[0xff; 10];
  435. }
  436. #[cfg(all(test, feature = "proto-ipv4"))]
  437. mod test_ipv4 {
  438. use super::tests_common::*;
  439. use crate::wire::Icmpv4DstUnreachable;
  440. const REMOTE_IPV4: Ipv4Address = Ipv4Address([0x7f, 0x00, 0x00, 0x02]);
  441. const LOCAL_IPV4: Ipv4Address = Ipv4Address([0x7f, 0x00, 0x00, 0x01]);
  442. const LOCAL_END_V4: IpEndpoint = IpEndpoint { addr: IpAddress::Ipv4(LOCAL_IPV4), port: LOCAL_PORT };
  443. static ECHOV4_REPR: Icmpv4Repr = Icmpv4Repr::EchoRequest {
  444. ident: 0x1234,
  445. seq_no: 0x5678,
  446. data: &[0xff; 16]
  447. };
  448. static LOCAL_IPV4_REPR: IpRepr = IpRepr::Ipv4(Ipv4Repr {
  449. src_addr: Ipv4Address::UNSPECIFIED,
  450. dst_addr: REMOTE_IPV4,
  451. protocol: IpProtocol::Icmp,
  452. payload_len: 24,
  453. hop_limit: 0x40
  454. });
  455. static REMOTE_IPV4_REPR: IpRepr = IpRepr::Ipv4(Ipv4Repr {
  456. src_addr: REMOTE_IPV4,
  457. dst_addr: LOCAL_IPV4,
  458. protocol: IpProtocol::Icmp,
  459. payload_len: 24,
  460. hop_limit: 0x40
  461. });
  462. #[test]
  463. fn test_send_unaddressable() {
  464. let mut socket = socket(buffer(0), buffer(1));
  465. assert_eq!(socket.send_slice(b"abcdef", IpAddress::default()),
  466. Err(Error::Unaddressable));
  467. assert_eq!(socket.send_slice(b"abcdef", REMOTE_IPV4.into()), Ok(()));
  468. }
  469. #[test]
  470. fn test_send_dispatch() {
  471. let mut socket = socket(buffer(0), buffer(1));
  472. let checksum = ChecksumCapabilities::default();
  473. assert_eq!(socket.dispatch(&Context::DUMMY, |_| unreachable!()),
  474. Err(Error::Exhausted));
  475. // This buffer is too long
  476. assert_eq!(socket.send_slice(&[0xff; 67], REMOTE_IPV4.into()), Err(Error::Truncated));
  477. assert!(socket.can_send());
  478. let mut bytes = [0xff; 24];
  479. let mut packet = Icmpv4Packet::new_unchecked(&mut bytes);
  480. ECHOV4_REPR.emit(&mut packet, &checksum);
  481. assert_eq!(socket.send_slice(&packet.into_inner()[..], REMOTE_IPV4.into()), Ok(()));
  482. assert_eq!(socket.send_slice(b"123456", REMOTE_IPV4.into()), Err(Error::Exhausted));
  483. assert!(!socket.can_send());
  484. assert_eq!(socket.dispatch(&Context::DUMMY, |(ip_repr, icmp_repr)| {
  485. assert_eq!(ip_repr, LOCAL_IPV4_REPR);
  486. assert_eq!(icmp_repr, ECHOV4_REPR.into());
  487. Err(Error::Unaddressable)
  488. }), Err(Error::Unaddressable));
  489. // buffer is not taken off of the tx queue due to the error
  490. assert!(!socket.can_send());
  491. assert_eq!(socket.dispatch(&Context::DUMMY, |(ip_repr, icmp_repr)| {
  492. assert_eq!(ip_repr, LOCAL_IPV4_REPR);
  493. assert_eq!(icmp_repr, ECHOV4_REPR.into());
  494. Ok(())
  495. }), Ok(()));
  496. // buffer is taken off of the queue this time
  497. assert!(socket.can_send());
  498. }
  499. #[test]
  500. fn test_set_hop_limit_v4() {
  501. let mut s = socket(buffer(0), buffer(1));
  502. let checksum = ChecksumCapabilities::default();
  503. let mut bytes = [0xff; 24];
  504. let mut packet = Icmpv4Packet::new_unchecked(&mut bytes);
  505. ECHOV4_REPR.emit(&mut packet, &checksum);
  506. s.set_hop_limit(Some(0x2a));
  507. assert_eq!(s.send_slice(&packet.into_inner()[..], REMOTE_IPV4.into()), Ok(()));
  508. assert_eq!(s.dispatch(&Context::DUMMY, |(ip_repr, _)| {
  509. assert_eq!(ip_repr, IpRepr::Ipv4(Ipv4Repr {
  510. src_addr: Ipv4Address::UNSPECIFIED,
  511. dst_addr: REMOTE_IPV4,
  512. protocol: IpProtocol::Icmp,
  513. payload_len: ECHOV4_REPR.buffer_len(),
  514. hop_limit: 0x2a,
  515. }));
  516. Ok(())
  517. }), Ok(()));
  518. }
  519. #[test]
  520. fn test_recv_process() {
  521. let mut socket = socket(buffer(1), buffer(1));
  522. assert_eq!(socket.bind(Endpoint::Ident(0x1234)), Ok(()));
  523. assert!(!socket.can_recv());
  524. assert_eq!(socket.recv(), Err(Error::Exhausted));
  525. let checksum = ChecksumCapabilities::default();
  526. let mut bytes = [0xff; 24];
  527. let mut packet = Icmpv4Packet::new_unchecked(&mut bytes);
  528. ECHOV4_REPR.emit(&mut packet, &checksum);
  529. let data = &packet.into_inner()[..];
  530. assert!(socket.accepts(&Context::DUMMY, &REMOTE_IPV4_REPR, &ECHOV4_REPR.into()));
  531. assert_eq!(socket.process(&Context::DUMMY, &REMOTE_IPV4_REPR, &ECHOV4_REPR.into()),
  532. Ok(()));
  533. assert!(socket.can_recv());
  534. assert!(socket.accepts(&Context::DUMMY, &REMOTE_IPV4_REPR, &ECHOV4_REPR.into()));
  535. assert_eq!(socket.process(&Context::DUMMY, &REMOTE_IPV4_REPR, &ECHOV4_REPR.into()),
  536. Err(Error::Exhausted));
  537. assert_eq!(socket.recv(), Ok((&data[..], REMOTE_IPV4.into())));
  538. assert!(!socket.can_recv());
  539. }
  540. #[test]
  541. fn test_accept_bad_id() {
  542. let mut socket = socket(buffer(1), buffer(1));
  543. assert_eq!(socket.bind(Endpoint::Ident(0x1234)), Ok(()));
  544. let checksum = ChecksumCapabilities::default();
  545. let mut bytes = [0xff; 20];
  546. let mut packet = Icmpv4Packet::new_unchecked(&mut bytes);
  547. let icmp_repr = Icmpv4Repr::EchoRequest {
  548. ident: 0x4321,
  549. seq_no: 0x5678,
  550. data: &[0xff; 16]
  551. };
  552. icmp_repr.emit(&mut packet, &checksum);
  553. // Ensure that a packet with an identifier that isn't the bound
  554. // ID is not accepted
  555. assert!(!socket.accepts(&Context::DUMMY, &REMOTE_IPV4_REPR, &icmp_repr.into()));
  556. }
  557. #[test]
  558. fn test_accepts_udp() {
  559. let mut socket = socket(buffer(1), buffer(1));
  560. assert_eq!(socket.bind(Endpoint::Udp(LOCAL_END_V4)), Ok(()));
  561. let checksum = ChecksumCapabilities::default();
  562. let mut bytes = [0xff; 18];
  563. let mut packet = UdpPacket::new_unchecked(&mut bytes);
  564. UDP_REPR.emit(
  565. &mut packet,
  566. &REMOTE_IPV4.into(),
  567. &LOCAL_IPV4.into(),
  568. UDP_PAYLOAD.len(),
  569. |buf| buf.copy_from_slice(UDP_PAYLOAD),
  570. &checksum);
  571. let data = &packet.into_inner()[..];
  572. let icmp_repr = Icmpv4Repr::DstUnreachable {
  573. reason: Icmpv4DstUnreachable::PortUnreachable,
  574. header: Ipv4Repr {
  575. src_addr: LOCAL_IPV4,
  576. dst_addr: REMOTE_IPV4,
  577. protocol: IpProtocol::Icmp,
  578. payload_len: 12,
  579. hop_limit: 0x40
  580. },
  581. data: data
  582. };
  583. let ip_repr = IpRepr::Unspecified {
  584. src_addr: REMOTE_IPV4.into(),
  585. dst_addr: LOCAL_IPV4.into(),
  586. protocol: IpProtocol::Icmp,
  587. payload_len: icmp_repr.buffer_len(),
  588. hop_limit: 0x40
  589. };
  590. assert!(!socket.can_recv());
  591. // Ensure we can accept ICMP error response to the bound
  592. // UDP port
  593. assert!(socket.accepts(&Context::DUMMY, &ip_repr, &icmp_repr.into()));
  594. assert_eq!(socket.process(&Context::DUMMY, &ip_repr, &icmp_repr.into()),
  595. Ok(()));
  596. assert!(socket.can_recv());
  597. let mut bytes = [0x00; 46];
  598. let mut packet = Icmpv4Packet::new_unchecked(&mut bytes[..]);
  599. icmp_repr.emit(&mut packet, &checksum);
  600. assert_eq!(socket.recv(), Ok((&packet.into_inner()[..], REMOTE_IPV4.into())));
  601. assert!(!socket.can_recv());
  602. }
  603. }
  604. #[cfg(all(test, feature = "proto-ipv6"))]
  605. mod test_ipv6 {
  606. use super::tests_common::*;
  607. use crate::wire::Icmpv6DstUnreachable;
  608. const REMOTE_IPV6: Ipv6Address = Ipv6Address([0xfe, 0x80, 0, 0, 0, 0, 0, 0,
  609. 0, 0, 0, 0, 0, 0, 0, 1]);
  610. const LOCAL_IPV6: Ipv6Address = Ipv6Address([0xfe, 0x80, 0, 0, 0, 0, 0, 0,
  611. 0, 0, 0, 0, 0, 0, 0, 2]);
  612. const LOCAL_END_V6: IpEndpoint = IpEndpoint { addr: IpAddress::Ipv6(LOCAL_IPV6), port: LOCAL_PORT };
  613. static ECHOV6_REPR: Icmpv6Repr = Icmpv6Repr::EchoRequest {
  614. ident: 0x1234,
  615. seq_no: 0x5678,
  616. data: &[0xff; 16]
  617. };
  618. static LOCAL_IPV6_REPR: IpRepr = IpRepr::Ipv6(Ipv6Repr {
  619. src_addr: Ipv6Address::UNSPECIFIED,
  620. dst_addr: REMOTE_IPV6,
  621. next_header: IpProtocol::Icmpv6,
  622. payload_len: 24,
  623. hop_limit: 0x40
  624. });
  625. static REMOTE_IPV6_REPR: IpRepr = IpRepr::Ipv6(Ipv6Repr {
  626. src_addr: REMOTE_IPV6,
  627. dst_addr: LOCAL_IPV6,
  628. next_header: IpProtocol::Icmpv6,
  629. payload_len: 24,
  630. hop_limit: 0x40
  631. });
  632. #[test]
  633. fn test_send_unaddressable() {
  634. let mut socket = socket(buffer(0), buffer(1));
  635. assert_eq!(socket.send_slice(b"abcdef", IpAddress::default()),
  636. Err(Error::Unaddressable));
  637. assert_eq!(socket.send_slice(b"abcdef", REMOTE_IPV6.into()), Ok(()));
  638. }
  639. #[test]
  640. fn test_send_dispatch() {
  641. let mut socket = socket(buffer(0), buffer(1));
  642. let checksum = ChecksumCapabilities::default();
  643. assert_eq!(socket.dispatch(&Context::DUMMY, |_| unreachable!()),
  644. Err(Error::Exhausted));
  645. // This buffer is too long
  646. assert_eq!(socket.send_slice(&[0xff; 67], REMOTE_IPV6.into()), Err(Error::Truncated));
  647. assert!(socket.can_send());
  648. let mut bytes = vec![0xff; 24];
  649. let mut packet = Icmpv6Packet::new_unchecked(&mut bytes);
  650. ECHOV6_REPR.emit(&LOCAL_IPV6.into(), &REMOTE_IPV6.into(), &mut packet, &checksum);
  651. assert_eq!(socket.send_slice(&packet.into_inner()[..], REMOTE_IPV6.into()), Ok(()));
  652. assert_eq!(socket.send_slice(b"123456", REMOTE_IPV6.into()), Err(Error::Exhausted));
  653. assert!(!socket.can_send());
  654. assert_eq!(socket.dispatch(&Context::DUMMY, |(ip_repr, icmp_repr)| {
  655. assert_eq!(ip_repr, LOCAL_IPV6_REPR);
  656. assert_eq!(icmp_repr, ECHOV6_REPR.into());
  657. Err(Error::Unaddressable)
  658. }), Err(Error::Unaddressable));
  659. // buffer is not taken off of the tx queue due to the error
  660. assert!(!socket.can_send());
  661. assert_eq!(socket.dispatch(&Context::DUMMY, |(ip_repr, icmp_repr)| {
  662. assert_eq!(ip_repr, LOCAL_IPV6_REPR);
  663. assert_eq!(icmp_repr, ECHOV6_REPR.into());
  664. Ok(())
  665. }), Ok(()));
  666. // buffer is taken off of the queue this time
  667. assert!(socket.can_send());
  668. }
  669. #[test]
  670. fn test_set_hop_limit() {
  671. let mut s = socket(buffer(0), buffer(1));
  672. let checksum = ChecksumCapabilities::default();
  673. let mut bytes = vec![0xff; 24];
  674. let mut packet = Icmpv6Packet::new_unchecked(&mut bytes);
  675. ECHOV6_REPR.emit(&LOCAL_IPV6.into(), &REMOTE_IPV6.into(), &mut packet, &checksum);
  676. s.set_hop_limit(Some(0x2a));
  677. assert_eq!(s.send_slice(&packet.into_inner()[..], REMOTE_IPV6.into()), Ok(()));
  678. assert_eq!(s.dispatch(&Context::DUMMY, |(ip_repr, _)| {
  679. assert_eq!(ip_repr, IpRepr::Ipv6(Ipv6Repr {
  680. src_addr: Ipv6Address::UNSPECIFIED,
  681. dst_addr: REMOTE_IPV6,
  682. next_header: IpProtocol::Icmpv6,
  683. payload_len: ECHOV6_REPR.buffer_len(),
  684. hop_limit: 0x2a,
  685. }));
  686. Ok(())
  687. }), Ok(()));
  688. }
  689. #[test]
  690. fn test_recv_process() {
  691. let mut socket = socket(buffer(1), buffer(1));
  692. assert_eq!(socket.bind(Endpoint::Ident(0x1234)), Ok(()));
  693. assert!(!socket.can_recv());
  694. assert_eq!(socket.recv(), Err(Error::Exhausted));
  695. let checksum = ChecksumCapabilities::default();
  696. let mut bytes = [0xff; 24];
  697. let mut packet = Icmpv6Packet::new_unchecked(&mut bytes);
  698. ECHOV6_REPR.emit(&LOCAL_IPV6.into(), &REMOTE_IPV6.into(), &mut packet, &checksum);
  699. let data = &packet.into_inner()[..];
  700. assert!(socket.accepts(&Context::DUMMY, &REMOTE_IPV6_REPR, &ECHOV6_REPR.into()));
  701. assert_eq!(socket.process(&Context::DUMMY, &REMOTE_IPV6_REPR, &ECHOV6_REPR.into()),
  702. Ok(()));
  703. assert!(socket.can_recv());
  704. assert!(socket.accepts(&Context::DUMMY, &REMOTE_IPV6_REPR, &ECHOV6_REPR.into()));
  705. assert_eq!(socket.process(&Context::DUMMY, &REMOTE_IPV6_REPR, &ECHOV6_REPR.into()),
  706. Err(Error::Exhausted));
  707. assert_eq!(socket.recv(), Ok((&data[..], REMOTE_IPV6.into())));
  708. assert!(!socket.can_recv());
  709. }
  710. #[test]
  711. fn test_accept_bad_id() {
  712. let mut socket = socket(buffer(1), buffer(1));
  713. assert_eq!(socket.bind(Endpoint::Ident(0x1234)), Ok(()));
  714. let checksum = ChecksumCapabilities::default();
  715. let mut bytes = [0xff; 20];
  716. let mut packet = Icmpv6Packet::new_unchecked(&mut bytes);
  717. let icmp_repr = Icmpv6Repr::EchoRequest {
  718. ident: 0x4321,
  719. seq_no: 0x5678,
  720. data: &[0xff; 16]
  721. };
  722. icmp_repr.emit(&LOCAL_IPV6.into(), &REMOTE_IPV6.into(), &mut packet, &checksum);
  723. // Ensure that a packet with an identifier that isn't the bound
  724. // ID is not accepted
  725. assert!(!socket.accepts(&Context::DUMMY, &REMOTE_IPV6_REPR, &icmp_repr.into()));
  726. }
  727. #[test]
  728. fn test_accepts_udp() {
  729. let mut socket = socket(buffer(1), buffer(1));
  730. assert_eq!(socket.bind(Endpoint::Udp(LOCAL_END_V6)), Ok(()));
  731. let checksum = ChecksumCapabilities::default();
  732. let mut bytes = [0xff; 18];
  733. let mut packet = UdpPacket::new_unchecked(&mut bytes);
  734. UDP_REPR.emit(
  735. &mut packet,
  736. &REMOTE_IPV6.into(),
  737. &LOCAL_IPV6.into(),
  738. UDP_PAYLOAD.len(),
  739. |buf| buf.copy_from_slice(UDP_PAYLOAD),
  740. &checksum);
  741. let data = &packet.into_inner()[..];
  742. let icmp_repr = Icmpv6Repr::DstUnreachable {
  743. reason: Icmpv6DstUnreachable::PortUnreachable,
  744. header: Ipv6Repr {
  745. src_addr: LOCAL_IPV6,
  746. dst_addr: REMOTE_IPV6,
  747. next_header: IpProtocol::Icmpv6,
  748. payload_len: 12,
  749. hop_limit: 0x40
  750. },
  751. data: data
  752. };
  753. let ip_repr = IpRepr::Unspecified {
  754. src_addr: REMOTE_IPV6.into(),
  755. dst_addr: LOCAL_IPV6.into(),
  756. protocol: IpProtocol::Icmpv6,
  757. payload_len: icmp_repr.buffer_len(),
  758. hop_limit: 0x40
  759. };
  760. assert!(!socket.can_recv());
  761. // Ensure we can accept ICMP error response to the bound
  762. // UDP port
  763. assert!(socket.accepts(&Context::DUMMY, &ip_repr, &icmp_repr.into()));
  764. assert_eq!(socket.process(&Context::DUMMY, &ip_repr, &icmp_repr.into()),
  765. Ok(()));
  766. assert!(socket.can_recv());
  767. let mut bytes = [0x00; 66];
  768. let mut packet = Icmpv6Packet::new_unchecked(&mut bytes[..]);
  769. icmp_repr.emit(&LOCAL_IPV6.into(), &REMOTE_IPV6.into(), &mut packet, &checksum);
  770. assert_eq!(socket.recv(), Ok((&packet.into_inner()[..], REMOTE_IPV6.into())));
  771. assert!(!socket.can_recv());
  772. }
  773. }