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>
21 #include "trafgen_dev.h"
23 static int dev_pcap_open(struct dev_io
*dev
, const char *name
, enum dev_io_mode_t mode
)
25 dev
->pcap_magic
= ORIGINAL_TCPDUMP_MAGIC
;
26 dev
->pcap_ops
= pcap_ops
[PCAP_OPS_SG
];
28 if (mode
== DEV_IO_IN
) {
29 if (!strncmp("-", name
, strlen("-"))) {
30 dev
->fd
= dup_or_die(fileno(stdin
));
33 dev
->fd
= open(name
, O_RDONLY
| O_LARGEFILE
| O_NOATIME
);
34 if (dev
->fd
< 0 && errno
== EPERM
)
35 dev
->fd
= open_or_die(name
, O_RDONLY
| O_LARGEFILE
);
38 dev
->pcap_mode
= PCAP_MODE_RD
;
39 } else if (mode
& DEV_IO_OUT
) {
40 if (!strncmp("-", name
, strlen("-"))) {
41 dev
->fd
= dup_or_die(fileno(stdout
));
42 close(fileno(stdout
));
44 dev
->fd
= open_or_die_m(name
, O_RDWR
| O_CREAT
| O_TRUNC
|
45 O_LARGEFILE
, DEFFILEMODE
);
48 dev
->pcap_mode
= PCAP_MODE_WR
;
54 panic("pcap_dev: Cannot open file %s! %s.\n", name
, strerror(errno
));
56 if (dev
->pcap_ops
->init_once_pcap
)
57 dev
->pcap_ops
->init_once_pcap(false);
59 if (mode
== DEV_IO_IN
) {
60 if (dev
->pcap_ops
->pull_fhdr_pcap(dev
->fd
, &dev
->pcap_magic
, &dev
->link_type
))
61 panic("Error reading pcap header!\n");
64 if (dev
->pcap_ops
->prepare_access_pcap
) {
65 if (dev
->pcap_ops
->prepare_access_pcap(dev
->fd
, dev
->pcap_mode
, false))
66 panic("Error prepare reading pcap!\n");
72 static int dev_pcap_read(struct dev_io
*dev
, uint8_t *buf
, size_t len
,
73 struct timespec
*tstamp
)
78 if (dev
->pcap_ops
->read_pcap(dev
->fd
, &phdr
, dev
->pcap_magic
, buf
, len
) <= 0)
81 pkt_len
= pcap_get_length(&phdr
, dev
->pcap_magic
);
85 pcap_get_tstamp(&phdr
, dev
->pcap_magic
, tstamp
);
90 static int dev_pcap_write(struct dev_io
*dev
, const uint8_t *buf
, size_t len
)
96 /* Write PCAP file header only once */
97 if (!dev
->is_initialized
) {
98 if (dev
->pcap_ops
->push_fhdr_pcap(dev
->fd
, dev
->pcap_magic
, dev
->link_type
)) {
99 fprintf(stderr
, "Error writing pcap header!\n");
103 if (dev
->pcap_ops
->prepare_access_pcap
) {
104 if (dev
->pcap_ops
->prepare_access_pcap(dev
->fd
, PCAP_MODE_WR
, true)) {
105 fprintf(stderr
, "Error prepare writing pcap!\n");
110 dev
->is_initialized
= true;
113 bug_on(gettimeofday(&time
, NULL
));
115 phdr
.ppo
.ts
.tv_sec
= time
.tv_sec
;
116 phdr
.ppo
.ts
.tv_usec
= time
.tv_usec
;
117 phdr
.ppo
.caplen
= len
;
120 ret
= dev
->pcap_ops
->write_pcap(dev
->fd
, &phdr
, dev
->pcap_magic
,
121 buf
, pcap_get_length(&phdr
, dev
->pcap_magic
));
123 if (unlikely(ret
!= (int) pcap_get_total_length(&phdr
, dev
->pcap_magic
))) {
124 fprintf(stderr
, "Write error to pcap!\n");
131 static void dev_pcap_close(struct dev_io
*dev
)
133 if (dev
->pcap_mode
== PCAP_MODE_WR
)
134 dev
->pcap_ops
->fsync_pcap(dev
->fd
);
136 if (dev
->pcap_ops
->prepare_close_pcap
)
137 dev
->pcap_ops
->prepare_close_pcap(dev
->fd
, dev
->pcap_mode
);
142 static const struct dev_io_ops dev_pcap_ops
= {
143 .open
= dev_pcap_open
,
144 .read
= dev_pcap_read
,
145 .write
= dev_pcap_write
,
146 .close
= dev_pcap_close
,
149 static int dev_net_open(struct dev_io
*dev
, const char *name
, enum dev_io_mode_t mode
)
151 dev
->ifindex
= __device_ifindex(name
);
152 dev
->dev_type
= device_type(name
);
153 dev
->fd
= pf_socket();
158 static int dev_net_write(struct dev_io
*dev
, const uint8_t *buf
, size_t len
)
160 struct sockaddr_ll saddr
= {
161 .sll_family
= PF_PACKET
,
162 .sll_halen
= ETH_ALEN
,
163 .sll_ifindex
= dev
->ifindex
,
166 return sendto(dev
->fd
, buf
, len
, 0, (struct sockaddr
*) &saddr
, sizeof(saddr
));
169 static int dev_net_set_link_type(struct dev_io
*dev
, int link_type
)
171 if (link_type
!= LINKTYPE_IEEE802_11
&& link_type
!= LINKTYPE_IEEE802_11_RADIOTAP
)
174 dev
->trans
= xstrdup(dev
->name
);
177 enter_rfmon_mac80211(dev
->trans
, &dev
->name
);
178 dev
->ifindex
= __device_ifindex(dev
->name
);
179 dev
->dev_type
= device_type(dev
->name
);
184 static void dev_net_close(struct dev_io
*dev
)
186 if (dev
->link_type
== LINKTYPE_IEEE802_11
|| dev
->link_type
== LINKTYPE_IEEE802_11_RADIOTAP
)
187 leave_rfmon_mac80211(dev
->name
);
192 static const struct dev_io_ops dev_net_ops
= {
193 .open
= dev_net_open
,
194 .write
= dev_net_write
,
195 .set_link_type
= dev_net_set_link_type
,
196 .close
= dev_net_close
,
199 struct dev_io
*dev_io_open(const char *name
, enum dev_io_mode_t mode
)
201 struct dev_io
*dev
= xzmalloc(sizeof(struct dev_io
));
203 if (strstr(name
, ".pcap")) {
204 dev
->name
= xstrdup(name
);
205 dev
->ops
= &dev_pcap_ops
;
206 } else if (device_mtu(name
) > 0) {
207 dev
->name
= xstrndup(name
, IFNAMSIZ
);
208 dev
->ops
= &dev_net_ops
;
210 fprintf(stderr
, "No networking device or pcap file: %s\n", name
);
214 if (dev
->ops
->open
) {
215 if (dev
->ops
->open(dev
, name
, mode
)) {
224 int dev_io_write(struct dev_io
*dev
, const uint8_t *buf
, size_t len
)
230 return dev
->ops
->write(dev
, buf
, len
);
235 int dev_io_read(struct dev_io
*dev
, uint8_t *buf
, size_t len
,
236 struct timespec
*tstamp
)
242 return dev
->ops
->read(dev
, buf
, len
, tstamp
);
247 const char *dev_io_name_get(struct dev_io
*dev
)
252 bool dev_io_is_netdev(struct dev_io
*dev
)
254 return dev
->ops
== &dev_net_ops
;
257 bool dev_io_is_pcap(struct dev_io
*dev
)
259 return dev
->ops
== &dev_pcap_ops
;
262 int dev_io_link_type_set(struct dev_io
*dev
, int link_type
)
264 if (dev
->ops
->set_link_type
) {
265 if (dev
->ops
->set_link_type(dev
, link_type
))
269 dev
->link_type
= link_type
;
273 int dev_io_ifindex_get(struct dev_io
*dev
)
278 int dev_io_fd_get(struct dev_io
*dev
)
283 void dev_io_close(struct dev_io
*dev
)
287 dev
->ops
->close(dev
);