6 个版本
0.0.6 | 2024 年 6 月 4 日 |
---|---|
0.0.5 | 2023 年 11 月 30 日 |
0.0.4 | 2023 年 1 月 9 日 |
0.0.3 | 2022 年 12 月 29 日 |
0.0.2 | 2022 年 11 月 28 日 |
#1 在 #osi 中
每月 1,470 次下载
39KB
781 行
network-types
表示网络协议头部(在第 2、3 和 4 层)的 Rust 结构体。
该包是 no_std,这使得它非常适合使用 Aya 编写的 eBPF 程序。
示例
一个示例,用于记录关于入站数据包的地址和端口的 XDP 程序
use core::mem;
use aya_ebpf::{bindings::xdp_action, macros::xdp, programs::XdpContext};
use aya_log_ebpf::info;
use network_types::{
eth::{EthHdr, EtherType},
ip::{Ipv4Hdr, Ipv6Hdr, IpProto},
tcp::TcpHdr,
udp::UdpHdr,
};
#[xdp]
pub fn xdp_firewall(ctx: XdpContext) -> u32 {
match try_xdp_firewall(ctx) {
Ok(ret) => ret,
Err(_) => xdp_action::XDP_PASS,
}
}
#[inline(always)]
unsafe fn ptr_at<T>(ctx: &XdpContext, offset: usize) -> Result<*const T, ()> {
let start = ctx.data();
let end = ctx.data_end();
let len = mem::size_of::<T>();
if start + offset + len > end {
return Err(());
}
Ok((start + offset) as *const T)
}
fn try_xdp_firewall(ctx: XdpContext) -> Result<u32, ()> {
let ethhdr: *const EthHdr = unsafe { ptr_at(&ctx, 0)? };
match unsafe { *ethhdr }.ether_type {
EtherType::Ipv4 => {
let ipv4hdr: *const Ipv4Hdr = unsafe { ptr_at(&ctx, EthHdr::LEN)? };
let source_addr = 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 Ok(xdp_action::XDP_PASS),
};
info!(&ctx, "SRC IP: {:i}, SRC PORT: {}", source_addr, source_port);
}
EtherType::Ipv6 => {
let ipv6hdr: *const Ipv6Hdr = unsafe { ptr_at(&ctx, EthHdr::LEN)? };
let source_addr = unsafe { (*ipv6hdr).src_addr.in6_u.u6_addr8 };
let source_port = match unsafe { (*ipv6hdr).next_hdr } {
IpProto::Tcp => {
let tcphdr: *const TcpHdr =
unsafe { ptr_at(&ctx, EthHdr::LEN + Ipv6Hdr::LEN) }?;
u16::from_be(unsafe { (*tcphdr).source })
}
IpProto::Udp => {
let udphdr: *const UdpHdr =
unsafe { ptr_at(&ctx, EthHdr::LEN + Ipv6Hdr::LEN) }?;
u16::from_be(unsafe { (*udphdr).source })
}
_ => return Ok(xdp_action::XDP_PASS),
};
info!(&ctx, "SRC IP: {:i}, SRC PORT: {}", source_addr, source_port);
}
_ => {},
}
Ok(xdp_action::XDP_PASS)
}
命名约定
在命名结构体和字段时,我们尽量遵守以下原则
- 使用
CamelCase
,即使对于通常全大写的名称(例如,Icmp
而不是ICMP
)。这是 std::net 模块使用的约定。 - 当字段名称(由 RFC 或其他标准指定)包含空格时,请用
_
替换。通常,使用snake_case
为字段名称。 - 缩短以下冗长的名称
source
->src
destination
->dst
address
->addr
功能标志
Serde 支持可以通过 serde
功能标志启用。它打算与像 bincode
这样的二进制序列化库一起使用,这些库利用 Serde 的基础设施。
请注意,启用 Serde 时会丢失 no_std
支持。
许可证:MIT
依赖项
~170KB