|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)pk1.c 5.1 (Berkeley) 7/2/83"; ! 3: #endif ! 4: ! 5: extern char *malloc(); ! 6: ! 7: #define USER 1 ! 8: #include <stdio.h> ! 9: #ifdef SYSIII ! 10: #include <sys/types.h> ! 11: #endif ! 12: #include "pk.p" ! 13: #include <sys/param.h> ! 14: #include "pk.h" ! 15: #include <sys/buf.h> ! 16: #include <setjmp.h> ! 17: #include <signal.h> ! 18: ! 19: ! 20: #define PKMAXSTMSG 40 ! 21: #define PKTIME 25 ! 22: extern int Errorrate; ! 23: int Connodata = 0; ! 24: int Ntimeout = 0; ! 25: #define CONNODATA 10 ! 26: #define NTIMEOUT 50 ! 27: /* ! 28: * packet driver support routines ! 29: * ! 30: */ ! 31: ! 32: struct pack *pklines[NPLINES]; ! 33: ! 34: /* ! 35: * start initial synchronization. ! 36: */ ! 37: ! 38: struct pack * ! 39: pkopen(ifn, ofn) ! 40: int ifn, ofn; ! 41: { ! 42: register struct pack *pk; ! 43: register char **bp; ! 44: register int i; ! 45: ! 46: if (++pkactive >= NPLINES) ! 47: return(NULL); ! 48: if ((pk = (struct pack *) malloc(sizeof (struct pack))) == NULL) ! 49: return(NULL); ! 50: pkzero((caddr_t) pk, sizeof (struct pack)); ! 51: pk->p_ifn = ifn; ! 52: pk->p_ofn = ofn; ! 53: pk->p_xsize = pk->p_rsize = PACKSIZE; ! 54: pk->p_rwindow = pk->p_swindow = WINDOWS; ! 55: /* allocate input windows */ ! 56: for (i = 0; i < pk->p_rwindow; i++) { ! 57: if ((bp = (char **) GETEPACK) == NULL) ! 58: break; ! 59: *bp = (char *) pk->p_ipool; ! 60: pk->p_ipool = bp; ! 61: } ! 62: if (i == 0) ! 63: return(NULL); ! 64: pk->p_rwindow = i; ! 65: ! 66: /* start synchronization */ ! 67: pk->p_msg = pk->p_rmsg = M_INITA; ! 68: for (i = 0; i < NPLINES; i++) { ! 69: if (pklines[i] == NULL) { ! 70: pklines[i] = pk; ! 71: break; ! 72: } ! 73: } ! 74: if (i >= NPLINES) ! 75: return(NULL); ! 76: pkoutput(pk); ! 77: ! 78: for (i = 0; i < PKMAXSTMSG; i++) { ! 79: PKGETPKT(pk); ! 80: if ((pk->p_state & LIVE) != 0) ! 81: break; ! 82: } ! 83: if (i >= PKMAXSTMSG) ! 84: return(NULL); ! 85: ! 86: pkreset(pk); ! 87: return(pk); ! 88: } ! 89: ! 90: ! 91: /* ! 92: * input framing and block checking. ! 93: * frame layout for most devices is: ! 94: * ! 95: * S|K|X|Y|C|Z| ... data ... | ! 96: * ! 97: * where S == initial synch byte ! 98: * K == encoded frame size (indexes pksizes[]) ! 99: * X, Y == block check bytes ! 100: * C == control byte ! 101: * Z == XOR of header (K^X^Y^C) ! 102: * data == 0 or more data bytes ! 103: * ! 104: */ ! 105: ! 106: int pksizes[] = { ! 107: 1, 32, 64, 128, 256, 512, 1024, 2048, 4096, 1 ! 108: }; ! 109: ! 110: #define GETRIES 5 ! 111: /* ! 112: * Pseudo-dma byte collection. ! 113: */ ! 114: ! 115: pkgetpack(ipk) ! 116: struct pack *ipk; ! 117: { ! 118: int ret, k, tries; ! 119: register char *p; ! 120: register struct pack *pk; ! 121: register struct header *h; ! 122: unsigned short sum; ! 123: int ifn; ! 124: char **bp; ! 125: char hdchk; ! 126: ! 127: pk = PADDR; ! 128: if ((pk->p_state & DOWN) || ! 129: Connodata > CONNODATA /* || Ntimeout > NTIMEOUT */) ! 130: pkfail(); ! 131: ifn = pk->p_ifn; ! 132: ! 133: /* find HEADER */ ! 134: for (tries = 0; tries < GETRIES; ) { ! 135: p = (caddr_t) &pk->p_ihbuf; ! 136: if ((ret = pkcget(ifn, p, 1)) < 0) { ! 137: /* set up retransmit or REJ */ ! 138: tries++; ! 139: pk->p_msg |= pk->p_rmsg; ! 140: if (pk->p_msg == 0) ! 141: pk->p_msg |= M_RR; ! 142: if ((pk->p_state & LIVE) == LIVE) ! 143: pk->p_state |= RXMIT; ! 144: pkoutput(pk); ! 145: continue; ! 146: } ! 147: if (*p != SYN) ! 148: continue; ! 149: p++; ! 150: ret = pkcget(ifn, p, HDRSIZ - 1); ! 151: if (ret == -1) ! 152: continue; ! 153: break; ! 154: } ! 155: if (tries >= GETRIES) { ! 156: PKDEBUG(4, "tries = %d\n", tries); ! 157: pkfail(); ! 158: } ! 159: ! 160: Connodata++; ! 161: h = (struct header * ) &pk->p_ihbuf; ! 162: p = (caddr_t) h; ! 163: hdchk = p[1] ^ p[2] ^ p[3] ^ p[4]; ! 164: p += 2; ! 165: sum = (unsigned) *p++ & 0377; ! 166: sum |= (unsigned) *p << 8; ! 167: h->sum = sum; ! 168: PKDEBUG(7, "rec h->cntl %o\n", (unsigned) h->cntl); ! 169: k = h->ksize; ! 170: if (hdchk != h->ccntl) { ! 171: /* bad header */ ! 172: PKDEBUG(7, "bad header %o,", hdchk); ! 173: PKDEBUG(7, "h->ccntl %o\n", h->ccntl); ! 174: return; ! 175: } ! 176: if (k == 9) { ! 177: if (((h->sum + h->cntl) & 0xffff) == CHECK) { ! 178: pkcntl(h->cntl, pk); ! 179: PKDEBUG(7, "state - %o\n", pk->p_state); ! 180: } ! 181: else { ! 182: /* bad header */ ! 183: PKDEBUG(7, "bad header (k==9) %o\n", h->cntl); ! 184: pk->p_state |= BADFRAME; ! 185: } ! 186: return; ! 187: } ! 188: if (k && pksizes[k] == pk->p_rsize) { ! 189: pk->p_rpr = h->cntl & MOD8; ! 190: pksack(pk); ! 191: Connodata = 0; ! 192: bp = pk->p_ipool; ! 193: pk->p_ipool = (char **) *bp; ! 194: if (bp == NULL) { ! 195: PKDEBUG(7, "bp NULL %s\n", ""); ! 196: return; ! 197: } ! 198: } ! 199: else { ! 200: return; ! 201: } ! 202: ret = pkcget(pk->p_ifn, (char *) bp, pk->p_rsize); ! 203: if (ret == 0) ! 204: pkdata(h->cntl, h->sum, pk, (char **) bp); ! 205: return; ! 206: } ! 207: ! 208: ! 209: pkdata(c, sum, pk, bp) ! 210: char c; ! 211: unsigned short sum; ! 212: register struct pack *pk; ! 213: char **bp; ! 214: { ! 215: register x; ! 216: int t; ! 217: char m; ! 218: ! 219: if (pk->p_state & DRAINO || !(pk->p_state & LIVE)) { ! 220: pk->p_msg |= pk->p_rmsg; ! 221: pkoutput(pk); ! 222: goto drop; ! 223: } ! 224: t = next[pk->p_pr]; ! 225: for(x=pk->p_pr; x!=t; x = (x-1)&7) { ! 226: if (pk->p_is[x] == 0) ! 227: goto slot; ! 228: } ! 229: drop: ! 230: *bp = (char *)pk->p_ipool; ! 231: pk->p_ipool = bp; ! 232: return; ! 233: ! 234: slot: ! 235: m = mask[x]; ! 236: pk->p_imap |= m; ! 237: pk->p_is[x] = c; ! 238: pk->p_isum[x] = sum; ! 239: pk->p_ib[x] = (char *)bp; ! 240: return; ! 241: } ! 242: ! 243: ! 244: ! 245: /* ! 246: * setup input transfers ! 247: */ ! 248: pkrstart(pk) ! 249: {} ! 250: ! 251: #define PKMAXBUF 128 ! 252: /* ! 253: * Start transmission on output device associated with pk. ! 254: * For asynch devices (t_line==1) framing is ! 255: * imposed. For devices with framing and crc ! 256: * in the driver (t_line==2) the transfer is ! 257: * passed on to the driver. ! 258: */ ! 259: pkxstart(pk, cntl, x) ! 260: register struct pack *pk; ! 261: char cntl; ! 262: register x; ! 263: { ! 264: register char *p; ! 265: int ret; ! 266: short checkword; ! 267: char hdchk; ! 268: ! 269: p = (caddr_t) &pk->p_ohbuf; ! 270: *p++ = SYN; ! 271: if (x < 0) { ! 272: *p++ = hdchk = 9; ! 273: checkword = cntl; ! 274: } ! 275: else { ! 276: *p++ = hdchk = pk->p_lpsize; ! 277: checkword = pk->p_osum[x] ^ (unsigned)(cntl & 0377); ! 278: } ! 279: checkword = CHECK - checkword; ! 280: *p = checkword; ! 281: hdchk ^= *p++; ! 282: *p = checkword>>8; ! 283: hdchk ^= *p++; ! 284: *p = cntl; ! 285: hdchk ^= *p++; ! 286: *p = hdchk; ! 287: /* writes */ ! 288: PKDEBUG(7, "send %o\n", (unsigned) cntl); ! 289: p = (caddr_t) & pk->p_ohbuf; ! 290: if (x < 0) { ! 291: #ifdef PROTODEBUG ! 292: GENERROR(p, HDRSIZ); ! 293: #endif ! 294: ret = write(pk->p_ofn, p, HDRSIZ); ! 295: PKASSERT(ret == HDRSIZ, "PKXSTART ret", "", ret); ! 296: } ! 297: else { ! 298: char buf[PKMAXBUF + HDRSIZ], *b; ! 299: int i; ! 300: for (i = 0, b = buf; i < HDRSIZ; i++) ! 301: *b++ = *p++; ! 302: for (i = 0, p = pk->p_ob[x]; i < pk->p_xsize; i++) ! 303: *b++ = *p++; ! 304: #ifdef PROTODEBUG ! 305: GENERROR(buf, pk->p_xsize + HDRSIZ); ! 306: #endif ! 307: ret = write(pk->p_ofn, buf, pk->p_xsize + HDRSIZ); ! 308: PKASSERT(ret == pk->p_xsize + HDRSIZ, ! 309: "PKXSTART ret", "", ret); ! 310: Connodata = 0; ! 311: } ! 312: if (pk->p_msg) ! 313: pkoutput(pk); ! 314: return; ! 315: } ! 316: ! 317: ! 318: pkmove(p1, p2, count, flag) ! 319: char *p1, *p2; ! 320: int count, flag; ! 321: { ! 322: register char *s, *d; ! 323: register int i; ! 324: ! 325: if (flag == B_WRITE) { ! 326: s = p2; ! 327: d = p1; ! 328: } ! 329: else { ! 330: s = p1; ! 331: d = p2; ! 332: } ! 333: for (i = 0; i < count; i++) ! 334: *d++ = *s++; ! 335: return; ! 336: } ! 337: ! 338: ! 339: /*** ! 340: * pkcget(fn, b, n) get n characters from input ! 341: * char *b; - buffer for characters ! 342: * int fn; - file descriptor ! 343: * int n; - requested number of characters ! 344: * ! 345: * return codes: ! 346: * n - number of characters returned ! 347: * 0 - end of file ! 348: */ ! 349: ! 350: jmp_buf Getjbuf; ! 351: cgalarm() { longjmp(Getjbuf, 1); } ! 352: ! 353: pkcget(fn, b, n) ! 354: int fn, n; ! 355: register char *b; ! 356: { ! 357: register int nchars, ret; ! 358: ! 359: if (setjmp(Getjbuf)) { ! 360: Ntimeout++; ! 361: PKDEBUG(4, "alarm %d\n", Ntimeout); ! 362: return(-1); ! 363: } ! 364: signal(SIGALRM, cgalarm); ! 365: ! 366: alarm(PKTIME); ! 367: for (nchars = 0; nchars < n; nchars += ret) { ! 368: ret = read(fn, b, n - nchars); ! 369: if (ret == 0) { ! 370: alarm(0); ! 371: return(-1); ! 372: } ! 373: PKASSERT(ret > 0, "PKCGET READ", "", ret); ! 374: b += ret; ! 375: } ! 376: alarm(0); ! 377: return(0); ! 378: } ! 379: ! 380: ! 381: #ifdef PROTODEBUG ! 382: generror(p, s) ! 383: char *p; ! 384: int s; ! 385: { ! 386: int r; ! 387: if (Errorrate != 0 && (rand() % Errorrate) == 0) { ! 388: r = rand() % s; ! 389: fprintf(stderr, "gen err at %o, (%o), ", r, (unsigned) *(p + r)); ! 390: *(p + r) += 1; ! 391: } ! 392: return; ! 393: } ! 394: ! 395: ! 396: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.