Style. NFCI.
parent
65c8aea921
commit
19373c58c8
|
@ -20,12 +20,12 @@ use wire::{TcpPacket, TcpRepr, TcpControl};
|
|||
use socket::{Socket, SocketSet, AnySocket};
|
||||
#[cfg(feature = "socket-raw")]
|
||||
use socket::RawSocket;
|
||||
#[cfg(feature = "socket-icmp")]
|
||||
use socket::IcmpSocket;
|
||||
#[cfg(feature = "socket-udp")]
|
||||
use socket::UdpSocket;
|
||||
#[cfg(feature = "socket-tcp")]
|
||||
use socket::TcpSocket;
|
||||
#[cfg(feature = "socket-icmp")]
|
||||
use socket::IcmpSocket;
|
||||
use super::ArpCache;
|
||||
|
||||
/// An Ethernet network interface.
|
||||
|
@ -223,6 +223,16 @@ impl<'b, 'c, DeviceT> Interface<'b, 'c, DeviceT>
|
|||
device_result = inner.dispatch(tx_token, timestamp, Packet::Raw(response));
|
||||
device_result
|
||||
}, &caps.checksum),
|
||||
#[cfg(feature = "socket-icmp")]
|
||||
Socket::Icmp(ref mut socket) =>
|
||||
socket.dispatch(&caps, |response| {
|
||||
let tx_token = device.transmit().ok_or(Error::Exhausted)?;
|
||||
match response {
|
||||
(IpRepr::Ipv4(repr), icmp_repr) =>
|
||||
inner.dispatch(tx_token, timestamp, Packet::Icmpv4((repr, icmp_repr))),
|
||||
_ => Err(Error::Unaddressable),
|
||||
}
|
||||
}),
|
||||
#[cfg(feature = "socket-udp")]
|
||||
Socket::Udp(ref mut socket) =>
|
||||
socket.dispatch(|response| {
|
||||
|
@ -237,16 +247,6 @@ impl<'b, 'c, DeviceT> Interface<'b, 'c, DeviceT>
|
|||
device_result = inner.dispatch(tx_token, timestamp, Packet::Tcp(response));
|
||||
device_result
|
||||
}),
|
||||
#[cfg(feature = "socket-icmp")]
|
||||
Socket::Icmp(ref mut socket) =>
|
||||
socket.dispatch(&caps, |response| {
|
||||
let tx_token = device.transmit().ok_or(Error::Exhausted)?;
|
||||
match response {
|
||||
(IpRepr::Ipv4(repr), icmp_repr) =>
|
||||
inner.dispatch(tx_token, timestamp, Packet::Icmpv4((repr, icmp_repr))),
|
||||
_ => Err(Error::Unaddressable),
|
||||
}
|
||||
}),
|
||||
Socket::__Nonexhaustive(_) => unreachable!()
|
||||
};
|
||||
match (device_result, socket_result) {
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
//!
|
||||
//! # The socket layer
|
||||
//! The socket layer APIs are provided in the module [socket](socket/index.html); currently,
|
||||
//! TCP, UDP, ICMP, and Raw sockets are provided. The socket API provides the usual primitives,
|
||||
//! raw, ICMP, TCP, and UDP sockets are provided. The socket API provides the usual primitives,
|
||||
//! but necessarily differs in many from the [Berkeley socket API][berk], as the latter was
|
||||
//! not designed to be used without heap allocation.
|
||||
//! [berk]: https://en.wikipedia.org/wiki/Berkeley_sockets
|
||||
|
|
|
@ -167,43 +167,49 @@ impl<'a, 'b> IcmpSocket<'a, 'b> {
|
|||
/// diagnose connection problems.
|
||||
///
|
||||
/// ```
|
||||
/// # use smoltcp::socket::{IcmpPacketBuffer, IcmpSocketBuffer};
|
||||
/// # use smoltcp::socket::{Socket, IcmpSocket, IcmpPacketBuffer, IcmpSocketBuffer};
|
||||
/// # let rx_buffer = IcmpSocketBuffer::new(vec![IcmpPacketBuffer::new(vec![0; 20])]);
|
||||
/// # let tx_buffer = IcmpSocketBuffer::new(vec![IcmpPacketBuffer::new(vec![0; 20])]);
|
||||
/// use smoltcp::wire::IpEndpoint;
|
||||
/// use smoltcp::socket::{Socket, IcmpSocket, IcmpEndpoint};
|
||||
/// let mut icmp_socket = match IcmpSocket::new(rx_buffer, tx_buffer) {
|
||||
/// Socket::Icmp(socket) => socket,
|
||||
/// _ => unreachable!()
|
||||
/// };
|
||||
/// use smoltcp::socket::IcmpEndpoint;
|
||||
///
|
||||
/// let mut icmp_socket = // ...
|
||||
/// # match IcmpSocket::new(rx_buffer, tx_buffer) {
|
||||
/// # Socket::Icmp(socket) => socket,
|
||||
/// # _ => unreachable!()
|
||||
/// # };
|
||||
///
|
||||
/// // Bind to ICMP error responses for UDP packets sent from port 53.
|
||||
/// let endpoint = IpEndpoint::from(53);
|
||||
/// icmp_socket.bind(IcmpEndpoint::Udp(endpoint)).unwrap();
|
||||
/// ```
|
||||
///
|
||||
/// ## Bind to a specific ICMP identifier:
|
||||
/// ## Bind to a specific IP identifier:
|
||||
///
|
||||
/// To [send] and [recv] ICMP packets that are not associated with a specific UDP
|
||||
/// port, the socket may be bound to a specific ICMP identifier using
|
||||
/// port, the socket may be bound to a specific IP identifier using
|
||||
/// [IcmpEndpoint::Ident]. This is useful for sending and receiving Echo Request/Reply
|
||||
/// messages.
|
||||
///
|
||||
/// ```
|
||||
/// # use smoltcp::socket::{IcmpPacketBuffer, IcmpSocketBuffer};
|
||||
/// # use smoltcp::socket::{Socket, IcmpSocket, IcmpPacketBuffer, IcmpSocketBuffer};
|
||||
/// # let rx_buffer = IcmpSocketBuffer::new(vec![IcmpPacketBuffer::new(vec![0; 20])]);
|
||||
/// # let tx_buffer = IcmpSocketBuffer::new(vec![IcmpPacketBuffer::new(vec![0; 20])]);
|
||||
/// use smoltcp::socket::{Socket, IcmpSocket, IcmpEndpoint};
|
||||
/// let mut icmp_socket = match IcmpSocket::new(rx_buffer, tx_buffer) {
|
||||
/// Socket::Icmp(socket) => socket,
|
||||
/// _ => unreachable!()
|
||||
/// };
|
||||
/// // Bind to ICMP messages with the identifier 0x1234
|
||||
/// use smoltcp::socket::IcmpEndpoint;
|
||||
///
|
||||
/// let mut icmp_socket = // ...
|
||||
/// # match IcmpSocket::new(rx_buffer, tx_buffer) {
|
||||
/// # Socket::Icmp(socket) => socket,
|
||||
/// # _ => unreachable!()
|
||||
/// # };
|
||||
///
|
||||
/// // Bind to ICMP messages with the IP identifier 0x1234
|
||||
/// icmp_socket.bind(IcmpEndpoint::Ident(0x1234)).unwrap();
|
||||
/// ```
|
||||
///
|
||||
/// [is_specified]: enum.IcmpEndpoint.html#method.is_specified
|
||||
/// [IcmpEndpoint::Ident]: enum.IcmpEndpoint#variant.Ident
|
||||
/// [IcmpEndpoint::Udp]: enum.IcmpEndpoint#variant.Udp
|
||||
/// [IcmpEndpoint::Ident]: enum.IcmpEndpoint.html#variant.Ident
|
||||
/// [IcmpEndpoint::Udp]: enum.IcmpEndpoint.html#variant.Udp
|
||||
/// [send]: #method.send
|
||||
/// [recv]: #method.recv
|
||||
pub fn bind<T: Into<Endpoint>>(&mut self, endpoint: T) -> Result<()> {
|
||||
|
@ -241,7 +247,7 @@ impl<'a, 'b> IcmpSocket<'a, 'b> {
|
|||
///
|
||||
/// This function returns `Err(Error::Exhausted)` if the transmit buffer is full,
|
||||
/// `Err(Error::Truncated)` if the requested size is larger than the packet buffer
|
||||
/// size, and `Err(Error::Unaddressable)` if the or remote address, is unspecified.
|
||||
/// size, and `Err(Error::Unaddressable)` if the remote address is unspecified.
|
||||
pub fn send(&mut self, size: usize, endpoint: IpAddress) -> Result<&mut [u8]> {
|
||||
if endpoint.is_unspecified() {
|
||||
return Err(Error::Unaddressable)
|
||||
|
@ -289,34 +295,24 @@ impl<'a, 'b> IcmpSocket<'a, 'b> {
|
|||
/// the given sockets received buffer.
|
||||
pub(crate) fn accepts(&self, ip_repr: &IpRepr, icmp_repr: &Icmpv4Repr,
|
||||
cksum: &ChecksumCapabilities) -> bool {
|
||||
match self.endpoint {
|
||||
match (&self.endpoint, icmp_repr) {
|
||||
// If we are bound to ICMP errors associated to a UDP port, only
|
||||
// accept Destination Unreachable messages with the data containing
|
||||
// a UDP packet send from the local port we are bound to.
|
||||
Endpoint::Udp(endpoint) =>
|
||||
if !endpoint.addr.is_unspecified() && endpoint.addr != ip_repr.dst_addr() {
|
||||
false
|
||||
} else {
|
||||
match icmp_repr {
|
||||
&Icmpv4Repr::DstUnreachable { data, .. } => {
|
||||
let packet = UdpPacket::new(data);
|
||||
match UdpRepr::parse(&packet, &ip_repr.src_addr(),
|
||||
&ip_repr.dst_addr(), cksum) {
|
||||
Ok(repr) => endpoint.port == repr.src_port,
|
||||
Err(_) => false,
|
||||
}
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
(&Endpoint::Udp(endpoint), &Icmpv4Repr::DstUnreachable { data, .. })
|
||||
if endpoint.addr.is_unspecified() || endpoint.addr == ip_repr.dst_addr() => {
|
||||
let packet = UdpPacket::new(data);
|
||||
match UdpRepr::parse(&packet, &ip_repr.src_addr(), &ip_repr.dst_addr(), cksum) {
|
||||
Ok(repr) => endpoint.port == repr.src_port,
|
||||
Err(_) => false,
|
||||
}
|
||||
}
|
||||
// If we are bound to a specific ICMP identifier value, only accept an
|
||||
// Echo Request/Reply with the identifier field matching the endpoint
|
||||
// port.
|
||||
Endpoint::Ident(id) => match icmp_repr {
|
||||
&Icmpv4Repr::EchoRequest { ident, .. } | &Icmpv4Repr::EchoReply { ident, .. } =>
|
||||
ident == id,
|
||||
_ => false,
|
||||
}
|
||||
(&Endpoint::Ident(bound_ident), &Icmpv4Repr::EchoRequest { ident, .. }) |
|
||||
(&Endpoint::Ident(bound_ident), &Icmpv4Repr::EchoReply { ident, .. }) =>
|
||||
ident == bound_ident,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
@ -330,9 +326,9 @@ impl<'a, 'b> IcmpSocket<'a, 'b> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn dispatch<F>(&mut self, caps: &DeviceCapabilities,
|
||||
emit: F) -> Result<()>
|
||||
where F: FnOnce((IpRepr, Icmpv4Repr)) -> Result<()> {
|
||||
pub(crate) fn dispatch<F>(&mut self, caps: &DeviceCapabilities, emit: F) -> Result<()>
|
||||
where F: FnOnce((IpRepr, Icmpv4Repr)) -> Result<()>
|
||||
{
|
||||
let handle = self.handle;
|
||||
let ttl = self.ttl.unwrap_or(64);
|
||||
let checksum = &caps.checksum;
|
||||
|
|
Loading…
Reference in New Issue