use crate::extractor::{Extracted, FlowExtractor};
use crate::view::PacketView;
#[derive(Debug, Clone, Copy)]
pub struct StripVlan<E>(pub E);
impl<E: FlowExtractor> FlowExtractor for StripVlan<E> {
type Key = E::Key;
fn extract(&self, view: PacketView<'_>) -> Option<Extracted<E::Key>> {
self.0.extract(view)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::Timestamp;
use crate::extract::FiveTuple;
use etherparse::{Ethernet2Header, IpNumber, Ipv4Header, SingleVlanHeader, TcpHeader, VlanId};
fn vlan_ipv4_tcp(vlan_id: u16) -> Vec<u8> {
let payload = b"";
let mut tcp = TcpHeader::new(1234, 80, 1000, 8192);
tcp.syn = true;
let ip = Ipv4Header::new(
(tcp.header_len() + payload.len()) as u16,
64,
IpNumber::TCP,
[10, 0, 0, 1],
[10, 0, 0, 2],
)
.unwrap();
let vlan = SingleVlanHeader {
pcp: 0u8.try_into().unwrap(),
drop_eligible_indicator: false,
vlan_id: VlanId::try_new(vlan_id).unwrap(),
ether_type: etherparse::EtherType::IPV4,
};
let eth = Ethernet2Header {
destination: [0; 6],
source: [0; 6],
ether_type: etherparse::EtherType::VLAN_TAGGED_FRAME,
};
let mut out = Vec::new();
eth.write(&mut out).unwrap();
vlan.write(&mut out).unwrap();
ip.write(&mut out).unwrap();
tcp.write(&mut out).unwrap();
out.extend_from_slice(payload);
out
}
#[test]
fn vlan_tagged_frame_extracts() {
let f = vlan_ipv4_tcp(100);
let e = StripVlan(FiveTuple::bidirectional())
.extract(PacketView::new(&f, Timestamp::default()))
.unwrap();
assert!(e.tcp.is_some());
}
}