From 5f5d1604492ae15967f9d86f41fbeeedcae0ae2b Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Thu, 8 Jul 1999 06:44:55 +0200 Subject: Import ax25-tools 0.0.3 from tarball --- kiss/Makefile.am | 11 ++- kiss/Makefile.in | 28 +++--- kiss/kissattach.8 | 22 +++-- kiss/kissattach.c | 86 ++++++++++++------ kiss/kissnetd.c | 2 +- kiss/kissparms.c | 2 + kiss/mkiss.8 | 12 ++- kiss/mkiss.c | 256 +++++++++++++++++++++++++++++++++++++++--------------- kiss/spattach.8 | 1 + 9 files changed, 296 insertions(+), 124 deletions(-) create mode 100644 kiss/spattach.8 (limited to 'kiss') diff --git a/kiss/Makefile.am b/kiss/Makefile.am index 82db252..c37accc 100644 --- a/kiss/Makefile.am +++ b/kiss/Makefile.am @@ -5,7 +5,16 @@ sbin_PROGRAMS = kissattach kissnetd kissparms mkiss net2kiss LDADD= $(AX25_LIB) -man_MANS = kissattach.8 kissnetd.8 kissparms.8 mkiss.8 net2kiss.8 +man_MANS = kissattach.8 spattach.8 kissnetd.8 kissparms.8 mkiss.8 net2kiss.8 EXTRA_DIST = $(man_MANS) +INCLUDES = -DAX25_SYSCONFDIR=\""$(AX25_SYSCONFDIR)"\" \ + -DAX25_LOCALSTATEDIR=\""$(AX25_LOCALSTATEDIR)"\" + +AX25_SYSCONFDIR=${sysconfdir}/ax25/ +AX25_LOCALSTATEDIR=${localstatedir}/ax25/ + +install-exec-local: + (cd $(DESTDIR)$(sbindir) ; ln -s kissattach spattach) + diff --git a/kiss/Makefile.in b/kiss/Makefile.in index ba5b17c..fdada1d 100644 --- a/kiss/Makefile.in +++ b/kiss/Makefile.in @@ -72,9 +72,15 @@ sbin_PROGRAMS = kissattach kissnetd kissparms mkiss net2kiss LDADD = $(AX25_LIB) -man_MANS = kissattach.8 kissnetd.8 kissparms.8 mkiss.8 net2kiss.8 +man_MANS = kissattach.8 spattach.8 kissnetd.8 kissparms.8 mkiss.8 net2kiss.8 EXTRA_DIST = $(man_MANS) + +INCLUDES = -DAX25_SYSCONFDIR=\""$(AX25_SYSCONFDIR)"\" -DAX25_LOCALSTATEDIR=\""$(AX25_LOCALSTATEDIR)"\" + + +AX25_SYSCONFDIR = ${sysconfdir}/ax25/ +AX25_LOCALSTATEDIR = ${localstatedir}/ax25/ mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = ../config.h CONFIG_CLEAN_FILES = @@ -290,11 +296,6 @@ distdir: $(DISTFILES) || cp -p $$d/$$file $(distdir)/$$file || :; \ fi; \ done -kissattach.o: kissattach.c ../config.h ../pathnames.h -kissnetd.o: kissnetd.c -kissparms.o: kissparms.c ../config.h -mkiss.o: mkiss.c ../config.h -net2kiss.o: net2kiss.c info-am: info: info-am @@ -304,7 +305,7 @@ check-am: all-am check: check-am installcheck-am: installcheck: installcheck-am -install-exec-am: install-sbinPROGRAMS +install-exec-am: install-sbinPROGRAMS install-exec-local install-exec: install-exec-am install-data-am: install-man @@ -361,15 +362,18 @@ install-sbinPROGRAMS mostlyclean-compile distclean-compile \ clean-compile maintainer-clean-compile install-man8 uninstall-man8 \ install-man uninstall-man tags mostlyclean-tags distclean-tags \ clean-tags maintainer-clean-tags distdir info-am info dvi-am dvi check \ -check-am installcheck-am installcheck install-exec-am install-exec \ -install-data-am install-data install-am install uninstall-am uninstall \ -all-redirect all-am all installdirs mostlyclean-generic \ -distclean-generic clean-generic maintainer-clean-generic clean \ -mostlyclean distclean maintainer-clean +check-am installcheck-am installcheck install-exec-local \ +install-exec-am install-exec install-data-am install-data install-am \ +install uninstall-am uninstall all-redirect all-am all installdirs \ +mostlyclean-generic distclean-generic clean-generic \ +maintainer-clean-generic clean mostlyclean distclean maintainer-clean installconf: +install-exec-local: + (cd $(DESTDIR)$(sbindir) ; ln -s kissattach spattach) + # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: diff --git a/kiss/kissattach.8 b/kiss/kissattach.8 index eabc2a1..1ba0ea7 100644 --- a/kiss/kissattach.8 +++ b/kiss/kissattach.8 @@ -1,13 +1,15 @@ -.TH KISSATTACH 8 "13 October 1996" Linux "Linux System Managers Manual" +.TH KISSATTACH 8 "4 July 1999" Linux "Linux System Managers Manual" .SH NAME -kissattach \- Attach a KISS interface +kissattach, spattach \- Attach a KISS or 6PACK interface .SH SYNOPSIS -.B kissattach [-i inetaddr] [-l] [-m mtu] [-v] tty port +.B kissattach [-6] [-i inetaddr] [-l] [-m mtu] [-v] tty port +.sp +.B spattach [-i inetaddr] [-l] [-m mtu] [-v] tty port .SH DESCRIPTION .LP -Attach a KISS interface to what is normally a tty line connected to a TNC in -KISS mode. This program will turn itself into a background process. To down -an interface send its kissattach process a SIGKILL. +Attach a KISS or a 6PACK interface to what is normally a tty line connected +to a TNC in KISS or 6PACK mode. This program will turn itself into a +background process. To down an interface send its attach process a SIGTERM. .LP .B Kissattach takes many of the parameters for the port from the axports(5) file. If the @@ -16,12 +18,16 @@ serial port speed, a zero value means that no speed is set. The paclen parameter is used for the device mtu unless overridden by a value on the command line. .LP -The tty argument will typically be that of a serial port with a KISS TNC -attached, although it could be a psuedo tty or a KISS port emulator such as +The tty argument will typically be that of a serial port with a KISS or 6PACK +TNC attached, although it could be a pseudo tty or a KISS port emulator such as an SCC card. The port arguments is the name of a port as given in the axports(5) file. .SH OPTIONS .TP 16 +.BI "\-6" +Use the 6PACK line discipline instead of KISS. This is the default if +the program is called as spattach. +.TP 16 .BI "\-i inetaddr" Set the internet address of the interface. This address may either be a dotted decimal address or a host name. diff --git a/kiss/kissattach.c b/kiss/kissattach.c index 0c80fe4..7b26560 100644 --- a/kiss/kissattach.c +++ b/kiss/kissattach.c @@ -1,4 +1,3 @@ - #include #include #include @@ -9,6 +8,7 @@ #include #include #include +#include #include @@ -35,10 +35,21 @@ #include "../pathnames.h" +#ifndef N_6PACK +#define N_6PACK 7 /* This is valid for all architectures in 2.2.x */ +#endif + static char *callsign; static int speed = 0; static int mtu = 0; static int logging = FALSE; +static char *progname; + +static char *basename(char *s) +{ + char *p = strrchr(s, '/'); + return p ? p + 1 : s; +} static void terminate(int sig) { @@ -57,7 +68,7 @@ static int readconfig(char *port) int n = 0; if ((fp = fopen(CONF_AXPORTS_FILE, "r")) == NULL) { - fprintf(stderr, "kissattach: cannot open axports file\n"); + fprintf(stderr, "%s: cannot open axports file\n", progname); return FALSE; } @@ -71,7 +82,7 @@ static int readconfig(char *port) continue; if ((s = strtok(buffer, " \t\r\n")) == NULL) { - fprintf(stderr, "kissattach: unable to parse line %d of the axports file\n", n); + fprintf(stderr, "%s: unable to parse line %d of the axports file\n", progname, n); return FALSE; } @@ -79,27 +90,27 @@ static int readconfig(char *port) continue; if ((s = strtok(NULL, " \t\r\n")) == NULL) { - fprintf(stderr, "kissattach: unable to parse line %d of the axports file\n", n); + fprintf(stderr, "%s: unable to parse line %d of the axports file\n", progname, n); return FALSE; } callsign = strdup(s); if ((s = strtok(NULL, " \t\r\n")) == NULL) { - fprintf(stderr, "kissattach: unable to parse line %d of the axports file\n", n); + fprintf(stderr, "%s: unable to parse line %d of the axports file\n", progname, n); return FALSE; } speed = atoi(s); if ((s = strtok(NULL, " \t\r\n")) == NULL) { - fprintf(stderr, "kissattach: unable to parse line %d of the axports file\n", n); + fprintf(stderr, "%s: unable to parse line %d of the axports file\n", progname, n); return FALSE; } if (mtu == 0) { if ((mtu = atoi(s)) <= 0) { - fprintf(stderr, "kissattach: invalid paclen setting\n"); + fprintf(stderr, "%s: invalid paclen setting\n", progname); return FALSE; } } @@ -111,7 +122,7 @@ static int readconfig(char *port) fclose(fp); - fprintf(stderr, "kissattach: cannot find port %s in axports\n", port); + fprintf(stderr, "%s: cannot find port %s in axports\n", progname, port); return FALSE; } @@ -126,7 +137,8 @@ static int setifcall(int fd, char *name) if (ioctl(fd, SIOCSIFHWADDR, call) != 0) { close(fd); - perror("kissattach: SIOCSIFHWADDR"); + fprintf(stderr, "%s: ", progname); + perror("SIOCSIFHWADDR"); return FALSE; } @@ -140,7 +152,8 @@ static int startiface(char *dev, struct hostent *hp) int fd; if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { - perror("kissattach: socket"); + fprintf(stderr, "%s: ", progname); + perror("socket"); return FALSE; } @@ -158,7 +171,8 @@ static int startiface(char *dev, struct hostent *hp) ifr.ifr_addr.sa_data[6] = 0; if (ioctl(fd, SIOCSIFADDR, &ifr) < 0) { - perror("kissattach: SIOCSIFADDR"); + fprintf(stderr, "%s: ", progname); + perror("SIOCSIFADDR"); return FALSE; } } @@ -166,12 +180,14 @@ static int startiface(char *dev, struct hostent *hp) ifr.ifr_mtu = mtu; if (ioctl(fd, SIOCSIFMTU, &ifr) < 0) { - perror("kissattach: SIOCSIFMTU"); + fprintf(stderr, "%s: ", progname); + perror("SIOCSIFMTU"); return FALSE; } if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) { - perror("kissattach: SIOCGIFFLAGS"); + fprintf(stderr, "%s: ", progname); + perror("SIOCGIFFLAGS"); return FALSE; } @@ -180,7 +196,8 @@ static int startiface(char *dev, struct hostent *hp) ifr.ifr_flags |= IFF_RUNNING; if (ioctl(fd, SIOCSIFFLAGS, &ifr) < 0) { - perror("kissattach: SIOCSIFFLAGS"); + fprintf(stderr, "%s: ", progname); + perror("SIOCSIFFLAGS"); return FALSE; } @@ -198,11 +215,19 @@ int main(int argc, char *argv[]) int v = 4; struct hostent *hp = NULL; - while ((fd = getopt(argc, argv, "i:lm:v")) != -1) { + progname = basename(argv[0]); + + if (!strcmp(progname, "spattach")) + disc = N_6PACK; + + while ((fd = getopt(argc, argv, "6i:lm:v")) != -1) { switch (fd) { + case '6': + disc = N_6PACK; + break; case 'i': if ((hp = gethostbyname(optarg)) == NULL) { - fprintf(stderr, "kissattach: invalid internet name/address - %s\n", optarg); + fprintf(stderr, "%s: invalid internet name/address - %s\n", progname, optarg); return 1; } break; @@ -211,27 +236,27 @@ int main(int argc, char *argv[]) break; case 'm': if ((mtu = atoi(optarg)) <= 0) { - fprintf(stderr, "kissattach: invalid mtu size - %s\n", optarg); + fprintf(stderr, "%s: invalid mtu size - %s\n", progname, optarg); return 1; } break; case 'v': - printf("kissattach: %s\n", VERSION); + printf("%s: %s\n", progname, VERSION); return 0; case ':': case '?': - fprintf(stderr, "usage: kissattach [-i inetaddr] [-l] [-m mtu] [-v] ttyinterface port\n"); + fprintf(stderr, "usage: %s [-i inetaddr] [-l] [-m mtu] [-v] ttyinterface port\n", progname); return 1; } } if ((argc - optind) != 2) { - fprintf(stderr, "usage: kissattach [-i inetaddr] [-l] [-m mtu] [-v] ttyinterface port\n"); + fprintf(stderr, "usage: %s [-i inetaddr] [-l] [-m mtu] [-v] ttyinterface port\n", progname); return 1; } if (tty_is_locked(argv[optind])) { - fprintf(stderr, "kissattach: device %s already in use\n", argv[optind]); + fprintf(stderr, "%s: device %s already in use\n", progname, argv[optind]); return 1; } @@ -239,7 +264,8 @@ int main(int argc, char *argv[]) return 1; if ((fd = open(argv[optind], O_RDONLY | O_NONBLOCK)) == -1) { - perror("kissattach: open"); + fprintf(stderr, "%s: ", progname); + perror("open"); return 1; } @@ -247,12 +273,17 @@ int main(int argc, char *argv[]) return 1; if (ioctl(fd, TIOCSETD, &disc) == -1) { - perror("kissattach: TIOCSETD"); + fprintf(stderr, "%s: Error setting line discipline: ", progname); + perror("TIOCSETD"); + fprintf(stderr, "Are you sure you have enabled %s support in the kernel\n", + disc == N_AX25 ? "MKISS" : "6PACK"); + fprintf(stderr, "or, if you made it a module, that the module is loaded?\n"); return 1; } if (ioctl(fd, SIOCGIFNAME, dev) == -1) { - perror("kissattach: SIOCGIFNAME"); + fprintf(stderr, "%s: ", progname); + perror("SIOCGIFNAME"); return 1; } @@ -261,7 +292,8 @@ int main(int argc, char *argv[]) /* Now set the encapsulation */ if (ioctl(fd, SIOCSIFENCAP, &v) == -1) { - perror("kissattach: SIOCSIFENCAP"); + fprintf(stderr, "%s: ", progname); + perror("SIOCSIFENCAP"); return 1; } @@ -271,7 +303,7 @@ int main(int argc, char *argv[]) printf("AX.25 port %s bound to device %s\n", argv[optind + 1], dev); if (logging) { - openlog("kissattach", LOG_PID, LOG_DAEMON); + openlog(progname, LOG_PID, LOG_DAEMON); syslog(LOG_INFO, "AX.25 port %s bound to device %s\n", argv[optind + 1], dev); } @@ -282,7 +314,7 @@ int main(int argc, char *argv[]) * Become a daemon if we can. */ if (!daemon_start(FALSE)) { - fprintf(stderr, "kissattach: cannot become a daemon\n"); + fprintf(stderr, "%s: cannot become a daemon\n", progname); return 1; } diff --git a/kiss/kissnetd.c b/kiss/kissnetd.c index ff38779..99e31dd 100644 --- a/kiss/kissnetd.c +++ b/kiss/kissnetd.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/kiss/kissparms.c b/kiss/kissparms.c index d761f55..ea0f0bd 100644 --- a/kiss/kissparms.c +++ b/kiss/kissparms.c @@ -21,6 +21,8 @@ #include #endif +#include + #define PARAM_TXDELAY 1 #define PARAM_PERSIST 2 #define PARAM_SLOTTIME 3 diff --git a/kiss/mkiss.8 b/kiss/mkiss.8 index 4c6c973..f629403 100644 --- a/kiss/mkiss.8 +++ b/kiss/mkiss.8 @@ -1,8 +1,8 @@ -.TH MKISS 8 "05 January 1997" Linux "Linux System Managers Manual" +.TH MKISS 8 "4 July 1999" Linux "Linux System Managers Manual" .SH NAME mkiss \- Attach a multi KISS interface .SH SYNOPSIS -.B mkiss [-c] [-h] [-l] [-s speed] [-p] [-v] ttyinterface pty... +.B mkiss [-c] [-f] [-h] [-l] [-s speed] [-p pollrate] [-v] ttyinterface pty... .SH DESCRIPTION .LP .B Mkiss @@ -37,6 +37,11 @@ This enables a one-byte checksum on each incoming and outgoing KISS frame on the serial port. This checksum is used by G8BPQ KISS roms to maintain the integrity of KISS frames. .TP 10 +.BI \-f +This enables a 16-bit checksum on each incoming and outgoing KISS frame on +the serial port. This checksum is used by Flexnet Node and BayCom Mailbox +to maintain the integrity of KISS frames. +.TP 10 .BI \-h Enables hardware handshaking on the serial line to the TNC. The KISS specification states that no hardware flow control shall be used so the @@ -48,9 +53,10 @@ Enables system logging, the default is off. .BI "\-s speed" Set the speed of the serial port. .TP 10 -.BI "\-p" +.BI "\-p pollrate" Enables polling. Polled mode is used by G8BPQ KISS roms to prevent contention on systems where multiple TNCs share the same serial line. +Pollrate is interval between polls (in 100ms units). .TP 10 .BI \-v Display the version. diff --git a/kiss/mkiss.c b/kiss/mkiss.c index 8621ce4..bfdb46d 100644 --- a/kiss/mkiss.c +++ b/kiss/mkiss.c @@ -30,6 +30,11 @@ * system logging. * * 1.06 23/11/96 Tomi Manninen - Added simple support for polled kiss. + * + * 1.07 12/24/97 Deti Fliegl - Added Flexnet/BayCom CRC mode with commandline + * parameter -f + * + * 1.08 xx/xx/99 Tom Mazouch - Adjustable poll interval */ #include @@ -50,6 +55,9 @@ #include +#define FLEX_CRC 2 +#define G8BPQ_CRC 1 + #define SIZE 4096 #define FEND 0300 /* Frame End (0xC0) */ @@ -57,6 +65,7 @@ #define TFEND 0334 /* Transposed Frame End (0xDC) */ #define TFESC 0335 /* Transposed Frame Escape (0xDD) */ +#define ACKREQ 0x0C #define POLL 0x0E /* @@ -69,21 +78,26 @@ static int crc_errors = 0; static int invalid_ports = 0; static int return_polls = 0; -static char *usage_string = "usage: mkiss [-p] [-c] [-h] [-l] [-s speed] [-v] ttyinterface pty ...\n"; +static char *usage_string = "usage: mkiss [-p interval] [-c] [-f] [-h] [-l] [-s speed] [-v] ttyinterface pty ...\n"; static int dump_report = FALSE; static int logging = FALSE; static int crcflag = FALSE; static int hwflag = FALSE; -static int pollflag = FALSE; +static int pollspeed = 0; + +/* CRC-stuff */ +typedef unsigned short int u16; +#define CRCTYP 0x20 +static u16 crctab[256]; struct iface { char *name; /* Interface name (/dev/???) */ int fd; /* File descriptor */ int escaped; /* FESC received? */ - unsigned char crc; /* Incoming frame crc */ + u16 crc; /* Incoming frame crc */ unsigned char obuf[SIZE]; /* TX buffer */ unsigned char *optr; /* Next byte to transmit */ unsigned int errors; /* KISS protocol error count */ @@ -94,6 +108,28 @@ struct iface unsigned long txbytes; /* TX bytes count */ }; +static void init_crc(void) +{ + short int i, j; + u16 accum, data; + + for (i = 0; i < 256; i++) { /* fill table with CRC of values... */ + accum = 0xffff; + data = i; + for (j = 0; j < 8; ++j) { + if ((data^accum) & 0x0001) + /* if msb of data^accum is TRUE */ + /* then shift and subtract poly */ + accum = (accum >> 1) ^ 0x8408; + else + /* otherwise: transparent shift */ + accum >>= 1; + data >>= 1; /* move up next bit for XOR */ + } + crctab[i] = accum; + } +} + static int poll(int fd, int ports) { char buffer[3]; @@ -111,60 +147,88 @@ static int poll(int fd, int ports) return 0; } +static int put_ubyte(unsigned char* s, u16* crc, unsigned char c, int usecrc) +{ + int len = 1; + + if (c == FEND) { + *s++ = FESC; + *s++ = TFEND; + len++; + } else { + *s++ = c; + if (c == FESC) { + *s++ = TFESC; + len++; + } + } + + switch (usecrc) { + case G8BPQ_CRC: + *crc ^= c; /* Adjust checksum */ + break; + case FLEX_CRC: + *crc = (*crc<<8)^crctab[(*crc>>8)^((u16)((c)&255))]; + break; + } + + return len; +} + static int kiss_tx(int fd, int port, unsigned char *s, int len, int usecrc) { unsigned char *ptr = obuf; - unsigned char c; - unsigned char crc = 0; - int first = TRUE; + unsigned char c, cmd; + u16 crc = 0; + int i; + + cmd = s[0] & 0x0F; /* Non-data frames don't get a checksum byte */ - if ((s[0] & 0x0F) != 0) + if (usecrc == G8BPQ_CRC && cmd != 0 && cmd != ACKREQ) usecrc = FALSE; - /* Allow for checksum byte */ - if (usecrc) - len++; - /* * Send an initial FEND character to flush out any * data that may have accumulated in the receiver * due to line noise. */ - *ptr++ = FEND; + if (usecrc == FLEX_CRC) { + crc = 0xffff; + ptr += put_ubyte(ptr, &crc, CRCTYP, usecrc); + c = *s++; + } else { + c = *s++; + c = (c & 0x0F) | (port << 4); + ptr += put_ubyte(ptr, &crc, c, usecrc); + } + /* * For each byte in the packet, send the appropriate * character sequence, according to the SLIP protocol. */ + for(i = 0; i < len - 1; i++) + ptr += put_ubyte(ptr, &crc, s[i], usecrc); - while (len-- > 0) { - c = *s++; - if (first) { /* Control byte */ - c = (c & 0x0F) | (port << 4); - first = FALSE; - } - if (usecrc) { - if (len == 0) /* Now past user data... */ - c = crc; /* ...time to encode cksum */ - else - crc ^= c; /* Adjust checksum */ - } - switch (c) { - case FEND: - *ptr++ = FESC; - *ptr++ = TFEND; - break; - case FESC: - *ptr++ = FESC; - *ptr++ = TFESC; - break; - default: - *ptr++ = c; - break; + /* + * Now the checksum... + */ + switch (usecrc) { + case G8BPQ_CRC: + c = crc & 0xFF; + ptr += put_ubyte(ptr, &crc, c, usecrc); + break; + case FLEX_CRC: + { + u16 u = crc; + ptr += put_ubyte(ptr, &crc, u / 256, usecrc); + ptr += put_ubyte(ptr, &crc, u & 255, usecrc); } + break; } + *ptr++ = FEND; return write(fd, obuf, ptr - obuf); } @@ -176,37 +240,62 @@ static int kiss_rx(struct iface *ifp, unsigned char c, int usecrc) switch (c) { case FEND: len = ifp->optr - ifp->obuf; + if (len != 0 && ifp->escaped) { /* protocol error... */ len = 0; /* ...drop frame */ ifp->errors++; } - if (len != 0 && (ifp->obuf[0] & 0x0F) != 0) { - /* - * Non-data frames don't have checksum. - */ - usecrc = 0; - if ((ifp->obuf[0] & 0x0F) == POLL) { - len = 0; /* drop returned polls */ - return_polls++; - } else - ifp->nondata++; - } - if (len != 0 && usecrc) { - if (ifp->crc != 0) { /* checksum failed... */ - len = 0; /* ...drop frame */ - crc_errors++; - } else - len--; /* delete checksum byte */ + + if (len != 0) { + switch (usecrc) { + case G8BPQ_CRC: + if ((ifp->obuf[0] & 0x0F) != 0) { + /* + * Non-data frames don't have checksum. + */ + usecrc = 0; + if ((ifp->obuf[0] & 0x0F) == POLL) { + /* drop returned polls */ + len = 0; + return_polls++; + } else + ifp->nondata++; + } else { + if ((ifp->crc & 0xFF) != 0) { + /* checksum failed... */ + /* ...drop frame */ + len = 0; + crc_errors++; + } else + /* delete checksum byte */ + len--; + } + break; + case FLEX_CRC: + if (len > 14 && ifp->crc == 0x7070) { + len -= 2; + *ifp->obuf = 0; + } else { + len = 0; + crc_errors++; + } + break; + } } + if (len != 0) { ifp->rxpackets++; ifp->rxbytes += len; } + /* * Clean up. */ ifp->optr = ifp->obuf; - ifp->crc = 0; + if (usecrc == FLEX_CRC) + ifp->crc = 0xffff; + else + ifp->crc = 0; ifp->escaped = FALSE; return len; case FESC: @@ -231,9 +320,20 @@ static int kiss_rx(struct iface *ifp, unsigned char c, int usecrc) } break; } + *ifp->optr++ = c; - if (usecrc) + + switch (usecrc) { + case G8BPQ_CRC: ifp->crc ^= c; + break; + case FLEX_CRC: + ifp->crc = (ifp->crc << 8) ^ crctab[(ifp->crc >> 8) ^ c]; + break; + default: + break; + } + return 0; } @@ -264,9 +364,14 @@ static void report(struct iface *tty, struct iface **pty, int numptys) syslog(LOG_INFO, "Hardware handshaking %sabled.", hwflag ? "en" : "dis"); syslog(LOG_INFO, "G8BPQ checksumming %sabled.", - crcflag ? "en" : "dis"); + crcflag == G8BPQ_CRC ? "en" : "dis"); + syslog(LOG_INFO, "FLEX checksumming %sabled.", + crcflag == FLEX_CRC ? "en" : "dis"); + syslog(LOG_INFO, "polling %sabled.", - pollflag ? "en" : "dis"); + pollspeed ? "en" : "dis"); + if (pollspeed) + syslog(LOG_INFO, "Poll interval %d00ms", pollspeed); syslog(LOG_INFO, "ttyinterface is %s (fd=%d)", tty->name, tty->fd); for (i = 0; i < numptys; i++) syslog(LOG_INFO, "pty%d is %s (fd=%d)", i, pty[i]->name, @@ -297,14 +402,17 @@ int main(int argc, char *argv[]) unsigned char *icp; int topfd; fd_set readfd; - struct timeval timeout; + struct timeval timeout, pollinterval; int retval, numptys, i, size, len; int speed = -1; - while ((size = getopt(argc, argv, "chlps:v")) != -1) { + while ((size = getopt(argc, argv, "cfhlp:s:v")) != -1) { switch (size) { case 'c': - crcflag = TRUE; + crcflag = G8BPQ_CRC; + break; + case 'f': + crcflag = FLEX_CRC; break; case 'h': hwflag = TRUE; @@ -313,7 +421,9 @@ int main(int argc, char *argv[]) logging = TRUE; break; case 'p': - pollflag = TRUE; + pollspeed = atoi(optarg); + pollinterval.tv_sec = pollspeed / 10; + pollinterval.tv_usec = (pollspeed % 10) * 100000L; break; case 's': speed = atoi(optarg); @@ -368,9 +478,13 @@ int main(int argc, char *argv[]) tty->name = argv[optind]; tty_raw(tty->fd, hwflag); - if (speed != -1) tty_speed(tty->fd, speed); + if (speed != -1 && !tty_speed(tty->fd, speed)) { + close(tty->fd); + return 1; + } tty->optr = tty->obuf; topfd = tty->fd; + /* * Make it block again... */ @@ -414,7 +528,7 @@ int main(int argc, char *argv[]) openlog("mkiss", LOG_PID, LOG_DAEMON); syslog(LOG_INFO, "starting"); } - + init_crc(); /* * Loop until an error occurs on a read. */ @@ -424,13 +538,11 @@ int main(int argc, char *argv[]) for (i = 0; i < numptys; i++) FD_SET(pty[i]->fd, &readfd); - if (pollflag) { - timeout.tv_sec = 1; - timeout.tv_usec = 0; - } + if (pollspeed) + timeout = pollinterval; errno = 0; - retval = select(topfd + 1, &readfd, NULL, NULL, pollflag ? &timeout : NULL); + retval = select(topfd + 1, &readfd, NULL, NULL, pollspeed ? &timeout : NULL); if (retval == -1) { if (dump_report) { @@ -445,9 +557,9 @@ int main(int argc, char *argv[]) } /* - * Timer expired. + * Timer expired - let's poll... */ - if (retval == 0 && pollflag) { + if (retval == 0 && pollspeed) { poll(tty->fd, numptys); continue; } @@ -469,7 +581,7 @@ int main(int argc, char *argv[]) pty[i]->txbytes += len; } else invalid_ports++; - if (pollflag) + if (pollspeed) poll(tty->fd, numptys); } } @@ -496,7 +608,7 @@ int main(int argc, char *argv[]) } } - end: +end: if (logging) closelog(); diff --git a/kiss/spattach.8 b/kiss/spattach.8 new file mode 100644 index 0000000..2a2db22 --- /dev/null +++ b/kiss/spattach.8 @@ -0,0 +1 @@ +.so man8/kissattach.8 -- cgit v1.2.3