1 use crate::cmp::Ordering;
2 use crate::fmt::{self, Write as FmtWrite};
3 use crate::hash;
4 use crate::io::Write as IoWrite;
5 use crate::mem::transmute;
6 use crate::sys::net::netc as c;
7 use crate::sys_common::{AsInner, FromInner, IntoInner};
8 #[derive(Copy, Clone, Eq, PartialEq, Hash, PartialOrd, Ord)]
9 pub enum IpAddr {
10     V4(Ipv4Addr),
11     V6(Ipv6Addr),
12 }
13 #[derive(Copy)]
14 pub struct Ipv4Addr {
15     inner: c::in_addr,
16 }
17 #[derive(Copy)]
18 pub struct Ipv6Addr {
19     inner: c::in6_addr,
20 }
21 #[derive(Copy, PartialEq, Eq, Clone, Hash, Debug)]
22 #[non_exhaustive]
23 pub enum Ipv6MulticastScope {
24     InterfaceLocal,
25     LinkLocal,
26     RealmLocal,
27     AdminLocal,
28     SiteLocal,
29     OrganizationLocal,
30     Global,
31 }
32 impl IpAddr {
is_unspecified(&self) -> bool33     pub const fn is_unspecified(&self) -> bool {
34         match self {
35             IpAddr::V4(ip) => ip.is_unspecified(),
36             IpAddr::V6(ip) => ip.is_unspecified(),
37         }
38     }
is_loopback(&self) -> bool39     pub const fn is_loopback(&self) -> bool {
40         match self {
41             IpAddr::V4(ip) => ip.is_loopback(),
42             IpAddr::V6(ip) => ip.is_loopback(),
43         }
44     }
is_global(&self) -> bool45     pub const fn is_global(&self) -> bool {
46         match self {
47             IpAddr::V4(ip) => ip.is_global(),
48             IpAddr::V6(ip) => ip.is_global(),
49         }
50     }
is_multicast(&self) -> bool51     pub const fn is_multicast(&self) -> bool {
52         match self {
53             IpAddr::V4(ip) => ip.is_multicast(),
54             IpAddr::V6(ip) => ip.is_multicast(),
55         }
56     }
is_documentation(&self) -> bool57     pub const fn is_documentation(&self) -> bool {
58         match self {
59             IpAddr::V4(ip) => ip.is_documentation(),
60             IpAddr::V6(ip) => ip.is_documentation(),
61         }
62     }
is_benchmarking(&self) -> bool63     pub const fn is_benchmarking(&self) -> bool {
64         match self {
65             IpAddr::V4(ip) => ip.is_benchmarking(),
66             IpAddr::V6(ip) => ip.is_benchmarking(),
67         }
68     }
is_ipv4(&self) -> bool69     pub const fn is_ipv4(&self) -> bool {
70         matches!(self, IpAddr::V4(_))
71     }
is_ipv6(&self) -> bool72     pub const fn is_ipv6(&self) -> bool {
73         matches!(self, IpAddr::V6(_))
74     }
to_canonical(&self) -> IpAddr75     pub const fn to_canonical(&self) -> IpAddr {
76         match self {
77             &v4 @ IpAddr::V4(_) => v4,
78             IpAddr::V6(v6) => v6.to_canonical(),
79         }
80     }
81 }
82 impl Ipv4Addr {
new(a: u8, b: u8, c: u8, d: u8) -> Ipv4Addr83     pub const fn new(a: u8, b: u8, c: u8, d: u8) -> Ipv4Addr {
84         Ipv4Addr {
85             inner: c::in_addr {
86                 s_addr: u32::from_ne_bytes([a, b, c, d]),
87             },
88         }
89     }
90     pub const LOCALHOST: Self = Ipv4Addr::new(127, 0, 0, 1);
91     #[doc(alias = "INADDR_ANY")]
92     pub const UNSPECIFIED: Self = Ipv4Addr::new(0, 0, 0, 0);
93     pub const BROADCAST: Self = Ipv4Addr::new(255, 255, 255, 255);
octets(&self) -> [u8; 4]94     pub const fn octets(&self) -> [u8; 4] {
95         self.inner.s_addr.to_ne_bytes()
96     }
is_unspecified(&self) -> bool97     pub const fn is_unspecified(&self) -> bool {
98         self.inner.s_addr == 0
99     }
is_loopback(&self) -> bool100     pub const fn is_loopback(&self) -> bool {
101         self.octets()[0] == 127
102     }
is_private(&self) -> bool103     pub const fn is_private(&self) -> bool {
104         match self.octets() {
105             [10, ..] => true,
106             [172, b, ..] if b >= 16 && b <= 31 => true,
107             [192, 168, ..] => true,
108             _ => false,
109         }
110     }
is_link_local(&self) -> bool111     pub const fn is_link_local(&self) -> bool {
112         matches!(self.octets(), [169, 254, ..])
113     }
is_global(&self) -> bool114     pub const fn is_global(&self) -> bool {
115         if u32::from_be_bytes(self.octets()) == 0xc0000009
116             || u32::from_be_bytes(self.octets()) == 0xc000000a
117         {
118             return true;
119         }
120         !self.is_private()
121             && !self.is_loopback()
122             && !self.is_link_local()
123             && !self.is_broadcast()
124             && !self.is_documentation()
125             && !self.is_shared()
126             && !(self.octets()[0] == 192 && self.octets()[1] == 0 && self.octets()[2] == 0)
127             && !self.is_reserved()
128             && !self.is_benchmarking()
129             && self.octets()[0] != 0
130     }
is_shared(&self) -> bool131     pub const fn is_shared(&self) -> bool {
132         self.octets()[0] == 100 && (self.octets()[1] & 0b1100_0000 == 0b0100_0000)
133     }
is_benchmarking(&self) -> bool134     pub const fn is_benchmarking(&self) -> bool {
135         self.octets()[0] == 198 && (self.octets()[1] & 0xfe) == 18
136     }
is_reserved(&self) -> bool137     pub const fn is_reserved(&self) -> bool {
138         self.octets()[0] & 240 == 240 && !self.is_broadcast()
139     }
is_multicast(&self) -> bool140     pub const fn is_multicast(&self) -> bool {
141         self.octets()[0] >= 224 && self.octets()[0] <= 239
142     }
is_broadcast(&self) -> bool143     pub const fn is_broadcast(&self) -> bool {
144         u32::from_be_bytes(self.octets()) == u32::from_be_bytes(Self::BROADCAST.octets())
145     }
is_documentation(&self) -> bool146     pub const fn is_documentation(&self) -> bool {
147         matches!(
148             self.octets(),
149             [192, 0, 2, _] | [198, 51, 100, _] | [203, 0, 113, _]
150         )
151     }
to_ipv6_compatible(&self) -> Ipv6Addr152     pub const fn to_ipv6_compatible(&self) -> Ipv6Addr {
153         let [a, b, c, d] = self.octets();
154         Ipv6Addr {
155             inner: c::in6_addr {
156                 s6_addr: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, a, b, c, d],
157             },
158         }
159     }
to_ipv6_mapped(&self) -> Ipv6Addr160     pub const fn to_ipv6_mapped(&self) -> Ipv6Addr {
161         let [a, b, c, d] = self.octets();
162         Ipv6Addr {
163             inner: c::in6_addr {
164                 s6_addr: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, a, b, c, d],
165             },
166         }
167     }
168 }
169 impl fmt::Display for IpAddr {
fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result170     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
171         match self {
172             IpAddr::V4(ip) => ip.fmt(fmt),
173             IpAddr::V6(ip) => ip.fmt(fmt),
174         }
175     }
176 }
177 impl fmt::Debug for IpAddr {
fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result178     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
179         fmt::Display::fmt(self, fmt)
180     }
181 }
182 impl From<Ipv4Addr> for IpAddr {
from(ipv4: Ipv4Addr) -> IpAddr183     fn from(ipv4: Ipv4Addr) -> IpAddr {
184         IpAddr::V4(ipv4)
185     }
186 }
187 impl From<Ipv6Addr> for IpAddr {
from(ipv6: Ipv6Addr) -> IpAddr188     fn from(ipv6: Ipv6Addr) -> IpAddr {
189         IpAddr::V6(ipv6)
190     }
191 }
192 impl fmt::Display for Ipv4Addr {
fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result193     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
194         let octets = self.octets();
195         if fmt.precision().is_none() && fmt.width().is_none() {
196             write!(
197                 fmt,
198                 "{}.{}.{}.{}",
199                 octets[0], octets[1], octets[2], octets[3]
200             )
201         } else {
202             const IPV4_BUF_LEN: usize = 15;
203             let mut buf = [0u8; IPV4_BUF_LEN];
204             let mut buf_slice = &mut buf[..];
205             write!(
206                 buf_slice,
207                 "{}.{}.{}.{}",
208                 octets[0], octets[1], octets[2], octets[3]
209             )
210             .unwrap();
211             let len = IPV4_BUF_LEN - buf_slice.len();
212             let buf = unsafe { crate::str::from_utf8_unchecked(&buf[..len]) };
213             fmt.pad(buf)
214         }
215     }
216 }
217 impl fmt::Debug for Ipv4Addr {
fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result218     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
219         fmt::Display::fmt(self, fmt)
220     }
221 }
222 impl Clone for Ipv4Addr {
clone(&self) -> Ipv4Addr223     fn clone(&self) -> Ipv4Addr {
224         *self
225     }
226 }
227 impl PartialEq for Ipv4Addr {
eq(&self, other: &Ipv4Addr) -> bool228     fn eq(&self, other: &Ipv4Addr) -> bool {
229         self.inner.s_addr == other.inner.s_addr
230     }
231 }
232 impl PartialEq<Ipv4Addr> for IpAddr {
eq(&self, other: &Ipv4Addr) -> bool233     fn eq(&self, other: &Ipv4Addr) -> bool {
234         match self {
235             IpAddr::V4(v4) => v4 == other,
236             IpAddr::V6(_) => false,
237         }
238     }
239 }
240 impl PartialEq<IpAddr> for Ipv4Addr {
eq(&self, other: &IpAddr) -> bool241     fn eq(&self, other: &IpAddr) -> bool {
242         match other {
243             IpAddr::V4(v4) => self == v4,
244             IpAddr::V6(_) => false,
245         }
246     }
247 }
248 impl Eq for Ipv4Addr {}
249 impl hash::Hash for Ipv4Addr {
hash<H: hash::Hasher>(&self, s: &mut H)250     fn hash<H: hash::Hasher>(&self, s: &mut H) {
251         { self.inner.s_addr }.hash(s)
252     }
253 }
254 impl PartialOrd for Ipv4Addr {
partial_cmp(&self, other: &Ipv4Addr) -> Option<Ordering>255     fn partial_cmp(&self, other: &Ipv4Addr) -> Option<Ordering> {
256         Some(self.cmp(other))
257     }
258 }
259 impl PartialOrd<Ipv4Addr> for IpAddr {
partial_cmp(&self, other: &Ipv4Addr) -> Option<Ordering>260     fn partial_cmp(&self, other: &Ipv4Addr) -> Option<Ordering> {
261         match self {
262             IpAddr::V4(v4) => v4.partial_cmp(other),
263             IpAddr::V6(_) => Some(Ordering::Greater),
264         }
265     }
266 }
267 impl PartialOrd<IpAddr> for Ipv4Addr {
partial_cmp(&self, other: &IpAddr) -> Option<Ordering>268     fn partial_cmp(&self, other: &IpAddr) -> Option<Ordering> {
269         match other {
270             IpAddr::V4(v4) => self.partial_cmp(v4),
271             IpAddr::V6(_) => Some(Ordering::Less),
272         }
273     }
274 }
275 impl Ord for Ipv4Addr {
cmp(&self, other: &Ipv4Addr) -> Ordering276     fn cmp(&self, other: &Ipv4Addr) -> Ordering {
277         u32::from_be(self.inner.s_addr).cmp(&u32::from_be(other.inner.s_addr))
278     }
279 }
280 impl IntoInner<c::in_addr> for Ipv4Addr {
into_inner(self) -> c::in_addr281     fn into_inner(self) -> c::in_addr {
282         self.inner
283     }
284 }
285 impl From<Ipv4Addr> for u32 {
from(ip: Ipv4Addr) -> u32286     fn from(ip: Ipv4Addr) -> u32 {
287         let ip = ip.octets();
288         u32::from_be_bytes(ip)
289     }
290 }
291 impl From<u32> for Ipv4Addr {
from(ip: u32) -> Ipv4Addr292     fn from(ip: u32) -> Ipv4Addr {
293         Ipv4Addr::from(ip.to_be_bytes())
294     }
295 }
296 impl From<[u8; 4]> for Ipv4Addr {
from(octets: [u8; 4]) -> Ipv4Addr297     fn from(octets: [u8; 4]) -> Ipv4Addr {
298         Ipv4Addr::new(octets[0], octets[1], octets[2], octets[3])
299     }
300 }
301 impl From<[u8; 4]> for IpAddr {
from(octets: [u8; 4]) -> IpAddr302     fn from(octets: [u8; 4]) -> IpAddr {
303         IpAddr::V4(Ipv4Addr::from(octets))
304     }
305 }
306 impl Ipv6Addr {
new(a: u16, b: u16, c: u16, d: u16, e: u16, f: u16, g: u16, h: u16) -> Ipv6Addr307     pub const fn new(a: u16, b: u16, c: u16, d: u16, e: u16, f: u16, g: u16, h: u16) -> Ipv6Addr {
308         let addr16 = [
309             a.to_be(),
310             b.to_be(),
311             c.to_be(),
312             d.to_be(),
313             e.to_be(),
314             f.to_be(),
315             g.to_be(),
316             h.to_be(),
317         ];
318         Ipv6Addr {
319             inner: c::in6_addr {
320                 s6_addr: unsafe { transmute::<_, [u8; 16]>(addr16) },
321             },
322         }
323     }
324     pub const LOCALHOST: Self = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1);
325     pub const UNSPECIFIED: Self = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0);
segments(&self) -> [u16; 8]326     pub const fn segments(&self) -> [u16; 8] {
327         let [a, b, c, d, e, f, g, h] = unsafe { transmute::<_, [u16; 8]>(self.inner.s6_addr) };
328         [
329             u16::from_be(a),
330             u16::from_be(b),
331             u16::from_be(c),
332             u16::from_be(d),
333             u16::from_be(e),
334             u16::from_be(f),
335             u16::from_be(g),
336             u16::from_be(h),
337         ]
338     }
is_unspecified(&self) -> bool339     pub const fn is_unspecified(&self) -> bool {
340         u128::from_be_bytes(self.octets()) == u128::from_be_bytes(Ipv6Addr::UNSPECIFIED.octets())
341     }
is_loopback(&self) -> bool342     pub const fn is_loopback(&self) -> bool {
343         u128::from_be_bytes(self.octets()) == u128::from_be_bytes(Ipv6Addr::LOCALHOST.octets())
344     }
is_global(&self) -> bool345     pub const fn is_global(&self) -> bool {
346         match self.multicast_scope() {
347             Some(Ipv6MulticastScope::Global) => true,
348             None => self.is_unicast_global(),
349             _ => false,
350         }
351     }
is_unique_local(&self) -> bool352     pub const fn is_unique_local(&self) -> bool {
353         (self.segments()[0] & 0xfe00) == 0xfc00
354     }
is_unicast(&self) -> bool355     pub const fn is_unicast(&self) -> bool {
356         !self.is_multicast()
357     }
is_unicast_link_local(&self) -> bool358     pub const fn is_unicast_link_local(&self) -> bool {
359         (self.segments()[0] & 0xffc0) == 0xfe80
360     }
is_documentation(&self) -> bool361     pub const fn is_documentation(&self) -> bool {
362         (self.segments()[0] == 0x2001) && (self.segments()[1] == 0xdb8)
363     }
is_benchmarking(&self) -> bool364     pub const fn is_benchmarking(&self) -> bool {
365         (self.segments()[0] == 0x2001) && (self.segments()[1] == 0x2) && (self.segments()[2] == 0)
366     }
is_unicast_global(&self) -> bool367     pub const fn is_unicast_global(&self) -> bool {
368         self.is_unicast()
369             && !self.is_loopback()
370             && !self.is_unicast_link_local()
371             && !self.is_unique_local()
372             && !self.is_unspecified()
373             && !self.is_documentation()
374     }
multicast_scope(&self) -> Option<Ipv6MulticastScope>375     pub const fn multicast_scope(&self) -> Option<Ipv6MulticastScope> {
376         if self.is_multicast() {
377             match self.segments()[0] & 0x000f {
378                 1 => Some(Ipv6MulticastScope::InterfaceLocal),
379                 2 => Some(Ipv6MulticastScope::LinkLocal),
380                 3 => Some(Ipv6MulticastScope::RealmLocal),
381                 4 => Some(Ipv6MulticastScope::AdminLocal),
382                 5 => Some(Ipv6MulticastScope::SiteLocal),
383                 8 => Some(Ipv6MulticastScope::OrganizationLocal),
384                 14 => Some(Ipv6MulticastScope::Global),
385                 _ => None,
386             }
387         } else {
388             None
389         }
390     }
is_multicast(&self) -> bool391     pub const fn is_multicast(&self) -> bool {
392         (self.segments()[0] & 0xff00) == 0xff00
393     }
to_ipv4_mapped(&self) -> Option<Ipv4Addr>394     pub const fn to_ipv4_mapped(&self) -> Option<Ipv4Addr> {
395         match self.octets() {
396             [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, a, b, c, d] => {
397                 Some(Ipv4Addr::new(a, b, c, d))
398             }
399             _ => None,
400         }
401     }
to_ipv4(&self) -> Option<Ipv4Addr>402     pub const fn to_ipv4(&self) -> Option<Ipv4Addr> {
403         if let [0, 0, 0, 0, 0, 0 | 0xffff, ab, cd] = self.segments() {
404             let [a, b] = ab.to_be_bytes();
405             let [c, d] = cd.to_be_bytes();
406             Some(Ipv4Addr::new(a, b, c, d))
407         } else {
408             None
409         }
410     }
to_canonical(&self) -> IpAddr411     pub const fn to_canonical(&self) -> IpAddr {
412         if let Some(mapped) = self.to_ipv4_mapped() {
413             return IpAddr::V4(mapped);
414         }
415         IpAddr::V6(*self)
416     }
octets(&self) -> [u8; 16]417     pub const fn octets(&self) -> [u8; 16] {
418         self.inner.s6_addr
419     }
420 }
421 impl fmt::Display for Ipv6Addr {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result422     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
423         if f.precision().is_none() && f.width().is_none() {
424             let segments = self.segments();
425             if self.is_unspecified() {
426                 f.write_str("::")
427             } else if self.is_loopback() {
428                 f.write_str("::1")
429             } else if let Some(ipv4) = self.to_ipv4() {
430                 match segments[5] {
431                     0 => write!(f, "::{}", ipv4),
432                     0xffff => write!(f, "::ffff:{}", ipv4),
433                     _ => unreachable!(),
434                 }
435             } else { # [derive (Copy , Clone , Default)] struct Span { start : usize , len : usize , } let zeroes = { let mut longest = Span :: default () ; let mut current = Span :: default () ; for (i , & segment) in segments . iter () . enumerate () { if segment == 0 { if current . len == 0 { current . start = i ; } current . len += 1 ; if current . len > longest . len { longest = current ; } } else { current = Span :: default () ; } } longest } ; # [doc = " Write a colon-separated part of the address"] # [inline] fn fmt_subslice (f : & mut fmt :: Formatter < '_ > , chunk : & [u16]) -> fmt :: Result { if let Some ((first , tail)) = chunk . split_first () { write ! (f , "{:x}" , first) ? ; for segment in tail { f . write_char (':') ? ; write ! (f , "{:x}" , segment) ? ; } } Ok (()) } if zeroes . len > 1 { fmt_subslice (f , & segments [.. zeroes . start]) ? ; f . write_str ("::") ? ; fmt_subslice (f , & segments [zeroes . start + zeroes . len ..]) } else { fmt_subslice (f , & segments) } }
436         } else {
437             const IPV6_BUF_LEN: usize = (4 * 8) + 7;
438             let mut buf = [0u8; IPV6_BUF_LEN];
439             let mut buf_slice = &mut buf[..];
440             write!(buf_slice, "{}", self).unwrap();
441             let len = IPV6_BUF_LEN - buf_slice.len();
442             let buf = unsafe { crate::str::from_utf8_unchecked(&buf[..len]) };
443             f.pad(buf)
444         }
445     }
446 }
447 impl fmt::Debug for Ipv6Addr {
fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result448     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
449         fmt::Display::fmt(self, fmt)
450     }
451 }
452 impl Clone for Ipv6Addr {
clone(&self) -> Ipv6Addr453     fn clone(&self) -> Ipv6Addr {
454         *self
455     }
456 }
457 impl PartialEq for Ipv6Addr {
eq(&self, other: &Ipv6Addr) -> bool458     fn eq(&self, other: &Ipv6Addr) -> bool {
459         self.inner.s6_addr == other.inner.s6_addr
460     }
461 }
462 impl PartialEq<IpAddr> for Ipv6Addr {
eq(&self, other: &IpAddr) -> bool463     fn eq(&self, other: &IpAddr) -> bool {
464         match other {
465             IpAddr::V4(_) => false,
466             IpAddr::V6(v6) => self == v6,
467         }
468     }
469 }
470 impl PartialEq<Ipv6Addr> for IpAddr {
eq(&self, other: &Ipv6Addr) -> bool471     fn eq(&self, other: &Ipv6Addr) -> bool {
472         match self {
473             IpAddr::V4(_) => false,
474             IpAddr::V6(v6) => v6 == other,
475         }
476     }
477 }
478 impl Eq for Ipv6Addr {}
479 impl hash::Hash for Ipv6Addr {
hash<H: hash::Hasher>(&self, s: &mut H)480     fn hash<H: hash::Hasher>(&self, s: &mut H) {
481         self.inner.s6_addr.hash(s)
482     }
483 }
484 impl PartialOrd for Ipv6Addr {
partial_cmp(&self, other: &Ipv6Addr) -> Option<Ordering>485     fn partial_cmp(&self, other: &Ipv6Addr) -> Option<Ordering> {
486         Some(self.cmp(other))
487     }
488 }
489 impl PartialOrd<Ipv6Addr> for IpAddr {
partial_cmp(&self, other: &Ipv6Addr) -> Option<Ordering>490     fn partial_cmp(&self, other: &Ipv6Addr) -> Option<Ordering> {
491         match self {
492             IpAddr::V4(_) => Some(Ordering::Less),
493             IpAddr::V6(v6) => v6.partial_cmp(other),
494         }
495     }
496 }
497 impl PartialOrd<IpAddr> for Ipv6Addr {
partial_cmp(&self, other: &IpAddr) -> Option<Ordering>498     fn partial_cmp(&self, other: &IpAddr) -> Option<Ordering> {
499         match other {
500             IpAddr::V4(_) => Some(Ordering::Greater),
501             IpAddr::V6(v6) => self.partial_cmp(v6),
502         }
503     }
504 }
505 impl Ord for Ipv6Addr {
cmp(&self, other: &Ipv6Addr) -> Ordering506     fn cmp(&self, other: &Ipv6Addr) -> Ordering {
507         self.segments().cmp(&other.segments())
508     }
509 }
510 impl AsInner<c::in6_addr> for Ipv6Addr {
as_inner(&self) -> &c::in6_addr511     fn as_inner(&self) -> &c::in6_addr {
512         &self.inner
513     }
514 }
515 impl FromInner<c::in6_addr> for Ipv6Addr {
from_inner(addr: c::in6_addr) -> Ipv6Addr516     fn from_inner(addr: c::in6_addr) -> Ipv6Addr {
517         Ipv6Addr { inner: addr }
518     }
519 }
520 impl From<Ipv6Addr> for u128 {
from(ip: Ipv6Addr) -> u128521     fn from(ip: Ipv6Addr) -> u128 {
522         let ip = ip.octets();
523         u128::from_be_bytes(ip)
524     }
525 }
526 impl From<u128> for Ipv6Addr {
from(ip: u128) -> Ipv6Addr527     fn from(ip: u128) -> Ipv6Addr {
528         Ipv6Addr::from(ip.to_be_bytes())
529     }
530 }
531 impl From<[u8; 16]> for Ipv6Addr {
from(octets: [u8; 16]) -> Ipv6Addr532     fn from(octets: [u8; 16]) -> Ipv6Addr {
533         let inner = c::in6_addr { s6_addr: octets };
534         Ipv6Addr::from_inner(inner)
535     }
536 }
537 impl From<[u16; 8]> for Ipv6Addr {
from(segments: [u16; 8]) -> Ipv6Addr538     fn from(segments: [u16; 8]) -> Ipv6Addr {
539         let [a, b, c, d, e, f, g, h] = segments;
540         Ipv6Addr::new(a, b, c, d, e, f, g, h)
541     }
542 }
543 impl From<[u8; 16]> for IpAddr {
from(octets: [u8; 16]) -> IpAddr544     fn from(octets: [u8; 16]) -> IpAddr {
545         IpAddr::V6(Ipv6Addr::from(octets))
546     }
547 }
548 impl From<[u16; 8]> for IpAddr {
from(segments: [u16; 8]) -> IpAddr549     fn from(segments: [u16; 8]) -> IpAddr {
550         IpAddr::V6(Ipv6Addr::from(segments))
551     }
552 }
553