tap.cc (8229:78bf55f23338) tap.cc (12053:014d6270849b)
1/*
2 * Copyright (c) 2003-2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;

--- 16 unchanged lines hidden (view full) ---

25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * Authors: Nathan Binkert
29 */
30
31extern "C" {
32#include <pcap.h>
1/*
2 * Copyright (c) 2003-2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;

--- 16 unchanged lines hidden (view full) ---

25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * Authors: Nathan Binkert
29 */
30
31extern "C" {
32#include <pcap.h>
33
33}
34
35#include <arpa/inet.h>
34}
35
36#include <arpa/inet.h>
37#include <fcntl.h>
38#include <libgen.h>
39#include <netdb.h>
36#include <netinet/in.h>
37#include <netinet/tcp.h>
40#include <netinet/in.h>
41#include <netinet/tcp.h>
42#include <poll.h>
38#include <sys/ioctl.h>
39#include <sys/socket.h>
40#include <sys/types.h>
43#include <sys/ioctl.h>
44#include <sys/socket.h>
45#include <sys/types.h>
41#include <dnet.h>
42#include <fcntl.h>
43#include <libgen.h>
44#include <netdb.h>
45#include <poll.h>
46#include <unistd.h>
47
48#include <cerrno>
49#include <csignal>
46#include <unistd.h>
47
48#include <cerrno>
49#include <csignal>
50#include <cstdio>
51#include <cstdlib>
52#include <cstring>
50#include <list>
51#include <string>
52
53#include <list>
54#include <string>
55
53#include "base/cprintf.hh"
54
55#define panic(arg...) \
56#define panic(arg...) \
56 do { cprintf("Panic: " arg); exit(1); } while (0)
57 do { printf("Panic: " arg); exit(1); } while (0)
57
58
58char *program = "ethertap";
59const char *program = "ethertap";
59void
60usage()
61{
60void
61usage()
62{
62 cprintf(
63 printf(
63 "usage: \n"
64 "\t%s [-b bufsize] [-d] [-f filter] [-p port] [-v] <device> <host>\n"
65 "\t%s [-b bufsize] [-d] [-f filter] [-l] [-p port] [-v] <device>\n",
66 program, program);
67 exit(2);
68}
69
70int verbose = 0;
71#define DPRINTF(args...) do { \
72 if (verbose >= 1) \
64 "usage: \n"
65 "\t%s [-b bufsize] [-d] [-f filter] [-p port] [-v] <device> <host>\n"
66 "\t%s [-b bufsize] [-d] [-f filter] [-l] [-p port] [-v] <device>\n",
67 program, program);
68 exit(2);
69}
70
71int verbose = 0;
72#define DPRINTF(args...) do { \
73 if (verbose >= 1) \
73 cprintf(args); \
74 printf(args); \
74} while (0)
75
76#define DDUMP(args...) do { \
77 if (verbose >= 2) \
78 dump((const u_char *)args); \
79} while (0)
80
81void
82dump(const u_char *data, int len)
83{
84 int c, i, j;
85
86 for (i = 0; i < len; i += 16) {
75} while (0)
76
77#define DDUMP(args...) do { \
78 if (verbose >= 2) \
79 dump((const u_char *)args); \
80} while (0)
81
82void
83dump(const u_char *data, int len)
84{
85 int c, i, j;
86
87 for (i = 0; i < len; i += 16) {
87 cprintf("%08x ", i);
88 printf("%08x ", i);
88 c = len - i;
89 if (c > 16) c = 16;
90
91 for (j = 0; j < c; j++) {
89 c = len - i;
90 if (c > 16) c = 16;
91
92 for (j = 0; j < c; j++) {
92 cprintf("%02x ", data[i + j] & 0xff);
93 printf("%02x ", data[i + j] & 0xff);
93 if ((j & 0xf) == 7 && j > 0)
94 if ((j & 0xf) == 7 && j > 0)
94 cprintf(" ");
95 printf(" ");
95 }
96
97 for (; j < 16; j++)
96 }
97
98 for (; j < 16; j++)
98 cprintf(" ");
99 cprintf(" ");
99 printf(" ");
100 printf(" ");
100
101 for (j = 0; j < c; j++) {
102 int ch = data[i + j] & 0x7f;
101
102 for (j = 0; j < c; j++) {
103 int ch = data[i + j] & 0x7f;
103 cprintf("%c", (char)(isprint(ch) ? ch : ' '));
104 printf("%c", (char)(isprint(ch) ? ch : ' '));
104 }
105
105 }
106
106 cprintf("\n");
107 printf("\n");
107
108 if (c < 16)
109 break;
110 }
111}
112
113bool quit = false;
114void

