2 * netsniff-ng - the packet sniffing beast
3 * By Daniel Borkmann <daniel@netsniff-ng.org>
4 * Copyright 2009, 2010, 2011 Daniel Borkmann.
5 * Subject to the GPL, version 2.
16 #include "write_or_die.h"
19 static int rw_pcap_pull_file_header(int fd
)
22 struct pcap_filehdr hdr
;
24 ret
= read(fd
, &hdr
, sizeof(hdr
));
25 if (unlikely(ret
!= sizeof(hdr
)))
27 pcap_validate_header_maybe_die(&hdr
);
32 static int rw_pcap_push_file_header(int fd
)
35 struct pcap_filehdr hdr
;
37 memset(&hdr
, 0, sizeof(hdr
));
38 pcap_prepare_header(&hdr
, LINKTYPE_EN10MB
, 0,
39 PCAP_DEFAULT_SNAPSHOT_LEN
);
40 ret
= write_or_die(fd
, &hdr
, sizeof(hdr
));
41 if (unlikely(ret
!= sizeof(hdr
))) {
42 whine("Failed to write pkt file header!\n");
49 static ssize_t
rw_pcap_write_pcap_pkt(int fd
, struct pcap_pkthdr
*hdr
,
50 uint8_t *packet
, size_t len
)
53 ret
= write_or_die(fd
, hdr
, sizeof(*hdr
));
54 if (unlikely(ret
!= sizeof(*hdr
))) {
55 whine("Failed to write pkt header!\n");
58 if (unlikely(hdr
->len
!= len
))
60 ret
= write_or_die(fd
, packet
, hdr
->len
);
61 if (unlikely(ret
!= hdr
->len
)) {
62 whine("Failed to write pkt payload!\n");
65 return sizeof(*hdr
) + hdr
->len
;
68 static ssize_t
rw_pcap_read_pcap_pkt(int fd
, struct pcap_pkthdr
*hdr
,
69 uint8_t *packet
, size_t len
)
72 ret
= read(fd
, hdr
, sizeof(*hdr
));
73 if (unlikely(ret
!= sizeof(*hdr
)))
75 if (unlikely(hdr
->len
> len
))
77 ret
= read(fd
, packet
, hdr
->len
);
78 if (unlikely(ret
!= hdr
->len
))
80 if (unlikely(hdr
->len
== 0))
81 return -EINVAL
; /* Bogus packet */
82 return sizeof(*hdr
) + hdr
->len
;
85 static void rw_pcap_fsync_pcap(int fd
)
90 struct pcap_file_ops rw_pcap_ops __read_mostly
= {
92 .pull_file_header
= rw_pcap_pull_file_header
,
93 .push_file_header
= rw_pcap_push_file_header
,
94 .write_pcap_pkt
= rw_pcap_write_pcap_pkt
,
95 .read_pcap_pkt
= rw_pcap_read_pcap_pkt
,
96 .fsync_pcap
= rw_pcap_fsync_pcap
,
99 int init_rw_pcap(void)
101 return pcap_ops_group_register(&rw_pcap_ops
, PCAP_OPS_RW
);
104 void cleanup_rw_pcap(void)
106 pcap_ops_group_unregister(PCAP_OPS_RW
);