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 LINKTYPE_EN10MB 1 /* Ethernet (10Mb) */
33 #define LINKTYPE_IEEE802_11 105 /* IEEE 802.11 wireless */
37 uint16_t version_major
;
38 uint16_t version_minor
;
50 struct pcap_timeval_ns
{
56 struct pcap_timeval ts
;
61 struct pcap_pkthdr_ns
{
62 struct pcap_timeval_ns ts
;
67 struct pcap_pkthdr_kuz
{
68 struct pcap_timeval ts
;
76 struct pcap_pkthdr_bkm
{
77 struct pcap_timeval_ns ts
;
87 struct pcap_pkthdr ppo
;
88 struct pcap_pkthdr_ns ppn
;
89 struct pcap_pkthdr_kuz ppk
;
90 struct pcap_pkthdr_bkm ppb
;
95 DEFAULT
= ORIGINAL_TCPDUMP_MAGIC
,
96 NSEC
= NSEC_TCPDUMP_MAGIC
,
97 KUZNETZOV
= KUZNETZOV_TCPDUMP_MAGIC
,
98 BORKMANN
= BORKMANN_TCPDUMP_MAGIC
,
100 DEFAULT_SWAPPED
= ___constant_swab32(ORIGINAL_TCPDUMP_MAGIC
),
101 NSEC_SWAPPED
= ___constant_swab32(NSEC_TCPDUMP_MAGIC
),
102 KUZNETZOV_SWAPPED
= ___constant_swab32(KUZNETZOV_TCPDUMP_MAGIC
),
103 BORKMANN_SWAPPED
= ___constant_swab32(BORKMANN_TCPDUMP_MAGIC
),
106 enum pcap_ops_groups
{
117 struct pcap_file_ops
{
118 void (*init_once_pcap
)(void);
119 int (*pull_fhdr_pcap
)(int fd
, uint32_t *magic
, uint32_t *linktype
);
120 int (*push_fhdr_pcap
)(int fd
, uint32_t magic
, uint32_t linktype
);
121 int (*prepare_access_pcap
)(int fd
, enum pcap_mode mode
, bool jumbo
);
122 ssize_t (*write_pcap
)(int fd
, pcap_pkthdr_t
*phdr
, enum pcap_type type
,
123 const uint8_t *packet
, size_t len
);
124 ssize_t (*read_pcap
)(int fd
, pcap_pkthdr_t
*phdr
, enum pcap_type type
,
125 uint8_t *packet
, size_t len
);
126 void (*prepare_close_pcap
)(int fd
, enum pcap_mode mode
);
127 void (*fsync_pcap
)(int fd
);
130 extern const struct pcap_file_ops pcap_rw_ops
;
131 extern const struct pcap_file_ops pcap_sg_ops
;
132 extern const struct pcap_file_ops pcap_mm_ops
;
134 static inline void pcap_check_magic(uint32_t magic
)
138 case ORIGINAL_TCPDUMP_MAGIC
:
139 case NSEC_TCPDUMP_MAGIC
:
140 case KUZNETZOV_TCPDUMP_MAGIC
:
141 case BORKMANN_TCPDUMP_MAGIC
:
143 case ___constant_swab32(ORIGINAL_TCPDUMP_MAGIC
):
144 case ___constant_swab32(NSEC_TCPDUMP_MAGIC
):
145 case ___constant_swab32(KUZNETZOV_TCPDUMP_MAGIC
):
146 case ___constant_swab32(BORKMANN_TCPDUMP_MAGIC
):
150 panic("This file has not a valid pcap header\n");
154 static inline bool pcap_magic_is_swapped(uint32_t magic
)
156 bool swapped
= false;
159 case ___constant_swab32(ORIGINAL_TCPDUMP_MAGIC
):
160 case ___constant_swab32(NSEC_TCPDUMP_MAGIC
):
161 case ___constant_swab32(KUZNETZOV_TCPDUMP_MAGIC
):
162 case ___constant_swab32(BORKMANN_TCPDUMP_MAGIC
):
169 static inline u32
pcap_get_length(pcap_pkthdr_t
*phdr
, enum pcap_type type
)
172 #define CASE_RET_CAPLEN(what, member, swap) \
174 return (swap ? ___constant_swab32(phdr->member.caplen) : \
177 CASE_RET_CAPLEN(DEFAULT
, ppo
, 0);
178 CASE_RET_CAPLEN(NSEC
, ppn
, 0);
179 CASE_RET_CAPLEN(KUZNETZOV
, ppk
, 0);
180 CASE_RET_CAPLEN(BORKMANN
, ppb
, 0);
182 CASE_RET_CAPLEN(DEFAULT_SWAPPED
, ppo
, 1);
183 CASE_RET_CAPLEN(NSEC_SWAPPED
, ppn
, 1);
184 CASE_RET_CAPLEN(KUZNETZOV_SWAPPED
, ppk
, 1);
185 CASE_RET_CAPLEN(BORKMANN_SWAPPED
, ppb
, 1);
192 static inline void pcap_set_length(pcap_pkthdr_t
*phdr
, enum pcap_type type
, u32 len
)
195 #define CASE_SET_CAPLEN(what, member, swap) \
197 phdr->member.caplen = (swap ? ___constant_swab32(len) : len); \
200 CASE_SET_CAPLEN(DEFAULT
, ppo
, 0);
201 CASE_SET_CAPLEN(NSEC
, ppn
, 0);
202 CASE_SET_CAPLEN(KUZNETZOV
, ppk
, 0);
203 CASE_SET_CAPLEN(BORKMANN
, ppb
, 0);
205 CASE_SET_CAPLEN(DEFAULT_SWAPPED
, ppo
, 1);
206 CASE_SET_CAPLEN(NSEC_SWAPPED
, ppn
, 1);
207 CASE_SET_CAPLEN(KUZNETZOV_SWAPPED
, ppk
, 1);
208 CASE_SET_CAPLEN(BORKMANN_SWAPPED
, ppb
, 1);
215 static inline u32
pcap_get_hdr_length(pcap_pkthdr_t
*phdr
, enum pcap_type type
)
218 #define CASE_RET_HDRLEN(what, member) \
220 return sizeof(phdr->member)
222 CASE_RET_HDRLEN(DEFAULT
, ppo
);
223 CASE_RET_HDRLEN(NSEC
, ppn
);
224 CASE_RET_HDRLEN(KUZNETZOV
, ppk
);
225 CASE_RET_HDRLEN(BORKMANN
, ppb
);
227 CASE_RET_HDRLEN(DEFAULT_SWAPPED
, ppo
);
228 CASE_RET_HDRLEN(NSEC_SWAPPED
, ppn
);
229 CASE_RET_HDRLEN(KUZNETZOV_SWAPPED
, ppk
);
230 CASE_RET_HDRLEN(BORKMANN_SWAPPED
, ppb
);
237 static inline u32
pcap_get_total_length(pcap_pkthdr_t
*phdr
, enum pcap_type type
)
240 #define CASE_RET_TOTLEN(what, member, swap) \
242 return ((swap ? ___constant_swab32(phdr->member.caplen) : \
243 phdr->member.caplen) + sizeof(phdr->member))
245 CASE_RET_TOTLEN(DEFAULT
, ppo
, 0);
246 CASE_RET_TOTLEN(NSEC
, ppn
, 0);
247 CASE_RET_TOTLEN(KUZNETZOV
, ppk
, 0);
248 CASE_RET_TOTLEN(BORKMANN
, ppb
, 0);
250 CASE_RET_TOTLEN(DEFAULT_SWAPPED
, ppo
, 1);
251 CASE_RET_TOTLEN(NSEC_SWAPPED
, ppn
, 1);
252 CASE_RET_TOTLEN(KUZNETZOV_SWAPPED
, ppk
, 1);
253 CASE_RET_TOTLEN(BORKMANN_SWAPPED
, ppb
, 1);
260 static inline void tpacket_hdr_to_pcap_pkthdr(struct tpacket2_hdr
*thdr
,
261 struct sockaddr_ll
*sll
,
267 phdr
->ppo
.ts
.tv_sec
= thdr
->tp_sec
;
268 phdr
->ppo
.ts
.tv_usec
= thdr
->tp_nsec
/ 1000;
269 phdr
->ppo
.caplen
= thdr
->tp_snaplen
;
270 phdr
->ppo
.len
= thdr
->tp_len
;
273 case DEFAULT_SWAPPED
:
274 phdr
->ppo
.ts
.tv_sec
= ___constant_swab32(thdr
->tp_sec
);
275 phdr
->ppo
.ts
.tv_usec
= ___constant_swab32(thdr
->tp_nsec
/ 1000);
276 phdr
->ppo
.caplen
= ___constant_swab32(thdr
->tp_snaplen
);
277 phdr
->ppo
.len
= ___constant_swab32(thdr
->tp_len
);
281 phdr
->ppn
.ts
.tv_sec
= thdr
->tp_sec
;
282 phdr
->ppn
.ts
.tv_nsec
= thdr
->tp_nsec
;
283 phdr
->ppn
.caplen
= thdr
->tp_snaplen
;
284 phdr
->ppn
.len
= thdr
->tp_len
;
288 phdr
->ppn
.ts
.tv_sec
= ___constant_swab32(thdr
->tp_sec
);
289 phdr
->ppn
.ts
.tv_nsec
= ___constant_swab32(thdr
->tp_nsec
);
290 phdr
->ppn
.caplen
= ___constant_swab32(thdr
->tp_snaplen
);
291 phdr
->ppn
.len
= ___constant_swab32(thdr
->tp_len
);
295 phdr
->ppk
.ts
.tv_sec
= thdr
->tp_sec
;
296 phdr
->ppk
.ts
.tv_usec
= thdr
->tp_nsec
/ 1000;
297 phdr
->ppk
.caplen
= thdr
->tp_snaplen
;
298 phdr
->ppk
.len
= thdr
->tp_len
;
299 phdr
->ppk
.ifindex
= sll
->sll_ifindex
;
300 phdr
->ppk
.protocol
= sll
->sll_protocol
;
301 phdr
->ppk
.pkttype
= sll
->sll_pkttype
;
304 case KUZNETZOV_SWAPPED
:
305 phdr
->ppk
.ts
.tv_sec
= ___constant_swab32(thdr
->tp_sec
);
306 phdr
->ppk
.ts
.tv_usec
= ___constant_swab32(thdr
->tp_nsec
/ 1000);
307 phdr
->ppk
.caplen
= ___constant_swab32(thdr
->tp_snaplen
);
308 phdr
->ppk
.len
= ___constant_swab32(thdr
->tp_len
);
309 phdr
->ppk
.ifindex
= ___constant_swab32((u32
) sll
->sll_ifindex
);
310 phdr
->ppk
.protocol
= ___constant_swab16(sll
->sll_protocol
);
311 phdr
->ppk
.pkttype
= sll
->sll_pkttype
;
315 phdr
->ppb
.ts
.tv_sec
= thdr
->tp_sec
;
316 phdr
->ppb
.ts
.tv_nsec
= thdr
->tp_nsec
;
317 phdr
->ppb
.caplen
= thdr
->tp_snaplen
;
318 phdr
->ppb
.len
= thdr
->tp_len
;
319 phdr
->ppb
.ifindex
= (u32
) sll
->sll_ifindex
;
320 phdr
->ppb
.protocol
= sll
->sll_protocol
;
321 phdr
->ppb
.hatype
= sll
->sll_hatype
;
322 phdr
->ppb
.pkttype
= sll
->sll_pkttype
;
325 case BORKMANN_SWAPPED
:
326 phdr
->ppb
.ts
.tv_sec
= ___constant_swab32(thdr
->tp_sec
);
327 phdr
->ppb
.ts
.tv_nsec
= ___constant_swab32(thdr
->tp_nsec
);
328 phdr
->ppb
.caplen
= ___constant_swab32(thdr
->tp_snaplen
);
329 phdr
->ppb
.len
= ___constant_swab32(thdr
->tp_len
);
330 phdr
->ppb
.ifindex
= ___constant_swab32((u32
) sll
->sll_ifindex
);
331 phdr
->ppb
.protocol
= ___constant_swab16(sll
->sll_protocol
);
332 phdr
->ppb
.hatype
= sll
->sll_hatype
;
333 phdr
->ppb
.pkttype
= sll
->sll_pkttype
;
341 static inline void pcap_pkthdr_to_tpacket_hdr(pcap_pkthdr_t
*phdr
,
343 struct tpacket2_hdr
*thdr
,
344 struct sockaddr_ll
*sll
)
348 thdr
->tp_sec
= phdr
->ppo
.ts
.tv_sec
;
349 thdr
->tp_nsec
= phdr
->ppo
.ts
.tv_usec
* 1000;
350 thdr
->tp_snaplen
= phdr
->ppo
.caplen
;
351 thdr
->tp_len
= phdr
->ppo
.len
;
354 case DEFAULT_SWAPPED
:
355 thdr
->tp_sec
= ___constant_swab32(phdr
->ppo
.ts
.tv_sec
);
356 thdr
->tp_nsec
= ___constant_swab32(phdr
->ppo
.ts
.tv_usec
) * 1000;
357 thdr
->tp_snaplen
= ___constant_swab32(phdr
->ppo
.caplen
);
358 thdr
->tp_len
= ___constant_swab32(phdr
->ppo
.len
);
362 thdr
->tp_sec
= phdr
->ppn
.ts
.tv_sec
;
363 thdr
->tp_nsec
= phdr
->ppn
.ts
.tv_nsec
;
364 thdr
->tp_snaplen
= phdr
->ppn
.caplen
;
365 thdr
->tp_len
= phdr
->ppn
.len
;
369 thdr
->tp_sec
= ___constant_swab32(phdr
->ppn
.ts
.tv_sec
);
370 thdr
->tp_nsec
= ___constant_swab32(phdr
->ppn
.ts
.tv_nsec
);
371 thdr
->tp_snaplen
= ___constant_swab32(phdr
->ppn
.caplen
);
372 thdr
->tp_len
= ___constant_swab32(phdr
->ppn
.len
);
376 thdr
->tp_sec
= phdr
->ppk
.ts
.tv_sec
;
377 thdr
->tp_nsec
= phdr
->ppk
.ts
.tv_usec
* 1000;
378 thdr
->tp_snaplen
= phdr
->ppk
.caplen
;
379 thdr
->tp_len
= phdr
->ppk
.len
;
382 case KUZNETZOV_SWAPPED
:
383 thdr
->tp_sec
= ___constant_swab32(phdr
->ppk
.ts
.tv_sec
);
384 thdr
->tp_nsec
= ___constant_swab32(phdr
->ppk
.ts
.tv_usec
) * 1000;
385 thdr
->tp_snaplen
= ___constant_swab32(phdr
->ppk
.caplen
);
386 thdr
->tp_len
= ___constant_swab32(phdr
->ppk
.len
);
390 thdr
->tp_sec
= phdr
->ppb
.ts
.tv_sec
;
391 thdr
->tp_nsec
= phdr
->ppb
.ts
.tv_nsec
;
392 thdr
->tp_snaplen
= phdr
->ppb
.caplen
;
393 thdr
->tp_len
= phdr
->ppb
.len
;
396 case BORKMANN_SWAPPED
:
397 thdr
->tp_sec
= ___constant_swab32(phdr
->ppb
.ts
.tv_sec
);
398 thdr
->tp_nsec
= ___constant_swab32(phdr
->ppb
.ts
.tv_nsec
);
399 thdr
->tp_snaplen
= ___constant_swab32(phdr
->ppb
.caplen
);
400 thdr
->tp_len
= ___constant_swab32(phdr
->ppb
.len
);
408 #define FEATURE_UNKNOWN (0 << 0)
409 #define FEATURE_TIMEVAL_MS (1 << 0)
410 #define FEATURE_TIMEVAL_NS (1 << 1)
411 #define FEATURE_LEN (1 << 2)
412 #define FEATURE_CAPLEN (1 << 3)
413 #define FEATURE_IFINDEX (1 << 4)
414 #define FEATURE_PROTO (1 << 5)
415 #define FEATURE_HATYPE (1 << 6)
416 #define FEATURE_PKTTYPE (1 << 7)
418 struct pcap_magic_type
{
419 const uint32_t magic
;
421 const uint16_t features
;
424 static const struct pcap_magic_type pcap_magic_types
[] __maybe_unused
= {
426 .magic
= ORIGINAL_TCPDUMP_MAGIC
,
427 .desc
= "tcpdump-capable pcap",
428 .features
= FEATURE_TIMEVAL_MS
|
432 .magic
= NSEC_TCPDUMP_MAGIC
,
433 .desc
= "tcpdump-capable pcap with ns resolution",
434 .features
= FEATURE_TIMEVAL_NS
|
438 .magic
= KUZNETZOV_TCPDUMP_MAGIC
,
439 .desc
= "Alexey Kuznetzov's pcap",
440 .features
= FEATURE_TIMEVAL_MS
|
447 .magic
= BORKMANN_TCPDUMP_MAGIC
,
448 .desc
= "netsniff-ng pcap",
449 .features
= FEATURE_TIMEVAL_NS
|
459 static inline void pcap_dump_type_features(void)
463 for (i
= 0; i
< array_size(pcap_magic_types
); ++i
) {
464 printf("%s:\n", pcap_magic_types
[i
].desc
);
465 printf(" magic: 0x%x (swapped: 0x%x)\n",
466 pcap_magic_types
[i
].magic
,
467 ___constant_swab32(pcap_magic_types
[i
].magic
));
468 printf(" features:\n");
470 if (pcap_magic_types
[i
].features
== FEATURE_UNKNOWN
) {
471 printf(" unknown\n");
475 if (pcap_magic_types
[i
].features
& FEATURE_TIMEVAL_MS
)
476 printf(" timeval in us\n");
477 if (pcap_magic_types
[i
].features
& FEATURE_TIMEVAL_NS
)
478 printf(" timeval in ns\n");
479 if (pcap_magic_types
[i
].features
& FEATURE_LEN
)
480 printf(" packet length\n");
481 if (pcap_magic_types
[i
].features
& FEATURE_CAPLEN
)
482 printf(" packet cap-length\n");
483 if (pcap_magic_types
[i
].features
& FEATURE_IFINDEX
)
484 printf(" packet ifindex\n");
485 if (pcap_magic_types
[i
].features
& FEATURE_PROTO
)
486 printf(" packet protocol\n");
487 if (pcap_magic_types
[i
].features
& FEATURE_HATYPE
)
488 printf(" hardware type\n");
489 if (pcap_magic_types
[i
].features
& FEATURE_PKTTYPE
)
490 printf(" packet type\n");
494 static const char *pcap_ops_group_to_str
[] __maybe_unused
= {
495 [PCAP_OPS_RW
] = "rw",
496 [PCAP_OPS_SG
] = "sg",
497 [PCAP_OPS_MM
] = "mm",
500 static const struct pcap_file_ops
*pcap_ops
[] __maybe_unused
= {
501 [PCAP_OPS_RW
] = &pcap_rw_ops
,
502 [PCAP_OPS_SG
] = &pcap_sg_ops
,
503 [PCAP_OPS_MM
] = &pcap_mm_ops
,
506 static inline void pcap_prepare_header(struct pcap_filehdr
*hdr
, uint32_t magic
,
507 uint32_t linktype
, int32_t thiszone
,
510 bool swapped
= pcap_magic_is_swapped(magic
);
513 hdr
->version_major
= swapped
? ___constant_swab16(PCAP_VERSION_MAJOR
) : PCAP_VERSION_MAJOR
;
514 hdr
->version_minor
= swapped
? ___constant_swab16(PCAP_VERSION_MINOR
) : PCAP_VERSION_MINOR
;
515 hdr
->thiszone
= swapped
? ___constant_swab32(thiszone
) : thiszone
;
517 hdr
->snaplen
= swapped
? ___constant_swab32(snaplen
) : snaplen
;
518 hdr
->linktype
= swapped
? ___constant_swab32(linktype
) : linktype
;
521 static inline void pcap_validate_header(const struct pcap_filehdr
*hdr
)
523 pcap_check_magic(hdr
->magic
);
525 switch (hdr
->linktype
) {
526 case LINKTYPE_EN10MB
:
527 case LINKTYPE_IEEE802_11
:
528 case ___constant_swab32(LINKTYPE_EN10MB
):
529 case ___constant_swab32(LINKTYPE_IEEE802_11
):
532 panic("This file has not a valid pcap header\n");
535 if (unlikely(hdr
->version_major
!= PCAP_VERSION_MAJOR
) &&
536 ___constant_swab16(hdr
->version_major
) != PCAP_VERSION_MAJOR
)
537 panic("This file has not a valid pcap header\n");
538 if (unlikely(hdr
->version_minor
!= PCAP_VERSION_MINOR
) &&
539 ___constant_swab16(hdr
->version_minor
) != PCAP_VERSION_MINOR
)
540 panic("This file has not a valid pcap header\n");
543 static int pcap_generic_pull_fhdr(int fd
, uint32_t *magic
,
544 uint32_t *linktype
) __maybe_unused
;
546 static int pcap_generic_pull_fhdr(int fd
, uint32_t *magic
, uint32_t *linktype
)
549 struct pcap_filehdr hdr
;
551 ret
= read(fd
, &hdr
, sizeof(hdr
));
552 if (unlikely(ret
!= sizeof(hdr
)))
555 pcap_validate_header(&hdr
);
558 *linktype
= hdr
.linktype
;
563 static int pcap_generic_push_fhdr(int fd
, uint32_t magic
,
564 uint32_t linktype
) __maybe_unused
;
566 static int pcap_generic_push_fhdr(int fd
, uint32_t magic
, uint32_t linktype
)
569 struct pcap_filehdr hdr
;
571 memset(&hdr
, 0, sizeof(hdr
));
573 pcap_prepare_header(&hdr
, magic
, linktype
, 0, PCAP_DEFAULT_SNAPSHOT_LEN
);
575 ret
= write_or_die(fd
, &hdr
, sizeof(hdr
));
576 if (unlikely(ret
!= sizeof(hdr
)))
577 panic("Failed to write pkt file header!\n");
582 #endif /* PCAP_IO_H */