diff --git a/tools/tunslip6.c b/tools/tunslip6.c index 75659e270..3029eb536 100644 --- a/tools/tunslip6.c +++ b/tools/tunslip6.c @@ -62,7 +62,7 @@ const char *netmask; int slipfd = 0; uint16_t basedelay=0,delaymsec=0; uint32_t startsec,startmsec,delaystartsec,delaystartmsec; -int timestamp = 0, flowcontrol=0, showprogress=0; +int timestamp = 0, flowcontrol=0, showprogress=0, flowcontrol_xonxoff=0; int ssystem(const char *fmt, ...) __attribute__((__format__ (__printf__, 1, 2))); @@ -75,6 +75,10 @@ void slip_send_char(int fd, unsigned char c); char tundev[1024] = { "" }; +/* IPv6 required minimum MTU */ +#define MIN_DEVMTU 1500 +int devmtu = MIN_DEVMTU; + int ssystem(const char *fmt, ...) __attribute__((__format__ (__printf__, 1, 2))); @@ -91,11 +95,15 @@ ssystem(const char *fmt, ...) return system(cmd); } -#define SLIP_END 0300 -#define SLIP_ESC 0333 -#define SLIP_ESC_END 0334 -#define SLIP_ESC_ESC 0335 +#define SLIP_END 0300 +#define SLIP_ESC 0333 +#define SLIP_ESC_END 0334 +#define SLIP_ESC_ESC 0335 +#define SLIP_ESC_XON 0336 +#define SLIP_ESC_XOFF 0337 +#define XON 17 +#define XOFF 19 /* get sockaddr, IPv4 or IPv6: */ void * @@ -287,6 +295,12 @@ serial_to_tun(FILE *inslip, int outfd) case SLIP_ESC_ESC: c = SLIP_ESC; break; + case SLIP_ESC_XON: + c = XON; + break; + case SLIP_ESC_XOFF: + c = XOFF; + break; } /* FALLTHROUGH */ default: @@ -330,6 +344,22 @@ slip_send_char(int fd, unsigned char c) slip_send(fd, SLIP_ESC); slip_send(fd, SLIP_ESC_ESC); break; + case XON: + if(flowcontrol_xonxoff) { + slip_send(fd, SLIP_ESC); + slip_send(fd, SLIP_ESC_XON); + } else { + slip_send(fd, c); + } + break; + case XOFF: + if(flowcontrol_xonxoff) { + slip_send(fd, SLIP_ESC); + slip_send(fd, SLIP_ESC_XOFF); + } else { + slip_send(fd, c); + } + break; default: slip_send(fd, c); break; @@ -415,6 +445,22 @@ write_to_serial(int outfd, void *inbuf, int len) slip_send(outfd, SLIP_ESC); slip_send(outfd, SLIP_ESC_ESC); break; + case XON: + if(flowcontrol_xonxoff) { + slip_send(outfd, SLIP_ESC); + slip_send(outfd, SLIP_ESC_XON); + } else { + slip_send(outfd, p[i]); + } + break; + case XOFF: + if(flowcontrol_xonxoff) { + slip_send(outfd, SLIP_ESC); + slip_send(outfd, SLIP_ESC_XOFF); + } else { + slip_send(outfd, p[i]); + } + break; default: slip_send(outfd, p[i]); break; @@ -467,6 +513,12 @@ stty_telos(int fd) tty.c_cflag |= CRTSCTS; else tty.c_cflag &= ~CRTSCTS; + tty.c_iflag &= ~IXON; + if(flowcontrol_xonxoff) { + tty.c_iflag |= IXOFF | IXANY; + } else { + tty.c_iflag &= ~IXOFF & ~IXANY; + } tty.c_cflag &= ~HUPCL; tty.c_cflag &= ~CLOCAL; @@ -609,7 +661,7 @@ ifconf(const char *tundev, const char *ipaddr) { #ifdef linux if (timestamp) stamptime(); - ssystem("ifconfig %s inet `hostname` up", tundev); + ssystem("ifconfig %s inet `hostname` mtu %d up", tundev, devmtu); if (timestamp) stamptime(); ssystem("ifconfig %s add %s", tundev, ipaddr); @@ -670,7 +722,7 @@ ifconf(const char *tundev, const char *ipaddr) prefix = "64"; } if (timestamp) stamptime(); - ssystem("ifconfig %s inet6 up", tundev ); + ssystem("ifconfig %s inet6 mtu %d up", tundev, devmtu); if (timestamp) stamptime(); ssystem("ifconfig %s inet6 %s add", tundev, ipaddr ); if (timestamp) stamptime(); @@ -679,7 +731,7 @@ ifconf(const char *tundev, const char *ipaddr) } #else if (timestamp) stamptime(); - ssystem("ifconfig %s inet `hostname` %s up", tundev, ipaddr); + ssystem("ifconfig %s inet `hostname` %s mtu %d up", tundev, ipaddr, devmtu); if (timestamp) stamptime(); ssystem("sysctl -w net.inet.ip.forwarding=1"); #endif /* !linux */ @@ -708,7 +760,7 @@ main(int argc, char **argv) prog = argv[0]; setvbuf(stdout, NULL, _IOLBF, 0); /* Line buffered output. */ - while((c = getopt(argc, argv, "B:HILPhs:t:v::d::a:p:T")) != -1) { + while((c = getopt(argc, argv, "B:HILPhXM:s:t:v::d::a:p:T")) != -1) { switch(c) { case 'B': baudrate = atoi(optarg); @@ -718,10 +770,20 @@ main(int argc, char **argv) flowcontrol=1; break; + case 'X': + flowcontrol_xonxoff=1; + break; + case 'L': timestamp=1; break; + case 'M': + devmtu=atoi(optarg); + if(devmtu < MIN_DEVMTU) { + devmtu = MIN_DEVMTU; + } + case 'P': showprogress=1; break; @@ -782,8 +844,10 @@ fprintf(stderr," -B baudrate 9600,19200,38400,57600,115200 (default),230400\n #endif fprintf(stderr," -H Hardware CTS/RTS flow control (default disabled)\n"); fprintf(stderr," -I Inquire IP address\n"); +fprintf(stderr," -X Software XON/XOFF flow control (default disabled)\n"); fprintf(stderr," -L Log output format (adds time stamps)\n"); fprintf(stderr," -s siodev Serial device (default /dev/ttyUSB0)\n"); +fprintf(stderr," -M Interface MTU (default and min: 1280)\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," -v[level] Verbosity level\n"); @@ -836,9 +900,18 @@ exit(1); case 460800: b_rate = B460800; break; + case 500000: + b_rate = B500000; + break; + case 576000: + b_rate = B576000; + break; case 921600: b_rate = B921600; break; + case 1000000: + b_rate = B1000000; + break; #endif default: err(1, "unknown baudrate %d", baudrate);