Esempio n. 1
0
int check_tun(const struct arguments *args,
              const struct epoll_event *ev,
              const int epoll_fd,
              int sessions, int maxsessions) {
    // Check tun error
    if (ev->events & EPOLLERR) {
        log_android(ANDROID_LOG_ERROR, "tun %d exception", args->tun);
        if (fcntl(args->tun, F_GETFL) < 0) {
            log_android(ANDROID_LOG_ERROR, "fcntl tun %d F_GETFL error %d: %s",
                        args->tun, errno, strerror(errno));
            report_exit(args, "fcntl tun %d F_GETFL error %d: %s",
                        args->tun, errno, strerror(errno));
        } else
            report_exit(args, "tun %d exception", args->tun);
        return -1;
    }

    // Check tun read
    if (ev->events & EPOLLIN) {
        uint8_t *buffer = malloc(get_mtu());
        ssize_t length = read(args->tun, buffer, get_mtu());
        if (length < 0) {
            free(buffer);

            log_android(ANDROID_LOG_ERROR, "tun %d read error %d: %s",
                        args->tun, errno, strerror(errno));
            if (errno == EINTR || errno == EAGAIN)
                // Retry later
                return 0;
            else {
                report_exit(args, "tun %d read error %d: %s",
                            args->tun, errno, strerror(errno));
                return -1;
            }
        }
        else if (length > 0) {
            // Write pcap record
            if (pcap_file != NULL)
                write_pcap_rec(buffer, (size_t) length);

            if (length > max_tun_msg) {
                max_tun_msg = length;
                log_android(ANDROID_LOG_WARN, "Maximum tun msg length %d", max_tun_msg);
            }

            // Handle IP from tun
            handle_ip(args, buffer, (size_t) length, epoll_fd, sessions, maxsessions);

            free(buffer);
        }
        else {
            // tun eof
            free(buffer);

            log_android(ANDROID_LOG_ERROR, "tun %d empty read", args->tun);
            report_exit(args, "tun %d empty read", args->tun);
            return -1;
        }
    }

    return 0;
}
Esempio n. 2
0
static void write_pcap_hdr(FILE *file)
{
	struct pcap_file_header hdr = {
		.magic		= PCAP_FILE_MAGIC,
		.version_major	= 2,
		.version_minor	= 4,
		.thiszone	= 0,
		.sigfigs	= 0,
		.snaplen	= MAX_PSDU,
		.linktype	= DLT_IEEE802_15_4
	};

	if (fwrite(&hdr, sizeof(hdr), 1, file) != 1) {
		perror("fwrite");
		exit(1);
	}
}


static void write_pcap_rec(FILE *file, const struct timeval *tv,
    const void *buf, int n)
{
	struct pcap_pkthdr hdr = {
		.ts_sec		= tv->tv_sec,
		.ts_usec	= tv->tv_usec,
		.caplen		= n,
		.len		= n
	};

	if (fwrite(&hdr, sizeof(hdr), 1, file) != 1) {
		perror("fwrite");
		exit(1);
	}
	if (fwrite(buf, n, 1, file) != 1) {
		perror("fwrite");
		exit(1);
	}
}


static void receive_pcap(struct atrf_dsc *dsc, const char *name)
{
	FILE *file;
	uint8_t buf[MAX_PSDU+1]; /* PSDU+LQI */
	struct timeval now;
	int n;
	int count = 0;

	file = fopen(name, "w");
	if (!file) {
		perror(name);
		exit(1);
	}
	write_pcap_hdr(file);
	while (run) {
		wait_for_interrupt(dsc,
		    IRQ_TRX_END,
		    quick ? 0xff : IRQ_TRX_END | IRQ_RX_START | IRQ_AMI,
		    quick ? -1 : 0);
		if (!run)
			break;
		gettimeofday(&now, NULL);
		n = atrf_buf_read(dsc, buf, sizeof(buf));
		if (n < 0)
			exit(1);
		if (n < 2) {
			fprintf(stderr, "%d bytes received\n", n);
			continue;
		}
		write_pcap_rec(file, &now, buf, n-1);
		if (!quick)
			(void) write(2, ".", 1);
		count++;
	}
	if (fclose(file) == EOF) {
		perror(name);
		exit(1);
	}
	fprintf(stderr, "%sreceived %d message%s\n", count ? "\n" : "",
	    count, count == 1 ? "" : "s");
}


static void receive(struct atrf_dsc *dsc, const char *name, int hex)
{
	atrf_reg_write(dsc, REG_TRX_STATE, TRX_CMD_RX_ON);
	/*
	 * 180 us, according to AVR2001 section 4.2. We time out after
	 * nominally 200 us.
	 */
	wait_for_interrupt(dsc, IRQ_PLL_LOCK, IRQ_PLL_LOCK, 1);

	if (name)
		receive_pcap(dsc, name);
	else
		receive_message(dsc, hex);
}