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 --- |