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