Skip to content

Commit 28e922d

Browse files
committed
fix incorrect RFC9072 extended parameter support
1 parent 4adb94b commit 28e922d

File tree

1 file changed

+37
-6
lines changed

1 file changed

+37
-6
lines changed

src/parser/bgp/messages.rs

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,33 @@ impl BgpNotificationMessage {
156156
/// Parse BGP OPEN message.
157157
///
158158
/// The parsing of BGP OPEN message also includes decoding the BGP capabilities.
159+
///
160+
/// RFC 4271: https://datatracker.ietf.org/doc/html/rfc4271
161+
/// ```text
162+
/// 0 1 2 3
163+
/// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
164+
/// +-+-+-+-+-+-+-+-+
165+
/// | Version |
166+
/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
167+
/// | My Autonomous System |
168+
/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
169+
/// | Hold Time |
170+
/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
171+
/// | BGP Identifier |
172+
/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
173+
/// | Opt Parm Len |
174+
/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
175+
/// | |
176+
/// | Optional Parameters (variable) |
177+
/// | |
178+
/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
179+
///
180+
/// 0 1
181+
/// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
182+
/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-...
183+
/// | Parm. Type | Parm. Length | Parameter Value (variable)
184+
/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-...
185+
/// ```
159186
pub fn parse_bgp_open_message(input: &mut Bytes) -> Result<BgpOpenMessage, ParserError> {
160187
input.has_n_remaining(10)?;
161188
let version = input.get_u8();
@@ -172,8 +199,14 @@ pub fn parse_bgp_open_message(input: &mut Bytes) -> Result<BgpOpenMessage, Parse
172199
while input.remaining() >= 2 {
173200
let mut param_type = input.get_u8();
174201
if first {
202+
if opt_params_len == 0 && param_type == 255 {
203+
return Err(ParserError::ParseError(
204+
"RFC 9072 violation: Non-Extended Optional Parameters Length must not be 0 when using extended format".to_string()
205+
));
206+
}
175207
// first parameter, check if it is extended length message
176-
if opt_params_len == 255 && param_type == 255 {
208+
if opt_params_len != 0 && param_type == 255 {
209+
// RFC 9072: https://datatracker.ietf.org/doc/rfc9072/
177210
//
178211
// 0 1 2 3
179212
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
@@ -191,7 +224,7 @@ pub fn parse_bgp_open_message(input: &mut Bytes) -> Result<BgpOpenMessage, Parse
191224
// | |
192225
// | Optional Parameters (variable) |
193226
// | |
194-
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
227+
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
195228
//
196229
// Figure 1: Extended Encoding OPEN Format
197230
extended_length = true;
@@ -218,6 +251,7 @@ pub fn parse_bgp_open_message(input: &mut Bytes) -> Result<BgpOpenMessage, Parse
218251
true => input.read_u16()?,
219252
false => input.read_u8()? as u16,
220253
};
254+
221255
// https://tools.ietf.org/html/rfc3392
222256
// https://www.iana.org/assignments/bgp-parameters/bgp-parameters.xhtml#bgp-parameters-11
223257

@@ -232,10 +266,7 @@ pub fn parse_bgp_open_message(input: &mut Bytes) -> Result<BgpOpenMessage, Parse
232266
// capability codes:
233267
// https://www.iana.org/assignments/capability-codes/capability-codes.xhtml#capability-codes-2
234268
let code = param_data.read_u8()?;
235-
let len = match extended_length {
236-
true => param_data.read_u16()?,
237-
false => param_data.read_u8()? as u16,
238-
};
269+
let len = param_data.read_u8()? as u16; // Capability length is ALWAYS 1 byte per RFC 5492
239270

240271
let capability_data = param_data.read_n_bytes(len as usize)?;
241272
let capability_type = BgpCapabilityType::from(code);

0 commit comments

Comments
 (0)