示例#1
0
文件: senslip.c 项目: EDAyele/wsn430
int main(int argc, char **argv)
{
	int c;
	int tunfd, slipfd, maxfd;
	int ret;
	fd_set rset, wset;

	unsigned short dst_port = DST_PORT + 1;

	ip_id = getpid() * time(NULL);

	setvbuf(stdout, NULL, _IOLBF, 0); /* Line buffered output. */

	while ((c = getopt(argc, argv, "n:t:")) != -1) {
		switch (c) {
		case 'n':
			dst_port = DST_PORT + atoi(optarg);
			break;
		case 't':
			if (strncmp("/dev/", optarg, 5) == 0) {
				strcpy(tundev, optarg + 5);
			} else {
				strcpy(tundev, optarg);
			}
			break;

		case '?':
		case 'h':
		default:
			err(1,USAGE_STRING);
			break;
		}
	}
	argc -= (optind - 1);
	argv += (optind - 1);

	if (argc != 1) {
		err(1, USAGE_STRING);
	}
	ipaddr = "172.16.0.0";
	netmask = "255.255.0.0";
	circuit_addr = inet_addr(ipaddr);
	netaddr = inet_addr(ipaddr) & inet_addr(netmask);

	slipfd = devopen(dst_port);
	if (slipfd == -1) {
		err(1, "can't open port %u", dst_port);
	}

	fprintf(stderr, "slip sending to port %u\n", dst_port);
	stty_telos(slipfd);
	slip_send(slipfd, SLIP_END);

	tunfd = tun_alloc(tundev);
	if (tunfd == -1)
		err(1, "main: open");
	fprintf(stderr, "opened device ``/dev/%s''\n", tundev);

	atexit(cleanup);
	signal(SIGHUP, sigcleanup);
	signal(SIGTERM, sigcleanup);
	signal(SIGINT, sigcleanup);
	signal(SIGALRM, sigalarm);
	ifconf(tundev, ipaddr, netmask);

	while (1) {
		maxfd = 0;
		FD_ZERO(&rset);
		FD_ZERO(&wset);

		if (got_sigalarm) {
			/* Send "?IPA". */
			slip_send(slipfd, '?');
			slip_send(slipfd, 'I');
			slip_send(slipfd, 'P');
			slip_send(slipfd, 'A');
			slip_send(slipfd, SLIP_END);
			got_sigalarm = 0;
		}

		if (!slip_empty()) { /* Anything to flush? */
			FD_SET(slipfd, &wset);
		}

		FD_SET(slipfd, &rset); /* Read from slip ASAP! */
		if (slipfd > maxfd)
			maxfd = slipfd;

		/* We only have one packet at a time queued for slip output. */
		if (slip_empty()) {
			FD_SET(tunfd, &rset);
			if (tunfd > maxfd)
				maxfd = tunfd;
			if (dhsock != -1) {
				FD_SET(dhsock, &rset);
				if (dhsock > maxfd)
					maxfd = dhsock;
			}
		}

		ret = select(maxfd + 1, &rset, &wset, NULL, NULL);
		if (ret == -1 && errno != EINTR) {
			err(1, "select");
		} else if (ret > 0) {
			if (FD_ISSET(slipfd, &rset)) {
				serial_to_tun(slipfd, tunfd);
			}

			if (FD_ISSET(slipfd, &wset)) {
				slip_flushbuf(slipfd);
				sigalarm_reset();
			}

			if (slip_empty() && FD_ISSET(tunfd, &rset)) {
				tun_to_serial(tunfd, slipfd);
				slip_flushbuf(slipfd);
				sigalarm_reset();
			}

			if (dhsock != -1 && slip_empty() && FD_ISSET(dhsock, &rset)) {
				relay_dhcp_to_client(slipfd); ///  ####  ////
				slip_flushbuf(slipfd);
			}
		}
	}
}
示例#2
0
文件: tunslip.c 项目: 4dahalibut/RIOT
int
main(int argc, char **argv)
{
    int c;
    int tunfd, slipfd, maxfd;
    int ret;
    fd_set rset, wset;
    FILE *inslip;
    const char *siodev = NULL;
    const char *dhcp_server = NULL;
    u_int16_t myport = BOOTPS, dhport = BOOTPS;
    int baudrate = -2;

    ip_id = getpid() * time(NULL);

    setvbuf(stdout, NULL, _IOLBF, 0); /* Line buffered output. */

    while ((c = getopt(argc, argv, "B:D:hs:t:")) != -1) {
        switch (c) {
            case 'B':
                baudrate = atoi(optarg);
                break;

            case 'D':
                dhcp_server = optarg;
                break;

            case 's':
                if (strncmp("/dev/", optarg, 5) == 0) {
                    siodev = optarg + 5;
                }
                else {
                    siodev = optarg;
                }

                break;

            case 't':
                if (strncmp("/dev/", optarg, 5) == 0) {
                    strcpy(tundev, optarg + 5);
                }
                else {
                    strcpy(tundev, optarg);
                }

                break;

            case '?':
            case 'h':
            default:
                err(1, "usage: tunslip [-B baudrate] [-s siodev] [-t tundev] [-D dhcp-server] ipaddress netmask [dhcp-server]");
                break;
        }
    }

    argc -= (optind - 1);
    argv += (optind - 1);

    if (argc != 3 && argc != 4) {
        err(1, "usage: tunslip [-s siodev] [-t tundev] [-D dhcp-server] ipaddress netmask [dhcp-server]");
    }

    ipaddr = argv[1];
    netmask = argv[2];
    circuit_addr = inet_addr(ipaddr);
    netaddr = inet_addr(ipaddr) & inet_addr(netmask);

    switch (baudrate) {
        case -2:
            break;			/* Use default. */

        case 9600:
            b_rate = B9600;
            break;

        case 19200:
            b_rate = B19200;
            break;

        case 38400:
            b_rate = B38400;
            break;

        case 57600:
            b_rate = B57600;
            break;

        case 115200:
            b_rate = B115200;
            break;

        default:
            err(1, "unknown baudrate %d", baudrate);
            break;
    }

    /*
     * Set up DHCP relay agent socket and find the address of this relay
     * agent.
     */
    if (argc == 4) {
        dhcp_server = argv[3];
    }

    if (dhcp_server != NULL) {
        struct sockaddr_in myaddr;
        socklen_t len;
        in_addr_t a;

        if (strchr(dhcp_server, ':') != NULL) {
            dhport = atoi(strchr(dhcp_server, ':') + 1);
            myport = dhport + 1;
            *strchr(dhcp_server, ':') = '\0';
        }

        a = inet_addr(dhcp_server);

        if (a == -1) {
            err(1, "illegal dhcp-server address");
        }

#ifndef linux
        dhaddr.sin_len = sizeof(dhaddr);
#endif
        dhaddr.sin_family = AF_INET;
        dhaddr.sin_port = htons(dhport);
        dhaddr.sin_addr.s_addr = a;

        dhsock = socket(AF_INET, SOCK_DGRAM, 0);

        if (dhsock < 0) {
            err(1, "socket");
        }

        memset(&myaddr, 0x0, sizeof(myaddr));
#ifndef linux
        myaddr.sin_len = sizeof(myaddr);
#endif
        myaddr.sin_family = AF_INET;
        myaddr.sin_addr.s_addr = INADDR_ANY;
        myaddr.sin_port = htons(myport);

        if (bind(dhsock, (struct sockaddr *)&myaddr, sizeof(myaddr)) < 0) {
            err(1, "bind dhcp-relay");
        }

        if (connect(dhsock, (struct sockaddr *)&dhaddr, sizeof(dhaddr)) < 0) {
            err(1, "connect to dhcp-server");
        }

        len = sizeof(myaddr);

        if (getsockname(dhsock, (struct sockaddr *)&myaddr, &len) < 0) {
            err(1, "getsockname dhsock");
        }

        giaddr = myaddr.sin_addr.s_addr;

        /*
         * Don't want connected socket.
         */
        close(dhsock);
        dhsock = socket(AF_INET, SOCK_DGRAM, 0);

        if (dhsock < 0) {
            err(1, "socket");
        }

        myaddr.sin_family = AF_INET;
        myaddr.sin_addr.s_addr = INADDR_ANY;
        myaddr.sin_port = htons(myport);

        if (bind(dhsock, (struct sockaddr *)&myaddr, sizeof(myaddr)) < 0) {
            err(1, "bind dhcp-relay");
        }

        fprintf(stderr, "DHCP server at %s:%d\n", dhcp_server, dhport);
    }

    if (siodev != NULL) {
        slipfd = devopen(siodev, O_RDWR | O_NONBLOCK);

        if (slipfd == -1) {
            err(1, "can't open siodev ``/dev/%s''", siodev);
        }
    }
    else {
        static const char *siodevs[] = {
            "ttyUSB0", "cuaU0", "ucom0" /* linux, fbsd6, fbsd5 */
        };
        int i;

        for (i = 0; i < 3; i++) {
            siodev = siodevs[i];
            slipfd = devopen(siodev, O_RDWR | O_NONBLOCK);

            if (slipfd != -1) {
                break;
            }
        }

        if (slipfd == -1) {
            err(1, "can't open siodev");
        }
    }

    fprintf(stderr, "slip started on ``/dev/%s''\n", siodev);
    stty_telos(slipfd);
    slip_send(slipfd, SLIP_END);
    inslip = fdopen(slipfd, "r");

    if (inslip == NULL) {
        err(1, "main: fdopen");
    }

    tunfd = tun_alloc(tundev);

    if (tunfd == -1) {
        err(1, "main: open");
    }

    fprintf(stderr, "opened device ``/dev/%s''\n", tundev);

    atexit(cleanup);
    signal(SIGHUP, sigcleanup);
    signal(SIGTERM, sigcleanup);
    signal(SIGINT, sigcleanup);
    signal(SIGALRM, sigalarm);
    ifconf(tundev, ipaddr, netmask);

    while (1) {
        maxfd = 0;
        FD_ZERO(&rset);
        FD_ZERO(&wset);

        if (got_sigalarm) {
            /* Send "?IPA". */
            slip_send(slipfd, '?');
            slip_send(slipfd, 'I');
            slip_send(slipfd, 'P');
            slip_send(slipfd, 'A');
            slip_send(slipfd, SLIP_END);
            got_sigalarm = 0;
        }

        if (!slip_empty()) {		/* Anything to flush? */
            FD_SET(slipfd, &wset);
        }

        FD_SET(slipfd, &rset);	/* Read from slip ASAP! */

        if (slipfd > maxfd) {
            maxfd = slipfd;
        }

        /* We only have one packet at a time queued for slip output. */
        if (slip_empty()) {
            FD_SET(tunfd, &rset);

            if (tunfd > maxfd) {
                maxfd = tunfd;
            }

            if (dhsock != -1) {
                FD_SET(dhsock, &rset);

                if (dhsock > maxfd) {
                    maxfd = dhsock;
                }
            }
        }

        ret = select(maxfd + 1, &rset, &wset, NULL, NULL);

        if (ret == -1 && errno != EINTR) {
            err(1, "select");
        }
        else if (ret > 0) {
            if (FD_ISSET(slipfd, &rset)) {
                serial_to_tun(inslip, tunfd);
            }

            if (FD_ISSET(slipfd, &wset)) {
                slip_flushbuf(slipfd);
                sigalarm_reset();
            }

            if (slip_empty() && FD_ISSET(tunfd, &rset)) {
                tun_to_serial(tunfd, slipfd);
                slip_flushbuf(slipfd);
                sigalarm_reset();
            }

            if (dhsock != -1 && slip_empty() && FD_ISSET(dhsock, &rset)) {
                relay_dhcp_to_client(slipfd);
                slip_flushbuf(slipfd);
            }
        }
    }
}