10个版本
0.1.0 | 2024年7月20日 |
---|---|
0.0.9 | 2024年7月15日 |
#562 在 网络编程
每月下载量 519次
210KB
4.5K SLoC
zero-packet
一个超级简单的库,可以高效地原地构建和解析网络数据包,无额外开销。
无异步,无分配,无依赖,无std,无不安全。它简单到不能再简单。
如果您正在处理原始套接字、低级网络或其他类似任务,请使用zero-packet
。
支持
您可以构建和解析各种任意复杂性的数据包。
- 以太网II
- 可选
- VLAN标记
- 双重标记
- 可选
- ARP
- IPv4
- IPv6
- 扩展头
- 跳选项
- 路由
- 分片
- 认证头
- 目标选项(第一和第二)
- 扩展头
- IP-in-IP
- 封装
- IPv4在IPv4中
- IPv4在IPv6中
- IPv6在IPv4中
- IPv6在IPv6中
- 封装
- ICMPv4
- ICMPv6
- TCP
- UDP
用法
入门
通过您的命令行安装
cargo add zero-packet
或将以下内容添加到您的Cargo.toml
[dependencies]
zero-packet = "0.1.0"
PacketBuilder
如果您想手动且高效地创建网络数据包,请查看此处。
// Raw packet that we will mutate in-place.
// Ethernet header (14 bytes) + IPv4 header (20 bytes) + UDP header (8 bytes) = 42 bytes.
let mut buffer = [0u8; 64]
// Some random payload (11 bytes).
let payload = b"Hello, UDP!";
// PacketBuilder is a zero-copy packet builder.
// Using the typestate pattern, a state machine is implemented at compile-time.
// The state machine ensures that the package is built structurally correct.
let mut packet_builder = PacketBuilder::new(&mut buffer);
// Sets Ethernet, IPv4 and UDP header fields.
// Optional: add payload to the packet.
// Encapsulates everything in the given byte slice.
let packet: &[u8] = packet_builder
.ethernet(src_mac, dest_mac, ethertype)?
.ipv4(version, ihl, dscp, ecn, total_length, id, flags, fragment_offset, ttl, protocol, src_ip, dest_ip)?
.udp(src_ip, src_port, dest_ip, dest_port, length, Some(payload))?
.build();
PacketParser
解析任何我们事先不知道其类型的数据包的接收到的字节切片。
// Some byte slice that we have received.
// We don't know yet what it contains.
let packet = [..];
// PacketParser is a zero-copy packet parser.
// The `parse` method recognizes which protocol headers are present.
let parsed = PacketParser::parse(&packet)?;
// Now it is as easy as this.
if let Some(ethernet) = parsed.ethernet {
let ethertype = ethernet.ethertype();
// ...
}
// Or this.
if let Some(ipv4) = parsed.ipv4 {
let src_ip = ipv4.src_ip();
// ...
}
// Alternatively, just manually read headers directly.
// By adjusting the index of the slice you can find different headers.
if let Some(tcp) = TcpReader::new(&packet)? {
let src_port = tcp.src_port();
// ...
}