--- 58 unchanged lines hidden (view full) ---

173void
174Connect(int fd, const std::string &host, int port)
175{
176 struct sockaddr_in sockaddr;
177 if (::inet_aton(host.c_str(), &sockaddr.sin_addr) == 0) {
178 struct hostent *hp;
179 hp = ::gethostbyname(host.c_str());
180 if (!hp)
108
109 if (c < 16)
110 break;
111 }
112}
113
114bool quit = false;
115void

--- 58 unchanged lines hidden (view full) ---

174void
175Connect(int fd, const std::string &host, int port)
176{
177 struct sockaddr_in sockaddr;
178 if (::inet_aton(host.c_str(), &sockaddr.sin_addr) == 0) {
179 struct hostent *hp;
180 hp = ::gethostbyname(host.c_str());
181 if (!hp)
181 panic("Host %s not found\n", host);
182 panic("Host %s not found\n", host.c_str());
182
183 sockaddr.sin_family = hp->h_addrtype;
184 memcpy(&sockaddr.sin_addr, hp->h_addr, hp->h_length);
185 }
186
187 sockaddr.sin_port = htons(port);
188 if (::connect(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr)) != 0)
183
184 sockaddr.sin_family = hp->h_addrtype;
185 memcpy(&sockaddr.sin_addr, hp->h_addr, hp->h_length);
186 }
187
188 sockaddr.sin_port = htons(port);
189 if (::connect(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr)) != 0)
189 panic("could not connect to %s on port %d\n", host, port);
190 panic("could not connect to %s on port %d\n", host.c_str(), port);
190
191
191 DPRINTF("connected to %s on port %d\n", host, port);
192 DPRINTF("connected to %s on port %d\n", host.c_str(), port);
192}
193
194class Ethernet
195{
196 protected:
197 int fd;
198
199 public:

--- 16 unchanged lines hidden (view full) ---

216 virtual bool read(const char *&data, int &len);
217 virtual bool write(const char *data, int len);
218};
219
220class PCap : public Ethernet
221{
222 private:
223 pcap_t *pcap;
193}
194
195class Ethernet
196{
197 protected:
198 int fd;
199
200 public:

--- 16 unchanged lines hidden (view full) ---

217 virtual bool read(const char *&data, int &len);
218 virtual bool write(const char *data, int len);
219};
220
221class PCap : public Ethernet
222{
223 private:
224 pcap_t *pcap;
224 eth_t *ethernet;
225
226 public:
227 PCap(char *device, char *filter = NULL);
228 ~PCap();
229 virtual bool read(const char *&data, int &len);
230 virtual bool write(const char *data, int len);
231};
232

--- 15 unchanged lines hidden (view full) ---

248
249 if (pcap_compile(pcap, &program, filter, 1, netmask) == -1)
250 panic("pcap_compile failed, invalid filter:\n%s\n", filter);
251
252 if (pcap_setfilter(pcap, &program) == -1)
253 panic("pcap_setfilter failed\n");
254 }
255
225
226 public:
227 PCap(char *device, char *filter = NULL);
228 ~PCap();
229 virtual bool read(const char *&data, int &len);
230 virtual bool write(const char *data, int len);
231};
232

--- 15 unchanged lines hidden (view full) ---

