1use anyhow::Result;
2use etherparse::{Ethernet2Slice, Ipv4Slice, Ipv6Slice, LinkSlice, NetSlice, SlicedPacket};
3
4pub enum RecvPacketIp<'a> {
5 Ipv4(&'a Ipv4Slice<'a>),
6 Ipv6(&'a Ipv6Slice<'a>),
7}
8
9pub struct RecvPacket<'a> {
10 pub raw: &'a [u8],
11 pub slice: &'a SlicedPacket<'a>,
12 pub ether: Option<&'a Ethernet2Slice<'a>>,
13 pub ip: Option<RecvPacketIp<'a>>,
14}
15
16impl RecvPacket<'_> {
17 pub fn new<'a>(raw: &'a [u8], slice: &'a SlicedPacket<'a>) -> Result<RecvPacket<'a>> {
18 let ether = match slice.link {
19 Some(LinkSlice::Ethernet2(ref ether)) => Some(ether),
20 _ => None,
21 };
22
23 let ip = match slice.net {
24 Some(NetSlice::Ipv4(ref ipv4)) => Some(RecvPacketIp::Ipv4(ipv4)),
25 Some(NetSlice::Ipv6(ref ipv6)) => Some(RecvPacketIp::Ipv6(ipv6)),
26 _ => None,
27 };
28
29 let packet = RecvPacket {
30 raw,
31 slice,
32 ether,
33 ip,
34 };
35 Ok(packet)
36 }
37}