1use ipnet::{IpNet, Ipv4Net, Ipv6Net};
5use std::convert::TryFrom;
6use std::{
7 io,
8 net::{Ipv4Addr, Ipv6Addr},
9};
10
11use crate::error::ParserError;
12use crate::models::*;
13use crate::ParserError::TruncatedMsg;
14use bytes::{Buf, BufMut, Bytes, BytesMut};
15use log::debug;
16use regex::Regex;
17use std::net::IpAddr;
18
19impl ReadUtils for Bytes {}
20
21pub trait ReadUtils: Buf {
23 #[inline]
24 fn has_n_remaining(&self, n: usize) -> Result<(), ParserError> {
25 let remaining = self.remaining();
26 if remaining < n {
27 Err(TruncatedMsg(format!(
28 "not enough bytes to read. remaining: {remaining}, required: {n}"
29 )))
30 } else {
31 Ok(())
32 }
33 }
34
35 #[inline]
36 fn read_u8(&mut self) -> Result<u8, ParserError> {
37 self.has_n_remaining(1)?;
38 Ok(self.get_u8())
39 }
40
41 #[inline]
42 fn read_u16(&mut self) -> Result<u16, ParserError> {
43 self.has_n_remaining(2)?;
44 Ok(self.get_u16())
45 }
46
47 #[inline]
48 fn read_u32(&mut self) -> Result<u32, ParserError> {
49 self.has_n_remaining(4)?;
50 Ok(self.get_u32())
51 }
52
53 #[inline]
54 fn read_u64(&mut self) -> Result<u64, ParserError> {
55 self.has_n_remaining(8)?;
56 Ok(self.get_u64())
57 }
58
59 fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), ParserError> {
60 self.has_n_remaining(buf.len())?;
61 self.copy_to_slice(buf);
62 Ok(())
63 }
64
65 fn read_address(&mut self, afi: &Afi) -> io::Result<IpAddr> {
66 match afi {
67 Afi::Ipv4 => match self.read_ipv4_address() {
68 Ok(ip) => Ok(IpAddr::V4(ip)),
69 _ => Err(io::Error::other("Cannot parse IPv4 address")),
70 },
71 Afi::Ipv6 => match self.read_ipv6_address() {
72 Ok(ip) => Ok(IpAddr::V6(ip)),
73 _ => Err(io::Error::other("Cannot parse IPv6 address")),
74 },
75 Afi::LinkState => {
76 Ok(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)))
79 }
80 }
81 }
82
83 fn read_ipv4_address(&mut self) -> Result<Ipv4Addr, ParserError> {
84 let addr = self.read_u32()?;
85 Ok(Ipv4Addr::from(addr))
86 }
87
88 fn read_ipv6_address(&mut self) -> Result<Ipv6Addr, ParserError> {
89 self.has_n_remaining(16)?;
90 let buf = self.get_u128();
91 Ok(Ipv6Addr::from(buf))
92 }
93
94 fn read_ipv4_prefix(&mut self) -> Result<Ipv4Net, ParserError> {
95 let addr = self.read_ipv4_address()?;
96 let mask = self.read_u8()?;
97 match Ipv4Net::new(addr, mask) {
98 Ok(n) => Ok(n),
99 Err(_) => Err(io::Error::other("Invalid prefix mask").into()),
100 }
101 }
102
103 fn read_ipv6_prefix(&mut self) -> Result<Ipv6Net, ParserError> {
104 let addr = self.read_ipv6_address()?;
105 let mask = self.read_u8()?;
106 match Ipv6Net::new(addr, mask) {
107 Ok(n) => Ok(n),
108 Err(_) => Err(io::Error::other("Invalid prefix mask").into()),
109 }
110 }
111
112 #[inline]
113 fn read_asn(&mut self, as_length: AsnLength) -> Result<Asn, ParserError> {
114 match as_length {
115 AsnLength::Bits16 => self.read_u16().map(Asn::new_16bit),
116 AsnLength::Bits32 => self.read_u32().map(Asn::new_32bit),
117 }
118 }
119
120 fn read_asns(&mut self, as_length: &AsnLength, count: usize) -> Result<Vec<Asn>, ParserError> {
121 let mut path = Vec::with_capacity(count);
122
123 match as_length {
124 AsnLength::Bits16 => {
125 self.has_n_remaining(count * 2)?; for _ in 0..count {
127 path.push(Asn::new_16bit(self.read_u16()?));
128 }
129 }
130 AsnLength::Bits32 => {
131 self.has_n_remaining(count * 4)?; for _ in 0..count {
133 path.push(Asn::new_32bit(self.read_u32()?));
134 }
135 }
136 }
137
138 Ok(path)
139 }
140
141 fn read_afi(&mut self) -> Result<Afi, ParserError> {
142 Afi::try_from(self.read_u16()?).map_err(ParserError::from)
143 }
144
145 fn read_safi(&mut self) -> Result<Safi, ParserError> {
146 Safi::try_from(self.read_u8()?).map_err(ParserError::from)
147 }
148
149 fn read_nlri_prefix(
155 &mut self,
156 afi: &Afi,
157 add_path: bool,
158 ) -> Result<NetworkPrefix, ParserError> {
159 let path_id = if add_path {
160 Some(self.read_u32()?)
161 } else {
162 None
163 };
164
165 let bit_len = self.read_u8()?;
167
168 let byte_len: usize = (bit_len as usize).div_ceil(8);
170 let addr: IpAddr = match afi {
171 Afi::Ipv4 => {
172 if byte_len > 4 {
174 return Err(ParserError::ParseError(format!(
175 "Invalid byte length for IPv4 prefix. byte_len: {byte_len}, bit_len: {bit_len}"
176 )));
177 }
178 self.has_n_remaining(byte_len)?;
179 let mut buff = [0; 4];
180 self.copy_to_slice(&mut buff[..byte_len]);
181 IpAddr::V4(Ipv4Addr::from(buff))
182 }
183 Afi::Ipv6 => {
184 if byte_len > 16 {
186 return Err(ParserError::ParseError(format!(
187 "Invalid byte length for IPv6 prefix. byte_len: {byte_len}, bit_len: {bit_len}"
188 )));
189 }
190 self.has_n_remaining(byte_len)?;
191 let mut buff = [0; 16];
192 self.copy_to_slice(&mut buff[..byte_len]);
193 IpAddr::V6(Ipv6Addr::from(buff))
194 }
195 Afi::LinkState => {
196 IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0))
199 }
200 };
201 let prefix = match IpNet::new(addr, bit_len) {
202 Ok(p) => p,
203 Err(_) => {
204 return Err(ParserError::ParseError(format!(
205 "Invalid network prefix length: {bit_len}"
206 )))
207 }
208 };
209
210 Ok(NetworkPrefix::new(prefix, path_id))
211 }
212
213 fn read_n_bytes(&mut self, n_bytes: usize) -> Result<Vec<u8>, ParserError> {
214 self.has_n_remaining(n_bytes)?;
215 Ok(self.copy_to_bytes(n_bytes).into())
216 }
217
218 fn read_n_bytes_to_string(&mut self, n_bytes: usize) -> Result<String, ParserError> {
219 let buffer = self.read_n_bytes(n_bytes)?;
220 Ok(buffer
221 .into_iter()
222 .map(|x: u8| x as char)
223 .collect::<String>())
224 }
225}
226
227pub fn parse_nlri_list(
228 mut input: Bytes,
229 add_path: bool,
230 afi: &Afi,
231) -> Result<Vec<NetworkPrefix>, ParserError> {
232 let mut is_add_path = add_path;
233 let mut prefixes = vec![];
234
235 let mut retry = false;
236 let mut guessed = false;
237
238 let mut input_copy = None;
239
240 while input.remaining() > 0 {
241 if !is_add_path && input[0] == 0 {
242 debug!("not add-path but with NLRI size to be 0, likely add-path msg in wrong msg type, treat as add-path now");
244 is_add_path = true;
246 guessed = true;
247 input_copy = Some(input.clone());
248 }
249 let prefix = match input.read_nlri_prefix(afi, is_add_path) {
250 Ok(p) => p,
251 Err(e) => {
252 if guessed {
253 retry = true;
254 break;
255 } else {
256 return Err(e);
257 }
258 }
259 };
260 prefixes.push(prefix);
261 }
262
263 if retry {
264 prefixes.clear();
265 let mut input_2 = input_copy.unwrap();
268 while input_2.remaining() > 0 {
269 let prefix = input_2.read_nlri_prefix(afi, add_path)?;
270 prefixes.push(prefix);
271 }
272 }
273
274 Ok(prefixes)
275}
276
277pub fn encode_asn(asn: &Asn, asn_len: &AsnLength) -> Bytes {
278 let mut bytes = BytesMut::new();
279 match asn_len {
280 AsnLength::Bits16 => bytes.put_u16(asn.into()),
281 AsnLength::Bits32 => {
282 bytes.put_u32(asn.into());
283 }
284 }
285 bytes.freeze()
286}
287
288pub fn encode_ipaddr(addr: &IpAddr) -> Vec<u8> {
289 match addr {
290 IpAddr::V4(addr) => addr.octets().to_vec(),
291 IpAddr::V6(addr) => addr.octets().to_vec(),
292 }
293}
294
295pub fn encode_nlri_prefixes(prefixes: &[NetworkPrefix]) -> Bytes {
296 let mut bytes = BytesMut::new();
297 for prefix in prefixes {
298 bytes.extend(prefix.encode());
299 }
300 bytes.freeze()
301}
302
303pub fn crc32(input: &str) -> String {
308 let input_bytes = input.as_bytes();
309 let mut table = [0u32; 256];
310 let polynomial = 0xedb88320u32;
311
312 for i in 0..256 {
313 let mut crc = i as u32;
314 for _ in 0..8 {
315 if crc & 1 == 1 {
316 crc = (crc >> 1) ^ polynomial;
317 } else {
318 crc >>= 1;
319 }
320 }
321 table[i as usize] = crc;
322 }
323
324 let mut crc = !0u32;
325 for byte in input_bytes.iter() {
326 let index = ((crc ^ (*byte as u32)) & 0xff) as usize;
327 crc = (crc >> 8) ^ table[index];
328 }
329
330 format!("{:08x}", !crc)
331}
332
333pub fn convert_timestamp(timestamp: f64) -> (u32, u32) {
355 let seconds = timestamp as u32;
356 let microseconds = ((timestamp - seconds as f64) * 1_000_000.0) as u32;
357 (seconds, microseconds)
358}
359
360#[derive(Debug, Clone)]
361pub struct ComparableRegex {
362 pattern: String,
363 regex: Regex,
364}
365
366impl PartialEq for ComparableRegex {
367 fn eq(&self, other: &Self) -> bool {
368 self.pattern == other.pattern
369 }
370}
371
372impl ComparableRegex {
373 pub fn new(pattern: &str) -> Result<Self, ParserError> {
374 let regex = match Regex::new(pattern) {
375 Ok(r) => r,
376 Err(_) => {
377 return Err(ParserError::FilterError(format!(
378 "Invalid regex pattern: {pattern}"
379 )))
380 }
381 };
382 Ok(ComparableRegex {
383 pattern: pattern.to_string(),
384 regex,
385 })
386 }
387
388 pub fn is_match<S: AsRef<str>>(&self, text: S) -> bool {
389 self.regex.is_match(text.as_ref())
390 }
391}
392
393#[cfg(test)]
394mod tests {
395 use super::*;
396 use bytes::Bytes;
397
398 #[test]
399 fn test_read_u8() {
400 let mut buf = Bytes::from_static(&[0x12]);
401 assert_eq!(buf.read_u8().unwrap(), 0x12);
402 }
403
404 #[test]
405 fn test_read_u16() {
406 let mut buf = Bytes::from_static(&[0x12, 0x34]);
407 assert_eq!(buf.read_u16().unwrap(), 0x1234);
408 }
409
410 #[test]
411 fn test_read_u32() {
412 let mut buf = Bytes::from_static(&[0x12, 0x34, 0x56, 0x78]);
413 assert_eq!(buf.read_u32().unwrap(), 0x12345678);
414 }
415
416 #[test]
417 fn test_read_u64() {
418 let mut buf = Bytes::from_static(&[0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0]);
419 assert_eq!(buf.read_u64().unwrap(), 0x123456789ABCDEF0);
420 }
421
422 #[test]
423 fn test_read_ipv4_address() {
424 let mut buf = Bytes::from_static(&[0xC0, 0xA8, 0x01, 0x01]);
425 assert_eq!(
426 buf.read_ipv4_address().unwrap(),
427 Ipv4Addr::new(192, 168, 1, 1)
428 );
429 }
430
431 #[test]
432 fn test_read_ipv6_address() {
433 let mut buf = Bytes::from_static(&[
434 0x20, 0x01, 0x0D, 0xB8, 0x85, 0xA3, 0x00, 0x00, 0x00, 0x00, 0x8A, 0x2E, 0x03, 0x70,
435 0x73, 0x34,
436 ]);
437 assert_eq!(
438 buf.read_ipv6_address().unwrap(),
439 Ipv6Addr::new(0x2001, 0x0DB8, 0x85A3, 0x0000, 0x0000, 0x8A2E, 0x0370, 0x7334)
440 );
441 }
442
443 #[test]
444 fn test_read_address() {
445 let mut buf = Bytes::from_static(&[0xC0, 0xA8, 0x01, 0x01]);
446 assert_eq!(
447 buf.read_address(&Afi::Ipv4).unwrap(),
448 IpAddr::V4(Ipv4Addr::new(192, 168, 1, 1))
449 );
450
451 let mut buf = Bytes::from_static(&[
452 0x20, 0x01, 0x0D, 0xB8, 0x85, 0xA3, 0x00, 0x00, 0x00, 0x00, 0x8A, 0x2E, 0x03, 0x70,
453 0x73, 0x34,
454 ]);
455 assert_eq!(
456 buf.read_address(&Afi::Ipv6).unwrap(),
457 IpAddr::V6(Ipv6Addr::new(
458 0x2001, 0x0DB8, 0x85A3, 0x0000, 0x0000, 0x8A2E, 0x0370, 0x7334
459 ))
460 );
461
462 let mut buf = Bytes::from_static(&[0xC0, 0xA8, 0x01]);
463 assert!(buf.read_address(&Afi::Ipv4).is_err());
464
465 let mut buf = Bytes::from_static(&[
466 0x20, 0x01, 0x0D, 0xB8, 0x85, 0xA3, 0x00, 0x00, 0x00, 0x00, 0x8A, 0x2E, 0x03, 0x70,
467 0x73,
468 ]);
469 assert!(buf.read_address(&Afi::Ipv6).is_err());
470 }
471
472 #[test]
473 fn test_read_asn() {
474 let mut buf = Bytes::from_static(&[0x00, 0x01]);
475 assert_eq!(buf.read_asn(AsnLength::Bits16).unwrap(), Asn::new_16bit(1));
476
477 let mut buf = Bytes::from_static(&[0x00, 0x00, 0x01, 0x00]);
478 assert_eq!(
479 buf.read_asn(AsnLength::Bits32).unwrap(),
480 Asn::new_32bit(256)
481 );
482 }
483
484 #[test]
485 fn read_asns() {
486 let mut buf = Bytes::from_static(&[0x00, 0x01, 0x00, 0x00]);
487 assert_eq!(
488 buf.read_asns(&AsnLength::Bits16, 2).unwrap(),
489 vec![Asn::new_16bit(1), Asn::new_16bit(0)]
490 );
491 }
492
493 #[test]
494 fn test_read_afi() {
495 let mut buf = Bytes::from_static(&[0x00, 0x01]);
496 assert_eq!(buf.read_afi().unwrap(), Afi::Ipv4);
497
498 let mut buf = Bytes::from_static(&[0x00, 0x02]);
499 assert_eq!(buf.read_afi().unwrap(), Afi::Ipv6);
500 }
501
502 #[test]
503 fn test_read_safi() {
504 let mut buf = Bytes::from_static(&[0x01]);
505 assert_eq!(buf.read_safi().unwrap(), Safi::Unicast);
506
507 let mut buf = Bytes::from_static(&[0x02]);
508 assert_eq!(buf.read_safi().unwrap(), Safi::Multicast);
509
510 let mut buf = Bytes::from_static(&[0x80]); assert_eq!(buf.read_safi().unwrap(), Safi::MplsVpn);
513
514 let mut buf = Bytes::from_static(&[0x81]); assert_eq!(buf.read_safi().unwrap(), Safi::MulticastVpn);
516 }
517
518 #[test]
519 fn test_has_n_remaining() {
520 let mut buf = Bytes::from_static(&[0x12, 0x34, 0x56, 0x78]);
521 assert!(buf.has_n_remaining(4).is_ok());
522 assert!(buf.has_n_remaining(5).is_err());
523
524 let _ = buf.read_u8().unwrap();
525 assert!(buf.has_n_remaining(3).is_ok());
526 assert!(buf.has_n_remaining(4).is_err());
527 }
528
529 #[test]
530 fn test_read_ipv4_prefix() {
531 let mut buf = Bytes::from_static(&[0xC0, 0xA8, 0x01, 0x01, 0x18]);
532 assert_eq!(
533 buf.read_ipv4_prefix().unwrap(),
534 Ipv4Net::new(Ipv4Addr::new(192, 168, 1, 1), 24).unwrap()
535 );
536
537 let mut buf = Bytes::from_static(&[0xC0, 0xA8, 0x01, 0x01, 0x21]);
539 assert!(buf.read_ipv4_prefix().is_err());
540 }
541
542 #[test]
543 fn test_read_ipv6_prefix() {
544 let mut buf = Bytes::from_static(&[
545 0x20, 0x01, 0x0D, 0xB8, 0x85, 0xA3, 0x00, 0x00, 0x00, 0x00, 0x8A, 0x2E, 0x03, 0x70,
546 0x73, 0x34, 0x40,
547 ]);
548 assert_eq!(
549 buf.read_ipv6_prefix().unwrap(),
550 Ipv6Net::new(
551 Ipv6Addr::new(0x2001, 0x0DB8, 0x85A3, 0x0000, 0x0000, 0x8A2E, 0x0370, 0x7334),
552 64
553 )
554 .unwrap()
555 );
556
557 let mut buf = Bytes::from_static(&[
559 0x20, 0x01, 0x0D, 0xB8, 0x85, 0xA3, 0x00, 0x00, 0x00, 0x00, 0x8A, 0x2E, 0x03, 0x70,
560 0x73, 0x34, 0x81,
561 ]);
562 assert!(buf.read_ipv6_prefix().is_err());
563 }
564
565 #[test]
566 fn test_read_n_bytes() {
567 let mut buf = Bytes::from_static(&[0x12, 0x34, 0x56, 0x78]);
568 assert_eq!(buf.read_n_bytes(4).unwrap(), vec![0x12, 0x34, 0x56, 0x78]);
569 }
570
571 #[test]
572 fn test_read_n_bytes_to_string() {
573 let mut buf = Bytes::from_static(&[0x48, 0x65, 0x6C, 0x6C, 0x6F]); assert_eq!(buf.read_n_bytes_to_string(5).unwrap(), "Hello");
575 }
576
577 #[test]
578 fn test_crc32() {
579 assert_eq!(crc32("Hello, World!"), "ec4ac3d0");
580 }
581
582 #[test]
583 fn test_read_nlri_prefix() {
584 let mut buf = Bytes::from_static(&[0x18, 0xC0, 0xA8, 0x01]);
585 let expected = NetworkPrefix::new(
586 IpNet::V4(Ipv4Net::new(Ipv4Addr::new(192, 168, 1, 0), 24).unwrap()),
587 None,
588 );
589 assert_eq!(buf.read_nlri_prefix(&Afi::Ipv4, false).unwrap(), expected);
590
591 let mut buf = Bytes::from_static(&[0x00, 0x00, 0x00, 0x01, 0x18, 0xC0, 0xA8, 0x01]);
592 let expected = NetworkPrefix::new(
593 IpNet::V4(Ipv4Net::new(Ipv4Addr::new(192, 168, 1, 0), 24).unwrap()),
594 Some(1),
595 );
596 assert_eq!(buf.read_nlri_prefix(&Afi::Ipv4, true).unwrap(), expected);
597 }
598
599 #[test]
600 fn test_encode_asn() {
601 let asn = Asn::new_32bit(1);
602 let asn_len = AsnLength::Bits32;
603 let expected = Bytes::from_static(&[0x00, 0x00, 0x00, 0x01]);
604 assert_eq!(encode_asn(&asn, &asn_len), expected);
605
606 let asn = Asn::new_16bit(1);
607 let asn_len = AsnLength::Bits16;
608 let expected = Bytes::from_static(&[0x00, 0x01]);
609 assert_eq!(encode_asn(&asn, &asn_len), expected);
610 }
611
612 #[test]
613 fn test_encode_ipaddr() {
614 let addr = IpAddr::V4(Ipv4Addr::new(192, 168, 1, 1));
615 let expected = vec![192, 168, 1, 1];
616 assert_eq!(encode_ipaddr(&addr), expected);
617
618 let addr = IpAddr::V6(Ipv6Addr::new(
619 0x2001, 0x0DB8, 0x85A3, 0x0000, 0x0000, 0x8A2E, 0x0370, 0x7334,
620 ));
621 let expected = vec![
622 0x20, 0x01, 0x0D, 0xB8, 0x85, 0xA3, 0x00, 0x00, 0x00, 0x00, 0x8A, 0x2E, 0x03, 0x70,
623 0x73, 0x34,
624 ];
625 assert_eq!(encode_ipaddr(&addr), expected);
626 }
627
628 #[test]
629 fn test_encode_nlri_prefixes() {
630 let prefixes = vec![
631 NetworkPrefix::new(
632 IpNet::V4(Ipv4Net::new(Ipv4Addr::new(192, 168, 1, 0), 24).unwrap()),
633 None,
634 ),
635 NetworkPrefix::new(
636 IpNet::V4(Ipv4Net::new(Ipv4Addr::new(192, 168, 2, 0), 24).unwrap()),
637 None,
638 ),
639 ];
640 let expected = Bytes::from_static(&[0x18, 0xC0, 0xA8, 0x01, 0x18, 0xC0, 0xA8, 0x02]);
641 assert_eq!(encode_nlri_prefixes(&prefixes), expected);
642
643 let prefixes = vec![
644 NetworkPrefix::new(
645 IpNet::V4(Ipv4Net::new(Ipv4Addr::new(192, 168, 1, 0), 24).unwrap()),
646 Some(1),
647 ),
648 NetworkPrefix::new(
649 IpNet::V4(Ipv4Net::new(Ipv4Addr::new(192, 168, 2, 0), 24).unwrap()),
650 Some(1),
651 ),
652 ];
653 let expected = Bytes::from_static(&[
654 0x00, 0x00, 0x00, 0x01, 0x18, 0xC0, 0xA8, 0x01, 0x00, 0x00, 0x00, 0x01, 0x18, 0xC0,
655 0xA8, 0x02,
656 ]);
657 assert_eq!(encode_nlri_prefixes(&prefixes), expected);
658 }
659
660 #[test]
661 fn test_comparable_regex_functionality() {
662 let regex1 = ComparableRegex::new(r"\d+").unwrap();
664 let regex2 = ComparableRegex::new(r"\d+").unwrap();
665 let regex3 = ComparableRegex::new(r"\w+").unwrap();
666
667 assert_eq!(regex1.pattern, r"\d+");
669 assert_eq!(regex3.pattern, r"\w+");
670
671 assert_eq!(regex1, regex2);
673
674 assert_ne!(regex1, regex3);
676
677 assert!(regex1.regex.is_match("123"));
679 assert!(!regex1.regex.is_match("abc"));
680 }
681
682 #[test]
683 #[should_panic(expected = "Invalid regex pattern")]
684 fn test_comparable_regex_invalid_pattern_panic() {
685 ComparableRegex::new(r"(\d+").unwrap(); }
688
689 #[test]
690 fn test_parse_nlri_list() {
691 let input = Bytes::from_static(&[0x18, 0xC0, 0xA8, 0x01, 0x18, 0xC0, 0xA8, 0x02]);
693 let expected = vec![
694 NetworkPrefix::new(
695 IpNet::V4(Ipv4Net::new(Ipv4Addr::new(192, 168, 1, 0), 24).unwrap()),
696 None,
697 ),
698 NetworkPrefix::new(
699 IpNet::V4(Ipv4Net::new(Ipv4Addr::new(192, 168, 2, 0), 24).unwrap()),
700 None,
701 ),
702 ];
703 assert_eq!(parse_nlri_list(input, false, &Afi::Ipv4).unwrap(), expected);
704
705 let input = Bytes::from_static(&[
707 0x00, 0x00, 0x00, 0x01, 0x18, 0xC0, 0xA8, 0x01, 0x00, 0x00, 0x00, 0x02, 0x18, 0xC0,
708 0xA8, 0x02,
709 ]);
710 let expected = vec![
711 NetworkPrefix::new(
712 IpNet::V4(Ipv4Net::new(Ipv4Addr::new(192, 168, 1, 0), 24).unwrap()),
713 Some(1),
714 ),
715 NetworkPrefix::new(
716 IpNet::V4(Ipv4Net::new(Ipv4Addr::new(192, 168, 2, 0), 24).unwrap()),
717 Some(2),
718 ),
719 ];
720 assert_eq!(parse_nlri_list(input, true, &Afi::Ipv4).unwrap(), expected);
721
722 let input = Bytes::from_static(&[0x00, 0x00, 0x00, 0x01, 0x18, 0xC0, 0xA8, 0x01]);
724 let expected = vec![NetworkPrefix::new(
725 IpNet::V4(Ipv4Net::new(Ipv4Addr::new(192, 168, 1, 0), 24).unwrap()),
726 Some(1),
727 )];
728 assert_eq!(parse_nlri_list(input, false, &Afi::Ipv4).unwrap(), expected);
729 }
730
731 #[test]
732 fn test_convert_timestamp() {
733 let (seconds, microseconds) = convert_timestamp(1609459200.0);
735 assert_eq!(seconds, 1609459200);
736 assert_eq!(microseconds, 0);
737
738 let (seconds, microseconds) = convert_timestamp(1609459200.123456);
740 assert_eq!(seconds, 1609459200);
741 assert_eq!(microseconds, 123456);
742
743 let (seconds, microseconds) = convert_timestamp(1609459200.1234567);
745 assert_eq!(seconds, 1609459200);
746 assert_eq!(microseconds, 123456); }
748}