From @nic.funet.fi:
[email protected] Sat Jun 18 00:00:19 1994
Received: from ucsd.edu ([132.239.254.201]) by nic.funet.fi with SMTP id <92228-3>; Sat, 18 Jun 1994 00:00:16 +0300
Received: by ucsd.edu; id NAA20506
sendmail 8.6.9/UCSD-2.2-sun
Fri, 17 Jun 1994 13:30:50 -0700 for ham-bsd-list
Received: from nothing.ucsd.edu by ucsd.edu; id NAA20502
sendmail 8.6.9/UCSD-2.2-sun via ESMTP
Fri, 17 Jun 1994 13:30:48 -0700 for <
[email protected]>
Received: from localhost by nothing.ucsd.edu (8.6.3/UCSDGENERIC.4)
id NAA06577 to
[email protected]; Fri, 17 Jun 1994 13:30:48 -0700
Date: Fri, 17 Jun 1994 23:30:48 +0300
From:
[email protected] (Brian Kantor)
Message-Id: <
[email protected]>
To:
[email protected]
Subject: kissmon.c
Status: RO
/*
* a simple program that expects to find a KISS TNC at 9600 bps serial
* speed on /dev/tty01 (COM2) of your BSDI 1.1 system. Displays common
* packet formats on the screen. Does not transmit.
*
* Brian Kantor June 1994
*/
#include <stdio.h>
#include <unistd.h>
#include <termios.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#define DEBUG 1
#define FR_END 0xc0
#define FR_ESC 0xdb
#define T_FR_END 0xdc
#define T_FR_ESC 0xdd
int trace = 0xff;
int tnc;
char tncdev[32];
unsigned char tncbuf[1024];
int plen;
int errcnt;
extern int errno;
main()
{
int c;
int escaped, framed;
escaped = 0;
framed = 0;
plen = 0;
strcpy(tncdev, "/dev/tty01");
opendev();
while ( (c = gettncchar()) != -1 )
{
if (c == FR_END)
{
if ( (trace & 1) && (plen > 0) )
{
printf("\nKISS len=%d\n", plen);
}
/* protocol upcall */
if (plen > 0 && tncbuf[0] == 0x00)
ax25in(tncbuf+1, plen-1);
framed = !framed;
plen = 0;
errcnt = 0;
continue;
}
if (!framed)
continue;
if (c == FR_ESC)
{
escaped = 1;
continue;
}
/* escaped chars */
if (escaped)
{
escaped = 0;
if (c == T_FR_END)
{
tncbuf[plen++] = FR_END;
continue;
}
if (c == T_FR_ESC)
{
tncbuf[plen++] = FR_ESC;
continue;
}
/* bad frame, flush it */
plen = 0;
continue;
}
tncbuf[plen++] = c;
}
}
/*
* read a character from the tnc. If there is an I/O error,
* return -1. If it times out, return 0. Else return the char
* timeout is in seconds; 0 = poll
*/
int
gettncchar()
{
unsigned char c[2];
/* so get the char already */
if (read(tnc, c, 1) != 1)
{
perror("tnc read");
return(-1);
}
c[0] &= 0x00FF; /* trim to 8 bits */
return((int) c[0]);
}
/* open the tnc */
int
opendev()
{
struct termios ti;
int err;
tnc = open(tncdev, (O_RDWR|O_EXCL), 0);
if (tnc < 0)
{
perror(tncdev);
return(errno);
}
if (DEBUG)
printf("%s is open on fd %d\n", tncdev, tnc);
/* get current port settings */
err = tcgetattr(tnc, &ti);
if (err < 0)
{
perror(tncdev);
return(errno);
}
/*
* set tty params to 9600 no parity
* this is for BSDI 1.1 God help you on other systems.
*/
cfmakeraw(&ti);
cfsetspeed(&ti, 9600);
ti.c_iflag |= IGNBRK; /* ignore breaks */
ti.c_cflag &= ~CSIZE; /* 8-bit bytes */
ti.c_cflag |= CS8;
ti.c_cflag &= ~CSTOPB; /* one stop bit */
ti.c_cflag &= ~PARENB; /* no parity */
ti.c_cc[VMIN] = 1; /* read() can return 1 byte */
ti.c_cc[VTIME] = 0; /* no time out */
errno = 0;
err = tcsetattr(tnc, TCSANOW, &ti);
if (err < 0)
{
perror(tncdev);
return(errno);
}
return 0;
}
ax25in(p,l)
unsigned char *p;
int l;
{
int i;
int addrend;
char v;
unsigned char op;
unsigned char pid;
char ps[16];
/* long enough to be meaningful? */
if (l < 15)
return;
if (trace & 2)
{
v = '1';
if ( (*(p+6) & 0x80 == 1) && (*(p+12) & 0x80 == 0) )
v = 'C';
if ( (*(p+6) & 0x80 == 0) && (*(p+12) & 0x80 == 1) )
v = 'R';
printf("AX.25 %c len=%d: ", v, l);
addrend = printaxaddr(p+7, 0); /* source addr */
printf("-> ");
printaxaddr(p, 0); /* dest addr */
if (!addrend)
printf("via ");
p += 14;
l -= 14;
/* print variable number of digipeater addresses */
while (!addrend)
{
addrend = printaxaddr(p, 1);
p += 7;
l -= 7;
}
op = *p++ & 0x00FF;
l -= 2;
switch (pid = *p++ & 0x00FF)
{
default: sprintf(ps, "%02x", pid); break;
case 0xCC: strcpy(ps, "IP"); break;
case 0xCD: strcpy(ps, "ARP"); break;
case 0xCF: strcpy(ps, "NR"); break;
case 0xF0: strcpy(ps, "text"); break;
}
/* interpret the opcode */
if ((op & 1) == 0)
{
printf("<I> R=%d S=%d P=%d dlen=%d pid=%s\n",
(op & 0xE0) >> 5, (op & 0x0E) >> 1,
(op & 0x10) >> 4, l, ps);
}
else if ((op & 0xEF) == 0x03)
{
printf("<UI> P=%d dlen=%d pid=%s\n",
(op & 0x10) >> 4, l, ps);
}
else if ((op & 0xEF) == 0x2F)
{
printf("<SABM> P=%d\n", (op & 0x10) >> 4);
}
else if ((op & 0xEF) == 0x43)
{
printf("<DISC> P=%d\n", (op & 0x10) >> 4);
}
else if ((op & 0xEF) == 0x0F)
{
printf("<DM> P=%d\n", (op & 0x10) >> 4);
}
else if ((op & 0xEF) == 0x63)
{
printf("<UA> P=%d\n", (op & 0x10) >> 4);
}
else if ((op & 0xEF) == 0x87)
{
printf("<FRMR> P=%d\n", (op & 0x10) >> 4);
hexout(p+2, 3);
}
else if ((op & 0x0F) == 0x01)
{
printf("<RR> R=%d PF=%d\n",
(op & 0xE0) >> 5, (op & 0x10) >> 4);
}
else if ((op & 0x0F) == 0x05)
{
printf("<RNR> R=%d PF=%d\n",
(op & 0xE0) >> 5, (op & 0x10) >> 4);
}
else if ((op & 0x0F) == 0x09)
{
printf("<REJ> R=%d PF=%d\n",
(op & 0xE0) >> 5, (op & 0x10) >> 4);
}
else
{
printf("unknown %02x\n", *p);
}
fflush(stdout);
}
/* I or UI, call the appropriate embedded protocol handler */
if ((op & 1) == 0 || (op & 0xEF) == 0x03)
{
switch(pid)
{
default: break;
case 0xCC: ipin(p, l);
break;
case 0xCD: arpin(p, l);
break;
case 0xCF: nrin(p, l);
break;
case 0xF0: if (trace & 3)
hexout(p, l);
break;
}
}
}
/* returns 1 if the address printed was flagged as the last one */
int
printaxaddr(p, digi)
unsigned char *p;
int digi;
{
char c;
c = (*p++) >> 1; if (c > ' ') putchar(c);
c = (*p++) >> 1; if (c > ' ') putchar(c);
c = (*p++) >> 1; if (c > ' ') putchar(c);
c = (*p++) >> 1; if (c > ' ') putchar(c);
c = (*p++) >> 1; if (c > ' ') putchar(c);
c = (*p++) >> 1; if (c > ' ') putchar(c);
printf("-%d%c ", ((*p >> 1) & 0x0f), ((digi && (*p&0x80)>>7)?'*':' '));
return(*p & 1);
}
/* pretty-print a string in hex */
hexout(s,l)
unsigned char *s;
int l;
{
int i, j;
char buf[17];
for (i=0; i < l; i++)
{
if ( (i % 16) == 0)
{
if (i > 0)
printf(" %s\n", buf);
printf("%04d", i);
strcpy(buf, " ");
}
if ( (i % 8) == 0)
printf("- ");
printf("%02x ", *s);
buf[i%16] = (isprint(*s) ? *s : '_');
s++;
}
j = (i % 16 == 0) ? 0 : (16 - (i % 16));
if (j > 7)
printf(" ");
while (j--)
printf(" ");
printf(" %s\n", buf);
fflush(stdout);
}
ipin(p, l)
char *p;
int l;
{
printf("IP len=%d\n", l);
hexout(p, l);
}
arpin(p, l)
char *p;
int l;
{
printf("ARP len=%d\n", l);
hexout(p, l);
}
nrin(p, l)
unsigned char *p;
int l;
{
int op;
printf("NETROM len=%d ", l);
/* network header */
printaxaddr(p, 0); p += 7;
printf("-> ");
printaxaddr(p, 0); p += 7;
printf("ttl=%x ", *p++);
/* transport header */
printf("ckt=%x/%x ", *p++, *p++);
printf("T=%x R=%x ", *p++, *p++);
/* flags */
if ((*p) & 0x80)
printf("CHOKE ");
if ((*p) & 0x40)
printf("NAK ");
if ((*p) & 0x20)
printf("MORE ");
if ((*p) & 0x10)
printf("rsvd ");
op = (*p++) & 0x0f;
switch (op)
{
case 0x01: printf("ConReq winreq=%x from ", *p++);
printaxaddr(p, 0); p += 7;
printf("@ ");
printaxaddr(p, 0); p += 7;
puts("");
break;
case 0x02: printf("ConAck winack=%x\n", *p++);
break;
case 0x03: printf("DiscReq\n");
break;
case 0x04: printf("DiscAck\n");
break;
case 0x05: printf("Info\n");
hexout(p, l);
break;
case 0x06: printf("InfoAck\n");
break;
default: printf("op=%02x ", op);
break;
}
}