1#![warn(clippy::all)]
50#![warn(clippy::pedantic)]
51#![allow(clippy::module_name_repetitions)]
52
53pub mod error;
54pub mod flow;
55pub mod layer;
56pub mod packet;
57pub mod parallel;
58pub mod pcap;
59pub mod sniffer;
60pub mod utils;
61
62pub use error::{PacketError, Result};
64pub use layer::arp::{ARP_FIXED_HEADER_LEN, ARP_HEADER_LEN, ArpRoute, HardwareAddr, ProtocolAddr};
65pub use layer::bindings::{
66 BindingRegistry, apply_binding, expected_upper_layers, find_binding, find_bindings_from,
67 find_bindings_to, infer_upper_layer,
68};
69pub use layer::ethernet::{
70 DOT3_MAX_LENGTH, ETHERNET_HEADER_LEN, EthernetFrameType, dispatch_hook, is_dot3, is_ethernet_ii,
71};
72pub use layer::ftp::{
73 FTP_CONTROL_PORT, FTP_DATA_PORT, FTP_FIELD_NAMES, FTP_MIN_HEADER_LEN, FtpBuilder, FtpLayer,
74};
75pub use layer::imap::{IMAP_FIELD_NAMES, IMAP_MIN_HEADER_LEN, IMAP_PORT, ImapBuilder, ImapLayer};
76pub use layer::modbus::{
77 MODBUS_FIELD_NAMES, MODBUS_MIN_HEADER_LEN, MODBUS_TCP_PORT, ModbusBuilder, ModbusLayer,
78};
79pub use layer::mqtt::{MQTT_FIELD_NAMES, MQTT_MIN_HEADER_LEN, MQTT_PORT, MqttBuilder, MqttLayer};
80pub use layer::mqttsn::{
81 MQTTSN_FIELD_NAMES, MQTTSN_MIN_HEADER_LEN, MQTTSN_PORT, MqttSnBuilder, MqttSnLayer,
82};
83pub use layer::neighbor::{
84 ArpCache, CacheEntry, NdpCache, ipv4_multicast_mac, ipv6_multicast_mac, is_ipv4_multicast,
85 is_ipv6_multicast, solicited_node_multicast,
86};
87pub use layer::pop3::{POP3_FIELD_NAMES, POP3_MIN_HEADER_LEN, POP3_PORT, Pop3Builder, Pop3Layer};
88pub use layer::quic::builder::QuicBuilder;
89pub use layer::smtp::{SMTP_FIELD_NAMES, SMTP_MIN_HEADER_LEN, SMTP_PORT, SmtpBuilder, SmtpLayer};
90pub use layer::tftp::{TFTP_MIN_HEADER_LEN, TFTP_PORT, TftpBuilder, TftpLayer};
91pub use layer::zwave::{
92 ZWAVE_FIELD_NAMES, ZWAVE_HEADER_LEN, ZWAVE_MIN_HEADER_LEN, ZWaveBuilder, ZWaveLayer,
93};
94pub use layer::{
95 ArpBuilder,
97 ArpLayer,
99 BytesField,
101 DnsLayer,
102 Dot3Builder,
103 Dot3Layer,
104 EthernetBuilder,
105 EthernetLayer,
106 Field,
107 FieldDesc,
108 FieldError,
109 FieldType,
110 FieldValue,
111 Http2Builder,
112 Http2FrameBuilder,
113 HttpRequestBuilder,
114 HttpResponseBuilder,
115 ICMPV6_MIN_HEADER_LEN,
116 IPV6_HEADER_LEN,
117 IcmpBuilder,
118 IcmpLayer,
119 Icmpv6Builder,
120 Icmpv6Layer,
121 IntoLayerStackEntry,
123 Ipv4Builder,
124 Ipv4Flags,
125 Ipv4Layer,
126 Ipv6Builder,
127 Ipv6Layer,
128 L2TP_FIELD_NAMES,
129 L2TP_MIN_HEADER_LEN,
130 L2TP_PORT,
131 L2tpBuilder,
132 L2tpLayer,
133 LAYER_BINDINGS,
134 Layer,
136 LayerBinding,
138 LayerEnum,
139 LayerIndex,
140 LayerKind,
141 LayerStack,
142 LayerStackEntry,
143 MacAddress,
144 NeighborCache,
146 NeighborResolver,
147 RAW_FIELDS,
148 RawBuilder,
149 RawLayer,
150 SSH_BINARY_HEADER_LEN,
151 SSH_PORT,
152 SshBuilder,
153 SshLayer,
154 TcpBuilder,
155 TcpFlags,
156 TcpLayer,
157 TlsRecordBuilder,
158 UdpBuilder,
159 UdpLayer,
160 icmpv6_checksum,
161 verify_icmpv6_checksum,
162};
163pub use packet::Packet;
164pub use pcap::{
165 CaptureFormat, CaptureIterator, CapturedPacket, LinkType, PcapIterator, PcapMetadata,
166 PcapNgIterator, PcapNgStreamWriter, rdpcap, wrpcap, wrpcap_packets, wrpcapng, wrpcapng_packets,
167};
168
169pub use flow::{
171 CanonicalKey, ConversationState, ConversationStatus, ConversationTable, DirectionStats,
172 FlowConfig, FlowDirection, FlowError, ProtocolState, TransportProtocol, ZWaveFlowState,
173 ZWaveKey, extract_flows, extract_flows_from_file, extract_flows_streaming,
174 extract_flows_with_config, extract_zwave_flows,
175};
176
177pub use sniffer::{
179 CaptureStats, InterfaceInfo, ParsedPacket, RawPacket, SnifferConfig, SnifferError,
180 SnifferHandle, WorkerPoolConfig, WorkerPoolSniffer, list_interfaces, validate_filter,
181};
182
183pub use utils::{
185 align_to, ethernet_min_frame, extract_bits, hexdump, hexstr, hexstr_sep, internet_checksum,
186 pad_to, parse_hex, set_bits, transport_checksum, verify_checksum,
187};
188
189pub mod ethertype {
191 pub use crate::layer::ethertype::*;
192}
193
194pub mod ip_protocol {
196 pub use crate::layer::ip_protocol::*;
197}
198
199pub mod arp_opcode {
201 pub use crate::layer::arp::opcode::*;
202}
203
204pub mod arp_hardware {
206 pub use crate::layer::arp::hardware_type::*;
207}
208
209pub mod arp_protocol {
211 pub use crate::layer::arp::protocol_type::*;
212}
213
214pub mod prelude {
216 pub use crate::arp_hardware;
217 pub use crate::arp_opcode;
218 pub use crate::ethertype;
219 pub use crate::{
220 ARP_HEADER_LEN,
221 ArpBuilder,
222 ArpCache,
223 ArpLayer,
225 BindingRegistry,
226 BytesField,
227 Dot3Builder,
228 Dot3Layer,
229 ETHERNET_HEADER_LEN,
230 EthernetBuilder,
231 EthernetLayer,
233 Field,
234 FieldDesc,
235 FieldError,
236 FieldType,
237 FieldValue,
238 HardwareAddr,
239 IntoLayerStackEntry,
241 Ipv4Builder,
242 Ipv4Flags,
243 Layer,
244 LayerBinding,
246 LayerEnum,
247 LayerIndex,
248 LayerKind,
249 LayerStack,
250 LayerStackEntry,
251 MacAddress,
253 NdpCache,
254 NeighborCache,
256 Packet,
258 PacketError,
259 ProtocolAddr,
260 RawBuilder,
262 RawLayer,
263 Result,
264 TcpBuilder,
265 TcpFlags,
266 apply_binding,
267 find_binding,
268 ipv4_multicast_mac,
269 ipv6_multicast_mac,
270 is_dot3,
271 is_ethernet_ii,
272 };
273 pub use std::net::{Ipv4Addr, Ipv6Addr};
274}
275
276pub const VERSION: &str = env!("CARGO_PKG_VERSION");
278
279#[must_use]
281pub fn version() -> &'static str {
282 VERSION
283}
284
285#[cfg(test)]
286mod tests {
287 use super::prelude::*;
288
289 #[test]
290 fn test_basic_packet_creation() {
291 let eth = EthernetBuilder::new()
293 .dst(MacAddress::BROADCAST)
294 .src(MacAddress::new([0x00, 0x11, 0x22, 0x33, 0x44, 0x55]))
295 .build_with_payload(LayerKind::Arp);
296
297 let arp = ArpBuilder::who_has(Ipv4Addr::new(192, 168, 1, 100))
299 .hwsrc(MacAddress::new([0x00, 0x11, 0x22, 0x33, 0x44, 0x55]))
300 .psrc(Ipv4Addr::new(192, 168, 1, 1))
301 .build();
302
303 let mut packet_data = eth;
305 packet_data.extend_from_slice(&arp);
306
307 let mut packet = Packet::from_bytes(packet_data);
309 packet.parse().unwrap();
310
311 assert_eq!(packet.layer_count(), 2);
312
313 let eth_layer = packet.ethernet().unwrap();
314 assert_eq!(
315 eth_layer.ethertype(packet.as_bytes()).unwrap(),
316 ethertype::ARP
317 );
318
319 let arp_layer = packet.arp().unwrap();
320 assert!(arp_layer.is_request(packet.as_bytes()));
321 }
322
323 #[test]
324 fn test_layer_bindings() {
325 let binding = find_binding(LayerKind::Ethernet, LayerKind::Arp);
327 assert!(binding.is_some());
328 assert_eq!(binding.unwrap().field_value, 0x0806);
329
330 let (field, value) = apply_binding(LayerKind::Ethernet, LayerKind::Ipv4).unwrap();
332 assert_eq!(field, "type");
333 assert_eq!(value, 0x0800);
334 }
335
336 #[test]
337 fn test_neighbor_resolution() {
338 let _cache = NeighborCache::new();
339
340 let mcast_ip = Ipv4Addr::new(224, 0, 0, 1);
342 let mcast_mac = ipv4_multicast_mac(mcast_ip);
343 assert!(mcast_mac.is_multicast());
344 assert!(mcast_mac.is_ipv4_multicast());
345 }
346
347 #[test]
348 fn test_frame_type_dispatch() {
349 let eth2 = vec![
351 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x08,
352 0x00, ];
354 assert!(!is_dot3(ð2, 0));
355 assert!(is_ethernet_ii(ð2, 0));
356
357 let dot3 = vec![
359 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x00,
360 0x64, ];
362 assert!(is_dot3(&dot3, 0));
363 assert!(!is_ethernet_ii(&dot3, 0));
364 }
365}