25 个版本
0.7.1 | 2024 年 8 月 13 日 |
---|---|
0.7.0 | 2024 年 3 月 25 日 |
0.6.2 | 2024 年 2 月 27 日 |
0.5.7 | 2023 年 10 月 17 日 |
0.1.1 | 2021 年 6 月 8 日 |
#60 在 解析器实现
144,241 每月下载量
在 131 个 仓库中使用 (直接使用 9 个)
170KB
4K SLoC
Simple DNS
纯 Rust 实现,用于处理 DNS 数据包
您可以使用 Packet 来解析或写入 DNS 数据包
Packet
Packet
代表一个 DNS 数据包,它是构造和操作数据包并在写入线格式之前的主要结构。
use simple_dns::*;
use simple_dns::rdata::*;
let mut packet = Packet::new_query(1);
let question = Question::new(Name::new_unchecked("_srv._udp.local"), TYPE::TXT.into(), CLASS::IN.into(), false);
packet.questions.push(question);
let resource = ResourceRecord::new(Name::new_unchecked("_srv._udp.local"), CLASS::IN, 10, RData::A(A { address: 10 }));
packet.additional_records.push(resource);
// Write the packet in the provided buffer;
let mut bytes = [0u8; 200];
assert!(packet.write_to(&mut &mut bytes[..]).is_ok());
// Same as above, but allocates and returns a Vec<u8>
let bytes = packet.build_bytes_vec();
assert!(bytes.is_ok());
// Same as above, but Names are compressed
let bytes = packet.build_bytes_vec_compressed();
assert!(bytes.is_ok());
资源的添加顺序无关紧要,只有在调用 build_bytes_vec
或 write_to
时才会构建数据包
要将缓冲区的内容解析为数据包,需要调用 Packet::parse
use simple_dns::Packet;
let bytes = b"\x00\x03\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x06\x67\x6f\x6f\x67\x6c\x65\x03\x63\x6f\x6d\x00\x00\x01\x00\x01";
let packet = Packet::parse(&bytes[..]);
assert!(packet.is_ok());
可以使用 header_buffer
模块函数来检查数据包的一些信息,而无需解析数据包。
检查 RCODE 和数据包标志时要小心,请参阅模块文档以获取更多信息。
use simple_dns::{header_buffer, PacketFlag};
let buffer = b"\x00\x03\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x06\x67\x6f\x6f\x67\x6c\x65\x03\x63\x6f\x6d\x00\x00\x01\x00\x01";
assert_eq!(Ok(3), header_buffer::id(&buffer[..]));
assert!(!header_buffer::has_flags(&buffer[..], PacketFlag::RESPONSE).unwrap());
Packet 支持 EDNS,通过 opt 和 opt_mut 函数。当处理 EDNS 数据包时,您 不应该 将 OPT 资源记录 直接添加到 附加记录 部分,除非您确切知道自己在做什么。
EDNS0 注意事项
EDNS 通过添加一个 OPT 资源记录并将部分头信息移动到附加记录部分来扩展 DNS 数据包头。RCODE 从 4 位增加到 12 位,其中前 4 位存储在头部部分,而最后 8 位存储在数据包的某个其他地方。
这将对数据包的解析或构建有一些影响
use simple_dns::{header_buffer, RCODE, Packet};
let buffer = b"\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x2e\x00\x00\x29\x01\xf4\x00\x00\x03\x01\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
let packet = Packet::parse(&buffer[..]).unwrap();
// Without parsing the full packet, it is impossible to know the true RCODE of the packet
assert_eq!(RCODE::NoError, header_buffer::rcode(&buffer[..]).unwrap());
assert_eq!(RCODE::BADVERS, packet.rcode());
请参阅 RFC 6891 以获取更多信息
DNS 数据包解析器/构建器
Packet 结构提供了数据包的解析和构建,它旨在完全符合以下 RFC
- RFC 1034
- RFC 1035
- RFC 1138
- RFC 1183
- RFC 1706
- RFC 1876
- RFC 1996
- RFC 2136
- RFC 6762
- RFC 2782
- RFC 3596
- RFC 6891
- RFC 9460
其他由其他RFC定义但不在本列表中的资源记录将逐步实现
更新数据包(RFC 2136)
此库可以解析更新数据包,但它不验证更新规则,并且更新字段在数据包字段中过载,如RFC 2136中定义。
依赖关系
~110KB