248
249 if (pcap_compile(pcap, &program, filter, 1, netmask) == -1)
250 panic("pcap_compile failed, invalid filter:\n%s\n", filter);
251
252 if (pcap_setfilter(pcap, &program) == -1)
253 panic("pcap_setfilter failed\n");
254 }
255
256 ethernet = eth_open(device);
257 if (!ethernet)
258 panic("cannot open the ethernet device for writing\n");
259
260 fd = pcap_fileno(pcap);
261}
262
263PCap::~PCap()
264{
265 pcap_close(pcap);
256 fd = pcap_fileno(pcap);
257}
258
259PCap::~PCap()
260{
261 pcap_close(pcap);
266 eth_close(ethernet);
267}
268
269bool
270PCap::read(const char *&data, int &len)
271{
272 pcap_pkthdr hdr;
273 data = (const char *)pcap_next(pcap, &hdr);
274 if (!data)
275 return false;
276
277 len = hdr.len;
278 return true;
279}
280
281bool
282PCap::write(const char *data, int len)
283{
262}
263
264bool
265PCap::read(const char *&data, int &len)
266{
267 pcap_pkthdr hdr;
268 data = (const char *)pcap_next(pcap, &hdr);
269 if (!data)
270 return false;
271
272 len = hdr.len;
273 return true;
274}
275
276bool
277PCap::write(const char *data, int len)
278{
284 eth_send(ethernet, data, len);
279 return pcap_inject(pcap, data, len) == len;
285}
286
287Tap::Tap(char *device)
288{
289 fd = open(device, O_RDWR, 0);
290 if (fd < 0)
291 panic("could not open %s: %s\n", device, strerror(errno));
292}

--- 37 unchanged lines hidden (view full) ---

330 bool usetap = false;
331 char c;
332 int daemon = false;
333 std::string host;
334 int devfd;
335
336 program = basename(argv[0]);
337
280}
281
282Tap::Tap(char *device)
283{
284 fd = open(device, O_RDWR, 0);
285 if (fd < 0)
286 panic("could not open %s: %s\n", device, strerror(errno));
287}

--- 37 unchanged lines hidden (view full) ---

325 bool usetap = false;
326 char c;
327 int daemon = false;
328 std::string host;
329 int devfd;
330
331 program = basename(argv[0]);
332
338 while ((c = getopt(argc, argv, "b:df:lp:tv")) != -1) {
333 int ret;
334 while ((ret = getopt(argc, argv, "b:df:lp:tv")) != -1) {
335 char c = ret;
339 switch (c) {
340 case 'b':
341 bufsize = atoi(optarg);
342 break;
343 case 'd':
344 daemon = true;
345 break;
346 case 'f':

--- 83 unchanged lines hidden (view full) ---

430 pollfd *client_pfd = listening ? NULL : &pfds[0];
431 int npfds = 2;
432
433 int32_t buffer_offset = 0;
434 int32_t data_len = 0;
435
436 DPRINTF("Begin poll loop\n");
437 while (!quit) {
336 switch (c) {
337 case 'b':
338 bufsize = atoi(optarg);
339 break;
340 case 'd':
341 daemon = true;
342 break;
343 case 'f':

--- 83 unchanged lines hidden (view full) ---

427 pollfd *client_pfd = listening ? NULL : &pfds[0];
428 int npfds = 2;
429
430 int32_t buffer_offset = 0;
431 int32_t data_len = 0;
432
433 DPRINTF("Begin poll loop\n");
434 while (!quit) {
438 int ret = ::poll(pfds, npfds, INFTIM);
435 int ret = ::poll(pfds, npfds, -1);
439 if (ret < 0)
440 continue;
441
442 if (listen_pfd && listen_pfd->revents) {
443 if (listen_pfd->revents & POLLIN) {
444 int fd = Accept(listen_pfd->fd, false);
445 if (client_pfd) {
446 DPRINTF("Connection rejected\n");

--- 92 unchanged lines hidden ---
436 if (ret < 0)
437 continue;
438
439 if (listen_pfd && listen_pfd->revents) {
440 if (listen_pfd->revents & POLLIN) {
441 int fd = Accept(listen_pfd->fd, false);
442 if (client_pfd) {
443 DPRINTF("Connection rejected\n");

--- 92 unchanged lines hidden ---