Skip to content

Commit

Permalink
add check that an IP payload is not a fragment or the first one befor…
Browse files Browse the repository at this point in the history
…e parsing transport header
  • Loading branch information
johanmazelanssi authored and chifflier committed Aug 29, 2024
1 parent 130c697 commit 59d84a1
Show file tree
Hide file tree
Showing 2 changed files with 237 additions and 138 deletions.
183 changes: 111 additions & 72 deletions pcap-rewrite/src/filters/key_parser_ipv4.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,45 +66,64 @@ pub fn parse_src_ipaddr_proto_dst_port(
match ipv4_packet.get_next_level_protocol() {
IpNextHeaderProtocols::Tcp => {
let ipv4_payload = libpcap_analyzer::extract_payload_l3_ipv4(ctx, &ipv4_packet)?;
match TcpPacket::new(ipv4_payload) {
Some(ref tcp) => {
let dst_port = tcp.get_destination();
Ok(IpAddrProtoPort::new(
src_ipaddr,
IpNextHeaderProtocols::Tcp,
dst_port,
))
if ipv4_payload.len() >= 20 && ipv4_packet.get_fragment_offset() == 0 {
match TcpPacket::new(ipv4_payload) {
Some(ref tcp) => {
let dst_port = tcp.get_destination();
Ok(IpAddrProtoPort::new(
src_ipaddr,
IpNextHeaderProtocols::Tcp,
dst_port,
))
}
None => {
warn!(
"Expected TCP packet in Ipv4 but could not parse at index {}",
ctx.pcap_index
);
Err(Error::Pnet(
"Expected TCP packet in Ipv4 but could not parse",
))
}
}
None => {
warn!(
"Expected TCP packet in Ipv4 but could not parse at index {}",
ctx.pcap_index
);
Err(Error::Pnet(
"Expected TCP packet in Ipv4 but could not parse",
))
}
}
}
IpNextHeaderProtocols::Udp => match UdpPacket::new(ipv4_packet.payload()) {
Some(ref udp) => {
let dst_port = udp.get_destination();
} else {
Ok(IpAddrProtoPort::new(
src_ipaddr,
IpNextHeaderProtocols::Udp,
dst_port,
ipv4_packet.get_next_level_protocol(),
0,
))
}
None => {
warn!(
"Expected UDP packet in Ipv4 but could not parse at index {}",
ctx.pcap_index
);
Err(Error::Pnet(
"Expected UDP packet in Ipv4 but could not parse",
}
IpNextHeaderProtocols::Udp => {
let ipv4_payload = libpcap_analyzer::extract_payload_l3_ipv4(ctx, &ipv4_packet)?;
if ipv4_payload.len() >= 20 && ipv4_packet.get_fragment_offset() == 0 {
match UdpPacket::new(ipv4_packet.payload()) {
Some(ref udp) => {
let dst_port = udp.get_destination();
Ok(IpAddrProtoPort::new(
src_ipaddr,
IpNextHeaderProtocols::Udp,
dst_port,
))
}
None => {
warn!(
"Expected UDP packet in Ipv4 but could not parse at index {}",
ctx.pcap_index
);
Err(Error::Pnet(
"Expected UDP packet in Ipv4 but could not parse",
))
}
}
} else {
Ok(IpAddrProtoPort::new(
src_ipaddr,
ipv4_packet.get_next_level_protocol(),
0,
))
}
},
}
_ => Ok(IpAddrProtoPort::new(
src_ipaddr,
ipv4_packet.get_next_level_protocol(),
Expand Down Expand Up @@ -146,52 +165,72 @@ pub fn parse_five_tuple(ctx: &ParseContext, payload: &[u8]) -> Result<FiveTuple,
match ipv4_packet.get_next_level_protocol() {
IpNextHeaderProtocols::Tcp => {
let ipv4_payload = libpcap_analyzer::extract_payload_l3_ipv4(ctx, &ipv4_packet)?;
match TcpPacket::new(ipv4_payload) {
Some(ref tcp) => {
let src_port = tcp.get_source();
let dst_port = tcp.get_destination();
Ok(FiveTuple {
src: src_ipaddr,
dst: dst_ipaddr,
proto: 6_u8,
src_port,
dst_port,
})
}
None => {
warn!(
"Expected TCP packet in Ipv4 but could not parse at index {}",
ctx.pcap_index
);
Err(Error::Pnet(
"Expected TCP packet in Ipv4 but could not parse",
))
if ipv4_payload.len() >= 20 && ipv4_packet.get_fragment_offset() == 0 {
match TcpPacket::new(ipv4_payload) {
Some(ref tcp) => {
let src_port = tcp.get_source();
let dst_port = tcp.get_destination();
Ok(FiveTuple {
src: src_ipaddr,
dst: dst_ipaddr,
proto: 6_u8,
src_port,
dst_port,
})
}
None => {
warn!(
"Expected TCP packet in Ipv4 but could not parse at index {}",
ctx.pcap_index
);
Err(Error::Pnet(
"Expected TCP packet in Ipv4 but could not parse",
))
}
}
} else {
Ok(FiveTuple {
src: src_ipaddr,
dst: dst_ipaddr,
proto: ipv4_packet.get_next_level_protocol().0,
src_port: 0,
dst_port: 0,
})
}
}
IpNextHeaderProtocols::Udp => {
let ipv4_payload = libpcap_analyzer::extract_payload_l3_ipv4(ctx, &ipv4_packet)?;
match UdpPacket::new(ipv4_payload) {
Some(ref udp) => {
let src_port = udp.get_source();
let dst_port = udp.get_destination();
Ok(FiveTuple {
src: src_ipaddr,
dst: dst_ipaddr,
proto: 17_u8,
src_port,
dst_port,
})
}
None => {
warn!(
"Expected UDP packet in Ipv4 but could not parse at index {}",
ctx.pcap_index
);
Err(Error::Pnet(
"Expected UDP packet in Ipv4 but could not parse",
))
if ipv4_payload.len() >= 20 && ipv4_packet.get_fragment_offset() == 0 {
match UdpPacket::new(ipv4_payload) {
Some(ref udp) => {
let src_port = udp.get_source();
let dst_port = udp.get_destination();
Ok(FiveTuple {
src: src_ipaddr,
dst: dst_ipaddr,
proto: 17_u8,
src_port,
dst_port,
})
}
None => {
warn!(
"Expected UDP packet in Ipv4 but could not parse at index {}",
ctx.pcap_index
);
Err(Error::Pnet(
"Expected UDP packet in Ipv4 but could not parse",
))
}
}
} else {
Ok(FiveTuple {
src: src_ipaddr,
dst: dst_ipaddr,
proto: ipv4_packet.get_next_level_protocol().0,
src_port: 0,
dst_port: 0,
})
}
}
_ => Ok(FiveTuple {
Expand Down
Loading

0 comments on commit 59d84a1

Please sign in to comment.