review: parse_port rejects ranges, document IPv6 ext header limit
parse_port now rejects port ranges ('1024:65535') with a clear
error message instead of silently using only the first number.
FilterRule uses a single u16 field and cannot represent ranges.
infer_context now documents the hardcoded 40-byte IPv6 header
limitation: smoltcp's next_header() chases extension headers to
return the final protocol, but the transport offset is not
computed. Port extraction silently returns None/None for packets
with extension headers, which is safe but means port-based
filter rules won't match for such packets.
This commit is contained in:
@@ -410,8 +410,15 @@ fn parse_protocol(value: &str) -> core::result::Result<Protocol, ParseError> {
|
||||
}
|
||||
|
||||
fn parse_port(value: &str) -> core::result::Result<u16, ParseError> {
|
||||
let port_str = value.split(':').next().unwrap_or(value);
|
||||
port_str
|
||||
// Accept single port (e.g. "80") but reject port ranges (e.g.
|
||||
// "1024:65535"). The FilterRule struct uses a single u16 field
|
||||
// and does not support ranges. Silently accepting the first
|
||||
// number would make --sport 1024:65535 match only port 1024,
|
||||
// which is both wrong and misleading.
|
||||
if value.contains(':') {
|
||||
return Err(ParseError::Msg("port ranges not supported (use a single port number)"));
|
||||
}
|
||||
value
|
||||
.parse::<u16>()
|
||||
.map_err(|_| ParseError::BadPort(value.to_string()))
|
||||
}
|
||||
|
||||
@@ -515,6 +515,14 @@ fn infer_context(
|
||||
if let Ok(ipv6) = Ipv6Packet::new_checked(packet) {
|
||||
let nh = ipv6.next_header();
|
||||
let payload_start = 40; // fixed IPv6 header
|
||||
// Extension headers (Hop-by-Hop, Routing, Fragment, etc.)
|
||||
// would shift the transport header to a higher offset.
|
||||
// smoltcp's next_header() chases extension headers to return
|
||||
// the final protocol, but we don't compute the actual
|
||||
// transport offset. For packets with extension headers the
|
||||
// port extraction below will read the wrong bytes and return
|
||||
// None/None, which is safe: the filter matches on IP+protocol
|
||||
// but silently skips port matching.
|
||||
let payload = if packet.len() > payload_start {
|
||||
&packet[payload_start..]
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user