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 <linux/if_packet.h>
22 #define TCPDUMP_MAGIC 0xa1b2c3d4
23 #define ORIGINAL_TCPDUMP_MAGIC TCPDUMP_MAGIC
24 #define NSEC_TCPDUMP_MAGIC 0xa1b23c4d
25 #define KUZNETZOV_TCPDUMP_MAGIC 0xa1b2cd34
26 #define BORKMANN_TCPDUMP_MAGIC 0xa1e2cb12
28 #define PCAP_VERSION_MAJOR 2
29 #define PCAP_VERSION_MINOR 4
30 #define PCAP_DEFAULT_SNAPSHOT_LEN 65535
32 #define PCAP_TSOURCE_SOFTWARE 1
33 #define PCAP_TSOURCE_SYS_HARDWARE 2
34 #define PCAP_TSOURCE_RAW_HARDWARE 3
36 #define LINKTYPE_EN10MB 1 /* Ethernet (10Mb) */
37 #define LINKTYPE_IEEE802_11 105 /* IEEE 802.11 wireless */
41 uint16_t version_major
;
42 uint16_t version_minor
;
54 struct pcap_timeval_ns
{
60 struct pcap_timeval ts
;
65 struct pcap_pkthdr_ns
{
66 struct pcap_timeval_ns ts
;
71 struct pcap_pkthdr_kuz
{
72 struct pcap_timeval ts
;
80 struct pcap_pkthdr_bkm
{
81 struct pcap_timeval_ns ts
;
92 struct pcap_pkthdr ppo
;
93 struct pcap_pkthdr_ns ppn
;
94 struct pcap_pkthdr_kuz ppk
;
95 struct pcap_pkthdr_bkm ppb
;
100 DEFAULT
= ORIGINAL_TCPDUMP_MAGIC
,
101 NSEC
= NSEC_TCPDUMP_MAGIC
,
102 KUZNETZOV
= KUZNETZOV_TCPDUMP_MAGIC
,
103 BORKMANN
= BORKMANN_TCPDUMP_MAGIC
,
105 DEFAULT_SWAPPED
= ___constant_swab32(ORIGINAL_TCPDUMP_MAGIC
),
106 NSEC_SWAPPED
= ___constant_swab32(NSEC_TCPDUMP_MAGIC
),
107 KUZNETZOV_SWAPPED
= ___constant_swab32(KUZNETZOV_TCPDUMP_MAGIC
),
108 BORKMANN_SWAPPED
= ___constant_swab32(BORKMANN_TCPDUMP_MAGIC
),
111 enum pcap_ops_groups
{
122 struct pcap_file_ops
{
123 void (*init_once_pcap
)(void);
124 int (*pull_fhdr_pcap
)(int fd
, uint32_t *magic
, uint32_t *linktype
);
125 int (*push_fhdr_pcap
)(int fd
, uint32_t magic
, uint32_t linktype
);
126 int (*prepare_access_pcap
)(int fd
, enum pcap_mode mode
, bool jumbo
);
127 ssize_t (*write_pcap
)(int fd
, pcap_pkthdr_t
*phdr
, enum pcap_type type
,
128 const uint8_t *packet
, size_t len
);
129 ssize_t (*read_pcap
)(int fd
, pcap_pkthdr_t
*phdr
, enum pcap_type type
,
130 uint8_t *packet
, size_t len
);
131 void (*prepare_close_pcap
)(int fd
, enum pcap_mode mode
);
132 void (*fsync_pcap
)(int fd
);
135 extern const struct pcap_file_ops pcap_rw_ops __maybe_unused
;
136 extern const struct pcap_file_ops pcap_sg_ops __maybe_unused
;
137 extern const struct pcap_file_ops pcap_mm_ops __maybe_unused
;
139 static inline uint16_t tp_to_pcap_tsource(uint32_t status
)
141 if (status
& TP_STATUS_TS_RAW_HARDWARE
)
142 return PCAP_TSOURCE_RAW_HARDWARE
;
143 else if (status
& TP_STATUS_TS_SYS_HARDWARE
)
144 return PCAP_TSOURCE_SYS_HARDWARE
;
145 else if (status
& TP_STATUS_TS_SOFTWARE
)
146 return PCAP_TSOURCE_SOFTWARE
;
151 static inline void pcap_check_magic(uint32_t magic
)
155 case ORIGINAL_TCPDUMP_MAGIC
:
156 case NSEC_TCPDUMP_MAGIC
:
157 case KUZNETZOV_TCPDUMP_MAGIC
:
158 case BORKMANN_TCPDUMP_MAGIC
:
160 case ___constant_swab32(ORIGINAL_TCPDUMP_MAGIC
):
161 case ___constant_swab32(NSEC_TCPDUMP_MAGIC
):
162 case ___constant_swab32(KUZNETZOV_TCPDUMP_MAGIC
):
163 case ___constant_swab32(BORKMANN_TCPDUMP_MAGIC
):
167 panic("This file has not a valid pcap header\n");
171 static inline bool pcap_magic_is_swapped(uint32_t magic
)
173 bool swapped
= false;
176 case ___constant_swab32(ORIGINAL_TCPDUMP_MAGIC
):
177 case ___constant_swab32(NSEC_TCPDUMP_MAGIC
):
178 case ___constant_swab32(KUZNETZOV_TCPDUMP_MAGIC
):
179 case ___constant_swab32(BORKMANN_TCPDUMP_MAGIC
):
186 static inline u32
pcap_get_length(pcap_pkthdr_t
*phdr
, enum pcap_type type
)
189 #define CASE_RET_CAPLEN(what, member, swap) \
191 return (swap ? ___constant_swab32(phdr->member.caplen) : \
194 CASE_RET_CAPLEN(DEFAULT
, ppo
, 0);
195 CASE_RET_CAPLEN(NSEC
, ppn
, 0);
196 CASE_RET_CAPLEN(KUZNETZOV
, ppk
, 0);
197 CASE_RET_CAPLEN(BORKMANN
, ppb
, 0);
199 CASE_RET_CAPLEN(DEFAULT_SWAPPED
, ppo
, 1);
200 CASE_RET_CAPLEN(NSEC_SWAPPED
, ppn
, 1);
201 CASE_RET_CAPLEN(KUZNETZOV_SWAPPED
, ppk
, 1);
202 CASE_RET_CAPLEN(BORKMANN_SWAPPED
, ppb
, 1);
209 static inline void pcap_set_length(pcap_pkthdr_t
*phdr
, enum pcap_type type
, u32 len
)
212 #define CASE_SET_CAPLEN(what, member, swap) \
214 phdr->member.caplen = (swap ? ___constant_swab32(len) : len); \
217 CASE_SET_CAPLEN(DEFAULT
, ppo
, 0);
218 CASE_SET_CAPLEN(NSEC
, ppn
, 0);
219 CASE_SET_CAPLEN(KUZNETZOV
, ppk
, 0);
220 CASE_SET_CAPLEN(BORKMANN
, ppb
, 0);
222 CASE_SET_CAPLEN(DEFAULT_SWAPPED
, ppo
, 1);
223 CASE_SET_CAPLEN(NSEC_SWAPPED
, ppn
, 1);
224 CASE_SET_CAPLEN(KUZNETZOV_SWAPPED
, ppk
, 1);
225 CASE_SET_CAPLEN(BORKMANN_SWAPPED
, ppb
, 1);
232 static inline u32
pcap_get_hdr_length(pcap_pkthdr_t
*phdr
, enum pcap_type type
)
235 #define CASE_RET_HDRLEN(what, member) \
237 return sizeof(phdr->member)
239 CASE_RET_HDRLEN(DEFAULT
, ppo
);
240 CASE_RET_HDRLEN(NSEC
, ppn
);
241 CASE_RET_HDRLEN(KUZNETZOV
, ppk
);
242 CASE_RET_HDRLEN(BORKMANN
, ppb
);
244 CASE_RET_HDRLEN(DEFAULT_SWAPPED
, ppo
);
245 CASE_RET_HDRLEN(NSEC_SWAPPED
, ppn
);
246 CASE_RET_HDRLEN(KUZNETZOV_SWAPPED
, ppk
);
247 CASE_RET_HDRLEN(BORKMANN_SWAPPED
, ppb
);
254 static inline u32
pcap_get_total_length(pcap_pkthdr_t
*phdr
, enum pcap_type type
)
257 #define CASE_RET_TOTLEN(what, member, swap) \
259 return ((swap ? ___constant_swab32(phdr->member.caplen) : \
260 phdr->member.caplen) + sizeof(phdr->member))
262 CASE_RET_TOTLEN(DEFAULT
, ppo
, 0);
263 CASE_RET_TOTLEN(NSEC
, ppn
, 0);
264 CASE_RET_TOTLEN(KUZNETZOV
, ppk
, 0);
265 CASE_RET_TOTLEN(BORKMANN
, ppb
, 0);
267 CASE_RET_TOTLEN(DEFAULT_SWAPPED
, ppo
, 1);
268 CASE_RET_TOTLEN(NSEC_SWAPPED
, ppn
, 1);
269 CASE_RET_TOTLEN(KUZNETZOV_SWAPPED
, ppk
, 1);
270 CASE_RET_TOTLEN(BORKMANN_SWAPPED
, ppb
, 1);
278 __tpacket_hdr_to_pcap_pkthdr(uint32_t sec
, uint32_t nsec
, uint32_t snaplen
,
279 uint32_t len
, uint32_t status
,
280 struct sockaddr_ll
*sll
, pcap_pkthdr_t
*phdr
,
285 phdr
->ppo
.ts
.tv_sec
= sec
;
286 phdr
->ppo
.ts
.tv_usec
= nsec
/ 1000;
287 phdr
->ppo
.caplen
= snaplen
;
291 case DEFAULT_SWAPPED
:
292 phdr
->ppo
.ts
.tv_sec
= ___constant_swab32(sec
);
293 phdr
->ppo
.ts
.tv_usec
= ___constant_swab32(nsec
/ 1000);
294 phdr
->ppo
.caplen
= ___constant_swab32(snaplen
);
295 phdr
->ppo
.len
= ___constant_swab32(len
);
299 phdr
->ppn
.ts
.tv_sec
= sec
;
300 phdr
->ppn
.ts
.tv_nsec
= nsec
;
301 phdr
->ppn
.caplen
= snaplen
;
306 phdr
->ppn
.ts
.tv_sec
= ___constant_swab32(sec
);
307 phdr
->ppn
.ts
.tv_nsec
= ___constant_swab32(nsec
);
308 phdr
->ppn
.caplen
= ___constant_swab32(snaplen
);
309 phdr
->ppn
.len
= ___constant_swab32(len
);
313 phdr
->ppk
.ts
.tv_sec
= sec
;
314 phdr
->ppk
.ts
.tv_usec
= nsec
/ 1000;
315 phdr
->ppk
.caplen
= snaplen
;
317 phdr
->ppk
.ifindex
= sll
->sll_ifindex
;
318 phdr
->ppk
.protocol
= sll
->sll_protocol
;
319 phdr
->ppk
.pkttype
= sll
->sll_pkttype
;
322 case KUZNETZOV_SWAPPED
:
323 phdr
->ppk
.ts
.tv_sec
= ___constant_swab32(sec
);
324 phdr
->ppk
.ts
.tv_usec
= ___constant_swab32(nsec
/ 1000);
325 phdr
->ppk
.caplen
= ___constant_swab32(snaplen
);
326 phdr
->ppk
.len
= ___constant_swab32(len
);
327 phdr
->ppk
.ifindex
= ___constant_swab32(sll
->sll_ifindex
);
328 phdr
->ppk
.protocol
= ___constant_swab16(sll
->sll_protocol
);
329 phdr
->ppk
.pkttype
= sll
->sll_pkttype
;
333 phdr
->ppb
.ts
.tv_sec
= sec
;
334 phdr
->ppb
.ts
.tv_nsec
= nsec
;
335 phdr
->ppb
.caplen
= snaplen
;
337 phdr
->ppb
.tsource
= tp_to_pcap_tsource(status
);
338 phdr
->ppb
.ifindex
= (u16
) sll
->sll_ifindex
;
339 phdr
->ppb
.protocol
= sll
->sll_protocol
;
340 phdr
->ppb
.hatype
= sll
->sll_hatype
;
341 phdr
->ppb
.pkttype
= sll
->sll_pkttype
;
344 case BORKMANN_SWAPPED
:
345 phdr
->ppb
.ts
.tv_sec
= ___constant_swab32(sec
);
346 phdr
->ppb
.ts
.tv_nsec
= ___constant_swab32(nsec
);
347 phdr
->ppb
.caplen
= ___constant_swab32(snaplen
);
348 phdr
->ppb
.len
= ___constant_swab32(len
);
349 phdr
->ppb
.tsource
= ___constant_swab16(tp_to_pcap_tsource(status
));
350 phdr
->ppb
.ifindex
= ___constant_swab16((u16
) sll
->sll_ifindex
);
351 phdr
->ppb
.protocol
= ___constant_swab16(sll
->sll_protocol
);
352 phdr
->ppb
.hatype
= sll
->sll_hatype
;
353 phdr
->ppb
.pkttype
= sll
->sll_pkttype
;
361 /* We need to do this crap here since member offsets are not interleaved,
362 * so hopfully the compiler does his job here. ;-)
365 static inline void tpacket_hdr_to_pcap_pkthdr(struct tpacket2_hdr
*thdr
,
366 struct sockaddr_ll
*sll
,
370 __tpacket_hdr_to_pcap_pkthdr(thdr
->tp_sec
, thdr
->tp_nsec
,
371 thdr
->tp_snaplen
, thdr
->tp_len
,
372 thdr
->tp_status
, sll
, phdr
, type
);
375 static inline void tpacket3_hdr_to_pcap_pkthdr(struct tpacket3_hdr
*thdr
,
376 struct sockaddr_ll
*sll
,
380 __tpacket_hdr_to_pcap_pkthdr(thdr
->tp_sec
, thdr
->tp_nsec
,
381 thdr
->tp_snaplen
, thdr
->tp_len
,
385 static inline void pcap_pkthdr_to_tpacket_hdr(pcap_pkthdr_t
*phdr
,
387 struct tpacket2_hdr
*thdr
,
388 struct sockaddr_ll
*sll
)
392 thdr
->tp_sec
= phdr
->ppo
.ts
.tv_sec
;
393 thdr
->tp_nsec
= phdr
->ppo
.ts
.tv_usec
* 1000;
394 thdr
->tp_snaplen
= phdr
->ppo
.caplen
;
395 thdr
->tp_len
= phdr
->ppo
.len
;
398 case DEFAULT_SWAPPED
:
399 thdr
->tp_sec
= ___constant_swab32(phdr
->ppo
.ts
.tv_sec
);
400 thdr
->tp_nsec
= ___constant_swab32(phdr
->ppo
.ts
.tv_usec
) * 1000;
401 thdr
->tp_snaplen
= ___constant_swab32(phdr
->ppo
.caplen
);
402 thdr
->tp_len
= ___constant_swab32(phdr
->ppo
.len
);
406 thdr
->tp_sec
= phdr
->ppn
.ts
.tv_sec
;
407 thdr
->tp_nsec
= phdr
->ppn
.ts
.tv_nsec
;
408 thdr
->tp_snaplen
= phdr
->ppn
.caplen
;
409 thdr
->tp_len
= phdr
->ppn
.len
;
413 thdr
->tp_sec
= ___constant_swab32(phdr
->ppn
.ts
.tv_sec
);
414 thdr
->tp_nsec
= ___constant_swab32(phdr
->ppn
.ts
.tv_nsec
);
415 thdr
->tp_snaplen
= ___constant_swab32(phdr
->ppn
.caplen
);
416 thdr
->tp_len
= ___constant_swab32(phdr
->ppn
.len
);
420 thdr
->tp_sec
= phdr
->ppk
.ts
.tv_sec
;
421 thdr
->tp_nsec
= phdr
->ppk
.ts
.tv_usec
* 1000;
422 thdr
->tp_snaplen
= phdr
->ppk
.caplen
;
423 thdr
->tp_len
= phdr
->ppk
.len
;
426 case KUZNETZOV_SWAPPED
:
427 thdr
->tp_sec
= ___constant_swab32(phdr
->ppk
.ts
.tv_sec
);
428 thdr
->tp_nsec
= ___constant_swab32(phdr
->ppk
.ts
.tv_usec
) * 1000;
429 thdr
->tp_snaplen
= ___constant_swab32(phdr
->ppk
.caplen
);
430 thdr
->tp_len
= ___constant_swab32(phdr
->ppk
.len
);
434 thdr
->tp_sec
= phdr
->ppb
.ts
.tv_sec
;
435 thdr
->tp_nsec
= phdr
->ppb
.ts
.tv_nsec
;
436 thdr
->tp_snaplen
= phdr
->ppb
.caplen
;
437 thdr
->tp_len
= phdr
->ppb
.len
;
440 case BORKMANN_SWAPPED
:
441 thdr
->tp_sec
= ___constant_swab32(phdr
->ppb
.ts
.tv_sec
);
442 thdr
->tp_nsec
= ___constant_swab32(phdr
->ppb
.ts
.tv_nsec
);
443 thdr
->tp_snaplen
= ___constant_swab32(phdr
->ppb
.caplen
);
444 thdr
->tp_len
= ___constant_swab32(phdr
->ppb
.len
);
452 #define FEATURE_UNKNOWN (0 << 0)
453 #define FEATURE_TIMEVAL_MS (1 << 0)
454 #define FEATURE_TIMEVAL_NS (1 << 1)
455 #define FEATURE_LEN (1 << 2)
456 #define FEATURE_CAPLEN (1 << 3)
457 #define FEATURE_IFINDEX (1 << 4)
458 #define FEATURE_PROTO (1 << 5)
459 #define FEATURE_HATYPE (1 << 6)
460 #define FEATURE_PKTTYPE (1 << 7)
461 #define FEATURE_TSOURCE (1 << 8)
463 struct pcap_magic_type
{
464 const uint32_t magic
;
466 const uint16_t features
;
469 static const struct pcap_magic_type pcap_magic_types
[] __maybe_unused
= {
471 .magic
= ORIGINAL_TCPDUMP_MAGIC
,
472 .desc
= "tcpdump-capable pcap",
473 .features
= FEATURE_TIMEVAL_MS
|
477 .magic
= NSEC_TCPDUMP_MAGIC
,
478 .desc
= "tcpdump-capable pcap with ns resolution",
479 .features
= FEATURE_TIMEVAL_NS
|
483 .magic
= KUZNETZOV_TCPDUMP_MAGIC
,
484 .desc
= "Alexey Kuznetzov's pcap",
485 .features
= FEATURE_TIMEVAL_MS
|
492 .magic
= BORKMANN_TCPDUMP_MAGIC
,
493 .desc
= "netsniff-ng pcap",
494 .features
= FEATURE_TIMEVAL_NS
|
505 static inline void pcap_dump_type_features(void)
509 for (i
= 0; i
< array_size(pcap_magic_types
); ++i
) {
510 printf("%s:\n", pcap_magic_types
[i
].desc
);
511 printf(" magic: 0x%x (swapped: 0x%x)\n",
512 pcap_magic_types
[i
].magic
,
513 ___constant_swab32(pcap_magic_types
[i
].magic
));
514 printf(" features:\n");
516 if (pcap_magic_types
[i
].features
== FEATURE_UNKNOWN
) {
517 printf(" unknown\n");
521 if (pcap_magic_types
[i
].features
& FEATURE_TIMEVAL_MS
)
522 printf(" timeval in us\n");
523 if (pcap_magic_types
[i
].features
& FEATURE_TIMEVAL_NS
)
524 printf(" timeval in ns\n");
525 if (pcap_magic_types
[i
].features
& FEATURE_TSOURCE
)
526 printf(" timestamp source\n");
527 if (pcap_magic_types
[i
].features
& FEATURE_LEN
)
528 printf(" packet length\n");
529 if (pcap_magic_types
[i
].features
& FEATURE_CAPLEN
)
530 printf(" packet cap-length\n");
531 if (pcap_magic_types
[i
].features
& FEATURE_IFINDEX
)
532 printf(" packet ifindex\n");
533 if (pcap_magic_types
[i
].features
& FEATURE_PROTO
)
534 printf(" packet protocol\n");
535 if (pcap_magic_types
[i
].features
& FEATURE_HATYPE
)
536 printf(" hardware type\n");
537 if (pcap_magic_types
[i
].features
& FEATURE_PKTTYPE
)
538 printf(" packet type\n");
542 static const char *pcap_ops_group_to_str
[] __maybe_unused
= {
543 [PCAP_OPS_RW
] = "rw",
544 [PCAP_OPS_SG
] = "sg",
545 [PCAP_OPS_MM
] = "mm",
548 static const struct pcap_file_ops
*pcap_ops
[] __maybe_unused
= {
549 [PCAP_OPS_RW
] = &pcap_rw_ops
,
550 [PCAP_OPS_SG
] = &pcap_sg_ops
,
551 [PCAP_OPS_MM
] = &pcap_mm_ops
,
554 static inline void pcap_prepare_header(struct pcap_filehdr
*hdr
, uint32_t magic
,
555 uint32_t linktype
, int32_t thiszone
,
558 bool swapped
= pcap_magic_is_swapped(magic
);
561 hdr
->version_major
= swapped
? ___constant_swab16(PCAP_VERSION_MAJOR
) : PCAP_VERSION_MAJOR
;
562 hdr
->version_minor
= swapped
? ___constant_swab16(PCAP_VERSION_MINOR
) : PCAP_VERSION_MINOR
;
563 hdr
->thiszone
= swapped
? ___constant_swab32(thiszone
) : thiszone
;
565 hdr
->snaplen
= swapped
? ___constant_swab32(snaplen
) : snaplen
;
566 hdr
->linktype
= swapped
? ___constant_swab32(linktype
) : linktype
;
569 static inline void pcap_validate_header(const struct pcap_filehdr
*hdr
)
571 pcap_check_magic(hdr
->magic
);
573 switch (hdr
->linktype
) {
574 case LINKTYPE_EN10MB
:
575 case LINKTYPE_IEEE802_11
:
576 case ___constant_swab32(LINKTYPE_EN10MB
):
577 case ___constant_swab32(LINKTYPE_IEEE802_11
):
580 panic("This file has not a valid pcap header\n");
583 if (unlikely(hdr
->version_major
!= PCAP_VERSION_MAJOR
) &&
584 ___constant_swab16(hdr
->version_major
) != PCAP_VERSION_MAJOR
)
585 panic("This file has not a valid pcap header\n");
586 if (unlikely(hdr
->version_minor
!= PCAP_VERSION_MINOR
) &&
587 ___constant_swab16(hdr
->version_minor
) != PCAP_VERSION_MINOR
)
588 panic("This file has not a valid pcap header\n");
591 static int pcap_generic_pull_fhdr(int fd
, uint32_t *magic
,
592 uint32_t *linktype
) __maybe_unused
;
594 static int pcap_generic_pull_fhdr(int fd
, uint32_t *magic
, uint32_t *linktype
)
597 struct pcap_filehdr hdr
;
599 ret
= read(fd
, &hdr
, sizeof(hdr
));
600 if (unlikely(ret
!= sizeof(hdr
)))
603 pcap_validate_header(&hdr
);
606 *linktype
= hdr
.linktype
;
611 static int pcap_generic_push_fhdr(int fd
, uint32_t magic
,
612 uint32_t linktype
) __maybe_unused
;
614 static int pcap_generic_push_fhdr(int fd
, uint32_t magic
, uint32_t linktype
)
617 struct pcap_filehdr hdr
;
619 memset(&hdr
, 0, sizeof(hdr
));
621 pcap_prepare_header(&hdr
, magic
, linktype
, 0, PCAP_DEFAULT_SNAPSHOT_LEN
);
623 ret
= write_or_die(fd
, &hdr
, sizeof(hdr
));
624 if (unlikely(ret
!= sizeof(hdr
)))
625 panic("Failed to write pkt file header!\n");
630 #endif /* PCAP_IO_H */