Rust structs representing network protocol headers (on Layer 2, 3 and 4).
The crate is no_std, which makes it a great fit for eBPF programs written with Aya.
An example of an XDP program logging information about addresses and ports for incoming packets:
```rust use core::mem;
use ayabpf::{bindings::xdpaction, macros::xdp, programs::XdpContext}; use ayalogebpf::info;
use network_types::{ eth::{EthHdr, EtherType}, ip::{Ipv4Hdr, IpProto}, tcp::TcpHdr, udp::UdpHdr, };
pub fn xdpfirewall(ctx: XdpContext) -> u32 { match tryxdpfirewall(ctx) { Ok(ret) => ret, Err() => xdpaction::XDPPASS, } }
unsafe fn ptrat
if start + offset + len > end {
return Err(());
}
Ok((start + offset) as *const T)
}
fn tryxdpfirewall(ctx: XdpContext) -> Result
let ipv4hdr: *const Ipv4Hdr = unsafe { ptr_at(&ctx, EthHdr::LEN)? };
let source_addr = u32::from_be(unsafe { *ipv4hdr }.src_addr);
let source_port = match unsafe { *ipv4hdr }.proto {
IpProto::Tcp => {
let tcphdr: *const TcpHdr =
unsafe { ptr_at(&ctx, EthHdr::LEN + Ipv4Hdr::LEN) }?;
u16::from_be(unsafe { *tcphdr }.source)
}
IpProto::Udp => {
let udphdr: *const UdpHdr =
unsafe { ptr_at(&ctx, EthHdr::LEN + Ipv4Hdr::LEN) }?;
u16::from_be(unsafe { *udphdr }.source)
}
_ => return Err(()),
};
info!(&ctx, "SRC IP: {}, SRC PORT: {}", source_addr, source_port);
Ok(xdp_action::XDP_PASS)
} ```
When naming stucts and fields, we are trying to stick to the following principles:
CamelCase
, even for names which normally would be all uppercase
(e.g. Icmp
instead of ICMP
). This is the convention used by the
std::net module._
. In general, use snake_case
for field names.source
-> src
destination
-> dst
address
-> addr
License: MIT