#include #include #include #include #include #include #include #include #include #include int main(int argc, char *argv[]) { int fd, sock; fd_set set; struct timeval wait; struct sockaddr_in sin; struct sockaddr_in sin2; signal(SIGPIPE, SIG_IGN); if (argc < 2 && argc > 3) { printf("usage: %s ipaddr [ipaddr]\n", argv[0]); exit(1); } fd = open("/dev/tap0", O_RDWR); if (fd < 0) { perror("open tap"); exit(1); } if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { perror("socket"); exit(1); } memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_port = htons((short)9998); sin.sin_addr.s_addr = htonl(INADDR_ANY); if (bind(sock, (struct sockaddr *) &sin, sizeof(sin)) < 0) { perror("bind"); exit(1); } sin.sin_addr.s_addr = inet_addr(argv[1]); if (argc == 3) { memset(&sin2, 0, sizeof(sin)); sin2.sin_family = AF_INET; sin2.sin_port = htons((short)9998); sin2.sin_addr.s_addr = inet_addr(argv[2]); } chdir("/"); if (fork() != 0) exit(0); setsid(); if (fork() != 0) exit(0); while (1) { wait.tv_sec = 10; wait.tv_usec = 0; FD_ZERO(&set); FD_SET(fd, &set); FD_SET(sock, &set); if (select(FD_SETSIZE, &set, (fd_set *)0, (fd_set *)0, &wait) < 0) { perror("select"); exit(1); } if (FD_ISSET(fd, &set)) { char buf[10240]; int ret; if ((ret=read(fd, buf, sizeof(buf))) < 0) { perror("read"); } else { int i; /* printf("%d bytes on tap0\n", ret); */ i = sendto(sock, buf, ret, 0, (struct sockaddr*)&sin, sizeof(sin)); if (i < 0) { perror("sendto1"); } else if (i != ret) { printf("short sendto (%d/%d)\n", i, ret); } if (argc == 3) { i = sendto(sock, buf, ret, 0, (struct sockaddr*)&sin2, sizeof(sin2)); if (i < 0) { perror("sendto2"); } else if (i != ret) { printf("short sendto (%d/%d)\n", i, ret); } } } } if (FD_ISSET(sock, &set)) { char buf[10240]; int ret; if ((ret=recvfrom(sock, buf, sizeof(buf), 0, NULL, NULL)) < 0) { perror("recvfrom"); } else { int i; /* printf("%d bytes on socket\n", ret); */ i = write(fd, buf, ret); if (i < 0) { perror("write"); } else if (i != ret) { printf("short write (%d/%d)\n", i, ret); } } } } }