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
,
454 struct sockaddr_ll
*sll
)
458 thdr
->tp_sec
= phdr
->ppo
.ts
.tv_sec
;
459 thdr
->tp_nsec
= phdr
->ppo
.ts
.tv_usec
* 1000;
460 thdr
->tp_snaplen
= phdr
->ppo
.caplen
;
461 thdr
->tp_len
= phdr
->ppo
.len
;
464 case DEFAULT_SWAPPED
:
465 thdr
->tp_sec
= ___constant_swab32(phdr
->ppo
.ts
.tv_sec
);
466 thdr
->tp_nsec
= ___constant_swab32(phdr
->ppo
.ts
.tv_usec
) * 1000;
467 thdr
->tp_snaplen
= ___constant_swab32(phdr
->ppo
.caplen
);
468 thdr
->tp_len
= ___constant_swab32(phdr
->ppo
.len
);
472 thdr
->tp_sec
= phdr
->ppn
.ts
.tv_sec
;
473 thdr
->tp_nsec
= phdr
->ppn
.ts
.tv_nsec
;
474 thdr
->tp_snaplen
= phdr
->ppn
.caplen
;
475 thdr
->tp_len
= phdr
->ppn
.len
;
479 thdr
->tp_sec
= ___constant_swab32(phdr
->ppn
.ts
.tv_sec
);
480 thdr
->tp_nsec
= ___constant_swab32(phdr
->ppn
.ts
.tv_nsec
);
481 thdr
->tp_snaplen
= ___constant_swab32(phdr
->ppn
.caplen
);
482 thdr
->tp_len
= ___constant_swab32(phdr
->ppn
.len
);
486 thdr
->tp_sec
= phdr
->ppk
.ts
.tv_sec
;
487 thdr
->tp_nsec
= phdr
->ppk
.ts
.tv_usec
* 1000;
488 thdr
->tp_snaplen
= phdr
->ppk
.caplen
;
489 thdr
->tp_len
= phdr
->ppk
.len
;
491 sll
->sll_ifindex
= phdr
->ppk
.ifindex
;
492 sll
->sll_protocol
= phdr
->ppk
.protocol
;
493 sll
->sll_pkttype
= phdr
->ppk
.pkttype
;
497 case KUZNETZOV_SWAPPED
:
498 thdr
->tp_sec
= ___constant_swab32(phdr
->ppk
.ts
.tv_sec
);
499 thdr
->tp_nsec
= ___constant_swab32(phdr
->ppk
.ts
.tv_usec
) * 1000;
500 thdr
->tp_snaplen
= ___constant_swab32(phdr
->ppk
.caplen
);
501 thdr
->tp_len
= ___constant_swab32(phdr
->ppk
.len
);
503 sll
->sll_ifindex
= ___constant_swab32(phdr
->ppk
.ifindex
);
504 sll
->sll_protocol
= ___constant_swab16(phdr
->ppk
.protocol
);
505 sll
->sll_pkttype
= phdr
->ppk
.pkttype
;
510 thdr
->tp_sec
= phdr
->ppb
.ts
.tv_sec
;
511 thdr
->tp_nsec
= phdr
->ppb
.ts
.tv_nsec
;
512 thdr
->tp_snaplen
= phdr
->ppb
.caplen
;
513 thdr
->tp_len
= phdr
->ppb
.len
;
515 sll
->sll_ifindex
= phdr
->ppb
.ifindex
;
516 sll
->sll_protocol
= phdr
->ppb
.protocol
;
517 sll
->sll_hatype
= phdr
->ppb
.hatype
;
518 sll
->sll_pkttype
= phdr
->ppb
.pkttype
;
522 case BORKMANN_SWAPPED
:
523 thdr
->tp_sec
= ___constant_swab32(phdr
->ppb
.ts
.tv_sec
);
524 thdr
->tp_nsec
= ___constant_swab32(phdr
->ppb
.ts
.tv_nsec
);
525 thdr
->tp_snaplen
= ___constant_swab32(phdr
->ppb
.caplen
);
526 thdr
->tp_len
= ___constant_swab32(phdr
->ppb
.len
);
528 sll
->sll_ifindex
= ___constant_swab16(phdr
->ppb
.ifindex
);
529 sll
->sll_protocol
= ___constant_swab16(phdr
->ppb
.protocol
);
530 sll
->sll_hatype
= phdr
->ppb
.hatype
;
531 sll
->sll_pkttype
= phdr
->ppb
.pkttype
;
540 #define FEATURE_UNKNOWN (0 << 0)
541 #define FEATURE_TIMEVAL_MS (1 << 0)
542 #define FEATURE_TIMEVAL_NS (1 << 1)
543 #define FEATURE_LEN (1 << 2)
544 #define FEATURE_CAPLEN (1 << 3)
545 #define FEATURE_IFINDEX (1 << 4)
546 #define FEATURE_PROTO (1 << 5)
547 #define FEATURE_HATYPE (1 << 6)
548 #define FEATURE_PKTTYPE (1 << 7)
549 #define FEATURE_TSOURCE (1 << 8)
551 struct pcap_magic_type
{
552 const uint32_t magic
;
554 const uint16_t features
;
557 static const struct pcap_magic_type pcap_magic_types
[] __maybe_unused
= {
559 .magic
= ORIGINAL_TCPDUMP_MAGIC
,
560 .desc
= "tcpdump-capable pcap",
561 .features
= FEATURE_TIMEVAL_MS
|
565 .magic
= NSEC_TCPDUMP_MAGIC
,
566 .desc
= "tcpdump-capable pcap with ns resolution",
567 .features
= FEATURE_TIMEVAL_NS
|
571 .magic
= KUZNETZOV_TCPDUMP_MAGIC
,
572 .desc
= "Alexey Kuznetzov's pcap",
573 .features
= FEATURE_TIMEVAL_MS
|
580 .magic
= BORKMANN_TCPDUMP_MAGIC
,
581 .desc
= "netsniff-ng pcap",
582 .features
= FEATURE_TIMEVAL_NS
|
593 static inline void pcap_dump_type_features(void)
597 for (i
= 0; i
< array_size(pcap_magic_types
); ++i
) {
598 printf("%s:\n", pcap_magic_types
[i
].desc
);
599 printf(" magic: 0x%x (swapped: 0x%x)\n",
600 pcap_magic_types
[i
].magic
,
601 ___constant_swab32(pcap_magic_types
[i
].magic
));
602 printf(" features:\n");
604 if (pcap_magic_types
[i
].features
== FEATURE_UNKNOWN
) {
605 printf(" unknown\n");
609 if (pcap_magic_types
[i
].features
& FEATURE_TIMEVAL_MS
)
610 printf(" timeval in us\n");
611 if (pcap_magic_types
[i
].features
& FEATURE_TIMEVAL_NS
)
612 printf(" timeval in ns\n");
613 if (pcap_magic_types
[i
].features
& FEATURE_TSOURCE
)
614 printf(" timestamp source\n");
615 if (pcap_magic_types
[i
].features
& FEATURE_LEN
)
616 printf(" packet length\n");
617 if (pcap_magic_types
[i
].features
& FEATURE_CAPLEN
)
618 printf(" packet cap-length\n");
619 if (pcap_magic_types
[i
].features
& FEATURE_IFINDEX
)
620 printf(" packet ifindex\n");
621 if (pcap_magic_types
[i
].features
& FEATURE_PROTO
)
622 printf(" packet protocol\n");
623 if (pcap_magic_types
[i
].features
& FEATURE_HATYPE
)
624 printf(" hardware type\n");
625 if (pcap_magic_types
[i
].features
& FEATURE_PKTTYPE
)
626 printf(" packet type\n");
630 static const char *pcap_ops_group_to_str
[] __maybe_unused
= {
631 [PCAP_OPS_RW
] = "read/write",
632 [PCAP_OPS_SG
] = "scatter-gather",
633 [PCAP_OPS_MM
] = "mmap",
636 static const struct pcap_file_ops
*pcap_ops
[] __maybe_unused
= {
637 [PCAP_OPS_RW
] = &pcap_rw_ops
,
638 [PCAP_OPS_SG
] = &pcap_sg_ops
,
639 [PCAP_OPS_MM
] = &pcap_mm_ops
,
642 static inline void pcap_prepare_header(struct pcap_filehdr
*hdr
, uint32_t magic
,
643 uint32_t linktype
, int32_t thiszone
,
646 bool swapped
= pcap_magic_is_swapped(magic
);
649 hdr
->version_major
= swapped
? ___constant_swab16(PCAP_VERSION_MAJOR
) : PCAP_VERSION_MAJOR
;
650 hdr
->version_minor
= swapped
? ___constant_swab16(PCAP_VERSION_MINOR
) : PCAP_VERSION_MINOR
;
651 hdr
->thiszone
= swapped
? (int32_t) ___constant_swab32(thiszone
) : thiszone
;
653 hdr
->snaplen
= swapped
? ___constant_swab32(snaplen
) : snaplen
;
654 hdr
->linktype
= swapped
? ___constant_swab32(linktype
) : linktype
;
657 static const bool pcap_supported_linktypes
[LINKTYPE_MAX
] __maybe_unused
= {
658 /* tunX captures from wireshark/tcpdump, non-portable */
659 [101] = true, [102] = true, [103] = true,
660 [LINKTYPE_NULL
] = true,
661 [LINKTYPE_EN10MB
] = true,
662 [LINKTYPE_EN3MB
] = true,
663 [LINKTYPE_AX25
] = true,
664 [LINKTYPE_PRONET
] = true,
665 [LINKTYPE_CHAOS
] = true,
666 [LINKTYPE_IEEE802
] = true,
667 [LINKTYPE_SLIP
] = true,
668 [LINKTYPE_PPP
] = true,
669 [LINKTYPE_FDDI
] = true,
670 [LINKTYPE_ATM_CLIP
] = true,
671 [LINKTYPE_C_HDLC
] = true,
672 [LINKTYPE_IEEE802_11
] = true,
673 [LINKTYPE_FRELAY
] = true,
674 [LINKTYPE_ECONET
] = true,
675 [LINKTYPE_ARCNET_LINUX
] = true,
676 [LINKTYPE_LINUX_IRDA
] = true,
677 [LINKTYPE_CAN20B
] = true,
678 [LINKTYPE_IEEE802_15_4_LINUX
] = true,
679 [LINKTYPE_INFINIBAND
] = true,
680 [LINKTYPE_NETLINK
] = true,
683 static inline void pcap_validate_header(const struct pcap_filehdr
*hdr
)
688 pcap_check_magic(hdr
->magic
);
690 linktype
= pcap_magic_is_swapped(hdr
->magic
) ? bswap_32(hdr
->linktype
) : hdr
->linktype
;
691 if (linktype
< LINKTYPE_MAX
)
692 good
= pcap_supported_linktypes
[linktype
];
695 panic("This file has an unsupported pcap link type (%d)!\n", linktype
);
696 if (unlikely(hdr
->version_major
!= PCAP_VERSION_MAJOR
) &&
697 ___constant_swab16(hdr
->version_major
) != PCAP_VERSION_MAJOR
)
698 panic("This file has an invalid pcap major version (must be %d)\n", PCAP_VERSION_MAJOR
);
699 if (unlikely(hdr
->version_minor
!= PCAP_VERSION_MINOR
) &&
700 ___constant_swab16(hdr
->version_minor
) != PCAP_VERSION_MINOR
)
701 panic("This file has an invalid pcap minor version (must be %d)\n", PCAP_VERSION_MINOR
);
704 static int pcap_generic_pull_fhdr(int fd
, uint32_t *magic
,
705 uint32_t *linktype
) __maybe_unused
;
707 static int pcap_generic_pull_fhdr(int fd
, uint32_t *magic
, uint32_t *linktype
)
710 struct pcap_filehdr hdr
;
712 ret
= read(fd
, &hdr
, sizeof(hdr
));
713 if (unlikely(ret
!= sizeof(hdr
)))
716 pcap_validate_header(&hdr
);
719 *linktype
= hdr
.linktype
;
724 static int pcap_generic_push_fhdr(int fd
, uint32_t magic
,
725 uint32_t linktype
) __maybe_unused
;
727 static int pcap_generic_push_fhdr(int fd
, uint32_t magic
, uint32_t linktype
)
730 struct pcap_filehdr hdr
;
732 memset(&hdr
, 0, sizeof(hdr
));
734 pcap_prepare_header(&hdr
, magic
, linktype
, 0, PCAP_DEFAULT_SNAPSHOT_LEN
);
736 ret
= write_or_die(fd
, &hdr
, sizeof(hdr
));
737 if (unlikely(ret
!= sizeof(hdr
)))
738 panic("Failed to write pkt file header!\n");
743 #endif /* PCAP_IO_H */