|
|
1.1 ! root 1: #include <signal.h> ! 2: #include <stdio.h> ! 3: #include "proto.h" ! 4: ! 5: struct Packet{ ! 6: char packet[MAXPKTSIZE]; ! 7: short size; ! 8: short timo; ! 9: short state; ! 10: }; ! 11: ! 12: typedef struct Packet * Pkp_t; ! 13: ! 14: struct Packet packets[NPBUFS]; ! 15: int ptype; ! 16: char xseq; ! 17: char freepkts; ! 18: char nulls[MAXPKTSIZE-PKTHDRSIZE]; ! 19: short xtimo; ! 20: ! 21: enum{ ! 22: badack, rack, unkack, skack, xpkts, timeout, dsize, speed, nstats ! 23: }; ! 24: ! 25: #define BADACK (int)badack ! 26: #define RACK (int)rack ! 27: #define UNKACK (int)unkack ! 28: #define SKACK (int)skack ! 29: #define XPKTS (int)xpkts ! 30: #define TIMEOUT (int)timeout ! 31: #define DSIZE (int)dsize ! 32: #define SPEED (int)speed ! 33: #define NSTATS (int)nstats ! 34: ! 35: struct{ ! 36: char *desc; ! 37: long count; ! 38: } stats[NSTATS]={ ! 39: {"unrecognised ack"}, ! 40: {"acks received"}, ! 41: {"unknown ack"}, ! 42: {"packets accepted by skipped sequence ack"}, ! 43: {"packets transmitted"}, ! 44: {"packets retransmitted by timeout"}, ! 45: {"max packet data size"}, ! 46: {"bytes/sec."}, ! 47: }; ! 48: ! 49: #define STATS(A) stats[A].count++ ! 50: ! 51: void ! 52: pinit(lspeed, maxpktdsize, aptype) ! 53: { ! 54: freepkts = NPBUFS; ! 55: xtimo = (NPBUFS*(PKTHDRSIZE+PKTCRCSIZE+PKTASIZE+maxpktdsize)+lspeed-1)/lspeed+2; ! 56: if((ptype=aptype) == ACKON) ! 57: ptimeout(); ! 58: stats[DSIZE].count = maxpktdsize; ! 59: stats[SPEED].count = lspeed; ! 60: } ! 61: ! 62: void ! 63: precv(c) ! 64: char c; ! 65: { ! 66: register Pkp_t pkp; ! 67: register char pseq, seq = c & SEQMASK; ! 68: register int hit = 0; ! 69: ! 70: if((c&PTYP) != ptype){ ! 71: STATS(BADACK); ! 72: return; ! 73: } ! 74: for (pkp = packets; pkp < &packets[NPBUFS]; pkp++) ! 75: if(pkp->state == WAIT) ! 76: { pseq = (pkp->packet[0])&SEQMASK; ! 77: if (seq == pseq) ! 78: { STATS(RACK); ! 79: pkp->state = OK; ! 80: freepkts++; ! 81: hit++; ! 82: } else ! 83: if ((seq > pseq && seq < pseq+NPBUFS) ! 84: || (seq < pseq && seq+SEQMOD < pseq+NPBUFS)) ! 85: { STATS(SKACK); ! 86: pkp->state = OK; ! 87: freepkts++; ! 88: hit++; ! 89: ! 90: } } ! 91: if (!hit) ! 92: STATS(UNKACK); ! 93: } ! 94: ! 95: int ! 96: psend(bufp, count) ! 97: char * bufp; ! 98: register int count; ! 99: { ! 100: register Pkp_t pkp; ! 101: register int i; ! 102: ! 103: if(ptype == ACKON){ ! 104: for(pkp=(Pkp_t)0, i=0; i<NPBUFS; i++ ) ! 105: if(packets[i].state != WAIT){ ! 106: if(pkp == (Pkp_t)0){ ! 107: pkp = &packets[i]; ! 108: pkp->state = WAIT; ! 109: pkp->timo = xtimo; ! 110: freepkts--; ! 111: } ! 112: } ! 113: if(pkp == (Pkp_t)0) ! 114: return -1; ! 115: } else ! 116: pkp = packets; ! 117: swab(bufp, &pkp->packet[PKTHDRSIZE], count); ! 118: pkp->packet[0] = ptype | ((xseq++)&SEQMASK); ! 119: pkp->packet[1] = count; ! 120: count += PKTHDRSIZE; ! 121: if(ptype != NOCRC){ ! 122: (void)crc(pkp->packet, count); ! 123: count += PKTCRCSIZE; ! 124: } ! 125: pkp->size = count; ! 126: Write(pkp->packet, count); ! 127: STATS(XPKTS); ! 128: return 0; ! 129: } ! 130: ! 131: ptimeout() ! 132: { register Pkp_t pkp; ! 133: ! 134: (void)signal(SIGALRM, SIG_IGN); ! 135: for (pkp = packets; pkp < &packets[NPBUFS]; pkp++) ! 136: if (pkp->state == WAIT && --pkp->timo <= 0){ ! 137: STATS(TIMEOUT); ! 138: pkp->timo = xtimo; ! 139: Write(nulls, pkp->size-PKTHDRSIZE); ! 140: Write(pkp->packet, pkp->size); ! 141: } ! 142: (void)signal(SIGALRM, ptimeout); ! 143: } ! 144: ! 145: void ! 146: pstats(fd) ! 147: FILE * fd; ! 148: { ! 149: register int i; ! 150: register int count = 0; ! 151: ! 152: if (fd != NULL) ! 153: for(i=0; i<NSTATS; i++ ) ! 154: if(stats[i].count){ ! 155: if(count++ == 0) ! 156: fprintf(fd, "\nStatistics:\n"); ! 157: fprintf(fd, "\t%ld %s\n", (long)stats[i].count, stats[i].desc); ! 158: } ! 159: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.