diff --git a/Cargo.toml b/Cargo.toml index c4ea6146f..15b8321e7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,7 +25,7 @@ byteorder = { version = "1.0", default-features = false } log = { version = "0.4.4", default-features = false, optional = true } libc = { version = "0.2.18", optional = true } bitflags = { version = "1.0", default-features = false } -defmt = { version = "0.3", optional = true } +defmt = { version = "0.3.8", optional = true, features = ["ip_in_core"] } cfg-if = "1.0.0" heapless = "0.8" diff --git a/benches/bench.rs b/benches/bench.rs index 0920958d9..7114cabfd 100644 --- a/benches/bench.rs +++ b/benches/bench.rs @@ -22,9 +22,9 @@ mod wire { ])); #[cfg(all(not(feature = "proto-ipv6"), feature = "proto-ipv4"))] - const SRC_ADDR: IpAddress = IpAddress::Ipv4(Ipv4Address([192, 168, 1, 1])); + const SRC_ADDR: IpAddress = IpAddress::Ipv4(Ipv4Address::new(192, 168, 1, 1)); #[cfg(all(not(feature = "proto-ipv6"), feature = "proto-ipv4"))] - const DST_ADDR: IpAddress = IpAddress::Ipv4(Ipv4Address([192, 168, 1, 2])); + const DST_ADDR: IpAddress = IpAddress::Ipv4(Ipv4Address::new(192, 168, 1, 2)); #[bench] #[cfg(any(feature = "proto-ipv6", feature = "proto-ipv4"))] @@ -84,8 +84,8 @@ mod wire { #[cfg(feature = "proto-ipv4")] fn bench_emit_ipv4(b: &mut test::Bencher) { let repr = Ipv4Repr { - src_addr: Ipv4Address([192, 168, 1, 1]), - dst_addr: Ipv4Address([192, 168, 1, 2]), + src_addr: Ipv4Address::new(192, 168, 1, 1), + dst_addr: Ipv4Address::new(192, 168, 1, 2), next_header: IpProtocol::Tcp, payload_len: 100, hop_limit: 64, diff --git a/examples/multicast.rs b/examples/multicast.rs index 44162d6d3..ab86a4bce 100644 --- a/examples/multicast.rs +++ b/examples/multicast.rs @@ -12,7 +12,7 @@ use smoltcp::wire::{ }; const MDNS_PORT: u16 = 5353; -const MDNS_GROUP: [u8; 4] = [224, 0, 0, 251]; +const MDNS_GROUP: Ipv4Address = Ipv4Address::new(224, 0, 0, 251); fn main() { utils::setup_logging("warn"); @@ -81,9 +81,7 @@ fn main() { let udp_handle = sockets.add(udp_socket); // Join a multicast group to receive mDNS traffic - iface - .join_multicast_group(Ipv4Address::from_bytes(&MDNS_GROUP)) - .unwrap(); + iface.join_multicast_group(MDNS_GROUP).unwrap(); loop { let timestamp = Instant::now(); diff --git a/src/iface/fragmentation.rs b/src/iface/fragmentation.rs index 8654ac3a2..16c84f456 100644 --- a/src/iface/fragmentation.rs +++ b/src/iface/fragmentation.rs @@ -329,8 +329,8 @@ impl Fragmenter { #[cfg(feature = "proto-ipv4-fragmentation")] ipv4: Ipv4Fragmenter { repr: Ipv4Repr { - src_addr: Ipv4Address::default(), - dst_addr: Ipv4Address::default(), + src_addr: Ipv4Address::new(0, 0, 0, 0), + dst_addr: Ipv4Address::new(0, 0, 0, 0), next_header: IpProtocol::Unknown(0), payload_len: 0, hop_limit: 0, @@ -373,8 +373,8 @@ impl Fragmenter { #[cfg(feature = "proto-ipv4-fragmentation")] { self.ipv4.repr = Ipv4Repr { - src_addr: Ipv4Address::default(), - dst_addr: Ipv4Address::default(), + src_addr: Ipv4Address::new(0, 0, 0, 0), + dst_addr: Ipv4Address::new(0, 0, 0, 0), next_header: IpProtocol::Unknown(0), payload_len: 0, hop_limit: 0, diff --git a/src/iface/interface/mod.rs b/src/iface/interface/mod.rs index 04c10f583..0e704de2a 100644 --- a/src/iface/interface/mod.rs +++ b/src/iface/interface/mod.rs @@ -830,7 +830,7 @@ impl InterfaceInner { match addr { #[cfg(feature = "proto-ipv4")] - IpAddress::Ipv4(key) => key == Ipv4Address::MULTICAST_ALL_SYSTEMS, + IpAddress::Ipv4(key) => key == IPV4_MULTICAST_ALL_SYSTEMS, #[cfg(feature = "proto-rpl")] IpAddress::Ipv6(Ipv6Address::LINK_LOCAL_ALL_RPL_NODES) => true, #[cfg(feature = "proto-ipv6")] @@ -987,30 +987,35 @@ impl InterfaceInner { } if dst_addr.is_multicast() { - let b = dst_addr.as_bytes(); let hardware_addr = match *dst_addr { #[cfg(feature = "proto-ipv4")] - IpAddress::Ipv4(_addr) => match self.caps.medium { + IpAddress::Ipv4(addr) => match self.caps.medium { #[cfg(feature = "medium-ethernet")] - Medium::Ethernet => HardwareAddress::Ethernet(EthernetAddress::from_bytes(&[ - 0x01, - 0x00, - 0x5e, - b[1] & 0x7F, - b[2], - b[3], - ])), + Medium::Ethernet => { + let b = addr.octets(); + HardwareAddress::Ethernet(EthernetAddress::from_bytes(&[ + 0x01, + 0x00, + 0x5e, + b[1] & 0x7F, + b[2], + b[3], + ])) + } #[cfg(feature = "medium-ieee802154")] Medium::Ieee802154 => unreachable!(), #[cfg(feature = "medium-ip")] Medium::Ip => unreachable!(), }, #[cfg(feature = "proto-ipv6")] - IpAddress::Ipv6(_addr) => match self.caps.medium { + IpAddress::Ipv6(addr) => match self.caps.medium { #[cfg(feature = "medium-ethernet")] - Medium::Ethernet => HardwareAddress::Ethernet(EthernetAddress::from_bytes(&[ - 0x33, 0x33, b[12], b[13], b[14], b[15], - ])), + Medium::Ethernet => { + let b = addr.as_bytes(); + HardwareAddress::Ethernet(EthernetAddress::from_bytes(&[ + 0x33, 0x33, b[12], b[13], b[14], b[15], + ])) + } #[cfg(feature = "medium-ieee802154")] Medium::Ieee802154 => { // Not sure if this is correct diff --git a/src/iface/interface/multicast.rs b/src/iface/interface/multicast.rs index 7542a12f4..68b1c7750 100644 --- a/src/iface/interface/multicast.rs +++ b/src/iface/interface/multicast.rs @@ -334,9 +334,7 @@ impl InterfaceInner { max_resp_time, } => { // General query - if group_addr.is_unspecified() - && ipv4_repr.dst_addr == Ipv4Address::MULTICAST_ALL_SYSTEMS - { + if group_addr.is_unspecified() && ipv4_repr.dst_addr == IPV4_MULTICAST_ALL_SYSTEMS { let ipv4_multicast_group_count = self .multicast .groups @@ -418,7 +416,7 @@ impl InterfaceInner { Packet::new_ipv4( Ipv4Repr { src_addr: iface_addr, - dst_addr: Ipv4Address::MULTICAST_ALL_ROUTERS, + dst_addr: IPV4_MULTICAST_ALL_ROUTERS, next_header: IpProtocol::Igmp, payload_len: igmp_repr.buffer_len(), hop_limit: 1, diff --git a/src/iface/interface/tests/ipv4.rs b/src/iface/interface/tests/ipv4.rs index 41e35301c..d3b8c61e8 100644 --- a/src/iface/interface/tests/ipv4.rs +++ b/src/iface/interface/tests/ipv4.rs @@ -72,7 +72,7 @@ fn test_no_icmp_no_unicast(#[case] medium: Medium) { // this should not trigger and Destination Unreachable // response. See RFC 1122 § 3.2.2. let repr = IpRepr::Ipv4(Ipv4Repr { - src_addr: Ipv4Address([0x7f, 0x00, 0x00, 0x01]), + src_addr: Ipv4Address::new(0x7f, 0x00, 0x00, 0x01), dst_addr: Ipv4Address::BROADCAST, next_header: IpProtocol::Unknown(0x0c), payload_len: 0, @@ -110,8 +110,8 @@ fn test_icmp_error_no_payload(#[case] medium: Medium) { // Unknown Ipv4 Protocol with no payload let repr = IpRepr::Ipv4(Ipv4Repr { - src_addr: Ipv4Address([0x7f, 0x00, 0x00, 0x02]), - dst_addr: Ipv4Address([0x7f, 0x00, 0x00, 0x01]), + src_addr: Ipv4Address::new(0x7f, 0x00, 0x00, 0x02), + dst_addr: Ipv4Address::new(0x7f, 0x00, 0x00, 0x01), next_header: IpProtocol::Unknown(0x0c), payload_len: 0, hop_limit: 0x40, @@ -126,8 +126,8 @@ fn test_icmp_error_no_payload(#[case] medium: Medium) { let icmp_repr = Icmpv4Repr::DstUnreachable { reason: Icmpv4DstUnreachable::ProtoUnreachable, header: Ipv4Repr { - src_addr: Ipv4Address([0x7f, 0x00, 0x00, 0x02]), - dst_addr: Ipv4Address([0x7f, 0x00, 0x00, 0x01]), + src_addr: Ipv4Address::new(0x7f, 0x00, 0x00, 0x02), + dst_addr: Ipv4Address::new(0x7f, 0x00, 0x00, 0x01), next_header: IpProtocol::Unknown(12), payload_len: 0, hop_limit: 64, @@ -137,8 +137,8 @@ fn test_icmp_error_no_payload(#[case] medium: Medium) { let expected_repr = Packet::new_ipv4( Ipv4Repr { - src_addr: Ipv4Address([0x7f, 0x00, 0x00, 0x01]), - dst_addr: Ipv4Address([0x7f, 0x00, 0x00, 0x02]), + src_addr: Ipv4Address::new(0x7f, 0x00, 0x00, 0x01), + dst_addr: Ipv4Address::new(0x7f, 0x00, 0x00, 0x02), next_header: IpProtocol::Icmp, payload_len: icmp_repr.buffer_len(), hop_limit: 64, @@ -170,62 +170,70 @@ fn test_local_subnet_broadcasts(#[case] medium: Medium) { let (mut iface, _, _device) = setup(medium); iface.update_ip_addrs(|addrs| { addrs.iter_mut().next().map(|addr| { - *addr = IpCidr::Ipv4(Ipv4Cidr::new(Ipv4Address([192, 168, 1, 23]), 24)); + *addr = IpCidr::Ipv4(Ipv4Cidr::new(Ipv4Address::new(192, 168, 1, 23), 24)); }); }); assert!(iface .inner - .is_broadcast_v4(Ipv4Address([255, 255, 255, 255]))); + .is_broadcast_v4(Ipv4Address::new(255, 255, 255, 255))); assert!(!iface .inner - .is_broadcast_v4(Ipv4Address([255, 255, 255, 254]))); - assert!(iface.inner.is_broadcast_v4(Ipv4Address([192, 168, 1, 255]))); - assert!(!iface.inner.is_broadcast_v4(Ipv4Address([192, 168, 1, 254]))); + .is_broadcast_v4(Ipv4Address::new(255, 255, 255, 254))); + assert!(iface + .inner + .is_broadcast_v4(Ipv4Address::new(192, 168, 1, 255))); + assert!(!iface + .inner + .is_broadcast_v4(Ipv4Address::new(192, 168, 1, 254))); iface.update_ip_addrs(|addrs| { addrs.iter_mut().next().map(|addr| { - *addr = IpCidr::Ipv4(Ipv4Cidr::new(Ipv4Address([192, 168, 23, 24]), 16)); + *addr = IpCidr::Ipv4(Ipv4Cidr::new(Ipv4Address::new(192, 168, 23, 24), 16)); }); }); assert!(iface .inner - .is_broadcast_v4(Ipv4Address([255, 255, 255, 255]))); + .is_broadcast_v4(Ipv4Address::new(255, 255, 255, 255))); assert!(!iface .inner - .is_broadcast_v4(Ipv4Address([255, 255, 255, 254]))); + .is_broadcast_v4(Ipv4Address::new(255, 255, 255, 254))); assert!(!iface .inner - .is_broadcast_v4(Ipv4Address([192, 168, 23, 255]))); + .is_broadcast_v4(Ipv4Address::new(192, 168, 23, 255))); assert!(!iface .inner - .is_broadcast_v4(Ipv4Address([192, 168, 23, 254]))); + .is_broadcast_v4(Ipv4Address::new(192, 168, 23, 254))); assert!(!iface .inner - .is_broadcast_v4(Ipv4Address([192, 168, 255, 254]))); + .is_broadcast_v4(Ipv4Address::new(192, 168, 255, 254))); assert!(iface .inner - .is_broadcast_v4(Ipv4Address([192, 168, 255, 255]))); + .is_broadcast_v4(Ipv4Address::new(192, 168, 255, 255))); iface.update_ip_addrs(|addrs| { addrs.iter_mut().next().map(|addr| { - *addr = IpCidr::Ipv4(Ipv4Cidr::new(Ipv4Address([192, 168, 23, 24]), 8)); + *addr = IpCidr::Ipv4(Ipv4Cidr::new(Ipv4Address::new(192, 168, 23, 24), 8)); }); }); assert!(iface .inner - .is_broadcast_v4(Ipv4Address([255, 255, 255, 255]))); + .is_broadcast_v4(Ipv4Address::new(255, 255, 255, 255))); assert!(!iface .inner - .is_broadcast_v4(Ipv4Address([255, 255, 255, 254]))); - assert!(!iface.inner.is_broadcast_v4(Ipv4Address([192, 23, 1, 255]))); - assert!(!iface.inner.is_broadcast_v4(Ipv4Address([192, 23, 1, 254]))); + .is_broadcast_v4(Ipv4Address::new(255, 255, 255, 254))); assert!(!iface .inner - .is_broadcast_v4(Ipv4Address([192, 255, 255, 254]))); + .is_broadcast_v4(Ipv4Address::new(192, 23, 1, 255))); + assert!(!iface + .inner + .is_broadcast_v4(Ipv4Address::new(192, 23, 1, 254))); + assert!(!iface + .inner + .is_broadcast_v4(Ipv4Address::new(192, 255, 255, 254))); assert!(iface .inner - .is_broadcast_v4(Ipv4Address([192, 255, 255, 255]))); + .is_broadcast_v4(Ipv4Address::new(192, 255, 255, 255))); } #[rstest] @@ -250,8 +258,8 @@ fn test_icmp_error_port_unreachable(#[case] medium: Medium) { }; let ip_repr = IpRepr::Ipv4(Ipv4Repr { - src_addr: Ipv4Address([0x7f, 0x00, 0x00, 0x02]), - dst_addr: Ipv4Address([0x7f, 0x00, 0x00, 0x01]), + src_addr: Ipv4Address::new(0x7f, 0x00, 0x00, 0x02), + dst_addr: Ipv4Address::new(0x7f, 0x00, 0x00, 0x01), next_header: IpProtocol::Udp, payload_len: udp_repr.header_len() + UDP_PAYLOAD.len(), hop_limit: 64, @@ -274,8 +282,8 @@ fn test_icmp_error_port_unreachable(#[case] medium: Medium) { let icmp_repr = Icmpv4Repr::DstUnreachable { reason: Icmpv4DstUnreachable::PortUnreachable, header: Ipv4Repr { - src_addr: Ipv4Address([0x7f, 0x00, 0x00, 0x02]), - dst_addr: Ipv4Address([0x7f, 0x00, 0x00, 0x01]), + src_addr: Ipv4Address::new(0x7f, 0x00, 0x00, 0x02), + dst_addr: Ipv4Address::new(0x7f, 0x00, 0x00, 0x01), next_header: IpProtocol::Udp, payload_len: udp_repr.header_len() + UDP_PAYLOAD.len(), hop_limit: 64, @@ -284,8 +292,8 @@ fn test_icmp_error_port_unreachable(#[case] medium: Medium) { }; let expected_repr = Packet::new_ipv4( Ipv4Repr { - src_addr: Ipv4Address([0x7f, 0x00, 0x00, 0x01]), - dst_addr: Ipv4Address([0x7f, 0x00, 0x00, 0x02]), + src_addr: Ipv4Address::new(0x7f, 0x00, 0x00, 0x01), + dst_addr: Ipv4Address::new(0x7f, 0x00, 0x00, 0x02), next_header: IpProtocol::Icmp, payload_len: icmp_repr.buffer_len(), hop_limit: 64, @@ -303,7 +311,7 @@ fn test_icmp_error_port_unreachable(#[case] medium: Medium) { ); let ip_repr = IpRepr::Ipv4(Ipv4Repr { - src_addr: Ipv4Address([0x7f, 0x00, 0x00, 0x02]), + src_addr: Ipv4Address::new(0x7f, 0x00, 0x00, 0x02), dst_addr: Ipv4Address::BROADCAST, next_header: IpProtocol::Udp, payload_len: udp_repr.header_len() + UDP_PAYLOAD.len(), @@ -346,7 +354,7 @@ fn test_handle_ipv4_broadcast(#[case] medium: Medium) { let (mut iface, mut sockets, _device) = setup(medium); let our_ipv4_addr = iface.ipv4_addr().unwrap(); - let src_ipv4_addr = Ipv4Address([127, 0, 0, 2]); + let src_ipv4_addr = Ipv4Address::new(127, 0, 0, 2); // ICMPv4 echo request let icmpv4_data: [u8; 4] = [0xaa, 0x00, 0x00, 0xff]; @@ -415,8 +423,8 @@ fn test_handle_valid_arp_request(#[case] medium: Medium) { let mut eth_bytes = vec![0u8; 42]; - let local_ip_addr = Ipv4Address([0x7f, 0x00, 0x00, 0x01]); - let remote_ip_addr = Ipv4Address([0x7f, 0x00, 0x00, 0x02]); + let local_ip_addr = Ipv4Address::new(0x7f, 0x00, 0x00, 0x01); + let remote_ip_addr = Ipv4Address::new(0x7f, 0x00, 0x00, 0x02); let local_hw_addr = EthernetAddress([0x02, 0x02, 0x02, 0x02, 0x02, 0x02]); let remote_hw_addr = EthernetAddress([0x52, 0x54, 0x00, 0x00, 0x00, 0x00]); @@ -471,7 +479,7 @@ fn test_handle_other_arp_request(#[case] medium: Medium) { let mut eth_bytes = vec![0u8; 42]; - let remote_ip_addr = Ipv4Address([0x7f, 0x00, 0x00, 0x02]); + let remote_ip_addr = Ipv4Address::new(0x7f, 0x00, 0x00, 0x02); let remote_hw_addr = EthernetAddress([0x52, 0x54, 0x00, 0x00, 0x00, 0x00]); let repr = ArpRepr::EthernetIpv4 { @@ -479,7 +487,7 @@ fn test_handle_other_arp_request(#[case] medium: Medium) { source_hardware_addr: remote_hw_addr, source_protocol_addr: remote_ip_addr, target_hardware_addr: EthernetAddress::default(), - target_protocol_addr: Ipv4Address([0x7f, 0x00, 0x00, 0x03]), + target_protocol_addr: Ipv4Address::new(0x7f, 0x00, 0x00, 0x03), }; let mut frame = EthernetFrame::new_unchecked(&mut eth_bytes); @@ -519,8 +527,8 @@ fn test_arp_flush_after_update_ip(#[case] medium: Medium) { let mut eth_bytes = vec![0u8; 42]; - let local_ip_addr = Ipv4Address([0x7f, 0x00, 0x00, 0x01]); - let remote_ip_addr = Ipv4Address([0x7f, 0x00, 0x00, 0x02]); + let local_ip_addr = Ipv4Address::new(0x7f, 0x00, 0x00, 0x01); + let remote_ip_addr = Ipv4Address::new(0x7f, 0x00, 0x00, 0x02); let local_hw_addr = EthernetAddress([0x02, 0x02, 0x02, 0x02, 0x02, 0x02]); let remote_hw_addr = EthernetAddress([0x52, 0x54, 0x00, 0x00, 0x00, 0x00]); @@ -529,7 +537,7 @@ fn test_arp_flush_after_update_ip(#[case] medium: Medium) { source_hardware_addr: remote_hw_addr, source_protocol_addr: remote_ip_addr, target_hardware_addr: EthernetAddress::default(), - target_protocol_addr: Ipv4Address([0x7f, 0x00, 0x00, 0x01]), + target_protocol_addr: Ipv4Address::new(0x7f, 0x00, 0x00, 0x01), }; let mut frame = EthernetFrame::new_unchecked(&mut eth_bytes); @@ -569,7 +577,7 @@ fn test_arp_flush_after_update_ip(#[case] medium: Medium) { ); // Update IP addrs to trigger ARP cache flush - let local_ip_addr_new = Ipv4Address([0x7f, 0x00, 0x00, 0x01]); + let local_ip_addr_new = Ipv4Address::new(0x7f, 0x00, 0x00, 0x01); iface.update_ip_addrs(|addrs| { addrs.iter_mut().next().map(|addr| { *addr = IpCidr::Ipv4(Ipv4Cidr::new(local_ip_addr_new, 24)); @@ -746,7 +754,7 @@ fn test_handle_igmp(#[case] medium: Medium) { assert_eq!(leaves.len(), 2); for (i, group_addr) in groups.iter().cloned().enumerate() { assert_eq!(leaves[i].0.next_header, IpProtocol::Igmp); - assert_eq!(leaves[i].0.dst_addr, Ipv4Address::MULTICAST_ALL_ROUTERS); + assert_eq!(leaves[i].0.dst_addr, IPV4_MULTICAST_ALL_ROUTERS); assert_eq!(leaves[i].1, IgmpRepr::LeaveGroup { group_addr }); } } @@ -771,8 +779,8 @@ fn test_raw_socket_no_reply(#[case] medium: Medium) { let raw_socket = raw::Socket::new(IpVersion::Ipv4, IpProtocol::Udp, rx_buffer, tx_buffer); sockets.add(raw_socket); - let src_addr = Ipv4Address([127, 0, 0, 2]); - let dst_addr = Ipv4Address([127, 0, 0, 1]); + let src_addr = Ipv4Address::new(127, 0, 0, 2); + let dst_addr = Ipv4Address::new(127, 0, 0, 1); const PAYLOAD_LEN: usize = 10; @@ -871,8 +879,8 @@ fn test_raw_socket_with_udp_socket(#[case] medium: Medium) { ); sockets.add(raw_socket); - let src_addr = Ipv4Address([127, 0, 0, 2]); - let dst_addr = Ipv4Address([127, 0, 0, 1]); + let src_addr = Ipv4Address::new(127, 0, 0, 2); + let dst_addr = Ipv4Address::new(127, 0, 0, 1); let udp_repr = UdpRepr { src_port: 67, @@ -951,8 +959,8 @@ fn test_icmp_reply_size(#[case] medium: Medium) { let (mut iface, mut sockets, _device) = setup(medium); - let src_addr = Ipv4Address([192, 168, 1, 1]); - let dst_addr = Ipv4Address([192, 168, 1, 2]); + let src_addr = Ipv4Address::new(192, 168, 1, 1); + let dst_addr = Ipv4Address::new(192, 168, 1, 2); // UDP packet that if not tructated will cause a icmp port unreachable reply // to exceed the minimum mtu bytes in length. diff --git a/src/iface/route.rs b/src/iface/route.rs index 123c6950c..628b5ffa0 100644 --- a/src/iface/route.rs +++ b/src/iface/route.rs @@ -200,17 +200,17 @@ mod test { #[cfg(all(feature = "proto-ipv4", not(feature = "proto-ipv6")))] mod mock { use super::super::*; - pub const ADDR_1A: Ipv4Address = Ipv4Address([192, 0, 2, 1]); - pub const ADDR_1B: Ipv4Address = Ipv4Address([192, 0, 2, 13]); - pub const ADDR_1C: Ipv4Address = Ipv4Address([192, 0, 2, 42]); + pub const ADDR_1A: Ipv4Address = Ipv4Address::new(192, 0, 2, 1); + pub const ADDR_1B: Ipv4Address = Ipv4Address::new(192, 0, 2, 13); + pub const ADDR_1C: Ipv4Address = Ipv4Address::new(192, 0, 2, 42); pub fn cidr_1() -> Ipv4Cidr { - Ipv4Cidr::new(Ipv4Address([192, 0, 2, 0]), 24) + Ipv4Cidr::new(Ipv4Address::new(192, 0, 2, 0), 24) } - pub const ADDR_2A: Ipv4Address = Ipv4Address([198, 51, 100, 1]); - pub const ADDR_2B: Ipv4Address = Ipv4Address([198, 51, 100, 21]); + pub const ADDR_2A: Ipv4Address = Ipv4Address::new(198, 51, 100, 1); + pub const ADDR_2B: Ipv4Address = Ipv4Address::new(198, 51, 100, 21); pub fn cidr_2() -> Ipv4Cidr { - Ipv4Cidr::new(Ipv4Address([198, 51, 100, 0]), 24) + Ipv4Cidr::new(Ipv4Address::new(198, 51, 100, 0), 24) } } diff --git a/src/parsers.rs b/src/parsers.rs index 16419ab5c..4e690b02f 100644 --- a/src/parsers.rs +++ b/src/parsers.rs @@ -10,7 +10,7 @@ use core::str::FromStr; use crate::wire::EthernetAddress; use crate::wire::{IpAddress, IpCidr, IpEndpoint}; #[cfg(feature = "proto-ipv4")] -use crate::wire::{Ipv4Address, Ipv4Cidr}; +use crate::wire::{Ipv4Address, Ipv4AddressExt, Ipv4Cidr}; #[cfg(feature = "proto-ipv6")] use crate::wire::{Ipv6Address, Ipv6Cidr}; @@ -294,7 +294,7 @@ impl<'a> Parser<'a> { #[cfg(feature = "proto-ipv4")] fn accept_ipv4(&mut self) -> Result { let octets = self.accept_ipv4_octets()?; - Ok(Ipv4Address(octets)) + Ok(Ipv4Address::from_bytes(&octets)) } fn accept_ip(&mut self) -> Result { @@ -383,16 +383,6 @@ impl FromStr for EthernetAddress { } } -#[cfg(feature = "proto-ipv4")] -impl FromStr for Ipv4Address { - type Err = (); - - /// Parse a string representation of an IPv4 address. - fn from_str(s: &str) -> Result { - Parser::new(s).until_eof(|p| p.accept_ipv4()) - } -} - #[cfg(feature = "proto-ipv6")] impl FromStr for Ipv6Address { type Err = (); @@ -526,26 +516,6 @@ mod test { assert_eq!(EthernetAddress::from_str("02:00:00:00:00:0x"), Err(())); } - #[test] - #[cfg(feature = "proto-ipv4")] - fn test_ipv4() { - assert_eq!(Ipv4Address::from_str(""), Err(())); - assert_eq!( - Ipv4Address::from_str("1.2.3.4"), - Ok(Ipv4Address([1, 2, 3, 4])) - ); - assert_eq!( - Ipv4Address::from_str("001.2.3.4"), - Ok(Ipv4Address([1, 2, 3, 4])) - ); - assert_eq!(Ipv4Address::from_str("0001.2.3.4"), Err(())); - assert_eq!(Ipv4Address::from_str("999.2.3.4"), Err(())); - assert_eq!(Ipv4Address::from_str("1.2.3.4.5"), Err(())); - assert_eq!(Ipv4Address::from_str("1.2.3"), Err(())); - assert_eq!(Ipv4Address::from_str("1.2.3."), Err(())); - assert_eq!(Ipv4Address::from_str("1.2.3.4."), Err(())); - } - #[test] #[cfg(feature = "proto-ipv6")] fn test_ipv6() { @@ -630,7 +600,7 @@ mod test { assert_eq!(IpAddress::from_str(""), Err(())); assert_eq!( IpAddress::from_str("1.2.3.4"), - Ok(IpAddress::Ipv4(Ipv4Address([1, 2, 3, 4]))) + Ok(IpAddress::Ipv4(Ipv4Address::new(1, 2, 3, 4))) ); assert_eq!(IpAddress::from_str("x"), Err(())); } @@ -654,19 +624,19 @@ mod test { let tests = [ ( "127.0.0.1/8", - Ok(Ipv4Cidr::new(Ipv4Address([127, 0, 0, 1]), 8u8)), + Ok(Ipv4Cidr::new(Ipv4Address::new(127, 0, 0, 1), 8u8)), ), ( "192.168.1.1/24", - Ok(Ipv4Cidr::new(Ipv4Address([192, 168, 1, 1]), 24u8)), + Ok(Ipv4Cidr::new(Ipv4Address::new(192, 168, 1, 1), 24u8)), ), ( "8.8.8.8/32", - Ok(Ipv4Cidr::new(Ipv4Address([8, 8, 8, 8]), 32u8)), + Ok(Ipv4Cidr::new(Ipv4Address::new(8, 8, 8, 8), 32u8)), ), ( "8.8.8.8/0", - Ok(Ipv4Cidr::new(Ipv4Address([8, 8, 8, 8]), 0u8)), + Ok(Ipv4Cidr::new(Ipv4Address::new(8, 8, 8, 8), 0u8)), ), ("", Err(())), ("1", Err(())), diff --git a/src/socket/dhcpv4.rs b/src/socket/dhcpv4.rs index b1b3cb583..a7673ae62 100644 --- a/src/socket/dhcpv4.rs +++ b/src/socket/dhcpv4.rs @@ -5,8 +5,9 @@ use crate::iface::Context; use crate::time::{Duration, Instant}; use crate::wire::dhcpv4::field as dhcpv4_field; use crate::wire::{ - DhcpMessageType, DhcpPacket, DhcpRepr, IpAddress, IpProtocol, Ipv4Address, Ipv4Cidr, Ipv4Repr, - UdpRepr, DHCP_CLIENT_PORT, DHCP_MAX_DNS_SERVER_COUNT, DHCP_SERVER_PORT, UDP_HEADER_LEN, + DhcpMessageType, DhcpPacket, DhcpRepr, IpAddress, IpProtocol, Ipv4Address, Ipv4AddressExt, + Ipv4Cidr, Ipv4Repr, UdpRepr, DHCP_CLIENT_PORT, DHCP_MAX_DNS_SERVER_COUNT, DHCP_SERVER_PORT, + UDP_HEADER_LEN, }; use crate::wire::{DhcpOption, HardwareAddress}; use heapless::Vec; @@ -880,14 +881,14 @@ mod test { const TXID: u32 = 0x12345678; - const MY_IP: Ipv4Address = Ipv4Address([192, 168, 1, 42]); - const SERVER_IP: Ipv4Address = Ipv4Address([192, 168, 1, 1]); - const DNS_IP_1: Ipv4Address = Ipv4Address([1, 1, 1, 1]); - const DNS_IP_2: Ipv4Address = Ipv4Address([1, 1, 1, 2]); - const DNS_IP_3: Ipv4Address = Ipv4Address([1, 1, 1, 3]); + const MY_IP: Ipv4Address = Ipv4Address::new(192, 168, 1, 42); + const SERVER_IP: Ipv4Address = Ipv4Address::new(192, 168, 1, 1); + const DNS_IP_1: Ipv4Address = Ipv4Address::new(1, 1, 1, 1); + const DNS_IP_2: Ipv4Address = Ipv4Address::new(1, 1, 1, 2); + const DNS_IP_3: Ipv4Address = Ipv4Address::new(1, 1, 1, 3); const DNS_IPS: &[Ipv4Address] = &[DNS_IP_1, DNS_IP_2, DNS_IP_3]; - const MASK_24: Ipv4Address = Ipv4Address([255, 255, 255, 0]); + const MASK_24: Ipv4Address = Ipv4Address::new(255, 255, 255, 0); const MY_MAC: EthernetAddress = EthernetAddress([0x02, 0x02, 0x02, 0x02, 0x02, 0x02]); diff --git a/src/socket/dns.rs b/src/socket/dns.rs index abb0f0caa..9d09d8f0c 100644 --- a/src/socket/dns.rs +++ b/src/socket/dns.rs @@ -28,7 +28,7 @@ const MDNS_IPV6_ADDR: IpAddress = IpAddress::Ipv6(crate::wire::Ipv6Address([ #[cfg(feature = "proto-ipv4")] #[allow(unused)] -const MDNS_IPV4_ADDR: IpAddress = IpAddress::Ipv4(crate::wire::Ipv4Address([224, 0, 0, 251])); +const MDNS_IPV4_ADDR: IpAddress = IpAddress::Ipv4(crate::wire::Ipv4Address::new(224, 0, 0, 251)); /// Error returned by [`Socket::start_query`] #[derive(Debug, PartialEq, Eq, Clone, Copy)] diff --git a/src/socket/icmp.rs b/src/socket/icmp.rs index 85a34b1f1..c5080a152 100644 --- a/src/socket/icmp.rs +++ b/src/socket/icmp.rs @@ -678,8 +678,8 @@ mod test_ipv4 { use super::tests_common::*; use crate::wire::{Icmpv4DstUnreachable, IpEndpoint, Ipv4Address}; - const REMOTE_IPV4: Ipv4Address = Ipv4Address([192, 168, 1, 2]); - const LOCAL_IPV4: Ipv4Address = Ipv4Address([192, 168, 1, 1]); + const REMOTE_IPV4: Ipv4Address = Ipv4Address::new(192, 168, 1, 2); + const LOCAL_IPV4: Ipv4Address = Ipv4Address::new(192, 168, 1, 1); const LOCAL_END_V4: IpEndpoint = IpEndpoint { addr: IpAddress::Ipv4(LOCAL_IPV4), port: LOCAL_PORT, @@ -711,7 +711,7 @@ mod test_ipv4 { fn test_send_unaddressable() { let mut socket = socket(buffer(0), buffer(1)); assert_eq!( - socket.send_slice(b"abcdef", IpAddress::Ipv4(Ipv4Address::default())), + socket.send_slice(b"abcdef", IpAddress::Ipv4(Ipv4Address::new(0, 0, 0, 0))), Err(SendError::Unaddressable) ); assert_eq!(socket.send_slice(b"abcdef", REMOTE_IPV4.into()), Ok(())); diff --git a/src/socket/raw.rs b/src/socket/raw.rs index bb3a204ad..b86063865 100644 --- a/src/socket/raw.rs +++ b/src/socket/raw.rs @@ -494,8 +494,8 @@ mod test { pub const IP_PROTO: u8 = 63; pub const HEADER_REPR: IpRepr = IpRepr::Ipv4(Ipv4Repr { - src_addr: Ipv4Address([10, 0, 0, 1]), - dst_addr: Ipv4Address([10, 0, 0, 2]), + src_addr: Ipv4Address::new(10, 0, 0, 1), + dst_addr: Ipv4Address::new(10, 0, 0, 2), next_header: IpProtocol::Unknown(IP_PROTO), payload_len: 4, hop_limit: 64, diff --git a/src/socket/tcp.rs b/src/socket/tcp.rs index 55620c4cb..af13b98a1 100644 --- a/src/socket/tcp.rs +++ b/src/socket/tcp.rs @@ -2584,14 +2584,6 @@ mod test { addr: None, port: LOCAL_PORT, }; - const LOCAL_END: IpEndpoint = IpEndpoint { - addr: LOCAL_ADDR.into_address(), - port: LOCAL_PORT, - }; - const REMOTE_END: IpEndpoint = IpEndpoint { - addr: REMOTE_ADDR.into_address(), - port: REMOTE_PORT, - }; const TUPLE: Tuple = Tuple { local: LOCAL_END, remote: REMOTE_END, @@ -2605,11 +2597,20 @@ mod test { use crate::wire::Ipv4Repr as IpvXRepr; use IpRepr::Ipv4 as IpReprIpvX; - const LOCAL_ADDR: IpvXAddress = IpvXAddress([192, 168, 1, 1]); - const REMOTE_ADDR: IpvXAddress = IpvXAddress([192, 168, 1, 2]); - const OTHER_ADDR: IpvXAddress = IpvXAddress([192, 168, 1, 3]); + const LOCAL_ADDR: IpvXAddress = IpvXAddress::new(192, 168, 1, 1); + const REMOTE_ADDR: IpvXAddress = IpvXAddress::new(192, 168, 1, 2); + const OTHER_ADDR: IpvXAddress = IpvXAddress::new(192, 168, 1, 3); const BASE_MSS: u16 = 1460; + + const LOCAL_END: IpEndpoint = IpEndpoint { + addr: IpAddress::Ipv4(LOCAL_ADDR), + port: LOCAL_PORT, + }; + const REMOTE_END: IpEndpoint = IpEndpoint { + addr: IpAddress::Ipv4(REMOTE_ADDR), + port: REMOTE_PORT, + }; } else { use crate::wire::Ipv6Address as IpvXAddress; use crate::wire::Ipv6Repr as IpvXRepr; @@ -2626,6 +2627,15 @@ mod test { ]); const BASE_MSS: u16 = 1440; + + const LOCAL_END: IpEndpoint = IpEndpoint { + addr: IpAddress::Ipv6(LOCAL_ADDR), + port: LOCAL_PORT, + }; + const REMOTE_END: IpEndpoint = IpEndpoint { + addr: IpAddress::Ipv6(REMOTE_ADDR), + port: REMOTE_PORT, + }; } } diff --git a/src/socket/udp.rs b/src/socket/udp.rs index 269043ef7..292d0c13e 100644 --- a/src/socket/udp.rs +++ b/src/socket/udp.rs @@ -619,9 +619,18 @@ mod test { use crate::wire::Ipv4Repr as IpvXRepr; use IpRepr::Ipv4 as IpReprIpvX; - const LOCAL_ADDR: IpvXAddress = IpvXAddress([192, 168, 1, 1]); - const REMOTE_ADDR: IpvXAddress = IpvXAddress([192, 168, 1, 2]); - const OTHER_ADDR: IpvXAddress = IpvXAddress([192, 168, 1, 3]); + const LOCAL_ADDR: IpvXAddress = IpvXAddress::new(192, 168, 1, 1); + const REMOTE_ADDR: IpvXAddress = IpvXAddress::new(192, 168, 1, 2); + const OTHER_ADDR: IpvXAddress = IpvXAddress::new(192, 168, 1, 3); + + const LOCAL_END: IpEndpoint = IpEndpoint { + addr: IpAddress::Ipv4(LOCAL_ADDR), + port: LOCAL_PORT, + }; + const REMOTE_END: IpEndpoint = IpEndpoint { + addr: IpAddress::Ipv4(REMOTE_ADDR), + port: REMOTE_PORT, + }; } else { use crate::wire::Ipv6Address as IpvXAddress; use crate::wire::Ipv6Repr as IpvXRepr; @@ -636,17 +645,18 @@ mod test { const OTHER_ADDR: IpvXAddress = IpvXAddress([ 0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, ]); + + const LOCAL_END: IpEndpoint = IpEndpoint { + addr: IpAddress::Ipv6(LOCAL_ADDR), + port: LOCAL_PORT, + }; + const REMOTE_END: IpEndpoint = IpEndpoint { + addr: IpAddress::Ipv6(REMOTE_ADDR), + port: REMOTE_PORT, + }; } } - pub const LOCAL_END: IpEndpoint = IpEndpoint { - addr: LOCAL_ADDR.into_address(), - port: LOCAL_PORT, - }; - pub const REMOTE_END: IpEndpoint = IpEndpoint { - addr: REMOTE_ADDR.into_address(), - port: REMOTE_PORT, - }; fn remote_metadata_with_local() -> UdpMetadata { // Would be great as a const once we have const `.into()`. UdpMetadata { diff --git a/src/wire/arp.rs b/src/wire/arp.rs index c7d0b8add..8129c59da 100644 --- a/src/wire/arp.rs +++ b/src/wire/arp.rs @@ -2,6 +2,7 @@ use byteorder::{ByteOrder, NetworkEndian}; use core::fmt; use super::{Error, Result}; +use super::{EthernetAddress, Ipv4Address, Ipv4AddressExt}; pub use super::EthernetProtocol as Protocol; @@ -250,8 +251,6 @@ impl> AsRef<[u8]> for Packet { } } -use crate::wire::{EthernetAddress, Ipv4Address}; - /// A high-level representation of an Address Resolution Protocol packet. #[derive(Debug, PartialEq, Eq, Clone, Copy)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] @@ -313,9 +312,9 @@ impl Repr { packet.set_protocol_len(4); packet.set_operation(operation); packet.set_source_hardware_addr(source_hardware_addr.as_bytes()); - packet.set_source_protocol_addr(source_protocol_addr.as_bytes()); + packet.set_source_protocol_addr(&source_protocol_addr.octets()); packet.set_target_hardware_addr(target_hardware_addr.as_bytes()); - packet.set_target_protocol_addr(target_protocol_addr.as_bytes()); + packet.set_target_protocol_addr(&target_protocol_addr.octets()); } } } diff --git a/src/wire/dhcpv4.rs b/src/wire/dhcpv4.rs index 3656c747d..87ace13e4 100644 --- a/src/wire/dhcpv4.rs +++ b/src/wire/dhcpv4.rs @@ -7,7 +7,7 @@ use heapless::Vec; use super::{Error, Result}; use crate::wire::arp::Hardware; -use crate::wire::{EthernetAddress, Ipv4Address}; +use crate::wire::{EthernetAddress, Ipv4Address, Ipv4AddressExt}; pub const SERVER_PORT: u16 = 67; pub const CLIENT_PORT: u16 = 68; @@ -503,25 +503,25 @@ impl + AsMut<[u8]>> Packet { /// and can respond to ARP requests”. pub fn set_client_ip(&mut self, value: Ipv4Address) { let field = &mut self.buffer.as_mut()[field::CIADDR]; - field.copy_from_slice(value.as_bytes()); + field.copy_from_slice(&value.octets()); } /// Sets the value of the `yiaddr` field. pub fn set_your_ip(&mut self, value: Ipv4Address) { let field = &mut self.buffer.as_mut()[field::YIADDR]; - field.copy_from_slice(value.as_bytes()); + field.copy_from_slice(&value.octets()); } /// Sets the value of the `siaddr` field. pub fn set_server_ip(&mut self, value: Ipv4Address) { let field = &mut self.buffer.as_mut()[field::SIADDR]; - field.copy_from_slice(value.as_bytes()); + field.copy_from_slice(&value.octets()); } /// Sets the value of the `giaddr` field. pub fn set_relay_agent_ip(&mut self, value: Ipv4Address) { let field = &mut self.buffer.as_mut()[field::GIADDR]; - field.copy_from_slice(value.as_bytes()); + field.copy_from_slice(&value.octets()); } /// Sets the flags to the specified value. @@ -881,26 +881,26 @@ impl<'a> Repr<'a> { if let Some(val) = &self.server_identifier { options.emit(DhcpOption { kind: field::OPT_SERVER_IDENTIFIER, - data: val.as_bytes(), + data: &val.octets(), })?; } if let Some(val) = &self.router { options.emit(DhcpOption { kind: field::OPT_ROUTER, - data: val.as_bytes(), + data: &val.octets(), })?; } if let Some(val) = &self.subnet_mask { options.emit(DhcpOption { kind: field::OPT_SUBNET_MASK, - data: val.as_bytes(), + data: &val.octets(), })?; } if let Some(val) = &self.requested_ip { options.emit(DhcpOption { kind: field::OPT_REQUESTED_IP, - data: val.as_bytes(), + data: &val.octets(), })?; } if let Some(val) = &self.max_size { @@ -930,7 +930,7 @@ impl<'a> Repr<'a> { .iter() .enumerate() .inspect(|(i, ip)| { - servers[(i * IP_SIZE)..((i + 1) * IP_SIZE)].copy_from_slice(ip.as_bytes()); + servers[(i * IP_SIZE)..((i + 1) * IP_SIZE)].copy_from_slice(&ip.octets()); }) .count() * IP_SIZE; @@ -1029,7 +1029,7 @@ mod test { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ]; - const IP_NULL: Ipv4Address = Ipv4Address([0, 0, 0, 0]); + const IP_NULL: Ipv4Address = Ipv4Address::new(0, 0, 0, 0); const CLIENT_MAC: EthernetAddress = EthernetAddress([0x0, 0x0b, 0x82, 0x01, 0xfc, 0x42]); const DHCP_SIZE: u16 = 1500; @@ -1236,9 +1236,9 @@ mod test { let mut repr = offer_repr(); repr.dns_servers = Some( Vec::from_slice(&[ - Ipv4Address([163, 1, 74, 6]), - Ipv4Address([163, 1, 74, 7]), - Ipv4Address([163, 1, 74, 3]), + Ipv4Address::new(163, 1, 74, 6), + Ipv4Address::new(163, 1, 74, 7), + Ipv4Address::new(163, 1, 74, 3), ]) .unwrap(), ); @@ -1255,9 +1255,9 @@ mod test { repr_parsed.dns_servers, Some( Vec::from_slice(&[ - Ipv4Address([163, 1, 74, 6]), - Ipv4Address([163, 1, 74, 7]), - Ipv4Address([163, 1, 74, 3]), + Ipv4Address::new(163, 1, 74, 6), + Ipv4Address::new(163, 1, 74, 7), + Ipv4Address::new(163, 1, 74, 3), ]) .unwrap() ) @@ -1295,9 +1295,9 @@ mod test { repr.dns_servers, Some( Vec::from_slice(&[ - Ipv4Address([163, 1, 74, 6]), - Ipv4Address([163, 1, 74, 7]), - Ipv4Address([163, 1, 74, 3]) + Ipv4Address::new(163, 1, 74, 6), + Ipv4Address::new(163, 1, 74, 7), + Ipv4Address::new(163, 1, 74, 3) ]) .unwrap() ) diff --git a/src/wire/dns.rs b/src/wire/dns.rs index 147f4a2f9..e5734d82a 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-ipv4")] -use crate::wire::Ipv4Address; #[cfg(feature = "proto-ipv6")] use crate::wire::Ipv6Address; +#[cfg(feature = "proto-ipv4")] +use crate::wire::{Ipv4Address, Ipv4AddressExt}; enum_with_unknown! { /// DNS OpCodes diff --git a/src/wire/igmp.rs b/src/wire/igmp.rs index ac1f48d2d..ba282bab4 100644 --- a/src/wire/igmp.rs +++ b/src/wire/igmp.rs @@ -5,7 +5,7 @@ use super::{Error, Result}; use crate::time::Duration; use crate::wire::ip::checksum; -use crate::wire::Ipv4Address; +use crate::wire::{Ipv4Address, Ipv4AddressExt}; enum_with_unknown! { /// Internet Group Management Protocol v1/v2 message version/type. @@ -156,7 +156,7 @@ impl + AsMut<[u8]>> Packet { #[inline] pub fn set_group_address(&mut self, addr: Ipv4Address) { let data = self.buffer.as_mut(); - data[field::GROUP_ADDRESS].copy_from_slice(addr.as_bytes()); + data[field::GROUP_ADDRESS].copy_from_slice(&addr.octets()); } /// Compute and fill in the header checksum. diff --git a/src/wire/ip.rs b/src/wire/ip.rs index 853970811..86dea66dd 100644 --- a/src/wire/ip.rs +++ b/src/wire/ip.rs @@ -4,7 +4,7 @@ use core::fmt; use super::{Error, Result}; use crate::phy::ChecksumCapabilities; #[cfg(feature = "proto-ipv4")] -use crate::wire::{Ipv4Address, Ipv4Cidr, Ipv4Packet, Ipv4Repr}; +use crate::wire::{Ipv4Address, Ipv4AddressExt, Ipv4Cidr, Ipv4Packet, Ipv4Repr}; #[cfg(feature = "proto-ipv6")] use crate::wire::{Ipv6Address, Ipv6Cidr, Ipv6Packet, Ipv6Repr}; @@ -127,16 +127,6 @@ impl Address { } } - /// Return an address as a sequence of octets, in big-endian. - pub const fn as_bytes(&self) -> &[u8] { - match self { - #[cfg(feature = "proto-ipv4")] - Address::Ipv4(addr) => addr.as_bytes(), - #[cfg(feature = "proto-ipv6")] - Address::Ipv6(addr) => addr.as_bytes(), - } - } - /// Query whether the address is a valid unicast address. pub fn is_unicast(&self) -> bool { match self { @@ -193,8 +183,8 @@ impl Address { impl From<::core::net::IpAddr> for Address { fn from(x: ::core::net::IpAddr) -> Address { match x { - ::core::net::IpAddr::V4(ipv4) => Address::Ipv4(ipv4.into()), - ::core::net::IpAddr::V6(ipv6) => Address::Ipv6(ipv6.into()), + ::core::net::IpAddr::V4(ipv4) => Address::Ipv4(ipv4), + ::core::net::IpAddr::V6(ipv6) => Address::Ipv6(ipv6), } } } @@ -224,13 +214,6 @@ impl From<::core::net::Ipv6Addr> for Address { } } -#[cfg(feature = "proto-ipv4")] -impl From for Address { - fn from(addr: Ipv4Address) -> Self { - Address::Ipv4(addr) - } -} - #[cfg(feature = "proto-ipv6")] impl From for Address { fn from(addr: Ipv6Address) -> Self { @@ -758,8 +741,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/ipv4.rs b/src/wire/ipv4.rs index d38612fda..82d2a6d49 100644 --- a/src/wire/ipv4.rs +++ b/src/wire/ipv4.rs @@ -26,6 +26,18 @@ pub const MIN_MTU: usize = 576; /// [RFC 8200 § 2]: https://www.rfc-editor.org/rfc/rfc791#section-3.2 pub const ADDR_SIZE: usize = 4; +/// An unspecified address. +pub const UNSPECIFIED: Address = Address::new(0, 0, 0, 0); + +/// The broadcast address. +pub const BROADCAST: Address = Address::new(0xff, 0xff, 0xff, 0xff); + +/// All multicast-capable nodes +pub const MULTICAST_ALL_SYSTEMS: Address = Address::new(224, 0, 0, 1); + +/// All multicast-capable routers +pub const MULTICAST_ALL_ROUTERS: Address = Address::new(224, 0, 0, 2); + #[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Clone, Copy)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct Key { @@ -35,89 +47,42 @@ pub struct Key { protocol: Protocol, } -/// A four-octet IPv4 address. -#[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Default)] -pub struct Address(pub [u8; ADDR_SIZE]); - -impl Address { - /// An unspecified address. - pub const UNSPECIFIED: Address = Address([0x00; ADDR_SIZE]); - - /// The broadcast address. - pub const BROADCAST: Address = Address([0xff; ADDR_SIZE]); - - /// All multicast-capable nodes - pub const MULTICAST_ALL_SYSTEMS: Address = Address([224, 0, 0, 1]); - - /// All multicast-capable routers - pub const MULTICAST_ALL_ROUTERS: Address = Address([224, 0, 0, 2]); - - /// Construct an IPv4 address from parts. - pub const fn new(a0: u8, a1: u8, a2: u8, a3: u8) -> Address { - Address([a0, a1, a2, a3]) - } +pub use core::net::Ipv4Addr as Address; +pub(crate) trait AddressExt { /// Construct an IPv4 address from a sequence of octets, in big-endian. /// /// # Panics /// The function panics if `data` is not four octets long. - pub fn from_bytes(data: &[u8]) -> Address { - let mut bytes = [0; ADDR_SIZE]; - bytes.copy_from_slice(data); - Address(bytes) - } - - /// Return an IPv4 address as a sequence of octets, in big-endian. - pub const fn as_bytes(&self) -> &[u8] { - &self.0 - } + fn from_bytes(data: &[u8]) -> Self; /// Query whether the address is an unicast address. - pub fn is_unicast(&self) -> bool { - !(self.is_broadcast() || self.is_multicast() || self.is_unspecified()) - } + fn is_unicast(&self) -> bool; - /// Query whether the address is the broadcast address. - pub fn is_broadcast(&self) -> bool { - self.0[0..4] == [255; ADDR_SIZE] - } - - /// Query whether the address is a multicast address. - pub const fn is_multicast(&self) -> bool { - self.0[0] & 0xf0 == 224 - } - - /// Query whether the address falls into the "unspecified" range. - pub const fn is_unspecified(&self) -> bool { - self.0[0] == 0 - } - - /// Query whether the address falls into the "link-local" range. - pub fn is_link_local(&self) -> bool { - self.0[0..2] == [169, 254] - } + /// 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; +} - /// Query whether the address falls into the "loopback" range. - pub const fn is_loopback(&self) -> bool { - self.0[0] == 127 +impl AddressExt for Address { + fn from_bytes(data: &[u8]) -> Address { + let mut bytes = [0; ADDR_SIZE]; + bytes.copy_from_slice(data); + Address::from_bits(u32::from_be_bytes(bytes)) } - /// Convert to an `IpAddress`. - /// - /// Same as `.into()`, but works in `const`. - pub const fn into_address(self) -> super::IpAddress { - super::IpAddress::Ipv4(self) + /// Query whether the address is an unicast address. + fn is_unicast(&self) -> bool { + !(self.is_broadcast() || self.is_multicast() || self.is_unspecified()) } - /// 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 { @@ -136,42 +101,9 @@ impl Address { } } -impl From<::core::net::Ipv4Addr> for Address { - fn from(x: ::core::net::Ipv4Addr) -> Address { - Address(x.octets()) - } -} - -impl From
for ::core::net::Ipv4Addr { - fn from(Address(x): Address) -> ::core::net::Ipv4Addr { - x.into() - } -} - -impl fmt::Display for Address { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let bytes = self.0; - write!(f, "{}.{}.{}.{}", bytes[0], bytes[1], bytes[2], bytes[3]) - } -} - -#[cfg(feature = "defmt")] -impl defmt::Format for Address { - fn format(&self, f: defmt::Formatter) { - defmt::write!( - f, - "{=u8}.{=u8}.{=u8}.{=u8}", - self.0[0], - self.0[1], - self.0[2], - self.0[3] - ) - } -} - /// A specification of an IPv4 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, @@ -192,7 +124,7 @@ impl Cidr { /// Create an IPv4 CIDR block from the given address and network mask. pub fn from_netmask(addr: Address, netmask: Address) -> Result { - let netmask = NetworkEndian::read_u32(&netmask.0[..]); + let netmask = netmask.to_bits(); if netmask.leading_zeros() == 0 && netmask.trailing_zeros() == netmask.count_zeros() { Ok(Cidr { address: addr, @@ -216,18 +148,11 @@ impl Cidr { /// Return the network mask of this IPv4 CIDR. pub const fn netmask(&self) -> Address { if self.prefix_len == 0 { - return Address([0, 0, 0, 0]); + return Address::new(0, 0, 0, 0); } let number = 0xffffffffu32 << (32 - self.prefix_len); - let data = [ - ((number >> 24) & 0xff) as u8, - ((number >> 16) & 0xff) as u8, - ((number >> 8) & 0xff) as u8, - ((number >> 0) & 0xff) as u8, - ]; - - Address(data) + Address::from_bits(number) } /// Return the broadcast address of this IPv4 CIDR. @@ -238,29 +163,15 @@ impl Cidr { return None; } - let network_number = NetworkEndian::read_u32(&network.address.0[..]); + let network_number = network.address.to_bits(); let number = network_number | 0xffffffffu32 >> network.prefix_len; - let data = [ - ((number >> 24) & 0xff) as u8, - ((number >> 16) & 0xff) as u8, - ((number >> 8) & 0xff) as u8, - ((number >> 0) & 0xff) as u8, - ]; - - Some(Address(data)) + Some(Address::from_bits(number)) } /// Return the network block of this IPv4 CIDR. pub const fn network(&self) -> Cidr { - let mask = self.netmask().0; - let network = [ - self.address.0[0] & mask[0], - self.address.0[1] & mask[1], - self.address.0[2] & mask[2], - self.address.0[3] & mask[3], - ]; Cidr { - address: Address(network), + address: Address::from_bits(self.address.to_bits() & self.netmask().to_bits()), prefix_len: self.prefix_len, } } @@ -268,15 +179,8 @@ impl Cidr { /// Query whether the subnetwork described by this IPv4 CIDR block contains /// the given address. pub fn contains_addr(&self, addr: &Address) -> bool { - // right shift by 32 is not legal - if self.prefix_len == 0 { - return true; - } - - let shift = 32 - self.prefix_len; - let self_prefix = NetworkEndian::read_u32(self.address.as_bytes()) >> shift; - let addr_prefix = NetworkEndian::read_u32(addr.as_bytes()) >> shift; - self_prefix == addr_prefix + self.address.to_bits() & self.netmask().to_bits() + == addr.to_bits() & self.netmask().to_bits() } /// Query whether the subnetwork described by this IPv4 CIDR block contains @@ -602,14 +506,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()) } /// Compute and fill in the header checksum. @@ -821,13 +725,13 @@ pub(crate) mod test { use super::*; #[allow(unused)] - pub(crate) const MOCK_IP_ADDR_1: Address = Address([192, 168, 1, 1]); + pub(crate) const MOCK_IP_ADDR_1: Address = Address::new(192, 168, 1, 1); #[allow(unused)] - pub(crate) const MOCK_IP_ADDR_2: Address = Address([192, 168, 1, 2]); + pub(crate) const MOCK_IP_ADDR_2: Address = Address::new(192, 168, 1, 2); #[allow(unused)] - pub(crate) const MOCK_IP_ADDR_3: Address = Address([192, 168, 1, 3]); + pub(crate) const MOCK_IP_ADDR_3: Address = Address::new(192, 168, 1, 3); #[allow(unused)] - pub(crate) const MOCK_IP_ADDR_4: Address = Address([192, 168, 1, 4]); + pub(crate) const MOCK_IP_ADDR_4: Address = Address::new(192, 168, 1, 4); #[allow(unused)] pub(crate) const MOCK_UNSPECIFIED: Address = Address::UNSPECIFIED; @@ -853,8 +757,8 @@ pub(crate) mod test { assert_eq!(packet.hop_limit(), 0x1a); assert_eq!(packet.next_header(), Protocol::Icmp); assert_eq!(packet.checksum(), 0xd56e); - assert_eq!(packet.src_addr(), Address([0x11, 0x12, 0x13, 0x14])); - assert_eq!(packet.dst_addr(), Address([0x21, 0x22, 0x23, 0x24])); + assert_eq!(packet.src_addr(), Address::new(0x11, 0x12, 0x13, 0x14)); + assert_eq!(packet.dst_addr(), Address::new(0x21, 0x22, 0x23, 0x24)); assert!(packet.verify_checksum()); assert_eq!(packet.payload(), &PAYLOAD_BYTES[..]); } @@ -875,8 +779,8 @@ pub(crate) mod test { packet.set_frag_offset(0x203 * 8); packet.set_hop_limit(0x1a); packet.set_next_header(Protocol::Icmp); - packet.set_src_addr(Address([0x11, 0x12, 0x13, 0x14])); - packet.set_dst_addr(Address([0x21, 0x22, 0x23, 0x24])); + packet.set_src_addr(Address::new(0x11, 0x12, 0x13, 0x14)); + packet.set_dst_addr(Address::new(0x21, 0x22, 0x23, 0x24)); packet.fill_checksum(); packet.payload_mut().copy_from_slice(&PAYLOAD_BYTES[..]); assert_eq!(&*packet.into_inner(), &PACKET_BYTES[..]); @@ -916,8 +820,8 @@ pub(crate) mod test { const fn packet_repr() -> Repr { Repr { - src_addr: Address([0x11, 0x12, 0x13, 0x14]), - dst_addr: Address([0x21, 0x22, 0x23, 0x24]), + src_addr: Address::new(0x11, 0x12, 0x13, 0x14), + dst_addr: Address::new(0x21, 0x22, 0x23, 0x24), next_header: Protocol::Icmp, payload_len: 4, hop_limit: 64, @@ -1043,124 +947,135 @@ pub(crate) mod test { #[test] fn test_cidr_from_netmask() { - assert!(Cidr::from_netmask(Address([0, 0, 0, 0]), Address([1, 0, 2, 0])).is_err()); - assert!(Cidr::from_netmask(Address([0, 0, 0, 0]), Address([0, 0, 0, 0])).is_err()); + assert!(Cidr::from_netmask(Address::new(0, 0, 0, 0), Address::new(1, 0, 2, 0)).is_err()); + assert!(Cidr::from_netmask(Address::new(0, 0, 0, 0), Address::new(0, 0, 0, 0)).is_err()); assert_eq!( - Cidr::from_netmask(Address([0, 0, 0, 1]), Address([255, 255, 255, 0])).unwrap(), - Cidr::new(Address([0, 0, 0, 1]), 24) + Cidr::from_netmask(Address::new(0, 0, 0, 1), Address::new(255, 255, 255, 0)).unwrap(), + Cidr::new(Address::new(0, 0, 0, 1), 24) ); assert_eq!( - Cidr::from_netmask(Address([192, 168, 0, 1]), Address([255, 255, 0, 0])).unwrap(), - Cidr::new(Address([192, 168, 0, 1]), 16) + Cidr::from_netmask(Address::new(192, 168, 0, 1), Address::new(255, 255, 0, 0)).unwrap(), + Cidr::new(Address::new(192, 168, 0, 1), 16) ); assert_eq!( - Cidr::from_netmask(Address([172, 16, 0, 1]), Address([255, 240, 0, 0])).unwrap(), - Cidr::new(Address([172, 16, 0, 1]), 12) + Cidr::from_netmask(Address::new(172, 16, 0, 1), Address::new(255, 240, 0, 0)).unwrap(), + Cidr::new(Address::new(172, 16, 0, 1), 12) ); assert_eq!( - Cidr::from_netmask(Address([255, 255, 255, 1]), Address([255, 255, 255, 0])).unwrap(), - Cidr::new(Address([255, 255, 255, 1]), 24) + Cidr::from_netmask( + Address::new(255, 255, 255, 1), + Address::new(255, 255, 255, 0) + ) + .unwrap(), + Cidr::new(Address::new(255, 255, 255, 1), 24) ); assert_eq!( - Cidr::from_netmask(Address([255, 255, 255, 255]), Address([255, 255, 255, 255])) - .unwrap(), - Cidr::new(Address([255, 255, 255, 255]), 32) + Cidr::from_netmask( + Address::new(255, 255, 255, 255), + Address::new(255, 255, 255, 255) + ) + .unwrap(), + Cidr::new(Address::new(255, 255, 255, 255), 32) ); } #[test] fn test_cidr_netmask() { assert_eq!( - Cidr::new(Address([0, 0, 0, 0]), 0).netmask(), - Address([0, 0, 0, 0]) + Cidr::new(Address::new(0, 0, 0, 0), 0).netmask(), + Address::new(0, 0, 0, 0) ); assert_eq!( - Cidr::new(Address([0, 0, 0, 1]), 24).netmask(), - Address([255, 255, 255, 0]) + Cidr::new(Address::new(0, 0, 0, 1), 24).netmask(), + Address::new(255, 255, 255, 0) ); assert_eq!( - Cidr::new(Address([0, 0, 0, 0]), 32).netmask(), - Address([255, 255, 255, 255]) + Cidr::new(Address::new(0, 0, 0, 0), 32).netmask(), + Address::new(255, 255, 255, 255) ); assert_eq!( - Cidr::new(Address([127, 0, 0, 0]), 8).netmask(), - Address([255, 0, 0, 0]) + Cidr::new(Address::new(127, 0, 0, 0), 8).netmask(), + Address::new(255, 0, 0, 0) ); assert_eq!( - Cidr::new(Address([192, 168, 0, 0]), 16).netmask(), - Address([255, 255, 0, 0]) + Cidr::new(Address::new(192, 168, 0, 0), 16).netmask(), + Address::new(255, 255, 0, 0) ); assert_eq!( - Cidr::new(Address([192, 168, 1, 1]), 16).netmask(), - Address([255, 255, 0, 0]) + Cidr::new(Address::new(192, 168, 1, 1), 16).netmask(), + Address::new(255, 255, 0, 0) ); assert_eq!( - Cidr::new(Address([192, 168, 1, 1]), 17).netmask(), - Address([255, 255, 128, 0]) + Cidr::new(Address::new(192, 168, 1, 1), 17).netmask(), + Address::new(255, 255, 128, 0) ); assert_eq!( - Cidr::new(Address([172, 16, 0, 0]), 12).netmask(), - Address([255, 240, 0, 0]) + Cidr::new(Address::new(172, 16, 0, 0), 12).netmask(), + Address::new(255, 240, 0, 0) ); assert_eq!( - Cidr::new(Address([255, 255, 255, 1]), 24).netmask(), - Address([255, 255, 255, 0]) + Cidr::new(Address::new(255, 255, 255, 1), 24).netmask(), + Address::new(255, 255, 255, 0) ); assert_eq!( - Cidr::new(Address([255, 255, 255, 255]), 32).netmask(), - Address([255, 255, 255, 255]) + Cidr::new(Address::new(255, 255, 255, 255), 32).netmask(), + Address::new(255, 255, 255, 255) ); } #[test] fn test_cidr_broadcast() { assert_eq!( - Cidr::new(Address([0, 0, 0, 0]), 0).broadcast().unwrap(), - Address([255, 255, 255, 255]) + Cidr::new(Address::new(0, 0, 0, 0), 0).broadcast().unwrap(), + Address::new(255, 255, 255, 255) ); assert_eq!( - Cidr::new(Address([0, 0, 0, 1]), 24).broadcast().unwrap(), - Address([0, 0, 0, 255]) + Cidr::new(Address::new(0, 0, 0, 1), 24).broadcast().unwrap(), + Address::new(0, 0, 0, 255) ); - assert_eq!(Cidr::new(Address([0, 0, 0, 0]), 32).broadcast(), None); + assert_eq!(Cidr::new(Address::new(0, 0, 0, 0), 32).broadcast(), None); assert_eq!( - Cidr::new(Address([127, 0, 0, 0]), 8).broadcast().unwrap(), - Address([127, 255, 255, 255]) + Cidr::new(Address::new(127, 0, 0, 0), 8) + .broadcast() + .unwrap(), + Address::new(127, 255, 255, 255) ); assert_eq!( - Cidr::new(Address([192, 168, 0, 0]), 16) + Cidr::new(Address::new(192, 168, 0, 0), 16) .broadcast() .unwrap(), - Address([192, 168, 255, 255]) + Address::new(192, 168, 255, 255) ); assert_eq!( - Cidr::new(Address([192, 168, 1, 1]), 16) + Cidr::new(Address::new(192, 168, 1, 1), 16) .broadcast() .unwrap(), - Address([192, 168, 255, 255]) + Address::new(192, 168, 255, 255) ); assert_eq!( - Cidr::new(Address([192, 168, 1, 1]), 17) + Cidr::new(Address::new(192, 168, 1, 1), 17) .broadcast() .unwrap(), - Address([192, 168, 127, 255]) + Address::new(192, 168, 127, 255) ); assert_eq!( - Cidr::new(Address([172, 16, 0, 1]), 12).broadcast().unwrap(), - Address([172, 31, 255, 255]) + Cidr::new(Address::new(172, 16, 0, 1), 12) + .broadcast() + .unwrap(), + Address::new(172, 31, 255, 255) ); assert_eq!( - Cidr::new(Address([255, 255, 255, 1]), 24) + Cidr::new(Address::new(255, 255, 255, 1), 24) .broadcast() .unwrap(), - Address([255, 255, 255, 255]) + Address::new(255, 255, 255, 255) ); assert_eq!( - Cidr::new(Address([255, 255, 255, 254]), 31).broadcast(), + Cidr::new(Address::new(255, 255, 255, 254), 31).broadcast(), None ); assert_eq!( - Cidr::new(Address([255, 255, 255, 255]), 32).broadcast(), + Cidr::new(Address::new(255, 255, 255, 255), 32).broadcast(), None ); } @@ -1168,44 +1083,44 @@ pub(crate) mod test { #[test] fn test_cidr_network() { assert_eq!( - Cidr::new(Address([0, 0, 0, 0]), 0).network(), - Cidr::new(Address([0, 0, 0, 0]), 0) + Cidr::new(Address::new(0, 0, 0, 0), 0).network(), + Cidr::new(Address::new(0, 0, 0, 0), 0) ); assert_eq!( - Cidr::new(Address([0, 0, 0, 1]), 24).network(), - Cidr::new(Address([0, 0, 0, 0]), 24) + Cidr::new(Address::new(0, 0, 0, 1), 24).network(), + Cidr::new(Address::new(0, 0, 0, 0), 24) ); assert_eq!( - Cidr::new(Address([0, 0, 0, 0]), 32).network(), - Cidr::new(Address([0, 0, 0, 0]), 32) + Cidr::new(Address::new(0, 0, 0, 0), 32).network(), + Cidr::new(Address::new(0, 0, 0, 0), 32) ); assert_eq!( - Cidr::new(Address([127, 0, 0, 0]), 8).network(), - Cidr::new(Address([127, 0, 0, 0]), 8) + Cidr::new(Address::new(127, 0, 0, 0), 8).network(), + Cidr::new(Address::new(127, 0, 0, 0), 8) ); assert_eq!( - Cidr::new(Address([192, 168, 0, 0]), 16).network(), - Cidr::new(Address([192, 168, 0, 0]), 16) + Cidr::new(Address::new(192, 168, 0, 0), 16).network(), + Cidr::new(Address::new(192, 168, 0, 0), 16) ); assert_eq!( - Cidr::new(Address([192, 168, 1, 1]), 16).network(), - Cidr::new(Address([192, 168, 0, 0]), 16) + Cidr::new(Address::new(192, 168, 1, 1), 16).network(), + Cidr::new(Address::new(192, 168, 0, 0), 16) ); assert_eq!( - Cidr::new(Address([192, 168, 1, 1]), 17).network(), - Cidr::new(Address([192, 168, 0, 0]), 17) + Cidr::new(Address::new(192, 168, 1, 1), 17).network(), + Cidr::new(Address::new(192, 168, 0, 0), 17) ); assert_eq!( - Cidr::new(Address([172, 16, 0, 1]), 12).network(), - Cidr::new(Address([172, 16, 0, 0]), 12) + Cidr::new(Address::new(172, 16, 0, 1), 12).network(), + Cidr::new(Address::new(172, 16, 0, 0), 12) ); assert_eq!( - Cidr::new(Address([255, 255, 255, 1]), 24).network(), - Cidr::new(Address([255, 255, 255, 0]), 24) + Cidr::new(Address::new(255, 255, 255, 1), 24).network(), + Cidr::new(Address::new(255, 255, 255, 0), 24) ); assert_eq!( - Cidr::new(Address([255, 255, 255, 255]), 32).network(), - Cidr::new(Address([255, 255, 255, 255]), 32) + Cidr::new(Address::new(255, 255, 255, 255), 32).network(), + Cidr::new(Address::new(255, 255, 255, 255), 32) ); } } diff --git a/src/wire/ipv6.rs b/src/wire/ipv6.rs index 836643e7d..1eba39077 100644 --- a/src/wire/ipv6.rs +++ b/src/wire/ipv6.rs @@ -6,7 +6,7 @@ use core::fmt; use super::{Error, Result}; use crate::wire::ip::pretty_print_ip_payload; #[cfg(feature = "proto-ipv4")] -use crate::wire::ipv4; +use crate::wire::{Ipv4Address, Ipv4AddressExt}; pub use super::IpProtocol as Protocol; @@ -246,11 +246,9 @@ impl Address { #[cfg(feature = "proto-ipv4")] /// Convert an IPv4 mapped IPv6 address to an IPv4 address. - pub fn as_ipv4(&self) -> Option { + pub fn as_ipv4(&self) -> Option { if self.is_ipv4_mapped() { - Some(ipv4::Address::from_bytes( - &self.0[IPV4_MAPPED_PREFIX_SIZE..], - )) + Some(Ipv4Address::from_bytes(&self.0[IPV4_MAPPED_PREFIX_SIZE..])) } else { None } @@ -474,11 +472,11 @@ impl defmt::Format for Address { #[cfg(feature = "proto-ipv4")] /// Convert the given IPv4 address into a IPv4-mapped IPv6 address -impl From for Address { - fn from(address: ipv4::Address) -> Self { +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.0); + b[Self::IPV4_MAPPED_PREFIX.len()..].copy_from_slice(&address.octets()); Self(b) } } diff --git a/src/wire/mod.rs b/src/wire/mod.rs index 64ac65323..4ec8a70f1 100644 --- a/src/wire/mod.rs +++ b/src/wire/mod.rs @@ -187,9 +187,14 @@ pub use self::ip::{ #[cfg(feature = "proto-ipv4")] pub use self::ipv4::{ Address as Ipv4Address, Cidr as Ipv4Cidr, Key as Ipv4FragKey, Packet as Ipv4Packet, - Repr as Ipv4Repr, HEADER_LEN as IPV4_HEADER_LEN, MIN_MTU as IPV4_MIN_MTU, + Repr as Ipv4Repr, BROADCAST as IPV4_BROADCAST, HEADER_LEN as IPV4_HEADER_LEN, + MIN_MTU as IPV4_MIN_MTU, MULTICAST_ALL_ROUTERS as IPV4_MULTICAST_ALL_ROUTERS, + MULTICAST_ALL_SYSTEMS as IPV4_MULTICAST_ALL_SYSTEMS, UNSPECIFIED as IPV4_UNSPECIFIED, }; +#[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")] diff --git a/src/wire/tcp.rs b/src/wire/tcp.rs index e05b89db5..e064182d9 100644 --- a/src/wire/tcp.rs +++ b/src/wire/tcp.rs @@ -1192,9 +1192,9 @@ mod test { use crate::wire::Ipv4Address; #[cfg(feature = "proto-ipv4")] - const SRC_ADDR: Ipv4Address = Ipv4Address([192, 168, 1, 1]); + const SRC_ADDR: Ipv4Address = Ipv4Address::new(192, 168, 1, 1); #[cfg(feature = "proto-ipv4")] - const DST_ADDR: Ipv4Address = Ipv4Address([192, 168, 1, 2]); + const DST_ADDR: Ipv4Address = Ipv4Address::new(192, 168, 1, 2); #[cfg(feature = "proto-ipv4")] static PACKET_BYTES: [u8; 28] = [ diff --git a/src/wire/udp.rs b/src/wire/udp.rs index d7ad0d401..9d341e0ee 100644 --- a/src/wire/udp.rs +++ b/src/wire/udp.rs @@ -354,9 +354,9 @@ mod test { use crate::wire::Ipv4Address; #[cfg(feature = "proto-ipv4")] - const SRC_ADDR: Ipv4Address = Ipv4Address([192, 168, 1, 1]); + const SRC_ADDR: Ipv4Address = Ipv4Address::new(192, 168, 1, 1); #[cfg(feature = "proto-ipv4")] - const DST_ADDR: Ipv4Address = Ipv4Address([192, 168, 1, 2]); + const DST_ADDR: Ipv4Address = Ipv4Address::new(192, 168, 1, 2); #[cfg(feature = "proto-ipv4")] static PACKET_BYTES: [u8; 12] = [