home *** CD-ROM | disk | FTP | other *** search
- /*++
- /* NAME
- /* kphys 3
- /* SUMMARY
- /* k protocol packet exchange
- /* PACKAGE
- /* uucp across the TUEnet
- /* SYNOPSIS
- /* #include "kp.h"
- /*
- /* kspack(fd,type,num,size,data)
- /* int fd, num, size;
- /* char type, data[MAXPACKSIZ];
- /*
- /* krpack(fd,num,size,data)
- /* int fd, *num, *size;
- /* char data[MAXPACKSIZ];
- /* DESCRIPTION
- /* The functions in this file take care of data framing and verification.
- /*
- /* Kspack() sends a packet of the specified type and number,
- /* and with len data bytes.
- /*
- /* Krpack() tries to receive a packet and returns: the packet type plus
- /* size and data, or TIME (no packet) or FAIL (bad checksum).
- /*
- /* The data format has been derived from kermit implementations:
- /*
- /* .nf
- /* .in +5
- /* SOH packet header, ASCII control-P
- /* len (size of data, low 6 bits) + 32
- /* len (size of data, high 6 bits) + 32
- /* num (packet number mod 64) + 32
- /* type packet type
- /* check one-byte type-1 kermit checksum
- /*
- /* The header is followed by checksummed data if len >0:
- /*
- /* .nf
- /* .in +5
- /* data len data bytes
- /* check1 (upper 2 bits of type-3 kermit 16-bit checksum) + 32
- /* check2 (middle 6 bits of type-3 kermit 16-bit checksum) + 32
- /* check3 (lower 6 bits of type-3 kermit 16-bit checksum) + 32
- /*
- /* Every packet is followed by an ASCII carriage return, which is
- /* ignored upon reception of a packet. It prevents timeout errors
- /* when one byte gets lost (the most common case).
- /* BUGS
- /* It is yet another convention for data framing.
- /* AUTHOR(S)
- /* Wietse Venema
- /* Eindhoven University of Technology
- /* Department of Mathematics and Computer Science
- /* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
- /* CREATION DATE
- /* Mon Feb 3 13:38:14 MET 1986
- /* LAST MODIFICATION
- /* 90/01/22 13:01:56
- /* VERSION/RELEASE
- /* 2.1
- /*--*/
-
- #include <signal.h>
- #include <setjmp.h>
- #include "kp.h"
-
- #define READS(fd,ch) {if (read(fd,&ch,1) < 0) clkint(); if ((ch &= 0177) == SOH) goto SYNC;}
-
- jmp_buf env; /* Environment ptr for timeout longjump */
-
- clkint() /* Timer interrupt handler */
- {
- longjmp(env,TRUE); /* Tell krpack to give up */
- }
-
- kspack(fd,type,num,len,data)
- int fd;
- char type, *data;
- int num, len;
- {
- char chksum, header[6], chk[3]; /* Checksums, header */
-
- DEBUG(7,"xmt: type %c\n",type);
- if (len > 0)
- DEBUG(7,"xmt: data %d\n",len);
-
- header[0] = SOH; /* Packet marker (SOH) */
- header[1] = tosix(len); /* Send the character count */
- chksum = header[1]; /* Initialize the checksum */
- header[2] = tosix(len>>OUT); /* Send the character count */
- chksum += header[2]; /* Update checksum */
- header[3] = tochar(num); /* Packet number */
- chksum += header[3]; /* Update checksum */
- header[4] = type; /* Packet type */
- chksum += header[4]; /* Update checksum */
- chksum = (((chksum&0300) >> 6)+chksum)&077; /* Compute header checksum */
- header[5] = tochar(chksum); /* Put it in the packet */
- write(fd,header,6); /* Send the header */
-
- if (len > 0) { /* Make data packet */
- write(fd,data,len); /* Send data */
- chk3(data,len,chk); /* Compute 16-bit checksum */
- write(fd,chk,3); /* Send checksum */
- }
- write(fd,"\r",1); /* Extra-packet line terminator */
- }
-
- krpack(fd,num,len,data)
- int fd;
- int *num; /* Packet number */
- int *len; /* Packet length */
- char *data; /* Packet data */
- {
- int i; /* Data character number, loop exit */
- char t, /* Current input character */
- type, /* Packet type */
- rchk[3], /* Data checksum from host */
- cchk[3], /* Data checksum computed here */
- cchksum, /* Our (computed) checksum */
- rchksum; /* Header checksum from other host */
-
- if (setjmp(env)) {
- DEBUG(7,"rcv: timed out\n","");
- return TIME; /* Timed out */
- }
- signal(SIGALRM,clkint); /* Setup the timeout */
- alarm(TIMEOUT);
-
- for (;;) /* Wait for packet header */
- READS(fd,t);
- SYNC: /* Got SOH */
- alarm(TIMEOUT);
- DEBUG(7,"rcv: found sync\n","");
- READS(fd,t); /* Get character */
- cchksum = t; /* Start the checksum */
- *len = unchar(t); /* Character count, low six bits */
-
- READS(fd,t); /* Get character */
- cchksum += t; /* Update checksum */
- *len += (unchar(t)<<OUT); /* Character count, high six bits */
-
- READS(fd,t); /* Get character */
- cchksum += t; /* Update checksum */
- *num = unchar(t); /* Packet number */
-
- READS(fd,t); /* Get character */
- cchksum += t; /* Update checksum */
- type = t; /* Packet type */
-
- READS(fd,t); /* Get header checksum */
- rchksum = unchar(t); /* Convert to numeric */
- /* Fold in bits 7,8 to compute */
- cchksum = (((cchksum&0300) >> 6)+cchksum)&077; /* header checksum */
-
- if (cchksum != rchksum) {
- DEBUG(7,"rcv: bad header\n","");
- alarm(0); /* Disable the timer interrupt */
- return FAIL;
- }
- DEBUG(7,"rcv: type %c\n",type);
-
- if ((*len > 0) && (data != NULLP))
- {
- for (i=0; i<*len; i++) /* The data itself, if any */
- { /* Loop for character count */
- READS(fd,t); /* Get character */
- data[i] = t; /* Keep data */
- }
-
- for (i=0; i<3; i++) /* 16-bit CRC checksum */
- {
- READS(fd,t); /* Get character */
- rchk[i] = t; /* Keep data */
- }
-
- chk3(data,*len,cchk); /* Compute CRC */
- if (strncmp(rchk,cchk,3)) { /* Check with received CRC */
- DEBUG(7,"rcv: bad data\n","");
- alarm(0); /* Disable the timer interrupt */
- return FAIL;
- }
- DEBUG(7,"rcv: data %d\n",*len);
- }
- alarm(0); /* Disable the timer interrupt */
- return(type); /* All OK, return packet type */
- }
-
- /* C H K 3 -- Compute a type-3 Kermit block check. */
- /*
- Calculate the 16-bit CRC of a string using a byte-oriented
- tableless algorithm invented by Andy Lowry (Columbia University). The
- magic number 010201 is derived from the CRC-CCITT polynomial x^16+x^12+x^5+1.
- */
- static chk3(s,len,chk)
- char *s, *chk;
- int len;
- {
- unsigned int c, q;
- long crc = 0;
-
- while (len--) {
- c = *s++;
- q = (crc ^ c) & 017; /* Low-order nibble */
- crc = (crc >> 4) ^ (q * 010201);
- q = (crc ^ (c >> 4)) & 017; /* High order nibble */
- crc = (crc >> 4) ^ (q * 010201);
- }
- *chk++ = tochar(((unsigned)(crc & 0170000)) >> 12);
- *chk++ = tochar((crc & 07700) >> 6);
- *chk++ = tochar(crc & 077);
- }
-