icmp.rs 33 KB

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