1pub mod arp;
7pub mod bindings;
8pub mod dns;
9pub mod dot11;
10pub mod dot15d4;
11pub mod ethernet;
12pub mod field;
13pub mod field_ext;
14pub mod ftp;
15pub mod generic;
16pub mod http;
17pub mod http2;
18pub mod icmp;
19pub mod icmpv6;
20pub mod imap;
21pub mod ipv4;
22pub mod ipv6;
23pub mod l2tp;
24pub mod modbus;
25pub mod mqtt;
26pub mod mqttsn;
27pub mod neighbor;
28pub mod pop3;
29pub mod quic;
30pub mod raw;
31pub mod smtp;
32pub mod ssh;
33pub mod stack;
34pub mod tcp;
35pub mod tftp;
36pub mod tls;
37pub mod udp;
38pub mod zwave;
39
40use std::ops::Range;
41
42pub use arp::{ArpBuilder, ArpLayer};
44pub use bindings::{LAYER_BINDINGS, LayerBinding};
45pub use ethernet::{Dot3Builder, Dot3Layer, EthernetBuilder, EthernetLayer};
46pub use field::{BytesField, Field, FieldDesc, FieldError, FieldType, FieldValue, MacAddress};
47pub use ftp::{
48 FTP_CONTROL_PORT, FTP_DATA_PORT, FTP_FIELD_NAMES, FTP_MIN_HEADER_LEN, FtpBuilder, FtpLayer,
49 is_ftp_payload,
50};
51pub use http::{HTTP_FIELD_NAMES, HttpLayer, HttpRequestBuilder, HttpResponseBuilder};
52pub use http2::{HTTP2_FIELD_NAMES, Http2Builder, Http2FrameBuilder, Http2Layer};
53pub use icmp::{ICMP_MIN_HEADER_LEN, IcmpBuilder, IcmpLayer, icmp_checksum, verify_icmp_checksum};
54pub use icmpv6::{
55 ICMPV6_MIN_HEADER_LEN, Icmpv6Builder, Icmpv6Layer, icmpv6_checksum, verify_icmpv6_checksum,
56};
57pub use imap::{
58 IMAP_FIELD_NAMES, IMAP_MIN_HEADER_LEN, IMAP_PORT, ImapBuilder, ImapLayer, is_imap_payload,
59};
60pub use ipv4::{Ipv4Builder, Ipv4Flags, Ipv4Layer, Ipv4Options, Ipv4Route};
61pub use ipv6::{IPV6_HEADER_LEN, Ipv6Builder, Ipv6Layer};
62pub use l2tp::{L2TP_FIELD_NAMES, L2TP_MIN_HEADER_LEN, L2TP_PORT, L2tpBuilder, L2tpLayer};
63pub use modbus::{
64 MODBUS_FIELD_NAMES, MODBUS_MIN_HEADER_LEN, MODBUS_TCP_PORT, ModbusBuilder, ModbusLayer,
65 is_modbus_tcp_payload,
66};
67pub use mqtt::{
68 MQTT_FIELD_NAMES, MQTT_MIN_HEADER_LEN, MQTT_PORT, MqttBuilder, MqttLayer, is_mqtt_payload,
69};
70pub use mqttsn::{
71 MQTTSN_FIELD_NAMES, MQTTSN_MIN_HEADER_LEN, MQTTSN_PORT, MqttSnBuilder, MqttSnLayer,
72 is_mqttsn_payload,
73};
74pub use neighbor::{NeighborCache, NeighborResolver};
75pub use pop3::{
76 POP3_FIELD_NAMES, POP3_MIN_HEADER_LEN, POP3_PORT, Pop3Builder, Pop3Layer, is_pop3_payload,
77};
78pub use raw::{RAW_FIELDS, RawBuilder, RawLayer};
79pub use smtp::{
80 SMTP_FIELD_NAMES, SMTP_MIN_HEADER_LEN, SMTP_PORT, SmtpBuilder, SmtpLayer, is_smtp_payload,
81};
82pub use ssh::{SSH_BINARY_HEADER_LEN, SSH_PORT, SshBuilder, SshLayer};
83pub use stack::{IntoLayerStackEntry, LayerStack, LayerStackEntry};
84pub use tcp::{
85 TCP_FIELDS, TCP_MAX_HEADER_LEN, TCP_MIN_HEADER_LEN, TCP_SERVICES, TcpAoValue, TcpBuilder,
86 TcpFlags, TcpLayer, TcpOption, TcpOptionKind, TcpOptions, TcpOptionsBuilder, TcpSackBlock,
87 TcpTimestamp, service_name, service_port, tcp_checksum, tcp_checksum_ipv4, verify_tcp_checksum,
88};
89pub use tftp::{TFTP_MIN_HEADER_LEN, TFTP_PORT, TftpBuilder, TftpLayer, is_tftp_payload};
90pub use tls::{
91 TLS_FIELDS, TLS_PORT, TLS_RECORD_HEADER_LEN, TlsAlertBuilder, TlsCcsBuilder, TlsContentType,
92 TlsLayer, TlsRecordBuilder, TlsVersion,
93};
94pub use udp::{
95 UDP_HEADER_LEN, UdpBuilder, UdpLayer, udp_checksum_ipv4, udp_checksum_ipv6,
96 verify_udp_checksum_ipv4, verify_udp_checksum_ipv6,
97};
98pub use zwave::{
99 ZWAVE_FIELD_NAMES, ZWAVE_HEADER_LEN, ZWAVE_MIN_HEADER_LEN, ZWaveBuilder, ZWaveLayer,
100};
101
102#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
104#[repr(u8)]
105pub enum LayerKind {
106 Ethernet = 0,
107 Dot3 = 1,
108 Arp = 2,
109 Ipv4 = 3,
110 Ipv6 = 4,
111 Icmp = 5,
112 Icmpv6 = 6,
113 Tcp = 7,
114 Udp = 8,
115 Dns = 9,
116 Dot1Q = 10,
117 Dot1AD = 11,
118 Dot1AH = 12,
119 LLC = 13,
120 SNAP = 14,
121 Ssh = 15,
122 Tls = 16,
123 Dot15d4 = 17,
124 Dot15d4Fcs = 18,
125 Dot11 = 19,
126 Http = 20,
127 Quic = 21,
128 Generic = 22,
129 Http2 = 23,
130 L2tp = 24,
131 Mqtt = 25,
132 MqttSn = 26,
133 Modbus = 27,
134 ZWave = 28,
135 Ftp = 29,
136 Tftp = 30,
137 Smtp = 31,
138 Pop3 = 32,
139 Imap = 33,
140 Raw = 255,
141}
142
143impl LayerKind {
144 #[inline]
145 #[must_use]
146 pub const fn name(&self) -> &'static str {
147 match self {
148 Self::Ethernet => "Ethernet",
149 Self::Dot3 => "802.3",
150 Self::Arp => "ARP",
151 Self::Ipv4 => "IPv4",
152 Self::Ipv6 => "IPv6",
153 Self::Icmp => "ICMP",
154 Self::Icmpv6 => "ICMPv6",
155 Self::Tcp => "TCP",
156 Self::Udp => "UDP",
157 Self::Dns => "DNS",
158 Self::Dot1Q => "802.1Q",
159 Self::Dot1AD => "802.1AD",
160 Self::Dot1AH => "802.1AH",
161 Self::LLC => "LLC",
162 Self::SNAP => "SNAP",
163 Self::Ssh => "SSH",
164 Self::Tls => "TLS",
165 Self::Dot15d4 => "802.15.4",
166 Self::Dot15d4Fcs => "802.15.4 FCS",
167 Self::Dot11 => "802.11",
168 Self::Http => "HTTP",
169 Self::Quic => "QUIC",
170 Self::Generic => "Generic",
171 Self::Http2 => "HTTP/2",
172 Self::L2tp => "L2TP",
173 Self::Mqtt => "MQTT",
174 Self::MqttSn => "MQTT-SN",
175 Self::Modbus => "Modbus",
176 Self::ZWave => "Z-Wave",
177 Self::Ftp => "FTP",
178 Self::Tftp => "TFTP",
179 Self::Smtp => "SMTP",
180 Self::Pop3 => "POP3",
181 Self::Imap => "IMAP",
182 Self::Raw => "Raw",
183 }
184 }
185
186 #[inline]
187 #[must_use]
188 pub const fn min_header_size(&self) -> usize {
189 match self {
190 Self::Ethernet | Self::Dot3 => ethernet::ETHERNET_HEADER_LEN,
191 Self::Arp => arp::ARP_HEADER_LEN,
192 Self::Ipv4 => ipv4::IPV4_MIN_HEADER_LEN,
193 Self::Ipv6 => 40,
194 Self::Icmp | Self::Icmpv6 => 8,
195 Self::Tcp => tcp::TCP_MIN_HEADER_LEN,
196 Self::Udp => 8,
197 Self::Dns => 12,
198 Self::Dot1Q => 4,
199 Self::Dot1AD => 4,
200 Self::Dot1AH => 6,
201 Self::LLC => 3,
202 Self::SNAP => 5,
203 Self::Ssh => ssh::SSH_BINARY_HEADER_LEN,
204 Self::Tls => tls::TLS_RECORD_HEADER_LEN,
205 Self::Dot15d4 => 3, Self::Dot15d4Fcs => 5, Self::Dot11 => dot11::DOT11_MIN_HEADER_LEN,
208 Self::Http => 14, Self::Quic => quic::QUIC_MIN_HEADER_LEN,
210 Self::Generic => 0,
211 Self::Http2 => 9, Self::L2tp => l2tp::L2TP_MIN_HEADER_LEN,
213 Self::Mqtt => mqtt::MQTT_MIN_HEADER_LEN,
214 Self::MqttSn => mqttsn::MQTTSN_MIN_HEADER_LEN,
215 Self::Modbus => modbus::MODBUS_MIN_HEADER_LEN,
216 Self::ZWave => zwave::ZWAVE_MIN_HEADER_LEN,
217 Self::Ftp => ftp::FTP_MIN_HEADER_LEN,
218 Self::Tftp => tftp::TFTP_MIN_HEADER_LEN,
219 Self::Smtp => smtp::SMTP_MIN_HEADER_LEN,
220 Self::Pop3 => pop3::POP3_MIN_HEADER_LEN,
221 Self::Imap => imap::IMAP_MIN_HEADER_LEN,
222 Self::Raw => 0,
223 }
224 }
225
226 #[inline]
228 #[must_use]
229 pub const fn is_link_layer(&self) -> bool {
230 matches!(
231 self,
232 Self::Ethernet | Self::Dot3 | Self::Dot1Q | Self::Dot1AD | Self::Dot1AH
233 )
234 }
235
236 #[inline]
238 #[must_use]
239 pub const fn is_network_layer(&self) -> bool {
240 matches!(self, Self::Ipv4 | Self::Ipv6 | Self::Arp)
241 }
242
243 #[inline]
245 #[must_use]
246 pub const fn is_transport_layer(&self) -> bool {
247 matches!(self, Self::Tcp | Self::Udp | Self::Icmp | Self::Icmpv6)
248 }
249}
250
251impl std::fmt::Display for LayerKind {
252 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
253 write!(f, "{}", self.name())
254 }
255}
256
257#[derive(Debug, Clone, Copy, PartialEq, Eq)]
259pub struct LayerIndex {
260 pub kind: LayerKind,
261 pub start: usize,
262 pub end: usize,
263}
264
265impl LayerIndex {
266 #[inline]
267 #[must_use]
268 pub const fn new(kind: LayerKind, start: usize, end: usize) -> Self {
269 Self { kind, start, end }
270 }
271
272 #[inline]
273 #[must_use]
274 pub const fn range(&self) -> Range<usize> {
275 self.start..self.end
276 }
277
278 #[inline]
279 #[must_use]
280 pub const fn len(&self) -> usize {
281 self.end - self.start
282 }
283
284 #[inline]
285 #[must_use]
286 pub const fn is_empty(&self) -> bool {
287 self.start == self.end
288 }
289
290 #[inline]
292 #[must_use]
293 pub fn slice<'a>(&self, buf: &'a [u8]) -> &'a [u8] {
294 &buf[self.start..self.end.min(buf.len())]
295 }
296
297 #[inline]
299 pub fn slice_mut<'a>(&self, buf: &'a mut [u8]) -> &'a mut [u8] {
300 let end = self.end.min(buf.len());
301 &mut buf[self.start..end]
302 }
303
304 #[inline]
306 #[must_use]
307 pub fn payload<'a>(&self, buf: &'a [u8]) -> &'a [u8] {
308 &buf[self.end.min(buf.len())..]
309 }
310}
311
312pub trait Layer {
318 fn kind(&self) -> LayerKind;
320
321 fn summary(&self, data: &[u8]) -> String;
323
324 fn header_len(&self, data: &[u8]) -> usize;
326
327 fn hashret(&self, _data: &[u8]) -> Vec<u8> {
329 vec![]
330 }
331
332 fn answers(&self, _data: &[u8], _other: &Self, _other_data: &[u8]) -> bool {
334 false
335 }
336
337 fn extract_padding<'a>(&self, data: &'a [u8]) -> (&'a [u8], &'a [u8]) {
339 let header_len = self.header_len(data);
340 (&data[header_len..], &[])
341 }
342
343 fn field_names(&self) -> &'static [&'static str] {
345 &[]
346 }
347}
348
349#[derive(Debug, Clone)]
351pub enum LayerEnum {
352 Ethernet(EthernetLayer),
353 Dot3(Dot3Layer),
354 Arp(ArpLayer),
355 Ipv4(Ipv4Layer),
356 Ipv6(Ipv6Layer),
357 Icmp(IcmpLayer),
358 Icmpv6(Icmpv6Layer),
359 Tcp(TcpLayer),
360 Udp(UdpLayer),
361 Dns(DnsLayer),
362 Ssh(SshLayer),
363 Tls(TlsLayer),
364 Dot15d4(dot15d4::Dot15d4Layer),
365 Dot15d4Fcs(dot15d4::Dot15d4FcsLayer),
366 Dot11(dot11::Dot11Layer),
367 Http(http::HttpLayer),
368 Http2(http2::Http2Layer),
369 Quic(quic::QuicLayer),
370 L2tp(l2tp::L2tpLayer),
371 Mqtt(mqtt::MqttLayer),
372 MqttSn(mqttsn::MqttSnLayer),
373 Modbus(modbus::ModbusLayer),
374 ZWave(zwave::ZWaveLayer),
375 Ftp(ftp::FtpLayer),
376 Tftp(tftp::TftpLayer),
377 Smtp(smtp::SmtpLayer),
378 Pop3(pop3::Pop3Layer),
379 Imap(imap::ImapLayer),
380 Raw(RawLayer),
381}
382
383impl LayerEnum {
384 #[inline]
385 #[must_use]
386 pub fn kind(&self) -> LayerKind {
387 match self {
388 Self::Ethernet(_) => LayerKind::Ethernet,
389 Self::Dot3(_) => LayerKind::Dot3,
390 Self::Arp(_) => LayerKind::Arp,
391 Self::Ipv4(_) => LayerKind::Ipv4,
392 Self::Ipv6(_) => LayerKind::Ipv6,
393 Self::Icmp(_) => LayerKind::Icmp,
394 Self::Icmpv6(_) => LayerKind::Icmpv6,
395 Self::Tcp(_) => LayerKind::Tcp,
396 Self::Udp(_) => LayerKind::Udp,
397 Self::Dns(_) => LayerKind::Dns,
398 Self::Ssh(_) => LayerKind::Ssh,
399 Self::Tls(_) => LayerKind::Tls,
400 Self::Dot15d4(_) => LayerKind::Dot15d4,
401 Self::Dot15d4Fcs(_) => LayerKind::Dot15d4Fcs,
402 Self::Dot11(_) => LayerKind::Dot11,
403 Self::Http(_) => LayerKind::Http,
404 Self::Http2(_) => LayerKind::Http2,
405 Self::Quic(_) => LayerKind::Quic,
406 Self::L2tp(_) => LayerKind::L2tp,
407 Self::Mqtt(_) => LayerKind::Mqtt,
408 Self::MqttSn(_) => LayerKind::MqttSn,
409 Self::Modbus(_) => LayerKind::Modbus,
410 Self::ZWave(_) => LayerKind::ZWave,
411 Self::Ftp(_) => LayerKind::Ftp,
412 Self::Tftp(_) => LayerKind::Tftp,
413 Self::Smtp(_) => LayerKind::Smtp,
414 Self::Pop3(_) => LayerKind::Pop3,
415 Self::Imap(_) => LayerKind::Imap,
416 Self::Raw(_) => LayerKind::Raw,
417 }
418 }
419
420 #[inline]
421 #[must_use]
422 pub fn index(&self) -> &LayerIndex {
423 match self {
424 Self::Ethernet(l) => &l.index,
425 Self::Dot3(l) => &l.index,
426 Self::Arp(l) => &l.index,
427 Self::Ipv4(l) => &l.index,
428 Self::Ipv6(l) => &l.index,
429 Self::Icmp(l) => &l.index,
430 Self::Icmpv6(l) => &l.index,
431 Self::Tcp(l) => &l.index,
432 Self::Udp(l) => &l.index,
433 Self::Dns(l) => &l.index,
434 Self::Ssh(l) => &l.index,
435 Self::Tls(l) => &l.index,
436 Self::Dot15d4(l) => &l.index,
437 Self::Dot15d4Fcs(l) => &l.index,
438 Self::Dot11(l) => &l.index,
439 Self::Http(l) => &l.index,
440 Self::Http2(l) => &l.index,
441 Self::Quic(l) => &l.index,
442 Self::L2tp(l) => &l.index,
443 Self::Mqtt(l) => &l.index,
444 Self::MqttSn(l) => &l.index,
445 Self::Modbus(l) => &l.index,
446 Self::ZWave(l) => &l.index,
447 Self::Ftp(l) => &l.index,
448 Self::Tftp(l) => &l.index,
449 Self::Smtp(l) => &l.index,
450 Self::Pop3(l) => &l.index,
451 Self::Imap(l) => &l.index,
452 Self::Raw(l) => &l.index,
453 }
454 }
455
456 #[must_use]
457 pub fn summary(&self, buf: &[u8]) -> String {
458 match self {
459 Self::Ethernet(l) => l.summary(buf),
460 Self::Dot3(l) => l.summary(buf),
461 Self::Arp(l) => l.summary(buf),
462 Self::Ipv4(l) => l.summary(buf),
463 Self::Ipv6(l) => l.summary(buf),
464 Self::Icmp(l) => l.summary(buf),
465 Self::Icmpv6(l) => l.summary(buf),
466 Self::Tcp(l) => l.summary(buf),
467 Self::Udp(l) => l.summary(buf),
468 Self::Dns(l) => l.summary(buf),
469 Self::Ssh(l) => l.summary(buf),
470 Self::Tls(l) => l.summary(buf),
471 Self::Dot15d4(l) => l.summary(buf),
472 Self::Dot15d4Fcs(l) => l.summary(buf),
473 Self::Dot11(l) => l.summary(buf),
474 Self::Http(l) => l.summary(buf),
475 Self::Http2(l) => l.summary(buf),
476 Self::Quic(l) => l.summary(buf),
477 Self::L2tp(l) => l.summary(buf),
478 Self::Mqtt(l) => l.summary(buf),
479 Self::MqttSn(l) => l.summary(buf),
480 Self::Modbus(l) => l.summary(buf),
481 Self::ZWave(l) => l.summary(buf),
482 Self::Ftp(l) => l.summary(buf),
483 Self::Tftp(l) => l.summary(buf),
484 Self::Smtp(l) => l.summary(buf),
485 Self::Pop3(l) => l.summary(buf),
486 Self::Imap(l) => l.summary(buf),
487 Self::Raw(l) => l.summary(buf),
488 }
489 }
490
491 #[must_use]
492 pub fn hashret(&self, buf: &[u8]) -> Vec<u8> {
493 match self {
494 Self::Ethernet(l) => l.hashret(buf),
495 Self::Arp(l) => l.hashret(buf),
496 Self::Ipv4(l) => l.hashret(buf),
497 Self::Icmp(l) => l.hashret(buf),
498 Self::Tcp(l) => l.hashret(buf),
499 Self::Udp(l) => l.hashret(buf),
500 Self::Dot15d4(l) => l.hashret(buf),
501 Self::Dot15d4Fcs(l) => l.hashret(buf),
502 Self::Dot11(l) => l.hashret(buf),
503 _ => vec![],
504 }
505 }
506
507 #[must_use]
508 pub fn header_len(&self, buf: &[u8]) -> usize {
509 match self {
510 Self::Ethernet(l) => l.header_len(buf),
511 Self::Dot3(_) => ethernet::ETHERNET_HEADER_LEN,
512 Self::Arp(l) => l.header_len(buf),
513 Self::Ipv4(l) => l.header_len(buf),
514 Self::Ipv6(l) => l.header_len(buf),
515 Self::Icmp(l) => l.header_len(buf),
516 Self::Icmpv6(l) => l.header_len(buf),
517 Self::Tcp(l) => l.header_len(buf),
518 Self::Udp(l) => l.header_len(buf),
519 Self::Dns(l) => l.header_len(buf),
520 Self::Ssh(l) => l.header_len(buf),
521 Self::Tls(l) => l.header_len(buf),
522 Self::Dot15d4(l) => l.header_len(buf),
523 Self::Dot15d4Fcs(l) => l.header_len(buf),
524 Self::Dot11(l) => l.header_len(buf),
525 Self::Http(l) => l.header_len(buf),
526 Self::Http2(l) => l.header_len(buf),
527 Self::Quic(l) => l.header_len(buf),
528 Self::L2tp(l) => l.header_len(buf),
529 Self::Mqtt(l) => l.header_len(buf),
530 Self::MqttSn(l) => l.header_len(buf),
531 Self::Modbus(l) => l.header_len(buf),
532 Self::ZWave(l) => l.header_len(buf),
533 Self::Ftp(l) => l.header_len(buf),
534 Self::Tftp(l) => l.header_len(buf),
535 Self::Smtp(l) => l.header_len(buf),
536 Self::Pop3(l) => l.header_len(buf),
537 Self::Imap(l) => l.header_len(buf),
538 Self::Raw(l) => l.header_len(buf),
539 }
540 }
541
542 #[must_use]
545 pub fn show_fields(&self, buf: &[u8]) -> Vec<(&'static str, String)> {
546 match self {
547 Self::Ethernet(l) => ethernet_show_fields(l, buf),
548 Self::Dot3(l) => dot3_show_fields(l, buf),
549 Self::Arp(l) => arp_show_fields(l, buf),
550 Self::Ipv4(l) => ipv4_show_fields(l, buf),
551 Self::Ipv6(l) => ipv6_show_fields(l, buf),
552 Self::Icmp(l) => icmp_show_fields(l, buf),
553 Self::Icmpv6(l) => icmpv6_show_fields(l, buf),
554 Self::Tcp(l) => tcp_show_fields(l, buf),
555 Self::Udp(l) => udp_show_fields(l, buf),
556 Self::Dns(l) => dns_show_fields(l, buf),
557 Self::Ssh(l) => ssh_show_fields(l, buf),
558 Self::Tls(l) => tls_show_fields(l, buf),
559 Self::Dot15d4(l) => dot15d4_show_fields(l, buf),
560 Self::Dot15d4Fcs(l) => dot15d4_fcs_show_fields(l, buf),
561 Self::Dot11(l) => dot11_show_fields(l, buf),
562 Self::Http(l) => http_show_fields(l, buf),
563 Self::Http2(l) => http2_show_fields(l, buf),
564 Self::Quic(l) => quic_show_fields(l, buf),
565 Self::L2tp(l) => l2tp_show_fields(l, buf),
566 Self::Mqtt(l) => mqtt_show_fields(l, buf),
567 Self::MqttSn(l) => mqttsn_show_fields(l, buf),
568 Self::Modbus(l) => modbus_show_fields(l, buf),
569 Self::ZWave(l) => zwave_show_fields(l, buf),
570 Self::Ftp(l) => ftp::ftp_show_fields(l, buf),
571 Self::Tftp(l) => tftp::tftp_show_fields(l, buf),
572 Self::Smtp(l) => smtp::smtp_show_fields(l, buf),
573 Self::Pop3(l) => pop3::pop3_show_fields(l, buf),
574 Self::Imap(l) => imap::imap_show_fields(l, buf),
575 Self::Raw(l) => raw::raw_show_fields(l, buf),
576 }
577 }
578
579 #[must_use]
582 pub fn get_field(&self, buf: &[u8], name: &str) -> Option<Result<FieldValue, FieldError>> {
583 match self {
584 Self::Ethernet(l) => l.get_field(buf, name),
585 Self::Dot3(l) => l.get_field(buf, name),
586 Self::Arp(l) => l.get_field(buf, name),
587 Self::Ipv4(l) => l.get_field(buf, name),
588 Self::Icmp(l) => l.get_field(buf, name),
589 Self::Tcp(l) => l.get_field(buf, name),
590 Self::Udp(l) => l.get_field(buf, name),
591 Self::Raw(l) => l.get_field(buf, name),
592 Self::Ssh(l) => l.get_field(buf, name),
593 Self::Tls(l) => l.get_field(buf, name),
594 Self::Dns(l) => l.get_field(buf, name),
595 Self::Dot15d4(l) => l.get_field(buf, name),
596 Self::Dot15d4Fcs(l) => l.get_field(buf, name),
597 Self::Dot11(l) => l.get_field(buf, name),
598 Self::Http(l) => l.get_field(buf, name),
599 Self::Http2(l) => l.get_field(buf, name),
600 Self::Quic(l) => l.get_field(buf, name),
601 Self::Ipv6(l) => l.get_field(buf, name),
602 Self::Icmpv6(l) => l.get_field(buf, name),
603 Self::L2tp(l) => l.get_field(buf, name),
604 Self::Mqtt(l) => l.get_field(buf, name),
605 Self::MqttSn(l) => l.get_field(buf, name),
606 Self::Modbus(l) => l.get_field(buf, name),
607 Self::ZWave(l) => l.get_field(buf, name),
608 Self::Ftp(l) => l.get_field(buf, name),
609 Self::Tftp(l) => l.get_field(buf, name),
610 Self::Smtp(l) => l.get_field(buf, name),
611 Self::Pop3(l) => l.get_field(buf, name),
612 Self::Imap(l) => l.get_field(buf, name),
613 }
614 }
615
616 pub fn set_field(
619 &self,
620 buf: &mut [u8],
621 name: &str,
622 value: FieldValue,
623 ) -> Option<Result<(), FieldError>> {
624 match self {
625 Self::Ethernet(l) => l.set_field(buf, name, value),
626 Self::Dot3(l) => l.set_field(buf, name, value),
627 Self::Arp(l) => l.set_field(buf, name, value),
628 Self::Ipv4(l) => l.set_field(buf, name, value),
629 Self::Icmp(l) => l.set_field(buf, name, value),
630 Self::Tcp(l) => l.set_field(buf, name, value),
631 Self::Udp(l) => l.set_field(buf, name, value),
632 Self::Raw(l) => l.set_field(buf, name, value),
633 Self::Ssh(l) => l.set_field(buf, name, value),
634 Self::Tls(l) => l.set_field(buf, name, value),
635 Self::Dns(l) => l.set_field(buf, name, value),
636 Self::Dot15d4(l) => l.set_field(buf, name, value),
637 Self::Dot15d4Fcs(l) => l.set_field(buf, name, value),
638 Self::Dot11(l) => l.set_field(buf, name, value),
639 Self::Http(_) => None, Self::Http2(_) => None, Self::Quic(l) => l.set_field(buf, name, value),
642 Self::Ipv6(l) => l.set_field(buf, name, value),
643 Self::Icmpv6(l) => l.set_field(buf, name, value),
644 Self::L2tp(l) => l.set_field(buf, name, value),
645 Self::Mqtt(l) => l.set_field(buf, name, value),
646 Self::MqttSn(l) => l.set_field(buf, name, value),
647 Self::Modbus(l) => l.set_field(buf, name, value),
648 Self::ZWave(l) => l.set_field(buf, name, value),
649 Self::Ftp(_) => None, Self::Tftp(_) => None, Self::Smtp(_) => None, Self::Pop3(_) => None, Self::Imap(_) => None, }
655 }
656
657 #[must_use]
659 pub fn field_names(&self) -> &'static [&'static str] {
660 match self {
661 Self::Ethernet(l) => l.field_names(),
662 Self::Dot3(_) => Dot3Layer::field_names(),
663 Self::Arp(l) => l.field_names(),
664 Self::Ipv4(l) => l.field_names(),
665 Self::Icmp(l) => l.field_names(),
666 Self::Tcp(l) => l.field_names(),
667 Self::Udp(l) => l.field_names(),
668 Self::Raw(_) => RawLayer::field_names(),
669 Self::Ssh(l) => l.field_names(),
670 Self::Tls(l) => l.field_names(),
671 Self::Dns(_) => DnsLayer::field_names(),
672 Self::Dot15d4(_) => dot15d4::Dot15d4Layer::field_names(),
673 Self::Dot15d4Fcs(_) => dot15d4::Dot15d4FcsLayer::field_names(),
674 Self::Dot11(_) => dot11::Dot11Layer::field_names(),
675 Self::Http(l) => l.field_names(),
676 Self::Http2(_) => Http2Layer::field_names(),
677 Self::Quic(_) => quic::QuicLayer::field_names(),
678 Self::Ipv6(_) => Ipv6Layer::field_names(),
679 Self::Icmpv6(_) => Icmpv6Layer::field_names(),
680 Self::L2tp(_) => l2tp::L2tpLayer::field_names(),
681 Self::Mqtt(_) => mqtt::MqttLayer::field_names(),
682 Self::MqttSn(_) => mqttsn::MqttSnLayer::field_names(),
683 Self::Modbus(_) => modbus::ModbusLayer::field_names(),
684 Self::ZWave(_) => zwave::ZWaveLayer::field_names(),
685 Self::Ftp(l) => l.field_names(),
686 Self::Tftp(l) => l.field_names(),
687 Self::Smtp(l) => l.field_names(),
688 Self::Pop3(l) => l.field_names(),
689 Self::Imap(l) => l.field_names(),
690 }
691 }
692}
693
694fn ethernet_show_fields(l: &EthernetLayer, buf: &[u8]) -> Vec<(&'static str, String)> {
699 let mut fields = Vec::new();
700 fields.push((
701 "dst",
702 l.dst(buf).map_or_else(|_| "?".into(), |m| m.to_string()),
703 ));
704 fields.push((
705 "src",
706 l.src(buf).map_or_else(|_| "?".into(), |m| m.to_string()),
707 ));
708 let etype = l.ethertype(buf).unwrap_or(0);
709 fields.push((
710 "type",
711 format!("{:#06x} ({})", etype, ethertype::name(etype)),
712 ));
713 fields
714}
715
716fn dot3_show_fields(l: &Dot3Layer, buf: &[u8]) -> Vec<(&'static str, String)> {
717 let mut fields = Vec::new();
718 fields.push((
719 "dst",
720 l.dst(buf).map_or_else(|_| "?".into(), |m| m.to_string()),
721 ));
722 fields.push((
723 "src",
724 l.src(buf).map_or_else(|_| "?".into(), |m| m.to_string()),
725 ));
726 fields.push((
727 "len",
728 l.len_field(buf)
729 .map_or_else(|_| "?".into(), |v| v.to_string()),
730 ));
731 fields
732}
733
734fn arp_show_fields(l: &ArpLayer, buf: &[u8]) -> Vec<(&'static str, String)> {
735 let mut fields = Vec::new();
736 let hwtype = l.hwtype(buf).unwrap_or(0);
737 fields.push((
738 "hwtype",
739 format!("{:#06x} ({})", hwtype, arp::hardware_type::name(hwtype)),
740 ));
741 let ptype = l.ptype(buf).unwrap_or(0);
742 fields.push(("ptype", format!("{ptype:#06x}")));
743 fields.push((
744 "hwlen",
745 l.hwlen(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
746 ));
747 fields.push((
748 "plen",
749 l.plen(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
750 ));
751 let op = l.op(buf).unwrap_or(0);
752 fields.push(("op", format!("{} ({})", op, arp::opcode::name(op))));
753 fields.push((
754 "hwsrc",
755 l.hwsrc_raw(buf)
756 .map_or_else(|_| "?".into(), |a| a.to_string()),
757 ));
758 fields.push((
759 "psrc",
760 l.psrc_raw(buf)
761 .map_or_else(|_| "?".into(), |a| a.to_string()),
762 ));
763 fields.push((
764 "hwdst",
765 l.hwdst_raw(buf)
766 .map_or_else(|_| "?".into(), |a| a.to_string()),
767 ));
768 fields.push((
769 "pdst",
770 l.pdst_raw(buf)
771 .map_or_else(|_| "?".into(), |a| a.to_string()),
772 ));
773 fields
774}
775
776fn ipv4_show_fields(l: &Ipv4Layer, buf: &[u8]) -> Vec<(&'static str, String)> {
777 let mut fields = Vec::new();
778 fields.push((
779 "version",
780 l.version(buf)
781 .map_or_else(|_| "?".into(), |v| v.to_string()),
782 ));
783 fields.push((
784 "ihl",
785 l.ihl(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
786 ));
787 fields.push((
788 "tos",
789 l.tos(buf)
790 .map_or_else(|_| "?".into(), |v| format!("{v:#04x}")),
791 ));
792 fields.push((
793 "len",
794 l.total_len(buf)
795 .map_or_else(|_| "?".into(), |v| v.to_string()),
796 ));
797 fields.push((
798 "id",
799 l.id(buf)
800 .map_or_else(|_| "?".into(), |v| format!("{v:#06x}")),
801 ));
802 fields.push((
803 "flags",
804 l.flags(buf).map_or_else(|_| "?".into(), |f| f.to_string()),
805 ));
806 fields.push((
807 "frag",
808 l.frag_offset(buf)
809 .map_or_else(|_| "?".into(), |v| v.to_string()),
810 ));
811 fields.push((
812 "ttl",
813 l.ttl(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
814 ));
815 let proto = l.protocol(buf).unwrap_or(0);
816 fields.push(("proto", format!("{} ({})", proto, l.protocol_name(buf))));
817 fields.push((
818 "chksum",
819 l.checksum(buf)
820 .map_or_else(|_| "?".into(), |v| format!("{v:#06x}")),
821 ));
822 fields.push((
823 "src",
824 l.src(buf).map_or_else(|_| "?".into(), |ip| ip.to_string()),
825 ));
826 fields.push((
827 "dst",
828 l.dst(buf).map_or_else(|_| "?".into(), |ip| ip.to_string()),
829 ));
830 let opts_len = l.options_len(buf);
832 if opts_len > 0 {
833 fields.push(("options", format!("[{opts_len} bytes]")));
834 }
835 fields
836}
837
838fn ipv6_show_fields(l: &Ipv6Layer, buf: &[u8]) -> Vec<(&'static str, String)> {
839 let mut fields = Vec::new();
840 fields.push((
841 "version",
842 l.version(buf)
843 .map_or_else(|_| "?".into(), |v| v.to_string()),
844 ));
845 fields.push((
846 "tc",
847 l.traffic_class(buf)
848 .map_or_else(|_| "?".into(), |v| format!("{v:#04x}")),
849 ));
850 fields.push((
851 "fl",
852 l.flow_label(buf)
853 .map_or_else(|_| "?".into(), |v| format!("{v:#07x}")),
854 ));
855 fields.push((
856 "plen",
857 l.payload_len(buf)
858 .map_or_else(|_| "?".into(), |v| v.to_string()),
859 ));
860 let nh = l.next_header(buf).unwrap_or(0);
861 fields.push(("nh", format!("{} ({})", nh, ipv4::protocol::to_name(nh))));
862 fields.push((
863 "hlim",
864 l.hop_limit(buf)
865 .map_or_else(|_| "?".into(), |v| v.to_string()),
866 ));
867 fields.push((
868 "src",
869 l.src(buf).map_or_else(|_| "?".into(), |a| a.to_string()),
870 ));
871 fields.push((
872 "dst",
873 l.dst(buf).map_or_else(|_| "?".into(), |a| a.to_string()),
874 ));
875 fields
876}
877
878fn icmp_show_fields(l: &IcmpLayer, buf: &[u8]) -> Vec<(&'static str, String)> {
879 let mut fields = Vec::new();
880
881 fields.push((
883 "type",
884 l.icmp_type(buf).map_or_else(
885 |_| "?".into(),
886 |t: u8| format!("{} ({})", t, icmp::type_name(t)),
887 ),
888 ));
889
890 fields.push((
892 "code",
893 l.code(buf)
894 .map_or_else(|_| "?".into(), |c: u8| c.to_string()),
895 ));
896
897 fields.push((
899 "chksum",
900 l.checksum(buf)
901 .map_or_else(|_| "?".into(), |v: u16| format!("{v:#06x}")),
902 ));
903
904 if let Ok(Some(id)) = l.id(buf) {
906 fields.push(("id", format!("{id:#06x}")));
907 }
908
909 if let Ok(Some(seq)) = l.seq(buf) {
911 fields.push(("seq", seq.to_string()));
912 }
913
914 if let Ok(Some(gateway)) = l.gateway(buf) {
916 fields.push(("gw", gateway.to_string()));
917 }
918
919 if let Ok(Some(ptr)) = l.ptr(buf) {
921 fields.push(("ptr", ptr.to_string()));
922 }
923
924 if let Ok(Some(mtu)) = l.next_hop_mtu(buf) {
926 fields.push(("mtu", mtu.to_string()));
927 }
928
929 if let Ok(Some(ts_ori)) = l.ts_ori(buf) {
931 fields.push(("ts_ori", ts_ori.to_string()));
932 }
933 if let Ok(Some(ts_rx)) = l.ts_rx(buf) {
934 fields.push(("ts_rx", ts_rx.to_string()));
935 }
936 if let Ok(Some(ts_tx)) = l.ts_tx(buf) {
937 fields.push(("ts_tx", ts_tx.to_string()));
938 }
939
940 if let Ok(Some(addr_mask)) = l.addr_mask(buf) {
942 fields.push(("addr_mask", addr_mask.to_string()));
943 }
944
945 fields
946}
947
948fn icmpv6_show_fields(l: &Icmpv6Layer, buf: &[u8]) -> Vec<(&'static str, String)> {
949 let mut fields = Vec::new();
950 let icmpv6_type = l.icmpv6_type(buf).unwrap_or(0);
951 let type_name = icmpv6::types::name(icmpv6_type);
952 fields.push(("type", format!("{icmpv6_type} ({type_name})")));
953 fields.push((
954 "code",
955 l.code(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
956 ));
957 fields.push((
958 "chksum",
959 l.checksum(buf)
960 .map_or_else(|_| "?".into(), |v| format!("{v:#06x}")),
961 ));
962 if let Ok(Some(id)) = l.id(buf) {
963 fields.push(("id", format!("{id:#06x}")));
964 }
965 if let Ok(Some(seq)) = l.seq(buf) {
966 fields.push(("seq", seq.to_string()));
967 }
968 if let Ok(Some(target)) = l.target_addr(buf) {
969 fields.push(("tgt", target.to_string()));
970 }
971 if let Ok(Some(mtu)) = l.mtu(buf) {
972 fields.push(("mtu", mtu.to_string()));
973 }
974 fields
975}
976
977fn tcp_show_fields(l: &TcpLayer, buf: &[u8]) -> Vec<(&'static str, String)> {
978 let mut fields = Vec::new();
979 fields.push((
980 "sport",
981 l.src_port(buf)
982 .map_or_else(|_| "?".into(), |v| v.to_string()),
983 ));
984 fields.push((
985 "dport",
986 l.dst_port(buf)
987 .map_or_else(|_| "?".into(), |v| v.to_string()),
988 ));
989 fields.push((
990 "seq",
991 l.seq(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
992 ));
993 fields.push((
994 "ack",
995 l.ack(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
996 ));
997 fields.push((
998 "dataofs",
999 l.data_offset(buf)
1000 .map_or_else(|_| "?".into(), |v| v.to_string()),
1001 ));
1002 fields.push((
1003 "reserved",
1004 l.reserved(buf)
1005 .map_or_else(|_| "?".into(), |v| v.to_string()),
1006 ));
1007 fields.push((
1008 "flags",
1009 l.flags(buf).map_or_else(|_| "?".into(), |f| f.to_string()),
1010 ));
1011 fields.push((
1012 "window",
1013 l.window(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
1014 ));
1015 fields.push((
1016 "chksum",
1017 l.checksum(buf)
1018 .map_or_else(|_| "?".into(), |v| format!("{v:#06x}")),
1019 ));
1020 fields.push((
1021 "urgptr",
1022 l.urgent_ptr(buf)
1023 .map_or_else(|_| "?".into(), |v| v.to_string()),
1024 ));
1025 let opts_len = l.options_len(buf);
1027 if opts_len > 0 {
1028 fields.push(("options", format!("[{opts_len} bytes]")));
1029 }
1030 fields
1031}
1032
1033fn udp_show_fields(l: &UdpLayer, buf: &[u8]) -> Vec<(&'static str, String)> {
1034 let mut fields = Vec::new();
1035 fields.push((
1036 "sport",
1037 l.src_port(buf)
1038 .map_or_else(|_| "?".into(), |v: u16| v.to_string()),
1039 ));
1040 fields.push((
1041 "dport",
1042 l.dst_port(buf)
1043 .map_or_else(|_| "?".into(), |v: u16| v.to_string()),
1044 ));
1045 fields.push((
1046 "len",
1047 l.length(buf)
1048 .map_or_else(|_| "?".into(), |v: u16| v.to_string()),
1049 ));
1050 fields.push((
1051 "chksum",
1052 l.checksum(buf)
1053 .map_or_else(|_| "?".into(), |v: u16| format!("{v:#06x}")),
1054 ));
1055 fields
1056}
1057
1058fn dns_show_fields(l: &DnsLayer, buf: &[u8]) -> Vec<(&'static str, String)> {
1059 let mut fields = Vec::new();
1060 fields.push((
1061 "id",
1062 l.id(buf)
1063 .map_or_else(|_| "?".into(), |v| format!("{v:#06x}")),
1064 ));
1065 let qr = l.qr(buf).unwrap_or(false);
1066 fields.push(("qr", if qr { "response" } else { "query" }.to_string()));
1067 fields.push((
1068 "opcode",
1069 l.opcode(buf).map_or_else(
1070 |_| "?".into(),
1071 |v| format!("{} ({})", v, dns::types::opcode_name(v)),
1072 ),
1073 ));
1074 fields.push((
1075 "aa",
1076 l.aa(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
1077 ));
1078 fields.push((
1079 "tc",
1080 l.tc(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
1081 ));
1082 fields.push((
1083 "rd",
1084 l.rd(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
1085 ));
1086 fields.push((
1087 "ra",
1088 l.ra(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
1089 ));
1090 fields.push(("z", l.z(buf).map_or_else(|_| "?".into(), |v| v.to_string())));
1091 fields.push((
1092 "ad",
1093 l.ad(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
1094 ));
1095 fields.push((
1096 "cd",
1097 l.cd(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
1098 ));
1099 fields.push((
1100 "rcode",
1101 l.rcode(buf).map_or_else(
1102 |_| "?".into(),
1103 |v| format!("{} ({})", v, dns::types::rcode_name(v)),
1104 ),
1105 ));
1106 fields.push((
1107 "qdcount",
1108 l.qdcount(buf)
1109 .map_or_else(|_| "?".into(), |v| v.to_string()),
1110 ));
1111 fields.push((
1112 "ancount",
1113 l.ancount(buf)
1114 .map_or_else(|_| "?".into(), |v| v.to_string()),
1115 ));
1116 fields.push((
1117 "nscount",
1118 l.nscount(buf)
1119 .map_or_else(|_| "?".into(), |v| v.to_string()),
1120 ));
1121 fields.push((
1122 "arcount",
1123 l.arcount(buf)
1124 .map_or_else(|_| "?".into(), |v| v.to_string()),
1125 ));
1126 if let Ok(questions) = l.questions(buf) {
1128 for (i, q) in questions.iter().enumerate() {
1129 fields.push(("qd", format!("[{}] {}", i, q.summary())));
1130 }
1131 }
1132 fields
1133}
1134
1135fn ssh_show_fields(l: &SshLayer, buf: &[u8]) -> Vec<(&'static str, String)> {
1136 let mut fields = Vec::new();
1137 if l.is_version_exchange(buf) {
1138 if let Some(vs) = l.version_string(buf) {
1139 fields.push(("version_string", vs.to_string()));
1140 }
1141 } else {
1142 fields.push((
1143 "packet_length",
1144 l.packet_length(buf)
1145 .map_or_else(|_| "?".into(), |v| v.to_string()),
1146 ));
1147 fields.push((
1148 "padding_length",
1149 l.padding_length(buf)
1150 .map_or_else(|_| "?".into(), |v| v.to_string()),
1151 ));
1152 match l.message_type(buf) {
1153 Ok(Some(t)) => {
1154 fields.push((
1155 "message_type",
1156 format!("{} ({})", t, ssh::msg_types::name(t)),
1157 ));
1158 },
1159 Ok(None) => {},
1160 Err(_) => {
1161 fields.push(("message_type", "?".into()));
1162 },
1163 }
1164 }
1165 fields
1166}
1167
1168fn tls_show_fields(l: &TlsLayer, buf: &[u8]) -> Vec<(&'static str, String)> {
1169 let mut fields = Vec::new();
1170 fields.push((
1171 "type",
1172 l.content_type(buf).map_or_else(
1173 |_| "?".into(),
1174 |ct| format!("{} ({})", ct.as_u8(), ct.name()),
1175 ),
1176 ));
1177 fields.push((
1178 "version",
1179 l.version(buf)
1180 .map(|v| {
1181 let ver = TlsVersion(v);
1182 format!("{:#06x} ({})", v, ver.name())
1183 })
1184 .unwrap_or_else(|_| "?".into()),
1185 ));
1186 fields.push((
1187 "len",
1188 l.length(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
1189 ));
1190 let frag = l.fragment(buf);
1191 if !frag.is_empty() {
1192 if frag.len() <= 16 {
1193 fields.push(("fragment", format!("[{} bytes] {:02x?}", frag.len(), frag)));
1194 } else {
1195 fields.push(("fragment", format!("[{} bytes]", frag.len())));
1196 }
1197 }
1198 fields
1199}
1200
1201fn dot11_show_fields(l: &dot11::Dot11Layer, buf: &[u8]) -> Vec<(&'static str, String)> {
1202 let mut fields = Vec::new();
1203 fields.push((
1204 "type",
1205 l.frame_type(buf).map_or_else(
1206 |_| "?".into(),
1207 |v| format!("{} ({})", v, dot11::types::frame_type::name(v)),
1208 ),
1209 ));
1210 fields.push((
1211 "subtype",
1212 l.subtype(buf)
1213 .map(|v| {
1214 let ft = l.frame_type(buf).unwrap_or(0);
1215 format!("{} ({})", v, dot11::types::subtype_name(ft, v))
1216 })
1217 .unwrap_or_else(|_| "?".into()),
1218 ));
1219 fields.push((
1220 "proto",
1221 l.protocol_version(buf)
1222 .map_or_else(|_| "?".into(), |v| v.to_string()),
1223 ));
1224 fields.push((
1225 "FCfield",
1226 l.flags(buf)
1227 .map_or_else(|_| "?".into(), |v| format!("{v:#04x}")),
1228 ));
1229 fields.push((
1230 "ID",
1231 l.duration(buf)
1232 .map_or_else(|_| "?".into(), |v| v.to_string()),
1233 ));
1234 fields.push((
1235 "addr1",
1236 l.addr1(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
1237 ));
1238 fields.push((
1239 "addr2",
1240 l.addr2(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
1241 ));
1242 fields.push((
1243 "addr3",
1244 l.addr3(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
1245 ));
1246 fields.push((
1247 "SC",
1248 l.seq_ctrl_raw(buf)
1249 .map_or_else(|_| "?".into(), |v| format!("{v:#06x}")),
1250 ));
1251 if l.has_addr4(buf) {
1252 fields.push((
1253 "addr4",
1254 l.addr4(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
1255 ));
1256 }
1257 fields
1258}
1259
1260fn dot15d4_show_fields(l: &dot15d4::Dot15d4Layer, buf: &[u8]) -> Vec<(&'static str, String)> {
1261 let mut fields = Vec::new();
1262 let ft = l.fcf_frametype(buf).unwrap_or(0);
1264 fields.push((
1265 "fcf_frametype",
1266 format!("{} ({})", ft, dot15d4::types::frame_type_name(ft)),
1267 ));
1268 fields.push((
1270 "fcf_security",
1271 l.fcf_security(buf)
1272 .map_or_else(|_| "?".into(), |v| v.to_string()),
1273 ));
1274 fields.push((
1275 "fcf_pending",
1276 l.fcf_pending(buf)
1277 .map_or_else(|_| "?".into(), |v| v.to_string()),
1278 ));
1279 fields.push((
1280 "fcf_ackreq",
1281 l.fcf_ackreq(buf)
1282 .map_or_else(|_| "?".into(), |v| v.to_string()),
1283 ));
1284 fields.push((
1285 "fcf_panidcompress",
1286 l.fcf_panidcompress(buf)
1287 .map_or_else(|_| "?".into(), |v| v.to_string()),
1288 ));
1289 let dam = l.fcf_destaddrmode(buf).unwrap_or(0);
1291 fields.push((
1292 "fcf_destaddrmode",
1293 format!("{} ({})", dam, dot15d4::types::addr_mode_name(dam)),
1294 ));
1295 fields.push((
1296 "fcf_framever",
1297 l.fcf_framever(buf)
1298 .map_or_else(|_| "?".into(), |v| v.to_string()),
1299 ));
1300 let sam = l.fcf_srcaddrmode(buf).unwrap_or(0);
1301 fields.push((
1302 "fcf_srcaddrmode",
1303 format!("{} ({})", sam, dot15d4::types::addr_mode_name(sam)),
1304 ));
1305 fields.push((
1307 "seqnum",
1308 l.seqnum(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
1309 ));
1310 if let Ok(Some(panid)) = l.dest_panid(buf) {
1312 fields.push(("dest_panid", format!("{panid:#06x}")));
1313 }
1314 if let Ok(Some(addr)) = l.dest_addr_short(buf) {
1315 fields.push(("dest_addr", format!("{addr:#06x}")));
1316 }
1317 if let Ok(Some(addr)) = l.dest_addr_long(buf) {
1318 fields.push(("dest_addr", format!("{addr:#018x}")));
1319 }
1320 if let Ok(Some(panid)) = l.src_panid(buf) {
1321 fields.push(("src_panid", format!("{panid:#06x}")));
1322 }
1323 if let Ok(Some(addr)) = l.src_addr_short(buf) {
1324 fields.push(("src_addr", format!("{addr:#06x}")));
1325 }
1326 if let Ok(Some(addr)) = l.src_addr_long(buf) {
1327 fields.push(("src_addr", format!("{addr:#018x}")));
1328 }
1329 fields
1330}
1331
1332fn dot15d4_fcs_show_fields(
1333 l: &dot15d4::Dot15d4FcsLayer,
1334 buf: &[u8],
1335) -> Vec<(&'static str, String)> {
1336 let inner = dot15d4::Dot15d4Layer::new(l.index.start, l.index.end.saturating_sub(2));
1337 let mut fields = dot15d4_show_fields(&inner, buf);
1338 let slice = l.index.slice(buf);
1340 if slice.len() >= 2 {
1341 let fcs_bytes = &slice[slice.len() - 2..];
1342 let fcs = u16::from_le_bytes([fcs_bytes[0], fcs_bytes[1]]);
1343 let verified = l.verify_fcs(buf).unwrap_or(false);
1344 let status = if verified { "ok" } else { "INVALID" };
1345 fields.push(("fcs", format!("{fcs:#06x} ({status})")));
1346 }
1347 fields
1348}
1349
1350fn http_show_fields(l: &http::HttpLayer, buf: &[u8]) -> Vec<(&'static str, String)> {
1351 let mut fields = Vec::new();
1352 if l.is_request(buf) {
1353 fields.push(("method", l.method(buf).unwrap_or("?").to_string()));
1354 fields.push(("uri", l.uri(buf).unwrap_or("?").to_string()));
1355 fields.push(("version", l.http_version(buf).unwrap_or("?").to_string()));
1356 } else if l.is_response(buf) {
1357 fields.push(("version", l.http_version(buf).unwrap_or("?").to_string()));
1358 fields.push((
1359 "status_code",
1360 l.status_code(buf)
1361 .map_or_else(|| "?".into(), |c| c.to_string()),
1362 ));
1363 fields.push(("reason", l.reason(buf).unwrap_or("?").to_string()));
1364 }
1365 fields
1366}
1367
1368fn http2_show_fields(l: &http2::Http2Layer, buf: &[u8]) -> Vec<(&'static str, String)> {
1369 let mut fields = Vec::new();
1370 if l.has_preface {
1371 fields.push(("preface", "true".to_string()));
1372 }
1373 if let Some(frame) = l.first_frame(buf) {
1374 fields.push((
1375 "frame_type",
1376 format!("{} ({})", frame.frame_type.as_u8(), frame.frame_type.name()),
1377 ));
1378 fields.push(("flags", format!("{:#04x}", frame.flags)));
1379 fields.push(("stream_id", frame.stream_id.to_string()));
1380 fields.push(("length", frame.length.to_string()));
1381 }
1382 fields
1383}
1384
1385fn quic_show_fields(l: &quic::QuicLayer, buf: &[u8]) -> Vec<(&'static str, String)> {
1386 let mut fields = Vec::new();
1387 fields.push((
1388 "header_form",
1389 if l.is_long_header(buf) {
1390 "long".to_string()
1391 } else {
1392 "short".to_string()
1393 },
1394 ));
1395 if let Some(pt) = l.packet_type(buf) {
1396 fields.push(("packet_type", pt.name().to_string()));
1397 }
1398 if let Some(ver) = l.version(buf) {
1399 fields.push(("version", format!("{ver:#010x}")));
1400 }
1401 fields
1402}
1403
1404fn l2tp_show_fields(l: &l2tp::L2tpLayer, buf: &[u8]) -> Vec<(&'static str, String)> {
1405 let mut fields = Vec::new();
1406 fields.push((
1407 "flags",
1408 l.flags_word(buf)
1409 .map_or_else(|_| "?".into(), |v| format!("{v:#06x}")),
1410 ));
1411 fields.push((
1412 "version",
1413 l.version(buf)
1414 .map_or_else(|_| "?".into(), |v| v.to_string()),
1415 ));
1416 fields.push((
1417 "msg_type",
1418 l.msg_type(buf)
1419 .map(|v| {
1420 if v == 0 {
1421 "data".to_string()
1422 } else {
1423 "control".to_string()
1424 }
1425 })
1426 .unwrap_or_else(|_| "?".into()),
1427 ));
1428 if let Ok(Some(length)) = l.length(buf) {
1429 fields.push(("length", length.to_string()));
1430 }
1431 fields.push((
1432 "tunnel_id",
1433 l.tunnel_id(buf)
1434 .map_or_else(|_| "?".into(), |v| v.to_string()),
1435 ));
1436 fields.push((
1437 "session_id",
1438 l.session_id(buf)
1439 .map_or_else(|_| "?".into(), |v| v.to_string()),
1440 ));
1441 if let Ok(Some(ns)) = l.ns(buf) {
1442 fields.push(("ns", ns.to_string()));
1443 }
1444 if let Ok(Some(nr)) = l.nr(buf) {
1445 fields.push(("nr", nr.to_string()));
1446 }
1447 fields
1448}
1449
1450fn mqtt_show_fields(l: &mqtt::MqttLayer, buf: &[u8]) -> Vec<(&'static str, String)> {
1451 let mut fields = Vec::new();
1452 fields.push((
1453 "msg_type",
1454 l.msg_type(buf).map_or_else(
1455 |_| "?".into(),
1456 |v| format!("{} ({})", v, mqtt::message_type_name(v)),
1457 ),
1458 ));
1459 fields.push((
1460 "dup",
1461 l.dup(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
1462 ));
1463 fields.push((
1464 "qos",
1465 l.qos(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
1466 ));
1467 fields.push((
1468 "retain",
1469 l.retain(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
1470 ));
1471 fields.push((
1472 "remaining_length",
1473 l.remaining_length(buf)
1474 .map_or_else(|_| "?".into(), |v| v.to_string()),
1475 ));
1476 if let Ok(mt) = l.msg_type(buf) {
1477 if mt == mqtt::PUBLISH {
1478 if let Ok(topic) = l.topic(buf) {
1479 fields.push(("topic", topic));
1480 }
1481 } else if mt == mqtt::CONNECT {
1482 if let Ok(name) = l.proto_name(buf) {
1483 fields.push(("proto_name", name));
1484 }
1485 if let Ok(level) = l.proto_level(buf) {
1486 fields.push(("proto_level", level.to_string()));
1487 }
1488 if let Ok(klive) = l.klive(buf) {
1489 fields.push(("klive", klive.to_string()));
1490 }
1491 if let Ok(cid) = l.client_id(buf) {
1492 fields.push(("client_id", cid));
1493 }
1494 } else if mt == mqtt::CONNACK
1495 && let Ok(rc) = l.retcode(buf)
1496 {
1497 fields.push(("retcode", rc.to_string()));
1498 }
1499 }
1500 fields
1501}
1502
1503fn mqttsn_show_fields(l: &mqttsn::MqttSnLayer, buf: &[u8]) -> Vec<(&'static str, String)> {
1504 let mut fields = Vec::new();
1505 fields.push((
1506 "length",
1507 l.packet_length(buf)
1508 .map_or_else(|_| "?".into(), |v| v.to_string()),
1509 ));
1510 let mt = l.msg_type(buf).unwrap_or(0xFF);
1511 fields.push((
1512 "type",
1513 format!("{} ({})", mt, mqttsn::message_type_name(mt)),
1514 ));
1515 if let Ok(v) = l.gw_id(buf) {
1516 fields.push(("gw_id", format!("{v:#04x}")));
1517 }
1518 if let Ok(v) = l.duration(buf) {
1519 fields.push(("duration", v.to_string()));
1520 }
1521 if let Ok(v) = l.return_code(buf) {
1522 fields.push(("return_code", v.to_string()));
1523 }
1524 if let Ok(v) = l.tid(buf) {
1525 fields.push(("tid", format!("{v:#06x}")));
1526 }
1527 if let Ok(v) = l.mid(buf) {
1528 fields.push(("mid", format!("{v:#06x}")));
1529 }
1530 fields
1531}
1532
1533fn modbus_show_fields(l: &modbus::ModbusLayer, buf: &[u8]) -> Vec<(&'static str, String)> {
1534 let mut fields = Vec::new();
1535 fields.push((
1536 "trans_id",
1537 l.trans_id(buf)
1538 .map_or_else(|_| "?".into(), |v| v.to_string()),
1539 ));
1540 fields.push((
1541 "proto_id",
1542 l.proto_id(buf)
1543 .map_or_else(|_| "?".into(), |v| format!("{v:#06x}")),
1544 ));
1545 fields.push((
1546 "length",
1547 l.length(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
1548 ));
1549 fields.push((
1550 "unit_id",
1551 l.unit_id(buf)
1552 .map_or_else(|_| "?".into(), |v| format!("{v:#04x}")),
1553 ));
1554 let fc = l.func_code(buf).unwrap_or(0);
1555 fields.push((
1556 "func_code",
1557 format!("{:#04x} ({})", fc, modbus::func_code_name(fc)),
1558 ));
1559 if l.is_error(buf) {
1560 fields.push((
1561 "except_code",
1562 l.except_code(buf).map_or_else(
1563 |_| "?".into(),
1564 |v| format!("{} ({})", v, modbus::except_code_name(v)),
1565 ),
1566 ));
1567 }
1568 fields
1569}
1570
1571fn zwave_show_fields(l: &zwave::ZWaveLayer, buf: &[u8]) -> Vec<(&'static str, String)> {
1572 let mut fields = Vec::new();
1573 fields.push((
1574 "home_id",
1575 l.home_id(buf)
1576 .map_or_else(|_| "?".into(), |v| format!("{v:#010x}")),
1577 ));
1578 fields.push((
1579 "src",
1580 l.src(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
1581 ));
1582 fields.push((
1583 "dst",
1584 l.dst(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
1585 ));
1586 fields.push((
1587 "routed",
1588 l.routed(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
1589 ));
1590 fields.push((
1591 "ackreq",
1592 l.ackreq(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
1593 ));
1594 fields.push((
1595 "lowpower",
1596 l.lowpower(buf)
1597 .map_or_else(|_| "?".into(), |v| v.to_string()),
1598 ));
1599 fields.push((
1600 "speedmodified",
1601 l.speedmodified(buf)
1602 .map_or_else(|_| "?".into(), |v| v.to_string()),
1603 ));
1604 fields.push((
1605 "headertype",
1606 l.headertype(buf)
1607 .map_or_else(|_| "?".into(), |v| format!("{v:#04x}")),
1608 ));
1609 fields.push((
1610 "beam_control",
1611 l.beam_control(buf)
1612 .map_or_else(|_| "?".into(), |v| v.to_string()),
1613 ));
1614 fields.push((
1615 "seqn",
1616 l.seqn(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
1617 ));
1618 fields.push((
1619 "length",
1620 l.length(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
1621 ));
1622 if !l.is_ack(buf) {
1623 fields.push((
1624 "cmd_class",
1625 l.cmd_class(buf).map_or_else(
1626 |_| "?".into(),
1627 |v| format!("{:#04x} ({})", v, zwave::cmd_class_name(v)),
1628 ),
1629 ));
1630 if let Ok(cmd) = l.cmd(buf) {
1631 fields.push(("cmd", format!("{cmd:#04x}")));
1632 }
1633 }
1634 fields.push((
1635 "crc",
1636 l.crc(buf)
1637 .map_or_else(|_| "?".into(), |v| format!("{v:#04x}")),
1638 ));
1639 fields
1640}
1641
1642pub use dns::DnsLayer;
1643
1644pub mod ethertype {
1646 use crate::LayerKind;
1647
1648 pub const IPV4: u16 = 0x0800;
1649 pub const ARP: u16 = 0x0806;
1650 pub const IPV6: u16 = 0x86DD;
1651 pub const VLAN: u16 = 0x8100;
1652 pub const DOT1AD: u16 = 0x88A8;
1653 pub const DOT1AH: u16 = 0x88E7;
1654 pub const MACSEC: u16 = 0x88E5;
1655 pub const LOOPBACK: u16 = 0x9000;
1656
1657 #[must_use]
1658 pub fn name(t: u16) -> &'static str {
1659 match t {
1660 IPV4 => "IPv4",
1661 ARP => "ARP",
1662 IPV6 => "IPv6",
1663 VLAN => "802.1Q",
1664 DOT1AD => "802.1AD",
1665 DOT1AH => "802.1AH",
1666 MACSEC => "MACsec",
1667 LOOPBACK => "Loopback",
1668 _ => "Unknown",
1669 }
1670 }
1671
1672 #[must_use]
1673 pub fn to_layer_kind(t: u16) -> Option<LayerKind> {
1674 match t {
1675 IPV4 => Some(LayerKind::Ipv4),
1676 ARP => Some(LayerKind::Arp),
1677 IPV6 => Some(LayerKind::Ipv6),
1678 VLAN => Some(LayerKind::Dot1Q),
1679 DOT1AD => Some(LayerKind::Dot1AD),
1680 DOT1AH => Some(LayerKind::Dot1AH),
1681 _ => None,
1682 }
1683 }
1684
1685 #[must_use]
1686 pub fn from_layer_kind(kind: LayerKind) -> Option<u16> {
1687 match kind {
1688 LayerKind::Ipv4 => Some(IPV4),
1689 LayerKind::Arp => Some(ARP),
1690 LayerKind::Ipv6 => Some(IPV6),
1691 LayerKind::Dot1Q => Some(VLAN),
1692 LayerKind::Dot1AD => Some(DOT1AD),
1693 LayerKind::Dot1AH => Some(DOT1AH),
1694 _ => None,
1695 }
1696 }
1697}
1698
1699pub mod ip_protocol {
1701 pub use crate::layer::ipv4::protocol::*;
1702}
1703
1704#[cfg(test)]
1705mod tests {
1706 use super::*;
1707
1708 #[test]
1709 fn test_layer_kind() {
1710 assert_eq!(LayerKind::Ethernet.name(), "Ethernet");
1711 assert_eq!(LayerKind::Arp.min_header_size(), 28);
1712 assert!(LayerKind::Ethernet.is_link_layer());
1713 assert!(LayerKind::Ipv4.is_network_layer());
1714 assert!(LayerKind::Tcp.is_transport_layer());
1715 }
1716
1717 #[test]
1718 fn test_layer_index() {
1719 let idx = LayerIndex::new(LayerKind::Ethernet, 0, 14);
1720 assert_eq!(idx.len(), 14);
1721 assert_eq!(idx.range(), 0..14);
1722
1723 let buf = vec![0u8; 100];
1724 assert_eq!(idx.slice(&buf).len(), 14);
1725 assert_eq!(idx.payload(&buf).len(), 86);
1726 }
1727
1728 #[test]
1729 fn test_ethertype_conversions() {
1730 assert_eq!(ethertype::to_layer_kind(0x0800), Some(LayerKind::Ipv4));
1731 assert_eq!(ethertype::from_layer_kind(LayerKind::Arp), Some(0x0806));
1732 }
1733}