std:🥅 add Ipv6Addr::is_unicast_link_local_strict() · rust-lang/rust@1f0aa40 (original) (raw)

`@@ -1027,12 +1027,81 @@ impl Ipv6Addr {

`

1027

1027

`(self.segments()[0] & 0xfe00) == 0xfc00

`

1028

1028

`}

`

1029

1029

``

1030

``

`` -

/// Returns [true] if the address is unicast and link-local (fe80::/10).

``

``

1030

`` +

/// Returns [true] if the address is a unicast link-local address (fe80::/64).

``

1031

1031

`///

`

1032

``

`-

/// This property is defined in [IETF RFC 4291].

`

``

1032

`+

/// A common mis-conception is to think that "unicast link-local addresses start with

`

``

1033

`` +

/// fe80::", but the [IETF RFC 4291] actually defines a stricter format for these addresses:

``

1033

1034

`///

`

1034

``

`-

/// [IETF RFC 4291]: https://tools.ietf.org/html/rfc4291

`

``

1035


/// ```no_rust

``

1036

`+

/// | 10 |

`

``

1037

`+

/// | bits | 54 bits | 64 bits |

`

``

1038

`+

/// +----------+-------------------------+----------------------------+

`

``

1039

`+

/// |1111111010| 0 | interface ID |

`

``

1040

`+

/// +----------+-------------------------+----------------------------+

`

``

1041


/// ```

``

1042

`+

///

`

``

1043

`+

/// This method validates the format defined in the RFC and won't recognize the following

`

``

1044

`` +

/// addresses such as fe80:0:0:1:: or fe81:: as unicast link-local addresses for example.

``

``

1045

`` +

/// If you need a less strict validation use [is_unicast_link_local()] instead.

``

``

1046

`+

///

`

``

1047

`+

/// # Examples

`

``

1048

`+

///

`

``

1049


/// ```

``

1050

`+

/// #![feature(ip)]

`

``

1051

`+

///

`

``

1052

`+

/// use std:🥅:Ipv6Addr;

`

``

1053

`+

///

`

``

1054

`+

/// fn main() {

`

``

1055

`+

/// let ip = Ipv6Addr::new(0xfe80, 0, 0, 0, 0, 0, 0, 0);

`

``

1056

`+

/// assert!(ip.is_unicast_link_local_strict());

`

``

1057

`+

///

`

``

1058

`+

/// let ip = Ipv6Addr::new(0xfe80, 0, 0, 0, 0xffff, 0xffff, 0xffff, 0xffff);

`

``

1059

`+

/// assert!(ip.is_unicast_link_local_strict());

`

``

1060

`+

///

`

``

1061

`+

/// let ip = Ipv6Addr::new(0xfe80, 0, 0, 1, 0, 0, 0, 0);

`

``

1062

`+

/// assert!(!ip.is_unicast_link_local_strict());

`

``

1063

`+

/// assert!(ip.is_unicast_link_local());

`

``

1064

`+

///

`

``

1065

`+

/// let ip = Ipv6Addr::new(0xfe81, 0, 0, 0, 0, 0, 0, 0);

`

``

1066

`+

/// assert!(!ip.is_unicast_link_local_strict());

`

``

1067

`+

/// assert!(ip.is_unicast_link_local());

`

``

1068

`+

/// }

`

``

1069


/// ```

``

1070

`+

///

`

``

1071

`+

/// # See also

`

``

1072

`+

///

`

``

1073

`+

/// - [IETF RFC 4291 section 2.5.6]

`

``

1074

`+

/// - [RFC 4291 errata 4406]

`

``

1075

`+

///

`

``

1076

`+

/// [IETF RFC 4291 section 2.5.6]: https://tools.ietf.org/html/rfc4291#section-2.5.6

`

1035

1077

`` /// [true]: ../../std/primitive.bool.html

``

``

1078

`+

/// [RFC 4291 errata 4406]: https://www.rfc-editor.org/errata/eid4406

`

``

1079

`` +

/// is_unicast_link_local()

``

``

1080

`+

///

`

``

1081

`+

pub fn is_unicast_link_local_strict(&self) -> bool {

`

``

1082

`+

(self.segments()[0] & 0xffff) == 0xfe80

`

