Example #1
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;
}
static int _recv(netdev2_t *netdev2, void *buf, size_t len, void *info)
{
    netdev2_tap_t *dev = (netdev2_tap_t*)netdev2;
    (void)info;

    if (!buf) {
        if (len > 0) {
            /* no memory available in pktbuf, discarding the frame */
            DEBUG("netdev2_tap: discarding the frame\n");

            /* repeating `real_read` for small size on tap device results in
             * freeze for some reason. Using a large buffer for now. */
            /*
            uint8_t buf[4];
            while (real_read(dev->tap_fd, buf, sizeof(buf)) > 0) {
            }
            */

            static uint8_t buf[ETHERNET_FRAME_LEN];

            real_read(dev->tap_fd, buf, sizeof(buf));

            _continue_reading(dev);
        }

        /* no way of figuring out packet size without racey buffering,
         * so we return the maximum possible size */
        return ETHERNET_FRAME_LEN;
    }

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

    if (nread > 0) {
        ethernet_hdr_t *hdr = (ethernet_hdr_t *)buf;
        if (!(dev->promiscous) && !_is_addr_multicast(hdr->dst) &&
            !_is_addr_broadcast(hdr->dst) &&
            (memcmp(hdr->dst, dev->addr, ETHERNET_ADDR_LEN) != 0)) {
            DEBUG("netdev2_tap: 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]);

            native_async_read_continue(dev->tap_fd);

            return 0;
        }

        _continue_reading(dev);

#ifdef MODULE_NETSTATS_L2
        netdev2->stats.rx_count++;
        netdev2->stats.rx_bytes += nread;
#endif
        return nread;
    }
    else if (nread == -1) {
        if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
        }
        else {
            err(EXIT_FAILURE, "netdev2_tap: read");
        }
    }
    else if (nread == 0) {
        DEBUG("_native_handle_tap_input: ignoring null-event");
    }
    else {
        errx(EXIT_FAILURE, "internal error _rx_event");
    }

    return -1;
}