asyncio/ip/
addr.rs

1use std::fmt;
2use std::mem;
3use std::ops::{AddAssign, SubAssign};
4use std::cmp::Ordering;
5
6fn add_assign(bytes: &mut [u8], mut rhs: i64) {
7    if rhs < 0 {
8        sub_assign(bytes, -rhs)
9    } else {
10        for it in bytes.iter_mut().rev() {
11            let (val, car) = it.overflowing_add(rhs as u8);
12            *it = val;
13            rhs >>= 8;
14            if car {
15                rhs += 1;
16            }
17        }
18        if rhs > 0 {
19            panic!("overflow");
20        }
21    }
22}
23
24fn sub_assign(bytes: &mut [u8], mut rhs: i64) {
25    if rhs < 0 {
26        add_assign(bytes, -rhs)
27    } else {
28        for it in bytes.iter_mut().rev() {
29            let (val, car) = it.overflowing_sub(rhs as u8);
30            *it = val;
31            rhs >>= 8;
32            if car {
33                rhs += 1;
34            }
35        }
36        if rhs > 0 {
37            panic!("overflow");
38        }
39    }
40}
41
42fn fmt_v6(bytes: &[u8; 16], f: &mut fmt::Formatter) -> fmt::Result {
43    let ar: &[u16; 8] = unsafe { mem::transmute(bytes) };
44    let mut cnt = 0;
45    let mut max_idx = 0;
46    let mut max_cnt = 0;
47    for (i, e) in ar.iter().enumerate() {
48        if *e != 0 {
49            if max_cnt < cnt {
50                max_idx = i - cnt;
51                max_cnt = cnt;
52            }
53            cnt = 0;
54        } else {
55            cnt += 1;
56        }
57    }
58    if max_cnt < cnt {
59        max_idx = ar.len() - cnt;
60        max_cnt = cnt;
61    }
62
63    if max_idx == 0 && max_cnt == 0 {
64        return write!(f, "{:x}:{:x}:{:x}:{:x}:{:x}:{:x}:{:x}:{:x}",
65                      u16::from_be(ar[0]), u16::from_be(ar[1]), u16::from_be(ar[2]), u16::from_be(ar[3]),
66                      u16::from_be(ar[4]), u16::from_be(ar[5]), u16::from_be(ar[6]), u16::from_be(ar[7]));
67    }
68
69    if max_idx == 0 {
70        try!(write!(f, ":"));
71    } else {
72        for i in 0..max_idx {
73            try!(write!(f, "{:x}:", u16::from_be(ar[i])));
74        }
75    }
76
77    if max_idx + max_cnt == 8 {
78        try!(write!(f, ":"));
79    } else {
80        for i in max_idx + max_cnt..ar.len() {
81            try!(write!(f, ":{:x}", u16::from_be(ar[i])));
82        }
83    }
84    Ok(())
85}
86
87fn netmask_len(addr: &[u8]) -> u8 {
88    if addr[0] == 0 {
89        return 0;
90    }
91
92    let mut mask = 0;
93    let mut it = addr.iter();
94    while let Some(&n) = it.next() {
95        match n {
96            0b00000000 => {
97                break;
98            },
99            0b10000000 => {
100                mask += 1;
101                break;
102            },
103            0b11000000 => {
104                mask += 2;
105                break;
106            },
107            0b11100000 => {
108                mask += 3;
109                break;
110            },
111            0b11110000 => {
112                mask += 4;
113                break;
114            },
115            0b11111000 => {
116                mask += 5;
117                break;
118            },
119            0b11111100 => {
120                mask += 6;
121                break;
122            },
123            0b11111110 => {
124                mask += 7;
125                break;
126            },
127            0b11111111 => {
128                mask += 8;
129            },
130            _ => return 0,
131        }
132    }
133    while let Some(&n) = it.next() {
134        if n != 0 {
135            return 0;
136        }
137    }
138    mask
139}
140
141/// Implements Link-layer addresses.
142///
143/// Also referred to as MAC address and Hardware address.
144#[derive(Default, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
145pub struct LlAddr {
146    bytes: [u8; 6],
147}
148
149impl LlAddr {
150    /// Returns a Link-layer address.
151    ///
152    /// The result will represent the LL-address a:b:c:d:e:f.
153    ///
154    /// # Example
155    ///
156    /// ```
157    /// use asyncio::ip::LlAddr;
158    ///
159    /// let mac = LlAddr::new(0,0,0,0,0,0);
160    /// ```
161    pub fn new(a: u8, b: u8, c: u8, d: u8, e: u8, f: u8) -> LlAddr {
162        LlAddr { bytes: [a,b,c,d,e,f] }
163    }
164
165    /// Returns 6 octets bytes.
166    ///
167    /// # Example
168    ///
169    /// ```
170    /// use asyncio::ip::LlAddr;
171    ///
172    /// assert_eq!(LlAddr::new(1,2,3,4,5,6).as_bytes(), &[1,2,3,4,5,6]);
173    /// ```
174    pub fn as_bytes(&self) -> &[u8; 6] {
175        &self.bytes
176    }
177
178    /// Returns a OUI (Organizationally Unique Identifier).
179    ///
180    /// # Example
181    ///
182    /// ```
183    /// use asyncio::ip::LlAddr;
184    ///
185    /// let mac = LlAddr::new(0xaa, 0xbb, 0xcc, 0, 0, 0);
186    /// assert_eq!(mac.oui(), 0xaabbcc);
187    /// ```
188    pub fn oui(&self) -> i32 {
189        ((self.bytes[0] as i32 * 256 + self.bytes[1] as i32) * 256 + self.bytes[2] as i32)
190    }
191}
192
193impl AddAssign<i64> for LlAddr {
194    fn add_assign(&mut self, rhs: i64) {
195        add_assign(&mut self.bytes, rhs)
196    }
197}
198
199impl SubAssign<i64> for LlAddr {
200    fn sub_assign(&mut self, rhs: i64) {
201        sub_assign(&mut self.bytes, rhs)
202    }
203}
204
205impl fmt::Display for LlAddr {
206    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
207        write!(f, "{:02X}:{:02X}:{:02X}:{:02X}:{:02X}:{:02X}",
208               self.bytes[0], self.bytes[1], self.bytes[2],
209               self.bytes[3], self.bytes[4], self.bytes[5])
210    }
211}
212
213impl fmt::Debug for LlAddr {
214    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
215        write!(f, "{}", self)
216    }
217}
218
219impl From<[u8; 6]> for LlAddr {
220    fn from(bytes: [u8; 6]) -> Self {
221        LlAddr { bytes: bytes }
222    }
223}
224
225/// Implements IP version 4 style addresses.
226#[derive(Default, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
227pub struct IpAddrV4 {
228    bytes: [u8; 4],
229}
230
231impl IpAddrV4 {
232    /// Returns a IP-v4 address.
233    ///
234    /// The result will represent the IP address `a`.`b`.`c`.`d`.
235    ///
236    /// # Examples
237    /// ```
238    /// use asyncio::ip::IpAddrV4;
239    ///
240    /// let ip = IpAddrV4::new(192,168,0,1);
241    /// ```
242    pub fn new(a: u8, b: u8, c: u8, d: u8) -> IpAddrV4 {
243        IpAddrV4 { bytes: [a,b,c,d] }
244    }
245
246    /// Returns a unspecified IP-v4 address.
247    ///
248    /// # Examples
249    /// ```
250    /// use asyncio::ip::IpAddrV4;
251    ///
252    /// let ip = IpAddrV4::any();
253    /// assert_eq!(ip, IpAddrV4::new(0,0,0,0));
254    /// ```
255    pub fn any() -> IpAddrV4 {
256        IpAddrV4 { bytes: [0; 4] }
257    }
258
259    /// Returns a IP-v4 address for a loopback address.
260    ///
261    /// # Examples
262    /// ```
263    /// use asyncio::ip::IpAddrV4;
264    ///
265    /// let ip = IpAddrV4::loopback();
266    /// assert_eq!(ip, IpAddrV4::new(127,0,0,1));
267    /// ```
268    pub fn loopback() -> IpAddrV4 {
269        IpAddrV4::new(127,0,0,1)
270    }
271
272    /// Returns true for if this is a unspecified address 0.0.0.0.
273    ///
274    /// # Examples
275    /// ```
276    /// use asyncio::ip::IpAddrV4;
277    ///
278    /// assert!(IpAddrV4::any().is_unspecified());
279    /// ```
280    pub fn is_unspecified(&self) -> bool {
281        self.bytes.iter().all(|&x| x == 0)
282    }
283
284    /// Return true for if this is a loopback address 127.0.0.1.
285    ///
286    /// # Examples
287    /// ```
288    /// use asyncio::ip::IpAddrV4;
289    ///
290    /// assert!(IpAddrV4::loopback().is_loopback());
291    /// ```
292    pub fn is_loopback(&self) -> bool {
293        (self.bytes[0] & 0xFF) == 0x7F
294    }
295
296    /// Returns true for if this is a class A address.
297    ///
298    /// The class A address ranges:
299    ///
300    /// - 10.0.0.0/8
301    ///
302    /// # Examples
303    /// ```
304    /// use asyncio::ip::IpAddrV4;
305    ///
306    /// assert!(IpAddrV4::new(10,0,0,1).is_class_a());
307    /// ```
308    pub fn is_class_a(&self) -> bool {
309        (self.bytes[0] & 0x80) == 0
310    }
311
312    /// Returns true for if this is a class B address.
313    ///
314    /// The class B address ranges:
315    ///
316    /// - 172.16.0.0/12
317    ///
318    /// # Examples
319    /// ```
320    /// use asyncio::ip::IpAddrV4;
321    ///
322    /// assert!(IpAddrV4::new(172,16,0,1).is_class_b());
323    /// ```
324    pub fn is_class_b(&self) -> bool {
325        (self.bytes[0] & 0xC0) == 0x80
326    }
327
328    /// Returns true for if this is a class C address.
329    ///
330    /// The class c address ranges:
331    ///
332    /// - 192.168.0.0/16
333    ///
334    /// # Examples
335    /// ```
336    /// use asyncio::ip::IpAddrV4;
337    ///
338    /// assert!(IpAddrV4::new(192,168,0,1).is_class_c());
339    /// ```
340    pub fn is_class_c(&self) -> bool {
341        (self.bytes[0] & 0xE0) == 0xC0
342    }
343
344    /// Returns true for if this is a private address.
345    ///
346    /// The private address ranges:
347    ///
348    ///  - 10.0.0.0/8
349    ///  - 172.16.0.0/12
350    ///  - 192.168.0.0/16
351    ///
352    /// # Examples
353    /// ```
354    /// use asyncio::ip::IpAddrV4;
355    ///
356    /// assert!(IpAddrV4::new(192,168,0,1).is_private());
357    /// ```
358    pub fn is_private(&self) -> bool {
359        self.is_class_a() || self.is_class_b() || self.is_class_c()
360    }
361
362    /// Returns true for if this is a class D address.
363    ///
364    /// The class D address ranges:
365    ///
366    /// - 224.0.0.0/4
367    ///
368    /// # Examples
369    /// ```
370    /// use asyncio::ip::IpAddrV4;
371    ///
372    /// assert!(IpAddrV4::new(224,0,0,1).is_multicast());
373    /// ```
374    pub fn is_multicast(&self) -> bool {
375        (self.bytes[0] & 0xF0) == 0xE0
376    }
377
378    /// Returns true for if this is a link-local address.
379    ///
380    /// The link-local address ranges:
381    ///
382    /// - 169.254.0.0/16
383    ///
384    /// # Examples
385    /// ```
386    /// use asyncio::ip::IpAddrV4;
387    ///
388    /// assert!(IpAddrV4::new(169,254,0,0).is_link_local());
389    /// ```
390    pub fn is_link_local(&self) -> bool {
391        self.bytes[0] == 0xA9 && self.bytes[1] == 0xFE
392    }
393
394    /// Returns 4 octets bytes.
395    ///
396    /// # Examples
397    /// ```
398    /// use asyncio::ip::IpAddrV4;
399    ///
400    /// assert_eq!(IpAddrV4::new(169,254,0,1).as_bytes(), &[169,254,0,1]);
401    /// ```
402    pub fn as_bytes(&self) -> &[u8; 4] {
403        &self.bytes
404    }
405
406    /// Returns `u32` in host byte order.
407    ///
408    /// # Examples
409    /// ```
410    /// use asyncio::ip::IpAddrV4;
411    ///
412    /// assert_eq!(IpAddrV4::new(10,0,0,1).to_u32(), 10*256*256*256+1);
413    /// ```
414    pub fn to_u32(&self) -> u32 {
415        ((((((self.bytes[0] as u32) << 8)
416            + self.bytes[1] as u32) << 8)
417            + self.bytes[2] as u32) << 8)
418            + self.bytes[3] as u32
419    }
420}
421
422impl AddAssign<i64> for IpAddrV4 {
423    fn add_assign(&mut self, rhs: i64) {
424        *self = Self::from(self.to_u32() + rhs as u32);
425    }
426}
427
428impl SubAssign<i64> for IpAddrV4 {
429    fn sub_assign(&mut self, rhs: i64) {
430        *self = Self::from(self.to_u32() - rhs as u32);
431    }
432}
433
434impl fmt::Display for IpAddrV4 {
435    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
436        write!(f, "{}.{}.{}.{}", self.bytes[0], self.bytes[1], self.bytes[2], self.bytes[3])
437    }
438}
439
440impl fmt::Debug for IpAddrV4 {
441    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
442        write!(f, "{}", self)
443    }
444}
445
446impl From<u32> for IpAddrV4 {
447    fn from(mut addr: u32) -> Self {
448        let d = (addr & 0xFF) as u8;
449        addr >>= 8;
450        let c = (addr & 0xFF) as u8;
451        addr >>= 8;
452        let b = (addr & 0xFF) as u8;
453        addr >>= 8;
454        IpAddrV4::new(addr as u8, b, c, d)
455    }
456}
457
458impl From<[u8; 4]> for IpAddrV4 {
459    fn from(bytes: [u8; 4]) -> Self {
460        IpAddrV4 { bytes: bytes }
461    }
462}
463
464/// Implements IP version 6 style addresses.
465#[derive(Default, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
466pub struct IpAddrV6 {
467    scope_id: u32,
468    bytes: [u8; 16],
469}
470
471impl IpAddrV6 {
472    /// Returns a IP-v6 address.
473    ///
474    /// The result will represent the IP address `a`:`b`:`c`:`d`:`e`:`f`:`g`:`h`
475    ///
476    /// # Examples
477    /// ```
478    /// use asyncio::ip::IpAddrV6;
479    ///
480    /// let ip = IpAddrV6::new(0,0,0,0,0,0,0,1);
481    /// ```
482    pub fn new(a: u16, b: u16, c: u16, d: u16, e: u16, f: u16, g: u16, h: u16) -> IpAddrV6 {
483        let ar = [ a.to_be(), b.to_be(), c.to_be(), d.to_be(), e.to_be(), f.to_be(), g.to_be(), h.to_be() ];
484        IpAddrV6::from(unsafe { mem::transmute(ar) }, 0)
485    }
486
487    /// Returns a IP-v6 address with set a scope-id.
488    ///
489    /// The result will represent the IP address `a`:`b`:`c`:`d`:`e`:`f`:`g`:`h`%[scope-id]
490    ///
491    /// # Examples
492    /// ```
493    /// use asyncio::ip::IpAddrV6;
494    ///
495    /// let ip = IpAddrV6::with_scope_id(0,0,0,0,0,0,0,1,0x01);
496    /// ```
497    pub fn with_scope_id(a: u16, b: u16, c: u16, d: u16, e: u16, f: u16, g: u16, h: u16, scope_id: u32) -> IpAddrV6 {
498        let ar = [ a.to_be(), b.to_be(), c.to_be(), d.to_be(), e.to_be(), f.to_be(), g.to_be(), h.to_be() ];
499        IpAddrV6::from(unsafe { mem::transmute(ar) }, scope_id)
500    }
501
502    /// Returns a unspecified IP-v6 address.
503    ///
504    /// # Examples
505    /// ```
506    /// use asyncio::ip::IpAddrV6;
507    ///
508    /// let ip = IpAddrV6::any();
509    /// assert_eq!(ip, IpAddrV6::new(0,0,0,0,0,0,0,0));
510    /// ```
511    pub fn any() -> IpAddrV6 {
512        IpAddrV6 { scope_id: 0, bytes: [0; 16] }
513    }
514
515    /// Returns a loopback IP-v6 address.
516    ///
517    /// # Examples
518    /// ```
519    /// use asyncio::ip::IpAddrV6;
520    ///
521    /// let ip = IpAddrV6::loopback();
522    /// assert_eq!(ip, IpAddrV6::new(0,0,0,0,0,0,0,1));
523    /// ```
524    pub fn loopback() -> IpAddrV6 {
525        IpAddrV6 { scope_id: 0, bytes: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1] }
526    }
527
528    /// Returns a IP-v6 address from 16-octet bytes.
529    ///
530    /// # Examples
531    /// ```
532    /// use asyncio::ip::IpAddrV6;
533    ///
534    /// let ip = IpAddrV6::from([0,1,2,3, 4,5,6,7, 8,9,10,11, 12,13,14,15], 0);
535    /// assert_eq!(ip, IpAddrV6::new(0x0001, 0x0203,0x0405,0x0607,0x0809,0x0A0B, 0x0C0D, 0x0E0F));
536    /// ```
537    pub fn from(bytes: [u8; 16], scope_id: u32) -> IpAddrV6 {
538        IpAddrV6 { scope_id: scope_id, bytes: bytes }
539    }
540
541    /// Returns a scope-id.
542    ///
543    /// # Examples
544    /// ```
545    /// use asyncio::ip::IpAddrV6;
546    ///
547    /// let ip = IpAddrV6::with_scope_id(0,0,0,0,0,0,0,0, 10);
548    /// assert_eq!(ip.get_scope_id(), 10);
549    /// ```
550    pub fn get_scope_id(&self) -> u32 {
551        self.scope_id
552    }
553
554    /// Sets a scope-id.
555    ///
556    /// # Examples
557    /// ```
558    /// use asyncio::ip::IpAddrV6;
559    ///
560    /// let mut ip = IpAddrV6::loopback();
561    /// assert_eq!(ip.get_scope_id(), 0);
562    ///
563    /// ip.set_scope_id(0x10);
564    /// assert_eq!(ip.get_scope_id(), 16);
565    /// ```
566    pub fn set_scope_id(&mut self, scope_id: u32) {
567        self.scope_id = scope_id
568    }
569
570    /// Returns true if this is a unspecified address.
571    pub fn is_unspecified(&self) -> bool {
572        self.bytes.iter().all(|&x| x == 0)
573    }
574
575    /// Returns true if this is a loopback address.
576    pub fn is_loopback(&self) -> bool {
577        (self.bytes[0] == 0 && self.bytes[1] == 0 && self.bytes[2] == 0 && self.bytes[3] == 0 &&
578         self.bytes[4] == 0 && self.bytes[5] == 0 && self.bytes[6] == 0 && self.bytes[7] == 0 &&
579         self.bytes[8] == 0 && self.bytes[9] == 0 && self.bytes[10] == 0 && self.bytes[11] == 0 &&
580         self.bytes[12] == 0 && self.bytes[13] == 0 && self.bytes[14] == 0 && self.bytes[15] == 1)
581    }
582
583    /// Returns true if this is a link-local address.
584    pub fn is_link_local(&self) -> bool {
585        self.bytes[0] == 0xFE && (self.bytes[1] & 0xC0) == 0x80
586    }
587
588    /// Returns true if this is a site-local address.
589    pub fn is_site_local(&self) -> bool {
590        self.bytes[0] == 0xFE && (self.bytes[1] & 0xC0) == 0xC0
591    }
592
593    /// Returns true if this is a some multicast address.
594    pub fn is_multicast(&self) -> bool {
595        self.bytes[0] == 0xFF
596    }
597
598    /// Returns true if this is a multicast address for global.
599    pub fn is_multicast_global(&self) -> bool {
600        self.bytes[0] == 0xFF && (self.bytes[1] & 0x0F) == 0x0E
601    }
602
603    /// Returns true if this is a multicast address for link-local.
604    pub fn is_multicast_link_local(&self) -> bool {
605        self.bytes[0] == 0xFF && (self.bytes[1] & 0x0F) == 0x02
606    }
607
608    /// Returns true if this is a multicast address for node-local.
609    pub fn is_multicast_node_local(&self) -> bool {
610        self.bytes[0] == 0xFF && (self.bytes[1] & 0x0F) == 0x01
611    }
612
613    /// Returns true if this is a multicast address for org-local.
614    pub fn is_multicast_org_local(&self) -> bool {
615        self.bytes[0] == 0xFF && (self.bytes[1] & 0x0F) == 0x08
616    }
617
618    /// Returns true if this is a multicast address for site-local.
619    pub fn is_multicast_site_local(&self) -> bool {
620        self.bytes[0] == 0xFF && (self.bytes[1] & 0x0F) == 0x05
621    }
622
623    /// Returns true if this is a mapped IP-v4 address.
624    pub fn is_v4_mapped(&self) -> bool {
625        (self.bytes[0] == 0 && self.bytes[1] == 0 && self.bytes[2] == 0 && self.bytes[3] == 0 &&
626         self.bytes[4] == 0 && self.bytes[5] == 0 && self.bytes[6] == 0 && self.bytes[7] == 0 &&
627         self.bytes[8] == 0 && self.bytes[9] == 0 && self.bytes[10] == 0xFF && self.bytes[11] == 0xFF)
628    }
629
630    /// Returns true if this is a IP-v4 compatible address.
631    pub fn is_v4_compatible(&self) -> bool {
632        ((self.bytes[0] == 0 && self.bytes[1] == 0 && self.bytes[2] == 0 && self.bytes[3] == 0 &&
633          self.bytes[4] == 0 && self.bytes[5] == 0 && self.bytes[6] == 0 && self.bytes[7] == 0 &&
634          self.bytes[8] == 0 && self.bytes[9] == 0 && self.bytes[10] == 0 && self.bytes[11] == 0)
635         && !(self.bytes[12] == 0 && self.bytes[13] == 0 && self.bytes[14] == 0
636              && (self.bytes[15] == 0 || self.bytes[15] == 1)))
637    }
638
639    /// Retruns a 16 octets array.
640    pub fn as_bytes(&self) -> &[u8; 16] {
641        &self.bytes
642    }
643
644    /// Retruns a IP-v4 address if this is a convertable address.
645    pub fn to_v4(&self) -> Option<IpAddrV4> {
646        if self.is_v4_mapped() || self.is_v4_compatible() {
647            Some(IpAddrV4 { bytes: [ self.bytes[12], self.bytes[13], self.bytes[14], self.bytes[15] ] })
648        } else {
649            None
650        }
651    }
652
653    /// Returns a mapped IP-v4 address.
654    ///
655    /// Ex. 192.168.0.1 => ::ffff:192.168.0.1
656    pub fn v4_mapped(addr: &IpAddrV4) -> Self {
657        IpAddrV6 {
658            scope_id: 0,
659            bytes: [0,0,0,0,0,0,0,0,0,0,0xFF,0xFF,
660                    addr.bytes[0], addr.bytes[1], addr.bytes[2], addr.bytes[3]]
661        }
662    }
663
664    /// Returns a IP-v4 compatible address if the `addr` isn't in `0.0.0.0`, `0.0.0.1`.
665    ///
666    /// Ex. 192.168.0.1 => ::192.168.0.1
667    pub fn v4_compatible(addr: &IpAddrV4) -> Option<Self> {
668        if addr.bytes[0] == 0 && addr.bytes[1] == 0 && addr.bytes[2] == 0
669            && (addr.bytes[3] == 0 || addr.bytes[3] == 1)
670        {
671            None
672        } else {
673            Some(IpAddrV6 {
674                scope_id: 0,
675                bytes: [0,0,0,0,0,0,0,0,0,0,0,0,
676                        addr.bytes[0], addr.bytes[1], addr.bytes[2], addr.bytes[3]]
677            })
678        }
679    }
680}
681
682impl AddAssign<i64> for IpAddrV6 {
683    fn add_assign(&mut self, rhs: i64) {
684        add_assign(&mut self.bytes, rhs)
685    }
686}
687
688impl SubAssign<i64> for IpAddrV6 {
689    fn sub_assign(&mut self, rhs: i64) {
690        sub_assign(&mut self.bytes, rhs)
691    }
692}
693
694impl fmt::Display for IpAddrV6 {
695    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
696        fmt_v6(&self.bytes, f)
697    }
698}
699
700impl fmt::Debug for IpAddrV6 {
701    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
702        write!(f, "{}", self)
703    }
704}
705
706impl From<[u8; 16]> for IpAddrV6 {
707    fn from(bytes: [u8; 16]) -> Self {
708        IpAddrV6 { scope_id: 0, bytes: bytes }
709    }
710}
711
712/// Implements version-independent IP addresses.
713#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
714pub enum IpAddr {
715    V4(IpAddrV4),
716    V6(IpAddrV6),
717}
718
719impl IpAddr {
720    /// Return true if this is unspecified address.
721    pub fn is_unspecified(&self) -> bool {
722        match self {
723            &IpAddr::V4(ref addr) => addr.is_unspecified(),
724            &IpAddr::V6(ref addr) => addr.is_unspecified(),
725        }
726    }
727
728    /// Return true if this is loopback address.
729    pub fn is_loopback(&self) -> bool {
730        match self {
731            &IpAddr::V4(ref addr) => addr.is_loopback(),
732            &IpAddr::V6(ref addr) => addr.is_loopback(),
733        }
734    }
735
736    /// Return true if this is multicast address.
737    pub fn is_multicast(&self) -> bool {
738        match self {
739            &IpAddr::V4(ref addr) => addr.is_multicast(),
740            &IpAddr::V6(ref addr) => addr.is_multicast(),
741        }
742    }
743
744    /// Returns bytes of `&[u8; 4]` or `&[u8; 16]`.
745    pub fn as_bytes(&self) -> &[u8] {
746        match self {
747            &IpAddr::V4(ref addr) => addr.as_bytes(),
748            &IpAddr::V6(ref addr) => addr.as_bytes(),
749        }
750    }
751}
752
753impl AddAssign<i64> for IpAddr {
754    fn add_assign(&mut self, rhs: i64) {
755         match self {
756             &mut IpAddr::V4(ref mut addr) => addr.add_assign(rhs),
757             &mut IpAddr::V6(ref mut addr) => addr.add_assign(rhs),
758        }
759    }
760}
761
762impl SubAssign<i64> for IpAddr {
763    fn sub_assign(&mut self, rhs: i64) {
764         match self {
765             &mut IpAddr::V4(ref mut addr) => addr.sub_assign(rhs),
766             &mut IpAddr::V6(ref mut addr) => addr.sub_assign(rhs),
767         }
768    }
769}
770
771impl fmt::Display for IpAddr {
772    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
773        match self {
774            &IpAddr::V4(ref addr) => write!(f, "{}", addr),
775            &IpAddr::V6(ref addr) => write!(f, "{}", addr),
776        }
777    }
778}
779
780impl fmt::Debug for IpAddr {
781    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
782        write!(f, "{}", self)
783    }
784}
785
786/// Implements Prefix IP version 4 style addresses.
787pub struct PrefixIpAddrV4 {
788    bytes: [u8; 4],
789    len: u8,
790}
791
792impl PrefixIpAddrV4 {
793    fn masking(lhs: IpAddrV4, rhs: IpAddrV4) -> [u8; 4] {
794        unsafe {
795            let lhs: u32 = mem::transmute(lhs);
796            let rhs: u32 = mem::transmute(rhs);
797            mem::transmute(lhs & rhs)
798        }
799    }
800
801    /// Returns new PrefixIpAddrV4.
802    ///
803    /// # Examples
804    ///
805    /// ```
806    /// use asyncio::ip::{IpAddrV4, PrefixIpAddrV4};
807    ///
808    /// assert!(PrefixIpAddrV4::new(IpAddrV4::new(192,168,100,1),
809    ///                             IpAddrV4::new(255,255,255,0)).is_some());
810    ///
811    /// assert!(PrefixIpAddrV4::new(IpAddrV4::new(192,168,100,1),
812    ///                             IpAddrV4::new(0,0,0,255)).is_none());
813    /// ```
814    pub fn new(addr: IpAddrV4, netmask: IpAddrV4) -> Option<PrefixIpAddrV4> {
815        let len = netmask_len(&netmask.bytes);
816        debug_assert!(len <= 32);
817        if len != 0 {
818            Some(PrefixIpAddrV4 {
819                bytes: Self::masking(addr, netmask),
820                len: len,
821            })
822        } else {
823            None
824        }
825    }
826
827    /// Returns new PrefixIpAddrV4.
828    ///
829    /// # Panics
830    /// Panics if len == 0 or len > 32
831    ///
832    /// ```rust,no_run
833    /// use asyncio::ip::{IpAddrV4, PrefixIpAddrV4};
834    ///
835    /// PrefixIpAddrV4::from(IpAddrV4::any(), 0);  // panic!
836    /// ```
837    pub fn from(addr: IpAddrV4, len: u8) -> PrefixIpAddrV4 {
838        assert!(0 < len && len <= 32);
839        PrefixIpAddrV4 {
840            bytes: Self::masking(addr, (u32::max_value() << (32 - len)).into()),
841            len: len,
842        }
843    }
844
845    /// Returns a network address.
846    ///
847    /// # Examples
848    ///
849    /// ```
850    /// use asyncio::ip::{IpAddrV4, PrefixIpAddrV4};
851    ///
852    /// let lo = PrefixIpAddrV4::from(IpAddrV4::loopback(), 8);
853    /// assert_eq!(lo.network(), IpAddrV4::new(127,0,0,0));
854    /// ```
855    pub fn network(&self) -> IpAddrV4 {
856        self.bytes.into()
857    }
858
859    /// Returns a subnet mask.
860    ///
861    /// # Examples
862    ///
863    /// ```
864    /// use asyncio::ip::{IpAddrV4, PrefixIpAddrV4};
865    ///
866    /// let lo = PrefixIpAddrV4::from(IpAddrV4::loopback(), 8);
867    /// assert_eq!(lo.netmask(), IpAddrV4::new(255,0,0,0));
868    /// ```
869    pub fn netmask(&self) -> IpAddrV4 {
870        (u32::max_value() << (32 - self.len)).into()
871    }
872
873    /// Returns a length of subnet mask.
874    pub fn netmask_len(&self) -> u8 {
875        self.len
876    }
877}
878
879impl fmt::Display for PrefixIpAddrV4 {
880    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
881        write!(f, "{}.{}.{}.{}/{}", self.bytes[0], self.bytes[1], self.bytes[2], self.bytes[3], self.len)
882    }
883}
884
885impl fmt::Debug for PrefixIpAddrV4 {
886    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
887        write!(f, "{}", self)
888    }
889}
890
891/// Implements Prefix IP version 6 style addresses.
892pub struct PrefixIpAddrV6 {
893    bytes: [u8; 16],
894    len: u8,
895}
896
897impl PrefixIpAddrV6 {
898    fn masking(lhs: [u8; 16], rhs: [u8; 16]) -> [u8; 16] {
899        unsafe {
900            let lhs: [u64; 2] = mem::transmute(lhs);
901            let rhs: [u64; 2] = mem::transmute(rhs);
902            mem::transmute([lhs[0] & rhs[0], lhs[1] & rhs[1]])
903        }
904    }
905
906    fn make_netmask(len: u8) -> [u8; 16] {
907        let bytes = match len.cmp(&64) {
908            Ordering::Less => [(!((1u64 << (64 - len)) - 1)).to_be(), 0],
909            Ordering::Equal => [u64::max_value(), 0],
910            Ordering::Greater => [u64::max_value(), (!((1u64 << (128 - len)) - 1)).to_be()],
911        };
912        unsafe { mem::transmute(bytes) }
913    }
914
915    /// Returns new PrefixIpAddrV6.
916    ///
917    /// # Examples
918    ///
919    /// ```
920    /// use asyncio::ip::{IpAddrV6, PrefixIpAddrV6};
921    ///
922    /// assert!(PrefixIpAddrV6::new(IpAddrV6::loopback(),
923    ///                             IpAddrV6::new(0xffff,0xffff,0xffff,0xffff,0,0,0,0)).is_some());
924    ///
925    /// assert!(PrefixIpAddrV6::new(IpAddrV6::loopback(),
926    ///                             IpAddrV6::any()).is_none());
927    /// ```
928    pub fn new(addr: IpAddrV6, netmask: IpAddrV6) -> Option<PrefixIpAddrV6> {
929        let len = netmask_len(&netmask.bytes);
930        debug_assert!(len <= 128);
931        if len != 0 {
932            Some(PrefixIpAddrV6 {
933                bytes: Self::masking(addr.bytes, netmask.bytes),
934                len: len,
935            })
936        } else {
937            None
938        }
939    }
940
941    /// Returns new PrefixIpAddrV6.
942    ///
943    /// # Panics
944    ///
945    /// Panics if len == 0 or len > 128
946    ///
947    /// ```rust,no_run
948    /// use asyncio::ip::{IpAddrV6, PrefixIpAddrV6};
949    ///
950    /// PrefixIpAddrV6::from(IpAddrV6::loopback(), 0);  // panic!
951    /// ```
952    pub fn from(addr: IpAddrV6, len: u8) -> PrefixIpAddrV6 {
953        assert!(0 < len && len <= 128);
954        PrefixIpAddrV6 {
955            bytes: Self::masking(addr.bytes, Self::make_netmask(len)),
956            len: len,
957        }
958    }
959
960    /// Returns a prefix address.
961    ///
962    /// # Examples
963    ///
964    /// ```
965    /// use asyncio::ip::{IpAddrV6, PrefixIpAddrV6};
966    ///
967    /// let lo = PrefixIpAddrV6::from(IpAddrV6::loopback(), 64);
968    /// assert_eq!(lo.prefix(), IpAddrV6::any());
969    /// ```
970    pub fn prefix(&self) -> IpAddrV6 {
971        self.bytes.into()
972    }
973
974    /// Returns a subnet mask.
975    ///
976    /// # Examples
977    ///
978    /// ```
979    /// use asyncio::ip::{IpAddrV6, PrefixIpAddrV6};
980    ///
981    /// let lo = PrefixIpAddrV6::from(IpAddrV6::loopback(), 64);
982    /// assert_eq!(lo.netmask(), IpAddrV6::new(0xffff,0xffff,0xffff,0xffff,0,0,0,0));
983    /// ```
984    pub fn netmask(&self) -> IpAddrV6 {
985        Self::make_netmask(self.len).into()
986    }
987
988    /// Returns a length of subnet mask.
989    pub fn netmask_len(&self) -> u8 {
990        self.len
991    }
992}
993
994impl fmt::Display for PrefixIpAddrV6 {
995    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
996        try!(fmt_v6(&self.bytes, f));
997        write!(f, "/{}", self.len)
998    }
999}
1000
1001impl fmt::Debug for PrefixIpAddrV6 {
1002    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1003        write!(f, "{}", self)
1004    }
1005}
1006
1007#[test]
1008fn test_lladdr() {
1009    assert_eq!(LlAddr::default().bytes, [0,0,0,0,0,0]);
1010    assert_eq!(LlAddr::new(1,2,3,4,5,6).bytes, [1,2,3,4,5,6]);
1011    assert!(LlAddr::new(1,2,3,4,5,6) == LlAddr::from([1,2,3,4,5,6]));
1012    assert!(LlAddr::new(1,2,3,4,5,6) < LlAddr::new(1,2,3,4,5,7));
1013    assert!(LlAddr::new(1,2,3,4,5,6) < LlAddr::new(1,2,3,4,6,0));
1014    assert!(LlAddr::new(1,2,3,4,5,6) < LlAddr::new(1,2,3,5,0,0));
1015    assert!(LlAddr::new(1,2,3,4,5,6) < LlAddr::new(1,2,4,0,0,0));
1016    assert!(LlAddr::new(1,2,3,4,5,6) < LlAddr::new(1,3,0,0,0,0));
1017    assert!(LlAddr::new(1,2,3,4,5,6) < LlAddr::new(2,0,0,0,0,0));
1018}
1019
1020#[test]
1021fn test_lladdr_format() {
1022    assert_eq!(format!("{}", LlAddr::new(1,2,3,4,5,6)), "01:02:03:04:05:06");
1023    assert_eq!(format!("{}", LlAddr::new(0xAA,0xBB,0xCC,0xDD,0xEE,0xFF)), "AA:BB:CC:DD:EE:FF");
1024}
1025
1026#[test]
1027fn test_ipaddr_v4() {
1028    assert_eq!(IpAddrV4::default().bytes, [0,0,0,0]);
1029    assert_eq!(IpAddrV4::new(1,2,3,4).bytes, [1,2,3,4]);
1030    assert_eq!(IpAddrV4::new(1,2,3,4), IpAddrV4::from([1,2,3,4]));
1031    assert!(IpAddrV4::new(1,2,3,4) < IpAddrV4::new(1,2,3,5));
1032    assert!(IpAddrV4::new(1,2,3,4) < IpAddrV4::new(1,2,4,0));
1033    assert!(IpAddrV4::new(1,2,3,4) < IpAddrV4::new(1,3,0,0));
1034    assert!(IpAddrV4::new(1,2,3,4) < IpAddrV4::new(2,0,0,0));
1035}
1036
1037#[test]
1038fn test_ipaddr_v4_format() {
1039    assert_eq!(format!("{}", IpAddrV4::any()), "0.0.0.0");
1040    assert_eq!(format!("{}", IpAddrV4::loopback()), "127.0.0.1");
1041}
1042
1043#[test]
1044fn test_ipaddr_v4_add() {
1045    let mut a = IpAddrV4::new(192,168,0,1);
1046    a += 1;
1047    assert_eq!(a, IpAddrV4::new(192,168,0,2));
1048    a += 100;
1049    assert_eq!(a, IpAddrV4::new(192,168,0,102));
1050    a += 256*10;
1051    assert_eq!(a, IpAddrV4::new(192,168,10,102));
1052}
1053
1054#[test]
1055fn test_ipaddr_v4_sub() {
1056    let mut a = IpAddrV4::new(192,168,0,1);
1057    a -= 1;
1058    assert_eq!(a, IpAddrV4::new(192,168,0,0));
1059    a -= 100;
1060    assert_eq!(a, IpAddrV4::new(192,167,255,156));
1061    a -= 256*10;
1062    assert_eq!(a, IpAddrV4::new(192,167,245,156));
1063}
1064
1065#[test]
1066fn test_ipaddr_v6() {
1067    assert_eq!(IpAddrV6::default().bytes, [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]);
1068    assert_eq!(IpAddrV6::new(0x0102,0x0304,0x0506,0x0708,0x090a,0x0b0c,0x0d0e,0x0f10).bytes,
1069               [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]);
1070    assert_eq!(IpAddrV6::new(0x0102,0x0304,0x0506,0x0708,0x090a,0x0b0c,0x0d0e,0x0f10),
1071               IpAddrV6::from([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16], 0));
1072    assert_eq!(IpAddrV6::with_scope_id(0,0,0,0,0,0,0,0,100).get_scope_id(), 100);
1073    assert!(IpAddrV6::from([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16], 0) <
1074            IpAddrV6::from([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,17], 0));
1075    assert!(IpAddrV6::from([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16], 0) <
1076            IpAddrV6::from([1,2,3,4,5,6,7,8,9,10,11,12,13,14,16,00], 0));
1077    assert!(IpAddrV6::from([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16], 0) <
1078            IpAddrV6::from([1,2,3,4,5,6,7,8,9,10,11,12,13,15,00,00], 0));
1079}
1080
1081#[test]
1082fn test_ipaddr_v6_format() {
1083    assert_eq!(format!("{}", IpAddrV6::any()), "::");
1084    assert_eq!(format!("{}", IpAddrV6::loopback()), "::1");
1085    assert_eq!(format!("{}", IpAddrV6::new(1,2,3,4,5,6,7,8)), "1:2:3:4:5:6:7:8");
1086    assert_eq!(format!("{}", IpAddrV6::new(0,2,3,4,5,6,7,8)), "::2:3:4:5:6:7:8");
1087    assert_eq!(format!("{}", IpAddrV6::new(1,2,3,4,5,6,7,0)), "1:2:3:4:5:6:7::");
1088    assert_eq!(format!("{}", IpAddrV6::new(1,2,3,4,0,6,7,8)), "1:2:3:4::6:7:8");
1089    assert_eq!(format!("{}", IpAddrV6::new(1,0,0,0,0,0,0,8)), "1::8");
1090}
1091
1092#[test]
1093fn test_add_assign() {
1094    let mut a = [0,0];
1095    add_assign(&mut a, 0xFF);
1096    assert_eq!(&a, &[0, 0xFF]);
1097    add_assign(&mut a, 0x01);
1098    assert_eq!(&a, &[1, 0]);
1099    add_assign(&mut a, 0x101);
1100    assert_eq!(&a, &[2, 1]);
1101}
1102
1103#[test]
1104#[should_panic]
1105fn test_add_assign_overflow() {
1106    let mut a = [0xFF, 0xFF];
1107    add_assign(&mut a, 1);
1108}
1109
1110#[test]
1111fn test_sub_assign() {
1112    let mut a = [0xFF, 0xFF];
1113    sub_assign(&mut a, 0xFF);
1114    assert_eq!(&a, &[0xFF, 0]);
1115    sub_assign(&mut a, 0x01);
1116    assert_eq!(&a, &[0xFE, 0xFF]);
1117    sub_assign(&mut a, 0x101);
1118    assert_eq!(&a, &[0xFD, 0xFE]);
1119}
1120
1121#[test]
1122#[should_panic]
1123fn test_sub_assign_underflow() {
1124    let mut a = [0, 0];
1125    sub_assign(&mut a, 1);
1126}
1127
1128#[test]
1129fn test_ipaddr_as_bytes() {
1130    let bytes = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16];
1131    let v4 = IpAddr::V4(IpAddrV4::new(1,2,3,4));
1132    assert!(v4.as_bytes() == &bytes[..4]);
1133    assert!(v4.as_bytes() != &bytes[..5]);
1134    assert!(v4.as_bytes() != &bytes[1..5]);
1135
1136    let v6 = IpAddr::V6(IpAddrV6::from(bytes.clone(), 0));
1137    assert!(v6.as_bytes() == &bytes[..]);
1138    assert!(v6.as_bytes() != v4.as_bytes());
1139}
1140
1141#[test]
1142fn test_netmask_len() {
1143    assert_eq!(netmask_len(&[255,255,255,0]), 24);
1144    assert_eq!(netmask_len(&[255,255,255,255]), 32);
1145    assert_eq!(netmask_len(&[255,255,254,0]), 23);
1146    assert_eq!(netmask_len(&[255,255,255,254]), 31);
1147    assert_eq!(netmask_len(&[128,0,0,0]), 1);
1148
1149    assert_eq!(netmask_len(&[0,0,0,0]), 0);
1150    assert_eq!(netmask_len(&[1,1,1,1]), 0);
1151    assert_eq!(netmask_len(&[128,1,1,1]), 0);
1152}
1153
1154#[test]
1155fn test_prefix_ipaddr_v4() {
1156    let ip = PrefixIpAddrV4::new(IpAddrV4::new(192,168,0,1), IpAddrV4::new(255,255,255,0)).unwrap();
1157    assert_eq!(ip.network(), IpAddrV4::new(192,168,0,0));
1158    assert_eq!(ip.netmask(), IpAddrV4::new(255,255,255,0));
1159    assert_eq!(ip.netmask_len(), 24);
1160
1161    let ip = PrefixIpAddrV4::new(IpAddrV4::new(192,168,255,1), IpAddrV4::new(255,255,240,0)).unwrap();
1162    assert_eq!(ip.network(), IpAddrV4::new(192,168,240,0));
1163    assert_eq!(ip.netmask(), IpAddrV4::new(255,255,240,0));
1164    assert_eq!(ip.netmask_len(), 20);
1165}
1166
1167#[test]
1168#[should_panic]
1169fn test_prefix_ipaddr_v4_from_panic() {
1170    PrefixIpAddrV4::from(IpAddrV4::loopback(), 0);
1171}
1172
1173#[test]
1174fn test_prefix_ipaddr_v4_format() {
1175    let ip = PrefixIpAddrV4::new(IpAddrV4::new(192,168,0,1), IpAddrV4::new(255,255,255,0)).unwrap();
1176    assert_eq!(format!("{}", ip), "192.168.0.0/24");
1177}
1178
1179#[test]
1180fn test_prefix_ipaddr_v6_half() {
1181    let netmask = IpAddrV6::new(0xffff,0xffff,0xffff,0xffff,0,0,0,0);
1182    let ip = PrefixIpAddrV6::new(IpAddrV6::new(0x2001,0,0,0,0,0,0xdead,0xbeaf), netmask.clone()).unwrap();
1183    assert_eq!(ip.prefix(), IpAddrV6::new(0x2001,0,0,0,0,0,0,0));
1184    assert_eq!(ip.netmask(), netmask);
1185    assert_eq!(ip.netmask_len(), 64);
1186}
1187
1188#[test]
1189fn test_prefix_ipaddr_v6_long() {
1190    let netmask = IpAddrV6::new(0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xfff0);
1191    let ip = PrefixIpAddrV6::new(IpAddrV6::new(0x2001,0,0,0,0,0,0xdead, 0xbeaf), netmask.clone()).unwrap();
1192    assert_eq!(ip.prefix(), IpAddrV6::new(0x2001,0,0,0,0,0,0xdead,0xbea0));
1193    assert_eq!(ip.netmask(), netmask);
1194    assert_eq!(ip.netmask_len(), 124);
1195}
1196
1197#[test]
1198fn test_prefix_ipaddr_v6_short() {
1199    let netmask = IpAddrV6::new(0xfe00, 0,0,0,0,0,0,0);
1200    let ip = PrefixIpAddrV6::new(IpAddrV6::new(0x2001,0,0,0,0,0,0xdead, 0xbeaf), netmask.clone()).unwrap();
1201    assert_eq!(ip.prefix(), IpAddrV6::new(0x2000,0,0,0,0,0,0,0));
1202    assert_eq!(ip.netmask(), netmask);
1203    assert_eq!(ip.netmask_len(), 7);
1204}
1205
1206#[test]
1207#[should_panic]
1208fn test_prefix_ipaddr_v6_from_panic() {
1209    PrefixIpAddrV6::from(IpAddrV6::loopback(), 0);
1210}
1211
1212#[test]
1213fn test_prefix_ipaddr_v6_format() {
1214    let ip = PrefixIpAddrV6::from(IpAddrV6::loopback(), 64);
1215    assert_eq!(format!("{}", ip), "::/64");
1216
1217    let ip = PrefixIpAddrV6::from(IpAddrV6::new(0xdead,0xbeaf,0,0,0,0,0,0), 32);
1218    assert_eq!(format!("{}", ip), "dead:beaf::/32");
1219}