pk1.c
来自「unix v7是最后一个广泛发布的研究型UNIX版本」· C语言 代码 · 共 375 行
C
375 行
#define USER 1#include <stdio.h>#include <sys/pk.p>#include <sys/param.h>#include <sys/pk.h>#include <sys/buf.h>#include <setjmp.h>#include <signal.h>#define PKTIME 10int Errorrate;int Conbad = 0;int Ntimeout = 0;#define CONBAD 5#define NTIMEOUT 50/* * packet driver support routines * */struct pack *pklines[NPLINES];/* * start initial synchronization. */struct pack *pkopen(ifn, ofn)int ifn, ofn;{ struct pack *pk; char **bp; int i; if (++pkactive >= NPLINES) return(NULL); if ((pk = (struct pack *) malloc(sizeof (struct pack))) == NULL) return(NULL); pkzero((caddr_t) pk, sizeof (struct pack)); pk->p_ifn = ifn; pk->p_ofn = ofn; pk->p_xsize = pk->p_rsize = PACKSIZE; pk->p_rwindow = pk->p_swindow = WINDOWS; /* allocate input windows */ for (i = 0; i < pk->p_rwindow; i++) { if ((bp = (char **) GETEPACK) == NULL) break; *bp = (char *) pk->p_ipool; pk->p_ipool = bp; } if (i == 0) return(NULL); pk->p_rwindow = i; /* start synchronization */ pk->p_msg = pk->p_rmsg = M_INITA; for (i = 0; i < NPLINES; i++) { if (pklines[i] == NULL) { pklines[i] = pk; break; } } if (i >= NPLINES) return(NULL); pkoutput(pk); while ((pk->p_state & LIVE) == 0) { PKGETPKT(pk); } pkreset(pk); return(pk);}/* * input framing and block checking. * frame layout for most devices is: * * S|K|X|Y|C|Z| ... data ... | * * where S == initial synch byte * K == encoded frame size (indexes pksizes[]) * X, Y == block check bytes * C == control byte * Z == XOR of header (K^X^Y^C) * data == 0 or more data bytes * */int pksizes[] = { 1, 32, 64, 128, 256, 512, 1024, 2048, 4096, 1};#define GETRIES 5/* * Pseudo-dma byte collection. */pkgetpack(ipk)struct pack *ipk;{ int ret, k, tries; register char *p; struct pack *pk; struct header *h; unsigned short sum; int ifn; char **bp; char hdchk; if (Conbad > CONBAD /* || Ntimeout > NTIMEOUT */) pkfail(); pk = PADDR; ifn = pk->p_ifn; /* find HEADER */ for (tries = 0; tries < GETRIES; ) { p = (caddr_t) &pk->p_ihbuf; if ((ret = pkcget(ifn, p, 1)) < 0) { /* set up retransmit or REJ */ tries++; pk->p_msg |= pk->p_rmsg; if (pk->p_msg == 0) pk->p_msg |= M_RR; if ((pk->p_state & LIVE) == LIVE) pk->p_state |= RXMIT; pkoutput(pk); continue; } if (*p != SYN) continue; p++; ret = pkcget(ifn, p, HDRSIZ - 1); if (ret == -1) continue; break; } if (tries >= GETRIES) { PKDEBUG(4, "tries = %d\n", tries); pkfail(); } h = (struct header * ) &pk->p_ihbuf; p = (caddr_t) h; hdchk = p[1] ^ p[2] ^ p[3] ^ p[4]; p += 2; sum = (unsigned) *p++; sum |= (unsigned) *p << 8; h->sum = sum; PKDEBUG(7, "rec h->cntl %o\n", (unsigned) h->cntl); k = h->ksize; if (hdchk != h->ccntl) { /* bad header */ PKDEBUG(7, "bad header %o,", hdchk); PKDEBUG(7, "h->ccntl %o\n", h->ccntl); Conbad++; return; } if (k == 9) { if (h->sum + h->cntl == CHECK) { pkcntl(h->cntl, pk); Conbad = 0; PKDEBUG(7, "state - %o\n", pk->p_state); } else { /* bad header */ Conbad++; PKDEBUG(7, "bad header %o\n", h->cntl); pk->p_state |= BADFRAME; } return; } if (k && pksizes[k] == pk->p_rsize) { pk->p_rpr = h->cntl & MOD8; pksack(pk); Conbad = 0; bp = pk->p_ipool; pk->p_ipool = (char **) *bp; if (bp == NULL) { PKDEBUG(7, "bp NULL %s\n", ""); return; } } else { Conbad++; return; } ret = pkcget(pk->p_ifn, (char *) bp, pk->p_rsize); PKASSERT(ret != -1, "PKGETPKT CAN't READ %d", ret); pkdata(h->cntl, h->sum, pk, (char *) bp); return;}pkdata(c, sum, pk, bp)char c;short sum;register struct pack *pk;char **bp;{register x;int t;char m; if (pk->p_state & DRAINO || !(pk->p_state & LIVE)) { pk->p_msg |= pk->p_rmsg; pkoutput(pk); goto drop; } t = next[pk->p_pr]; for(x=pk->p_pr; x!=t; x = (x-1)&7) { if (pk->p_is[x] == 0) goto slot; }drop: *bp = (char *)pk->p_ipool; pk->p_ipool = bp; return;slot: m = mask[x]; pk->p_imap |= m; pk->p_is[x] = c; pk->p_isum[x] = sum; pk->p_ib[x] = (char *)bp; return;}/* * setup input transfers */pkrstart(pk){}/* * Start transmission on output device associated with pk. * For asynch devices (t_line==1) framing is * imposed. For devices with framing and crc * in the driver (t_line==2) the transfer is * passed on to the driver. */pkxstart(pk, cntl, x)struct pack *pk;char cntl;register x;{ register char *p; int ret; short checkword; char hdchk; p = (caddr_t) &pk->p_ohbuf; *p++ = SYN; if (x < 0) { *p++ = hdchk = 9; checkword = cntl; } else { *p++ = hdchk = pk->p_lpsize; checkword = pk->p_osum[x] ^ (unsigned)cntl; } checkword = CHECK - checkword; *p = checkword; hdchk ^= *p++; *p = checkword>>8; hdchk ^= *p++; *p = cntl; hdchk ^= *p++; *p = hdchk; /* writes */PKDEBUG(7, "send %o\n", (unsigned) cntl); p = (caddr_t) & pk->p_ohbuf; if (x < 0) { GENERROR(p, HDRSIZ); ret = write(pk->p_ofn, p, HDRSIZ); PKASSERT(ret == HDRSIZ, "PKXSTART ret %d", ret); } else { char buf[PACKSIZE + HDRSIZ], *b; int i; for (i = 0, b = buf; i < HDRSIZ; i++) *b++ = *p++; for (i = 0, p = pk->p_ob[x]; i < pk->p_rsize; i++) *b++ = *p++; GENERROR(buf, pk->p_rsize + HDRSIZ); ret = write(pk->p_ofn, buf, pk->p_rsize + HDRSIZ); PKASSERT(ret == pk->p_rsize + HDRSIZ, "PKXSTART ret %d", ret); } if (pk->p_msg) pkoutput(pk); return;}pkmove(p1, p2, count, flag)char *p1, *p2;int count, flag;{ char *s, *d; int i; if (flag == B_WRITE) { s = p2; d = p1; } else { s = p1; d = p2; } for (i = 0; i < count; i++) *d++ = *s++; return;}/*** * pkcget(fn, b, n) get n characters from input * char *b; - buffer for characters * int fn; - file descriptor * int n; - requested number of characters * * return codes: * n - number of characters returned * 0 - end of file */jmp_buf Getjbuf;cgalarm() { longjmp(Getjbuf, 1); }pkcget(fn, b, n)int fn, n;char *b;{ int nchars, ret; if (setjmp(Getjbuf)) { Ntimeout++; PKDEBUG(4, "alarm %d\n", Ntimeout); return(-1); } signal(SIGALRM, cgalarm); for (nchars = 0; nchars < n; nchars += ret) { alarm(PKTIME); ret = read(fn, b, n - nchars); if (ret == 0) { alarm(0); return(-1); } PKASSERT(ret > 0, "PKCGET READ %d", ret); b += ret; } alarm(0); return(0);}generror(p, s)char *p;int s;{ int r; if (Errorrate != 0 && (rand() % Errorrate) == 0) { r = rand() % s;fprintf(stderr, "gen err at %o, (%o), ", r, (unsigned) *(p + r)); *(p + r) += 1; } return;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?