2 * netsniff-ng - the packet sniffing beast
3 * Copyright 2011 - 2013 Daniel Borkmann <dborkma@tik.ee.ethz.ch>,
4 * Swiss federal institute of technology (ETH Zurich)
5 * Subject to the GPL, version 2.
13 #include <net/ethernet.h>
19 #include "trafgen_dev.h"
21 static int dev_pcap_open(struct dev_io
*dev
, const char *name
, enum dev_io_mode_t mode
)
23 dev
->pcap_magic
= ORIGINAL_TCPDUMP_MAGIC
;
24 dev
->pcap_ops
= pcap_ops
[PCAP_OPS_SG
];
26 if (mode
== DEV_IO_IN
) {
27 if (!strncmp("-", name
, strlen("-"))) {
28 dev
->fd
= dup_or_die(fileno(stdin
));
31 dev
->fd
= open(name
, O_RDONLY
| O_LARGEFILE
| O_NOATIME
);
32 if (dev
->fd
< 0 && errno
== EPERM
)
33 dev
->fd
= open_or_die(name
, O_RDONLY
| O_LARGEFILE
);
36 dev
->pcap_mode
= PCAP_MODE_RD
;
37 } else if (mode
& DEV_IO_OUT
) {
38 if (!strncmp("-", name
, strlen("-"))) {
39 dev
->fd
= dup_or_die(fileno(stdout
));
40 close(fileno(stdout
));
42 dev
->fd
= open_or_die_m(name
, O_RDWR
| O_CREAT
| O_TRUNC
|
43 O_LARGEFILE
, DEFFILEMODE
);
46 dev
->pcap_mode
= PCAP_MODE_WR
;
52 panic("pcap_dev: Cannot open file %s! %s.\n", name
, strerror(errno
));
54 if (dev
->pcap_ops
->init_once_pcap
)
55 dev
->pcap_ops
->init_once_pcap(false);
57 if (mode
== DEV_IO_IN
) {
58 if (dev
->pcap_ops
->pull_fhdr_pcap(dev
->fd
, &dev
->pcap_magic
, &dev
->link_type
))
59 panic("Error reading pcap header!\n");
62 if (dev
->pcap_ops
->prepare_access_pcap
) {
63 if (dev
->pcap_ops
->prepare_access_pcap(dev
->fd
, dev
->pcap_mode
, false))
64 panic("Error prepare reading pcap!\n");
70 static int dev_pcap_read(struct dev_io
*dev
, uint8_t *buf
, size_t len
,
71 struct timespec
*tstamp
)
76 if (dev
->pcap_ops
->read_pcap(dev
->fd
, &phdr
, dev
->pcap_magic
, buf
, len
) <= 0)
79 pkt_len
= pcap_get_length(&phdr
, dev
->pcap_magic
);
83 pcap_get_tstamp(&phdr
, dev
->pcap_magic
, tstamp
);
88 static int dev_pcap_write(struct dev_io
*dev
, const uint8_t *buf
, size_t len
)
94 /* Write PCAP file header only once */
95 if (!dev
->is_initialized
) {
96 if (dev
->pcap_ops
->push_fhdr_pcap(dev
->fd
, dev
->pcap_magic
, dev
->link_type
)) {
97 fprintf(stderr
, "Error writing pcap header!\n");
101 if (dev
->pcap_ops
->prepare_access_pcap
) {
102 if (dev
->pcap_ops
->prepare_access_pcap(dev
->fd
, PCAP_MODE_WR
, true)) {
103 fprintf(stderr
, "Error prepare writing pcap!\n");
108 dev
->is_initialized
= true;
111 bug_on(gettimeofday(&time
, NULL
));
113 phdr
.ppo
.ts
.tv_sec
= time
.tv_sec
;
114 phdr
.ppo
.ts
.tv_usec
= time
.tv_usec
;
115 phdr
.ppo
.caplen
= len
;
118 ret
= dev
->pcap_ops
->write_pcap(dev
->fd
, &phdr
, dev
->pcap_magic
,
119 buf
, pcap_get_length(&phdr
, dev
->pcap_magic
));
121 if (unlikely(ret
!= (int) pcap_get_total_length(&phdr
, dev
->pcap_magic
))) {
122 fprintf(stderr
, "Write error to pcap!\n");
129 static void dev_pcap_close(struct dev_io
*dev
)
131 if (dev
->pcap_mode
== PCAP_MODE_WR
)
132 dev
->pcap_ops
->fsync_pcap(dev
->fd
);
134 if (dev
->pcap_ops
->prepare_close_pcap
)
135 dev
->pcap_ops
->prepare_close_pcap(dev
->fd
, dev
->pcap_mode
);
140 static const struct dev_io_ops dev_pcap_ops
= {
141 .open
= dev_pcap_open
,
142 .read
= dev_pcap_read
,
143 .write
= dev_pcap_write
,
144 .close
= dev_pcap_close
,
147 static int dev_net_open(struct dev_io
*dev
, const char *name
, enum dev_io_mode_t mode
)
149 dev
->ifindex
= __device_ifindex(name
);
150 dev
->dev_type
= device_type(name
);
151 dev
->fd
= pf_socket();
156 static int dev_net_write(struct dev_io
*dev
, const uint8_t *buf
, size_t len
)
158 struct sockaddr_ll saddr
= {
159 .sll_family
= PF_PACKET
,
160 .sll_halen
= ETH_ALEN
,
161 .sll_ifindex
= dev
->ifindex
,
164 return sendto(dev
->fd
, buf
, len
, 0, (struct sockaddr
*) &saddr
, sizeof(saddr
));
167 static const struct dev_io_ops dev_net_ops
= {
168 .open
= dev_net_open
,
169 .write
= dev_net_write
,
172 struct dev_io
*dev_io_open(const char *name
, enum dev_io_mode_t mode
)
174 struct dev_io
*dev
= xzmalloc(sizeof(struct dev_io
));
176 if (strstr(name
, ".pcap")) {
177 dev
->ops
= &dev_pcap_ops
;
178 } else if (device_mtu(name
) > 0) {
179 dev
->ops
= &dev_net_ops
;
181 fprintf(stderr
, "No networking device or pcap file: %s\n", name
);
185 if (dev
->ops
->open
) {
186 if (dev
->ops
->open(dev
, name
, mode
)) {
192 dev
->name
= xstrdup(name
);
196 int dev_io_write(struct dev_io
*dev
, const uint8_t *buf
, size_t len
)
202 return dev
->ops
->write(dev
, buf
, len
);
207 int dev_io_read(struct dev_io
*dev
, uint8_t *buf
, size_t len
,
208 struct timespec
*tstamp
)
214 return dev
->ops
->read(dev
, buf
, len
, tstamp
);
219 const char *dev_io_name_get(struct dev_io
*dev
)
224 bool dev_io_is_netdev(struct dev_io
*dev
)
226 return dev
->ops
== &dev_net_ops
;
229 bool dev_io_is_pcap(struct dev_io
*dev
)
231 return dev
->ops
== &dev_pcap_ops
;
234 void dev_io_link_type_set(struct dev_io
*dev
, int link_type
)
236 dev
->link_type
= link_type
;
239 int dev_io_ifindex_get(struct dev_io
*dev
)
244 int dev_io_fd_get(struct dev_io
*dev
)
249 void dev_io_close(struct dev_io
*dev
)
253 dev
->ops
->close(dev
);