|
|
1.1 root 1: typedef struct Etherhdr Etherhdr;
2: typedef struct Fragq Fragq;
3: typedef struct Ilcb Ilcb;
4: typedef struct Ilhdr Ilhdr;
5: typedef ulong Ipaddr;
6: typedef struct Ipconv Ipconv;
7: typedef struct Ipfrag Ipfrag;
8: typedef struct Ipifc Ipifc;
9: typedef struct Ipdevice Ipdevice;
10: typedef ushort Port;
11: typedef struct Reseq Reseq;
12: typedef struct Tcp Tcp;
13: typedef struct Tcpctl Tcpctl;
14: typedef struct Tcphdr Tcphdr;
15: typedef struct Timer Timer;
16: typedef struct Udphdr Udphdr;
17:
18: struct Etherhdr
19: {
20: #define ETHER_HDR 14
21: uchar d[6];
22: uchar s[6];
23: uchar type[2];
24:
25: /* Now we have the ip fields */
26: #define ETHER_IPHDR 20
27: uchar vihl; /* Version and header length */
28: uchar tos; /* Type of service */
29: uchar length[2]; /* packet length */
30: uchar id[2]; /* Identification */
31: uchar frag[2]; /* Fragment information */
32: uchar ttl; /* Time to live */
33: uchar proto; /* Protocol */
34: uchar cksum[2]; /* Header checksum */
35: uchar src[4]; /* Ip source */
36: uchar dst[4]; /* Ip destination */
37: };
38:
39: /* Ethernet packet types */
40: #define ET_IP 0x0800
41:
42: struct Udphdr
43: {
44: #define UDP_EHSIZE 22
45: uchar d[6]; /* Ethernet destination */
46: uchar s[6]; /* Ethernet source */
47: uchar type[2]; /* Ethernet packet type */
48:
49: uchar vihl; /* Version and header length */
50: uchar tos; /* Type of service */
51: uchar length[2]; /* packet length */
52: uchar id[2]; /* Identification */
53: uchar frag[2]; /* Fragment information */
54:
55: /* Udp pseudo ip really starts here */
56: #define UDP_PHDRSIZE 12
57: #define UDP_HDRSIZE 20
58: uchar Unused;
59: uchar udpproto; /* Protocol */
60: uchar udpplen[2]; /* Header plus data length */
61: uchar udpsrc[4]; /* Ip source */
62: uchar udpdst[4]; /* Ip destination */
63: uchar udpsport[2]; /* Source port */
64: uchar udpdport[2]; /* Destination port */
65: uchar udplen[2]; /* data length */
66: uchar udpcksum[2]; /* Checksum */
67: };
68:
69: struct Ilhdr
70: {
71: #define IL_EHSIZE 34
72: uchar d[6]; /* Ethernet destination */
73: uchar s[6]; /* Ethernet source */
74: uchar type[2]; /* Ethernet packet type */
75:
76: uchar vihl; /* Version and header length */
77: uchar tos; /* Type of service */
78: uchar length[2]; /* packet length */
79: uchar id[2]; /* Identification */
80: uchar frag[2]; /* Fragment information */
81: uchar ttl; /* Time to live */
82: uchar proto; /* Protocol */
83: uchar cksum[2]; /* Header checksum */
84: uchar src[4]; /* Ip source */
85: uchar dst[4]; /* Ip destination */
86: #define IL_HDRSIZE 18
87: uchar ilsum[2]; /* Checksum including header */
88: uchar illen[2]; /* Packet length */
89: uchar iltype; /* Packet type */
90: uchar ilspec; /* Special */
91: uchar ilsrc[2]; /* Src port */
92: uchar ildst[2]; /* Dst port */
93: uchar ilid[4]; /* Sequence id */
94: uchar ilack[4]; /* Acked sequence */
95: };
96:
97: struct Ilcb /* Control block */
98: {
99: int state; /* Connection state */
100:
101: Rendez syncer; /* where syncer waits for a connect */
102:
103: QLock ackq; /* Unacknowledged queue */
104: Block *unacked;
105: Block *unackedtail;
106:
107: QLock outo; /* Out of order packet queue */
108: Block *outoforder;
109:
110: ulong next; /* Id of next to send */
111: ulong recvd; /* Last packet received */
112: ulong start; /* Local start id */
113: ulong rstart; /* Remote start id */
114:
115: int timeout; /* Time out counter */
116: int slowtime; /* Slow time counter */
117: int fasttime; /* Retransmission timer */
118: int acktime; /* Acknowledge timer */
119: int querytime; /* Query timer */
120: int deathtime; /* Time to kill connection */
121:
122: int rtt; /* Average round trip time */
123: ulong rttack; /* The ack we are waiting for */
124: ulong ackms; /* Time we issued */
125:
126: int window; /* Maximum receive window */
127: };
128:
129: enum /* Packet types */
130: {
131: Ilsync,
132: Ildata,
133: Ildataquery,
134: Ilack,
135: Ilquerey,
136: Ilstate,
137: Ilclose,
138: };
139:
140: enum /* Connection state */
141: {
142: Ilclosed,
143: Ilsyncer,
144: Ilsyncee,
145: Ilestablished,
146: Illistening,
147: Ilclosing,
148: };
149:
150: #define TCP_PKT (TCP_EHSIZE+TCP_IPLEN+TCP_PHDRSIZE)
151:
152: struct Tcphdr
153: {
154: #define TCP_EHSIZE 14
155: uchar d[6]; /* Ethernet destination */
156: uchar s[6]; /* Ethernet source */
157: uchar type[2]; /* Ethernet packet type */
158: #define TCP_IPLEN 8
159: uchar vihl; /* Version and header length */
160: uchar tos; /* Type of service */
161: uchar length[2]; /* packet length */
162: uchar id[2]; /* Identification */
163: uchar frag[2]; /* Fragment information */
164:
165: #define TCP_PHDRSIZE 12
166: uchar Unused;
167: uchar proto;
168: uchar tcplen[2];
169: uchar tcpsrc[4];
170: uchar tcpdst[4];
171:
172: #define TCP_HDRSIZE 20
173: uchar tcpsport[2];
174: uchar tcpdport[2];
175: uchar tcpseq[4];
176: uchar tcpack[4];
177: uchar tcpflag[2];
178: uchar tcpwin[2];
179: uchar tcpcksum[2];
180: uchar tcpurg[2];
181:
182: /* Options segment */
183: uchar tcpopt[2];
184: uchar tcpmss[2];
185: };
186:
187: enum
188: {
189: TimerOFF = 0,
190: TimerON = 1,
191: TimerDONE = 2,
192: };
193:
194: struct Timer
195: {
196: Timer *next;
197: Timer *prev;
198: int state;
199: int start;
200: int count;
201: void (*func)(void*);
202: void *arg;
203: };
204:
205: struct Tctl
206: {
207: uchar state; /* Connection state */
208: uchar type; /* Listening or active connection */
209: uchar code; /* Icmp code */
210: struct {
211: ulong una; /* Unacked data pointer */
212: ulong nxt; /* Next sequence expected */
213: ulong ptr; /* Data pointer */
214: ushort wnd; /* Tcp send window */
215: ulong up; /* Urgent data pointer */
216: ulong wl1;
217: ulong wl2;
218: } snd;
219: struct {
220: ulong nxt; /* Receive pointer to next byte slot */
221: ushort wnd; /* Receive window incoming */
222: ulong up; /* Urgent pointer */
223: } rcv;
224: ulong iss; /* Initial sequence number */
225: ushort cwind; /* Congestion window */
226: ushort ssthresh; /* Slow start threshold */
227: int resent; /* Bytes just resent */
228: int irs; /* Initial received squence */
229: ushort mss; /* Mean segment size */
230: int rerecv; /* Overlap of data rerecevived */
231: ushort window; /* Recevive window */
232: int max_snd; /* Max send */
233: ulong last_ack; /* Last acknowledege received */
234: char backoff; /* Exponential backoff counter */
235: char flags; /* State flags */
236: char tos; /* Type of service */
237:
238: Blist rcvq; /* Received data */
239: ulong rcvcnt; /* Bytes queued for upstream */
240:
241: Block *sndq; /* List of data going out */
242: ulong sndcnt; /* Amount of data in send queue */
243: Rendez sndr; /* process flow control */
244: QLock sndrlock;
245: int sndfull;
246:
247: Reseq *reseq; /* Resequencing queue */
248: Timer timer; /* Activity timer */
249: Timer acktimer; /* Acknoledge timer */
250: Timer rtt_timer; /* Round trip timer */
251: ulong rttseq; /* Round trip sequence */
252: int srtt; /* Shortened round trip */
253: int mdev; /* Mean deviation of round trip */
254: int kacounter; /* when counter goes to zero, hangup */
255: };
256:
257: struct Tcpctl
258: {
259: QLock;
260: Rendez syner;
261: struct Tctl;
262: };
263:
264: struct Tcp
265: {
266: Port source;
267: Port dest;
268: ulong seq;
269: ulong ack;
270: char flags;
271: ushort wnd;
272: ushort up;
273: ushort mss;
274: };
275:
276: struct Reseq
277: {
278: Reseq *next;
279: Tcp seg;
280: Block *bp;
281: ushort length;
282: char tos;
283: };
284:
285: /* An ip interface used for UDP/TCP/IL */
286: struct Ipconv
287: {
288: QLock; /* Ref count lock */
289: Netprot; /* stat info */
290: int ref;
291: Ipaddr dst; /* Destination from connect */
292: Ipaddr src; /* local address */
293: Port psrc; /* Source port */
294: Port pdst; /* Destination port */
295:
296: Ipifc *ifc; /* Ip protocol interface */
297: Queue *readq; /* Pointer to upstream read q */
298: QLock listenq; /* List of people waiting incoming cons */
299: Rendez listenr; /* Some where to sleep while waiting */
300:
301: char *err; /* Async protocol error */
302: int backlog; /* Maximum number of waiting connections */
303: int headers; /* include header in packet */
304: int curlog; /* Number of waiting connections */
305: Ipconv *newcon; /* This is the start of a connection */
306: char text[NAMELEN]; /* program announcing/connecting port */
307:
308: union {
309: Tcpctl tcpctl; /* Tcp control block */
310: Ilcb ilctl; /* Il control block */
311: };
312: };
313:
314:
315: enum
316: {
317: MAX_TIME = (1<<20), /* Forever */
318: TCP_ACK = 50, /* Timed ack sequence in ms */
319:
320: URG = 0x20, /* Data marked urgent */
321: ACK = 0x10, /* Aknowledge is valid */
322: PSH = 0x08, /* Whole data pipe is pushed */
323: RST = 0x04, /* Reset connection */
324: SYN = 0x02, /* Pkt. is synchronise */
325: FIN = 0x01, /* Start close down */
326:
327: EOL_KIND = 0,
328: NOOP_KIND = 1,
329: MSS_KIND = 2,
330:
331: MSS_LENGTH = 4, /* Mean segment size */
332: MSL2 = 10,
333: MSPTICK = 50, /* Milliseconds per timer tick */
334: DEF_MSS = 512, /* Default mean segment */
335: DEF_RTT = 1000, /* Default round trip */
336:
337: TCP_PASSIVE = 0, /* Listen connection */
338: TCP_ACTIVE = 1, /* Outgoing connection */
339: IL_PASSIVE = 0,
340: IL_ACTIVE = 1,
341:
342: MAXBACKOFF = 12,
343: FORCE = 1,
344: CLONE = 2,
345: RETRAN = 4,
346: ACTIVE = 8,
347: SYNACK = 16,
348: AGAIN = 8,
349: DGAIN = 4,
350: };
351:
352: #define set_timer(t,x) (((t)->start) = (x)/MSPTICK)
353: #define run_timer(t) ((t)->state == TimerON)
354:
355: enum /* Tcp connection states */
356: {
357: Closed = 0,
358: Listen,
359: Syn_sent,
360: Syn_received,
361: Established,
362: Finwait1,
363: Finwait2,
364: Close_wait,
365: Closing,
366: Last_ack,
367: Time_wait
368: };
369:
370: enum
371: {
372: Nipconv= 512, /* max conversations per interface */
373: Udphdrsize= 6, /* size if a to/from user Udp header */
374: Nipd= 34, /* ip hardware interfaces */
375: };
376:
377: /*
378: * Ip interface structure. We have one for each active protocol driver
379: */
380: struct Ipifc
381: {
382: QLock;
383: Network; /* user level network interface */
384: Ipifc *next;
385: int inited;
386: uchar protocol; /* Ip header protocol number */
387: void (*iprcv) (Ipifc*, Block*); /* Receive demultiplexor */
388: ulong chkerrs; /* checksum errors */
389: Ipconv **conv; /* conversations */
390: };
391:
392: /*
393: * Ip hardare interface structure. We have one for each physical interface
394: */
395: struct Ipdevice
396: {
397: Queue *q;
398:
399: Ipaddr Myip[7];
400: Ipaddr Mymask;
401: Ipaddr Mynetmask;
402: Ipaddr Remip; /* address of remote side */
403: uchar Netmyip[4]; /* In Network byte order */
404: int maxmtu; /* Maximum transfer unit */
405: int minmtu; /* Minumum tranfer unit */
406: int hsize; /* Media header size */
407:
408: int type; /* channel identifier */
409: int dev;
410:
411: QLock outl;
412: };
413:
414: struct Fragq
415: {
416: QLock;
417: Block *blist;
418: Fragq *next;
419: Ipaddr src;
420: Ipaddr dst;
421: ushort id;
422: ulong age;
423: };
424:
425: struct Ipfrag
426: {
427: ushort foff;
428: ushort flen;
429: };
430:
431: enum {
432: IP_VER = 0x40, /* Using IP version 4 */
433: IP_HLEN = 0x05, /* Header length in characters */
434: IP_DF = 0x4000, /* Don't fragment */
435: IP_MF = 0x2000, /* More fragments */
436:
437: /* Sizes */
438: IP_MAX = (32*1024), /* Maximum Internet packet size */
439: UDP_MAX = (IP_MAX-ETHER_IPHDR), /* Maximum UDP datagram size */
440: UDP_DATMAX = (UDP_MAX-UDP_HDRSIZE),/* Maximum amount of udp data */
441: IL_DATMAX = (IP_MAX-IL_HDRSIZE), /* Maximum IL data in one ip packet */
442:
443: /* Protocol numbers */
444: IP_ICMPPROTO = 1,
445: IP_UDPPROTO = 17,
446: IP_TCPPROTO = 6,
447: IP_ILPROTO = 40,
448:
449: /* Psuedo protocol - not on the wire */
450: IP_ROUTER = 128,
451:
452: /* Protocol port numbers */
453: PORTALLOC = 5000, /* First automatic allocated port */
454: PRIVPORTALLOC = 600, /* First priveleged port allocated */
455: UNPRIVPORTALLOC = 1024, /* First unpriveleged port allocated */
456: PORTMAX = 30000, /* Last port to allocte */
457: };
458:
459: void add_reseq(Tcpctl *, char, Tcp *, Block *, ushort);
460: int arp_lookup(uchar*, uchar*);
461: int backoff(int);
462: Block* btrim(Block*, int, int);
463: void localclose(Ipconv *, char []);
464: int dupb(Block **, Block *, int, int);
465: void extract_oob(Block **, Block **, Tcp *);
466: void get_reseq(Tcpctl *, char *, Tcp *, Block **, ushort *);
467: Ipaddr ipgetsrc(uchar*);
468: void hnputl(uchar*, ulong);
469: void hnputs(uchar*, ushort);
470: Block* htontcp(Tcp *, Block *, Tcphdr *);
471: Block* htontcp(Tcp *, Block *, Tcphdr *);
472: void iloutoforder(Ipconv*, Ilhdr*, Block*);
473: void ilstart(Ipconv *, int, int);
474: int inb_window(Tcpctl *, int);
475: void init_tcpctl(Ipconv *);
476: void initfrag(int);
477: void initipifc(Ipifc*, uchar, void (*)(Ipifc*, Block*));
478: Ipconv* ip_conn(Ipifc*, Port, Port, Ipaddr dest);
479: ushort ip_csum(uchar*);
480: Block* ip_reassemble(int, Block*, Etherhdr*);
481: int ipclonecon(Chan *);
482: int ipconbusy(Ipconv*);
483: Ipconv* ipcreateconv(Ipifc*, int);
484: int ipforme(uchar*);
485: Fragq* ipfragallo(void);
486: void ipfragfree(Fragq*, int);
487: Ipconv* ipincoming(Ipifc*, Ipconv*);
488: int iplisten(Chan *);
489: void iplocalfill(Chan*, char*, int);
490: void ipmkdir(Qinfo *, Dirtab *, Ipconv *);
491: Ipaddr ipparse(char*);
492: void ipremotefill(Chan*, char*, int);
493: Ipdevice* iproute(uchar*, uchar*);
494: void ipsetaddrs(Ipdevice*);
495: void ipstatusfill(Chan*, char*, int);
496: Port nextport(Ipifc*, int);
497: ushort nhgets(uchar*);
498: ulong nhgetl(uchar*);
499: int ntohtcp(Tcp *, Block **);
500: int ntohtcp(Tcp*, Block**);
501: Ipconv* portused(Ipifc*, Port);
502: void ppkt(Block*);
503: void proc_syn(Ipconv*, char, Tcp*);
504: ushort ptcl_csum(Block*bp, int, int);
505: int pullb(Block **, int);
506: void reset(Ipaddr, Ipaddr, char, ushort, Tcp*);
507: void tcpsndsyn(Tcpctl*);
508: int seq_ge(ulong, ulong);
509: int seq_gt(ulong, ulong);
510: int seq_gt(ulong, ulong);
511: int seq_le(ulong, ulong);
512: int seq_lt(ulong, ulong);
513: int seq_within(ulong, ulong, ulong);
514: int seq_within(ulong, ulong, ulong);
515: void tcpsetstate(Ipconv *, char);
516: void tcpgo(Timer *);
517: void tcphalt(Timer *);
518: void tcpxstate(Ipconv*, char oldstate, char newstate);
519: void tcpacktimer(void *);
520: void tcpinput(Ipifc*, Block *);
521: void tcpoutput(Ipconv*);
522: void tcptimeout(void *);
523: void tcpackproc(void*);
524: void tcpflow(void*);
525: void tcpflushincoming(Ipconv*);
526: void tcprcvwin(Ipconv *);
527: void tcpstart(Ipconv *, int, ushort, char);
528: int trim(Tcpctl *, Tcp *, Block **, ushort *);
529: void udprcvmsg(Ipifc*, Block*);
530: void update(Ipconv *, Tcp *);
531:
532: #define fmtaddr(xx) (xx>>24)&0xff,(xx>>16)&0xff,(xx>>8)&0xff,xx&0xff
533: #define MIN(a, b) ((a) < (b) ? (a) : (b))
534: #define MAX(a, b) ((a) > (b) ? (a) : (b))
535: #define BLKIP(xp) ((Etherhdr *)((xp)->rptr))
536: #define BLKFRAG(xp) ((Ipfrag *)((xp)->base))
537: #define PREC(x) ((x)>>5 & 7)
538:
539: extern Ipaddr Myip[7];
540: extern Ipaddr Mymask;
541: extern Ipaddr Mynetmask;
542: extern Ipaddr classmask[4];
543: extern Ipifc *ipifc[];
544: extern Ipdevice ipd[Nipd];
545: extern char *tcpstate[];
546: extern char *ilstate[];
547: extern Rendez tcpflowr;
548: extern Qinfo tcpinfo;
549: extern Qinfo ipinfo;
550: extern Qinfo ipconvinfo;
551: extern Qinfo udpinfo;
552: extern Qinfo ilinfo;
553: extern Qinfo arpinfo;
554: extern Queue *Ipoutput;
555:
556: /* offsets into Myip */
557: enum
558: {
559: Myself = 0,
560: Mybcast = 1,
561: Mynet = 3,
562: Mysubnet = 5,
563: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.