int main(int argc, char **argv) { int c; int tunfd, maxfd; int ret; fd_set rset, wset; FILE *inslip; const char *siodev = NULL; const char *host = NULL; const char *port = NULL; const char *prog; int baudrate = -2; int tap = 0; slipfd = 0; prog = argv[0]; setvbuf(stdout, NULL, _IOLBF, 0); /* Line buffered output. */ while((c = getopt(argc, argv, "B:D:Lhs:t:v::d::a:p:T")) != -1) { switch(c) { case 'B': baudrate = atoi(optarg); break; case 'L': timestamp=1; break; case 's': if(strncmp("/dev/", optarg, 5) == 0) { siodev = optarg + 5; } else { siodev = optarg; } break; case 't': if(strncmp("/dev/", optarg, 5) == 0) { strncpy(tundev, optarg + 5, sizeof(tundev)); } else { strncpy(tundev, optarg, sizeof(tundev)); } break; case 'a': host = optarg; break; case 'p': port = optarg; break; case 'd': basedelay = 10; if (optarg) basedelay = atoi(optarg); break; case 'v': verbose = 2; if (optarg) verbose = atoi(optarg); break; case 'T': tap = 1; break; case '?': case 'h': default: fprintf(stderr,"usage: %s [options] ipaddress\n", prog); fprintf(stderr,"example: tunslip6 -L -v2 -s ttyUSB1 aaaa::1/64\n"); fprintf(stderr,"Options are:\n"); fprintf(stderr," -B baudrate 9600,19200,38400,57600,115200 (default)\n"); fprintf(stderr," -L Log output format (adds time stamps)\n"); fprintf(stderr," -s siodev Serial device (default /dev/ttyUSB0)\n"); fprintf(stderr," -T Make tap interface (default is tun interface)\n"); //fprintf(stderr," -t tundev Name of interface (default tap0 or tun0)\n"); fprintf(stderr," -t tundev Name of interface\n"); fprintf(stderr," -v[level] Verbosity level\n"); fprintf(stderr," -v0 No messages\n"); fprintf(stderr," -v1 Encapsulated SLIP debug messages (default)\n"); fprintf(stderr," -v2 Printable strings after they are received\n"); fprintf(stderr," -v3 Printable strings and SLIP packet notifications\n"); fprintf(stderr," -v4 All printable characters as they are received\n"); fprintf(stderr," -v5 All SLIP packets in hex\n"); fprintf(stderr," -v Equivalent to -v3\n"); fprintf(stderr," -d[basedelay] Minimum delay between outgoing SLIP packets.\n"); fprintf(stderr," Actual delay is basedelay*(#6LowPAN fragments) milliseconds.\n"); fprintf(stderr," -d is equivalent to -d10.\n"); fprintf(stderr," -a serveraddr \n"); fprintf(stderr," -p serverport \n"); exit(1); break; } } argc -= (optind - 1); argv += (optind - 1); if(argc != 2 && argc != 3) { err(1, "usage: %s [-B baudrate] [-L] [-s siodev] [-t tundev] [-T] [-v verbosity] [-d delay] [-a serveraddress] [-p serverport] ipaddress", prog); } ipaddr = argv[1]; 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; } #if 0 if(*tundev == '\0') { /* Use default. */ if(tap) { strcpy(tundev, "tap0"); } else { strcpy(tundev, "tun0"); } } #endif if(host != NULL) { struct addrinfo hints, *servinfo, *p; int rv; char s[INET6_ADDRSTRLEN]; if(port == NULL) { port = "60001"; } memset(&hints, 0, sizeof hints); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; if((rv = getaddrinfo(host, port, &hints, &servinfo)) != 0) { err(1, "getaddrinfo: %s", gai_strerror(rv)); } /* loop through all the results and connect to the first we can */ for(p = servinfo; p != NULL; p = p->ai_next) { if((slipfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) { perror("client: socket"); continue; } if(connect(slipfd, p->ai_addr, p->ai_addrlen) == -1) { close(slipfd); perror("client: connect"); continue; } break; } if(p == NULL) { err(1, "can't connect to ``%s:%s''", host, port); } fcntl(slipfd, F_SETFL, O_NONBLOCK); inet_ntop(p->ai_family, get_in_addr((struct sockaddr *)p->ai_addr), s, sizeof(s)); fprintf(stderr, "slip connected to ``%s:%s''\n", s, port); /* all done with this structure */ freeaddrinfo(servinfo); } else { 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"); } } if (timestamp) stamptime(); 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, tap); if(tunfd == -1) err(1, "main: open"); if (timestamp) stamptime(); fprintf(stderr, "opened %s device ``/dev/%s''\n", tap ? "tap" : "tun", tundev); atexit(cleanup); signal(SIGHUP, sigcleanup); signal(SIGTERM, sigcleanup); signal(SIGINT, sigcleanup); signal(SIGALRM, sigalarm); ifconf(tundev, ipaddr); while(1) { maxfd = 0; FD_ZERO(&rset); FD_ZERO(&wset); /* do not send IPA all the time... - add get MAC later... */ /* 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; } 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(); } /* Optional delay between outgoing packets */ /* Base delay times number of 6lowpan fragments to be sent */ if(delaymsec) { struct timeval tv; int dmsec; gettimeofday(&tv, NULL) ; dmsec=(tv.tv_sec-delaystartsec)*1000+tv.tv_usec/1000-delaystartmsec; if(dmsec<0) delaymsec=0; if(dmsec>delaymsec) delaymsec=0; } if(delaymsec==0) { //int size; if(slip_empty() && FD_ISSET(tunfd, &rset)) { //size = tun_to_serial(tunfd, slipfd); tun_to_serial(tunfd, slipfd); slip_flushbuf(slipfd); sigalarm_reset(); if(basedelay) { struct timeval tv; gettimeofday(&tv, NULL) ; // delaymsec=basedelay*(1+(size/120));//multiply by # of 6lowpan packets? delaymsec=basedelay; delaystartsec =tv.tv_sec; delaystartmsec=tv.tv_usec/1000; } } } } } }
int main(int argc, char **argv) { int c; int tunfd, slipfd, maxfd; int ret; fd_set rset, wset; FILE *inslip; const char *siodev = NULL; int baudrate = -2; request_mac = 1; 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 '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: errx(1, USAGE_STRING); break; } } argc -= (optind - 1); argv += (optind - 1); if(argc != 3 && argc != 4) { errx(1, USAGE_STRING); } 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; } 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); printf("opening: %s", 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); /* request mac address from gateway node for autoconfiguration of ethernet interface tap0 */ if (request_mac) { slip_send(slipfd, '?'); slip_send(slipfd, 'M'); slip_send(slipfd, SLIP_END); request_mac = 0; } 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; } 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(); } } } }
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); } } } }
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); } } } }