1use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
2
3#[derive(Debug, Clone, PartialEq, Eq, Default)]
5pub enum IpVersion {
6 #[default]
8 V4,
9 V6,
11}
12
13impl IpVersion {
14 pub(crate) fn iter(&self) -> IpVersionAddrIter {
15 match self {
16 Self::V4 => IpVersionAddrIter::V4(1),
17 Self::V6 => IpVersionAddrIter::V6(1),
18 }
19 }
20}
21
22#[derive(Debug)]
23pub(crate) enum IpVersionAddrIter {
24 V4(u32),
26 V6(u128),
28}
29
30impl Default for IpVersionAddrIter {
31 fn default() -> Self {
32 Self::V4(1)
33 }
34}
35
36impl IpVersionAddrIter {
37 pub(crate) fn next(&mut self) -> IpAddr {
38 match self {
39 Self::V4(next) => {
40 let host = *next;
41 *next = next.wrapping_add(1);
42
43 let a = (host >> 8) as u8;
44 let b = (host & 0xFF) as u8;
45
46 IpAddr::V4(Ipv4Addr::new(192, 168, a, b))
47 }
48 Self::V6(next) => {
49 let host = *next;
50 *next = next.wrapping_add(1);
51
52 let a = ((host >> 48) & 0xffff) as u16;
53 let b = ((host >> 32) & 0xffff) as u16;
54 let c = ((host >> 16) & 0xffff) as u16;
55 let d = (host & 0xffff) as u16;
56
57 IpAddr::V6(Ipv6Addr::new(0xfe80, 0, 0, 0, a, b, c, d))
58 }
59 }
60 }
61}
62
63#[cfg(test)]
64mod tests {
65 use crate::{lookup, Builder, IpVersion, Result};
66 use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
67
68 #[test]
69 fn ip_version_v4() -> Result {
70 let mut sim = Builder::new().build();
71 sim.client("client", async move {
72 assert_eq!(lookup("client"), IpAddr::V4(Ipv4Addr::new(192, 168, 0, 1)));
73 assert_eq!(lookup("server"), IpAddr::V4(Ipv4Addr::new(192, 168, 0, 2)));
74 Ok(())
75 });
76 sim.client("server", async move { Ok(()) });
77
78 assert_eq!(
79 sim.lookup("client"),
80 IpAddr::V4(Ipv4Addr::new(192, 168, 0, 1))
81 );
82 assert_eq!(
83 sim.lookup("server"),
84 IpAddr::V4(Ipv4Addr::new(192, 168, 0, 2))
85 );
86
87 sim.run()
88 }
89
90 #[test]
91 fn ip_version_v6() -> Result {
92 let mut sim = Builder::new().ip_version(IpVersion::V6).build();
93 sim.client("client", async move {
94 assert_eq!(
95 lookup("client"),
96 IpAddr::V6(Ipv6Addr::new(0xfe80, 0, 0, 0, 0, 0, 0, 1))
97 );
98 assert_eq!(
99 lookup("server"),
100 IpAddr::V6(Ipv6Addr::new(0xfe80, 0, 0, 0, 0, 0, 0, 2))
101 );
102 Ok(())
103 });
104 sim.client("server", async move { Ok(()) });
105
106 assert_eq!(
107 sim.lookup("client"),
108 IpAddr::V6(Ipv6Addr::new(0xfe80, 0, 0, 0, 0, 0, 0, 1))
109 );
110 assert_eq!(
111 sim.lookup("server"),
112 IpAddr::V6(Ipv6Addr::new(0xfe80, 0, 0, 0, 0, 0, 0, 2))
113 );
114
115 sim.run()
116 }
117}