@@ -59,6 +59,48 @@ pub enum Ipv6MulticastScope {
59
59
Global
60
60
}
61
61
62
+ impl IpAddr {
63
+ /// Returns true for the special 'unspecified' address (0.0.0.0 in IPv4, :: in IPv6).
64
+ pub fn is_unspecified ( & self ) -> bool {
65
+ match * self {
66
+ IpAddr :: V4 ( ref a) => a. is_unspecified ( ) ,
67
+ IpAddr :: V6 ( ref a) => a. is_unspecified ( ) ,
68
+ }
69
+ }
70
+
71
+ /// Returns true if this is a loopback address (127.0.0.0/8 in IPv4, ::1 in IPv6).
72
+ pub fn is_loopback ( & self ) -> bool {
73
+ match * self {
74
+ IpAddr :: V4 ( ref a) => a. is_loopback ( ) ,
75
+ IpAddr :: V6 ( ref a) => a. is_loopback ( ) ,
76
+ }
77
+ }
78
+
79
+ /// Returns true if the address appears to be globally routable.
80
+ pub fn is_global ( & self ) -> bool {
81
+ match * self {
82
+ IpAddr :: V4 ( ref a) => a. is_global ( ) ,
83
+ IpAddr :: V6 ( ref a) => a. is_global ( ) ,
84
+ }
85
+ }
86
+
87
+ /// Returns true if this is a multicast address (224.0.0.0/4 in IPv4, ff00::/8 in IPv6)
88
+ pub fn is_multicast ( & self ) -> bool {
89
+ match * self {
90
+ IpAddr :: V4 ( ref a) => a. is_multicast ( ) ,
91
+ IpAddr :: V6 ( ref a) => a. is_multicast ( ) ,
92
+ }
93
+ }
94
+
95
+ /// Returns true if this address is in a range designated for documentation.
96
+ pub fn is_documentation ( & self ) -> bool {
97
+ match * self {
98
+ IpAddr :: V4 ( ref a) => a. is_documentation ( ) ,
99
+ IpAddr :: V6 ( ref a) => a. is_documentation ( ) ,
100
+ }
101
+ }
102
+ }
103
+
62
104
impl Ipv4Addr {
63
105
/// Creates a new IPv4 address from four eight-bit octets.
64
106
///
@@ -756,6 +798,67 @@ mod tests {
756
798
None ) ;
757
799
}
758
800
801
+ #[ test]
802
+ fn ip_properties ( ) {
803
+ fn check4 ( octets : & [ u8 ; 4 ] , unspec : bool , loopback : bool ,
804
+ global : bool , multicast : bool , documentation : bool ) {
805
+ let ip = IpAddr :: V4 ( Ipv4Addr :: new ( octets[ 0 ] , octets[ 1 ] , octets[ 2 ] , octets[ 3 ] ) ) ;
806
+ assert_eq ! ( ip. is_unspecified( ) , unspec) ;
807
+ assert_eq ! ( ip. is_loopback( ) , loopback) ;
808
+ assert_eq ! ( ip. is_global( ) , global) ;
809
+ assert_eq ! ( ip. is_multicast( ) , multicast) ;
810
+ assert_eq ! ( ip. is_documentation( ) , documentation) ;
811
+ }
812
+
813
+ fn check6 ( str_addr : & str , unspec : bool , loopback : bool ,
814
+ global : bool , u_doc : bool , mcast : bool ) {
815
+ let ip = IpAddr :: V6 ( str_addr. parse ( ) . unwrap ( ) ) ;
816
+ assert_eq ! ( ip. is_unspecified( ) , unspec) ;
817
+ assert_eq ! ( ip. is_loopback( ) , loopback) ;
818
+ assert_eq ! ( ip. is_global( ) , global) ;
819
+ assert_eq ! ( ip. is_documentation( ) , u_doc) ;
820
+ assert_eq ! ( ip. is_multicast( ) , mcast) ;
821
+ }
822
+
823
+ // address unspec loopbk global multicast doc
824
+ check4 ( & [ 0 , 0 , 0 , 0 ] , true , false , false , false , false ) ;
825
+ check4 ( & [ 0 , 0 , 0 , 1 ] , false , false , true , false , false ) ;
826
+ check4 ( & [ 0 , 1 , 0 , 0 ] , false , false , true , false , false ) ;
827
+ check4 ( & [ 10 , 9 , 8 , 7 ] , false , false , false , false , false ) ;
828
+ check4 ( & [ 127 , 1 , 2 , 3 ] , false , true , false , false , false ) ;
829
+ check4 ( & [ 172 , 31 , 254 , 253 ] , false , false , false , false , false ) ;
830
+ check4 ( & [ 169 , 254 , 253 , 242 ] , false , false , false , false , false ) ;
831
+ check4 ( & [ 192 , 0 , 2 , 183 ] , false , false , false , false , true ) ;
832
+ check4 ( & [ 192 , 1 , 2 , 183 ] , false , false , true , false , false ) ;
833
+ check4 ( & [ 192 , 168 , 254 , 253 ] , false , false , false , false , false ) ;
834
+ check4 ( & [ 198 , 51 , 100 , 0 ] , false , false , false , false , true ) ;
835
+ check4 ( & [ 203 , 0 , 113 , 0 ] , false , false , false , false , true ) ;
836
+ check4 ( & [ 203 , 2 , 113 , 0 ] , false , false , true , false , false ) ;
837
+ check4 ( & [ 224 , 0 , 0 , 0 ] , false , false , true , true , false ) ;
838
+ check4 ( & [ 239 , 255 , 255 , 255 ] , false , false , true , true , false ) ;
839
+ check4 ( & [ 255 , 255 , 255 , 255 ] , false , false , false , false , false ) ;
840
+
841
+ // address unspec loopbk global doc mcast
842
+ check6 ( "::" , true , false , false , false , false ) ;
843
+ check6 ( "::1" , false , true , false , false , false ) ;
844
+ check6 ( "::0.0.0.2" , false , false , true , false , false ) ;
845
+ check6 ( "1::" , false , false , true , false , false ) ;
846
+ check6 ( "fc00::" , false , false , false , false , false ) ;
847
+ check6 ( "fdff:ffff::" , false , false , false , false , false ) ;
848
+ check6 ( "fe80:ffff::" , false , false , false , false , false ) ;
849
+ check6 ( "febf:ffff::" , false , false , false , false , false ) ;
850
+ check6 ( "fec0::" , false , false , false , false , false ) ;
851
+ check6 ( "ff01::" , false , false , false , false , true ) ;
852
+ check6 ( "ff02::" , false , false , false , false , true ) ;
853
+ check6 ( "ff03::" , false , false , false , false , true ) ;
854
+ check6 ( "ff04::" , false , false , false , false , true ) ;
855
+ check6 ( "ff05::" , false , false , false , false , true ) ;
856
+ check6 ( "ff08::" , false , false , false , false , true ) ;
857
+ check6 ( "ff0e::" , false , false , true , false , true ) ;
858
+ check6 ( "2001:db8:85a3::8a2e:370:7334" , false , false , false , true , false ) ;
859
+ check6 ( "102:304:506:708:90a:b0c:d0e:f10" , false , false , true , false , false ) ;
860
+ }
861
+
759
862
#[ test]
760
863
fn ipv4_properties ( ) {
761
864
fn check ( octets : & [ u8 ; 4 ] , unspec : bool , loopback : bool ,
0 commit comments