netstack3_base/testutil/
addr.rs1use net_declare::{net_ip_v4, net_ip_v6, net_mac, net_subnet_v4, net_subnet_v6};
8use net_types::ethernet::Mac;
9use net_types::ip::{
10 GenericOverIp, Ip, IpAddress, Ipv4, Ipv4Addr, Ipv6, Ipv6Addr, Ipv6Scope, Subnet,
11};
12use net_types::{
13 MulticastAddr, NonMappedAddr, SpecifiedAddr, UnicastAddr, UnicastAddress, Witness as _,
14};
15
16use crate::device::address::AssignedAddrIpExt;
17use crate::socket::DualStackIpExt;
18
19pub trait TestDualStackIpExt: TestIpExt + DualStackIpExt<OtherVersion: TestIpExt> {}
24
25impl<I> TestDualStackIpExt for I where I: TestIpExt + DualStackIpExt<OtherVersion: TestIpExt> {}
26
27pub trait TestIpExt: Ip + packet_formats::ip::IpExt + AssignedAddrIpExt {
29 const TEST_ADDRS: TestAddrs<Self::Addr>;
31
32 fn get_other_ip_address(last: u8) -> SpecifiedAddr<Self::Addr>;
36
37 fn get_other_remote_ip_address(last: u8) -> SpecifiedAddr<Self::Addr>;
41
42 fn get_multicast_addr(last: u8) -> MulticastAddr<Self::Addr>;
46}
47
48impl TestIpExt for Ipv4 {
49 const TEST_ADDRS: TestAddrs<Ipv4Addr> = TEST_ADDRS_V4;
50
51 fn get_other_ip_address(last: u8) -> SpecifiedAddr<Ipv4Addr> {
52 let mut bytes = Self::TEST_ADDRS.local_ip.get().ipv4_bytes();
53 bytes[bytes.len() - 1] = last;
54 SpecifiedAddr::new(Ipv4Addr::new(bytes)).unwrap()
55 }
56
57 fn get_other_remote_ip_address(last: u8) -> SpecifiedAddr<Self::Addr> {
58 let mut bytes = Self::TEST_ADDRS.local_ip.get().ipv4_bytes();
59 bytes[0] += 1;
60 bytes[bytes.len() - 1] = last;
61 SpecifiedAddr::new(Ipv4Addr::new(bytes)).unwrap()
62 }
63
64 fn get_multicast_addr(last: u8) -> MulticastAddr<Self::Addr> {
65 assert!(u32::from(Self::Addr::BYTES * 8 - Self::MULTICAST_SUBNET.prefix()) > u8::BITS);
66 let mut bytes = Self::MULTICAST_SUBNET.network().ipv4_bytes();
67 bytes[bytes.len() - 1] = last;
68 MulticastAddr::new(Ipv4Addr::new(bytes)).unwrap()
69 }
70}
71
72impl TestIpExt for Ipv6 {
73 const TEST_ADDRS: TestAddrs<Ipv6Addr> = TEST_ADDRS_V6;
74
75 fn get_other_ip_address(last: u8) -> SpecifiedAddr<Ipv6Addr> {
76 let mut bytes = Self::TEST_ADDRS.local_ip.get().ipv6_bytes();
77 bytes[bytes.len() - 1] = last;
78 SpecifiedAddr::new(Ipv6Addr::from(bytes)).unwrap()
79 }
80
81 fn get_other_remote_ip_address(last: u8) -> SpecifiedAddr<Self::Addr> {
82 let mut bytes = Self::TEST_ADDRS.local_ip.get().ipv6_bytes();
83 bytes[0] += 1;
84 bytes[bytes.len() - 1] = last;
85 SpecifiedAddr::new(Ipv6Addr::from(bytes)).unwrap()
86 }
87
88 fn get_multicast_addr(last: u8) -> MulticastAddr<Self::Addr> {
89 assert!((Self::Addr::BYTES * 8 - Self::MULTICAST_SUBNET.prefix()) as u32 > u8::BITS);
90 let mut bytes = Self::MULTICAST_SUBNET.network().ipv6_bytes();
91 bytes[1] = Ipv6Scope::MULTICAST_SCOPE_ID_GLOBAL;
93 bytes[bytes.len() - 1] = last;
94 MulticastAddr::new(Ipv6Addr::from_bytes(bytes)).unwrap()
95 }
96}
97
98#[derive(Clone, GenericOverIp)]
103#[generic_over_ip(A, IpAddress)]
104pub struct TestAddrs<A: IpAddress> {
105 pub subnet: Subnet<A>,
107 pub local_ip: SpecifiedAddr<A>,
110 pub local_mac: UnicastAddr<Mac>,
112 pub remote_ip: SpecifiedAddr<A>,
114 pub remote_mac: UnicastAddr<Mac>,
116}
117
118const LOCAL_MAC: UnicastAddr<Mac> =
119 unsafe { UnicastAddr::new_unchecked(net_mac!("00:01:02:03:04:05")) };
120const REMOTE_MAC: UnicastAddr<Mac> =
121 unsafe { UnicastAddr::new_unchecked(net_mac!("06:07:08:09:0A:0B")) };
122
123pub const TEST_ADDRS_V4: TestAddrs<Ipv4Addr> = TestAddrs {
125 subnet: net_subnet_v4!("192.0.2.0/24"),
126 local_ip: unsafe { SpecifiedAddr::new_unchecked(net_ip_v4!("192.0.2.1")) },
127 local_mac: LOCAL_MAC,
128 remote_ip: unsafe { SpecifiedAddr::new_unchecked(net_ip_v4!("192.0.2.2")) },
129 remote_mac: REMOTE_MAC,
130};
131
132pub const TEST_ADDRS_V6: TestAddrs<Ipv6Addr> = TestAddrs {
134 subnet: net_subnet_v6!("2001:db8::/32"),
135 local_ip: unsafe { SpecifiedAddr::new_unchecked(net_ip_v6!("2001:db8::1")) },
136 local_mac: LOCAL_MAC,
137 remote_ip: unsafe { SpecifiedAddr::new_unchecked(net_ip_v6!("2001:db8::2")) },
138 remote_mac: REMOTE_MAC,
139};
140
141impl<A: IpAddress> TestAddrs<A> {
142 pub fn swap(&self) -> Self {
144 Self {
145 subnet: self.subnet,
146 local_ip: self.remote_ip,
147 local_mac: self.remote_mac,
148 remote_ip: self.local_ip,
149 remote_mac: self.local_mac,
150 }
151 }
152
153 pub fn local_non_mapped_unicast(&self) -> NonMappedAddr<UnicastAddr<A>>
156 where
157 A: UnicastAddress,
158 {
159 NonMappedAddr::new(UnicastAddr::try_from(self.local_ip).unwrap()).unwrap()
160 }
161
162 pub fn remote_non_mapped_unicast(&self) -> NonMappedAddr<UnicastAddr<A>>
165 where
166 A: UnicastAddress,
167 {
168 NonMappedAddr::new(UnicastAddr::try_from(self.remote_ip).unwrap()).unwrap()
169 }
170}