1#![warn(clippy::all)]
50#![warn(clippy::pedantic)]
51#![allow(clippy::module_name_repetitions)]
52
53pub mod error;
54pub mod layer;
55pub mod packet;
56pub mod pcap;
57pub mod utils;
58
59pub use error::{PacketError, Result};
61pub use layer::arp::{ARP_FIXED_HEADER_LEN, ARP_HEADER_LEN, ArpRoute, HardwareAddr, ProtocolAddr};
62pub use layer::bindings::{
63 BindingRegistry, apply_binding, expected_upper_layers, find_binding, find_bindings_from,
64 find_bindings_to, infer_upper_layer,
65};
66pub use layer::ethernet::{
67 DOT3_MAX_LENGTH, ETHERNET_HEADER_LEN, EthernetFrameType, dispatch_hook, is_dot3, is_ethernet_ii,
68};
69pub use layer::neighbor::{
70 ArpCache, CacheEntry, NdpCache, ipv4_multicast_mac, ipv6_multicast_mac, is_ipv4_multicast,
71 is_ipv6_multicast, solicited_node_multicast,
72};
73pub use layer::quic::builder::QuicBuilder;
74pub use layer::{
75 ArpBuilder,
77 ArpLayer,
79 BytesField,
81 DnsLayer,
82 Dot3Builder,
83 Dot3Layer,
84 EthernetBuilder,
85 EthernetLayer,
86 Field,
87 FieldDesc,
88 FieldError,
89 FieldType,
90 FieldValue,
91 Http2Builder,
92 Http2FrameBuilder,
93 HttpRequestBuilder,
94 HttpResponseBuilder,
95 ICMPV6_MIN_HEADER_LEN,
96 IPV6_HEADER_LEN,
97 IcmpBuilder,
98 IcmpLayer,
99 Icmpv6Builder,
100 Icmpv6Layer,
101 IntoLayerStackEntry,
103 Ipv4Builder,
104 Ipv4Flags,
105 Ipv4Layer,
106 Ipv6Builder,
107 Ipv6Layer,
108 L2TP_FIELD_NAMES,
109 L2TP_MIN_HEADER_LEN,
110 L2TP_PORT,
111 L2tpBuilder,
112 L2tpLayer,
113 LAYER_BINDINGS,
114 Layer,
116 LayerBinding,
118 LayerEnum,
119 LayerIndex,
120 LayerKind,
121 LayerStack,
122 LayerStackEntry,
123 MacAddress,
124 NeighborCache,
126 NeighborResolver,
127 RAW_FIELDS,
128 RawBuilder,
129 RawLayer,
130 SSH_BINARY_HEADER_LEN,
131 SSH_PORT,
132 SshBuilder,
133 SshLayer,
134 TcpBuilder,
135 TcpFlags,
136 TcpLayer,
137 TlsRecordBuilder,
138 UdpBuilder,
139 UdpLayer,
140 icmpv6_checksum,
141 verify_icmpv6_checksum,
142};
143pub use packet::Packet;
144pub use pcap::{
145 CapturedPacket, LinkType, PcapIterator, PcapMetadata, rdpcap, wrpcap, wrpcap_packets,
146};
147
148pub use utils::{
150 align_to, ethernet_min_frame, extract_bits, hexdump, hexstr, hexstr_sep, internet_checksum,
151 pad_to, parse_hex, set_bits, transport_checksum, verify_checksum,
152};
153
154pub mod ethertype {
156 pub use crate::layer::ethertype::*;
157}
158
159pub mod ip_protocol {
161 pub use crate::layer::ip_protocol::*;
162}
163
164pub mod arp_opcode {
166 pub use crate::layer::arp::opcode::*;
167}
168
169pub mod arp_hardware {
171 pub use crate::layer::arp::hardware_type::*;
172}
173
174pub mod arp_protocol {
176 pub use crate::layer::arp::protocol_type::*;
177}
178
179pub mod prelude {
181 pub use crate::arp_hardware;
182 pub use crate::arp_opcode;
183 pub use crate::ethertype;
184 pub use crate::{
185 ARP_HEADER_LEN,
186 ArpBuilder,
187 ArpCache,
188 ArpLayer,
190 BindingRegistry,
191 BytesField,
192 Dot3Builder,
193 Dot3Layer,
194 ETHERNET_HEADER_LEN,
195 EthernetBuilder,
196 EthernetLayer,
198 Field,
199 FieldDesc,
200 FieldError,
201 FieldType,
202 FieldValue,
203 HardwareAddr,
204 IntoLayerStackEntry,
206 Ipv4Builder,
207 Ipv4Flags,
208 Layer,
209 LayerBinding,
211 LayerEnum,
212 LayerIndex,
213 LayerKind,
214 LayerStack,
215 LayerStackEntry,
216 MacAddress,
218 NdpCache,
219 NeighborCache,
221 Packet,
223 PacketError,
224 ProtocolAddr,
225 RawBuilder,
227 RawLayer,
228 Result,
229 TcpBuilder,
230 TcpFlags,
231 apply_binding,
232 find_binding,
233 ipv4_multicast_mac,
234 ipv6_multicast_mac,
235 is_dot3,
236 is_ethernet_ii,
237 };
238 pub use std::net::{Ipv4Addr, Ipv6Addr};
239}
240
241pub const VERSION: &str = env!("CARGO_PKG_VERSION");
243
244pub fn version() -> &'static str {
246 VERSION
247}
248
249#[cfg(test)]
250mod tests {
251 use super::prelude::*;
252
253 #[test]
254 fn test_basic_packet_creation() {
255 let eth = EthernetBuilder::new()
257 .dst(MacAddress::BROADCAST)
258 .src(MacAddress::new([0x00, 0x11, 0x22, 0x33, 0x44, 0x55]))
259 .build_with_payload(LayerKind::Arp);
260
261 let arp = ArpBuilder::who_has(Ipv4Addr::new(192, 168, 1, 100))
263 .hwsrc(MacAddress::new([0x00, 0x11, 0x22, 0x33, 0x44, 0x55]))
264 .psrc(Ipv4Addr::new(192, 168, 1, 1))
265 .build();
266
267 let mut packet_data = eth;
269 packet_data.extend_from_slice(&arp);
270
271 let mut packet = Packet::from_bytes(packet_data);
273 packet.parse().unwrap();
274
275 assert_eq!(packet.layer_count(), 2);
276
277 let eth_layer = packet.ethernet().unwrap();
278 assert_eq!(
279 eth_layer.ethertype(packet.as_bytes()).unwrap(),
280 ethertype::ARP
281 );
282
283 let arp_layer = packet.arp().unwrap();
284 assert!(arp_layer.is_request(packet.as_bytes()));
285 }
286
287 #[test]
288 fn test_layer_bindings() {
289 let binding = find_binding(LayerKind::Ethernet, LayerKind::Arp);
291 assert!(binding.is_some());
292 assert_eq!(binding.unwrap().field_value, 0x0806);
293
294 let (field, value) = apply_binding(LayerKind::Ethernet, LayerKind::Ipv4).unwrap();
296 assert_eq!(field, "type");
297 assert_eq!(value, 0x0800);
298 }
299
300 #[test]
301 fn test_neighbor_resolution() {
302 let _cache = NeighborCache::new();
303
304 let mcast_ip = Ipv4Addr::new(224, 0, 0, 1);
306 let mcast_mac = ipv4_multicast_mac(mcast_ip);
307 assert!(mcast_mac.is_multicast());
308 assert!(mcast_mac.is_ipv4_multicast());
309 }
310
311 #[test]
312 fn test_frame_type_dispatch() {
313 let eth2 = vec![
315 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x08,
316 0x00, ];
318 assert!(!is_dot3(ð2, 0));
319 assert!(is_ethernet_ii(ð2, 0));
320
321 let dot3 = vec![
323 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x00,
324 0x64, ];
326 assert!(is_dot3(&dot3, 0));
327 assert!(!is_ethernet_ii(&dot3, 0));
328 }
329}