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