diff --git a/benches/bench.rs b/benches/bench.rs index 7114cabfd..a05ccff91 100644 --- a/benches/bench.rs +++ b/benches/bench.rs @@ -13,13 +13,9 @@ mod wire { extern crate test; #[cfg(feature = "proto-ipv6")] - const SRC_ADDR: IpAddress = IpAddress::Ipv6(Ipv6Address([ - 0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, - ])); + const SRC_ADDR: IpAddress = IpAddress::Ipv6(Ipv6Address::new(0xfe80, 0, 0, 0, 0, 0, 0, 1)); #[cfg(feature = "proto-ipv6")] - const DST_ADDR: IpAddress = IpAddress::Ipv6(Ipv6Address([ - 0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, - ])); + const DST_ADDR: IpAddress = IpAddress::Ipv6(Ipv6Address::new(0xfe80, 0, 0, 0, 0, 0, 0, 2)); #[cfg(all(not(feature = "proto-ipv6"), feature = "proto-ipv4"))] const SRC_ADDR: IpAddress = IpAddress::Ipv4(Ipv4Address::new(192, 168, 1, 1)); @@ -102,8 +98,8 @@ mod wire { #[cfg(feature = "proto-ipv6")] fn bench_emit_ipv6(b: &mut test::Bencher) { let repr = Ipv6Repr { - src_addr: Ipv6Address([0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]), - dst_addr: Ipv6Address([0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2]), + src_addr: Ipv6Address::new(0xfe80, 0, 0, 0, 0, 0, 0, 1), + dst_addr: Ipv6Address::new(0xfe80, 0, 0, 0, 0, 0, 0, 2), next_header: IpProtocol::Tcp, payload_len: 100, hop_limit: 64, diff --git a/examples/multicast6.rs b/examples/multicast6.rs index 46e4e7bd7..e9a2712b2 100644 --- a/examples/multicast6.rs +++ b/examples/multicast6.rs @@ -19,9 +19,9 @@ use smoltcp::wire::{EthernetAddress, IpAddress, IpCidr, Ipv6Address}; // will send packets to the multicast group we join below on tap0. const PORT: u16 = 8123; -const GROUP: [u16; 8] = [0xff02, 0, 0, 0, 0, 0, 0, 0x1234]; -const LOCAL_ADDR: [u16; 8] = [0xfe80, 0, 0, 0, 0, 0, 0, 0x101]; -const ROUTER_ADDR: [u16; 8] = [0xfe80, 0, 0, 0, 0, 0, 0, 0x100]; +const GROUP: Ipv6Address = Ipv6Address::new(0xff02, 0, 0, 0, 0, 0, 0, 0x1234); +const LOCAL_ADDR: Ipv6Address = Ipv6Address::new(0xfe80, 0, 0, 0, 0, 0, 0, 0x101); +const ROUTER_ADDR: Ipv6Address = Ipv6Address::new(0xfe80, 0, 0, 0, 0, 0, 0, 0x100); fn main() { utils::setup_logging("warn"); @@ -37,7 +37,6 @@ fn main() { utils::parse_middleware_options(&mut matches, device, /*loopback=*/ false); // Create interface - let local_addr = Ipv6Address::from_parts(&LOCAL_ADDR); let ethernet_addr = EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x02]); let mut config = match device.capabilities().medium { Medium::Ethernet => Config::new(ethernet_addr.into()), @@ -49,12 +48,12 @@ fn main() { let mut iface = Interface::new(config, &mut device, Instant::now()); iface.update_ip_addrs(|ip_addrs| { ip_addrs - .push(IpCidr::new(IpAddress::from(local_addr), 64)) + .push(IpCidr::new(IpAddress::from(LOCAL_ADDR), 64)) .unwrap(); }); iface .routes_mut() - .add_default_ipv6_route(Ipv6Address::from_parts(&ROUTER_ADDR)) + .add_default_ipv6_route(ROUTER_ADDR) .unwrap(); // Create sockets @@ -65,9 +64,7 @@ fn main() { let udp_handle = sockets.add(udp_socket); // Join a multicast group - iface - .join_multicast_group(Ipv6Address::from_parts(&GROUP)) - .unwrap(); + iface.join_multicast_group(GROUP).unwrap(); loop { let timestamp = Instant::now(); diff --git a/src/iface/interface/ipv6.rs b/src/iface/interface/ipv6.rs index a8d29e48c..90feea360 100644 --- a/src/iface/interface/ipv6.rs +++ b/src/iface/interface/ipv6.rs @@ -58,7 +58,7 @@ impl InterfaceInner { fn common_prefix_length(dst_addr: &Ipv6Cidr, src_addr: &Ipv6Address) -> usize { let addr = dst_addr.address(); let mut bits = 0; - for (l, r) in addr.as_bytes().iter().zip(src_addr.as_bytes().iter()) { + for (l, r) in addr.octets().iter().zip(src_addr.octets().iter()) { if l == r { bits += 8; } else { @@ -82,7 +82,7 @@ impl InterfaceInner { .count() == 0 { - return Ipv6Address::LOOPBACK; + return Ipv6Address::LOCALHOST; } let mut candidate = self @@ -147,10 +147,10 @@ impl InterfaceInner { pub fn has_solicited_node(&self, addr: Ipv6Address) -> bool { self.ip_addrs.iter().any(|cidr| { match *cidr { - IpCidr::Ipv6(cidr) if cidr.address() != Ipv6Address::LOOPBACK => { + IpCidr::Ipv6(cidr) if cidr.address() != Ipv6Address::LOCALHOST => { // Take the lower order 24 bits of the IPv6 address and // append those bits to FF02:0:0:0:0:1:FF00::/104. - addr.as_bytes()[14..] == cidr.address().as_bytes()[14..] + addr.octets()[14..] == cidr.address().octets()[14..] } _ => false, } @@ -523,7 +523,7 @@ impl InterfaceInner { // Per [RFC 3810 § 5.2.14], all MLDv2 reports are sent to ff02::16. // [RFC 3810 § 5.2.14]: https://tools.ietf.org/html/rfc3810#section-5.2.14 - let dst_addr = Ipv6Address::LINK_LOCAL_ALL_MLDV2_ROUTERS; + let dst_addr = IPV6_LINK_LOCAL_ALL_MLDV2_ROUTERS; // Create a dummy IPv6 extension header so we can calculate the total length of the packet. // The actual extension header will be created later by Packet::emit_payload(). diff --git a/src/iface/interface/mod.rs b/src/iface/interface/mod.rs index 0e704de2a..cfac7f205 100644 --- a/src/iface/interface/mod.rs +++ b/src/iface/interface/mod.rs @@ -832,10 +832,10 @@ impl InterfaceInner { #[cfg(feature = "proto-ipv4")] IpAddress::Ipv4(key) => key == IPV4_MULTICAST_ALL_SYSTEMS, #[cfg(feature = "proto-rpl")] - IpAddress::Ipv6(Ipv6Address::LINK_LOCAL_ALL_RPL_NODES) => true, + IpAddress::Ipv6(IPV6_LINK_LOCAL_ALL_RPL_NODES) => true, #[cfg(feature = "proto-ipv6")] IpAddress::Ipv6(key) => { - key == Ipv6Address::LINK_LOCAL_ALL_NODES || self.has_solicited_node(key) + key == IPV6_LINK_LOCAL_ALL_NODES || self.has_solicited_node(key) } #[allow(unreachable_patterns)] _ => false, @@ -1011,7 +1011,7 @@ impl InterfaceInner { IpAddress::Ipv6(addr) => match self.caps.medium { #[cfg(feature = "medium-ethernet")] Medium::Ethernet => { - let b = addr.as_bytes(); + let b = addr.octets(); HardwareAddress::Ethernet(EthernetAddress::from_bytes(&[ 0x33, 0x33, b[12], b[13], b[14], b[15], ])) diff --git a/src/iface/interface/tests/ipv6.rs b/src/iface/interface/tests/ipv6.rs index 620712c9c..adc058fd3 100644 --- a/src/iface/interface/tests/ipv6.rs +++ b/src/iface/interface/tests/ipv6.rs @@ -49,8 +49,8 @@ fn any_ip(#[case] medium: Medium) { parse_ipv6(&data), Ok(Packet::new_ipv6( Ipv6Repr { - src_addr: Ipv6Address::from_parts(&[0xfdbe, 0, 0, 0, 0, 0, 0, 0x0002]), - dst_addr: Ipv6Address::from_parts(&[0xfdbe, 0, 0, 0, 0, 0, 0, 0x0003]), + src_addr: Ipv6Address::new(0xfdbe, 0, 0, 0, 0, 0, 0, 0x0002), + dst_addr: Ipv6Address::new(0xfdbe, 0, 0, 0, 0, 0, 0, 0x0003), hop_limit: 64, next_header: IpProtocol::Icmpv6, payload_len: 8, @@ -73,9 +73,7 @@ fn any_ip(#[case] medium: Medium) { Ipv6Address::new(0xfdbe, 0, 0, 0, 0, 0, 0, 0), 64, )), - via_router: IpAddress::Ipv6(Ipv6Address::from_parts(&[ - 0xfdbe, 0, 0, 0, 0, 0, 0, 0x0001, - ])), + via_router: IpAddress::Ipv6(Ipv6Address::new(0xfdbe, 0, 0, 0, 0, 0, 0, 0x0001)), preferred_until: None, expires_at: None, }) @@ -157,8 +155,8 @@ fn hop_by_hop_skip_with_icmp(#[case] medium: Medium) { let response = Some(Packet::new_ipv6( Ipv6Repr { - src_addr: Ipv6Address::from_parts(&[0xfdbe, 0, 0, 0, 0, 0, 0, 0x0001]), - dst_addr: Ipv6Address::from_parts(&[0xfdbe, 0, 0, 0, 0, 0, 0, 0x0002]), + src_addr: Ipv6Address::new(0xfdbe, 0, 0, 0, 0, 0, 0, 0x0001), + dst_addr: Ipv6Address::new(0xfdbe, 0, 0, 0, 0, 0, 0, 0x0002), hop_limit: 64, next_header: IpProtocol::Icmpv6, payload_len: 19, @@ -350,8 +348,8 @@ fn imcp_empty_echo_request(#[case] medium: Medium) { parse_ipv6(&data), Ok(Packet::new_ipv6( Ipv6Repr { - src_addr: Ipv6Address::from_parts(&[0xfdbe, 0, 0, 0, 0, 0, 0, 0x0002]), - dst_addr: Ipv6Address::from_parts(&[0xfdbe, 0, 0, 0, 0, 0, 0, 0x0001]), + src_addr: Ipv6Address::new(0xfdbe, 0, 0, 0, 0, 0, 0, 0x0002), + dst_addr: Ipv6Address::new(0xfdbe, 0, 0, 0, 0, 0, 0, 0x0001), hop_limit: 64, next_header: IpProtocol::Icmpv6, payload_len: 8, @@ -366,8 +364,8 @@ fn imcp_empty_echo_request(#[case] medium: Medium) { let response = Some(Packet::new_ipv6( Ipv6Repr { - src_addr: Ipv6Address::from_parts(&[0xfdbe, 0, 0, 0, 0, 0, 0, 0x0001]), - dst_addr: Ipv6Address::from_parts(&[0xfdbe, 0, 0, 0, 0, 0, 0, 0x0002]), + src_addr: Ipv6Address::new(0xfdbe, 0, 0, 0, 0, 0, 0, 0x0001), + dst_addr: Ipv6Address::new(0xfdbe, 0, 0, 0, 0, 0, 0, 0x0002), hop_limit: 64, next_header: IpProtocol::Icmpv6, payload_len: 8, @@ -411,8 +409,8 @@ fn icmp_echo_request(#[case] medium: Medium) { parse_ipv6(&data), Ok(Packet::new_ipv6( Ipv6Repr { - src_addr: Ipv6Address::from_parts(&[0xfdbe, 0, 0, 0, 0, 0, 0, 0x0002]), - dst_addr: Ipv6Address::from_parts(&[0xfdbe, 0, 0, 0, 0, 0, 0, 0x0001]), + src_addr: Ipv6Address::new(0xfdbe, 0, 0, 0, 0, 0, 0, 0x0002), + dst_addr: Ipv6Address::new(0xfdbe, 0, 0, 0, 0, 0, 0, 0x0001), hop_limit: 64, next_header: IpProtocol::Icmpv6, payload_len: 19, @@ -427,8 +425,8 @@ fn icmp_echo_request(#[case] medium: Medium) { let response = Some(Packet::new_ipv6( Ipv6Repr { - src_addr: Ipv6Address::from_parts(&[0xfdbe, 0, 0, 0, 0, 0, 0, 0x0001]), - dst_addr: Ipv6Address::from_parts(&[0xfdbe, 0, 0, 0, 0, 0, 0, 0x0002]), + src_addr: Ipv6Address::new(0xfdbe, 0, 0, 0, 0, 0, 0, 0x0001), + dst_addr: Ipv6Address::new(0xfdbe, 0, 0, 0, 0, 0, 0, 0x0002), hop_limit: 64, next_header: IpProtocol::Icmpv6, payload_len: 19, @@ -472,8 +470,8 @@ fn icmp_echo_reply_as_input(#[case] medium: Medium) { parse_ipv6(&data), Ok(Packet::new_ipv6( Ipv6Repr { - src_addr: Ipv6Address::from_parts(&[0xfdbe, 0, 0, 0, 0, 0, 0, 0x0002]), - dst_addr: Ipv6Address::from_parts(&[0xfdbe, 0, 0, 0, 0, 0, 0, 0x0001]), + src_addr: Ipv6Address::new(0xfdbe, 0, 0, 0, 0, 0, 0, 0x0002), + dst_addr: Ipv6Address::new(0xfdbe, 0, 0, 0, 0, 0, 0, 0x0001), hop_limit: 64, next_header: IpProtocol::Icmpv6, payload_len: 19, @@ -517,8 +515,8 @@ fn unknown_proto_with_multicast_dst_address(#[case] medium: Medium) { let response = Some(Packet::new_ipv6( Ipv6Repr { - src_addr: Ipv6Address::from_parts(&[0xfdbe, 0, 0, 0, 0, 0, 0, 0x0001]), - dst_addr: Ipv6Address::from_parts(&[0xfdbe, 0, 0, 0, 0, 0, 0, 0x0002]), + src_addr: Ipv6Address::new(0xfdbe, 0, 0, 0, 0, 0, 0, 0x0001), + dst_addr: Ipv6Address::new(0xfdbe, 0, 0, 0, 0, 0, 0, 0x0002), hop_limit: 64, next_header: IpProtocol::Icmpv6, payload_len: 48, @@ -527,8 +525,8 @@ fn unknown_proto_with_multicast_dst_address(#[case] medium: Medium) { reason: Icmpv6ParamProblem::UnrecognizedNxtHdr, pointer: 40, header: Ipv6Repr { - src_addr: Ipv6Address::from_parts(&[0xfdbe, 0, 0, 0, 0, 0, 0, 0x0002]), - dst_addr: Ipv6Address::from_parts(&[0xff02, 0, 0, 0, 0, 0, 0, 0x0001]), + src_addr: Ipv6Address::new(0xfdbe, 0, 0, 0, 0, 0, 0, 0x0002), + dst_addr: Ipv6Address::new(0xff02, 0, 0, 0, 0, 0, 0, 0x0001), hop_limit: 64, next_header: IpProtocol::Unknown(0x0c), payload_len: 0, @@ -567,8 +565,8 @@ fn unknown_proto(#[case] medium: Medium) { let response = Some(Packet::new_ipv6( Ipv6Repr { - src_addr: Ipv6Address::from_parts(&[0xfdbe, 0, 0, 0, 0, 0, 0, 0x0001]), - dst_addr: Ipv6Address::from_parts(&[0xfdbe, 0, 0, 0, 0, 0, 0, 0x0002]), + src_addr: Ipv6Address::new(0xfdbe, 0, 0, 0, 0, 0, 0, 0x0001), + dst_addr: Ipv6Address::new(0xfdbe, 0, 0, 0, 0, 0, 0, 0x0002), hop_limit: 64, next_header: IpProtocol::Icmpv6, payload_len: 48, @@ -577,8 +575,8 @@ fn unknown_proto(#[case] medium: Medium) { reason: Icmpv6ParamProblem::UnrecognizedNxtHdr, pointer: 40, header: Ipv6Repr { - src_addr: Ipv6Address::from_parts(&[0xfdbe, 0, 0, 0, 0, 0, 0, 0x0002]), - dst_addr: Ipv6Address::from_parts(&[0xfdbe, 0, 0, 0, 0, 0, 0, 0x0001]), + src_addr: Ipv6Address::new(0xfdbe, 0, 0, 0, 0, 0, 0, 0x0002), + dst_addr: Ipv6Address::new(0xfdbe, 0, 0, 0, 0, 0, 0, 0x0001), hop_limit: 64, next_header: IpProtocol::Unknown(0x0c), payload_len: 0, @@ -616,15 +614,15 @@ fn ndsic_neighbor_advertisement_ethernet(#[case] medium: Medium) { parse_ipv6(&data), Ok(Packet::new_ipv6( Ipv6Repr { - src_addr: Ipv6Address::from_parts(&[0xfdbe, 0, 0, 0, 0, 0, 0, 0x0002]), - dst_addr: Ipv6Address::from_parts(&[0xfdbe, 0, 0, 0, 0, 0, 0, 0x0001]), + src_addr: Ipv6Address::new(0xfdbe, 0, 0, 0, 0, 0, 0, 0x0002), + dst_addr: Ipv6Address::new(0xfdbe, 0, 0, 0, 0, 0, 0, 0x0001), hop_limit: 255, next_header: IpProtocol::Icmpv6, payload_len: 32, }, IpPayload::Icmpv6(Icmpv6Repr::Ndisc(NdiscRepr::NeighborAdvert { flags: NdiscNeighborFlags::SOLICITED, - target_addr: Ipv6Address::from_parts(&[0xfe80, 0, 0, 0, 0, 0, 0, 0x0002]), + target_addr: Ipv6Address::new(0xfe80, 0, 0, 0, 0, 0, 0, 0x0002), lladdr: Some(RawHardwareAddress::from_bytes(&[0, 0, 0, 0, 0, 1])), })) )) @@ -646,7 +644,7 @@ fn ndsic_neighbor_advertisement_ethernet(#[case] medium: Medium) { assert_eq!( iface.inner.neighbor_cache.lookup( - &IpAddress::Ipv6(Ipv6Address::from_parts(&[0xfdbe, 0, 0, 0, 0, 0, 0, 0x0002])), + &IpAddress::Ipv6(Ipv6Address::new(0xfdbe, 0, 0, 0, 0, 0, 0, 0x0002)), iface.inner.now, ), NeighborAnswer::Found(HardwareAddress::Ethernet(EthernetAddress::from_bytes(&[ @@ -671,15 +669,15 @@ fn ndsic_neighbor_advertisement_ethernet_multicast_addr(#[case] medium: Medium) parse_ipv6(&data), Ok(Packet::new_ipv6( Ipv6Repr { - src_addr: Ipv6Address::from_parts(&[0xfdbe, 0, 0, 0, 0, 0, 0, 0x0002]), - dst_addr: Ipv6Address::from_parts(&[0xfdbe, 0, 0, 0, 0, 0, 0, 0x0001]), + src_addr: Ipv6Address::new(0xfdbe, 0, 0, 0, 0, 0, 0, 0x0002), + dst_addr: Ipv6Address::new(0xfdbe, 0, 0, 0, 0, 0, 0, 0x0001), hop_limit: 255, next_header: IpProtocol::Icmpv6, payload_len: 32, }, IpPayload::Icmpv6(Icmpv6Repr::Ndisc(NdiscRepr::NeighborAdvert { flags: NdiscNeighborFlags::SOLICITED, - target_addr: Ipv6Address::from_parts(&[0xfe80, 0, 0, 0, 0, 0, 0, 0x0002]), + target_addr: Ipv6Address::new(0xfe80, 0, 0, 0, 0, 0, 0, 0x0002), lladdr: Some(RawHardwareAddress::from_bytes(&[ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff ])), @@ -703,7 +701,7 @@ fn ndsic_neighbor_advertisement_ethernet_multicast_addr(#[case] medium: Medium) assert_eq!( iface.inner.neighbor_cache.lookup( - &IpAddress::Ipv6(Ipv6Address::from_parts(&[0xfdbe, 0, 0, 0, 0, 0, 0, 0x0002])), + &IpAddress::Ipv6(Ipv6Address::new(0xfdbe, 0, 0, 0, 0, 0, 0, 0x0002)), iface.inner.now, ), NeighborAnswer::NotFound, @@ -726,15 +724,15 @@ fn ndsic_neighbor_advertisement_ieee802154(#[case] medium: Medium) { parse_ipv6(&data), Ok(Packet::new_ipv6( Ipv6Repr { - src_addr: Ipv6Address::from_parts(&[0xfdbe, 0, 0, 0, 0, 0, 0, 0x0002]), - dst_addr: Ipv6Address::from_parts(&[0xfdbe, 0, 0, 0, 0, 0, 0, 0x0001]), + src_addr: Ipv6Address::new(0xfdbe, 0, 0, 0, 0, 0, 0, 0x0002), + dst_addr: Ipv6Address::new(0xfdbe, 0, 0, 0, 0, 0, 0, 0x0001), hop_limit: 255, next_header: IpProtocol::Icmpv6, payload_len: 40, }, IpPayload::Icmpv6(Icmpv6Repr::Ndisc(NdiscRepr::NeighborAdvert { flags: NdiscNeighborFlags::SOLICITED, - target_addr: Ipv6Address::from_parts(&[0xfe80, 0, 0, 0, 0, 0, 0, 0x0002]), + target_addr: Ipv6Address::new(0xfe80, 0, 0, 0, 0, 0, 0, 0x0002), lladdr: Some(RawHardwareAddress::from_bytes(&[0, 0, 0, 0, 0, 0, 0, 1])), })) )) @@ -756,7 +754,7 @@ fn ndsic_neighbor_advertisement_ieee802154(#[case] medium: Medium) { assert_eq!( iface.inner.neighbor_cache.lookup( - &IpAddress::Ipv6(Ipv6Address::from_parts(&[0xfdbe, 0, 0, 0, 0, 0, 0, 0x0002])), + &IpAddress::Ipv6(Ipv6Address::new(0xfdbe, 0, 0, 0, 0, 0, 0, 0x0002)), iface.inner.now, ), NeighborAnswer::Found(HardwareAddress::Ieee802154(Ieee802154Address::from_bytes( @@ -1004,8 +1002,8 @@ fn get_source_address() { Ipv6Address::new(0x2001, 0x0db9, 0x0003, 0, 0, 0, 0, 2); assert_eq!( - iface.inner.get_source_address_ipv6(&Ipv6Address::LOOPBACK), - Ipv6Address::LOOPBACK + iface.inner.get_source_address_ipv6(&Ipv6Address::LOCALHOST), + Ipv6Address::LOCALHOST ); assert_eq!( @@ -1027,7 +1025,7 @@ fn get_source_address() { assert_eq!( iface .inner - .get_source_address_ipv6(&Ipv6Address::LINK_LOCAL_ALL_NODES), + .get_source_address_ipv6(&IPV6_LINK_LOCAL_ALL_NODES), OWN_LINK_LOCAL_ADDR ); assert_eq!( @@ -1056,7 +1054,7 @@ fn get_source_address() { OWN_UNIQUE_LOCAL_ADDR1 ); assert_eq!( - iface.get_source_address_ipv6(&Ipv6Address::LINK_LOCAL_ALL_NODES), + iface.get_source_address_ipv6(&IPV6_LINK_LOCAL_ALL_NODES), OWN_LINK_LOCAL_ADDR ); assert_eq!( @@ -1102,8 +1100,8 @@ fn get_source_address_only_link_local() { Ipv6Address::new(0x2001, 0x0db9, 0x0003, 0, 0, 0, 0, 2); assert_eq!( - iface.inner.get_source_address_ipv6(&Ipv6Address::LOOPBACK), - Ipv6Address::LOOPBACK + iface.inner.get_source_address_ipv6(&Ipv6Address::LOCALHOST), + Ipv6Address::LOCALHOST ); assert_eq!( @@ -1125,7 +1123,7 @@ fn get_source_address_only_link_local() { assert_eq!( iface .inner - .get_source_address_ipv6(&Ipv6Address::LINK_LOCAL_ALL_NODES), + .get_source_address_ipv6(&IPV6_LINK_LOCAL_ALL_NODES), OWN_LINK_LOCAL_ADDR ); assert_eq!( @@ -1154,7 +1152,7 @@ fn get_source_address_only_link_local() { OWN_LINK_LOCAL_ADDR ); assert_eq!( - iface.get_source_address_ipv6(&Ipv6Address::LINK_LOCAL_ALL_NODES), + iface.get_source_address_ipv6(&IPV6_LINK_LOCAL_ALL_NODES), OWN_LINK_LOCAL_ADDR ); assert_eq!( @@ -1193,68 +1191,68 @@ fn get_source_address_empty_interface() { Ipv6Address::new(0x2001, 0x0db9, 0x0003, 0, 0, 0, 0, 2); assert_eq!( - iface.inner.get_source_address_ipv6(&Ipv6Address::LOOPBACK), - Ipv6Address::LOOPBACK + iface.inner.get_source_address_ipv6(&Ipv6Address::LOCALHOST), + Ipv6Address::LOCALHOST ); assert_eq!( iface.inner.get_source_address_ipv6(&LINK_LOCAL_ADDR), - Ipv6Address::LOOPBACK + Ipv6Address::LOCALHOST ); assert_eq!( iface.inner.get_source_address_ipv6(&UNIQUE_LOCAL_ADDR1), - Ipv6Address::LOOPBACK + Ipv6Address::LOCALHOST ); assert_eq!( iface.inner.get_source_address_ipv6(&UNIQUE_LOCAL_ADDR2), - Ipv6Address::LOOPBACK + Ipv6Address::LOCALHOST ); assert_eq!( iface.inner.get_source_address_ipv6(&UNIQUE_LOCAL_ADDR3), - Ipv6Address::LOOPBACK + Ipv6Address::LOCALHOST ); assert_eq!( iface .inner - .get_source_address_ipv6(&Ipv6Address::LINK_LOCAL_ALL_NODES), - Ipv6Address::LOOPBACK + .get_source_address_ipv6(&IPV6_LINK_LOCAL_ALL_NODES), + Ipv6Address::LOCALHOST ); assert_eq!( iface.inner.get_source_address_ipv6(&GLOBAL_UNICAST_ADDR1), - Ipv6Address::LOOPBACK + Ipv6Address::LOCALHOST ); assert_eq!( iface.inner.get_source_address_ipv6(&GLOBAL_UNICAST_ADDR2), - Ipv6Address::LOOPBACK + Ipv6Address::LOCALHOST ); assert_eq!( iface.get_source_address_ipv6(&LINK_LOCAL_ADDR), - Ipv6Address::LOOPBACK + Ipv6Address::LOCALHOST ); assert_eq!( iface.get_source_address_ipv6(&UNIQUE_LOCAL_ADDR1), - Ipv6Address::LOOPBACK + Ipv6Address::LOCALHOST ); assert_eq!( iface.get_source_address_ipv6(&UNIQUE_LOCAL_ADDR2), - Ipv6Address::LOOPBACK + Ipv6Address::LOCALHOST ); assert_eq!( iface.get_source_address_ipv6(&UNIQUE_LOCAL_ADDR3), - Ipv6Address::LOOPBACK + Ipv6Address::LOCALHOST ); assert_eq!( - iface.get_source_address_ipv6(&Ipv6Address::LINK_LOCAL_ALL_NODES), - Ipv6Address::LOOPBACK + iface.get_source_address_ipv6(&IPV6_LINK_LOCAL_ALL_NODES), + Ipv6Address::LOCALHOST ); assert_eq!( iface.get_source_address_ipv6(&GLOBAL_UNICAST_ADDR1), - Ipv6Address::LOOPBACK + Ipv6Address::LOCALHOST ); assert_eq!( iface.get_source_address_ipv6(&GLOBAL_UNICAST_ADDR2), - Ipv6Address::LOOPBACK + Ipv6Address::LOCALHOST ); } @@ -1292,8 +1290,8 @@ fn test_join_ipv6_multicast_group(#[case] medium: Medium) { let (mut iface, mut sockets, mut device) = setup(medium); let groups = [ - Ipv6Address::from_parts(&[0xff05, 0, 0, 0, 0, 0, 0, 0x00fb]), - Ipv6Address::from_parts(&[0xff0e, 0, 0, 0, 0, 0, 0, 0x0017]), + Ipv6Address::new(0xff05, 0, 0, 0, 0, 0, 0, 0x00fb), + Ipv6Address::new(0xff0e, 0, 0, 0, 0, 0, 0, 0x0017), ]; let timestamp = Instant::from_millis(0); @@ -1302,9 +1300,9 @@ fn test_join_ipv6_multicast_group(#[case] medium: Medium) { iface.join_multicast_group(group).unwrap(); assert!(iface.has_multicast_group(group)); } - assert!(iface.has_multicast_group(Ipv6Address::LINK_LOCAL_ALL_NODES)); + assert!(iface.has_multicast_group(IPV6_LINK_LOCAL_ALL_NODES)); iface.poll(timestamp, &mut device, &mut sockets); - assert!(iface.has_multicast_group(Ipv6Address::LINK_LOCAL_ALL_NODES)); + assert!(iface.has_multicast_group(IPV6_LINK_LOCAL_ALL_NODES)); let reports = recv_icmpv6(&mut device, timestamp); assert_eq!(reports.len(), 2); diff --git a/src/iface/interface/tests/mod.rs b/src/iface/interface/tests/mod.rs index fe98ddd3d..1d70f88c2 100644 --- a/src/iface/interface/tests/mod.rs +++ b/src/iface/interface/tests/mod.rs @@ -98,7 +98,7 @@ fn test_handle_udp_broadcast(#[case] medium: Medium) { #[cfg(feature = "proto-ipv6")] let ip_repr = IpRepr::Ipv6(Ipv6Repr { src_addr: src_ip, - dst_addr: Ipv6Address::LINK_LOCAL_ALL_NODES, + dst_addr: IPV6_LINK_LOCAL_ALL_NODES, next_header: IpProtocol::Udp, payload_len: udp_repr.header_len() + UDP_PAYLOAD.len(), hop_limit: 0x40, diff --git a/src/iface/interface/tests/sixlowpan.rs b/src/iface/interface/tests/sixlowpan.rs index 14a4c46ae..56e1fb8ca 100644 --- a/src/iface/interface/tests/sixlowpan.rs +++ b/src/iface/interface/tests/sixlowpan.rs @@ -40,8 +40,8 @@ fn icmp_echo_request(#[case] medium: Medium) { let response = Some(Packet::new_ipv6( Ipv6Repr { - src_addr: Ipv6Address::from_parts(&[0xfe80, 0, 0, 0, 0x180b, 0x4242, 0x4242, 0x4242]), - dst_addr: Ipv6Address::from_parts(&[0xfe80, 0, 0, 0, 0x241c, 0x2957, 0x34a6, 0x3a62]), + src_addr: Ipv6Address::new(0xfe80, 0, 0, 0, 0x180b, 0x4242, 0x4242, 0x4242), + dst_addr: Ipv6Address::new(0xfe80, 0, 0, 0, 0x241c, 0x2957, 0x34a6, 0x3a62), hop_limit: 64, next_header: IpProtocol::Icmpv6, payload_len: 64, @@ -61,7 +61,7 @@ fn icmp_echo_request(#[case] medium: Medium) { let (mut iface, mut sockets, _device) = setup(medium); iface.update_ip_addrs(|ips| { ips.push(IpCidr::Ipv6(Ipv6Cidr::new( - Ipv6Address::from_parts(&[0xfe80, 0, 0, 0, 0x180b, 0x4242, 0x4242, 0x4242]), + Ipv6Address::new(0xfe80, 0, 0, 0, 0x180b, 0x4242, 0x4242, 0x4242), 10, ))) .unwrap(); @@ -99,7 +99,7 @@ fn test_echo_request_sixlowpan_128_bytes() { let now = iface.inner.now(); iface.inner.neighbor_cache.fill( - Ipv6Address([0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0x2, 0, 0, 0, 0, 0, 0, 0]).into(), + Ipv6Address::new(0xfe80, 0, 0, 0, 0x0200, 0, 0, 0).into(), HardwareAddress::Ieee802154(Ieee802154Address::default()), now, ); @@ -148,17 +148,11 @@ fn test_echo_request_sixlowpan_128_bytes() { assert_eq!( request_first_part_iphc_repr.src_addr, - Ipv6Address([ - 0xfe, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, 0x42, 0x42, 0x42, 0x42, 0x42, 0xb, - 0x1a, - ]), + Ipv6Address::new(0xfe80, 0, 0, 0, 0x4042, 0x4242, 0x4242, 0x0b1a), ); assert_eq!( request_first_part_iphc_repr.dst_addr, - Ipv6Address([ - 0xfe, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x92, 0xfc, 0x48, 0xc2, 0xa4, 0x41, 0xfc, - 0x76, - ]), + Ipv6Address::new(0xfe80, 0, 0, 0, 0x92fc, 0x48c2, 0xa441, 0xfc76), ); let request_second_part = [ @@ -206,14 +200,8 @@ fn test_echo_request_sixlowpan_128_bytes() { result, Some(Packet::new_ipv6( Ipv6Repr { - src_addr: Ipv6Address([ - 0xfe, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x92, 0xfc, 0x48, 0xc2, 0xa4, 0x41, - 0xfc, 0x76, - ]), - dst_addr: Ipv6Address([ - 0xfe, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, 0x42, 0x42, 0x42, 0x42, 0x42, - 0xb, 0x1a, - ]), + src_addr: Ipv6Address::new(0xfe80, 0, 0, 0, 0x92fc, 0x48c2, 0xa441, 0xfc76), + dst_addr: Ipv6Address::new(0xfe80, 0, 0, 0, 0x4042, 0x4242, 0x4242, 0x0b1a), next_header: IpProtocol::Icmpv6, payload_len: 136, hop_limit: 64, @@ -227,9 +215,9 @@ fn test_echo_request_sixlowpan_128_bytes() { ); iface.inner.neighbor_cache.fill( - IpAddress::Ipv6(Ipv6Address([ - 0xfe, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, 0x42, 0x42, 0x42, 0x42, 0x42, 0xb, 0x1a, - ])), + IpAddress::Ipv6(Ipv6Address::new( + 0xfe80, 0, 0, 0, 0x4042, 0x4242, 0x4242, 0x0b1a, + )), HardwareAddress::Ieee802154(Ieee802154Address::default()), Instant::now(), ); @@ -370,17 +358,12 @@ In at rhoncus tortor. Cras blandit tellus diam, varius vestibulum nibh commodo n &udp_data[..], udp::UdpMetadata { local_address: Some( - Ipv6Address([ - 0xfe, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x92, 0xfc, 0x48, 0xc2, 0xa4, - 0x41, 0xfc, 0x76, - ]) - .into() + Ipv6Address::new(0xfe80, 0, 0, 0, 0x92fc, 0x48c2, 0xa441, 0xfc76).into() ), ..IpEndpoint { - addr: IpAddress::Ipv6(Ipv6Address([ - 0xfe, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, 0x42, 0x42, 0x42, 0x42, - 0x42, 0xb, 0x1a, - ])), + addr: IpAddress::Ipv6(Ipv6Address::new( + 0xfe80, 0, 0, 0, 0x4042, 0x4242, 0x4242, 0x0b1a + )), port: 54217, } .into() @@ -395,8 +378,8 @@ In at rhoncus tortor. Cras blandit tellus diam, varius vestibulum nibh commodo n PacketMeta::default(), Packet::new_ipv6( Ipv6Repr { - src_addr: Ipv6Address::default(), - dst_addr: Ipv6Address::default(), + src_addr: Ipv6Address::UNSPECIFIED, + dst_addr: Ipv6Address::UNSPECIFIED, next_header: IpProtocol::Udp, payload_len: udp_data.len(), hop_limit: 64, diff --git a/src/iface/route.rs b/src/iface/route.rs index 628b5ffa0..f14a57d39 100644 --- a/src/iface/route.rs +++ b/src/iface/route.rs @@ -172,28 +172,17 @@ mod test { #[cfg(feature = "proto-ipv6")] mod mock { use super::super::*; - pub const ADDR_1A: Ipv6Address = - Ipv6Address([0xfe, 0x80, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1]); - pub const ADDR_1B: Ipv6Address = - Ipv6Address([0xfe, 0x80, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 13]); - pub const ADDR_1C: Ipv6Address = - Ipv6Address([0xfe, 0x80, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 42]); + pub const ADDR_1A: Ipv6Address = Ipv6Address::new(0xfe80, 0, 0, 2, 0, 0, 0, 1); + pub const ADDR_1B: Ipv6Address = Ipv6Address::new(0xfe80, 0, 0, 2, 0, 0, 0, 13); + pub const ADDR_1C: Ipv6Address = Ipv6Address::new(0xfe80, 0, 0, 2, 0, 0, 0, 42); pub fn cidr_1() -> Ipv6Cidr { - Ipv6Cidr::new( - Ipv6Address([0xfe, 0x80, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0]), - 64, - ) + Ipv6Cidr::new(Ipv6Address::new(0xfe80, 0, 0, 2, 0, 0, 0, 0), 64) } - pub const ADDR_2A: Ipv6Address = - Ipv6Address([0xfe, 0x80, 0, 0, 0, 0, 51, 100, 0, 0, 0, 0, 0, 0, 0, 1]); - pub const ADDR_2B: Ipv6Address = - Ipv6Address([0xfe, 0x80, 0, 0, 0, 0, 51, 100, 0, 0, 0, 0, 0, 0, 0, 21]); + pub const ADDR_2A: Ipv6Address = Ipv6Address::new(0xfe80, 0, 0, 0x3364, 0, 0, 0, 1); + pub const ADDR_2B: Ipv6Address = Ipv6Address::new(0xfe80, 0, 0, 0x3364, 0, 0, 0, 21); pub fn cidr_2() -> Ipv6Cidr { - Ipv6Cidr::new( - Ipv6Address([0xfe, 0x80, 0, 0, 0, 0, 51, 100, 0, 0, 0, 0, 0, 0, 0, 0]), - 64, - ) + Ipv6Cidr::new(Ipv6Address::new(0xfe80, 0, 0, 0x3364, 0, 0, 0, 0), 64) } } diff --git a/src/iface/rpl/of0.rs b/src/iface/rpl/of0.rs index 99e4d1f36..fd4a4c4f3 100644 --- a/src/iface/rpl/of0.rs +++ b/src/iface/rpl/of0.rs @@ -99,11 +99,11 @@ mod tests { let mut parents = ParentSet::default(); parents.add( - Ipv6Address::default(), - Parent::new(0, Rank::ROOT, Default::default(), Ipv6Address::default()), + Ipv6Address::UNSPECIFIED, + Parent::new(0, Rank::ROOT, Default::default(), Ipv6Address::UNSPECIFIED), ); - let mut address = Ipv6Address::default(); + let mut address = Ipv6Address::UNSPECIFIED; address.0[15] = 1; parents.add( @@ -112,7 +112,7 @@ mod tests { 0, Rank::new(1024, DEFAULT_MIN_HOP_RANK_INCREASE), Default::default(), - Ipv6Address::default(), + Ipv6Address::UNSPECIFIED, ), ); @@ -122,7 +122,7 @@ mod tests { 0, Rank::ROOT, Default::default(), - Ipv6Address::default(), + Ipv6Address::UNSPECIFIED, )) ); } diff --git a/src/iface/rpl/parents.rs b/src/iface/rpl/parents.rs index 70d5a5e88..690917a11 100644 --- a/src/iface/rpl/parents.rs +++ b/src/iface/rpl/parents.rs @@ -110,7 +110,7 @@ mod tests { let mut last_address = Default::default(); for i in 0..RPL_PARENTS_BUFFER_COUNT { let i = i as u16; - let mut address = Ipv6Address::default(); + let mut address = Ipv6Address::UNSPECIFIED; address.0[15] = i as u8; last_address = address; @@ -137,7 +137,7 @@ mod tests { // This one is not added to the set, because its Rank is worse than any other parent in the // set. - let mut address = Ipv6Address::default(); + let mut address = Ipv6Address::UNSPECIFIED; address.0[15] = 8; set.add( address, @@ -151,7 +151,7 @@ mod tests { assert_eq!(set.find(&address), None); /// This Parent has a better rank than the last one in the set. - let mut address = Ipv6Address::default(); + let mut address = Ipv6Address::UNSPECIFIED; address.0[15] = 9; set.add( address, diff --git a/src/iface/rpl/relations.rs b/src/iface/rpl/relations.rs index da02a3cf9..6d003ddf6 100644 --- a/src/iface/rpl/relations.rs +++ b/src/iface/rpl/relations.rs @@ -74,7 +74,7 @@ mod tests { fn addresses(count: usize) -> Vec { (0..count) .map(|i| { - let mut ip = Ipv6Address::default(); + let mut ip = Ipv6Address::UNSPECIFIED; ip.0[0] = i as u8; ip }) diff --git a/src/parsers.rs b/src/parsers.rs index 4e690b02f..99ce28453 100644 --- a/src/parsers.rs +++ b/src/parsers.rs @@ -277,7 +277,7 @@ impl<'a> Parser<'a> { // end of the address. addr[8 - tail_idx..].copy_from_slice(&tail[..tail_idx]); - Ok(Ipv6Address::from_parts(&addr)) + Ok(Ipv6Address::from(addr)) } fn accept_ipv4_octets(&mut self) -> Result<[u8; 4]> { @@ -383,16 +383,6 @@ impl FromStr for EthernetAddress { } } -#[cfg(feature = "proto-ipv6")] -impl FromStr for Ipv6Address { - type Err = (); - - /// Parse a string representation of an IPv6 address. - fn from_str(s: &str) -> Result { - Parser::new(s).until_eof(|p| p.accept_ipv6()) - } -} - impl FromStr for IpAddress { type Err = (); @@ -516,84 +506,6 @@ mod test { assert_eq!(EthernetAddress::from_str("02:00:00:00:00:0x"), Err(())); } - #[test] - #[cfg(feature = "proto-ipv6")] - fn test_ipv6() { - // Obviously not valid - assert_eq!(Ipv6Address::from_str(""), Err(())); - assert_eq!( - Ipv6Address::from_str("fe80:0:0:0:0:0:0:1"), - Ok(Ipv6Address::new(0xfe80, 0, 0, 0, 0, 0, 0, 1)) - ); - assert_eq!(Ipv6Address::from_str("::1"), Ok(Ipv6Address::LOOPBACK)); - assert_eq!(Ipv6Address::from_str("::"), Ok(Ipv6Address::UNSPECIFIED)); - assert_eq!( - Ipv6Address::from_str("fe80::1"), - Ok(Ipv6Address::new(0xfe80, 0, 0, 0, 0, 0, 0, 1)) - ); - assert_eq!( - Ipv6Address::from_str("1234:5678::"), - Ok(Ipv6Address::new(0x1234, 0x5678, 0, 0, 0, 0, 0, 0)) - ); - assert_eq!( - Ipv6Address::from_str("1234:5678::8765:4321"), - Ok(Ipv6Address::new(0x1234, 0x5678, 0, 0, 0, 0, 0x8765, 0x4321)) - ); - // Two double colons in address - assert_eq!(Ipv6Address::from_str("1234:5678::1::1"), Err(())); - assert_eq!( - Ipv6Address::from_str("4444:333:22:1::4"), - Ok(Ipv6Address::new(0x4444, 0x0333, 0x0022, 0x0001, 0, 0, 0, 4)) - ); - assert_eq!( - Ipv6Address::from_str("1:1:1:1:1:1::"), - Ok(Ipv6Address::new(1, 1, 1, 1, 1, 1, 0, 0)) - ); - assert_eq!( - Ipv6Address::from_str("::1:1:1:1:1:1"), - Ok(Ipv6Address::new(0, 0, 1, 1, 1, 1, 1, 1)) - ); - assert_eq!(Ipv6Address::from_str("::1:1:1:1:1:1:1"), Err(())); - // Double colon appears too late indicating an address that is too long - assert_eq!(Ipv6Address::from_str("1:1:1:1:1:1:1::"), Err(())); - // Section after double colon is too long for a valid address - assert_eq!(Ipv6Address::from_str("::1:1:1:1:1:1:1"), Err(())); - // Obviously too long - assert_eq!(Ipv6Address::from_str("1:1:1:1:1:1:1:1:1"), Err(())); - // Address is too short - assert_eq!(Ipv6Address::from_str("1:1:1:1:1:1:1"), Err(())); - // Long number - assert_eq!(Ipv6Address::from_str("::000001"), Err(())); - // IPv4-Mapped address - assert_eq!( - Ipv6Address::from_str("::ffff:192.168.1.1"), - Ok(Ipv6Address([ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 192, 168, 1, 1 - ])) - ); - assert_eq!( - Ipv6Address::from_str("0:0:0:0:0:ffff:192.168.1.1"), - Ok(Ipv6Address([ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 192, 168, 1, 1 - ])) - ); - assert_eq!( - Ipv6Address::from_str("0::ffff:192.168.1.1"), - Ok(Ipv6Address([ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 192, 168, 1, 1 - ])) - ); - // Only ffff is allowed in position 6 when IPv4 mapped - assert_eq!(Ipv6Address::from_str("0:0:0:0:0:eeee:192.168.1.1"), Err(())); - // Positions 1-5 must be 0 when IPv4 mapped - assert_eq!(Ipv6Address::from_str("0:0:0:0:1:ffff:192.168.1.1"), Err(())); - assert_eq!(Ipv6Address::from_str("1::ffff:192.168.1.1"), Err(())); - // Out of range ipv4 octet - assert_eq!(Ipv6Address::from_str("0:0:0:0:0:ffff:256.168.1.1"), Err(())); - // Invalid hex in ipv4 octet - assert_eq!(Ipv6Address::from_str("0:0:0:0:0:ffff:c0.168.1.1"), Err(())); - } - #[test] #[cfg(feature = "proto-ipv4")] fn test_ip_ipv4() { @@ -668,7 +580,7 @@ mod test { 64u8, )), ), - ("::1/128", Ok(Ipv6Cidr::new(Ipv6Address::LOOPBACK, 128u8))), + ("::1/128", Ok(Ipv6Cidr::new(Ipv6Address::LOCALHOST, 128u8))), ("::/128", Ok(Ipv6Cidr::new(Ipv6Address::UNSPECIFIED, 128u8))), ( "fe80:0:0:0:0:0:0:1/64", diff --git a/src/socket/dns.rs b/src/socket/dns.rs index 9d09d8f0c..681cf10f2 100644 --- a/src/socket/dns.rs +++ b/src/socket/dns.rs @@ -22,9 +22,9 @@ const RETRANSMIT_TIMEOUT: Duration = Duration::from_millis(10_000); // Should ge #[cfg(feature = "proto-ipv6")] #[allow(unused)] -const MDNS_IPV6_ADDR: IpAddress = IpAddress::Ipv6(crate::wire::Ipv6Address([ - 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb, -])); +const MDNS_IPV6_ADDR: IpAddress = IpAddress::Ipv6(crate::wire::Ipv6Address::new( + 0xff02, 0, 0, 0, 0, 0, 0, 0xfb, +)); #[cfg(feature = "proto-ipv4")] #[allow(unused)] diff --git a/src/socket/icmp.rs b/src/socket/icmp.rs index c5080a152..2a9258e49 100644 --- a/src/socket/icmp.rs +++ b/src/socket/icmp.rs @@ -940,10 +940,8 @@ mod test_ipv6 { use crate::wire::{Icmpv6DstUnreachable, IpEndpoint, Ipv6Address}; - const REMOTE_IPV6: Ipv6Address = - Ipv6Address([0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2]); - const LOCAL_IPV6: Ipv6Address = - Ipv6Address([0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]); + const REMOTE_IPV6: Ipv6Address = Ipv6Address::new(0xfe80, 0, 0, 0, 0, 0, 0, 2); + const LOCAL_IPV6: Ipv6Address = Ipv6Address::new(0xfe80, 0, 0, 0, 0, 0, 0, 1); const LOCAL_END_V6: IpEndpoint = IpEndpoint { addr: IpAddress::Ipv6(LOCAL_IPV6), port: LOCAL_PORT, @@ -974,7 +972,7 @@ mod test_ipv6 { fn test_send_unaddressable() { let mut socket = socket(buffer(0), buffer(1)); assert_eq!( - socket.send_slice(b"abcdef", IpAddress::Ipv6(Ipv6Address::default())), + socket.send_slice(b"abcdef", IpAddress::Ipv6(Ipv6Address::UNSPECIFIED)), Err(SendError::Unaddressable) ); assert_eq!(socket.send_slice(b"abcdef", REMOTE_IPV6.into()), Ok(())); diff --git a/src/socket/raw.rs b/src/socket/raw.rs index b86063865..7df7830e3 100644 --- a/src/socket/raw.rs +++ b/src/socket/raw.rs @@ -525,14 +525,8 @@ mod test { pub const IP_PROTO: u8 = 63; pub const HEADER_REPR: IpRepr = IpRepr::Ipv6(Ipv6Repr { - src_addr: Ipv6Address([ - 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x01, - ]), - dst_addr: Ipv6Address([ - 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x02, - ]), + src_addr: Ipv6Address::new(0xfe80, 0, 0, 0, 0, 0, 0, 1), + dst_addr: Ipv6Address::new(0xfe80, 0, 0, 0, 0, 0, 0, 2), next_header: IpProtocol::Unknown(IP_PROTO), payload_len: 4, hop_limit: 64, diff --git a/src/wire/dns.rs b/src/wire/dns.rs index e5734d82a..68f504f58 100644 --- a/src/wire/dns.rs +++ b/src/wire/dns.rs @@ -6,10 +6,10 @@ use core::iter; use core::iter::Iterator; use super::{Error, Result}; -#[cfg(feature = "proto-ipv6")] -use crate::wire::Ipv6Address; #[cfg(feature = "proto-ipv4")] use crate::wire::{Ipv4Address, Ipv4AddressExt}; +#[cfg(feature = "proto-ipv6")] +use crate::wire::{Ipv6Address, Ipv6AddressExt}; enum_with_unknown! { /// DNS OpCodes diff --git a/src/wire/icmpv6.rs b/src/wire/icmpv6.rs index 2a9e79d45..724421dea 100644 --- a/src/wire/icmpv6.rs +++ b/src/wire/icmpv6.rs @@ -847,10 +847,8 @@ mod test { use super::*; 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]); + const MOCK_IP_ADDR_1: Ipv6Address = Ipv6Address::new(0xfe80, 0, 0, 0, 0, 0, 0, 1); + const MOCK_IP_ADDR_2: Ipv6Address = Ipv6Address::new(0xfe80, 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, @@ -888,14 +886,8 @@ mod test { Repr::PktTooBig { mtu: 1500, header: Ipv6Repr { - src_addr: Ipv6Address([ - 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x01, - ]), - dst_addr: Ipv6Address([ - 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x02, - ]), + src_addr: Ipv6Address::new(0xfe80, 0, 0, 0, 0, 0, 0, 1), + dst_addr: Ipv6Address::new(0xfe80, 0, 0, 0, 0, 0, 0, 2), next_header: IpProtocol::Udp, payload_len: 12, hop_limit: 0x40, @@ -1017,8 +1009,8 @@ mod test { let repr = Repr::PktTooBig { mtu: 1280, header: Ipv6Repr { - src_addr: Default::default(), - dst_addr: Default::default(), + src_addr: Ipv6Address::UNSPECIFIED, + dst_addr: Ipv6Address::UNSPECIFIED, next_header: IpProtocol::Tcp, hop_limit: 64, payload_len: 1280, @@ -1031,8 +1023,8 @@ mod test { #[test] fn test_mtu_truncated_payload_roundtrip() { let ip_packet_repr = Ipv6Repr { - src_addr: Default::default(), - dst_addr: Default::default(), + src_addr: Ipv6Address::UNSPECIFIED, + dst_addr: Ipv6Address::UNSPECIFIED, next_header: IpProtocol::Tcp, hop_limit: 64, payload_len: IPV6_MIN_MTU - IPV6_HEADER_LEN, diff --git a/src/wire/ieee802154.rs b/src/wire/ieee802154.rs index 33fafb60e..43d656b0f 100644 --- a/src/wire/ieee802154.rs +++ b/src/wire/ieee802154.rs @@ -3,7 +3,7 @@ use core::fmt; use byteorder::{ByteOrder, LittleEndian}; use super::{Error, Result}; -use crate::wire::ipv6::Address as Ipv6Address; +use crate::wire::{Ipv6Address, Ipv6AddressExt}; enum_with_unknown! { /// IEEE 802.15.4 frame type. diff --git a/src/wire/ip.rs b/src/wire/ip.rs index 86dea66dd..a332bc12e 100644 --- a/src/wire/ip.rs +++ b/src/wire/ip.rs @@ -6,7 +6,7 @@ use crate::phy::ChecksumCapabilities; #[cfg(feature = "proto-ipv4")] use crate::wire::{Ipv4Address, Ipv4AddressExt, Ipv4Cidr, Ipv4Packet, Ipv4Repr}; #[cfg(feature = "proto-ipv6")] -use crate::wire::{Ipv6Address, Ipv6Cidr, Ipv6Packet, Ipv6Repr}; +use crate::wire::{Ipv6Address, Ipv6AddressExt, Ipv6Cidr, Ipv6Packet, Ipv6Repr}; /// Internet protocol version. #[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)] @@ -193,24 +193,17 @@ impl From
for ::core::net::IpAddr { fn from(x: Address) -> ::core::net::IpAddr { match x { #[cfg(feature = "proto-ipv4")] - Address::Ipv4(ipv4) => ::core::net::IpAddr::V4(ipv4.into()), + Address::Ipv4(ipv4) => ::core::net::IpAddr::V4(ipv4), #[cfg(feature = "proto-ipv6")] - Address::Ipv6(ipv6) => ::core::net::IpAddr::V6(ipv6.into()), + Address::Ipv6(ipv6) => ::core::net::IpAddr::V6(ipv6), } } } #[cfg(feature = "proto-ipv4")] -impl From<::core::net::Ipv4Addr> for Address { - fn from(ipv4: ::core::net::Ipv4Addr) -> Address { - Address::Ipv4(ipv4.into()) - } -} - -#[cfg(feature = "proto-ipv6")] -impl From<::core::net::Ipv6Addr> for Address { - fn from(ipv6: ::core::net::Ipv6Addr) -> Address { - Address::Ipv6(ipv6.into()) +impl From for Address { + fn from(ipv4: Ipv4Address) -> Address { + Address::Ipv4(ipv4) } } @@ -759,8 +752,8 @@ pub mod checksum { NetworkEndian::write_u16(&mut proto_len[2..4], length as u16); combine(&[ - data(src_addr.as_bytes()), - data(dst_addr.as_bytes()), + data(&src_addr.octets()), + data(&dst_addr.octets()), data(&proto_len[..]), ]) } diff --git a/src/wire/ipv6.rs b/src/wire/ipv6.rs index 1eba39077..d47d8faeb 100644 --- a/src/wire/ipv6.rs +++ b/src/wire/ipv6.rs @@ -5,8 +5,6 @@ use core::fmt; use super::{Error, Result}; use crate::wire::ip::pretty_print_ip_payload; -#[cfg(feature = "proto-ipv4")] -use crate::wire::{Ipv4Address, Ipv4AddressExt}; pub use super::IpProtocol as Protocol; @@ -20,10 +18,25 @@ pub const MIN_MTU: usize = 1280; /// [RFC 8200 § 2]: https://www.rfc-editor.org/rfc/rfc4291#section-2 pub const ADDR_SIZE: usize = 16; -/// Size of IPv4-mapping prefix in octets. +/// The link-local [all nodes multicast address]. /// -/// [RFC 8200 § 2]: https://www.rfc-editor.org/rfc/rfc4291#section-2 -pub const IPV4_MAPPED_PREFIX_SIZE: usize = ADDR_SIZE - 4; // 4 == ipv4::ADDR_SIZE , cannot DRY here because of dependency on a IPv4 module which is behind the feature +/// [all nodes multicast address]: https://tools.ietf.org/html/rfc4291#section-2.7.1 +pub const LINK_LOCAL_ALL_NODES: Address = Address::new(0xff02, 0, 0, 0, 0, 0, 0, 1); + +/// The link-local [all routers multicast address]. +/// +/// [all routers multicast address]: https://tools.ietf.org/html/rfc4291#section-2.7.1 +pub const LINK_LOCAL_ALL_ROUTERS: Address = Address::new(0xff02, 0, 0, 0, 0, 0, 0, 2); + +/// The link-local [all MLVDv2-capable routers multicast address]. +/// +/// [all MLVDv2-capable routers multicast address]: https://tools.ietf.org/html/rfc3810#section-11 +pub const LINK_LOCAL_ALL_MLDV2_ROUTERS: Address = Address::new(0xff02, 0, 0, 0, 0, 0, 0, 0x16); + +/// The link-local [all RPL nodes multicast address]. +/// +/// [all RPL nodes multicast address]: https://www.rfc-editor.org/rfc/rfc6550.html#section-20.19 +pub const LINK_LOCAL_ALL_RPL_NODES: Address = Address::new(0xff02, 0, 0, 0, 0, 0, 0, 0x1a); /// The [scope] of an address. /// @@ -61,209 +74,86 @@ impl From for MulticastScope { } } -/// A sixteen-octet IPv6 address. -#[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Default)] -pub struct Address(pub [u8; ADDR_SIZE]); - -impl Address { - /// The [unspecified address]. - /// - /// [unspecified address]: https://tools.ietf.org/html/rfc4291#section-2.5.2 - pub const UNSPECIFIED: Address = Address([0x00; ADDR_SIZE]); - - /// The link-local [all nodes multicast address]. - /// - /// [all nodes multicast address]: https://tools.ietf.org/html/rfc4291#section-2.7.1 - pub const LINK_LOCAL_ALL_NODES: Address = Address([ - 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, - ]); - - /// The link-local [all routers multicast address]. - /// - /// [all routers multicast address]: https://tools.ietf.org/html/rfc4291#section-2.7.1 - pub const LINK_LOCAL_ALL_ROUTERS: Address = Address([ - 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, - ]); - - /// The link-local [all MLVDv2-capable routers multicast address]. - /// - /// [all MLVDv2-capable routers multicast address]: https://tools.ietf.org/html/rfc3810#section-11 - pub const LINK_LOCAL_ALL_MLDV2_ROUTERS: Address = Address([ - 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x16, - ]); - - /// The link-local [all RPL nodes multicast address]. - /// - /// [all RPL nodes multicast address]: https://www.rfc-editor.org/rfc/rfc6550.html#section-20.19 - pub const LINK_LOCAL_ALL_RPL_NODES: Address = Address([ - 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x1a, - ]); - - /// The [loopback address]. - /// - /// [loopback address]: https://tools.ietf.org/html/rfc4291#section-2.5.3 - pub const LOOPBACK: Address = Address([ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, - ]); - - /// The prefix used in [IPv4-mapped addresses]. - /// - /// [IPv4-mapped addresses]: https://www.rfc-editor.org/rfc/rfc4291#section-2.5.5.2 - pub const IPV4_MAPPED_PREFIX: [u8; IPV4_MAPPED_PREFIX_SIZE] = - [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff]; - - /// Construct an IPv6 address from parts. - #[allow(clippy::too_many_arguments)] - pub const fn new( - a0: u16, - a1: u16, - a2: u16, - a3: u16, - a4: u16, - a5: u16, - a6: u16, - a7: u16, - ) -> Address { - Address([ - (a0 >> 8) as u8, - a0 as u8, - (a1 >> 8) as u8, - a1 as u8, - (a2 >> 8) as u8, - a2 as u8, - (a3 >> 8) as u8, - a3 as u8, - (a4 >> 8) as u8, - a4 as u8, - (a5 >> 8) as u8, - a5 as u8, - (a6 >> 8) as u8, - a6 as u8, - (a7 >> 8) as u8, - a7 as u8, - ]) - } +pub use core::net::Ipv6Addr as Address; +pub(crate) trait AddressExt { /// Construct an IPv6 address from a sequence of octets, in big-endian. /// /// # Panics /// The function panics if `data` is not sixteen octets long. - pub fn from_bytes(data: &[u8]) -> Address { - let mut bytes = [0; ADDR_SIZE]; - bytes.copy_from_slice(data); - Address(bytes) - } - - /// Construct an IPv6 address from a sequence of words, in big-endian. - /// - /// # Panics - /// The function panics if `data` is not 8 words long. - pub fn from_parts(data: &[u16]) -> Address { - assert!(data.len() >= 8); - let mut bytes = [0; ADDR_SIZE]; - for (word_idx, chunk) in bytes.chunks_mut(2).enumerate() { - NetworkEndian::write_u16(chunk, data[word_idx]); - } - Address(bytes) - } - - /// Write a IPv6 address to the given slice. - /// - /// # Panics - /// The function panics if `data` is not 8 words long. - pub fn write_parts(&self, data: &mut [u16]) { - assert!(data.len() >= 8); - for (i, chunk) in self.0.chunks(2).enumerate() { - data[i] = NetworkEndian::read_u16(chunk); - } - } - - /// Return an IPv6 address as a sequence of octets, in big-endian. - pub const fn as_bytes(&self) -> &[u8] { - &self.0 - } + fn from_bytes(data: &[u8]) -> Address; /// Query whether the IPv6 address is an [unicast address]. /// /// [unicast address]: https://tools.ietf.org/html/rfc4291#section-2.5 - pub fn is_unicast(&self) -> bool { - !(self.is_multicast() || self.is_unspecified()) - } + fn is_unicast(&self) -> bool; /// Query whether the IPv6 address is a [global unicast address]. /// /// [global unicast address]: https://datatracker.ietf.org/doc/html/rfc3587 - pub const fn is_global_unicast(&self) -> bool { - (self.0[0] >> 5) == 0b001 - } - - /// Query whether the IPv6 address is a [multicast address]. - /// - /// [multicast address]: https://tools.ietf.org/html/rfc4291#section-2.7 - pub const fn is_multicast(&self) -> bool { - self.0[0] == 0xff - } - - /// Query whether the IPv6 address is the [unspecified address]. - /// - /// [unspecified address]: https://tools.ietf.org/html/rfc4291#section-2.5.2 - pub fn is_unspecified(&self) -> bool { - self.0 == [0x00; ADDR_SIZE] - } + fn is_global_unicast(&self) -> bool; /// Query whether the IPv6 address is in the [link-local] scope. /// /// [link-local]: https://tools.ietf.org/html/rfc4291#section-2.5.6 - pub fn is_link_local(&self) -> bool { - self.0[0..8] == [0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] - } + fn is_link_local(&self) -> bool; /// Query whether the IPv6 address is a [Unique Local Address] (ULA). /// /// [Unique Local Address]: https://tools.ietf.org/html/rfc4193 - pub fn is_unique_local(&self) -> bool { - (self.0[0] & 0b1111_1110) == 0xfc - } + fn is_unique_local(&self) -> bool; - /// Query whether the IPv6 address is the [loopback address]. + /// Helper function used to mask an address given a prefix. /// - /// [loopback address]: https://tools.ietf.org/html/rfc4291#section-2.5.3 - pub fn is_loopback(&self) -> bool { - *self == Self::LOOPBACK - } + /// # Panics + /// This function panics if `mask` is greater than 128. + fn mask(&self, mask: u8) -> [u8; ADDR_SIZE]; - /// Query whether the IPv6 address is an [IPv4 mapped IPv6 address]. + /// The solicited node for the given unicast address. /// - /// [IPv4 mapped IPv6 address]: https://tools.ietf.org/html/rfc4291#section-2.5.5.2 - pub fn is_ipv4_mapped(&self) -> bool { - self.0[..IPV4_MAPPED_PREFIX_SIZE] == Self::IPV4_MAPPED_PREFIX + /// # Panics + /// This function panics if the given address is not + /// unicast. + fn solicited_node(&self) -> Address; + + /// Return the scope of the address. + fn multicast_scope(&self) -> MulticastScope; + + /// If `self` is a CIDR-compatible subnet mask, return `Some(prefix_len)`, + /// where `prefix_len` is the number of leading zeroes. Return `None` otherwise. + fn prefix_len(&self) -> Option; +} + +impl AddressExt for Address { + fn from_bytes(data: &[u8]) -> Address { + let mut bytes = [0; ADDR_SIZE]; + bytes.copy_from_slice(data); + Address::from(bytes) } - #[cfg(feature = "proto-ipv4")] - /// Convert an IPv4 mapped IPv6 address to an IPv4 address. - pub fn as_ipv4(&self) -> Option { - if self.is_ipv4_mapped() { - Some(Ipv4Address::from_bytes(&self.0[IPV4_MAPPED_PREFIX_SIZE..])) - } else { - None - } + fn is_unicast(&self) -> bool { + !(self.is_multicast() || self.is_unspecified()) } - /// Helper function used to mask an address given a prefix. - /// - /// # Panics - /// This function panics if `mask` is greater than 128. - pub(super) fn mask(&self, mask: u8) -> [u8; ADDR_SIZE] { + fn is_global_unicast(&self) -> bool { + (self.octets()[0] >> 5) == 0b001 + } + + fn is_link_local(&self) -> bool { + self.octets()[0..8] == [0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] + } + + fn is_unique_local(&self) -> bool { + (self.octets()[0] & 0b1111_1110) == 0xfc + } + + fn mask(&self, mask: u8) -> [u8; ADDR_SIZE] { assert!(mask <= 128); let mut bytes = [0u8; ADDR_SIZE]; let idx = (mask as usize) / 8; let modulus = (mask as usize) % 8; - let (first, second) = self.0.split_at(idx); + let octets = self.octets(); + let (first, second) = octets.split_at(idx); bytes[0..idx].copy_from_slice(first); if idx < ADDR_SIZE { let part = second[0]; @@ -272,23 +162,18 @@ impl Address { bytes } - /// The solicited node for the given unicast address. - /// - /// # Panics - /// This function panics if the given address is not - /// unicast. - pub fn solicited_node(&self) -> Address { + fn solicited_node(&self) -> Address { assert!(self.is_unicast()); - Address([ - 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, - self.0[13], self.0[14], self.0[15], + let o = self.octets(); + Address::from([ + 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, o[13], + o[14], o[15], ]) } - /// Return the scope of the address. - pub(crate) fn multicast_scope(&self) -> MulticastScope { + fn multicast_scope(&self) -> MulticastScope { if self.is_multicast() { - return MulticastScope::from(self.as_bytes()[1] & 0b1111); + return MulticastScope::from(self.octets()[1] & 0b1111); } if self.is_link_local() { @@ -302,22 +187,13 @@ impl Address { } } - /// Convert to an `IpAddress`. - /// - /// Same as `.into()`, but works in `const`. - pub const fn into_address(self) -> super::IpAddress { - super::IpAddress::Ipv6(self) - } - - /// If `self` is a CIDR-compatible subnet mask, return `Some(prefix_len)`, - /// where `prefix_len` is the number of leading zeroes. Return `None` otherwise. - pub fn prefix_len(&self) -> Option { + fn prefix_len(&self) -> Option { let mut ones = true; let mut prefix_len = 0; - for byte in self.as_bytes() { + for byte in self.octets() { let mut mask = 0x80; for _ in 0..8 { - let one = *byte & mask != 0; + let one = byte & mask != 0; if ones { // Expect 1s until first 0 if one { @@ -336,154 +212,9 @@ impl Address { } } -impl From<::core::net::Ipv6Addr> for Address { - fn from(x: ::core::net::Ipv6Addr) -> Address { - Address(x.octets()) - } -} - -impl From
for ::core::net::Ipv6Addr { - fn from(Address(x): Address) -> ::core::net::Ipv6Addr { - x.into() - } -} - -impl fmt::Display for Address { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - if self.is_ipv4_mapped() { - return write!( - f, - "::ffff:{}.{}.{}.{}", - self.0[IPV4_MAPPED_PREFIX_SIZE + 0], - self.0[IPV4_MAPPED_PREFIX_SIZE + 1], - self.0[IPV4_MAPPED_PREFIX_SIZE + 2], - self.0[IPV4_MAPPED_PREFIX_SIZE + 3] - ); - } - - // The string representation of an IPv6 address should - // collapse a series of 16 bit sections that evaluate - // to 0 to "::" - // - // See https://tools.ietf.org/html/rfc4291#section-2.2 - // for details. - enum State { - Head, - HeadBody, - Tail, - TailBody, - } - let mut words = [0u16; 8]; - self.write_parts(&mut words); - let mut state = State::Head; - for word in words.iter() { - state = match (*word, &state) { - // Once a u16 equal to zero write a double colon and - // skip to the next non-zero u16. - (0, &State::Head) | (0, &State::HeadBody) => { - write!(f, "::")?; - State::Tail - } - // Continue iterating without writing any characters until - // we hit a non-zero value. - (0, &State::Tail) => State::Tail, - // When the state is Head or Tail write a u16 in hexadecimal - // without the leading colon if the value is not 0. - (_, &State::Head) => { - write!(f, "{word:x}")?; - State::HeadBody - } - (_, &State::Tail) => { - write!(f, "{word:x}")?; - State::TailBody - } - // Write the u16 with a leading colon when parsing a value - // that isn't the first in a section - (_, &State::HeadBody) | (_, &State::TailBody) => { - write!(f, ":{word:x}")?; - state - } - } - } - Ok(()) - } -} - -#[cfg(feature = "defmt")] -impl defmt::Format for Address { - fn format(&self, f: defmt::Formatter) { - if self.is_ipv4_mapped() { - return defmt::write!( - f, - "::ffff:{}.{}.{}.{}", - self.0[IPV4_MAPPED_PREFIX_SIZE + 0], - self.0[IPV4_MAPPED_PREFIX_SIZE + 1], - self.0[IPV4_MAPPED_PREFIX_SIZE + 2], - self.0[IPV4_MAPPED_PREFIX_SIZE + 3] - ); - } - - // The string representation of an IPv6 address should - // collapse a series of 16 bit sections that evaluate - // to 0 to "::" - // - // See https://tools.ietf.org/html/rfc4291#section-2.2 - // for details. - enum State { - Head, - HeadBody, - Tail, - TailBody, - } - let mut words = [0u16; 8]; - self.write_parts(&mut words); - let mut state = State::Head; - for word in words.iter() { - state = match (*word, &state) { - // Once a u16 equal to zero write a double colon and - // skip to the next non-zero u16. - (0, &State::Head) | (0, &State::HeadBody) => { - defmt::write!(f, "::"); - State::Tail - } - // Continue iterating without writing any characters until - // we hit a non-zero value. - (0, &State::Tail) => State::Tail, - // When the state is Head or Tail write a u16 in hexadecimal - // without the leading colon if the value is not 0. - (_, &State::Head) => { - defmt::write!(f, "{:x}", word); - State::HeadBody - } - (_, &State::Tail) => { - defmt::write!(f, "{:x}", word); - State::TailBody - } - // Write the u16 with a leading colon when parsing a value - // that isn't the first in a section - (_, &State::HeadBody) | (_, &State::TailBody) => { - defmt::write!(f, ":{:x}", word); - state - } - } - } - } -} - -#[cfg(feature = "proto-ipv4")] -/// Convert the given IPv4 address into a IPv4-mapped IPv6 address -impl From for Address { - fn from(address: Ipv4Address) -> Self { - let mut b = [0_u8; ADDR_SIZE]; - b[..Self::IPV4_MAPPED_PREFIX.len()].copy_from_slice(&Self::IPV4_MAPPED_PREFIX); - b[Self::IPV4_MAPPED_PREFIX.len()..].copy_from_slice(&address.octets()); - Self(b) - } -} - /// A specification of an IPv6 CIDR block, containing an address and a variable-length /// subnet masking prefix length. -#[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Default)] +#[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)] pub struct Cidr { address: Address, prefix_len: u8, @@ -494,10 +225,7 @@ impl Cidr { /// /// [solicited node prefix]: https://tools.ietf.org/html/rfc4291#section-2.7.1 pub const SOLICITED_NODE_PREFIX: Cidr = Cidr { - address: Address([ - 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x00, - 0x00, 0x00, - ]), + address: Address::new(0xff02, 0, 0, 0, 0, 1, 0xff00, 0), prefix_len: 104, }; @@ -787,14 +515,14 @@ impl + AsMut<[u8]>> Packet { #[inline] pub fn set_src_addr(&mut self, value: Address) { let data = self.buffer.as_mut(); - data[field::SRC_ADDR].copy_from_slice(value.as_bytes()); + data[field::SRC_ADDR].copy_from_slice(&value.octets()); } /// Set the destination address field. #[inline] pub fn set_dst_addr(&mut self, value: Address) { let data = self.buffer.as_mut(); - data[field::DST_ADDR].copy_from_slice(value.as_bytes()); + data[field::DST_ADDR].copy_from_slice(&value.octets()); } /// Return a mutable pointer to the payload. @@ -928,26 +656,17 @@ impl> PrettyPrint for Packet { #[cfg(test)] pub(crate) mod test { - use super::Error; - use super::{Address, Cidr}; - use super::{Packet, Protocol, Repr}; + use super::*; use crate::wire::pretty_print::PrettyPrinter; - #[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]); + pub(crate) const MOCK_IP_ADDR_1: Address = Address::new(0xfe80, 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]); + pub(crate) const MOCK_IP_ADDR_2: Address = Address::new(0xfe80, 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]); + pub(crate) const MOCK_IP_ADDR_3: Address = Address::new(0xfe80, 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]); + pub(crate) const MOCK_IP_ADDR_4: Address = Address::new(0xfe80, 0, 0, 0, 0, 0, 0, 4); #[allow(unused)] pub(crate) const MOCK_UNSPECIFIED: Address = Address::UNSPECIFIED; @@ -957,18 +676,18 @@ pub(crate) mod test { #[test] fn test_basic_multicast() { - assert!(!Address::LINK_LOCAL_ALL_ROUTERS.is_unspecified()); - assert!(Address::LINK_LOCAL_ALL_ROUTERS.is_multicast()); - assert!(!Address::LINK_LOCAL_ALL_ROUTERS.is_link_local()); - assert!(!Address::LINK_LOCAL_ALL_ROUTERS.is_loopback()); - assert!(!Address::LINK_LOCAL_ALL_ROUTERS.is_unique_local()); - assert!(!Address::LINK_LOCAL_ALL_ROUTERS.is_global_unicast()); - assert!(!Address::LINK_LOCAL_ALL_NODES.is_unspecified()); - assert!(Address::LINK_LOCAL_ALL_NODES.is_multicast()); - assert!(!Address::LINK_LOCAL_ALL_NODES.is_link_local()); - assert!(!Address::LINK_LOCAL_ALL_NODES.is_loopback()); - assert!(!Address::LINK_LOCAL_ALL_NODES.is_unique_local()); - assert!(!Address::LINK_LOCAL_ALL_NODES.is_global_unicast()); + assert!(!LINK_LOCAL_ALL_ROUTERS.is_unspecified()); + assert!(LINK_LOCAL_ALL_ROUTERS.is_multicast()); + assert!(!LINK_LOCAL_ALL_ROUTERS.is_link_local()); + assert!(!LINK_LOCAL_ALL_ROUTERS.is_loopback()); + assert!(!LINK_LOCAL_ALL_ROUTERS.is_unique_local()); + assert!(!LINK_LOCAL_ALL_ROUTERS.is_global_unicast()); + assert!(!LINK_LOCAL_ALL_NODES.is_unspecified()); + assert!(LINK_LOCAL_ALL_NODES.is_multicast()); + assert!(!LINK_LOCAL_ALL_NODES.is_link_local()); + assert!(!LINK_LOCAL_ALL_NODES.is_loopback()); + assert!(!LINK_LOCAL_ALL_NODES.is_unique_local()); + assert!(!LINK_LOCAL_ALL_NODES.is_global_unicast()); } #[test] @@ -983,12 +702,12 @@ pub(crate) mod test { #[test] fn test_basic_loopback() { - assert!(!Address::LOOPBACK.is_unspecified()); - assert!(!Address::LOOPBACK.is_multicast()); - assert!(!Address::LOOPBACK.is_link_local()); - assert!(Address::LOOPBACK.is_loopback()); - assert!(!Address::LOOPBACK.is_unique_local()); - assert!(!Address::LOOPBACK.is_global_unicast()); + assert!(!Address::LOCALHOST.is_unspecified()); + assert!(!Address::LOCALHOST.is_multicast()); + assert!(!Address::LOCALHOST.is_link_local()); + assert!(Address::LOCALHOST.is_loopback()); + assert!(!Address::LOCALHOST.is_unique_local()); + assert!(!Address::LOCALHOST.is_global_unicast()); } #[test] @@ -1011,83 +730,6 @@ pub(crate) mod test { assert!(GLOBAL_UNICAST_ADDR.is_global_unicast()); } - #[test] - fn test_address_format() { - assert_eq!("ff02::1", format!("{}", Address::LINK_LOCAL_ALL_NODES)); - assert_eq!("fe80::1", format!("{LINK_LOCAL_ADDR}")); - assert_eq!( - "fe80::7f00:0:1", - format!( - "{}", - Address::new(0xfe80, 0, 0, 0, 0, 0x7f00, 0x0000, 0x0001) - ) - ); - assert_eq!("::", format!("{}", Address::UNSPECIFIED)); - assert_eq!("::1", format!("{}", Address::LOOPBACK)); - - #[cfg(feature = "proto-ipv4")] - assert_eq!( - "::ffff:192.168.1.1", - format!("{}", Address::from(Ipv4Address::new(192, 168, 1, 1))) - ); - } - - #[test] - fn test_new() { - assert_eq!( - Address::new(0xff02, 0, 0, 0, 0, 0, 0, 1), - Address::LINK_LOCAL_ALL_NODES - ); - assert_eq!( - Address::new(0xff02, 0, 0, 0, 0, 0, 0, 2), - Address::LINK_LOCAL_ALL_ROUTERS - ); - assert_eq!(Address::new(0, 0, 0, 0, 0, 0, 0, 1), Address::LOOPBACK); - assert_eq!(Address::new(0, 0, 0, 0, 0, 0, 0, 0), Address::UNSPECIFIED); - assert_eq!(Address::new(0xfe80, 0, 0, 0, 0, 0, 0, 1), LINK_LOCAL_ADDR); - } - - #[test] - fn test_from_parts() { - assert_eq!( - Address::from_parts(&[0xff02, 0, 0, 0, 0, 0, 0, 1]), - Address::LINK_LOCAL_ALL_NODES - ); - assert_eq!( - Address::from_parts(&[0xff02, 0, 0, 0, 0, 0, 0, 2]), - Address::LINK_LOCAL_ALL_ROUTERS - ); - assert_eq!( - Address::from_parts(&[0, 0, 0, 0, 0, 0, 0, 1]), - Address::LOOPBACK - ); - assert_eq!( - Address::from_parts(&[0, 0, 0, 0, 0, 0, 0, 0]), - Address::UNSPECIFIED - ); - assert_eq!( - Address::from_parts(&[0xfe80, 0, 0, 0, 0, 0, 0, 1]), - LINK_LOCAL_ADDR - ); - } - - #[test] - fn test_write_parts() { - let mut bytes = [0u16; 8]; - { - Address::LOOPBACK.write_parts(&mut bytes); - assert_eq!(Address::LOOPBACK, Address::from_parts(&bytes)); - } - { - Address::LINK_LOCAL_ALL_ROUTERS.write_parts(&mut bytes); - assert_eq!(Address::LINK_LOCAL_ALL_ROUTERS, Address::from_parts(&bytes)); - } - { - LINK_LOCAL_ADDR.write_parts(&mut bytes); - assert_eq!(LINK_LOCAL_ADDR, Address::from_parts(&bytes)); - } - } - #[test] fn test_mask() { let addr = Address::new(0x0123, 0x4567, 0x89ab, 0, 0, 0, 0, 1); @@ -1113,35 +755,6 @@ pub(crate) mod test { ); } - #[cfg(feature = "proto-ipv4")] - #[test] - fn test_is_ipv4_mapped() { - assert!(!Address::UNSPECIFIED.is_ipv4_mapped()); - assert!(Address::from(Ipv4Address::new(192, 168, 1, 1)).is_ipv4_mapped()); - } - - #[cfg(feature = "proto-ipv4")] - #[test] - fn test_as_ipv4() { - assert_eq!(None, Address::UNSPECIFIED.as_ipv4()); - - let ipv4 = Ipv4Address::new(192, 168, 1, 1); - assert_eq!(Some(ipv4), Address::from(ipv4).as_ipv4()); - } - - #[cfg(feature = "proto-ipv4")] - #[test] - fn test_from_ipv4_address() { - assert_eq!( - Address([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 192, 168, 1, 1]), - Address::from(Ipv4Address::new(192, 168, 1, 1)) - ); - assert_eq!( - Address([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 222, 1, 41, 90]), - Address::from(Ipv4Address::new(222, 1, 41, 90)) - ); - } - #[test] fn test_cidr() { // fe80::1/56 @@ -1265,16 +878,19 @@ pub(crate) mod test { assert!(!cidr.contains_addr(&addr)); } - for subnet in subnets.iter().map(|&(a, p)| Cidr::new(Address(a), p)) { + for subnet in subnets.iter().map(|&(a, p)| Cidr::new(Address::from(a), p)) { assert!(cidr.contains_subnet(&subnet)); } - for subnet in not_subnets.iter().map(|&(a, p)| Cidr::new(Address(a), p)) { + for subnet in not_subnets + .iter() + .map(|&(a, p)| Cidr::new(Address::from(a), p)) + { assert!(!cidr.contains_subnet(&subnet)); } let cidr_without_prefix = Cidr::new(LINK_LOCAL_ADDR, 0); - assert!(cidr_without_prefix.contains_addr(&Address::LOOPBACK)); + assert!(cidr_without_prefix.contains_addr(&Address::LOCALHOST)); } #[test] @@ -1283,12 +899,6 @@ pub(crate) mod test { let _ = Address::from_bytes(&[0u8; 15]); } - #[test] - #[should_panic(expected = "data.len() >= 8")] - fn test_from_parts_too_long() { - let _ = Address::from_parts(&[0u16; 7]); - } - #[test] fn test_scope() { use super::*; @@ -1322,7 +932,7 @@ pub(crate) mod test { ); assert_eq!( - Address::LINK_LOCAL_ALL_NODES.multicast_scope(), + LINK_LOCAL_ALL_NODES.multicast_scope(), MulticastScope::LinkLocal ); @@ -1347,11 +957,8 @@ pub(crate) mod test { const fn packet_repr() -> Repr { Repr { - src_addr: Address([ - 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x01, - ]), - dst_addr: Address::LINK_LOCAL_ALL_NODES, + src_addr: Address::new(0xfe80, 0, 0, 0, 0, 0, 0, 1), + dst_addr: LINK_LOCAL_ALL_NODES, next_header: Protocol::Udp, payload_len: 12, hop_limit: 64, @@ -1369,14 +976,8 @@ pub(crate) mod test { assert_eq!(packet.payload_len() as usize, REPR_PAYLOAD_BYTES.len()); assert_eq!(packet.next_header(), Protocol::Udp); assert_eq!(packet.hop_limit(), 0x40); - assert_eq!( - packet.src_addr(), - Address([ - 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x01 - ]) - ); - assert_eq!(packet.dst_addr(), Address::LINK_LOCAL_ALL_NODES); + assert_eq!(packet.src_addr(), Address::new(0xfe80, 0, 0, 0, 0, 0, 0, 1)); + assert_eq!(packet.dst_addr(), LINK_LOCAL_ALL_NODES); assert_eq!(packet.payload(), &REPR_PAYLOAD_BYTES[..]); } @@ -1398,8 +999,8 @@ pub(crate) mod test { packet.set_payload_len(0xc); packet.set_next_header(Protocol::Udp); packet.set_hop_limit(0xfe); - packet.set_src_addr(Address::LINK_LOCAL_ALL_ROUTERS); - packet.set_dst_addr(Address::LINK_LOCAL_ALL_NODES); + packet.set_src_addr(LINK_LOCAL_ALL_ROUTERS); + packet.set_dst_addr(LINK_LOCAL_ALL_NODES); packet .payload_mut() .copy_from_slice(&REPR_PAYLOAD_BYTES[..]); diff --git a/src/wire/ipv6routing.rs b/src/wire/ipv6routing.rs index a2b91e9ce..530eac6e9 100644 --- a/src/wire/ipv6routing.rs +++ b/src/wire/ipv6routing.rs @@ -1,7 +1,7 @@ use super::{Error, Result}; use core::fmt; -use crate::wire::Ipv6Address as Address; +use crate::wire::{Ipv6Address as Address, Ipv6AddressExt}; enum_with_unknown! { /// IPv6 Extension Routing Header Routing Type @@ -286,7 +286,7 @@ impl + AsMut<[u8]>> Header { /// This function may panic if this header is not the Type 2 Routing Header routing type. pub fn set_home_address(&mut self, value: Address) { let data = self.buffer.as_mut(); - data[field::HOME_ADDRESS].copy_from_slice(value.as_bytes()); + data[field::HOME_ADDRESS].copy_from_slice(&value.octets()); } } @@ -399,7 +399,7 @@ impl<'a> Repr<'a> { pub const fn buffer_len(&self) -> usize { match self { // Routing Type + Segments Left + Reserved + Home Address - Repr::Type2 { home_address, .. } => 2 + 4 + home_address.as_bytes().len(), + Repr::Type2 { home_address, .. } => 2 + 4 + home_address.octets().len(), Repr::Rpl { addresses, .. } => 2 + 4 + addresses.len(), } } @@ -484,7 +484,7 @@ mod test { // A representation of a Type 2 Routing header static REPR_TYPE2: Repr = Repr::Type2 { segments_left: 1, - home_address: Address::LOOPBACK, + home_address: Address::LOCALHOST, }; // A Source Routing Header with full IPv6 addresses in bytes @@ -552,7 +552,7 @@ mod test { let header = Header::new_unchecked(&BYTES_TYPE2[..]); assert_eq!(header.routing_type(), Type::Type2); assert_eq!(header.segments_left(), 1); - assert_eq!(header.home_address(), Address::LOOPBACK); + assert_eq!(header.home_address(), Address::LOCALHOST); let header = Header::new_unchecked(&BYTES_SRH_FULL[..]); assert_eq!(header.routing_type(), Type::Rpl); diff --git a/src/wire/mld.rs b/src/wire/mld.rs index bb5567067..058fb81ce 100644 --- a/src/wire/mld.rs +++ b/src/wire/mld.rs @@ -8,7 +8,7 @@ use byteorder::{ByteOrder, NetworkEndian}; use super::{Error, Result}; use crate::wire::icmpv6::{field, Message, Packet}; -use crate::wire::Ipv6Address; +use crate::wire::{Ipv6Address, Ipv6AddressExt}; enum_with_unknown! { /// MLDv2 Multicast Listener Report Record Type. See [RFC 3810 § 5.2.12] for @@ -110,7 +110,7 @@ impl + AsMut<[u8]>> Packet { #[inline] pub fn set_mcast_addr(&mut self, addr: Ipv6Address) { let data = self.buffer.as_mut(); - data[field::QUERY_MCAST_ADDR].copy_from_slice(addr.as_bytes()); + data[field::QUERY_MCAST_ADDR].copy_from_slice(&addr.octets()); } /// Set the Suppress Router-Side Processing flag. @@ -281,7 +281,7 @@ impl + AsRef<[u8]>> AddressRecord { pub fn set_mcast_addr(&mut self, addr: Ipv6Address) { assert!(addr.is_multicast()); let data = self.buffer.as_mut(); - data[field::RECORD_MCAST_ADDR].copy_from_slice(addr.as_bytes()); + data[field::RECORD_MCAST_ADDR].copy_from_slice(&addr.octets()); } } @@ -460,7 +460,7 @@ mod test { use super::*; use crate::phy::ChecksumCapabilities; use crate::wire::icmpv6::Message; - use crate::wire::Icmpv6Repr; + use crate::wire::{Icmpv6Repr, IPV6_LINK_LOCAL_ALL_NODES, IPV6_LINK_LOCAL_ALL_ROUTERS}; static QUERY_PACKET_BYTES: [u8; 44] = [ 0x82, 0x00, 0x73, 0x74, 0x04, 0x00, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -489,7 +489,7 @@ mod test { match ty { Message::MldQuery => Icmpv6Repr::Mld(Repr::Query { max_resp_code: 0x400, - mcast_addr: Ipv6Address::LINK_LOCAL_ALL_NODES, + mcast_addr: IPV6_LINK_LOCAL_ALL_NODES, s_flag: true, qrv: 0x02, qqic: 0x12, @@ -513,14 +513,14 @@ mod test { assert_eq!(packet.msg_code(), 0); assert_eq!(packet.checksum(), 0x7374); assert_eq!(packet.max_resp_code(), 0x0400); - assert_eq!(packet.mcast_addr(), Ipv6Address::LINK_LOCAL_ALL_NODES); + assert_eq!(packet.mcast_addr(), IPV6_LINK_LOCAL_ALL_NODES); assert!(packet.s_flag()); assert_eq!(packet.qrv(), 0x02); assert_eq!(packet.qqic(), 0x12); assert_eq!(packet.num_srcs(), 0x01); assert_eq!( Ipv6Address::from_bytes(packet.payload()), - Ipv6Address::LINK_LOCAL_ALL_ROUTERS + IPV6_LINK_LOCAL_ALL_ROUTERS ); } @@ -531,19 +531,16 @@ mod test { packet.set_msg_type(Message::MldQuery); packet.set_msg_code(0); packet.set_max_resp_code(0x0400); - packet.set_mcast_addr(Ipv6Address::LINK_LOCAL_ALL_NODES); + packet.set_mcast_addr(IPV6_LINK_LOCAL_ALL_NODES); packet.set_s_flag(); packet.set_qrv(0x02); packet.set_qqic(0x12); packet.set_num_srcs(0x01); packet .payload_mut() - .copy_from_slice(Ipv6Address::LINK_LOCAL_ALL_ROUTERS.as_bytes()); + .copy_from_slice(&IPV6_LINK_LOCAL_ALL_ROUTERS.octets()); packet.clear_reserved(); - packet.fill_checksum( - &Ipv6Address::LINK_LOCAL_ALL_NODES, - &Ipv6Address::LINK_LOCAL_ALL_ROUTERS, - ); + packet.fill_checksum(&IPV6_LINK_LOCAL_ALL_NODES, &IPV6_LINK_LOCAL_ALL_ROUTERS); assert_eq!(&*packet.into_inner(), &QUERY_PACKET_BYTES[..]); } @@ -558,10 +555,10 @@ mod test { assert_eq!(addr_rcrd.record_type(), RecordType::ModeIsInclude); assert_eq!(addr_rcrd.aux_data_len(), 0x00); assert_eq!(addr_rcrd.num_srcs(), 0x01); - assert_eq!(addr_rcrd.mcast_addr(), Ipv6Address::LINK_LOCAL_ALL_NODES); + assert_eq!(addr_rcrd.mcast_addr(), IPV6_LINK_LOCAL_ALL_NODES); assert_eq!( Ipv6Address::from_bytes(addr_rcrd.payload()), - Ipv6Address::LINK_LOCAL_ALL_ROUTERS + IPV6_LINK_LOCAL_ALL_ROUTERS ); } @@ -578,15 +575,12 @@ mod test { addr_rcrd.set_record_type(RecordType::ModeIsInclude); addr_rcrd.set_aux_data_len(0); addr_rcrd.set_num_srcs(1); - addr_rcrd.set_mcast_addr(Ipv6Address::LINK_LOCAL_ALL_NODES); + addr_rcrd.set_mcast_addr(IPV6_LINK_LOCAL_ALL_NODES); addr_rcrd .payload_mut() - .copy_from_slice(Ipv6Address::LINK_LOCAL_ALL_ROUTERS.as_bytes()); + .copy_from_slice(&IPV6_LINK_LOCAL_ALL_ROUTERS.octets()); } - packet.fill_checksum( - &Ipv6Address::LINK_LOCAL_ALL_NODES, - &Ipv6Address::LINK_LOCAL_ALL_ROUTERS, - ); + packet.fill_checksum(&IPV6_LINK_LOCAL_ALL_NODES, &IPV6_LINK_LOCAL_ALL_ROUTERS); assert_eq!(&*packet.into_inner(), &REPORT_PACKET_BYTES[..]); } @@ -594,8 +588,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, - &Ipv6Address::LINK_LOCAL_ALL_ROUTERS, + &IPV6_LINK_LOCAL_ALL_NODES, + &IPV6_LINK_LOCAL_ALL_ROUTERS, &packet, &ChecksumCapabilities::default(), ); @@ -606,8 +600,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, - &Ipv6Address::LINK_LOCAL_ALL_ROUTERS, + &IPV6_LINK_LOCAL_ALL_NODES, + &IPV6_LINK_LOCAL_ALL_ROUTERS, &packet, &ChecksumCapabilities::default(), ); @@ -620,8 +614,8 @@ mod test { let mut packet = Packet::new_unchecked(&mut bytes[..]); let repr = create_repr(Message::MldQuery); repr.emit( - &Ipv6Address::LINK_LOCAL_ALL_NODES, - &Ipv6Address::LINK_LOCAL_ALL_ROUTERS, + &IPV6_LINK_LOCAL_ALL_NODES, + &IPV6_LINK_LOCAL_ALL_ROUTERS, &mut packet, &ChecksumCapabilities::default(), ); @@ -634,8 +628,8 @@ mod test { let mut packet = Packet::new_unchecked(&mut bytes[..]); let repr = create_repr(Message::MldReport); repr.emit( - &Ipv6Address::LINK_LOCAL_ALL_NODES, - &Ipv6Address::LINK_LOCAL_ALL_ROUTERS, + &IPV6_LINK_LOCAL_ALL_NODES, + &IPV6_LINK_LOCAL_ALL_ROUTERS, &mut packet, &ChecksumCapabilities::default(), ); diff --git a/src/wire/mod.rs b/src/wire/mod.rs index 4ec8a70f1..3e31ca780 100644 --- a/src/wire/mod.rs +++ b/src/wire/mod.rs @@ -195,13 +195,17 @@ pub use self::ipv4::{ #[cfg(feature = "proto-ipv4")] pub(crate) use self::ipv4::AddressExt as Ipv4AddressExt; -#[cfg(feature = "proto-ipv6")] -pub(crate) use self::ipv6::MulticastScope as Ipv6MulticastScope; #[cfg(feature = "proto-ipv6")] pub use self::ipv6::{ Address as Ipv6Address, Cidr as Ipv6Cidr, Packet as Ipv6Packet, Repr as Ipv6Repr, - HEADER_LEN as IPV6_HEADER_LEN, MIN_MTU as IPV6_MIN_MTU, + HEADER_LEN as IPV6_HEADER_LEN, + LINK_LOCAL_ALL_MLDV2_ROUTERS as IPV6_LINK_LOCAL_ALL_MLDV2_ROUTERS, + LINK_LOCAL_ALL_NODES as IPV6_LINK_LOCAL_ALL_NODES, + LINK_LOCAL_ALL_ROUTERS as IPV6_LINK_LOCAL_ALL_ROUTERS, + LINK_LOCAL_ALL_RPL_NODES as IPV6_LINK_LOCAL_ALL_RPL_NODES, MIN_MTU as IPV6_MIN_MTU, }; +#[cfg(feature = "proto-ipv6")] +pub(crate) use self::ipv6::{AddressExt as Ipv6AddressExt, MulticastScope as Ipv6MulticastScope}; #[cfg(feature = "proto-ipv6")] pub use self::ipv6option::{ diff --git a/src/wire/ndisc.rs b/src/wire/ndisc.rs index a71cdd61a..3c1243e3b 100644 --- a/src/wire/ndisc.rs +++ b/src/wire/ndisc.rs @@ -4,8 +4,8 @@ use byteorder::{ByteOrder, NetworkEndian}; use super::{Error, Result}; use crate::time::Duration; use crate::wire::icmpv6::{field, Message, Packet}; -use crate::wire::Ipv6Address; use crate::wire::RawHardwareAddress; +use crate::wire::{Ipv6Address, Ipv6AddressExt}; use crate::wire::{NdiscOption, NdiscOptionRepr}; use crate::wire::{NdiscPrefixInformation, NdiscRedirectedHeader}; @@ -159,7 +159,7 @@ impl + AsMut<[u8]>> Packet { #[inline] pub fn set_target_addr(&mut self, value: Ipv6Address) { let data = self.buffer.as_mut(); - data[field::TARGET_ADDR].copy_from_slice(value.as_bytes()); + data[field::TARGET_ADDR].copy_from_slice(&value.octets()); } } @@ -184,7 +184,7 @@ impl + AsMut<[u8]>> Packet { #[inline] pub fn set_dest_addr(&mut self, value: Ipv6Address) { let data = self.buffer.as_mut(); - data[field::DEST_ADDR].copy_from_slice(value.as_bytes()); + data[field::DEST_ADDR].copy_from_slice(&value.octets()); } } @@ -462,10 +462,8 @@ mod test { 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]); + const MOCK_IP_ADDR_1: Ipv6Address = Ipv6Address::new(0xfe80, 0, 0, 0, 0, 0, 0, 1); + const MOCK_IP_ADDR_2: Ipv6Address = Ipv6Address::new(0xfe80, 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, diff --git a/src/wire/ndiscoption.rs b/src/wire/ndiscoption.rs index 0236d4351..583d9b569 100644 --- a/src/wire/ndiscoption.rs +++ b/src/wire/ndiscoption.rs @@ -4,7 +4,7 @@ use core::fmt; use super::{Error, Result}; use crate::time::Duration; -use crate::wire::{Ipv6Address, Ipv6Packet, Ipv6Repr, MAX_HARDWARE_ADDRESS_LEN}; +use crate::wire::{Ipv6Address, Ipv6AddressExt, Ipv6Packet, Ipv6Repr, MAX_HARDWARE_ADDRESS_LEN}; use crate::wire::RawHardwareAddress; @@ -356,7 +356,7 @@ impl + AsMut<[u8]>> NdiscOption { #[inline] pub fn set_prefix(&mut self, addr: Ipv6Address) { let data = self.buffer.as_mut(); - data[field::PREFIX].copy_from_slice(addr.as_bytes()); + data[field::PREFIX].copy_from_slice(&addr.octets()); } } diff --git a/src/wire/sixlowpan/iphc.rs b/src/wire/sixlowpan/iphc.rs index 5841eb738..429114128 100644 --- a/src/wire/sixlowpan/iphc.rs +++ b/src/wire/sixlowpan/iphc.rs @@ -6,7 +6,7 @@ use super::{ AddressContext, AddressMode, Error, NextHeader, Result, UnresolvedAddress, DISPATCH_IPHC_HEADER, }; -use crate::wire::{ieee802154::Address as LlAddress, ipv6, IpProtocol}; +use crate::wire::{ieee802154::Address as LlAddress, ipv6, ipv6::AddressExt, IpProtocol}; use byteorder::{ByteOrder, NetworkEndian}; mod field { @@ -526,7 +526,7 @@ impl + AsMut<[u8]>> Packet { ) -> usize { self.set_cid_field(0); self.set_sac_field(0); - let src = src_addr.as_bytes(); + let src = src_addr.octets(); if src_addr == ipv6::Address::UNSPECIFIED { self.set_sac_field(1); self.set_sam_field(0b00); @@ -574,7 +574,7 @@ impl + AsMut<[u8]>> Packet { } else { // We cannot elide anything. self.set_sam_field(0b00); - self.set_field(idx, src); + self.set_field(idx, &src); idx += 16; } @@ -593,7 +593,7 @@ impl + AsMut<[u8]>> Packet { self.set_dac_field(0); self.set_dam_field(0); self.set_m_field(0); - let dst = dst_addr.as_bytes(); + let dst = dst_addr.octets(); if dst_addr.is_multicast() { self.set_m_field(1); @@ -619,7 +619,7 @@ impl + AsMut<[u8]>> Packet { } else { self.set_dam_field(0b11); - self.set_field(idx, dst); + self.set_field(idx, &dst); idx += 16; } } else if dst_addr.is_link_local() { @@ -653,7 +653,7 @@ impl + AsMut<[u8]>> Packet { } else { self.set_dam_field(0b00); - self.set_field(idx, dst); + self.set_field(idx, &dst); idx += 16; } @@ -771,7 +771,7 @@ impl Repr { len += if self.src_addr == ipv6::Address::UNSPECIFIED { 0 } else if self.src_addr.is_link_local() { - let src = self.src_addr.as_bytes(); + let src = self.src_addr.octets(); let ll = [src[14], src[15]]; let is_eui_64 = self @@ -799,7 +799,7 @@ impl Repr { }; // Add the size of the destination header - let dst = self.dst_addr.as_bytes(); + let dst = self.dst_addr.octets(); len += if self.dst_addr.is_multicast() { if dst[1] == 0x02 && dst[2..15] == [0; 13] { 1 diff --git a/src/wire/sixlowpan/mod.rs b/src/wire/sixlowpan/mod.rs index 03a5218a0..59c13bfe2 100644 --- a/src/wire/sixlowpan/mod.rs +++ b/src/wire/sixlowpan/mod.rs @@ -6,6 +6,7 @@ use super::{Error, Result}; use crate::wire::ieee802154::Address as LlAddress; use crate::wire::ipv6; +use crate::wire::ipv6::AddressExt; use crate::wire::IpProtocol; pub mod frag; diff --git a/src/wire/sixlowpan/nhc.rs b/src/wire/sixlowpan/nhc.rs index 85e422a49..d558d1d5f 100644 --- a/src/wire/sixlowpan/nhc.rs +++ b/src/wire/sixlowpan/nhc.rs @@ -862,8 +862,8 @@ mod test { let payload = b"Hello World!"; - let src_addr = ipv6::Address::default(); - let dst_addr = ipv6::Address::default(); + let src_addr = ipv6::Address::UNSPECIFIED; + let dst_addr = ipv6::Address::UNSPECIFIED; let len = udp.header_len() + payload.len(); let mut buffer = [0u8; 127];