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