ethertap.cc (12632:a00c27d2256b) ethertap.cc (12978:3acf5f78d541)
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;

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

401 return write(socket, data, len) == len;
402}
403
404
405#if USE_TUNTAP
406
407EtherTap::EtherTap(const Params *p) : EtherTapBase(p)
408{
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;

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

401 return write(socket, data, len) == len;
402}
403
404
405#if USE_TUNTAP
406
407EtherTap::EtherTap(const Params *p) : EtherTapBase(p)
408{
409 int fd = open(p->tun_clone_device.c_str(), O_RDWR);
409 int fd = open(p->tun_clone_device.c_str(), O_RDWR | O_NONBLOCK);
410 if (fd < 0)
411 panic("Couldn't open %s.\n", p->tun_clone_device);
412
413 struct ifreq ifr;
414 memset(&ifr, 0, sizeof(ifr));
415 ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
416 strncpy(ifr.ifr_name, p->tap_device_name.c_str(), IFNAMSIZ - 1);
417

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

433EtherTap::recvReal(int revent)
434{
435 if (revent & POLLERR)
436 panic("Error polling for tap data.\n");
437
438 if (!(revent & POLLIN))
439 return;
440
410 if (fd < 0)
411 panic("Couldn't open %s.\n", p->tun_clone_device);
412
413 struct ifreq ifr;
414 memset(&ifr, 0, sizeof(ifr));
415 ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
416 strncpy(ifr.ifr_name, p->tap_device_name.c_str(), IFNAMSIZ - 1);
417

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

433EtherTap::recvReal(int revent)
434{
435 if (revent & POLLERR)
436 panic("Error polling for tap data.\n");
437
438 if (!(revent & POLLIN))
439 return;
440
441 ssize_t ret = read(tap, buffer, buflen);
442 if (ret < 0)
443 panic("Failed to read from tap device.\n");
441 ssize_t ret;
442 while ((ret = read(tap, buffer, buflen))) {
443 if (ret < 0) {
444 if (errno == EAGAIN)
445 break;
446 panic("Failed to read from tap device.\n");
447 }
444
448
445 sendSimulated(buffer, ret);
449 sendSimulated(buffer, ret);
450 }
446}
447
448bool
449EtherTap::sendReal(const void *data, size_t len)
450{
451}
452
453bool
454EtherTap::sendReal(const void *data, size_t len)
455{
451 if (write(tap, data, len) != len)
452 panic("Failed to write data to tap device.\n");
456 int n;
457 pollfd pfd[1];
458 pfd->fd = tap;
459 pfd->events = POLLOUT;
460
461 // `tap` is a nonblock fd. Here we try to write until success, and use
462 // poll to make a blocking wait.
463 while ((n = write(tap, data, len)) != len) {
464 if (errno != EAGAIN)
465 panic("Failed to write data to tap device.\n");
466 pfd->revents = 0;
467 int ret = poll(pfd, 1, -1);
468 // timeout is set to inf, we shouldn't get 0 in any case.
469 assert(ret != 0);
470 if (ret == -1 || (ret == 1 && (pfd->revents & POLLERR))) {
471 panic("Failed when polling to write data to tap device.\n");
472 }
473 }
453 return true;
454}
455
456EtherTap *
457EtherTapParams::create()
458{
459 return new EtherTap(this);
460}
461
462#endif
463
464EtherTapStub *
465EtherTapStubParams::create()
466{
467 return new EtherTapStub(this);
468}
474 return true;
475}
476
477EtherTap *
478EtherTapParams::create()
479{
480 return new EtherTap(this);
481}
482
483#endif
484
485EtherTapStub *
486EtherTapStubParams::create()
487{
488 return new EtherTapStub(this);
489}