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 CapturedPacket, LinkType, PcapIterator, PcapMetadata, rdpcap, wrpcap, wrpcap_packets,
164};
165
166pub use flow::{
168 CanonicalKey, ConversationState, ConversationStatus, ConversationTable, DirectionStats,
169 FlowConfig, FlowDirection, FlowError, ProtocolState, TransportProtocol, ZWaveFlowState,
170 ZWaveKey, extract_flows, extract_flows_with_config, extract_zwave_flows,
171};
172
173pub use utils::{
175 align_to, ethernet_min_frame, extract_bits, hexdump, hexstr, hexstr_sep, internet_checksum,
176 pad_to, parse_hex, set_bits, transport_checksum, verify_checksum,
177};
178
179pub mod ethertype {
181 pub use crate::layer::ethertype::*;
182}
183
184pub mod ip_protocol {
186 pub use crate::layer::ip_protocol::*;
187}
188
189pub mod arp_opcode {
191 pub use crate::layer::arp::opcode::*;
192}
193
194pub mod arp_hardware {
196 pub use crate::layer::arp::hardware_type::*;
197}
198
199pub mod arp_protocol {
201 pub use crate::layer::arp::protocol_type::*;
202}
203
204pub mod prelude {
206 pub use crate::arp_hardware;
207 pub use crate::arp_opcode;
208 pub use crate::ethertype;
209 pub use crate::{
210 ARP_HEADER_LEN,
211 ArpBuilder,
212 ArpCache,
213 ArpLayer,
215 BindingRegistry,
216 BytesField,
217 Dot3Builder,
218 Dot3Layer,
219 ETHERNET_HEADER_LEN,
220 EthernetBuilder,
221 EthernetLayer,
223 Field,
224 FieldDesc,
225 FieldError,
226 FieldType,
227 FieldValue,
228 HardwareAddr,
229 IntoLayerStackEntry,
231 Ipv4Builder,
232 Ipv4Flags,
233 Layer,
234 LayerBinding,
236 LayerEnum,
237 LayerIndex,
238 LayerKind,
239 LayerStack,
240 LayerStackEntry,
241 MacAddress,
243 NdpCache,
244 NeighborCache,
246 Packet,
248 PacketError,
249 ProtocolAddr,
250 RawBuilder,
252 RawLayer,
253 Result,
254 TcpBuilder,
255 TcpFlags,
256 apply_binding,
257 find_binding,
258 ipv4_multicast_mac,
259 ipv6_multicast_mac,
260 is_dot3,
261 is_ethernet_ii,
262 };
263 pub use std::net::{Ipv4Addr, Ipv6Addr};
264}
265
266pub const VERSION: &str = env!("CARGO_PKG_VERSION");
268
269#[must_use]
271pub fn version() -> &'static str {
272 VERSION
273}
274
275#[cfg(test)]
276mod tests {
277 use super::prelude::*;
278
279 #[test]
280 fn test_basic_packet_creation() {
281 let eth = EthernetBuilder::new()
283 .dst(MacAddress::BROADCAST)
284 .src(MacAddress::new([0x00, 0x11, 0x22, 0x33, 0x44, 0x55]))
285 .build_with_payload(LayerKind::Arp);
286
287 let arp = ArpBuilder::who_has(Ipv4Addr::new(192, 168, 1, 100))
289 .hwsrc(MacAddress::new([0x00, 0x11, 0x22, 0x33, 0x44, 0x55]))
290 .psrc(Ipv4Addr::new(192, 168, 1, 1))
291 .build();
292
293 let mut packet_data = eth;
295 packet_data.extend_from_slice(&arp);
296
297 let mut packet = Packet::from_bytes(packet_data);
299 packet.parse().unwrap();
300
301 assert_eq!(packet.layer_count(), 2);
302
303 let eth_layer = packet.ethernet().unwrap();
304 assert_eq!(
305 eth_layer.ethertype(packet.as_bytes()).unwrap(),
306 ethertype::ARP
307 );
308
309 let arp_layer = packet.arp().unwrap();
310 assert!(arp_layer.is_request(packet.as_bytes()));
311 }
312
313 #[test]
314 fn test_layer_bindings() {
315 let binding = find_binding(LayerKind::Ethernet, LayerKind::Arp);
317 assert!(binding.is_some());
318 assert_eq!(binding.unwrap().field_value, 0x0806);
319
320 let (field, value) = apply_binding(LayerKind::Ethernet, LayerKind::Ipv4).unwrap();
322 assert_eq!(field, "type");
323 assert_eq!(value, 0x0800);
324 }
325
326 #[test]
327 fn test_neighbor_resolution() {
328 let _cache = NeighborCache::new();
329
330 let mcast_ip = Ipv4Addr::new(224, 0, 0, 1);
332 let mcast_mac = ipv4_multicast_mac(mcast_ip);
333 assert!(mcast_mac.is_multicast());
334 assert!(mcast_mac.is_ipv4_multicast());
335 }
336
337 #[test]
338 fn test_frame_type_dispatch() {
339 let eth2 = vec![
341 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x08,
342 0x00, ];
344 assert!(!is_dot3(ð2, 0));
345 assert!(is_ethernet_ii(ð2, 0));
346
347 let dot3 = vec![
349 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x00,
350 0x64, ];
352 assert!(is_dot3(&dot3, 0));
353 assert!(!is_ethernet_ii(&dot3, 0));
354 }
355}