Skip to content

Commit

Permalink
add warn! with ctx.pcap_index
Browse files Browse the repository at this point in the history
  • Loading branch information
johanmazelanssi authored and chifflier committed Aug 29, 2024
1 parent 9eadbac commit d1a3918
Show file tree
Hide file tree
Showing 7 changed files with 235 additions and 91 deletions.
27 changes: 17 additions & 10 deletions pcap-rewrite/src/filters/common_filters.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
use crate::filters::filter::*;
use libpcap_tools::{Error,ParseContext};
use std::net::IpAddr;

use log::warn;
use pcap_parser::data::{PacketData, ETHERTYPE_IPV4, ETHERTYPE_IPV6};
use pnet_packet::ethernet::EthernetPacket;
use pnet_packet::ipv4::Ipv4Packet;
use pnet_packet::ipv6::Ipv6Packet;
use pnet_packet::Packet;
use std::net::IpAddr;

use libpcap_tools::{Error, ParseContext};

use crate::filters::filter::*;

/// Common filter to select packets matching this IP address either as source or destination
///
Expand All @@ -18,14 +22,17 @@ pub struct IPFilter {
}

impl Filter for IPFilter {
fn filter<'i>(&self, _ctx: &ParseContext, i: PacketData<'i>) -> FResult<PacketData<'i>, Error> {
fn filter<'i>(&self, ctx: &ParseContext, i: PacketData<'i>) -> FResult<PacketData<'i>, Error> {
match i {
PacketData::L2(data) => {
let p = match EthernetPacket::new(data) {
Some(p) => p,
None => Err("Cannot build ethernet data")?,
};
if self.match_l3(p.get_ethertype().0, p.payload()) {
let ethernet_packet = EthernetPacket::new(data).ok_or_else(|| {
warn!(
"Expected Ethernet packet but could not parse at index {:?}",
ctx.pcap_index
);
Error::Pnet("Expected Ethernet packet but could not parse")
})?;
if self.match_l3(ethernet_packet.get_ethertype().0, ethernet_packet.payload()) {
Ok(Verdict::Accept(i))
} else {
Ok(Verdict::Drop)
Expand Down Expand Up @@ -55,7 +62,7 @@ impl Filter for IPFilter {
Ok(Verdict::Drop)
}
}
PacketData::L4(_, _) => Err("Cannot filter IP, L4 content")?,
PacketData::L4(_, _) => Err(Error::DataParser("Cannot filter IP, L4 content"))?,
PacketData::Unsupported(_) => {
Err(Error::Unsupported("Cannot filter IP, unsupported data"))
}
Expand Down
4 changes: 3 additions & 1 deletion pcap-rewrite/src/filters/dispatch_filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ impl<Container, Key> DispatchFilter<Container, Key> {
let key_option = match packet_data {
PacketData::L2(data) => {
if data.len() < 14 {
warn!("L2 data too small for ethernet at index {}", ctx.pcap_index);
return Err(Error::DataParser("L2 data too small for ethernet"));
}

Expand All @@ -74,7 +75,8 @@ impl<Container, Key> DispatchFilter<Container, Key> {
EtherTypes::Lldp => None,
_ => {
warn!(
"Unimplemented Ethertype in L3 {:?}/{:x}",
"Unimplemented Ethertype in L3 at index {}: {:?}/{:x}",
ctx.pcap_index,
ether_type,
ether_type.to_primitive_values().0
);
Expand Down
24 changes: 18 additions & 6 deletions pcap-rewrite/src/filters/filter_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,13 @@ where
F1: Fn(&ParseContext, &[u8]) -> Result<D, Error>,
F2: Fn(&ParseContext, &[u8]) -> Result<D, Error>,
{
let ethernet_packet = EthernetPacket::new(packet_data)
.ok_or(Error::Pnet("Expected Ethernet packet but could not parse"))?;
let ethernet_packet = EthernetPacket::new(packet_data).ok_or_else(|| {
warn!(
"Expected Ethernet packet but could not parse at index {:?}",
ctx.pcap_index
);
Error::Pnet("Expected Ethernet packet but could not parse")
})?;
let ether_type_u16 = ethernet_packet.get_ethertype().0;
if ether_type_u16 <= 1500 {
// Ethernet 802.3
Expand All @@ -39,8 +44,13 @@ where
EtherTypes::Lldp => Ok(None),
EtherTypes::Vlan => {
// 802.11q
let vlan_packet = VlanPacket::new(ethernet_packet.payload())
.ok_or(Error::Pnet("Expected VLAN packet but could not parse"))?;
let vlan_packet = VlanPacket::new(ethernet_packet.payload()).ok_or_else(|| {
warn!(
"Expected VLAN packet but could not parse at index {:?}",
ctx.pcap_index
);
Error::Pnet("Expected VLAN packet but could not parse")
})?;
match vlan_packet.get_ethertype() {
EtherTypes::Arp => Ok(None),
EtherTypes::Ipv4 => Ok(Some((get_key_from_ipv4_l3_data)(
Expand All @@ -55,7 +65,8 @@ where
EtherTypes::Lldp => Ok(None),
_ => {
warn!(
"Unimplemented Ethertype in 33024/802.11q: {:?}/{:x}",
"Unimplemented Ethertype in 33024/802.11q at index {}: {:?}/{:x}",
ctx.pcap_index,
vlan_packet.get_ethertype(),
vlan_packet.get_ethertype().to_primitive_values().0
);
Expand All @@ -67,7 +78,8 @@ where
}
_ => {
warn!(
"Unimplemented Ethertype: {:?}/{:x}",
"Unimplemented Ethertype at index {}: {:?}/{:x}",
ctx.pcap_index,
ethernet_packet.get_ethertype(),
ethernet_packet.get_ethertype().to_primitive_values().0
);
Expand Down
19 changes: 12 additions & 7 deletions pcap-rewrite/src/filters/fragmentation/fragmentation_filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ impl<Container, Key> FragmentationFilter<Container, Key> {
let is_first_fragment = match packet.data {
PacketData::L2(data) => {
if data.len() < 14 {
warn!("L2 data too small for ethernet at index {}", ctx.pcap_index);
return Err(Error::DataParser("L2 data too small for ethernet"));
}

Expand All @@ -97,8 +98,8 @@ impl<Container, Key> FragmentationFilter<Container, Key> {
EtherTypes::Lldp => false,
_ => {
warn!(
"Unimplemented Ethertype in L3: {:?}/{:x}",
ether_type, ether_type.0
"Unimplemented Ethertype in L3 at index {}: {:?}/{:x}",
ctx.pcap_index, ether_type, ether_type.0
);
return Err(Error::Unimplemented("Unimplemented EtherType in L3"));
}
Expand All @@ -112,6 +113,7 @@ impl<Container, Key> FragmentationFilter<Container, Key> {
let data_option: Option<TwoTupleProtoIpidFiveTuple> = match packet.data {
PacketData::L2(data) => {
if data.len() < 14 {
warn!("L2 data too small for ethernet at index {}", ctx.pcap_index);
return Err(Error::DataParser("L2 data too small for ethernet"));
}

Expand All @@ -136,8 +138,8 @@ impl<Container, Key> FragmentationFilter<Container, Key> {
EtherTypes::Lldp => None,
_ => {
warn!(
"Unimplemented Ethertype in L3: {:?}/{:x}",
ether_type, ether_type.0
"Unimplemented Ethertype in L3 at index {}: {:?}/{:x}",
ctx.pcap_index, ether_type, ether_type.0
);
return Err(Error::Unimplemented("Unimplemented Ethertype in L3"));
}
Expand All @@ -148,7 +150,9 @@ impl<Container, Key> FragmentationFilter<Container, Key> {
};

match data_option {
None => Err("Could find a first IP fragment but could not two tuple/proto/IP id")?,
None => Err(Error::DataParser(
"Could find a first IP fragment but could not find two tuple/proto/IP id",
))?,
Some(data) => self.data_hs.insert(data),
};
}
Expand All @@ -163,6 +167,7 @@ impl<Container, Key> FragmentationFilter<Container, Key> {
let key_option = match packet_data {
PacketData::L2(data) => {
if data.len() < 14 {
warn!("L2 data too small for ethernet at index {}", ctx.pcap_index);
return Err(Error::DataParser("L2 data too small for ethernet"));
}

Expand All @@ -183,8 +188,8 @@ impl<Container, Key> FragmentationFilter<Container, Key> {
EtherTypes::Lldp => None,
_ => {
warn!(
"Unimplemented Ethertype in L3: {:?}/{:x}",
ether_type, ether_type.0
"Unimplemented Ethertype in L3 at index {}: {:?}/{:x}",
ctx.pcap_index, ether_type, ether_type.0
);
return Err(Error::Unimplemented("Unimplemented Ethertype in L3"));
}
Expand Down
23 changes: 17 additions & 6 deletions pcap-rewrite/src/filters/fragmentation/fragmentation_test.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
use libpcap_tools::{Error, ParseContext};

use log::warn;
use pnet_packet::ipv4::Ipv4Packet;
use pnet_packet::ipv6::Ipv6Packet;

use crate::filters::ipv6_utils;

pub fn is_ipv4_first_fragment(_ctx: &ParseContext, payload: &[u8]) -> Result<bool, Error> {
let ipv4_packet =
Ipv4Packet::new(payload).ok_or(Error::Pnet("Expected Ipv4 packet but could not parse"))?;
pub fn is_ipv4_first_fragment(ctx: &ParseContext, payload: &[u8]) -> Result<bool, Error> {
let ipv4_packet = Ipv4Packet::new(payload).ok_or_else(|| {
warn!(
"Expected Ipv4 packet but could not parse at index {}",
ctx.pcap_index
);
Error::Pnet("Expected Ipv4 packet but could not parse")
})?;
let flags = ipv4_packet.get_flags();
let fragment_offset = ipv4_packet.get_fragment_offset();

Expand All @@ -16,9 +22,14 @@ pub fn is_ipv4_first_fragment(_ctx: &ParseContext, payload: &[u8]) -> Result<boo
Ok(mf_flag == 1 && fragment_offset == 0)
}

pub fn is_ipv6_first_fragment(_ctx: &ParseContext, payload: &[u8]) -> Result<bool, Error> {
let ipv6_packet =
Ipv6Packet::new(payload).ok_or(Error::Pnet("Expected Ipv6 packet but could not parse"))?;
pub fn is_ipv6_first_fragment(ctx: &ParseContext, payload: &[u8]) -> Result<bool, Error> {
let ipv6_packet = Ipv6Packet::new(payload).ok_or_else(|| {
warn!(
"Expected Ipv6 packet but could not parse at index {}",
ctx.pcap_index
);
Error::Pnet("Expected Ipv6 packet but could not parse")
})?;
let (fragment_packet_option, _l4_proto, _payload) =
ipv6_utils::get_fragment_packet_option_l4_protol4_payload(payload, &ipv6_packet)?;
match fragment_packet_option {
Expand Down
Loading

0 comments on commit d1a3918

Please sign in to comment.