|
|
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.