ifpps: Rename cpu number parameter to stats_top()
[netsniff-ng.git] / pcap_io.h
blob773986851a9ead62f0769bc9dcc7279c48748709
1 /*
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.
6 */
8 #ifndef PCAP_IO_H
9 #define PCAP_IO_H
11 #include <unistd.h>
12 #include <stdint.h>
13 #include <stdbool.h>
14 #include <errno.h>
15 #include <sys/time.h>
16 #include <linux/if_packet.h>
18 #include "built_in.h"
19 #include "die.h"
20 #include "ioops.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 */
39 struct pcap_filehdr {
40 uint32_t magic;
41 uint16_t version_major;
42 uint16_t version_minor;
43 int32_t thiszone;
44 uint32_t sigfigs;
45 uint32_t snaplen;
46 uint32_t linktype;
49 struct pcap_timeval {
50 int32_t tv_sec;
51 int32_t tv_usec;
54 struct pcap_timeval_ns {
55 int32_t tv_sec;
56 int32_t tv_nsec;
59 struct pcap_pkthdr {
60 struct pcap_timeval ts;
61 uint32_t caplen;
62 uint32_t len;
65 struct pcap_pkthdr_ns {
66 struct pcap_timeval_ns ts;
67 uint32_t caplen;
68 uint32_t len;
71 struct pcap_pkthdr_kuz {
72 struct pcap_timeval ts;
73 uint32_t caplen;
74 uint32_t len;
75 uint32_t ifindex;
76 uint16_t protocol;
77 uint8_t pkttype;
80 struct pcap_pkthdr_bkm {
81 struct pcap_timeval_ns ts;
82 uint32_t caplen;
83 uint32_t len;
84 uint16_t tsource;
85 uint16_t ifindex;
86 uint16_t protocol;
87 uint8_t hatype;
88 uint8_t pkttype;
91 typedef union {
92 struct pcap_pkthdr ppo;
93 struct pcap_pkthdr_ns ppn;
94 struct pcap_pkthdr_kuz ppk;
95 struct pcap_pkthdr_bkm ppb;
96 uint8_t raw;
97 } pcap_pkthdr_t;
99 enum pcap_type {
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 {
112 PCAP_OPS_RW = 0,
113 PCAP_OPS_SG,
114 PCAP_OPS_MM,
117 enum pcap_mode {
118 PCAP_MODE_RD = 0,
119 PCAP_MODE_WR,
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;
147 else
148 return 0;
151 static inline void pcap_check_magic(uint32_t magic)
153 switch (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):
164 break;
166 default:
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;
175 switch (magic) {
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):
180 swapped = true;
183 return swapped;
186 static inline u32 pcap_get_length(pcap_pkthdr_t *phdr, enum pcap_type type)
188 switch (type) {
189 #define CASE_RET_CAPLEN(what, member, swap) \
190 case (what): \
191 return (swap ? ___constant_swab32(phdr->member.caplen) : \
192 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);
204 default:
205 bug();
209 static inline void pcap_set_length(pcap_pkthdr_t *phdr, enum pcap_type type, u32 len)
211 switch (type) {
212 #define CASE_SET_CAPLEN(what, member, swap) \
213 case (what): \
214 phdr->member.caplen = (swap ? ___constant_swab32(len) : len); \
215 break
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);
227 default:
228 bug();
232 static inline u32 pcap_get_hdr_length(pcap_pkthdr_t *phdr, enum pcap_type type)
234 switch (type) {
235 #define CASE_RET_HDRLEN(what, member) \
236 case (what): \
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);
249 default:
250 bug();
254 static inline u32 pcap_get_total_length(pcap_pkthdr_t *phdr, enum pcap_type type)
256 switch (type) {
257 #define CASE_RET_TOTLEN(what, member, swap) \
258 case (what): \
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);
272 default:
273 bug();
277 static inline void
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,
281 enum pcap_type type)
283 switch (type) {
284 case DEFAULT:
285 phdr->ppo.ts.tv_sec = sec;
286 phdr->ppo.ts.tv_usec = nsec / 1000;
287 phdr->ppo.caplen = snaplen;
288 phdr->ppo.len = len;
289 break;
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);
296 break;
298 case NSEC:
299 phdr->ppn.ts.tv_sec = sec;
300 phdr->ppn.ts.tv_nsec = nsec;
301 phdr->ppn.caplen = snaplen;
302 phdr->ppn.len = len;
303 break;
305 case NSEC_SWAPPED:
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);
310 break;
312 case KUZNETZOV:
313 phdr->ppk.ts.tv_sec = sec;
314 phdr->ppk.ts.tv_usec = nsec / 1000;
315 phdr->ppk.caplen = snaplen;
316 phdr->ppk.len = len;
317 phdr->ppk.ifindex = sll->sll_ifindex;
318 phdr->ppk.protocol = sll->sll_protocol;
319 phdr->ppk.pkttype = sll->sll_pkttype;
320 break;
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;
330 break;
332 case BORKMANN:
333 phdr->ppb.ts.tv_sec = sec;
334 phdr->ppb.ts.tv_nsec = nsec;
335 phdr->ppb.caplen = snaplen;
336 phdr->ppb.len = len;
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;
342 break;
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;
354 break;
356 default:
357 bug();
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,
367 pcap_pkthdr_t *phdr,
368 enum pcap_type type)
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,
377 pcap_pkthdr_t *phdr,
378 enum pcap_type type)
380 __tpacket_hdr_to_pcap_pkthdr(thdr->tp_sec, thdr->tp_nsec,
381 thdr->tp_snaplen, thdr->tp_len,
382 0, sll, phdr, type);
385 static inline void pcap_pkthdr_to_tpacket_hdr(pcap_pkthdr_t *phdr,
386 enum pcap_type type,
387 struct tpacket2_hdr *thdr,
388 struct sockaddr_ll *sll)
390 switch (type) {
391 case DEFAULT:
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;
396 break;
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);
403 break;
405 case NSEC:
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;
410 break;
412 case NSEC_SWAPPED:
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);
417 break;
419 case KUZNETZOV:
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;
424 break;
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);
431 break;
433 case BORKMANN:
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;
438 break;
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);
445 break;
447 default:
448 bug();
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;
465 const char *desc;
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 |
474 FEATURE_LEN |
475 FEATURE_CAPLEN,
476 }, {
477 .magic = NSEC_TCPDUMP_MAGIC,
478 .desc = "tcpdump-capable pcap with ns resolution",
479 .features = FEATURE_TIMEVAL_NS |
480 FEATURE_LEN |
481 FEATURE_CAPLEN,
482 }, {
483 .magic = KUZNETZOV_TCPDUMP_MAGIC,
484 .desc = "Alexey Kuznetzov's pcap",
485 .features = FEATURE_TIMEVAL_MS |
486 FEATURE_LEN |
487 FEATURE_CAPLEN |
488 FEATURE_IFINDEX |
489 FEATURE_PROTO |
490 FEATURE_PKTTYPE,
491 }, {
492 .magic = BORKMANN_TCPDUMP_MAGIC,
493 .desc = "netsniff-ng pcap",
494 .features = FEATURE_TIMEVAL_NS |
495 FEATURE_LEN |
496 FEATURE_CAPLEN |
497 FEATURE_TSOURCE |
498 FEATURE_IFINDEX |
499 FEATURE_PROTO |
500 FEATURE_HATYPE |
501 FEATURE_PKTTYPE,
505 static inline void pcap_dump_type_features(void)
507 int i;
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");
518 continue;
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,
556 uint32_t snaplen)
558 bool swapped = pcap_magic_is_swapped(magic);
560 hdr->magic = 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;
564 hdr->sigfigs = 0;
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):
578 break;
579 default:
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)
596 ssize_t ret;
597 struct pcap_filehdr hdr;
599 ret = read(fd, &hdr, sizeof(hdr));
600 if (unlikely(ret != sizeof(hdr)))
601 return -EIO;
603 pcap_validate_header(&hdr);
605 *magic = hdr.magic;
606 *linktype = hdr.linktype;
608 return 0;
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)
616 ssize_t ret;
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");
627 return 0;
630 #endif /* PCAP_IO_H */