Index: kiss/mkiss.8 =================================================================== RCS file: /home/ax25-cvs/ax25-tools/kiss/mkiss.8,v retrieving revision 1.4 diff -u -r1.4 mkiss.8 --- kiss/mkiss.8 20 Jan 2009 18:31:25 -0000 1.4 +++ kiss/mkiss.8 11 Sep 2009 15:21:00 -0000 @@ -1,22 +1,33 @@ -.TH MKISS 8 "4 July 1999" Linux "Linux System Managers Manual" +.TH MKISS 8 "2009-Sep-11" Linux "Linux System Managers Manual" .SH NAME mkiss \- Attach a multi KISS interface .SH SYNOPSIS -.B mkiss [-c] [-f] [-h] [-l] [-s speed] [-p pollrate] [-v] [-x n_ptmx] ttyinterface pty .. +.IP \fBmkiss\fR 6em +.RB [ \-c ] +.RB [ \-f ] +.RB [ \-h ] +.RB [ \-l ] +.\" .RB [ \-S ] +.RB [ "\-s \fIspeed\fR" ] +.RB [ "-p \fIpollrate\fR" ] +.RB [ \-v ] +.I serialport ax25-callsigns... .SH DESCRIPTION .LP -.B Mkiss +The +.B mkiss allows dual port TNCs or multiple TNCs sharing the same serial port to be -used with the Linux AX.25 kernel software. The AX.25 software has no support -for dual port TNCs or multiple TNCs charing the same serial line. The -different ports are addressed by encoding the port number in the control -byte of every kiss frame. -.B Mkiss -watches a serial port, and routes kiss frames to/from the pseudo ttys. The -other side of the pseudo ttys are then attached with -.B kissattach -as normal. -.sp 1 +used with the Linux AX.25 kernel software. +The kernel AX.25 software has no support for dual port TNCs or multiple TNCs +sharing the same serial line. +The different KISS-sub-ports are addressed by encoding the port number in +the control byte of every KISS frame. +.LP +The +.B mkiss +watches a real serial port, demultiplexes KISS-sub-ports from it, and routes +the frames to separately created kernel attached sub-interfaces. +.LP Statistics about the operation of .B mkiss may be obtained by sending the SIGUSR1 signal to the running program. On @@ -24,18 +35,12 @@ .B mkiss will print a set of statistics to the system log if logging has been enabled. -.sp 1 -Although mention is made of using pseudo ttys as the last arguments, -these devices may be normal serial ports. However -.B mkiss -provides no way in which to set their speed, the speed must therefore be set -by some other method. .SH OPTIONS .TP 10 .BI \-c 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. +integrity of KISS frames on serial line. .TP 10 .BI \-f This enables a 16-bit checksum on each incoming and outgoing KISS frame on @@ -61,15 +66,31 @@ .BI \-v Display the version. .TP 10 -.BI "\-x number" -This option is for Unix98 PTYs. It allocates "number" ptys; their names are written to stdout. When -x is used, the pty arguments are optional. +.BI serialport +A device definition opening a real serial port (/dev/ttyS0, /dev/ttyUSB7, ...) +.TP 10 +.BI ax25-callsigns... +As many callsigns (or AX.25 port identifiers) listed at +.I /etc/ax25/axports +file as there are actively used KISS-sub-ids. +Inactive sub-ids are marked with +.B "\-" +character. .SH "SEE ALSO" .BR kissattach (8), .BR ifconfig (8), .BR kill (1). +.SH BUGS +Need to add support for SMACK CRC. .SH AUTHORS -Tomi Manninen OH2BNS +Tomi Manninen OH2BNS, 1990es +.br +Jonathan Naylor G4KLX, 1990es +.br +Kevin Uhlir N0BEL, 1990es +.br +Matti Aarnio OH2MQK, 2009 .br -Jonathan Naylor G4KLX +Ralf Baechle DL5RB, 2009 .br -Kevin Uhlir N0BEL +Thomas Osterried DL9SAU, 2009 Index: kiss/mkiss.c =================================================================== RCS file: /home/ax25-cvs/ax25-tools/kiss/mkiss.c,v retrieving revision 1.6 diff -u -r1.6 mkiss.c --- kiss/mkiss.c 20 Jan 2009 18:31:25 -0000 1.6 +++ kiss/mkiss.c 11 Sep 2009 15:21:00 -0000 @@ -35,6 +35,9 @@ * parameter -f * * 1.08 xx/xx/99 Tom Mazouch - Adjustable poll interval + * + * 1.09 2009-09-11 Matti Aarnio - do openpty() for each intermix pty, fork(), + * and then do some jolly setup magic to run kissattach.. */ #include @@ -53,12 +56,14 @@ #include #include #include +#include #include #include #include +#define SMACK_CRC 3 #define FLEX_CRC 2 #define G8BPQ_CRC 1 @@ -78,18 +83,18 @@ static unsigned char ibuf[SIZE]; /* buffer for input operations */ static unsigned char obuf[SIZE]; /* buffer for kiss_tx() */ -static int crc_errors = 0; -static int invalid_ports = 0; -static int return_polls = 0; - -static char *usage_string = "usage: mkiss [-p interval] [-c] [-f] [-h] [-l] [-s speed] [-v] [-x ] ttyinterface pty ..\n"; - -static int dump_report = FALSE; - -static int logging = FALSE; -static int crcflag = FALSE; -static int hwflag = FALSE; -static int pollspeed = 0; +static int crc_errors; +static int invalid_ports; +static int return_polls; + +static char *usage_string = "usage: mkiss [-p interval] [-c] [-f] [-h] [-l] [-s speed] [-v] serialport {ax25-callsign, ...}\n"; + +static int dump_report; + +static int logging; +static int crcflag; +static int hwflag; +static int pollspeed; /* CRC-stuff */ typedef unsigned short int u16; @@ -98,7 +103,8 @@ struct iface { - char *name; /* Interface name (/dev/???) */ + const char *name; /* Interface name (/dev/???) */ + const char *callsign; /* Callsign */ int fd; /* File descriptor */ int escaped; /* FESC received? */ u16 crc; /* Incoming frame crc */ @@ -110,13 +116,11 @@ unsigned int txpackets; /* TX frames count */ unsigned long rxbytes; /* RX bytes count */ unsigned long txbytes; /* TX bytes count */ - char namepts[PATH_MAX]; /* name of the unix98 pts slaves, which - * the client has to use */ }; -static struct iface *tty = NULL; -static struct iface *pty[16] = { NULL }; -static int numptys = 0; +static struct iface *tty; +static struct iface *pty[16]; +static int numptys; static void init_crc(void) { @@ -240,7 +244,18 @@ } *ptr++ = FEND; - return write(fd, obuf, ptr - obuf); + + /* Make sure to write it all */ + len = ptr - obuf; + ptr = obuf; + while (len > 0) { + i = write(fd, ptr, len); + if (i > 0) { + len -= i; + ptr += i; + } + } + return i; } static int kiss_rx(struct iface *ifp, unsigned char c, int usecrc) @@ -361,8 +376,8 @@ free(tty); for (i = 0; i < numptys; i++) { - tty_unlock(pty[i]->name); - close(pty[i]->fd); + if (pty[i]->fd >= 0) + close(pty[i]->fd); free(pty[i]); } @@ -395,9 +410,11 @@ 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++) + for (i = 0; i < numptys; i++) { + if (pty[i]->fd < 0) continue; syslog(LOG_INFO, "pty%d is %s (fd=%d)", i, pty[i]->name, pty[i]->fd); + } syslog(LOG_INFO, "Checksum errors: %d", crc_errors); syslog(LOG_INFO, "Invalid ports: %d", invalid_ports); syslog(LOG_INFO, "Returned polls: %d", return_polls); @@ -425,11 +442,12 @@ struct timeval timeout, pollinterval; int retval, i, size, len; int speed = -1; - int ptmxdevices = 0; - char *npts; + int maxptys = 16; /* .. except for SMACK the max is 8 */ int wrote_info = 0; - while ((size = getopt(argc, argv, "cfhlp:s:vx:")) != -1) { + pollinterval.tv_sec = pollinterval.tv_usec = 0; + + while ((size = getopt(argc, argv, "cfhlp:Ss:v")) != -1) { switch (size) { case 'c': crcflag = G8BPQ_CRC; @@ -445,60 +463,43 @@ break; case 'p': pollspeed = atoi(optarg); - pollinterval.tv_sec = pollspeed / 10; + pollinterval.tv_sec = pollspeed / 10; pollinterval.tv_usec = (pollspeed % 10) * 100000L; break; + case 'S': + crcflag = SMACK_CRC; + maxptys = 8; + break; case 's': speed = atoi(optarg); break; - case 'x': - ptmxdevices = atoi(optarg); - if (ptmxdevices < 1 || ptmxdevices > 16) { - fprintf(stderr, "mkiss: too %s devices\n", ptmxdevices < 1 ? "few" : "many"); - return 1; - } - break; case 'v': printf("mkiss: %s\n", VERSION); return 1; - case ':': - case '?': + default: fprintf(stderr, usage_string); return 1; } } - if ((argc - optind) < 2 && ptmxdevices == 0) { - fprintf(stderr, usage_string); - return 1; - } - - if ((argc - optind) < 1 && ptmxdevices > 0) { + if ((argc - optind) < 2) { fprintf(stderr, usage_string); return 1; } numptys = argc - optind - 1; - if ((numptys + ptmxdevices) > 16) { - fprintf(stderr, "mkiss: max 16 pty interfaces allowed.\n"); + if (numptys > maxptys) { + fprintf(stderr, "mkiss: max %d pty interfaces allowed.\n",maxptys); return 1; } /* - * Check for lock files before opening any TTYs + * Check for lock files before opening any PTYs */ if (tty_is_locked(argv[optind])) { fprintf(stderr, "mkiss: tty %s is locked by another process\n", argv[optind]); return 1; } - for (i = 0; i < numptys; i++) { - if (!strcmp("/dev/ptmx", argv[optind + i + 1])) - continue; - if (tty_is_locked(argv[optind + i + 1])) { - fprintf(stderr, "mkiss: pty %s is locked by another process\n", argv[optind + i + 1]); - return 1; - } - } /* * Open and configure the tty interface. Open() is @@ -523,7 +524,6 @@ } tty->optr = tty->obuf; topfd = tty->fd; - tty->namepts[0] = '\0'; /* * Make it block again... @@ -533,59 +533,64 @@ /* * Open and configure the pty interfaces */ - for (i = 0; i < numptys+ptmxdevices; i++) { - static char name_ptmx[] = "/dev/ptmx"; - char *pty_name = (i < numptys ? argv[optind+i+1] : name_ptmx); + for (i = 0; i < numptys; i++) { + int slave, rc; + const char *callsign = argv[optind + i + 1]; if ((pty[i] = calloc(1, sizeof(struct iface))) == NULL) { perror("mkiss: malloc"); return 1; } - if ((pty[i]->fd = open(pty_name, O_RDWR)) == -1) { - perror("mkiss: open"); + + if (strcmp(callsign,"-")==0) { + /* A dummy, nobody there! */ + pty[i]->fd = -1; + continue; + } + + if (openpty(&pty[i]->fd, &slave, NULL, NULL, NULL)) { + perror("mkiss: openpty() failed."); return 1; } - pty[i]->name = pty_name; + + pty[i]->name = strdup(ttyname(slave)); /* Safe way to ask slave tty name */ + pty[i]->callsign = strdup(callsign); + tty_raw(pty[i]->fd, FALSE); pty[i]->optr = pty[i]->obuf; topfd = (pty[i]->fd > topfd) ? pty[i]->fd : topfd; - pty[i]->namepts[0] = '\0'; - if (!strcmp(pty[i]->name, "/dev/ptmx")) { - /* get name of pts-device */ - if ((npts = ptsname(pty[i]->fd)) == NULL) { - fprintf(stderr, "mkiss: Cannot get name of pts-device.\n"); - return 1; - } - strncpy(pty[i]->namepts, npts, PATH_MAX-1); - pty[i]->namepts[PATH_MAX-1] = '\0'; - /* unlock pts-device */ - if (unlockpt(pty[i]->fd) == -1) { - fprintf(stderr, "mkiss: Cannot unlock pts-device %s\n", pty[i]->namepts); - return 1; + rc = fork(); + if (rc == 0) { + char cmdbuf[300]; + /* child */ + if (slave != 0) { + dup2(slave, 0); + close(slave); } - if (wrote_info == 0) - printf("\nAwaiting client connects on:\n"); - else - printf(" "); - printf("%s", pty[i]->namepts); - wrote_info = 1; + for (i = 3; i <= topfd; ++i) close(i); + + sprintf(cmdbuf, "exec kissattach -- - %s", callsign); + system(cmdbuf); + _exit(99); + } else if (rc > 0) { + /* parent */ + close(slave); + } else { + /* error */ + perror("mkiss: fork()"); + return 1; } + } if (wrote_info > 0) printf("\n"); - numptys=numptys+ptmxdevices; - /* * Now all the ports are open, lock them. */ tty_lock(tty->name); - for (i = 0; i < numptys; i++) { - if (pty[i]->namepts[0] == '\0') - tty_lock(pty[i]->name); - } if (logging) { openlog("mkiss", LOG_PID, LOG_DAEMON); @@ -617,7 +622,8 @@ FD_ZERO(&readfd); FD_SET(tty->fd, &readfd); for (i = 0; i < numptys; i++) - FD_SET(pty[i]->fd, &readfd); + if (pty[i]->fd >= 0) + FD_SET(pty[i]->fd, &readfd); if (pollspeed) timeout = pollinterval; @@ -656,7 +662,8 @@ } for (icp = ibuf; size > 0; size--, icp++) { if ((len = kiss_rx(tty, *icp, crcflag)) != 0) { - if ((i = (*tty->obuf & 0xF0) >> 4) < numptys) { + if ((i = (*tty->obuf & 0xF0) >> 4) < numptys && + pty[i]->fd >= 0) { kiss_tx(pty[i]->fd, 0, tty->obuf, len, FALSE); pty[i]->txpackets++; pty[i]->txbytes += len; @@ -672,7 +679,7 @@ /* * A character has arrived on pty[i]. */ - if (FD_ISSET(pty[i]->fd, &readfd)) { + if (pty[i]->fd >= 0 && FD_ISSET(pty[i]->fd, &readfd)) { if ((size = read(pty[i]->fd, ibuf, SIZE)) < 0 && errno != EINTR) { if (logging) syslog(LOG_ERR, "pty[%d]->fd: %m\n", i); @@ -698,8 +705,8 @@ free(tty); for (i = 0; i < numptys; i++) { - tty_unlock(pty[i]->name); - close(pty[i]->fd); + if (pty[i]->fd >= 0) + close(pty[i]->fd); free(pty[i]); } Index: kiss/Makefile.am =================================================================== RCS file: /home/ax25-cvs/ax25-tools/kiss/Makefile.am,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 Makefile.am --- kiss/Makefile.am 10 Apr 2001 02:10:36 -0000 1.1.1.1 +++ kiss/Makefile.am 11 Sep 2009 15:21:00 -0000 @@ -3,7 +3,7 @@ sbin_PROGRAMS = kissattach kissnetd kissparms mkiss net2kiss -LDADD= $(AX25_LIB) +LDADD= $(AX25_LIB) -lutil man_MANS = kissattach.8 spattach.8 kissnetd.8 kissparms.8 mkiss.8 net2kiss.8