diff --git a/examples/ping.rs b/examples/ping.rs index 7e33a212a..3e7aef167 100644 --- a/examples/ping.rs +++ b/examples/ping.rs @@ -187,11 +187,8 @@ fn main() { remote_addr ); icmp_repr.emit( - &iface - .get_source_address_ipv6(&address) - .unwrap() - .into_address(), - &remote_addr, + &iface.get_source_address_ipv6(&address).unwrap(), + &address, &mut icmp_packet, &device_caps.checksum, ); @@ -223,11 +220,8 @@ fn main() { IpAddress::Ipv6(address) => { let icmp_packet = Icmpv6Packet::new_checked(&payload).unwrap(); let icmp_repr = Icmpv6Repr::parse( - &remote_addr, - &iface - .get_source_address_ipv6(&address) - .unwrap() - .into_address(), + &address, + &iface.get_source_address_ipv6(&address).unwrap(), &icmp_packet, &device_caps.checksum, ) diff --git a/src/iface/interface/ipv4.rs b/src/iface/interface/ipv4.rs index 8778c5902..303abdc1d 100644 --- a/src/iface/interface/ipv4.rs +++ b/src/iface/interface/ipv4.rs @@ -166,16 +166,13 @@ impl InterfaceInner { if udp_packet.src_port() == dhcp_socket.server_port && udp_packet.dst_port() == dhcp_socket.client_port { - let (src_addr, dst_addr) = (ip_repr.src_addr(), ip_repr.dst_addr()); let udp_repr = check!(UdpRepr::parse( &udp_packet, - &src_addr, - &dst_addr, + &ipv4_repr.src_addr.into(), + &ipv4_repr.dst_addr.into(), &self.caps.checksum )); - let udp_payload = udp_packet.payload(); - - dhcp_socket.process(self, &ipv4_repr, &udp_repr, udp_payload); + dhcp_socket.process(self, &ipv4_repr, &udp_repr, udp_packet.payload()); return None; } } @@ -200,7 +197,7 @@ impl InterfaceInner { } match ipv4_repr.next_header { - IpProtocol::Icmp => self.process_icmpv4(sockets, ip_repr, ip_payload), + IpProtocol::Icmp => self.process_icmpv4(sockets, ipv4_repr, ip_payload), #[cfg(feature = "proto-igmp")] IpProtocol::Igmp => self.process_igmp(ipv4_repr, ip_payload), @@ -298,7 +295,7 @@ impl InterfaceInner { pub(super) fn process_icmpv4<'frame>( &mut self, _sockets: &mut SocketSet, - ip_repr: IpRepr, + ip_repr: Ipv4Repr, ip_payload: &'frame [u8], ) -> Option> { let icmp_packet = check!(Icmpv4Packet::new_checked(ip_payload)); @@ -312,8 +309,8 @@ impl InterfaceInner { .items_mut() .filter_map(|i| icmp::Socket::downcast_mut(&mut i.socket)) { - if icmp_socket.accepts(self, &ip_repr, &icmp_repr.into()) { - icmp_socket.process(self, &ip_repr, &icmp_repr.into()); + if icmp_socket.accepts_v4(self, &ip_repr, &icmp_repr) { + icmp_socket.process_v4(self, &ip_repr, &icmp_repr); handled_by_icmp_socket = true; } } @@ -331,11 +328,7 @@ impl InterfaceInner { seq_no, data, }; - match ip_repr { - IpRepr::Ipv4(ipv4_repr) => self.icmpv4_reply(ipv4_repr, icmp_reply_repr), - #[allow(unreachable_patterns)] - _ => unreachable!(), - } + self.icmpv4_reply(ip_repr, icmp_reply_repr) } // Ignore any echo replies. diff --git a/src/iface/interface/ipv6.rs b/src/iface/interface/ipv6.rs index f0ffa6e0c..7fc858e6c 100644 --- a/src/iface/interface/ipv6.rs +++ b/src/iface/interface/ipv6.rs @@ -260,7 +260,7 @@ impl InterfaceInner { ip_payload: &'frame [u8], ) -> Option> { match nxt_hdr { - IpProtocol::Icmpv6 => self.process_icmpv6(sockets, ipv6_repr.into(), ip_payload), + IpProtocol::Icmpv6 => self.process_icmpv6(sockets, ipv6_repr, ip_payload), #[cfg(any(feature = "socket-udp", feature = "socket-dns"))] IpProtocol::Udp => self.process_udp( @@ -296,13 +296,13 @@ impl InterfaceInner { pub(super) fn process_icmpv6<'frame>( &mut self, _sockets: &mut SocketSet, - ip_repr: IpRepr, + ip_repr: Ipv6Repr, ip_payload: &'frame [u8], ) -> Option> { let icmp_packet = check!(Icmpv6Packet::new_checked(ip_payload)); let icmp_repr = check!(Icmpv6Repr::parse( - &ip_repr.src_addr(), - &ip_repr.dst_addr(), + &ip_repr.src_addr, + &ip_repr.dst_addr, &icmp_packet, &self.caps.checksum, )); @@ -317,8 +317,8 @@ impl InterfaceInner { .items_mut() .filter_map(|i| IcmpSocket::downcast_mut(&mut i.socket)) { - if icmp_socket.accepts(self, &ip_repr, &icmp_repr.into()) { - icmp_socket.process(self, &ip_repr, &icmp_repr.into()); + if icmp_socket.accepts_v6(self, &ip_repr, &icmp_repr) { + icmp_socket.process_v6(self, &ip_repr, &icmp_repr); handled_by_icmp_socket = true; } } @@ -330,35 +330,27 @@ impl InterfaceInner { ident, seq_no, data, - } => match ip_repr { - IpRepr::Ipv6(ipv6_repr) => { - let icmp_reply_repr = Icmpv6Repr::EchoReply { - ident, - seq_no, - data, - }; - self.icmpv6_reply(ipv6_repr, icmp_reply_repr) - } - #[allow(unreachable_patterns)] - _ => unreachable!(), - }, + } => { + let icmp_reply_repr = Icmpv6Repr::EchoReply { + ident, + seq_no, + data, + }; + self.icmpv6_reply(ip_repr, icmp_reply_repr) + } // Ignore any echo replies. Icmpv6Repr::EchoReply { .. } => None, // Forward any NDISC packets to the ndisc packet handler #[cfg(any(feature = "medium-ethernet", feature = "medium-ieee802154"))] - Icmpv6Repr::Ndisc(repr) if ip_repr.hop_limit() == 0xff => match ip_repr { - IpRepr::Ipv6(ipv6_repr) => match self.caps.medium { - #[cfg(feature = "medium-ethernet")] - Medium::Ethernet => self.process_ndisc(ipv6_repr, repr), - #[cfg(feature = "medium-ieee802154")] - Medium::Ieee802154 => self.process_ndisc(ipv6_repr, repr), - #[cfg(feature = "medium-ip")] - Medium::Ip => None, - }, - #[allow(unreachable_patterns)] - _ => unreachable!(), + Icmpv6Repr::Ndisc(repr) if ip_repr.hop_limit == 0xff => match self.caps.medium { + #[cfg(feature = "medium-ethernet")] + Medium::Ethernet => self.process_ndisc(ip_repr, repr), + #[cfg(feature = "medium-ieee802154")] + Medium::Ieee802154 => self.process_ndisc(ip_repr, repr), + #[cfg(feature = "medium-ip")] + Medium::Ip => None, }, // Don't report an error if a packet with unknown type diff --git a/src/iface/interface/sixlowpan.rs b/src/iface/interface/sixlowpan.rs index db81155fa..3caa446f5 100644 --- a/src/iface/interface/sixlowpan.rs +++ b/src/iface/interface/sixlowpan.rs @@ -508,8 +508,8 @@ impl InterfaceInner { match &mut packet.payload { IpPayload::Icmpv6(icmp_repr) => { icmp_repr.emit( - &packet.header.src_addr.into(), - &packet.header.dst_addr.into(), + &packet.header.src_addr, + &packet.header.dst_addr, &mut Icmpv6Packet::new_unchecked(&mut buffer[..icmp_repr.buffer_len()]), checksum_caps, ); diff --git a/src/iface/interface/tests/ipv4.rs b/src/iface/interface/tests/ipv4.rs index 9d2981f0d..cb93a4b48 100644 --- a/src/iface/interface/tests/ipv4.rs +++ b/src/iface/interface/tests/ipv4.rs @@ -565,7 +565,6 @@ fn test_icmpv4_socket(#[case] medium: Medium) { payload_len: 24, hop_limit: 64, }; - let ip_repr = IpRepr::Ipv4(ipv4_repr); // Open a socket and ensure the packet is handled due to the listening // socket. @@ -583,7 +582,9 @@ fn test_icmpv4_socket(#[case] medium: Medium) { ..ipv4_repr }; assert_eq!( - iface.inner.process_icmpv4(&mut sockets, ip_repr, icmp_data), + iface + .inner + .process_icmpv4(&mut sockets, ipv4_repr, icmp_data), Some(Packet::new_ipv4(ipv4_reply, IpPayload::Icmpv4(echo_reply))) ); diff --git a/src/iface/interface/tests/ipv6.rs b/src/iface/interface/tests/ipv6.rs index c52053708..0851dadea 100644 --- a/src/iface/interface/tests/ipv6.rs +++ b/src/iface/interface/tests/ipv6.rs @@ -16,8 +16,8 @@ fn parse_ipv6(data: &[u8]) -> crate::wire::Result> { IpProtocol::IpSecAh => todo!(), IpProtocol::Icmpv6 => { let icmp = Icmpv6Repr::parse( - &ipv6.src_addr.into(), - &ipv6.dst_addr.into(), + &ipv6.src_addr, + &ipv6.dst_addr, &Icmpv6Packet::new_checked(ipv6_header.payload())?, &Default::default(), )?; @@ -707,8 +707,8 @@ fn test_handle_valid_ndisc_request(#[case] medium: Medium) { frame.set_ethertype(EthernetProtocol::Ipv6); ip_repr.emit(frame.payload_mut(), &ChecksumCapabilities::default()); solicit.emit( - &remote_ip_addr.into(), - &local_ip_addr.solicited_node().into(), + &remote_ip_addr, + &local_ip_addr.solicited_node(), &mut Icmpv6Packet::new_unchecked(&mut frame.payload_mut()[ip_repr.header_len()..]), &ChecksumCapabilities::default(), ); diff --git a/src/iface/neighbor.rs b/src/iface/neighbor.rs index 0c451fa0e..8fa1d7d5d 100644 --- a/src/iface/neighbor.rs +++ b/src/iface/neighbor.rs @@ -163,7 +163,10 @@ impl Cache { #[cfg(test)] mod test { use super::*; - use crate::wire::ip::test::{MOCK_IP_ADDR_1, MOCK_IP_ADDR_2, MOCK_IP_ADDR_3, MOCK_IP_ADDR_4}; + #[cfg(all(feature = "proto-ipv4", not(feature = "proto-ipv6")))] + use crate::wire::ipv4::test::{MOCK_IP_ADDR_1, MOCK_IP_ADDR_2, MOCK_IP_ADDR_3, MOCK_IP_ADDR_4}; + #[cfg(feature = "proto-ipv6")] + use crate::wire::ipv6::test::{MOCK_IP_ADDR_1, MOCK_IP_ADDR_2, MOCK_IP_ADDR_3, MOCK_IP_ADDR_4}; use crate::wire::EthernetAddress; @@ -177,30 +180,30 @@ mod test { let mut cache = Cache::new(); assert!(!cache - .lookup(&MOCK_IP_ADDR_1, Instant::from_millis(0)) + .lookup(&MOCK_IP_ADDR_1.into(), Instant::from_millis(0)) .found()); assert!(!cache - .lookup(&MOCK_IP_ADDR_2, Instant::from_millis(0)) + .lookup(&MOCK_IP_ADDR_2.into(), Instant::from_millis(0)) .found()); - cache.fill(MOCK_IP_ADDR_1, HADDR_A, Instant::from_millis(0)); + cache.fill(MOCK_IP_ADDR_1.into(), HADDR_A, Instant::from_millis(0)); assert_eq!( - cache.lookup(&MOCK_IP_ADDR_1, Instant::from_millis(0)), + cache.lookup(&MOCK_IP_ADDR_1.into(), Instant::from_millis(0)), Answer::Found(HADDR_A) ); assert!(!cache - .lookup(&MOCK_IP_ADDR_2, Instant::from_millis(0)) + .lookup(&MOCK_IP_ADDR_2.into(), Instant::from_millis(0)) .found()); assert!(!cache .lookup( - &MOCK_IP_ADDR_1, + &MOCK_IP_ADDR_1.into(), Instant::from_millis(0) + Cache::ENTRY_LIFETIME * 2 ) .found(),); - cache.fill(MOCK_IP_ADDR_1, HADDR_A, Instant::from_millis(0)); + cache.fill(MOCK_IP_ADDR_1.into(), HADDR_A, Instant::from_millis(0)); assert!(!cache - .lookup(&MOCK_IP_ADDR_2, Instant::from_millis(0)) + .lookup(&MOCK_IP_ADDR_2.into(), Instant::from_millis(0)) .found()); } @@ -208,14 +211,14 @@ mod test { fn test_expire() { let mut cache = Cache::new(); - cache.fill(MOCK_IP_ADDR_1, HADDR_A, Instant::from_millis(0)); + cache.fill(MOCK_IP_ADDR_1.into(), HADDR_A, Instant::from_millis(0)); assert_eq!( - cache.lookup(&MOCK_IP_ADDR_1, Instant::from_millis(0)), + cache.lookup(&MOCK_IP_ADDR_1.into(), Instant::from_millis(0)), Answer::Found(HADDR_A) ); assert!(!cache .lookup( - &MOCK_IP_ADDR_1, + &MOCK_IP_ADDR_1.into(), Instant::from_millis(0) + Cache::ENTRY_LIFETIME * 2 ) .found(),); @@ -225,14 +228,14 @@ mod test { fn test_replace() { let mut cache = Cache::new(); - cache.fill(MOCK_IP_ADDR_1, HADDR_A, Instant::from_millis(0)); + cache.fill(MOCK_IP_ADDR_1.into(), HADDR_A, Instant::from_millis(0)); assert_eq!( - cache.lookup(&MOCK_IP_ADDR_1, Instant::from_millis(0)), + cache.lookup(&MOCK_IP_ADDR_1.into(), Instant::from_millis(0)), Answer::Found(HADDR_A) ); - cache.fill(MOCK_IP_ADDR_1, HADDR_B, Instant::from_millis(0)); + cache.fill(MOCK_IP_ADDR_1.into(), HADDR_B, Instant::from_millis(0)); assert_eq!( - cache.lookup(&MOCK_IP_ADDR_1, Instant::from_millis(0)), + cache.lookup(&MOCK_IP_ADDR_1.into(), Instant::from_millis(0)), Answer::Found(HADDR_B) ); } @@ -241,23 +244,23 @@ mod test { fn test_evict() { let mut cache = Cache::new(); - cache.fill(MOCK_IP_ADDR_1, HADDR_A, Instant::from_millis(100)); - cache.fill(MOCK_IP_ADDR_2, HADDR_B, Instant::from_millis(50)); - cache.fill(MOCK_IP_ADDR_3, HADDR_C, Instant::from_millis(200)); + cache.fill(MOCK_IP_ADDR_1.into(), HADDR_A, Instant::from_millis(100)); + cache.fill(MOCK_IP_ADDR_2.into(), HADDR_B, Instant::from_millis(50)); + cache.fill(MOCK_IP_ADDR_3.into(), HADDR_C, Instant::from_millis(200)); assert_eq!( - cache.lookup(&MOCK_IP_ADDR_2, Instant::from_millis(1000)), + cache.lookup(&MOCK_IP_ADDR_2.into(), Instant::from_millis(1000)), Answer::Found(HADDR_B) ); assert!(!cache - .lookup(&MOCK_IP_ADDR_4, Instant::from_millis(1000)) + .lookup(&MOCK_IP_ADDR_4.into(), Instant::from_millis(1000)) .found()); - cache.fill(MOCK_IP_ADDR_4, HADDR_D, Instant::from_millis(300)); + cache.fill(MOCK_IP_ADDR_4.into(), HADDR_D, Instant::from_millis(300)); assert!(!cache - .lookup(&MOCK_IP_ADDR_2, Instant::from_millis(1000)) + .lookup(&MOCK_IP_ADDR_2.into(), Instant::from_millis(1000)) .found()); assert_eq!( - cache.lookup(&MOCK_IP_ADDR_4, Instant::from_millis(1000)), + cache.lookup(&MOCK_IP_ADDR_4.into(), Instant::from_millis(1000)), Answer::Found(HADDR_D) ); } @@ -267,17 +270,17 @@ mod test { let mut cache = Cache::new(); assert_eq!( - cache.lookup(&MOCK_IP_ADDR_1, Instant::from_millis(0)), + cache.lookup(&MOCK_IP_ADDR_1.into(), Instant::from_millis(0)), Answer::NotFound ); cache.limit_rate(Instant::from_millis(0)); assert_eq!( - cache.lookup(&MOCK_IP_ADDR_1, Instant::from_millis(100)), + cache.lookup(&MOCK_IP_ADDR_1.into(), Instant::from_millis(100)), Answer::RateLimited ); assert_eq!( - cache.lookup(&MOCK_IP_ADDR_1, Instant::from_millis(2000)), + cache.lookup(&MOCK_IP_ADDR_1.into(), Instant::from_millis(2000)), Answer::NotFound ); } @@ -286,21 +289,21 @@ mod test { fn test_flush() { let mut cache = Cache::new(); - cache.fill(MOCK_IP_ADDR_1, HADDR_A, Instant::from_millis(0)); + cache.fill(MOCK_IP_ADDR_1.into(), HADDR_A, Instant::from_millis(0)); assert_eq!( - cache.lookup(&MOCK_IP_ADDR_1, Instant::from_millis(0)), + cache.lookup(&MOCK_IP_ADDR_1.into(), Instant::from_millis(0)), Answer::Found(HADDR_A) ); assert!(!cache - .lookup(&MOCK_IP_ADDR_2, Instant::from_millis(0)) + .lookup(&MOCK_IP_ADDR_2.into(), Instant::from_millis(0)) .found()); cache.flush(); assert!(!cache - .lookup(&MOCK_IP_ADDR_1, Instant::from_millis(0)) + .lookup(&MOCK_IP_ADDR_1.into(), Instant::from_millis(0)) .found()); assert!(!cache - .lookup(&MOCK_IP_ADDR_1, Instant::from_millis(0)) + .lookup(&MOCK_IP_ADDR_1.into(), Instant::from_millis(0)) .found()); } } diff --git a/src/iface/packet.rs b/src/iface/packet.rs index 4fdb19d77..b586d75e8 100644 --- a/src/iface/packet.rs +++ b/src/iface/packet.rs @@ -84,12 +84,20 @@ impl<'p> Packet<'p> { #[cfg(feature = "proto-igmp")] IpPayload::Igmp(igmp_repr) => igmp_repr.emit(&mut IgmpPacket::new_unchecked(payload)), #[cfg(feature = "proto-ipv6")] - IpPayload::Icmpv6(icmpv6_repr) => icmpv6_repr.emit( - &_ip_repr.src_addr(), - &_ip_repr.dst_addr(), - &mut Icmpv6Packet::new_unchecked(payload), - &caps.checksum, - ), + IpPayload::Icmpv6(icmpv6_repr) => { + let ipv6_repr = match _ip_repr { + #[cfg(feature = "proto-ipv4")] + IpRepr::Ipv4(_) => unreachable!(), + IpRepr::Ipv6(repr) => repr, + }; + + icmpv6_repr.emit( + &ipv6_repr.src_addr, + &ipv6_repr.dst_addr, + &mut Icmpv6Packet::new_unchecked(payload), + &caps.checksum, + ) + } #[cfg(feature = "socket-raw")] IpPayload::Raw(raw_packet) => payload.copy_from_slice(raw_packet), #[cfg(any(feature = "socket-udp", feature = "socket-dns"))] diff --git a/src/socket/icmp.rs b/src/socket/icmp.rs index c18b754d5..4ddf1da57 100644 --- a/src/socket/icmp.rs +++ b/src/socket/icmp.rs @@ -412,22 +412,26 @@ impl<'a> Socket<'a> { Ok((length, endpoint)) } - /// Filter determining which packets received by the interface are appended to - /// the given sockets received buffer. - pub(crate) fn accepts(&self, cx: &mut Context, ip_repr: &IpRepr, icmp_repr: &IcmpRepr) -> bool { + /// Fitler determining whether the socket accepts a given ICMPv4 packet. + /// Accepted packets are enqueued into the socket's receive buffer. + #[cfg(feature = "proto-ipv4")] + #[inline] + pub(crate) fn accepts_v4( + &self, + cx: &mut Context, + ip_repr: &Ipv4Repr, + icmp_repr: &Icmpv4Repr, + ) -> bool { match (&self.endpoint, icmp_repr) { // If we are bound to ICMP errors associated to a UDP port, only // accept Destination Unreachable or Time Exceeded messages with // the data containing a UDP packet send from the local port we // are bound to. - #[cfg(feature = "proto-ipv4")] ( &Endpoint::Udp(endpoint), - &IcmpRepr::Ipv4( - Icmpv4Repr::DstUnreachable { data, header, .. } - | Icmpv4Repr::TimeExceeded { data, header, .. }, - ), - ) if endpoint.addr.is_none() || endpoint.addr == Some(ip_repr.dst_addr()) => { + &Icmpv4Repr::DstUnreachable { data, header, .. } + | &Icmpv4Repr::TimeExceeded { data, header, .. }, + ) if endpoint.addr.is_none() || endpoint.addr == Some(ip_repr.dst_addr.into()) => { let packet = UdpPacket::new_unchecked(data); match UdpRepr::parse( &packet, @@ -439,14 +443,37 @@ impl<'a> Socket<'a> { Err(_) => false, } } - #[cfg(feature = "proto-ipv6")] + // 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(bound_ident), &Icmpv4Repr::EchoRequest { ident, .. }) + | (&Endpoint::Ident(bound_ident), &Icmpv4Repr::EchoReply { ident, .. }) => { + ident == bound_ident + } + _ => false, + } + } + + /// Fitler determining whether the socket accepts a given ICMPv6 packet. + /// Accepted packets are enqueued into the socket's receive buffer. + #[cfg(feature = "proto-ipv6")] + #[inline] + pub(crate) fn accepts_v6( + &self, + cx: &mut Context, + ip_repr: &Ipv6Repr, + icmp_repr: &Icmpv6Repr, + ) -> bool { + match (&self.endpoint, icmp_repr) { + // If we are bound to ICMP errors associated to a UDP port, only + // accept Destination Unreachable or Time Exceeded messages with + // the data containing a UDP packet send from the local port we + // are bound to. ( &Endpoint::Udp(endpoint), - &IcmpRepr::Ipv6( - Icmpv6Repr::DstUnreachable { data, header, .. } - | Icmpv6Repr::TimeExceeded { data, header, .. }, - ), - ) if endpoint.addr.is_none() || endpoint.addr == Some(ip_repr.dst_addr()) => { + &Icmpv6Repr::DstUnreachable { data, header, .. } + | &Icmpv6Repr::TimeExceeded { data, header, .. }, + ) if endpoint.addr.is_none() || endpoint.addr == Some(ip_repr.dst_addr.into()) => { let packet = UdpPacket::new_unchecked(data); match UdpRepr::parse( &packet, @@ -461,64 +488,60 @@ impl<'a> Socket<'a> { // If we are bound to a specific ICMP identifier value, only accept an // Echo Request/Reply with the identifier field matching the endpoint // port. - #[cfg(feature = "proto-ipv4")] ( &Endpoint::Ident(bound_ident), - &IcmpRepr::Ipv4(Icmpv4Repr::EchoRequest { ident, .. }), - ) - | ( - &Endpoint::Ident(bound_ident), - &IcmpRepr::Ipv4(Icmpv4Repr::EchoReply { ident, .. }), - ) => ident == bound_ident, - #[cfg(feature = "proto-ipv6")] - ( - &Endpoint::Ident(bound_ident), - &IcmpRepr::Ipv6(Icmpv6Repr::EchoRequest { ident, .. }), - ) - | ( - &Endpoint::Ident(bound_ident), - &IcmpRepr::Ipv6(Icmpv6Repr::EchoReply { ident, .. }), + &Icmpv6Repr::EchoRequest { ident, .. } | &Icmpv6Repr::EchoReply { ident, .. }, ) => ident == bound_ident, _ => false, } } - pub(crate) fn process(&mut self, _cx: &mut Context, ip_repr: &IpRepr, icmp_repr: &IcmpRepr) { - match icmp_repr { - #[cfg(feature = "proto-ipv4")] - IcmpRepr::Ipv4(icmp_repr) => { - net_trace!("icmp: receiving {} octets", icmp_repr.buffer_len()); - - match self - .rx_buffer - .enqueue(icmp_repr.buffer_len(), ip_repr.src_addr()) - { - Ok(packet_buf) => { - icmp_repr.emit( - &mut Icmpv4Packet::new_unchecked(packet_buf), - &ChecksumCapabilities::default(), - ); - } - Err(_) => net_trace!("icmp: buffer full, dropped incoming packet"), - } - } - #[cfg(feature = "proto-ipv6")] - IcmpRepr::Ipv6(icmp_repr) => { - net_trace!("icmp: receiving {} octets", icmp_repr.buffer_len()); - - match self - .rx_buffer - .enqueue(icmp_repr.buffer_len(), ip_repr.src_addr()) - { - Ok(packet_buf) => icmp_repr.emit( - &ip_repr.src_addr(), - &ip_repr.dst_addr(), - &mut Icmpv6Packet::new_unchecked(packet_buf), - &ChecksumCapabilities::default(), - ), - Err(_) => net_trace!("icmp: buffer full, dropped incoming packet"), - } + #[cfg(feature = "proto-ipv4")] + pub(crate) fn process_v4( + &mut self, + _cx: &mut Context, + ip_repr: &Ipv4Repr, + icmp_repr: &Icmpv4Repr, + ) { + net_trace!("icmp: receiving {} octets", icmp_repr.buffer_len()); + + match self + .rx_buffer + .enqueue(icmp_repr.buffer_len(), ip_repr.src_addr.into()) + { + Ok(packet_buf) => { + icmp_repr.emit( + &mut Icmpv4Packet::new_unchecked(packet_buf), + &ChecksumCapabilities::default(), + ); } + Err(_) => net_trace!("icmp: buffer full, dropped incoming packet"), + } + + #[cfg(feature = "async")] + self.rx_waker.wake(); + } + + #[cfg(feature = "proto-ipv6")] + pub(crate) fn process_v6( + &mut self, + _cx: &mut Context, + ip_repr: &Ipv6Repr, + icmp_repr: &Icmpv6Repr, + ) { + net_trace!("icmp: receiving {} octets", icmp_repr.buffer_len()); + + match self + .rx_buffer + .enqueue(icmp_repr.buffer_len(), ip_repr.src_addr.into()) + { + Ok(packet_buf) => icmp_repr.emit( + &ip_repr.src_addr, + &ip_repr.dst_addr, + &mut Icmpv6Packet::new_unchecked(packet_buf), + &ChecksumCapabilities::default(), + ), + Err(_) => net_trace!("icmp: buffer full, dropped incoming packet"), } #[cfg(feature = "async")] @@ -583,8 +606,8 @@ impl<'a> Socket<'a> { }; let packet = Icmpv6Packet::new_unchecked(&*packet_buf); let repr = match Icmpv6Repr::parse( - &src_addr.into(), - &dst_addr.into(), + &src_addr, + &dst_addr, &packet, &ChecksumCapabilities::ignored(), ) { @@ -684,13 +707,13 @@ mod test_ipv4 { hop_limit: 0x40, }); - static REMOTE_IPV4_REPR: IpRepr = IpRepr::Ipv4(Ipv4Repr { + static REMOTE_IPV4_REPR: Ipv4Repr = Ipv4Repr { src_addr: REMOTE_IPV4, dst_addr: LOCAL_IPV4, next_header: IpProtocol::Icmp, payload_len: 24, hop_limit: 0x40, - }); + }; #[test] fn test_send_unaddressable() { @@ -816,12 +839,12 @@ mod test_ipv4 { ECHOV4_REPR.emit(&mut packet, &checksum); let data = &*packet.into_inner(); - assert!(socket.accepts(cx, &REMOTE_IPV4_REPR, &ECHOV4_REPR.into())); - socket.process(cx, &REMOTE_IPV4_REPR, &ECHOV4_REPR.into()); + assert!(socket.accepts_v4(cx, &REMOTE_IPV4_REPR, &ECHOV4_REPR)); + socket.process_v4(cx, &REMOTE_IPV4_REPR, &ECHOV4_REPR); assert!(socket.can_recv()); - assert!(socket.accepts(cx, &REMOTE_IPV4_REPR, &ECHOV4_REPR.into())); - socket.process(cx, &REMOTE_IPV4_REPR, &ECHOV4_REPR.into()); + assert!(socket.accepts_v4(cx, &REMOTE_IPV4_REPR, &ECHOV4_REPR)); + socket.process_v4(cx, &REMOTE_IPV4_REPR, &ECHOV4_REPR); assert_eq!(socket.recv(), Ok((data, REMOTE_IPV4.into()))); assert!(!socket.can_recv()); @@ -849,7 +872,7 @@ mod test_ipv4 { // Ensure that a packet with an identifier that isn't the bound // ID is not accepted - assert!(!socket.accepts(cx, &REMOTE_IPV4_REPR, &icmp_repr.into())); + assert!(!socket.accepts_v4(cx, &REMOTE_IPV4_REPR, &icmp_repr)); } #[rstest] @@ -888,20 +911,20 @@ mod test_ipv4 { }, data, }; - let ip_repr = IpRepr::Ipv4(Ipv4Repr { + let ip_repr = Ipv4Repr { src_addr: REMOTE_IPV4, dst_addr: LOCAL_IPV4, next_header: IpProtocol::Icmp, payload_len: icmp_repr.buffer_len(), hop_limit: 0x40, - }); + }; assert!(!socket.can_recv()); // Ensure we can accept ICMP error response to the bound // UDP port - assert!(socket.accepts(cx, &ip_repr, &icmp_repr.into())); - socket.process(cx, &ip_repr, &icmp_repr.into()); + assert!(socket.accepts_v4(cx, &ip_repr, &icmp_repr)); + socket.process_v4(cx, &ip_repr, &icmp_repr); assert!(socket.can_recv()); let mut bytes = [0x00; 46]; @@ -939,21 +962,21 @@ mod test_ipv6 { data: &[0xff; 16], }; - static LOCAL_IPV6_REPR: IpRepr = IpRepr::Ipv6(Ipv6Repr { + static LOCAL_IPV6_REPR: Ipv6Repr = Ipv6Repr { src_addr: LOCAL_IPV6, dst_addr: REMOTE_IPV6, next_header: IpProtocol::Icmpv6, payload_len: 24, hop_limit: 0x40, - }); + }; - static REMOTE_IPV6_REPR: IpRepr = IpRepr::Ipv6(Ipv6Repr { + static REMOTE_IPV6_REPR: Ipv6Repr = Ipv6Repr { src_addr: REMOTE_IPV6, dst_addr: LOCAL_IPV6, next_header: IpProtocol::Icmpv6, payload_len: 24, hop_limit: 0x40, - }); + }; #[test] fn test_send_unaddressable() { @@ -986,12 +1009,7 @@ mod test_ipv6 { let mut bytes = vec![0xff; 24]; let mut packet = Icmpv6Packet::new_unchecked(&mut bytes); - ECHOV6_REPR.emit( - &LOCAL_IPV6.into(), - &REMOTE_IPV6.into(), - &mut packet, - &checksum, - ); + ECHOV6_REPR.emit(&LOCAL_IPV6, &REMOTE_IPV6, &mut packet, &checksum); assert_eq!( socket.send_slice(&*packet.into_inner(), REMOTE_IPV6.into()), @@ -1005,7 +1023,7 @@ mod test_ipv6 { assert_eq!( socket.dispatch(cx, |_, (ip_repr, icmp_repr)| { - assert_eq!(ip_repr, LOCAL_IPV6_REPR); + assert_eq!(ip_repr, LOCAL_IPV6_REPR.into()); assert_eq!(icmp_repr, ECHOV6_REPR.into()); Err(()) }), @@ -1016,7 +1034,7 @@ mod test_ipv6 { assert_eq!( socket.dispatch(cx, |_, (ip_repr, icmp_repr)| { - assert_eq!(ip_repr, LOCAL_IPV6_REPR); + assert_eq!(ip_repr, LOCAL_IPV6_REPR.into()); assert_eq!(icmp_repr, ECHOV6_REPR.into()); Ok::<_, ()>(()) }), @@ -1038,12 +1056,7 @@ mod test_ipv6 { let mut bytes = vec![0xff; 24]; let mut packet = Icmpv6Packet::new_unchecked(&mut bytes); - ECHOV6_REPR.emit( - &LOCAL_IPV6.into(), - &REMOTE_IPV6.into(), - &mut packet, - &checksum, - ); + ECHOV6_REPR.emit(&LOCAL_IPV6, &REMOTE_IPV6, &mut packet, &checksum); s.set_hop_limit(Some(0x2a)); @@ -1086,20 +1099,15 @@ mod test_ipv6 { let mut bytes = [0xff; 24]; let mut packet = Icmpv6Packet::new_unchecked(&mut bytes[..]); - ECHOV6_REPR.emit( - &LOCAL_IPV6.into(), - &REMOTE_IPV6.into(), - &mut packet, - &checksum, - ); + ECHOV6_REPR.emit(&LOCAL_IPV6, &REMOTE_IPV6, &mut packet, &checksum); let data = &*packet.into_inner(); - assert!(socket.accepts(cx, &REMOTE_IPV6_REPR, &ECHOV6_REPR.into())); - socket.process(cx, &REMOTE_IPV6_REPR, &ECHOV6_REPR.into()); + assert!(socket.accepts_v6(cx, &REMOTE_IPV6_REPR, &ECHOV6_REPR)); + socket.process_v6(cx, &REMOTE_IPV6_REPR, &ECHOV6_REPR); assert!(socket.can_recv()); - assert!(socket.accepts(cx, &REMOTE_IPV6_REPR, &ECHOV6_REPR.into())); - socket.process(cx, &REMOTE_IPV6_REPR, &ECHOV6_REPR.into()); + assert!(socket.accepts_v6(cx, &REMOTE_IPV6_REPR, &ECHOV6_REPR)); + socket.process_v6(cx, &REMOTE_IPV6_REPR, &ECHOV6_REPR); assert_eq!(socket.recv(), Ok((data, REMOTE_IPV6.into()))); assert!(!socket.can_recv()); @@ -1119,19 +1127,14 @@ mod test_ipv6 { let mut bytes = [0xff; 24]; let mut packet = Icmpv6Packet::new_unchecked(&mut bytes[..]); - ECHOV6_REPR.emit( - &LOCAL_IPV6.into(), - &REMOTE_IPV6.into(), - &mut packet, - &checksum, - ); + ECHOV6_REPR.emit(&LOCAL_IPV6, &REMOTE_IPV6, &mut packet, &checksum); - assert!(socket.accepts(cx, &REMOTE_IPV6_REPR, &ECHOV6_REPR.into())); - socket.process(cx, &REMOTE_IPV6_REPR, &ECHOV6_REPR.into()); + assert!(socket.accepts_v6(cx, &REMOTE_IPV6_REPR, &ECHOV6_REPR)); + socket.process_v6(cx, &REMOTE_IPV6_REPR, &ECHOV6_REPR); assert!(socket.can_recv()); - assert!(socket.accepts(cx, &REMOTE_IPV6_REPR, &ECHOV6_REPR.into())); - socket.process(cx, &REMOTE_IPV6_REPR, &ECHOV6_REPR.into()); + assert!(socket.accepts_v6(cx, &REMOTE_IPV6_REPR, &ECHOV6_REPR)); + socket.process_v6(cx, &REMOTE_IPV6_REPR, &ECHOV6_REPR); let mut buffer = [0u8; 1]; assert_eq!( @@ -1159,16 +1162,11 @@ mod test_ipv6 { seq_no: 0x5678, data: &[0xff; 16], }; - icmp_repr.emit( - &LOCAL_IPV6.into(), - &REMOTE_IPV6.into(), - &mut packet, - &checksum, - ); + icmp_repr.emit(&LOCAL_IPV6, &REMOTE_IPV6, &mut packet, &checksum); // Ensure that a packet with an identifier that isn't the bound // ID is not accepted - assert!(!socket.accepts(cx, &REMOTE_IPV6_REPR, &icmp_repr.into())); + assert!(!socket.accepts_v6(cx, &REMOTE_IPV6_REPR, &icmp_repr)); } #[rstest] @@ -1207,30 +1205,25 @@ mod test_ipv6 { }, data, }; - let ip_repr = IpRepr::Ipv6(Ipv6Repr { + let ip_repr = Ipv6Repr { src_addr: REMOTE_IPV6, dst_addr: LOCAL_IPV6, next_header: IpProtocol::Icmpv6, payload_len: icmp_repr.buffer_len(), hop_limit: 0x40, - }); + }; assert!(!socket.can_recv()); // Ensure we can accept ICMP error response to the bound // UDP port - assert!(socket.accepts(cx, &ip_repr, &icmp_repr.into())); - socket.process(cx, &ip_repr, &icmp_repr.into()); + assert!(socket.accepts_v6(cx, &ip_repr, &icmp_repr)); + socket.process_v6(cx, &ip_repr, &icmp_repr); assert!(socket.can_recv()); let mut bytes = [0x00; 66]; let mut packet = Icmpv6Packet::new_unchecked(&mut bytes[..]); - icmp_repr.emit( - &LOCAL_IPV6.into(), - &REMOTE_IPV6.into(), - &mut packet, - &checksum, - ); + icmp_repr.emit(&LOCAL_IPV6, &REMOTE_IPV6, &mut packet, &checksum); assert_eq!( socket.recv(), Ok((&*packet.into_inner(), REMOTE_IPV6.into())) diff --git a/src/wire/icmpv6.rs b/src/wire/icmpv6.rs index 3d68b2a11..2a9e79d45 100644 --- a/src/wire/icmpv6.rs +++ b/src/wire/icmpv6.rs @@ -9,7 +9,7 @@ use crate::wire::MldRepr; use crate::wire::NdiscRepr; #[cfg(feature = "proto-rpl")] use crate::wire::RplRepr; -use crate::wire::{IpAddress, IpProtocol, Ipv6Packet, Ipv6Repr}; +use crate::wire::{IpProtocol, Ipv6Address, Ipv6Packet, Ipv6Repr}; use crate::wire::{IPV6_HEADER_LEN, IPV6_MIN_MTU}; /// Error packets must not exceed min MTU @@ -421,14 +421,14 @@ impl> Packet { /// /// # Fuzzing /// This function always returns `true` when fuzzing. - pub fn verify_checksum(&self, src_addr: &IpAddress, dst_addr: &IpAddress) -> bool { + pub fn verify_checksum(&self, src_addr: &Ipv6Address, dst_addr: &Ipv6Address) -> bool { if cfg!(fuzzing) { return true; } let data = self.buffer.as_ref(); checksum::combine(&[ - checksum::pseudo_header(src_addr, dst_addr, IpProtocol::Icmpv6, data.len() as u32), + checksum::pseudo_header_v6(src_addr, dst_addr, IpProtocol::Icmpv6, data.len() as u32), checksum::data(data), ]) == !0 } @@ -535,12 +535,17 @@ impl + AsMut<[u8]>> Packet { } /// Compute and fill in the header checksum. - pub fn fill_checksum(&mut self, src_addr: &IpAddress, dst_addr: &IpAddress) { + pub fn fill_checksum(&mut self, src_addr: &Ipv6Address, dst_addr: &Ipv6Address) { self.set_checksum(0); let checksum = { let data = self.buffer.as_ref(); !checksum::combine(&[ - checksum::pseudo_header(src_addr, dst_addr, IpProtocol::Icmpv6, data.len() as u32), + checksum::pseudo_header_v6( + src_addr, + dst_addr, + IpProtocol::Icmpv6, + data.len() as u32, + ), checksum::data(data), ]) }; @@ -609,8 +614,8 @@ impl<'a> Repr<'a> { /// Parse an Internet Control Message Protocol version 6 packet and return /// a high-level representation. pub fn parse( - src_addr: &IpAddress, - dst_addr: &IpAddress, + src_addr: &Ipv6Address, + dst_addr: &Ipv6Address, packet: &Packet<&'a T>, checksum_caps: &ChecksumCapabilities, ) -> Result> @@ -725,8 +730,8 @@ impl<'a> Repr<'a> { /// packet. pub fn emit( &self, - src_addr: &IpAddress, - dst_addr: &IpAddress, + src_addr: &Ipv6Address, + dst_addr: &Ipv6Address, packet: &mut Packet<&mut T>, checksum_caps: &ChecksumCapabilities, ) where @@ -840,9 +845,13 @@ impl<'a> Repr<'a> { #[cfg(test)] mod test { use super::*; - use crate::wire::ip::test::{MOCK_IP_ADDR_1, MOCK_IP_ADDR_2}; use crate::wire::{IpProtocol, Ipv6Address, Ipv6Repr}; + const MOCK_IP_ADDR_1: Ipv6Address = + Ipv6Address([0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]); + const MOCK_IP_ADDR_2: Ipv6Address = + Ipv6Address([0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2]); + static ECHO_PACKET_BYTES: [u8; 12] = [ 0x80, 0x00, 0x19, 0xb3, 0x12, 0x34, 0xab, 0xcd, 0xaa, 0x00, 0x00, 0xff, ]; diff --git a/src/wire/ip.rs b/src/wire/ip.rs index da80aba3f..2609bebc0 100644 --- a/src/wire/ip.rs +++ b/src/wire/ip.rs @@ -753,7 +753,42 @@ pub mod checksum { propagate_carries(accum) } - /// Compute an IP pseudo header checksum. + #[cfg(feature = "proto-ipv4")] + pub fn pseudo_header_v4( + src_addr: &Ipv4Address, + dst_addr: &Ipv4Address, + next_header: Protocol, + length: u32, + ) -> u16 { + let mut proto_len = [0u8; 4]; + proto_len[1] = next_header.into(); + NetworkEndian::write_u16(&mut proto_len[2..4], length as u16); + + combine(&[ + data(src_addr.as_bytes()), + data(dst_addr.as_bytes()), + data(&proto_len[..]), + ]) + } + + #[cfg(feature = "proto-ipv6")] + pub fn pseudo_header_v6( + src_addr: &Ipv6Address, + dst_addr: &Ipv6Address, + next_header: Protocol, + length: u32, + ) -> u16 { + let mut proto_len = [0u8; 4]; + proto_len[1] = next_header.into(); + NetworkEndian::write_u16(&mut proto_len[2..4], length as u16); + + combine(&[ + data(src_addr.as_bytes()), + data(dst_addr.as_bytes()), + data(&proto_len[..]), + ]) + } + pub fn pseudo_header( src_addr: &Address, dst_addr: &Address, @@ -762,32 +797,15 @@ pub mod checksum { ) -> u16 { match (src_addr, dst_addr) { #[cfg(feature = "proto-ipv4")] - (&Address::Ipv4(src_addr), &Address::Ipv4(dst_addr)) => { - let mut proto_len = [0u8; 4]; - proto_len[1] = next_header.into(); - NetworkEndian::write_u16(&mut proto_len[2..4], length as u16); - - combine(&[ - data(src_addr.as_bytes()), - data(dst_addr.as_bytes()), - data(&proto_len[..]), - ]) + (Address::Ipv4(src_addr), Address::Ipv4(dst_addr)) => { + pseudo_header_v4(src_addr, dst_addr, next_header, length) } - #[cfg(feature = "proto-ipv6")] - (&Address::Ipv6(src_addr), &Address::Ipv6(dst_addr)) => { - let mut proto_len = [0u8; 8]; - proto_len[7] = next_header.into(); - NetworkEndian::write_u32(&mut proto_len[0..4], length); - combine(&[ - data(src_addr.as_bytes()), - data(dst_addr.as_bytes()), - data(&proto_len[..]), - ]) + (Address::Ipv6(src_addr), Address::Ipv6(dst_addr)) => { + pseudo_header_v6(src_addr, dst_addr, next_header, length) } - #[allow(unreachable_patterns)] - _ => panic!("Unexpected pseudo header addresses: {src_addr}, {dst_addr}"), + _ => unreachable!(), } } @@ -882,36 +900,6 @@ pub fn pretty_print_ip_payload>( pub(crate) mod test { #![allow(unused)] - #[cfg(feature = "proto-ipv6")] - pub(crate) const MOCK_IP_ADDR_1: IpAddress = IpAddress::Ipv6(Ipv6Address([ - 0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, - ])); - #[cfg(feature = "proto-ipv6")] - pub(crate) const MOCK_IP_ADDR_2: IpAddress = IpAddress::Ipv6(Ipv6Address([ - 0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, - ])); - #[cfg(feature = "proto-ipv6")] - pub(crate) const MOCK_IP_ADDR_3: IpAddress = IpAddress::Ipv6(Ipv6Address([ - 0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, - ])); - #[cfg(feature = "proto-ipv6")] - pub(crate) const MOCK_IP_ADDR_4: IpAddress = IpAddress::Ipv6(Ipv6Address([ - 0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, - ])); - #[cfg(feature = "proto-ipv6")] - pub(crate) const MOCK_UNSPECIFIED: IpAddress = IpAddress::Ipv6(Ipv6Address::UNSPECIFIED); - - #[cfg(all(feature = "proto-ipv4", not(feature = "proto-ipv6")))] - pub(crate) const MOCK_IP_ADDR_1: IpAddress = IpAddress::Ipv4(Ipv4Address([192, 168, 1, 1])); - #[cfg(all(feature = "proto-ipv4", not(feature = "proto-ipv6")))] - pub(crate) const MOCK_IP_ADDR_2: IpAddress = IpAddress::Ipv4(Ipv4Address([192, 168, 1, 2])); - #[cfg(all(feature = "proto-ipv4", not(feature = "proto-ipv6")))] - pub(crate) const MOCK_IP_ADDR_3: IpAddress = IpAddress::Ipv4(Ipv4Address([192, 168, 1, 3])); - #[cfg(all(feature = "proto-ipv4", not(feature = "proto-ipv6")))] - pub(crate) const MOCK_IP_ADDR_4: IpAddress = IpAddress::Ipv4(Ipv4Address([192, 168, 1, 4])); - #[cfg(all(feature = "proto-ipv4", not(feature = "proto-ipv6")))] - pub(crate) const MOCK_UNSPECIFIED: IpAddress = IpAddress::Ipv4(Ipv4Address::UNSPECIFIED); - use super::*; use crate::wire::{IpAddress, IpCidr, IpProtocol}; #[cfg(feature = "proto-ipv4")] diff --git a/src/wire/ipv4.rs b/src/wire/ipv4.rs index 2efd2b1eb..4a1190334 100644 --- a/src/wire/ipv4.rs +++ b/src/wire/ipv4.rs @@ -796,9 +796,20 @@ impl> PrettyPrint for Packet { } #[cfg(test)] -mod test { +pub(crate) mod test { use super::*; + #[allow(unused)] + pub(crate) const MOCK_IP_ADDR_1: Address = Address([192, 168, 1, 1]); + #[allow(unused)] + pub(crate) const MOCK_IP_ADDR_2: Address = Address([192, 168, 1, 2]); + #[allow(unused)] + pub(crate) const MOCK_IP_ADDR_3: Address = Address([192, 168, 1, 3]); + #[allow(unused)] + pub(crate) const MOCK_IP_ADDR_4: Address = Address([192, 168, 1, 4]); + #[allow(unused)] + pub(crate) const MOCK_UNSPECIFIED: Address = Address::UNSPECIFIED; + static PACKET_BYTES: [u8; 30] = [ 0x45, 0x00, 0x00, 0x1e, 0x01, 0x02, 0x62, 0x03, 0x1a, 0x01, 0xd5, 0x6e, 0x11, 0x12, 0x13, 0x14, 0x21, 0x22, 0x23, 0x24, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, diff --git a/src/wire/ipv6.rs b/src/wire/ipv6.rs index 236600d3a..f69645945 100644 --- a/src/wire/ipv6.rs +++ b/src/wire/ipv6.rs @@ -897,7 +897,7 @@ impl> PrettyPrint for Packet { } #[cfg(test)] -mod test { +pub(crate) mod test { use super::Error; use super::{Address, Cidr}; use super::{Packet, Protocol, Repr}; @@ -906,6 +906,21 @@ mod test { #[cfg(feature = "proto-ipv4")] use crate::wire::ipv4::Address as Ipv4Address; + #[allow(unused)] + pub(crate) const MOCK_IP_ADDR_1: Address = + Address([0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]); + #[allow(unused)] + pub(crate) const MOCK_IP_ADDR_2: Address = + Address([0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2]); + #[allow(unused)] + pub(crate) const MOCK_IP_ADDR_3: Address = + Address([0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3]); + #[allow(unused)] + pub(crate) const MOCK_IP_ADDR_4: Address = + Address([0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4]); + #[allow(unused)] + pub(crate) const MOCK_UNSPECIFIED: Address = Address::UNSPECIFIED; + const LINK_LOCAL_ADDR: Address = Address::new(0xfe80, 0, 0, 0, 0, 0, 0, 1); const UNIQUE_LOCAL_ADDR: Address = Address::new(0xfd00, 0, 0, 201, 1, 1, 1, 1); const GLOBAL_UNICAST_ADDR: Address = Address::new(0x2001, 0xdb8, 0x3, 0, 0, 0, 0, 1); diff --git a/src/wire/mld.rs b/src/wire/mld.rs index c33415151..6f447bd07 100644 --- a/src/wire/mld.rs +++ b/src/wire/mld.rs @@ -476,8 +476,8 @@ mod test { .copy_from_slice(Ipv6Address::LINK_LOCAL_ALL_ROUTERS.as_bytes()); packet.clear_reserved(); packet.fill_checksum( - &Ipv6Address::LINK_LOCAL_ALL_NODES.into(), - &Ipv6Address::LINK_LOCAL_ALL_ROUTERS.into(), + &Ipv6Address::LINK_LOCAL_ALL_NODES, + &Ipv6Address::LINK_LOCAL_ALL_ROUTERS, ); assert_eq!(&*packet.into_inner(), &QUERY_PACKET_BYTES[..]); } @@ -519,8 +519,8 @@ mod test { .copy_from_slice(Ipv6Address::LINK_LOCAL_ALL_ROUTERS.as_bytes()); } packet.fill_checksum( - &Ipv6Address::LINK_LOCAL_ALL_NODES.into(), - &Ipv6Address::LINK_LOCAL_ALL_ROUTERS.into(), + &Ipv6Address::LINK_LOCAL_ALL_NODES, + &Ipv6Address::LINK_LOCAL_ALL_ROUTERS, ); assert_eq!(&*packet.into_inner(), &REPORT_PACKET_BYTES[..]); } @@ -529,8 +529,8 @@ mod test { fn test_query_repr_parse() { let packet = Packet::new_unchecked(&QUERY_PACKET_BYTES[..]); let repr = Icmpv6Repr::parse( - &Ipv6Address::LINK_LOCAL_ALL_NODES.into(), - &Ipv6Address::LINK_LOCAL_ALL_ROUTERS.into(), + &Ipv6Address::LINK_LOCAL_ALL_NODES, + &Ipv6Address::LINK_LOCAL_ALL_ROUTERS, &packet, &ChecksumCapabilities::default(), ); @@ -541,8 +541,8 @@ mod test { fn test_report_repr_parse() { let packet = Packet::new_unchecked(&REPORT_PACKET_BYTES[..]); let repr = Icmpv6Repr::parse( - &Ipv6Address::LINK_LOCAL_ALL_NODES.into(), - &Ipv6Address::LINK_LOCAL_ALL_ROUTERS.into(), + &Ipv6Address::LINK_LOCAL_ALL_NODES, + &Ipv6Address::LINK_LOCAL_ALL_ROUTERS, &packet, &ChecksumCapabilities::default(), ); @@ -555,8 +555,8 @@ mod test { let mut packet = Packet::new_unchecked(&mut bytes[..]); let repr = create_repr(Message::MldQuery); repr.emit( - &Ipv6Address::LINK_LOCAL_ALL_NODES.into(), - &Ipv6Address::LINK_LOCAL_ALL_ROUTERS.into(), + &Ipv6Address::LINK_LOCAL_ALL_NODES, + &Ipv6Address::LINK_LOCAL_ALL_ROUTERS, &mut packet, &ChecksumCapabilities::default(), ); @@ -569,8 +569,8 @@ mod test { let mut packet = Packet::new_unchecked(&mut bytes[..]); let repr = create_repr(Message::MldReport); repr.emit( - &Ipv6Address::LINK_LOCAL_ALL_NODES.into(), - &Ipv6Address::LINK_LOCAL_ALL_ROUTERS.into(), + &Ipv6Address::LINK_LOCAL_ALL_NODES, + &Ipv6Address::LINK_LOCAL_ALL_ROUTERS, &mut packet, &ChecksumCapabilities::default(), ); diff --git a/src/wire/mod.rs b/src/wire/mod.rs index 5aed2d405..87d715f9c 100644 --- a/src/wire/mod.rs +++ b/src/wire/mod.rs @@ -97,9 +97,9 @@ pub mod ieee802154; mod igmp; pub(crate) mod ip; #[cfg(feature = "proto-ipv4")] -mod ipv4; +pub(crate) mod ipv4; #[cfg(feature = "proto-ipv6")] -mod ipv6; +pub(crate) mod ipv6; #[cfg(feature = "proto-ipv6")] mod ipv6ext_header; #[cfg(feature = "proto-ipv6")] diff --git a/src/wire/ndisc.rs b/src/wire/ndisc.rs index 99663159e..cbb59c658 100644 --- a/src/wire/ndisc.rs +++ b/src/wire/ndisc.rs @@ -459,10 +459,14 @@ impl<'a> Repr<'a> { mod test { use super::*; use crate::phy::ChecksumCapabilities; - use crate::wire::ip::test::{MOCK_IP_ADDR_1, MOCK_IP_ADDR_2}; use crate::wire::EthernetAddress; use crate::wire::Icmpv6Repr; + const MOCK_IP_ADDR_1: Ipv6Address = + Ipv6Address([0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]); + const MOCK_IP_ADDR_2: Ipv6Address = + Ipv6Address([0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2]); + static ROUTER_ADVERT_BYTES: [u8; 24] = [ 0x86, 0x00, 0xa9, 0xde, 0x40, 0x80, 0x03, 0x84, 0x00, 0x00, 0x03, 0x84, 0x00, 0x00, 0x03, 0x84, 0x01, 0x01, 0x52, 0x54, 0x00, 0x12, 0x34, 0x56, diff --git a/src/wire/rpl.rs b/src/wire/rpl.rs index a67c85e11..a8b6fb582 100644 --- a/src/wire/rpl.rs +++ b/src/wire/rpl.rs @@ -2414,8 +2414,8 @@ mod tests { SixlowpanNextHeader::Uncompressed(IpProtocol::Icmpv6) => { let icmp_packet = Icmpv6Packet::new_checked(packet.payload()).unwrap(); match Icmpv6Repr::parse( - &IpAddress::Ipv6(repr.src_addr), - &IpAddress::Ipv6(repr.dst_addr), + &repr.src_addr, + &repr.dst_addr, &icmp_packet, &ChecksumCapabilities::ignored(), ) { diff --git a/src/wire/sixlowpan/nhc.rs b/src/wire/sixlowpan/nhc.rs index 5539ce4eb..85e422a49 100644 --- a/src/wire/sixlowpan/nhc.rs +++ b/src/wire/sixlowpan/nhc.rs @@ -4,12 +4,7 @@ use super::{Error, NextHeader, Result, DISPATCH_EXT_HEADER, DISPATCH_UDP_HEADER}; use crate::{ phy::ChecksumCapabilities, - wire::{ - ip::{checksum, Address as IpAddress}, - ipv6, - udp::Repr as UdpRepr, - IpProtocol, - }, + wire::{ip::checksum, ipv6, udp::Repr as UdpRepr, IpProtocol}, }; use byteorder::{ByteOrder, NetworkEndian}; use ipv6::Address; @@ -708,9 +703,9 @@ impl<'a> UdpNhcRepr { if checksum_caps.udp.rx() { let payload_len = packet.payload().len(); let chk_sum = !checksum::combine(&[ - checksum::pseudo_header( - &IpAddress::Ipv6(*src_addr), - &IpAddress::Ipv6(*dst_addr), + checksum::pseudo_header_v6( + src_addr, + dst_addr, crate::wire::ip::Protocol::Udp, payload_len as u32 + 8, ), @@ -763,9 +758,9 @@ impl<'a> UdpNhcRepr { if checksum_caps.udp.tx() { let chk_sum = !checksum::combine(&[ - checksum::pseudo_header( - &IpAddress::Ipv6(*src_addr), - &IpAddress::Ipv6(*dst_addr), + checksum::pseudo_header_v6( + src_addr, + dst_addr, crate::wire::ip::Protocol::Udp, payload_len as u32 + 8, ),