#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include int main(int ac, char *av[]) { int fd; int s; int mode; char buf[2052]; int n, i; int endpt; struct sockaddr_in sin; fd_set rfdset; struct tuninfo ti; /* Run one end as 'qd_tun 1' and the other as 'qd_tun 2' */ if (ac < 2) errx(1, "usage: 1/2"); endpt = atoi(av[1]); if (endpt != 1 && endpt != 2) errx(1, "usage: 1/2"); s = socket(PF_INET, SOCK_DGRAM, 0); if (s < 0) err(1, "socket"); mode = 1; i = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &mode, sizeof(mode)); if (i < 0) err(1, "ioctl SO_REUSEADDR tun0"); memset(&sin, 0, sizeof(sin)); sin.sin_len = sizeof(sin); sin.sin_family = AF_INET; if (endpt == 1) { /* Endpoint 1 */ inet_aton("10.1.1.1", &sin.sin_addr); sin.sin_port = htons(10001); } else { /* Endpoint 2 */ inet_aton("10.2.2.2", &sin.sin_addr); sin.sin_port = htons(10002); } i = bind(s, (struct sockaddr *)&sin, sizeof(sin)); if (i < 0) err(1, "bind. right endpt?"); if (endpt == 1) { /* I am canning. his remote end. */ inet_aton("216.145.52.172", &sin.sin_addr); sin.sin_port = htons(33926); } else { /* I am daintree. his remote end. */ inet_aton("192.203.228.73", &sin.sin_addr); sin.sin_port = htons(53); } fd = open("/dev/tun0", O_RDWR | O_EXCL, 0); if (fd < 0) err(1, "open tun0"); mode = 1; i = ioctl(fd, FIONBIO, &mode, sizeof(mode)); if (i < 0) err(1, "ioctl FIONBIO tun0"); mode = 1; i = ioctl(s, FIONBIO, &mode, sizeof(mode)); if (i < 0) err(1, "ioctl FIONBIO sock"); mode = 1; i = ioctl(fd, TUNSIFHEAD, &mode, sizeof(mode)); if (i < 0) err(1, "ioctl TUNSIFHEAD"); memset(&ti, 0, sizeof(ti)); ti.baudrate = 100*1000*1000; ti.mtu = 1280; ti.type = IFT_TUNNEL; ti.dummy = 0; i = ioctl(fd, TUNSIFINFO, &ti, sizeof(ti)); if (i < 0) err(1, "ioctl TUNSIFINFO"); for (;;) { FD_ZERO(&rfdset); FD_SET(fd, &rfdset); FD_SET(s, &rfdset); n = select(FD_SETSIZE, &rfdset, NULL, NULL, NULL); if (n < 0) err(1, "select"); if (n == 0) continue; if (FD_ISSET(fd, &rfdset)) { n = read(fd, buf, sizeof(buf)); if (n > 0) { if (n >= 4) { mode = be32toh(*(uint32_t *)buf); /*printf("tun0 rcv protocol: %d\n", mode); */ if (mode != AF_INET6) continue; i = sendto(s, buf, n, 0, (struct sockaddr *)&sin, sizeof(sin)); if (i < 0) warn("sock sendto"); } } if (n < 0) { err(1, "tun0 eof"); } if (n == 0) { warn("tun0 short read"); } } if (FD_ISSET(s, &rfdset)) { n = read(s, buf, sizeof(buf)); if (n > 0) { if (n >= 4) { mode = be32toh(*(uint32_t *)buf); /* printf("sock rcv protocol: %d\n", mode); */ if (mode != AF_INET6) continue; i = write(fd, buf, n); if (i < 0) warn("tun0 write"); } } if (n < 0) { err(1, "sock eof"); } if (n == 0) { warnx("sock short read"); } } } }