2 * netsniff-ng - the packet sniffing beast
3 * Copyright 2009 - 2013 Daniel Borkmann.
4 * Copyright 2010 Emmanuel Roullit.
5 * Subject to the GPL, version 2.
16 #include <sys/socket.h>
18 #include <linux/if_packet.h>
19 #include <linux/if_arp.h>
26 #define TCPDUMP_MAGIC 0xa1b2c3d4
27 #define ORIGINAL_TCPDUMP_MAGIC TCPDUMP_MAGIC
28 #define NSEC_TCPDUMP_MAGIC 0xa1b23c4d
29 #define KUZNETZOV_TCPDUMP_MAGIC 0xa1b2cd34
30 #define BORKMANN_TCPDUMP_MAGIC 0xa1e2cb12
32 #define PCAP_VERSION_MAJOR 2
33 #define PCAP_VERSION_MINOR 4
34 #define PCAP_DEFAULT_SNAPSHOT_LEN 65535
36 #define PCAP_TSOURCE_SOFTWARE 1
37 #define PCAP_TSOURCE_SYS_HARDWARE 2
38 #define PCAP_TSOURCE_RAW_HARDWARE 3
40 #define LINKTYPE_NULL 0
41 #define LINKTYPE_EN10MB 1
42 #define LINKTYPE_EN3MB 2
43 #define LINKTYPE_AX25 3
44 #define LINKTYPE_PRONET 4
45 #define LINKTYPE_CHAOS 5
46 #define LINKTYPE_IEEE802 6
47 #define LINKTYPE_SLIP 8
48 #define LINKTYPE_PPP 9
49 #define LINKTYPE_FDDI 10
50 #define LINKTYPE_ATM_CLIP 19
51 #define LINKTYPE_C_HDLC 104
52 #define LINKTYPE_IEEE802_11 105
53 #define LINKTYPE_FRELAY 107
54 #define LINKTYPE_ECONET 115
55 #define LINKTYPE_ARCNET_LINUX 129
56 #define LINKTYPE_LINUX_IRDA 144
57 #define LINKTYPE_CAN20B 190
58 #define LINKTYPE_IEEE802_15_4_LINUX 191
59 #define LINKTYPE_INFINIBAND 247
60 #define LINKTYPE_NETLINK 253
61 #define LINKTYPE_MAX 254
65 uint16_t version_major
;
66 uint16_t version_minor
;
78 struct pcap_timeval_ns
{
84 struct pcap_timeval ts
;
89 struct pcap_pkthdr_ns
{
90 struct pcap_timeval_ns ts
;
95 struct pcap_pkthdr_kuz
{
96 struct pcap_timeval ts
;
104 struct pcap_pkthdr_bkm
{
105 struct pcap_timeval_ns ts
;
116 struct pcap_pkthdr ppo
;
117 struct pcap_pkthdr_ns ppn
;
118 struct pcap_pkthdr_kuz ppk
;
119 struct pcap_pkthdr_bkm ppb
;
124 DEFAULT
= ORIGINAL_TCPDUMP_MAGIC
,
125 NSEC
= NSEC_TCPDUMP_MAGIC
,
126 KUZNETZOV
= KUZNETZOV_TCPDUMP_MAGIC
,
127 BORKMANN
= BORKMANN_TCPDUMP_MAGIC
,
129 DEFAULT_SWAPPED
= ___constant_swab32(ORIGINAL_TCPDUMP_MAGIC
),
130 NSEC_SWAPPED
= ___constant_swab32(NSEC_TCPDUMP_MAGIC
),
131 KUZNETZOV_SWAPPED
= ___constant_swab32(KUZNETZOV_TCPDUMP_MAGIC
),
132 BORKMANN_SWAPPED
= ___constant_swab32(BORKMANN_TCPDUMP_MAGIC
),
135 enum pcap_ops_groups
{
146 struct pcap_file_ops
{
147 void (*init_once_pcap
)(void);
148 int (*pull_fhdr_pcap
)(int fd
, uint32_t *magic
, uint32_t *linktype
);
149 int (*push_fhdr_pcap
)(int fd
, uint32_t magic
, uint32_t linktype
);
150 int (*prepare_access_pcap
)(int fd
, enum pcap_mode mode
, bool jumbo
);
151 ssize_t (*write_pcap
)(int fd
, pcap_pkthdr_t
*phdr
, enum pcap_type type
,
152 const uint8_t *packet
, size_t len
);
153 ssize_t (*read_pcap
)(int fd
, pcap_pkthdr_t
*phdr
, enum pcap_type type
,
154 uint8_t *packet
, size_t len
);
155 void (*prepare_close_pcap
)(int fd
, enum pcap_mode mode
);
156 void (*fsync_pcap
)(int fd
);
159 extern const struct pcap_file_ops pcap_rw_ops __maybe_unused
;
160 extern const struct pcap_file_ops pcap_sg_ops __maybe_unused
;
161 extern const struct pcap_file_ops pcap_mm_ops __maybe_unused
;
163 static inline uint16_t tp_to_pcap_tsource(uint32_t status
)
165 if (status
& TP_STATUS_TS_RAW_HARDWARE
)
166 return PCAP_TSOURCE_RAW_HARDWARE
;
167 else if (status
& TP_STATUS_TS_SYS_HARDWARE
)
168 return PCAP_TSOURCE_SYS_HARDWARE
;
169 else if (status
& TP_STATUS_TS_SOFTWARE
)
170 return PCAP_TSOURCE_SOFTWARE
;
175 static inline int pcap_devtype_to_linktype(const char *ifname
)
177 switch (device_type(ifname
)) {
180 case ARPHRD_LOOPBACK
:
185 case ARPHRD_ETHER
: return LINKTYPE_EN10MB
;
186 case ARPHRD_IEEE80211_PRISM
:
187 case ARPHRD_IEEE80211_RADIOTAP
:
188 case ARPHRD_IEEE80211
: return LINKTYPE_IEEE802_11
;
189 case ARPHRD_NETLINK
: return LINKTYPE_NETLINK
;
190 case ARPHRD_EETHER
: return LINKTYPE_EN3MB
;
191 case ARPHRD_AX25
: return LINKTYPE_AX25
;
192 case ARPHRD_CHAOS
: return LINKTYPE_CHAOS
;
193 case ARPHRD_PRONET
: return LINKTYPE_PRONET
;
194 case ARPHRD_IEEE802_TR
:
195 case ARPHRD_IEEE802
: return LINKTYPE_IEEE802
;
196 case ARPHRD_INFINIBAND
: return LINKTYPE_INFINIBAND
;
197 case ARPHRD_ATM
: return LINKTYPE_ATM_CLIP
;
198 case ARPHRD_DLCI
: return LINKTYPE_FRELAY
;
199 case ARPHRD_ARCNET
: return LINKTYPE_ARCNET_LINUX
;
203 case ARPHRD_SLIP
: return LINKTYPE_SLIP
;
204 case ARPHRD_PPP
: return LINKTYPE_PPP
;
205 case ARPHRD_CAN
: return LINKTYPE_CAN20B
;
206 case ARPHRD_ECONET
: return LINKTYPE_ECONET
;
208 case ARPHRD_CISCO
: return LINKTYPE_C_HDLC
;
209 case ARPHRD_FDDI
: return LINKTYPE_FDDI
;
210 case ARPHRD_IEEE802154_MONITOR
:
211 case ARPHRD_IEEE802154
: return LINKTYPE_IEEE802_15_4_LINUX
;
212 case ARPHRD_IRDA
: return LINKTYPE_LINUX_IRDA
;
213 default: return LINKTYPE_NULL
;
217 static inline void pcap_check_magic(uint32_t magic
)
221 case ORIGINAL_TCPDUMP_MAGIC
:
222 case NSEC_TCPDUMP_MAGIC
:
223 case KUZNETZOV_TCPDUMP_MAGIC
:
224 case BORKMANN_TCPDUMP_MAGIC
:
226 case ___constant_swab32(ORIGINAL_TCPDUMP_MAGIC
):
227 case ___constant_swab32(NSEC_TCPDUMP_MAGIC
):
228 case ___constant_swab32(KUZNETZOV_TCPDUMP_MAGIC
):
229 case ___constant_swab32(BORKMANN_TCPDUMP_MAGIC
):
233 panic("This file has not a valid pcap header\n");
237 static inline bool pcap_magic_is_swapped(uint32_t magic
)
239 bool swapped
= false;
242 case ___constant_swab32(ORIGINAL_TCPDUMP_MAGIC
):
243 case ___constant_swab32(NSEC_TCPDUMP_MAGIC
):
244 case ___constant_swab32(KUZNETZOV_TCPDUMP_MAGIC
):
245 case ___constant_swab32(BORKMANN_TCPDUMP_MAGIC
):
252 static inline u32
pcap_get_length(pcap_pkthdr_t
*phdr
, enum pcap_type type
)
255 #define CASE_RET_CAPLEN(what, member, swap) \
257 return (swap ? ___constant_swab32(phdr->member.caplen) : \
260 CASE_RET_CAPLEN(DEFAULT
, ppo
, 0);
261 CASE_RET_CAPLEN(NSEC
, ppn
, 0);
262 CASE_RET_CAPLEN(KUZNETZOV
, ppk
, 0);
263 CASE_RET_CAPLEN(BORKMANN
, ppb
, 0);
265 CASE_RET_CAPLEN(DEFAULT_SWAPPED
, ppo
, 1);
266 CASE_RET_CAPLEN(NSEC_SWAPPED
, ppn
, 1);
267 CASE_RET_CAPLEN(KUZNETZOV_SWAPPED
, ppk
, 1);
268 CASE_RET_CAPLEN(BORKMANN_SWAPPED
, ppb
, 1);
275 static inline void pcap_set_length(pcap_pkthdr_t
*phdr
, enum pcap_type type
, u32 len
)
278 #define CASE_SET_CAPLEN(what, member, swap) \
280 phdr->member.caplen = (swap ? ___constant_swab32(len) : len); \
283 CASE_SET_CAPLEN(DEFAULT
, ppo
, 0);
284 CASE_SET_CAPLEN(NSEC
, ppn
, 0);
285 CASE_SET_CAPLEN(KUZNETZOV
, ppk
, 0);
286 CASE_SET_CAPLEN(BORKMANN
, ppb
, 0);
288 CASE_SET_CAPLEN(DEFAULT_SWAPPED
, ppo
, 1);
289 CASE_SET_CAPLEN(NSEC_SWAPPED
, ppn
, 1);
290 CASE_SET_CAPLEN(KUZNETZOV_SWAPPED
, ppk
, 1);
291 CASE_SET_CAPLEN(BORKMANN_SWAPPED
, ppb
, 1);
298 static inline u32
pcap_get_hdr_length(pcap_pkthdr_t
*phdr
, enum pcap_type type
)
301 #define CASE_RET_HDRLEN(what, member) \
303 return sizeof(phdr->member)
305 CASE_RET_HDRLEN(DEFAULT
, ppo
);
306 CASE_RET_HDRLEN(NSEC
, ppn
);
307 CASE_RET_HDRLEN(KUZNETZOV
, ppk
);
308 CASE_RET_HDRLEN(BORKMANN
, ppb
);
310 CASE_RET_HDRLEN(DEFAULT_SWAPPED
, ppo
);
311 CASE_RET_HDRLEN(NSEC_SWAPPED
, ppn
);
312 CASE_RET_HDRLEN(KUZNETZOV_SWAPPED
, ppk
);
313 CASE_RET_HDRLEN(BORKMANN_SWAPPED
, ppb
);
320 static inline u32
pcap_get_total_length(pcap_pkthdr_t
*phdr
, enum pcap_type type
)
323 #define CASE_RET_TOTLEN(what, member, swap) \
325 return ((swap ? ___constant_swab32(phdr->member.caplen) : \
326 phdr->member.caplen) + sizeof(phdr->member))
328 CASE_RET_TOTLEN(DEFAULT
, ppo
, 0);
329 CASE_RET_TOTLEN(NSEC
, ppn
, 0);
330 CASE_RET_TOTLEN(KUZNETZOV
, ppk
, 0);
331 CASE_RET_TOTLEN(BORKMANN
, ppb
, 0);
333 CASE_RET_TOTLEN(DEFAULT_SWAPPED
, ppo
, 1);
334 CASE_RET_TOTLEN(NSEC_SWAPPED
, ppn
, 1);
335 CASE_RET_TOTLEN(KUZNETZOV_SWAPPED
, ppk
, 1);
336 CASE_RET_TOTLEN(BORKMANN_SWAPPED
, ppb
, 1);
344 __tpacket_hdr_to_pcap_pkthdr(uint32_t sec
, uint32_t nsec
, uint32_t snaplen
,
345 uint32_t len
, uint32_t status
,
346 struct sockaddr_ll
*sll
, pcap_pkthdr_t
*phdr
,
351 phdr
->ppo
.ts
.tv_sec
= sec
;
352 phdr
->ppo
.ts
.tv_usec
= nsec
/ 1000;
353 phdr
->ppo
.caplen
= snaplen
;
357 case DEFAULT_SWAPPED
:
358 phdr
->ppo
.ts
.tv_sec
= ___constant_swab32(sec
);
359 phdr
->ppo
.ts
.tv_usec
= ___constant_swab32(nsec
/ 1000);
360 phdr
->ppo
.caplen
= ___constant_swab32(snaplen
);
361 phdr
->ppo
.len
= ___constant_swab32(len
);
365 phdr
->ppn
.ts
.tv_sec
= sec
;
366 phdr
->ppn
.ts
.tv_nsec
= nsec
;
367 phdr
->ppn
.caplen
= snaplen
;
372 phdr
->ppn
.ts
.tv_sec
= ___constant_swab32(sec
);
373 phdr
->ppn
.ts
.tv_nsec
= ___constant_swab32(nsec
);
374 phdr
->ppn
.caplen
= ___constant_swab32(snaplen
);
375 phdr
->ppn
.len
= ___constant_swab32(len
);
379 phdr
->ppk
.ts
.tv_sec
= sec
;
380 phdr
->ppk
.ts
.tv_usec
= nsec
/ 1000;
381 phdr
->ppk
.caplen
= snaplen
;
383 phdr
->ppk
.ifindex
= sll
->sll_ifindex
;
384 phdr
->ppk
.protocol
= sll
->sll_protocol
;
385 phdr
->ppk
.pkttype
= sll
->sll_pkttype
;
388 case KUZNETZOV_SWAPPED
:
389 phdr
->ppk
.ts
.tv_sec
= ___constant_swab32(sec
);
390 phdr
->ppk
.ts
.tv_usec
= ___constant_swab32(nsec
/ 1000);
391 phdr
->ppk
.caplen
= ___constant_swab32(snaplen
);
392 phdr
->ppk
.len
= ___constant_swab32(len
);
393 phdr
->ppk
.ifindex
= ___constant_swab32(sll
->sll_ifindex
);
394 phdr
->ppk
.protocol
= ___constant_swab16(sll
->sll_protocol
);
395 phdr
->ppk
.pkttype
= sll
->sll_pkttype
;
399 phdr
->ppb
.ts
.tv_sec
= sec
;
400 phdr
->ppb
.ts
.tv_nsec
= nsec
;
401 phdr
->ppb
.caplen
= snaplen
;
403 phdr
->ppb
.tsource
= tp_to_pcap_tsource(status
);
404 phdr
->ppb
.ifindex
= (u16
) sll
->sll_ifindex
;
405 phdr
->ppb
.protocol
= sll
->sll_protocol
;
406 phdr
->ppb
.hatype
= sll
->sll_hatype
;
407 phdr
->ppb
.pkttype
= sll
->sll_pkttype
;
410 case BORKMANN_SWAPPED
:
411 phdr
->ppb
.ts
.tv_sec
= ___constant_swab32(sec
);
412 phdr
->ppb
.ts
.tv_nsec
= ___constant_swab32(nsec
);
413 phdr
->ppb
.caplen
= ___constant_swab32(snaplen
);
414 phdr
->ppb
.len
= ___constant_swab32(len
);
415 phdr
->ppb
.tsource
= ___constant_swab16(tp_to_pcap_tsource(status
));
416 phdr
->ppb
.ifindex
= ___constant_swab16((u16
) sll
->sll_ifindex
);
417 phdr
->ppb
.protocol
= ___constant_swab16(sll
->sll_protocol
);
418 phdr
->ppb
.hatype
= sll
->sll_hatype
;
419 phdr
->ppb
.pkttype
= sll
->sll_pkttype
;
427 /* We need to do this crap here since member offsets are not interleaved,
428 * so hopfully the compiler does his job here. ;-)
431 static inline void tpacket_hdr_to_pcap_pkthdr(struct tpacket2_hdr
*thdr
,
432 struct sockaddr_ll
*sll
,
436 __tpacket_hdr_to_pcap_pkthdr(thdr
->tp_sec
, thdr
->tp_nsec
,
437 thdr
->tp_snaplen
, thdr
->tp_len
,
438 thdr
->tp_status
, sll
, phdr
, type
);
441 static inline void tpacket3_hdr_to_pcap_pkthdr(struct tpacket3_hdr
*thdr
,
442 struct sockaddr_ll
*sll
,
446 __tpacket_hdr_to_pcap_pkthdr(thdr
->tp_sec
, thdr
->tp_nsec
,
447 thdr
->tp_snaplen
, thdr
->tp_len
,
451 static inline void pcap_pkthdr_to_tpacket_hdr(pcap_pkthdr_t
*phdr
,
453 struct tpacket2_hdr
*thdr
)
457 thdr
->tp_sec
= phdr
->ppo
.ts
.tv_sec
;
458 thdr
->tp_nsec
= phdr
->ppo
.ts
.tv_usec
* 1000;
459 thdr
->tp_snaplen
= phdr
->ppo
.caplen
;
460 thdr
->tp_len
= phdr
->ppo
.len
;
463 case DEFAULT_SWAPPED
:
464 thdr
->tp_sec
= ___constant_swab32(phdr
->ppo
.ts
.tv_sec
);
465 thdr
->tp_nsec
= ___constant_swab32(phdr
->ppo
.ts
.tv_usec
) * 1000;
466 thdr
->tp_snaplen
= ___constant_swab32(phdr
->ppo
.caplen
);
467 thdr
->tp_len
= ___constant_swab32(phdr
->ppo
.len
);
471 thdr
->tp_sec
= phdr
->ppn
.ts
.tv_sec
;
472 thdr
->tp_nsec
= phdr
->ppn
.ts
.tv_nsec
;
473 thdr
->tp_snaplen
= phdr
->ppn
.caplen
;
474 thdr
->tp_len
= phdr
->ppn
.len
;
478 thdr
->tp_sec
= ___constant_swab32(phdr
->ppn
.ts
.tv_sec
);
479 thdr
->tp_nsec
= ___constant_swab32(phdr
->ppn
.ts
.tv_nsec
);
480 thdr
->tp_snaplen
= ___constant_swab32(phdr
->ppn
.caplen
);
481 thdr
->tp_len
= ___constant_swab32(phdr
->ppn
.len
);
485 thdr
->tp_sec
= phdr
->ppk
.ts
.tv_sec
;
486 thdr
->tp_nsec
= phdr
->ppk
.ts
.tv_usec
* 1000;
487 thdr
->tp_snaplen
= phdr
->ppk
.caplen
;
488 thdr
->tp_len
= phdr
->ppk
.len
;
491 case KUZNETZOV_SWAPPED
:
492 thdr
->tp_sec
= ___constant_swab32(phdr
->ppk
.ts
.tv_sec
);
493 thdr
->tp_nsec
= ___constant_swab32(phdr
->ppk
.ts
.tv_usec
) * 1000;
494 thdr
->tp_snaplen
= ___constant_swab32(phdr
->ppk
.caplen
);
495 thdr
->tp_len
= ___constant_swab32(phdr
->ppk
.len
);
499 thdr
->tp_sec
= phdr
->ppb
.ts
.tv_sec
;
500 thdr
->tp_nsec
= phdr
->ppb
.ts
.tv_nsec
;
501 thdr
->tp_snaplen
= phdr
->ppb
.caplen
;
502 thdr
->tp_len
= phdr
->ppb
.len
;
505 case BORKMANN_SWAPPED
:
506 thdr
->tp_sec
= ___constant_swab32(phdr
->ppb
.ts
.tv_sec
);
507 thdr
->tp_nsec
= ___constant_swab32(phdr
->ppb
.ts
.tv_nsec
);
508 thdr
->tp_snaplen
= ___constant_swab32(phdr
->ppb
.caplen
);
509 thdr
->tp_len
= ___constant_swab32(phdr
->ppb
.len
);
517 #define FEATURE_UNKNOWN (0 << 0)
518 #define FEATURE_TIMEVAL_MS (1 << 0)
519 #define FEATURE_TIMEVAL_NS (1 << 1)
520 #define FEATURE_LEN (1 << 2)
521 #define FEATURE_CAPLEN (1 << 3)
522 #define FEATURE_IFINDEX (1 << 4)
523 #define FEATURE_PROTO (1 << 5)
524 #define FEATURE_HATYPE (1 << 6)
525 #define FEATURE_PKTTYPE (1 << 7)
526 #define FEATURE_TSOURCE (1 << 8)
528 struct pcap_magic_type
{
529 const uint32_t magic
;
531 const uint16_t features
;
534 static const struct pcap_magic_type pcap_magic_types
[] __maybe_unused
= {
536 .magic
= ORIGINAL_TCPDUMP_MAGIC
,
537 .desc
= "tcpdump-capable pcap",
538 .features
= FEATURE_TIMEVAL_MS
|
542 .magic
= NSEC_TCPDUMP_MAGIC
,
543 .desc
= "tcpdump-capable pcap with ns resolution",
544 .features
= FEATURE_TIMEVAL_NS
|
548 .magic
= KUZNETZOV_TCPDUMP_MAGIC
,
549 .desc
= "Alexey Kuznetzov's pcap",
550 .features
= FEATURE_TIMEVAL_MS
|
557 .magic
= BORKMANN_TCPDUMP_MAGIC
,
558 .desc
= "netsniff-ng pcap",
559 .features
= FEATURE_TIMEVAL_NS
|
570 static inline void pcap_dump_type_features(void)
574 for (i
= 0; i
< array_size(pcap_magic_types
); ++i
) {
575 printf("%s:\n", pcap_magic_types
[i
].desc
);
576 printf(" magic: 0x%x (swapped: 0x%x)\n",
577 pcap_magic_types
[i
].magic
,
578 ___constant_swab32(pcap_magic_types
[i
].magic
));
579 printf(" features:\n");
581 if (pcap_magic_types
[i
].features
== FEATURE_UNKNOWN
) {
582 printf(" unknown\n");
586 if (pcap_magic_types
[i
].features
& FEATURE_TIMEVAL_MS
)
587 printf(" timeval in us\n");
588 if (pcap_magic_types
[i
].features
& FEATURE_TIMEVAL_NS
)
589 printf(" timeval in ns\n");
590 if (pcap_magic_types
[i
].features
& FEATURE_TSOURCE
)
591 printf(" timestamp source\n");
592 if (pcap_magic_types
[i
].features
& FEATURE_LEN
)
593 printf(" packet length\n");
594 if (pcap_magic_types
[i
].features
& FEATURE_CAPLEN
)
595 printf(" packet cap-length\n");
596 if (pcap_magic_types
[i
].features
& FEATURE_IFINDEX
)
597 printf(" packet ifindex\n");
598 if (pcap_magic_types
[i
].features
& FEATURE_PROTO
)
599 printf(" packet protocol\n");
600 if (pcap_magic_types
[i
].features
& FEATURE_HATYPE
)
601 printf(" hardware type\n");
602 if (pcap_magic_types
[i
].features
& FEATURE_PKTTYPE
)
603 printf(" packet type\n");
607 static const char *pcap_ops_group_to_str
[] __maybe_unused
= {
608 [PCAP_OPS_RW
] = "rw",
609 [PCAP_OPS_SG
] = "sg",
610 [PCAP_OPS_MM
] = "mm",
613 static const struct pcap_file_ops
*pcap_ops
[] __maybe_unused
= {
614 [PCAP_OPS_RW
] = &pcap_rw_ops
,
615 [PCAP_OPS_SG
] = &pcap_sg_ops
,
616 [PCAP_OPS_MM
] = &pcap_mm_ops
,
619 static inline void pcap_prepare_header(struct pcap_filehdr
*hdr
, uint32_t magic
,
620 uint32_t linktype
, int32_t thiszone
,
623 bool swapped
= pcap_magic_is_swapped(magic
);
626 hdr
->version_major
= swapped
? ___constant_swab16(PCAP_VERSION_MAJOR
) : PCAP_VERSION_MAJOR
;
627 hdr
->version_minor
= swapped
? ___constant_swab16(PCAP_VERSION_MINOR
) : PCAP_VERSION_MINOR
;
628 hdr
->thiszone
= swapped
? (int32_t) ___constant_swab32(thiszone
) : thiszone
;
630 hdr
->snaplen
= swapped
? ___constant_swab32(snaplen
) : snaplen
;
631 hdr
->linktype
= swapped
? ___constant_swab32(linktype
) : linktype
;
634 static const bool pcap_supported_linktypes
[LINKTYPE_MAX
] __maybe_unused
= {
635 /* tunX captures from wireshark/tcpdump, non-portable */
636 [101] = true, [102] = true, [103] = true,
637 [LINKTYPE_NULL
] = true,
638 [LINKTYPE_EN10MB
] = true,
639 [LINKTYPE_EN3MB
] = true,
640 [LINKTYPE_AX25
] = true,
641 [LINKTYPE_PRONET
] = true,
642 [LINKTYPE_CHAOS
] = true,
643 [LINKTYPE_IEEE802
] = true,
644 [LINKTYPE_SLIP
] = true,
645 [LINKTYPE_PPP
] = true,
646 [LINKTYPE_FDDI
] = true,
647 [LINKTYPE_ATM_CLIP
] = true,
648 [LINKTYPE_C_HDLC
] = true,
649 [LINKTYPE_IEEE802_11
] = true,
650 [LINKTYPE_FRELAY
] = true,
651 [LINKTYPE_ECONET
] = true,
652 [LINKTYPE_ARCNET_LINUX
] = true,
653 [LINKTYPE_LINUX_IRDA
] = true,
654 [LINKTYPE_CAN20B
] = true,
655 [LINKTYPE_IEEE802_15_4_LINUX
] = true,
656 [LINKTYPE_INFINIBAND
] = true,
657 [LINKTYPE_NETLINK
] = true,
660 static inline void pcap_validate_header(const struct pcap_filehdr
*hdr
)
663 uint32_t linktype_swab
= bswap_32(hdr
->linktype
);
664 pcap_check_magic(hdr
->magic
);
666 if (hdr
->linktype
< LINKTYPE_MAX
) {
667 if (pcap_supported_linktypes
[hdr
->linktype
])
671 if (linktype_swab
< LINKTYPE_MAX
) {
672 if (pcap_supported_linktypes
[linktype_swab
])
677 panic("This file has an unsupported pcap link type (%d)!\n", hdr
->linktype
);
678 if (unlikely(hdr
->version_major
!= PCAP_VERSION_MAJOR
) &&
679 ___constant_swab16(hdr
->version_major
) != PCAP_VERSION_MAJOR
)
680 panic("This file has not a valid pcap header\n");
681 if (unlikely(hdr
->version_minor
!= PCAP_VERSION_MINOR
) &&
682 ___constant_swab16(hdr
->version_minor
) != PCAP_VERSION_MINOR
)
683 panic("This file has not a valid pcap header\n");
686 static int pcap_generic_pull_fhdr(int fd
, uint32_t *magic
,
687 uint32_t *linktype
) __maybe_unused
;
689 static int pcap_generic_pull_fhdr(int fd
, uint32_t *magic
, uint32_t *linktype
)
692 struct pcap_filehdr hdr
;
694 ret
= read(fd
, &hdr
, sizeof(hdr
));
695 if (unlikely(ret
!= sizeof(hdr
)))
698 pcap_validate_header(&hdr
);
701 *linktype
= hdr
.linktype
;
706 static int pcap_generic_push_fhdr(int fd
, uint32_t magic
,
707 uint32_t linktype
) __maybe_unused
;
709 static int pcap_generic_push_fhdr(int fd
, uint32_t magic
, uint32_t linktype
)
712 struct pcap_filehdr hdr
;
714 memset(&hdr
, 0, sizeof(hdr
));
716 pcap_prepare_header(&hdr
, magic
, linktype
, 0, PCAP_DEFAULT_SNAPSHOT_LEN
);
718 ret
= write_or_die(fd
, &hdr
, sizeof(hdr
));
719 if (unlikely(ret
!= sizeof(hdr
)))
720 panic("Failed to write pkt file header!\n");
725 #endif /* PCAP_IO_H */