``

1083

`+

&& (self.segments()[1] & 0xffff) == 0

`

``

1084

`+

&& (self.segments()[2] & 0xffff) == 0

`

``

1085

`+

&& (self.segments()[3] & 0xffff) == 0

`

``

1086

`+

}

`

``

1087

+

``

1088

`` +

/// Returns [true] if the address is a unicast link-local address (fe80::/10).

``

``

1089

`+

///

`

``

1090

`` +

/// This method returns [true] for addresses in the range reserved by [RFC 4291 section 2.4],

``

``

1091

`+

/// i.e. addresses with the following format:

`

``

1092

`+

///

`

``

1093


/// ```no_rust

``

1094

`+

/// | 10 |

`

``

1095

`+

/// | bits | 54 bits | 64 bits |

`

``

1096

`+

/// +----------+-------------------------+----------------------------+

`

``

1097

`+

/// |1111111010| arbitratry value | interface ID |

`

``

1098

`+

/// +----------+-------------------------+----------------------------+

`

``

1099


/// ```

``

1100

`+

///

`

``

1101

`` +

/// As a result, this method consider addresses such as fe80:0:0:1:: or fe81:: to be

``

``

1102

`` +

/// unicast link-local addresses, whereas [is_unicast_link_local_strict()] does not. If you

``

``

1103

`+

/// need a strict validation fully compliant with the RFC, use

`

``

1104

`` +

/// [is_unicast_link_local_strict()].

``

1036

1105

`///

`

1037

1106

`/// # Examples

`

1038

1107

`///

`

`@@ -1042,11 +1111,32 @@ impl Ipv6Addr {

`

1042

1111

`/// use std:🥅:Ipv6Addr;

`

1043

1112

`///

`

1044

1113

`/// fn main() {

`

1045

``

`-

/// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_unicast_link_local(),

`

1046

``

`-

/// false);

`

1047

``

`-

/// assert_eq!(Ipv6Addr::new(0xfe8a, 0, 0, 0, 0, 0, 0, 0).is_unicast_link_local(), true);

`

``

1114

`+

/// let ip = Ipv6Addr::new(0xfe80, 0, 0, 0, 0, 0, 0, 0);

`

``

1115

`+

/// assert!(ip.is_unicast_link_local());

`

``

1116

`+

///

`

``

1117

`+

/// let ip = Ipv6Addr::new(0xfe80, 0, 0, 0, 0xffff, 0xffff, 0xffff, 0xffff);

`

``

1118

`+

/// assert!(ip.is_unicast_link_local());

`

``

1119

`+

///

`

``

1120

`+

/// let ip = Ipv6Addr::new(0xfe80, 0, 0, 1, 0, 0, 0, 0);

`

``

1121

`+

/// assert!(ip.is_unicast_link_local());

`

``

1122

`+

/// assert!(!ip.is_unicast_link_local_strict());

`

``

1123

`+

///

`

``

1124

`+

/// let ip = Ipv6Addr::new(0xfe81, 0, 0, 0, 0, 0, 0, 0);

`

``

1125

`+

/// assert!(ip.is_unicast_link_local());

`

``

1126

`+

/// assert!(!ip.is_unicast_link_local_strict());

`

1048

1127

`/// }

`

1049

1128

```` /// ```

````

``

1129

`+

///

`

``

1130

`+

/// # See also

`

``

1131

`+

///

`

``

1132

`+

/// - [IETF RFC 4291 section 2.4]

`

``

1133

`+

/// - [RFC 4291 errata 4406]

`

``

1134

`+

///

`

``

1135

`+

/// [IETF RFC 4291 section 2.4]: https://tools.ietf.org/html/rfc4291#section-2.4

`

``

1136

`` +

/// [true]: ../../std/primitive.bool.html

``

``

1137

`+

/// [RFC 4291 errata 4406]: https://www.rfc-editor.org/errata/eid4406

`

``

1138

`` +

/// is_unicast_link_local_strict()

``

``

1139

`+

///

`

1050

1140

`pub fn is_unicast_link_local(&self) -> bool {

`

1051

1141

`(self.segments()[0] & 0xffc0) == 0xfe80

`

1052

1142

`}

`