bgpkit_parser/models/network/
asn.rs1#[cfg(feature = "parser")]
2use bytes::{BufMut, Bytes, BytesMut};
3use std::cmp::Ordering;
4use std::fmt::{Debug, Display, Formatter};
5use std::hash::{Hash, Hasher};
6use std::str::FromStr;
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
10#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
11pub enum AsnLength {
12 Bits16,
13 Bits32,
14}
15
16impl AsnLength {
17 pub const fn is_four_byte(&self) -> bool {
18 match self {
19 AsnLength::Bits16 => false,
20 AsnLength::Bits32 => true,
21 }
22 }
23
24 pub const fn bytes(&self) -> usize {
26 match self {
27 AsnLength::Bits16 => 2,
28 AsnLength::Bits32 => 4,
29 }
30 }
31}
32
33#[derive(Clone, Copy, Eq)]
35#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
36#[cfg_attr(feature = "serde", serde(from = "u32", into = "u32"))]
37pub struct Asn {
38 asn: u32,
39 #[cfg_attr(feature = "serde", serde(skip_serializing, default))]
40 four_byte: bool,
41}
42
43impl Ord for Asn {
44 fn cmp(&self, other: &Self) -> Ordering {
45 self.asn.cmp(&other.asn)
46 }
47}
48
49impl Hash for Asn {
50 fn hash<H: Hasher>(&self, state: &mut H) {
51 self.asn.hash(state);
52 }
53}
54
55impl PartialEq for Asn {
56 fn eq(&self, other: &Self) -> bool {
57 self.asn == other.asn
58 }
59}
60
61impl PartialOrd for Asn {
62 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
63 Some(self.cmp(other))
64 }
65}
66
67impl Asn {
68 pub const RESERVED: Self = Asn::new_16bit(0);
69 #[doc(alias("AS_TRANS"))]
70 pub const TRANSITION: Self = Asn::new_16bit(23456);
71
72 #[inline]
74 pub const fn new_16bit(asn: u16) -> Self {
75 Asn {
76 asn: asn as u32,
77 four_byte: false,
78 }
79 }
80
81 #[inline]
83 pub const fn new_32bit(asn: u32) -> Self {
84 Asn {
85 asn,
86 four_byte: true,
87 }
88 }
89
90 pub const fn required_len(&self) -> AsnLength {
92 if self.asn <= u16::MAX as u32 {
93 return AsnLength::Bits16;
94 }
95
96 AsnLength::Bits32
97 }
98
99 #[inline]
103 pub const fn is_private(&self) -> bool {
104 match self.asn {
105 64512..=65534 => true, 4200000000..=4294967294 => true, _ => false,
108 }
109 }
110
111 #[inline]
122 pub const fn is_reserved(&self) -> bool {
123 match self.asn {
124 0 => true, 112 => true, 23456 => true, 64496..=64511 => true, 64512..=65534 => true, 65535 => true, 65536..=65551 => true, 4200000000..=4294967294 => true, 4294967295 => true, _ => false,
134 }
135 }
136
137 #[inline]
141 pub const fn is_reserved_for_documentation(&self) -> bool {
142 match self.asn {
143 64496..=64511 => true, 65536..=65551 => true, _ => false,
146 }
147 }
148
149 #[inline]
151 pub const fn is_four_byte(&self) -> bool {
152 self.four_byte
153 }
154
155 #[inline]
157 pub const fn to_u32(&self) -> u32 {
158 self.asn
159 }
160}
161
162impl Default for Asn {
164 #[inline]
165 fn default() -> Self {
166 Asn::RESERVED
167 }
168}
169
170impl PartialEq<u32> for Asn {
177 #[inline]
178 fn eq(&self, other: &u32) -> bool {
179 self.asn == *other
180 }
181}
182
183impl From<u32> for Asn {
184 #[inline]
185 fn from(v: u32) -> Self {
186 Asn::new_32bit(v)
187 }
188}
189
190impl From<Asn> for u32 {
191 #[inline]
192 fn from(value: Asn) -> Self {
193 value.asn
194 }
195}
196
197impl From<&Asn> for u32 {
198 #[inline]
199 fn from(value: &Asn) -> Self {
200 value.asn
201 }
202}
203
204impl PartialEq<i32> for Asn {
205 #[inline]
206 fn eq(&self, other: &i32) -> bool {
207 self.asn == *other as u32
208 }
209}
210
211impl From<i32> for Asn {
212 #[inline]
213 fn from(v: i32) -> Self {
214 Asn::new_32bit(v as u32)
215 }
216}
217
218impl From<Asn> for i32 {
219 #[inline]
220 fn from(value: Asn) -> Self {
221 value.asn as i32
222 }
223}
224
225impl From<&Asn> for i32 {
226 #[inline]
227 fn from(value: &Asn) -> Self {
228 value.asn as i32
229 }
230}
231
232impl PartialEq<u16> for Asn {
233 #[inline]
234 fn eq(&self, other: &u16) -> bool {
235 self.asn == *other as u32
236 }
237}
238
239impl From<u16> for Asn {
240 #[inline]
241 fn from(v: u16) -> Self {
242 Asn::new_16bit(v)
243 }
244}
245
246impl From<Asn> for u16 {
247 #[inline]
248 fn from(value: Asn) -> Self {
249 value.asn as u16
250 }
251}
252
253impl From<&Asn> for u16 {
254 #[inline]
255 fn from(value: &Asn) -> Self {
256 value.asn as u16
257 }
258}
259
260impl Display for Asn {
261 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
262 write!(f, "{}", self.asn)
263 }
264}
265
266impl Debug for Asn {
267 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
268 write!(f, "{}", self.asn)
269 }
270}
271
272impl FromStr for Asn {
274 type Err = <u32 as FromStr>::Err;
275
276 #[inline]
277 fn from_str(mut s: &str) -> Result<Self, Self::Err> {
278 if let Some(number) = s.strip_prefix("AS") {
279 s = number;
280 }
281
282 Ok(Asn::new_32bit(u32::from_str(s)?))
283 }
284}
285
286#[cfg(feature = "parser")]
287impl Asn {
288 pub fn encode(&self) -> Bytes {
289 let mut bytes = BytesMut::with_capacity(if self.four_byte { 4 } else { 2 });
290 match self.four_byte {
291 true => bytes.put_u32(self.asn),
292 false => bytes.put_u16(self.asn as u16),
293 }
294 bytes.freeze()
295 }
296}
297
298#[cfg(test)]
299mod tests {
300 use super::*;
301 #[cfg(feature = "parser")]
302 use crate::parser::ReadUtils;
303 use std::str::FromStr;
304
305 #[cfg(feature = "parser")]
306 #[test]
307 fn test_asn_encode() {
308 let asn = Asn::new_32bit(123);
309 let mut bytes = asn.encode();
310 assert_eq!(123, bytes.read_u32().unwrap());
311 }
312
313 #[test]
314 fn test_asn_is_reserved() {
315 let asn = Asn::new_32bit(0);
316 assert!(asn.is_reserved());
317
318 let asn = Asn::new_32bit(23456);
319 assert!(asn.is_reserved());
320
321 let asn = Asn::new_32bit(64513);
322 assert!(asn.is_reserved());
323
324 let asn = Asn::new_32bit(65535);
325 assert!(asn.is_reserved());
326
327 let asn = Asn::new_32bit(65536);
328 assert!(asn.is_reserved());
329
330 let asn = Asn::new_32bit(4200000000);
331 assert!(asn.is_reserved());
332
333 let asn = Asn::new_32bit(4294967295);
334 assert!(asn.is_reserved());
335
336 let asn = Asn::new_32bit(112);
337 assert!(asn.is_reserved());
338
339 let asn = Asn::new_32bit(400644);
340 assert!(!asn.is_reserved());
341 }
342
343 #[test]
344 fn test_asn_is_reserved_for_documentation() {
345 let asn = Asn::new_32bit(64497);
346 assert!(asn.is_reserved_for_documentation());
347
348 let asn = Asn::new_32bit(65537);
349 assert!(asn.is_reserved_for_documentation());
350
351 let asn = Asn::new_32bit(65535);
352 assert!(!asn.is_reserved_for_documentation());
353 }
354
355 #[test]
356 fn test_asn_is_private() {
357 let asn = Asn::new_32bit(64512);
358 assert!(asn.is_private());
359
360 let asn = Asn::new_32bit(4200000000);
361 assert!(asn.is_private());
362
363 let asn = Asn::new_32bit(4200000001);
364 assert!(asn.is_private());
365
366 let asn = Asn::new_32bit(400644);
367 assert!(!asn.is_private());
368 }
369
370 #[test]
371 fn test_asn_display() {
372 let asn = Asn::from_str("AS12345").unwrap();
373 assert_eq!(12345, asn.to_u32());
374 let asn = Asn::new_32bit(12345);
375 assert_eq!("12345", format!("{asn}"));
376 let asn = Asn::new_32bit(12345);
377 assert_eq!("12345", format!("{asn:?}"));
378 }
379
380 #[test]
381 fn test_default() {
382 assert_eq!(0, Asn::default().asn)
383 }
384
385 #[test]
386 fn test_conversion() {
387 let asn = Asn::from(12345);
389 assert_eq!(12345, asn.to_u32());
390
391 let asn = Asn::from(12345u16);
392 assert_eq!(12345, asn.to_u32());
393
394 let asn = Asn::from(12345i32);
395 assert_eq!(12345, asn.to_u32());
396
397 let asn = Asn::new_32bit(12345);
399 assert_eq!(12345, u32::from(asn));
400 assert_eq!(12345, u32::from(&asn));
401 assert_eq!(12345, i32::from(asn));
402 assert_eq!(12345, i32::from(&asn));
403 assert_eq!(asn, 12345u16);
404 assert_eq!(asn, 12345u32);
405
406 let asn = Asn::new_16bit(12345);
407 assert_eq!(12345, u16::from(asn));
408 assert_eq!(12345, u16::from(&asn));
409 }
410
411 #[test]
412 fn test_is_four_byte() {
413 let asn = Asn::new_32bit(12345);
414 assert!(asn.is_four_byte());
415 let asn = Asn::new_16bit(12345);
416 assert!(!asn.is_four_byte());
417 }
418
419 #[test]
420 fn test_asn_comparison() {
421 let asn1 = Asn::new_32bit(12345);
422 let asn2 = Asn::new_32bit(12345);
423 assert_eq!(asn1, asn2);
424 assert!(asn1 <= asn2);
425 assert!(asn1 >= asn2);
426
427 let asn3 = Asn::new_32bit(12346);
428 assert!(asn1 < asn3);
429 assert!(asn1 <= asn3);
430 }
431
432 #[test]
433 fn test_required_len() {
434 let asn = Asn::new_32bit(65536);
435 assert_eq!(AsnLength::Bits32, asn.required_len());
436 let asn = Asn::new_32bit(65535);
437 assert_eq!(AsnLength::Bits16, asn.required_len());
438 }
439
440 #[test]
441 #[cfg(feature = "serde")]
442 fn test_asn_length_serialization() {
443 let length_16bit = AsnLength::Bits16;
444 let serialized = serde_json::to_string(&length_16bit).unwrap();
445 assert_eq!(serialized, "\"Bits16\"");
446 let deserialized: AsnLength = serde_json::from_str(&serialized).unwrap();
447 assert_eq!(deserialized, length_16bit);
448
449 let length_32bit = AsnLength::Bits32;
450 let serialized = serde_json::to_string(&length_32bit).unwrap();
451 assert_eq!(serialized, "\"Bits32\"");
452 let deserialized: AsnLength = serde_json::from_str(&serialized).unwrap();
453 assert_eq!(deserialized, length_32bit);
454 }
455}