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>
17 #include <net/if_arp.h>
19 #include <linux/if_packet.h>
27 #define TCPDUMP_MAGIC 0xa1b2c3d4
28 #define ORIGINAL_TCPDUMP_MAGIC TCPDUMP_MAGIC
29 #define NSEC_TCPDUMP_MAGIC 0xa1b23c4d
30 #define ORIGINAL_TCPDUMP_MAGIC_LL 0xb1b2c3d4 /* Internal dummy just for mapping */
31 #define NSEC_TCPDUMP_MAGIC_LL 0xb1b23c4d /* Internal dummy just for mapping */
32 #define KUZNETZOV_TCPDUMP_MAGIC 0xa1b2cd34
33 #define BORKMANN_TCPDUMP_MAGIC 0xa1e2cb12
35 #define PCAP_VERSION_MAJOR 2
36 #define PCAP_VERSION_MINOR 4
37 #define PCAP_DEFAULT_SNAPSHOT_LEN 65535
39 #define PCAP_TSOURCE_SOFTWARE 1
40 #define PCAP_TSOURCE_SYS_HARDWARE 2
41 #define PCAP_TSOURCE_RAW_HARDWARE 3
45 uint16_t version_major
;
46 uint16_t version_minor
;
58 struct pcap_timeval_ns
{
72 struct pcap_timeval ts
;
77 struct pcap_pkthdr_ns
{
78 struct pcap_timeval_ns ts
;
83 struct pcap_pkthdr_ll
{
84 struct pcap_timeval ts
;
90 struct pcap_pkthdr_ns_ll
{
91 struct pcap_timeval_ns ts
;
97 struct pcap_pkthdr_kuz
{
98 struct pcap_timeval ts
;
106 struct pcap_pkthdr_bkm
{
107 struct pcap_timeval_ns ts
;
118 struct pcap_pkthdr ppo
;
119 struct pcap_pkthdr_ns ppn
;
120 struct pcap_pkthdr_ll ppo_ll
;
121 struct pcap_pkthdr_ns_ll ppn_ll
;
122 struct pcap_pkthdr_kuz ppk
;
123 struct pcap_pkthdr_bkm ppb
;
128 DEFAULT
= ORIGINAL_TCPDUMP_MAGIC
,
129 NSEC
= NSEC_TCPDUMP_MAGIC
,
130 DEFAULT_LL
= ORIGINAL_TCPDUMP_MAGIC_LL
,
131 NSEC_LL
= NSEC_TCPDUMP_MAGIC_LL
,
132 KUZNETZOV
= KUZNETZOV_TCPDUMP_MAGIC
,
133 BORKMANN
= BORKMANN_TCPDUMP_MAGIC
,
135 DEFAULT_SWAPPED
= ___constant_swab32(ORIGINAL_TCPDUMP_MAGIC
),
136 NSEC_SWAPPED
= ___constant_swab32(NSEC_TCPDUMP_MAGIC
),
137 DEFAULT_LL_SWAPPED
= ___constant_swab32(ORIGINAL_TCPDUMP_MAGIC_LL
),
138 NSEC_LL_SWAPPED
= ___constant_swab32(NSEC_TCPDUMP_MAGIC_LL
),
139 KUZNETZOV_SWAPPED
= ___constant_swab32(KUZNETZOV_TCPDUMP_MAGIC
),
140 BORKMANN_SWAPPED
= ___constant_swab32(BORKMANN_TCPDUMP_MAGIC
),
143 enum pcap_ops_groups
{
154 struct pcap_file_ops
{
155 void (*init_once_pcap
)(bool enforce_prio
);
156 int (*pull_fhdr_pcap
)(int fd
, uint32_t *magic
, uint32_t *linktype
);
157 int (*push_fhdr_pcap
)(int fd
, uint32_t magic
, uint32_t linktype
);
158 int (*prepare_access_pcap
)(int fd
, enum pcap_mode mode
, bool jumbo
);
159 ssize_t (*write_pcap
)(int fd
, pcap_pkthdr_t
*phdr
, enum pcap_type type
,
160 const uint8_t *packet
, size_t len
);
161 ssize_t (*read_pcap
)(int fd
, pcap_pkthdr_t
*phdr
, enum pcap_type type
,
162 uint8_t *packet
, size_t len
);
163 void (*prepare_close_pcap
)(int fd
, enum pcap_mode mode
);
164 void (*fsync_pcap
)(int fd
);
167 extern const struct pcap_file_ops pcap_rw_ops __maybe_unused
;
168 extern const struct pcap_file_ops pcap_sg_ops __maybe_unused
;
169 extern const struct pcap_file_ops pcap_mm_ops __maybe_unused
;
171 static inline void sockaddr_to_ll(const struct sockaddr_ll
*sll
,
174 ll
->pkttype
= cpu_to_be16(sll
->sll_pkttype
);
175 ll
->hatype
= cpu_to_be16(sll
->sll_hatype
);
176 ll
->len
= cpu_to_be16(sll
->sll_halen
);
177 ll
->protocol
= sll
->sll_protocol
; /* already be16 */
179 memcpy(ll
->addr
, sll
->sll_addr
, sizeof(ll
->addr
));
182 static inline void ll_to_sockaddr(const struct pcap_ll
*ll
,
183 struct sockaddr_ll
*sll
)
185 sll
->sll_pkttype
= be16_to_cpu(ll
->pkttype
);
186 sll
->sll_hatype
= be16_to_cpu(ll
->hatype
);
187 sll
->sll_halen
= be16_to_cpu(ll
->len
);
188 sll
->sll_protocol
= ll
->protocol
; /* stays be16 */
190 memcpy(sll
->sll_addr
, ll
->addr
, sizeof(ll
->addr
));
193 static inline uint16_t tp_to_pcap_tsource(uint32_t status
)
195 if (status
& TP_STATUS_TS_RAW_HARDWARE
)
196 return PCAP_TSOURCE_RAW_HARDWARE
;
197 else if (status
& TP_STATUS_TS_SYS_HARDWARE
)
198 return PCAP_TSOURCE_SYS_HARDWARE
;
199 else if (status
& TP_STATUS_TS_SOFTWARE
)
200 return PCAP_TSOURCE_SOFTWARE
;
205 static inline int pcap_devtype_to_linktype(int dev_type
)
210 case ARPHRD_LOOPBACK
:
216 return LINKTYPE_EN10MB
;
217 case ARPHRD_IEEE80211_RADIOTAP
:
218 return LINKTYPE_IEEE802_11_RADIOTAP
;
219 case ARPHRD_IEEE80211_PRISM
:
220 case ARPHRD_IEEE80211
:
221 return LINKTYPE_IEEE802_11
;
223 return LINKTYPE_NETLINK
;
225 return LINKTYPE_EN3MB
;
227 return LINKTYPE_AX25
;
229 return LINKTYPE_CHAOS
;
231 return LINKTYPE_PRONET
;
232 case ARPHRD_IEEE802_TR
:
234 return LINKTYPE_IEEE802
;
235 case ARPHRD_INFINIBAND
:
236 return LINKTYPE_INFINIBAND
;
238 return LINKTYPE_ATM_CLIP
;
240 return LINKTYPE_FRELAY
;
242 return LINKTYPE_ARCNET_LINUX
;
247 return LINKTYPE_SLIP
;
251 return LINKTYPE_CAN20B
;
253 return LINKTYPE_ECONET
;
256 return LINKTYPE_C_HDLC
;
258 return LINKTYPE_FDDI
;
259 case ARPHRD_IEEE802154_MONITOR
:
260 case ARPHRD_IEEE802154
:
261 return LINKTYPE_IEEE802_15_4_LINUX
;
263 return LINKTYPE_LINUX_IRDA
;
265 return LINKTYPE_NULL
;
269 static inline bool link_has_sll_hdr(uint32_t link_type
)
272 case LINKTYPE_NETLINK
:
273 case LINKTYPE_LINUX_SLL
:
274 case ___constant_swab32(LINKTYPE_NETLINK
):
275 case ___constant_swab32(LINKTYPE_LINUX_SLL
):
282 static inline int pcap_dev_to_linktype(const char *ifname
)
284 return pcap_devtype_to_linktype(device_type(ifname
));
287 static inline void pcap_check_magic(uint32_t magic
)
291 case ORIGINAL_TCPDUMP_MAGIC
:
292 case NSEC_TCPDUMP_MAGIC
:
293 case KUZNETZOV_TCPDUMP_MAGIC
:
294 case BORKMANN_TCPDUMP_MAGIC
:
296 case ___constant_swab32(ORIGINAL_TCPDUMP_MAGIC
):
297 case ___constant_swab32(NSEC_TCPDUMP_MAGIC
):
298 case ___constant_swab32(KUZNETZOV_TCPDUMP_MAGIC
):
299 case ___constant_swab32(BORKMANN_TCPDUMP_MAGIC
):
303 panic("This file has an unsupported pcap magic number(0x%x)\n", magic
);
307 static inline bool pcap_magic_is_swapped(uint32_t magic
)
309 bool swapped
= false;
312 case ___constant_swab32(ORIGINAL_TCPDUMP_MAGIC
):
313 case ___constant_swab32(NSEC_TCPDUMP_MAGIC
):
314 case ___constant_swab32(KUZNETZOV_TCPDUMP_MAGIC
):
315 case ___constant_swab32(BORKMANN_TCPDUMP_MAGIC
):
322 static inline u32
pcap_get_length(pcap_pkthdr_t
*phdr
, enum pcap_type type
)
325 #define CASE_RET_CAPLEN(what, member, swap, extra) \
327 return (swap ? ___constant_swab32(phdr->member.caplen) : \
328 phdr->member.caplen) - extra
330 CASE_RET_CAPLEN(DEFAULT
, ppo
, 0, 0);
331 CASE_RET_CAPLEN(NSEC
, ppn
, 0, 0);
332 CASE_RET_CAPLEN(DEFAULT_LL
, ppo_ll
, 0, sizeof(struct pcap_ll
));
333 CASE_RET_CAPLEN(NSEC_LL
, ppn_ll
, 0, sizeof(struct pcap_ll
));
334 CASE_RET_CAPLEN(KUZNETZOV
, ppk
, 0, 0);
335 CASE_RET_CAPLEN(BORKMANN
, ppb
, 0, 0);
337 CASE_RET_CAPLEN(DEFAULT_SWAPPED
, ppo
, 1, 0);
338 CASE_RET_CAPLEN(NSEC_SWAPPED
, ppn
, 1, 0);
339 CASE_RET_CAPLEN(DEFAULT_LL_SWAPPED
, ppo_ll
, 1, sizeof(struct pcap_ll
));
340 CASE_RET_CAPLEN(NSEC_LL_SWAPPED
, ppn_ll
, 1, sizeof(struct pcap_ll
));
341 CASE_RET_CAPLEN(KUZNETZOV_SWAPPED
, ppk
, 1, 0);
342 CASE_RET_CAPLEN(BORKMANN_SWAPPED
, ppb
, 1, 0);
349 static inline void pcap_set_length(pcap_pkthdr_t
*phdr
, enum pcap_type type
, u32 len
)
352 #define CASE_SET_CAPLEN(what, member, swap) \
354 phdr->member.caplen = (swap ? ___constant_swab32(len) : len); \
357 CASE_SET_CAPLEN(DEFAULT
, ppo
, 0);
358 CASE_SET_CAPLEN(NSEC
, ppn
, 0);
359 CASE_SET_CAPLEN(DEFAULT_LL
, ppo_ll
, 0);
360 CASE_SET_CAPLEN(NSEC_LL
, ppn_ll
, 0);
361 CASE_SET_CAPLEN(KUZNETZOV
, ppk
, 0);
362 CASE_SET_CAPLEN(BORKMANN
, ppb
, 0);
364 CASE_SET_CAPLEN(DEFAULT_SWAPPED
, ppo
, 1);
365 CASE_SET_CAPLEN(NSEC_SWAPPED
, ppn
, 1);
366 CASE_SET_CAPLEN(DEFAULT_LL_SWAPPED
, ppo_ll
, 1);
367 CASE_SET_CAPLEN(NSEC_LL_SWAPPED
, ppn_ll
, 1);
368 CASE_SET_CAPLEN(KUZNETZOV_SWAPPED
, ppk
, 1);
369 CASE_SET_CAPLEN(BORKMANN_SWAPPED
, ppb
, 1);
376 static inline void pcap_get_tstamp(pcap_pkthdr_t
*phdr
, enum pcap_type type
,
382 ts
->tv_sec
= phdr
->ppo
.ts
.tv_sec
;
383 ts
->tv_nsec
= phdr
->ppo
.ts
.tv_usec
* 1000;
386 case DEFAULT_SWAPPED
:
387 case DEFAULT_LL_SWAPPED
:
388 ts
->tv_sec
= ___constant_swab32(phdr
->ppo
.ts
.tv_sec
);
389 ts
->tv_nsec
= ___constant_swab32(phdr
->ppo
.ts
.tv_usec
) * 1000;;
394 ts
->tv_sec
= phdr
->ppn
.ts
.tv_sec
;
395 ts
->tv_nsec
= phdr
->ppn
.ts
.tv_nsec
/ 1000;
399 case NSEC_LL_SWAPPED
:
400 ts
->tv_sec
= ___constant_swab32(phdr
->ppn
.ts
.tv_sec
);
401 ts
->tv_nsec
= ___constant_swab32(phdr
->ppn
.ts
.tv_nsec
);
405 ts
->tv_sec
= phdr
->ppk
.ts
.tv_sec
;
406 ts
->tv_nsec
= phdr
->ppk
.ts
.tv_usec
;
409 case KUZNETZOV_SWAPPED
:
410 ts
->tv_sec
= ___constant_swab32(phdr
->ppk
.ts
.tv_sec
);
411 ts
->tv_nsec
= ___constant_swab32(phdr
->ppk
.ts
.tv_usec
);
415 ts
->tv_sec
= phdr
->ppb
.ts
.tv_sec
;
416 ts
->tv_nsec
= phdr
->ppb
.ts
.tv_nsec
;
419 case BORKMANN_SWAPPED
:
420 ts
->tv_sec
= ___constant_swab32(phdr
->ppb
.ts
.tv_sec
);
421 ts
->tv_nsec
= ___constant_swab32(phdr
->ppb
.ts
.tv_nsec
);
429 static inline u32
pcap_get_hdr_length(pcap_pkthdr_t
*phdr
, enum pcap_type type
)
432 #define CASE_RET_HDRLEN(what, member) \
434 return sizeof(phdr->member)
436 CASE_RET_HDRLEN(DEFAULT
, ppo
);
437 CASE_RET_HDRLEN(NSEC
, ppn
);
438 CASE_RET_HDRLEN(DEFAULT_LL
, ppo_ll
);
439 CASE_RET_HDRLEN(NSEC_LL
, ppn_ll
);
440 CASE_RET_HDRLEN(KUZNETZOV
, ppk
);
441 CASE_RET_HDRLEN(BORKMANN
, ppb
);
443 CASE_RET_HDRLEN(DEFAULT_SWAPPED
, ppo
);
444 CASE_RET_HDRLEN(NSEC_SWAPPED
, ppn
);
445 CASE_RET_HDRLEN(DEFAULT_LL_SWAPPED
, ppo_ll
);
446 CASE_RET_HDRLEN(NSEC_LL_SWAPPED
, ppn_ll
);
447 CASE_RET_HDRLEN(KUZNETZOV_SWAPPED
, ppk
);
448 CASE_RET_HDRLEN(BORKMANN_SWAPPED
, ppb
);
455 static inline u32
pcap_get_total_length(pcap_pkthdr_t
*phdr
, enum pcap_type type
)
457 return pcap_get_hdr_length(phdr
, type
) + pcap_get_length(phdr
, type
);
461 __tpacket_hdr_to_pcap_pkthdr(uint32_t sec
, uint32_t nsec
, uint32_t snaplen
,
462 uint32_t len
, uint32_t status
,
463 struct sockaddr_ll
*sll
, pcap_pkthdr_t
*phdr
,
469 phdr
->ppo
.ts
.tv_sec
= sec
;
470 phdr
->ppo
.ts
.tv_usec
= nsec
/ 1000;
471 phdr
->ppo
.caplen
= snaplen
;
473 if (type
== DEFAULT_LL
) {
474 phdr
->ppo
.caplen
+= sizeof(struct pcap_ll
);
475 phdr
->ppo
.len
+= sizeof(struct pcap_ll
);
476 sockaddr_to_ll(sll
, &phdr
->ppo_ll
.ll
);
480 case DEFAULT_SWAPPED
:
481 case DEFAULT_LL_SWAPPED
:
482 phdr
->ppo
.ts
.tv_sec
= ___constant_swab32(sec
);
483 phdr
->ppo
.ts
.tv_usec
= ___constant_swab32(nsec
/ 1000);
484 phdr
->ppo
.caplen
= ___constant_swab32(snaplen
);
485 phdr
->ppo
.len
= ___constant_swab32(len
);
486 if (type
== DEFAULT_LL_SWAPPED
) {
487 phdr
->ppo
.caplen
= ___constant_swab32(snaplen
+ sizeof(struct pcap_ll
));
488 phdr
->ppo
.len
= ___constant_swab32(len
+ sizeof(struct pcap_ll
));
489 sockaddr_to_ll(sll
, &phdr
->ppo_ll
.ll
);
495 phdr
->ppn
.ts
.tv_sec
= sec
;
496 phdr
->ppn
.ts
.tv_nsec
= nsec
;
497 phdr
->ppn
.caplen
= snaplen
;
499 if (type
== NSEC_LL
) {
500 phdr
->ppn
.caplen
+= sizeof(struct pcap_ll
);
501 phdr
->ppn
.len
+= sizeof(struct pcap_ll
);
502 sockaddr_to_ll(sll
, &phdr
->ppn_ll
.ll
);
507 case NSEC_LL_SWAPPED
:
508 phdr
->ppn
.ts
.tv_sec
= ___constant_swab32(sec
);
509 phdr
->ppn
.ts
.tv_nsec
= ___constant_swab32(nsec
);
510 phdr
->ppn
.caplen
= ___constant_swab32(snaplen
);
511 phdr
->ppn
.len
= ___constant_swab32(len
);
512 if (type
== NSEC_LL_SWAPPED
) {
513 phdr
->ppn
.caplen
= ___constant_swab32(snaplen
+ sizeof(struct pcap_ll
));
514 phdr
->ppn
.len
= ___constant_swab32(len
+ sizeof(struct pcap_ll
));
515 sockaddr_to_ll(sll
, &phdr
->ppn_ll
.ll
);
520 phdr
->ppk
.ts
.tv_sec
= sec
;
521 phdr
->ppk
.ts
.tv_usec
= nsec
/ 1000;
522 phdr
->ppk
.caplen
= snaplen
;
524 phdr
->ppk
.ifindex
= sll
->sll_ifindex
;
525 phdr
->ppk
.protocol
= sll
->sll_protocol
;
526 phdr
->ppk
.pkttype
= sll
->sll_pkttype
;
529 case KUZNETZOV_SWAPPED
:
530 phdr
->ppk
.ts
.tv_sec
= ___constant_swab32(sec
);
531 phdr
->ppk
.ts
.tv_usec
= ___constant_swab32(nsec
/ 1000);
532 phdr
->ppk
.caplen
= ___constant_swab32(snaplen
);
533 phdr
->ppk
.len
= ___constant_swab32(len
);
534 phdr
->ppk
.ifindex
= ___constant_swab32(sll
->sll_ifindex
);
535 phdr
->ppk
.protocol
= ___constant_swab16(sll
->sll_protocol
);
536 phdr
->ppk
.pkttype
= sll
->sll_pkttype
;
540 phdr
->ppb
.ts
.tv_sec
= sec
;
541 phdr
->ppb
.ts
.tv_nsec
= nsec
;
542 phdr
->ppb
.caplen
= snaplen
;
544 phdr
->ppb
.tsource
= tp_to_pcap_tsource(status
);
545 phdr
->ppb
.ifindex
= (u16
) sll
->sll_ifindex
;
546 phdr
->ppb
.protocol
= sll
->sll_protocol
;
547 phdr
->ppb
.hatype
= sll
->sll_hatype
;
548 phdr
->ppb
.pkttype
= sll
->sll_pkttype
;
551 case BORKMANN_SWAPPED
:
552 phdr
->ppb
.ts
.tv_sec
= ___constant_swab32(sec
);
553 phdr
->ppb
.ts
.tv_nsec
= ___constant_swab32(nsec
);
554 phdr
->ppb
.caplen
= ___constant_swab32(snaplen
);
555 phdr
->ppb
.len
= ___constant_swab32(len
);
556 phdr
->ppb
.tsource
= ___constant_swab16(tp_to_pcap_tsource(status
));
557 phdr
->ppb
.ifindex
= ___constant_swab16((u16
) sll
->sll_ifindex
);
558 phdr
->ppb
.protocol
= ___constant_swab16(sll
->sll_protocol
);
559 phdr
->ppb
.hatype
= sll
->sll_hatype
;
560 phdr
->ppb
.pkttype
= sll
->sll_pkttype
;
568 /* We need to do this crap here since member offsets are not interleaved,
569 * so hopfully the compiler does his job here. ;-)
572 static inline void tpacket_hdr_to_pcap_pkthdr(struct tpacket2_hdr
*thdr
,
573 struct sockaddr_ll
*sll
,
577 __tpacket_hdr_to_pcap_pkthdr(thdr
->tp_sec
, thdr
->tp_nsec
,
578 thdr
->tp_snaplen
, thdr
->tp_len
,
579 thdr
->tp_status
, sll
, phdr
, type
);
583 static inline void tpacket3_hdr_to_pcap_pkthdr(struct tpacket3_hdr
*thdr
,
584 struct sockaddr_ll
*sll
,
588 __tpacket_hdr_to_pcap_pkthdr(thdr
->tp_sec
, thdr
->tp_nsec
,
589 thdr
->tp_snaplen
, thdr
->tp_len
,
594 static inline void pcap_pkthdr_to_tpacket_hdr(pcap_pkthdr_t
*phdr
,
596 struct tpacket2_hdr
*thdr
,
597 struct sockaddr_ll
*sll
)
602 thdr
->tp_sec
= phdr
->ppo
.ts
.tv_sec
;
603 thdr
->tp_nsec
= phdr
->ppo
.ts
.tv_usec
* 1000;
604 thdr
->tp_snaplen
= phdr
->ppo
.caplen
;
605 thdr
->tp_len
= phdr
->ppo
.len
;
606 if (type
== DEFAULT_LL
) {
607 thdr
->tp_snaplen
-= sizeof(struct pcap_ll
);
608 thdr
->tp_len
-= sizeof(struct pcap_ll
);
610 ll_to_sockaddr(&phdr
->ppo_ll
.ll
, sll
);
614 case DEFAULT_SWAPPED
:
615 case DEFAULT_LL_SWAPPED
:
616 thdr
->tp_sec
= ___constant_swab32(phdr
->ppo
.ts
.tv_sec
);
617 thdr
->tp_nsec
= ___constant_swab32(phdr
->ppo
.ts
.tv_usec
) * 1000;
618 thdr
->tp_snaplen
= ___constant_swab32(phdr
->ppo
.caplen
);
619 thdr
->tp_len
= ___constant_swab32(phdr
->ppo
.len
);
620 if (type
== DEFAULT_LL_SWAPPED
) {
621 thdr
->tp_snaplen
-= sizeof(struct pcap_ll
);
622 thdr
->tp_len
-= sizeof(struct pcap_ll
);
624 ll_to_sockaddr(&phdr
->ppo_ll
.ll
, sll
);
630 thdr
->tp_sec
= phdr
->ppn
.ts
.tv_sec
;
631 thdr
->tp_nsec
= phdr
->ppn
.ts
.tv_nsec
;
632 thdr
->tp_snaplen
= phdr
->ppn
.caplen
;
633 thdr
->tp_len
= phdr
->ppn
.len
;
634 if (type
== NSEC_LL
) {
635 thdr
->tp_snaplen
-= sizeof(struct pcap_ll
);
636 thdr
->tp_len
-= sizeof(struct pcap_ll
);
638 ll_to_sockaddr(&phdr
->ppn_ll
.ll
, sll
);
643 case NSEC_LL_SWAPPED
:
644 thdr
->tp_sec
= ___constant_swab32(phdr
->ppn
.ts
.tv_sec
);
645 thdr
->tp_nsec
= ___constant_swab32(phdr
->ppn
.ts
.tv_nsec
);
646 thdr
->tp_snaplen
= ___constant_swab32(phdr
->ppn
.caplen
);
647 thdr
->tp_len
= ___constant_swab32(phdr
->ppn
.len
);
648 if (type
== NSEC_LL_SWAPPED
) {
649 thdr
->tp_snaplen
-= sizeof(struct pcap_ll
);
650 thdr
->tp_len
-= sizeof(struct pcap_ll
);
652 ll_to_sockaddr(&phdr
->ppn_ll
.ll
, sll
);
657 thdr
->tp_sec
= phdr
->ppk
.ts
.tv_sec
;
658 thdr
->tp_nsec
= phdr
->ppk
.ts
.tv_usec
* 1000;
659 thdr
->tp_snaplen
= phdr
->ppk
.caplen
;
660 thdr
->tp_len
= phdr
->ppk
.len
;
662 sll
->sll_ifindex
= phdr
->ppk
.ifindex
;
663 sll
->sll_protocol
= phdr
->ppk
.protocol
;
664 sll
->sll_pkttype
= phdr
->ppk
.pkttype
;
668 case KUZNETZOV_SWAPPED
:
669 thdr
->tp_sec
= ___constant_swab32(phdr
->ppk
.ts
.tv_sec
);
670 thdr
->tp_nsec
= ___constant_swab32(phdr
->ppk
.ts
.tv_usec
) * 1000;
671 thdr
->tp_snaplen
= ___constant_swab32(phdr
->ppk
.caplen
);
672 thdr
->tp_len
= ___constant_swab32(phdr
->ppk
.len
);
674 sll
->sll_ifindex
= ___constant_swab32(phdr
->ppk
.ifindex
);
675 sll
->sll_protocol
= ___constant_swab16(phdr
->ppk
.protocol
);
676 sll
->sll_pkttype
= phdr
->ppk
.pkttype
;
681 thdr
->tp_sec
= phdr
->ppb
.ts
.tv_sec
;
682 thdr
->tp_nsec
= phdr
->ppb
.ts
.tv_nsec
;
683 thdr
->tp_snaplen
= phdr
->ppb
.caplen
;
684 thdr
->tp_len
= phdr
->ppb
.len
;
686 sll
->sll_ifindex
= phdr
->ppb
.ifindex
;
687 sll
->sll_protocol
= phdr
->ppb
.protocol
;
688 sll
->sll_hatype
= phdr
->ppb
.hatype
;
689 sll
->sll_pkttype
= phdr
->ppb
.pkttype
;
693 case BORKMANN_SWAPPED
:
694 thdr
->tp_sec
= ___constant_swab32(phdr
->ppb
.ts
.tv_sec
);
695 thdr
->tp_nsec
= ___constant_swab32(phdr
->ppb
.ts
.tv_nsec
);
696 thdr
->tp_snaplen
= ___constant_swab32(phdr
->ppb
.caplen
);
697 thdr
->tp_len
= ___constant_swab32(phdr
->ppb
.len
);
699 sll
->sll_ifindex
= ___constant_swab16(phdr
->ppb
.ifindex
);
700 sll
->sll_protocol
= ___constant_swab16(phdr
->ppb
.protocol
);
701 sll
->sll_hatype
= phdr
->ppb
.hatype
;
702 sll
->sll_pkttype
= phdr
->ppb
.pkttype
;
711 #define FEATURE_UNKNOWN (0 << 0)
712 #define FEATURE_TIMEVAL_MS (1 << 0)
713 #define FEATURE_TIMEVAL_NS (1 << 1)
714 #define FEATURE_LEN (1 << 2)
715 #define FEATURE_CAPLEN (1 << 3)
716 #define FEATURE_IFINDEX (1 << 4)
717 #define FEATURE_PROTO (1 << 5)
718 #define FEATURE_HATYPE (1 << 6)
719 #define FEATURE_PKTTYPE (1 << 7)
720 #define FEATURE_TSOURCE (1 << 8)
722 struct pcap_magic_type
{
723 const uint32_t magic
;
725 const uint16_t features
;
728 static const struct pcap_magic_type pcap_magic_types
[] __maybe_unused
= {
730 .magic
= ORIGINAL_TCPDUMP_MAGIC
,
731 .desc
= "tcpdump-capable pcap",
732 .features
= FEATURE_TIMEVAL_MS
|
736 .magic
= NSEC_TCPDUMP_MAGIC
,
737 .desc
= "tcpdump-capable pcap with ns resolution",
738 .features
= FEATURE_TIMEVAL_NS
|
742 .magic
= KUZNETZOV_TCPDUMP_MAGIC
,
743 .desc
= "Alexey Kuznetzov's pcap",
744 .features
= FEATURE_TIMEVAL_MS
|
751 .magic
= BORKMANN_TCPDUMP_MAGIC
,
752 .desc
= "netsniff-ng pcap",
753 .features
= FEATURE_TIMEVAL_NS
|
764 static inline void pcap_dump_type_features(void)
768 for (i
= 0; i
< array_size(pcap_magic_types
); ++i
) {
769 printf("%s:\n", pcap_magic_types
[i
].desc
);
770 printf(" magic: 0x%x (swapped: 0x%x)\n",
771 pcap_magic_types
[i
].magic
,
772 ___constant_swab32(pcap_magic_types
[i
].magic
));
773 printf(" features:\n");
775 if (pcap_magic_types
[i
].features
== FEATURE_UNKNOWN
) {
776 printf(" unknown\n");
780 if (pcap_magic_types
[i
].features
& FEATURE_TIMEVAL_MS
)
781 printf(" timeval in us\n");
782 if (pcap_magic_types
[i
].features
& FEATURE_TIMEVAL_NS
)
783 printf(" timeval in ns\n");
784 if (pcap_magic_types
[i
].features
& FEATURE_TSOURCE
)
785 printf(" timestamp source\n");
786 if (pcap_magic_types
[i
].features
& FEATURE_LEN
)
787 printf(" packet length\n");
788 if (pcap_magic_types
[i
].features
& FEATURE_CAPLEN
)
789 printf(" packet cap-length\n");
790 if (pcap_magic_types
[i
].features
& FEATURE_IFINDEX
)
791 printf(" packet ifindex\n");
792 if (pcap_magic_types
[i
].features
& FEATURE_PROTO
)
793 printf(" packet protocol\n");
794 if (pcap_magic_types
[i
].features
& FEATURE_HATYPE
)
795 printf(" hardware type\n");
796 if (pcap_magic_types
[i
].features
& FEATURE_PKTTYPE
)
797 printf(" packet type\n");
801 static const char *pcap_ops_group_to_str
[] __maybe_unused
= {
802 [PCAP_OPS_RW
] = "read/write",
803 [PCAP_OPS_SG
] = "scatter-gather",
804 [PCAP_OPS_MM
] = "mmap",
807 static const struct pcap_file_ops
*pcap_ops
[] __maybe_unused
= {
808 [PCAP_OPS_RW
] = &pcap_rw_ops
,
809 [PCAP_OPS_SG
] = &pcap_sg_ops
,
810 [PCAP_OPS_MM
] = &pcap_mm_ops
,
813 static inline void pcap_prepare_header(struct pcap_filehdr
*hdr
, uint32_t magic
,
814 uint32_t linktype
, int32_t thiszone
,
817 bool swapped
= pcap_magic_is_swapped(magic
);
819 /* As *_LL types are just internal, we need to remap pcap
820 * magics to actually valid types.
823 case ORIGINAL_TCPDUMP_MAGIC_LL
:
824 magic
= ORIGINAL_TCPDUMP_MAGIC
;
826 case NSEC_TCPDUMP_MAGIC_LL
:
827 magic
= NSEC_TCPDUMP_MAGIC
;
829 case ___constant_swab32(ORIGINAL_TCPDUMP_MAGIC_LL
):
830 magic
= ___constant_swab32(ORIGINAL_TCPDUMP_MAGIC
);
832 case ___constant_swab32(NSEC_TCPDUMP_MAGIC_LL
):
833 magic
= ___constant_swab32(NSEC_TCPDUMP_MAGIC
);
838 hdr
->version_major
= swapped
? ___constant_swab16(PCAP_VERSION_MAJOR
) : PCAP_VERSION_MAJOR
;
839 hdr
->version_minor
= swapped
? ___constant_swab16(PCAP_VERSION_MINOR
) : PCAP_VERSION_MINOR
;
840 hdr
->thiszone
= swapped
? (int32_t) ___constant_swab32(thiszone
) : thiszone
;
842 hdr
->snaplen
= swapped
? ___constant_swab32(snaplen
) : snaplen
;
843 hdr
->linktype
= swapped
? ___constant_swab32(linktype
) : linktype
;
846 static const bool pcap_supported_linktypes
[LINKTYPE_MAX
] __maybe_unused
= {
847 /* tunX captures from wireshark/tcpdump, non-portable */
848 [101] = true, [102] = true, [103] = true,
849 [LINKTYPE_NULL
] = true,
850 [LINKTYPE_EN10MB
] = true,
851 [LINKTYPE_EN3MB
] = true,
852 [LINKTYPE_AX25
] = true,
853 [LINKTYPE_PRONET
] = true,
854 [LINKTYPE_CHAOS
] = true,
855 [LINKTYPE_IEEE802
] = true,
856 [LINKTYPE_SLIP
] = true,
857 [LINKTYPE_PPP
] = true,
858 [LINKTYPE_FDDI
] = true,
859 [LINKTYPE_ATM_CLIP
] = true,
860 [LINKTYPE_C_HDLC
] = true,
861 [LINKTYPE_IEEE802_11
] = true,
862 [LINKTYPE_IEEE802_11_RADIOTAP
] = true,
863 [LINKTYPE_FRELAY
] = true,
864 [LINKTYPE_ECONET
] = true,
865 [LINKTYPE_ARCNET_LINUX
] = true,
866 [LINKTYPE_LINUX_IRDA
] = true,
867 [LINKTYPE_CAN20B
] = true,
868 [LINKTYPE_IEEE802_15_4_LINUX
] = true,
869 [LINKTYPE_INFINIBAND
] = true,
870 [LINKTYPE_NETLINK
] = true,
871 [LINKTYPE_LINUX_SLL
] = true,
874 static inline void pcap_validate_header(struct pcap_filehdr
*hdr
)
879 pcap_check_magic(hdr
->magic
);
881 linktype
= pcap_magic_is_swapped(hdr
->magic
) ? bswap_32(hdr
->linktype
) : hdr
->linktype
;
882 if (linktype
< LINKTYPE_MAX
)
883 good
= pcap_supported_linktypes
[linktype
];
886 panic("This file has an unsupported pcap link type (%d)!\n", linktype
);
887 if (unlikely(hdr
->version_major
!= PCAP_VERSION_MAJOR
) &&
888 ___constant_swab16(hdr
->version_major
) != PCAP_VERSION_MAJOR
)
889 panic("This file has an invalid pcap major version (must be %d)\n", PCAP_VERSION_MAJOR
);
890 if (unlikely(hdr
->version_minor
!= PCAP_VERSION_MINOR
) &&
891 ___constant_swab16(hdr
->version_minor
) != PCAP_VERSION_MINOR
)
892 panic("This file has an invalid pcap minor version (must be %d)\n", PCAP_VERSION_MINOR
);
894 /* Remap to internal *_LL types in case of LINKTYPE_LINUX_SLL. */
895 if (linktype
== LINKTYPE_LINUX_SLL
|| linktype
== LINKTYPE_NETLINK
) {
896 switch (hdr
->magic
) {
897 case ORIGINAL_TCPDUMP_MAGIC
:
898 hdr
->magic
= ORIGINAL_TCPDUMP_MAGIC_LL
;
900 case NSEC_TCPDUMP_MAGIC
:
901 hdr
->magic
= NSEC_TCPDUMP_MAGIC_LL
;
903 case ___constant_swab32(ORIGINAL_TCPDUMP_MAGIC
):
904 hdr
->magic
= ___constant_swab32(ORIGINAL_TCPDUMP_MAGIC_LL
);
906 case ___constant_swab32(NSEC_TCPDUMP_MAGIC
):
907 hdr
->magic
= ___constant_swab32(NSEC_TCPDUMP_MAGIC_LL
);
913 static int pcap_generic_pull_fhdr(int fd
, uint32_t *magic
,
914 uint32_t *linktype
) __maybe_unused
;
916 static int pcap_generic_pull_fhdr(int fd
, uint32_t *magic
, uint32_t *linktype
)
919 struct pcap_filehdr hdr
;
921 ret
= read(fd
, &hdr
, sizeof(hdr
));
922 if (unlikely(ret
!= sizeof(hdr
)))
925 pcap_validate_header(&hdr
);
928 *linktype
= hdr
.linktype
;
933 static int pcap_generic_push_fhdr(int fd
, uint32_t magic
,
934 uint32_t linktype
) __maybe_unused
;
936 static int pcap_generic_push_fhdr(int fd
, uint32_t magic
, uint32_t linktype
)
939 struct pcap_filehdr hdr
;
941 memset(&hdr
, 0, sizeof(hdr
));
943 pcap_prepare_header(&hdr
, magic
, linktype
, 0, PCAP_DEFAULT_SNAPSHOT_LEN
);
945 ret
= write_or_die(fd
, &hdr
, sizeof(hdr
));
946 if (unlikely(ret
!= sizeof(hdr
)))
947 panic("Failed to write pkt file header!\n");
952 #endif /* PCAP_IO_H */