Skip to main content

bgpkit_parser/parser/bmp/
error.rs

1use crate::bmp::messages::headers::BmpPeerType;
2use crate::bmp::messages::peer_down_notification::PeerDownReason;
3use crate::bmp::messages::route_mirroring::RouteMirroringInfo;
4use crate::bmp::messages::termination_message::{TerminationReason, TerminationTlvType};
5use crate::bmp::messages::BmpMsgType;
6use crate::ParserError;
7use num_enum::TryFromPrimitiveError;
8use std::error::Error;
9use std::fmt::{Display, Formatter};
10
11#[derive(Debug, PartialEq, Clone, Eq)]
12pub enum ParserBmpError {
13    InvalidOpenBmpHeader,
14    UnsupportedOpenBmpMessage,
15    UnknownTlvType,
16    UnknownTlvValue,
17    CorruptedBmpMessage,
18    CorruptedBgpMessage(String),
19    TruncatedBmpMessage,
20}
21
22impl Display for ParserBmpError {
23    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
24        match self {
25            ParserBmpError::InvalidOpenBmpHeader => {
26                write!(f, "Invalid OpenBMP header")
27            }
28            ParserBmpError::UnsupportedOpenBmpMessage => {
29                write!(f, "Unsupported OpenBMP message")
30            }
31            ParserBmpError::CorruptedBmpMessage => {
32                write!(f, "Corrupted BMP message")
33            }
34            ParserBmpError::TruncatedBmpMessage => {
35                write!(f, "Truncated BMP message")
36            }
37            ParserBmpError::UnknownTlvType => {
38                write!(f, "Unknown TLV type")
39            }
40            ParserBmpError::UnknownTlvValue => {
41                write!(f, "Unknown TLV value")
42            }
43            ParserBmpError::CorruptedBgpMessage(s) => {
44                write!(f, "Corrupted BGP message: {}", s)
45            }
46        }
47    }
48}
49
50impl Error for ParserBmpError {}
51
52// TODO: These conversions make the error difficult to debug as they drop all of the error context
53impl From<std::io::Error> for ParserBmpError {
54    fn from(_: std::io::Error) -> Self {
55        ParserBmpError::InvalidOpenBmpHeader
56    }
57}
58
59impl From<ParserError> for ParserBmpError {
60    fn from(e: ParserError) -> Self {
61        ParserBmpError::CorruptedBgpMessage(e.to_string())
62    }
63}
64
65impl From<TryFromPrimitiveError<BmpMsgType>> for ParserBmpError {
66    fn from(_: TryFromPrimitiveError<BmpMsgType>) -> Self {
67        ParserBmpError::InvalidOpenBmpHeader
68    }
69}
70
71impl From<TryFromPrimitiveError<BmpPeerType>> for ParserBmpError {
72    fn from(_: TryFromPrimitiveError<BmpPeerType>) -> Self {
73        ParserBmpError::CorruptedBmpMessage
74    }
75}
76
77impl From<TryFromPrimitiveError<RouteMirroringInfo>> for ParserBmpError {
78    fn from(_: TryFromPrimitiveError<RouteMirroringInfo>) -> Self {
79        ParserBmpError::CorruptedBmpMessage
80    }
81}
82
83impl From<TryFromPrimitiveError<TerminationTlvType>> for ParserBmpError {
84    fn from(_: TryFromPrimitiveError<TerminationTlvType>) -> Self {
85        ParserBmpError::UnknownTlvType
86    }
87}
88
89impl From<TryFromPrimitiveError<TerminationReason>> for ParserBmpError {
90    fn from(_: TryFromPrimitiveError<TerminationReason>) -> Self {
91        ParserBmpError::UnknownTlvValue
92    }
93}
94
95impl From<TryFromPrimitiveError<PeerDownReason>> for ParserBmpError {
96    fn from(_: TryFromPrimitiveError<PeerDownReason>) -> Self {
97        ParserBmpError::UnknownTlvValue
98    }
99}
100
101#[cfg(test)]
102mod tests {
103    use super::*;
104
105    #[test]
106    fn test_parser_error_display() {
107        assert_eq!(
108            ParserBmpError::InvalidOpenBmpHeader.to_string(),
109            "Invalid OpenBMP header"
110        );
111        assert_eq!(
112            ParserBmpError::UnsupportedOpenBmpMessage.to_string(),
113            "Unsupported OpenBMP message"
114        );
115        assert_eq!(
116            ParserBmpError::CorruptedBmpMessage.to_string(),
117            "Corrupted BMP message"
118        );
119        assert_eq!(
120            ParserBmpError::CorruptedBgpMessage("test".to_string()).to_string(),
121            "Corrupted BGP message: test"
122        );
123        assert_eq!(
124            ParserBmpError::TruncatedBmpMessage.to_string(),
125            "Truncated BMP message"
126        );
127        assert_eq!(
128            ParserBmpError::UnknownTlvType.to_string(),
129            "Unknown TLV type"
130        );
131        assert_eq!(
132            ParserBmpError::UnknownTlvValue.to_string(),
133            "Unknown TLV value"
134        );
135    }
136
137    #[test]
138    fn test_error_conversions() {
139        assert_eq!(
140            ParserBmpError::from(std::io::Error::other("test")),
141            ParserBmpError::InvalidOpenBmpHeader
142        );
143        assert_eq!(
144            ParserBmpError::from(ParserError::ParseError("test".to_string())),
145            ParserBmpError::CorruptedBgpMessage("Error: test".to_string())
146        );
147        assert_eq!(
148            ParserBmpError::from(TryFromPrimitiveError::<BmpMsgType>::new(0)),
149            ParserBmpError::InvalidOpenBmpHeader
150        );
151        assert_eq!(
152            ParserBmpError::from(TryFromPrimitiveError::<BmpPeerType>::new(0)),
153            ParserBmpError::CorruptedBmpMessage
154        );
155        assert_eq!(
156            ParserBmpError::from(TryFromPrimitiveError::<RouteMirroringInfo>::new(0)),
157            ParserBmpError::CorruptedBmpMessage
158        );
159        assert_eq!(
160            ParserBmpError::from(TryFromPrimitiveError::<TerminationTlvType>::new(0)),
161            ParserBmpError::UnknownTlvType
162        );
163        assert_eq!(
164            ParserBmpError::from(TryFromPrimitiveError::<TerminationReason>::new(0)),
165            ParserBmpError::UnknownTlvValue
166        );
167        assert_eq!(
168            ParserBmpError::from(TryFromPrimitiveError::<PeerDownReason>::new(0)),
169            ParserBmpError::UnknownTlvValue
170        );
171    }
172}