Beispiel #1
0
static void _sigio_child(ng_tapnet_t *dev)
{
    pid_t parent = _native_pid;
    if ((_sigio_child_pid = real_fork()) == -1) {
        err(EXIT_FAILURE, "sigio_child: fork");
    }
    if (_sigio_child_pid > 0) {
        /* return in parent process */
        return;
    }
    /* watch tap interface and signal parent process if data is
     * available */
    fd_set rfds;
    while (1) {
        FD_ZERO(&rfds);
        FD_SET(dev->tap_fd, &rfds);
        if (real_select(dev->tap_fd + 1, &rfds, NULL, NULL, NULL) == 1) {
            kill(parent, SIGIO);
        }
        else {
            kill(parent, SIGKILL);
            err(EXIT_FAILURE, "osx_sigio_child: select");
        }
        pause();
    }
}
static void _continue_reading(netdev2_tap_t *dev)
{
    /* work around lost signals */
    fd_set rfds;
    struct timeval t;
    memset(&t, 0, sizeof(t));
    FD_ZERO(&rfds);
    FD_SET(dev->tap_fd, &rfds);

    _native_in_syscall++; /* no switching here */

    if (real_select(dev->tap_fd + 1, &rfds, NULL, NULL, &t) == 1) {
        int sig = SIGIO;
        extern int _sig_pipefd[2];
        extern ssize_t (*real_write)(int fd, const void * buf, size_t count);
        real_write(_sig_pipefd[1], &sig, sizeof(int));
        _native_sigpend++;
        DEBUG("netdev2_tap: sigpend++\n");
    }
    else {
        DEBUG("netdev2_tap: native_async_read_continue\n");
        native_async_read_continue(dev->tap_fd);
    }

    _native_in_syscall--;
}
int
select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) 
{
  int retval;

  print_trace ("%*sselect(%d, %p, %p, %p, %p)=...\n", indent, "",
	       n, readfds, writefds, exceptfds, timeout);
  indent+=2;

  /* call the real select function */
  retval = real_select (n, readfds, writefds, exceptfds, timeout);

  indent-=2;
  print_trace ("%*sselect(%d, %p, %p, %p, %p)=%d\n", indent, "", 
	       n, readfds, writefds, exceptfds, timeout, retval);

  return retval;
}
Beispiel #4
0
static int _recv(dev_eth_t *dev_eth, char *buf, int len) {
    dev_eth_tap_t *dev = (dev_eth_tap_t*)dev_eth;

    int nread = real_read(dev->tap_fd, buf, len);
    DEBUG("ng_tapnet: read %d bytes\n", nread);

    if (nread > 0) {
        ng_ethernet_hdr_t *hdr = (ng_ethernet_hdr_t *)buf;
        if (!(dev->promiscous) && !_is_addr_multicast(hdr->dst) &&
            !_is_addr_broadcast(hdr->dst) &&
            (memcmp(hdr->dst, dev->addr, NG_ETHERNET_ADDR_LEN) != 0)) {
            DEBUG("ng_eth_dev: received for %02x:%02x:%02x:%02x:%02x:%02x\n"
                  "That's not me => Dropped\n",
                  hdr->dst[0], hdr->dst[1], hdr->dst[2],
                  hdr->dst[3], hdr->dst[4], hdr->dst[5]);
#ifdef __MACH__
            kill(_sigio_child_pid, SIGCONT);
#endif
            return 0;
        }
        /* work around lost signals */
        fd_set rfds;
        struct timeval t;
        memset(&t, 0, sizeof(t));
        FD_ZERO(&rfds);
        FD_SET(dev->tap_fd, &rfds);

        _native_in_syscall++; /* no switching here */

        if (real_select(dev->tap_fd + 1, &rfds, NULL, NULL, &t) == 1) {
            int sig = SIGIO;
            extern int _sig_pipefd[2];
            extern ssize_t (*real_write)(int fd, const void * buf, size_t count);
            real_write(_sig_pipefd[1], &sig, sizeof(int));
            _native_sigpend++;
            DEBUG("dev_eth_tap: sigpend++\n");
        }
        else {
#ifdef __MACH__
        kill(_sigio_child_pid, SIGCONT);
#endif
        }

        _native_in_syscall--;

        return nread;
    }
    else if (nread == -1) {
        if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
        }
        else {
            err(EXIT_FAILURE, "dev_eth_tap: read");
        }
    }
    else if (nread == 0) {
        DEBUG("_native_handle_tap_input: ignoring null-event");
    }
    else {
        errx(EXIT_FAILURE, "internal error _rx_event");
    }

    return -1;
}