docs: authors: add Doug as minor contr. (thanks)
[netsniff-ng.git] / src / pcap_rw.c
blobbaff0a1129ae46f783d140709627a960dadfaa3e
1 /*
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.
6 */
8 #include <stdio.h>
9 #include <stdint.h>
10 #include <stdlib.h>
11 #include <unistd.h>
12 #include <errno.h>
14 #include "pcap.h"
15 #include "built_in.h"
16 #include "xutils.h"
17 #include "xio.h"
18 #include "die.h"
20 static int pcap_rw_pull_file_header(int fd, uint32_t *linktype)
22 ssize_t ret;
23 struct pcap_filehdr hdr;
25 ret = read(fd, &hdr, sizeof(hdr));
26 if (unlikely(ret != sizeof(hdr)))
27 return -EIO;
29 pcap_validate_header(&hdr);
31 *linktype = hdr.linktype;
33 return 0;
36 static int pcap_rw_push_file_header(int fd, uint32_t linktype)
38 ssize_t ret;
39 struct pcap_filehdr hdr;
41 memset(&hdr, 0, sizeof(hdr));
42 pcap_prepare_header(&hdr, linktype, 0, PCAP_DEFAULT_SNAPSHOT_LEN);
44 ret = write_or_die(fd, &hdr, sizeof(hdr));
45 if (unlikely(ret != sizeof(hdr))) {
46 whine("Failed to write pkt file header!\n");
47 return -EIO;
50 return 0;
53 static ssize_t pcap_rw_write_pcap_pkt(int fd, struct pcap_pkthdr *hdr,
54 uint8_t *packet, size_t len)
56 ssize_t ret = write_or_die(fd, hdr, sizeof(*hdr));
57 if (unlikely(ret != sizeof(*hdr))) {
58 whine("Failed to write pkt header!\n");
59 return -EIO;
62 if (unlikely(hdr->len != len))
63 return -EINVAL;
65 ret = write_or_die(fd, packet, hdr->len);
66 if (unlikely(ret != hdr->len)) {
67 whine("Failed to write pkt payload!\n");
68 return -EIO;
71 return sizeof(*hdr) + hdr->len;
74 static ssize_t pcap_rw_read_pcap_pkt(int fd, struct pcap_pkthdr *hdr,
75 uint8_t *packet, size_t len)
77 ssize_t ret = read(fd, hdr, sizeof(*hdr));
78 if (unlikely(ret != sizeof(*hdr)))
79 return -EIO;
81 if (unlikely(hdr->caplen == 0 || hdr->caplen > len))
82 return -EINVAL; /* Bogus packet */
84 ret = read(fd, packet, hdr->caplen);
85 if (unlikely(ret != hdr->caplen))
86 return -EIO;
88 return sizeof(*hdr) + hdr->caplen;
91 static void pcap_rw_fsync_pcap(int fd)
93 fdatasync(fd);
96 static int pcap_rw_prepare_writing_pcap(int fd)
98 set_ioprio_rt();
99 return 0;
102 static int pcap_rw_prepare_reading_pcap(int fd)
104 set_ioprio_rt();
105 return 0;
108 const struct pcap_file_ops pcap_rw_ops = {
109 .name = "read-write",
110 .pull_file_header = pcap_rw_pull_file_header,
111 .push_file_header = pcap_rw_push_file_header,
112 .write_pcap_pkt = pcap_rw_write_pcap_pkt,
113 .read_pcap_pkt = pcap_rw_read_pcap_pkt,
114 .fsync_pcap = pcap_rw_fsync_pcap,
115 .prepare_writing_pcap = pcap_rw_prepare_writing_pcap,
116 .prepare_reading_pcap = pcap_rw_prepare_reading_pcap,
119 int init_pcap_rw(int jumbo_support)
121 return pcap_ops_group_register(&pcap_rw_ops, PCAP_OPS_RW);
124 void cleanup_pcap_rw(void)
126 pcap_ops_group_unregister(PCAP_OPS_RW);