source: trunk/minix/servers/inet/generic/tcp_lib.c@ 9

Last change on this file since 9 was 9, checked in by Mattia Monga, 13 years ago

Minix 3.1.2a

File size: 13.9 KB
Line 
1/*
2tcp_lib.c
3
4Copyright 1995 Philip Homburg
5*/
6
7#include "inet.h"
8#include "buf.h"
9#include "clock.h"
10#include "event.h"
11#include "io.h"
12#include "type.h"
13
14#include "assert.h"
15#include "tcp_int.h"
16
17THIS_FILE
18
19#undef tcp_LEmod4G
20PUBLIC int tcp_LEmod4G(n1, n2)
21u32_t n1;
22u32_t n2;
23{
24 return !((u32_t)(n2-n1) & 0x80000000L);
25}
26
27#undef tcp_GEmod4G
28PUBLIC int tcp_GEmod4G(n1, n2)
29u32_t n1;
30u32_t n2;
31{
32 return !((u32_t)(n1-n2) & 0x80000000L);
33}
34
35#undef tcp_Lmod4G
36PUBLIC int tcp_Lmod4G(n1, n2)
37u32_t n1;
38u32_t n2;
39{
40 return !!((u32_t)(n1-n2) & 0x80000000L);
41}
42
43#undef tcp_Gmod4G
44PUBLIC int tcp_Gmod4G(n1, n2)
45u32_t n1;
46u32_t n2;
47{
48 return !!((u32_t)(n2-n1) & 0x80000000L);
49}
50
51PUBLIC void tcp_extract_ipopt(tcp_conn, ip_hdr)
52tcp_conn_t *tcp_conn;
53ip_hdr_t *ip_hdr;
54{
55 int ip_hdr_len;
56
57 ip_hdr_len= (ip_hdr->ih_vers_ihl & IH_IHL_MASK) << 2;
58 if (ip_hdr_len == IP_MIN_HDR_SIZE)
59 return;
60
61 DBLOCK(1, printf("ip_hdr options NOT supported (yet?)\n"));
62}
63
64PUBLIC void tcp_extract_tcpopt(tcp_conn, tcp_hdr, mssp)
65tcp_conn_t *tcp_conn;
66tcp_hdr_t *tcp_hdr;
67size_t *mssp;
68{
69 int i, tcp_hdr_len, type, len;
70 u8_t *cp;
71 u16_t mss;
72
73 *mssp= 0; /* No mss */
74
75 tcp_hdr_len= (tcp_hdr->th_data_off & TH_DO_MASK) >> 2;
76 if (tcp_hdr_len == TCP_MIN_HDR_SIZE)
77 return;
78 i= TCP_MIN_HDR_SIZE;
79 while (i<tcp_hdr_len)
80 {
81 cp= ((u8_t *)tcp_hdr)+i;
82 type= cp[0];
83 if (type == TCP_OPT_NOP)
84 {
85 i++;
86 continue;
87 }
88 if (type == TCP_OPT_EOL)
89 break;
90 if (i+2 > tcp_hdr_len)
91 break; /* No length field */
92 len= cp[1];
93 if (i+len > tcp_hdr_len)
94 break; /* Truncated option */
95 i += len;
96 switch(type)
97 {
98 case TCP_OPT_MSS:
99 if (len != 4)
100 break;
101 mss= (cp[2] << 8) | cp[3];
102 DBLOCK(1, printf("tcp_extract_tcpopt: got mss %d\n",
103 mss););
104 *mssp= mss;
105 break;
106 case TCP_OPT_WSOPT: /* window scale option */
107 case TCP_OPT_SACKOK: /* SACK permitted */
108 case TCP_OPT_TS: /* Timestamps option */
109 case TCP_OPT_CCNEW: /* new connection count */
110 /* Ignore this option. */
111 break;
112 default:
113 DBLOCK(0x1,
114 printf(
115 "tcp_extract_tcpopt: unknown option %d, len %d\n",
116 type, len));
117 break;
118 }
119 }
120}
121
122PUBLIC u16_t tcp_pack_oneCsum(ip_hdr, tcp_pack)
123ip_hdr_t *ip_hdr;
124acc_t *tcp_pack;
125{
126 size_t ip_hdr_len;
127 acc_t *pack;
128 u16_t sum;
129 u16_t word_buf[6];
130 int odd_length;
131 char *data_ptr;
132 int length;
133
134 ip_hdr_len= (ip_hdr->ih_vers_ihl & IH_IHL_MASK) << 2;
135 word_buf[0]= ip_hdr->ih_src & 0xffff;
136 word_buf[1]= (ip_hdr->ih_src >> 16) & 0xffff;
137 word_buf[2]= ip_hdr->ih_dst & 0xffff;
138 word_buf[3]= (ip_hdr->ih_dst >> 16) & 0xffff;
139 word_buf[4]= HTONS(IPPROTO_TCP);
140 word_buf[5]= htons(ntohs(ip_hdr->ih_length)-ip_hdr_len);
141 sum= oneC_sum(0, word_buf, sizeof(word_buf));
142
143 pack= tcp_pack;
144 odd_length= 0;
145 for (; pack; pack= pack->acc_next)
146 {
147
148 data_ptr= ptr2acc_data(pack);
149 length= pack->acc_length;
150
151 if (!length)
152 continue;
153 sum= oneC_sum (sum, (u16_t *)data_ptr, length);
154 if (length & 1)
155 {
156 odd_length= !odd_length;
157 sum= ((sum >> 8) & 0xff) | ((sum & 0xff) << 8);
158 }
159 }
160 if (odd_length)
161 {
162 /* Undo the last swap */
163 sum= ((sum >> 8) & 0xff) | ((sum & 0xff) << 8);
164 }
165 return sum;
166}
167
168PUBLIC void tcp_get_ipopt(tcp_conn, ip_hdropt)
169tcp_conn_t *tcp_conn;
170ip_hdropt_t *ip_hdropt;
171{
172 if (!tcp_conn->tc_remipopt)
173 {
174 ip_hdropt->iho_opt_siz= 0;
175 return;
176 }
177 DBLOCK(1, printf("ip_hdr options NOT supported (yet?)\n"));
178 ip_hdropt->iho_opt_siz= 0;
179 return;
180}
181
182PUBLIC void tcp_get_tcpopt(tcp_conn, tcp_hdropt)
183tcp_conn_t *tcp_conn;
184tcp_hdropt_t *tcp_hdropt;
185{
186 int optsiz;
187
188 if (!tcp_conn->tc_tcpopt)
189 {
190 tcp_hdropt->tho_opt_siz= 0;
191 return;
192 }
193 tcp_conn->tc_tcpopt= bf_pack(tcp_conn->tc_tcpopt);
194 optsiz= bf_bufsize(tcp_conn->tc_tcpopt);
195 memcpy(tcp_hdropt->tho_data, ptr2acc_data(tcp_conn->tc_tcpopt),
196 optsiz);
197 if ((optsiz & 3) != 0)
198 {
199 tcp_hdropt->tho_data[optsiz]= TCP_OPT_EOL;
200 optsiz= (optsiz+3) & ~3;
201 }
202 tcp_hdropt->tho_opt_siz= optsiz;
203
204 return;
205}
206
207PUBLIC acc_t *tcp_make_header(tcp_conn, ref_ip_hdr, ref_tcp_hdr, data)
208tcp_conn_t *tcp_conn;
209ip_hdr_t **ref_ip_hdr;
210tcp_hdr_t **ref_tcp_hdr;
211acc_t *data;
212{
213 ip_hdropt_t ip_hdropt;
214 tcp_hdropt_t tcp_hdropt;
215 ip_hdr_t *ip_hdr;
216 tcp_hdr_t *tcp_hdr;
217 acc_t *hdr_acc;
218 char *ptr2hdr;
219 int closed_connection;
220
221 closed_connection= (tcp_conn->tc_state == TCS_CLOSED);
222
223 if (tcp_conn->tc_remipopt || tcp_conn->tc_tcpopt)
224 {
225 tcp_get_ipopt (tcp_conn, &ip_hdropt);
226 tcp_get_tcpopt (tcp_conn, &tcp_hdropt);
227 assert (!(ip_hdropt.iho_opt_siz & 3));
228 assert (!(tcp_hdropt.tho_opt_siz & 3));
229
230 hdr_acc= bf_memreq(IP_MIN_HDR_SIZE+
231 ip_hdropt.iho_opt_siz+TCP_MIN_HDR_SIZE+
232 tcp_hdropt.tho_opt_siz);
233 ptr2hdr= ptr2acc_data(hdr_acc);
234
235 ip_hdr= (ip_hdr_t *)ptr2hdr;
236 ptr2hdr += IP_MIN_HDR_SIZE;
237
238 if (ip_hdropt.iho_opt_siz)
239 {
240 memcpy(ptr2hdr, (char *)ip_hdropt.iho_data,
241 ip_hdropt.iho_opt_siz);
242 }
243 ptr2hdr += ip_hdropt.iho_opt_siz;
244
245 tcp_hdr= (tcp_hdr_t *)ptr2hdr;
246 ptr2hdr += TCP_MIN_HDR_SIZE;
247
248 if (tcp_hdropt.tho_opt_siz)
249 {
250 memcpy (ptr2hdr, (char *)tcp_hdropt.tho_data,
251 tcp_hdropt.tho_opt_siz);
252 }
253 hdr_acc->acc_next= data;
254
255 ip_hdr->ih_vers_ihl= (IP_MIN_HDR_SIZE+
256 ip_hdropt.iho_opt_siz) >> 2;
257 tcp_hdr->th_data_off= (TCP_MIN_HDR_SIZE+
258 tcp_hdropt.tho_opt_siz) << 2;
259 }
260 else
261 {
262 hdr_acc= bf_memreq(IP_MIN_HDR_SIZE+TCP_MIN_HDR_SIZE);
263 ip_hdr= (ip_hdr_t *)ptr2acc_data(hdr_acc);
264 tcp_hdr= (tcp_hdr_t *)&ip_hdr[1];
265 hdr_acc->acc_next= data;
266
267 ip_hdr->ih_vers_ihl= IP_MIN_HDR_SIZE >> 2;
268 tcp_hdr->th_data_off= TCP_MIN_HDR_SIZE << 2;
269 }
270
271 if (!closed_connection && (tcp_conn->tc_state == TCS_CLOSED))
272 {
273 DBLOCK(1, printf("connection closed while inuse\n"));
274 bf_afree(hdr_acc);
275 return 0;
276 }
277
278 ip_hdr->ih_tos= tcp_conn->tc_tos;
279 ip_hdr->ih_ttl= tcp_conn->tc_ttl;
280 ip_hdr->ih_proto= IPPROTO_TCP;
281 ip_hdr->ih_src= tcp_conn->tc_locaddr;
282 ip_hdr->ih_dst= tcp_conn->tc_remaddr;
283 ip_hdr->ih_flags_fragoff= 0;
284 if (tcp_conn->tc_flags & TCF_PMTU)
285 ip_hdr->ih_flags_fragoff |= HTONS(IH_DONT_FRAG);
286
287 tcp_hdr->th_srcport= tcp_conn->tc_locport;
288 tcp_hdr->th_dstport= tcp_conn->tc_remport;
289 tcp_hdr->th_seq_nr= tcp_conn->tc_RCV_NXT;
290 tcp_hdr->th_flags= 0;
291 tcp_hdr->th_window= htons(tcp_conn->tc_RCV_HI-tcp_conn->tc_RCV_LO);
292 tcp_hdr->th_chksum= 0;
293 *ref_ip_hdr= ip_hdr;
294 *ref_tcp_hdr= tcp_hdr;
295 return hdr_acc;
296}
297
298PUBLIC void tcp_print_state (tcp_conn)
299tcp_conn_t *tcp_conn;
300{
301#if DEBUG
302 printf("tcp_conn_table[%d]->tc_state= ", tcp_conn-
303 tcp_conn_table);
304 if (!(tcp_conn->tc_flags & TCF_INUSE))
305 {
306 printf("not inuse\n");
307 return;
308 }
309 switch (tcp_conn->tc_state)
310 {
311 case TCS_CLOSED: printf("CLOSED"); break;
312 case TCS_LISTEN: printf("LISTEN"); break;
313 case TCS_SYN_RECEIVED: printf("SYN_RECEIVED"); break;
314 case TCS_SYN_SENT: printf("SYN_SENT"); break;
315 case TCS_ESTABLISHED: printf("ESTABLISHED"); break;
316 case TCS_CLOSING: printf("CLOSING"); break;
317 default: printf("unknown (=%d)", tcp_conn->tc_state); break;
318 }
319#endif
320}
321
322PUBLIC int tcp_check_conn(tcp_conn)
323tcp_conn_t *tcp_conn;
324{
325 int allright;
326 u32_t lo_queue, hi_queue;
327 int size;
328
329 allright= TRUE;
330 if (tcp_conn->tc_inconsistent)
331 {
332 assert(tcp_conn->tc_inconsistent == 1);
333 printf("tcp_check_conn: connection is inconsistent\n");
334 return allright;
335 }
336
337 /* checking receive queue */
338 lo_queue= tcp_conn->tc_RCV_LO;
339 if (lo_queue == tcp_conn->tc_IRS)
340 lo_queue++;
341 if (lo_queue == tcp_conn->tc_RCV_NXT && (tcp_conn->tc_flags &
342 TCF_FIN_RECV))
343 lo_queue--;
344 hi_queue= tcp_conn->tc_RCV_NXT;
345 if (hi_queue == tcp_conn->tc_IRS)
346 hi_queue++;
347 if (tcp_conn->tc_flags & TCF_FIN_RECV)
348 hi_queue--;
349
350 size= hi_queue-lo_queue;
351 if (size<0)
352 {
353 printf("rcv hi_queue-lo_queue < 0\n");
354 printf("SND_NXT= 0x%lx, SND_UNA= 0x%lx\n",
355 (unsigned long)tcp_conn->tc_SND_NXT,
356 (unsigned long)tcp_conn->tc_SND_UNA);
357 printf("lo_queue= 0x%lx, hi_queue= 0x%lx\n",
358 (unsigned long)lo_queue,
359 (unsigned long)hi_queue);
360 printf("size= %d\n", size);
361 allright= FALSE;
362 }
363 else if (!tcp_conn->tc_rcvd_data)
364 {
365 if (size)
366 {
367 printf("RCV_NXT-RCV_LO != 0\n");
368 tcp_print_conn(tcp_conn);
369 printf("lo_queue= %lu, hi_queue= %lu\n",
370 lo_queue, hi_queue);
371 allright= FALSE;
372 }
373 }
374 else if (size != bf_bufsize(tcp_conn->tc_rcvd_data))
375 {
376 printf("RCV_NXT-RCV_LO != sizeof tc_rcvd_data\n");
377 tcp_print_conn(tcp_conn);
378 printf(
379 "lo_queue= %lu, hi_queue= %lu, sizeof tc_rcvd_data= %d\n",
380 lo_queue, hi_queue, bf_bufsize(tcp_conn->tc_rcvd_data));
381 allright= FALSE;
382 }
383 else if (size != 0 && (tcp_conn->tc_state == TCS_CLOSED ||
384 tcp_conn->tc_state == TCS_LISTEN ||
385 tcp_conn->tc_state == TCS_SYN_RECEIVED ||
386 tcp_conn->tc_state == TCS_SYN_SENT))
387 {
388 printf("received data but not connected\n");
389 tcp_print_conn(tcp_conn);
390 allright= FALSE;
391 }
392 if (tcp_Lmod4G(tcp_conn->tc_RCV_HI, tcp_conn->tc_RCV_NXT))
393 {
394 printf("tc_RCV_HI (0x%lx) < tc_RCV_NXT (0x%lx)\n",
395 (unsigned long)tcp_conn->tc_RCV_HI,
396 (unsigned long)tcp_conn->tc_RCV_NXT);
397 allright= FALSE;
398 }
399
400 /* checking send data */
401 lo_queue= tcp_conn->tc_SND_UNA;
402 if (lo_queue == tcp_conn->tc_ISS)
403 lo_queue++;
404 if (lo_queue == tcp_conn->tc_SND_NXT &&
405 (tcp_conn->tc_flags & TCF_FIN_SENT))
406 {
407 lo_queue--;
408 }
409 hi_queue= tcp_conn->tc_SND_NXT;
410 if (hi_queue == tcp_conn->tc_ISS)
411 hi_queue++;
412 if (tcp_conn->tc_flags & TCF_FIN_SENT)
413 hi_queue--;
414
415 size= hi_queue-lo_queue;
416 if (size<0)
417 {
418 printf("snd hi_queue-lo_queue < 0\n");
419 printf("SND_ISS= 0x%lx, SND_UNA= 0x%lx, SND_NXT= 0x%lx\n",
420 (unsigned long)tcp_conn->tc_ISS,
421 (unsigned long)tcp_conn->tc_SND_UNA,
422 (unsigned long)tcp_conn->tc_SND_NXT);
423 printf("hi_queue= 0x%lx, lo_queue= 0x%lx, size= %d\n",
424 (unsigned long)hi_queue, (unsigned long)lo_queue,
425 size);
426 allright= FALSE;
427 }
428 else if (!tcp_conn->tc_send_data)
429 {
430 if (size)
431 {
432 printf("SND_NXT-SND_UNA != 0\n");
433 printf("SND_NXT= 0x%lx, SND_UNA= 0x%lx\n",
434 (unsigned long)tcp_conn->tc_SND_NXT,
435 (unsigned long)tcp_conn->tc_SND_UNA);
436 printf("lo_queue= 0x%lx, hi_queue= 0x%lx\n",
437 (unsigned long)lo_queue,
438 (unsigned long)hi_queue);
439 allright= FALSE;
440 }
441 }
442 else if (size != bf_bufsize(tcp_conn->tc_send_data))
443 {
444 printf("SND_NXT-SND_UNA != sizeof tc_send_data\n");
445 printf("SND_NXT= 0x%lx, SND_UNA= 0x%lx\n",
446 (unsigned long)tcp_conn->tc_SND_NXT,
447 (unsigned long)tcp_conn->tc_SND_UNA);
448 printf("lo_queue= 0x%lx, lo_queue= 0x%lx\n",
449 (unsigned long)lo_queue,
450 (unsigned long)hi_queue);
451 printf("bf_bufsize(data)= %d\n",
452 bf_bufsize(tcp_conn->tc_send_data));
453
454 allright= FALSE;
455 }
456
457 /* checking counters */
458 if (!tcp_GEmod4G(tcp_conn->tc_SND_UNA, tcp_conn->tc_ISS))
459 {
460 printf("SND_UNA < ISS\n");
461 allright= FALSE;
462 }
463 if (!tcp_GEmod4G(tcp_conn->tc_SND_NXT, tcp_conn->tc_SND_UNA))
464 {
465 printf("SND_NXT<SND_UNA\n");
466 allright= FALSE;
467 }
468 if (!tcp_GEmod4G(tcp_conn->tc_SND_TRM, tcp_conn->tc_SND_UNA))
469 {
470 printf("SND_TRM<SND_UNA\n");
471 allright= FALSE;
472 }
473 if (!tcp_GEmod4G(tcp_conn->tc_SND_NXT, tcp_conn->tc_SND_TRM))
474 {
475 printf("SND_NXT<SND_TRM\n");
476 allright= FALSE;
477 }
478
479 DIFBLOCK(1, (!allright), printf("tcp_check_conn: not allright\n"));
480 return allright;
481}
482
483PUBLIC void tcp_print_pack(ip_hdr, tcp_hdr)
484ip_hdr_t *ip_hdr;
485tcp_hdr_t *tcp_hdr;
486{
487 int tcp_hdr_len;
488
489 assert(tcp_hdr);
490 if (ip_hdr)
491 writeIpAddr(ip_hdr->ih_src);
492 else
493 printf("???");
494 printf(",%u ", ntohs(tcp_hdr->th_srcport));
495 if (ip_hdr)
496 writeIpAddr(ip_hdr->ih_dst);
497 else
498 printf("???");
499 printf(",%u ", ntohs(tcp_hdr->th_dstport));
500 printf(" 0x%lx", ntohl(tcp_hdr->th_seq_nr));
501 if (tcp_hdr->th_flags & THF_FIN)
502 printf(" <FIN>");
503 if (tcp_hdr->th_flags & THF_SYN)
504 printf(" <SYN>");
505 if (tcp_hdr->th_flags & THF_RST)
506 printf(" <RST>");
507 if (tcp_hdr->th_flags & THF_PSH)
508 printf(" <PSH>");
509 if (tcp_hdr->th_flags & THF_ACK)
510 printf(" <ACK 0x%lx %u>", ntohl(tcp_hdr->th_ack_nr),
511 ntohs(tcp_hdr->th_window));
512 if (tcp_hdr->th_flags & THF_URG)
513 printf(" <URG %u>", tcp_hdr->th_urgptr);
514 tcp_hdr_len= (tcp_hdr->th_data_off & TH_DO_MASK) >> 2;
515 if (tcp_hdr_len != TCP_MIN_HDR_SIZE)
516 printf(" <options %d>", tcp_hdr_len-TCP_MIN_HDR_SIZE);
517}
518
519PUBLIC void tcp_print_conn(tcp_conn)
520tcp_conn_t *tcp_conn;
521{
522 u32_t iss, irs;
523 tcp_fd_t *tcp_fd;
524
525 iss= tcp_conn->tc_ISS;
526 irs= tcp_conn->tc_IRS;
527
528 tcp_print_state (tcp_conn);
529 printf(
530 " ISS 0x%lx UNA +0x%lx(0x%lx) TRM +0x%lx(0x%lx) NXT +0x%lx(0x%lx)",
531 iss, tcp_conn->tc_SND_UNA-iss, tcp_conn->tc_SND_UNA,
532 tcp_conn->tc_SND_TRM-iss, tcp_conn->tc_SND_TRM,
533 tcp_conn->tc_SND_NXT-iss, tcp_conn->tc_SND_NXT);
534 printf(
535 " UP +0x%lx(0x%lx) PSH +0x%lx(0x%lx) ",
536 tcp_conn->tc_SND_UP-iss, tcp_conn->tc_SND_UP,
537 tcp_conn->tc_SND_PSH-iss, tcp_conn->tc_SND_PSH);
538 printf(" snd_cwnd +0x%lx(0x%lx)",
539 tcp_conn->tc_snd_cwnd-tcp_conn->tc_SND_UNA,
540 tcp_conn->tc_snd_cwnd);
541 printf(" transmit_seq ");
542 if (tcp_conn->tc_transmit_seq == 0)
543 printf("0");
544 else
545 {
546 printf("+0x%lx(0x%lx)", tcp_conn->tc_transmit_seq-iss,
547 tcp_conn->tc_transmit_seq);
548 }
549 printf(" IRS 0x%lx LO +0x%lx(0x%lx) NXT +0x%lx(0x%lx) HI +0x%lx(0x%lx)",
550 irs, tcp_conn->tc_RCV_LO-irs, tcp_conn->tc_RCV_LO,
551 tcp_conn->tc_RCV_NXT-irs, tcp_conn->tc_RCV_NXT,
552 tcp_conn->tc_RCV_HI-irs, tcp_conn->tc_RCV_HI);
553 if (tcp_conn->tc_flags & TCF_INUSE)
554 printf(" TCF_INUSE");
555 if (tcp_conn->tc_flags & TCF_FIN_RECV)
556 printf(" TCF_FIN_RECV");
557 if (tcp_conn->tc_flags & TCF_RCV_PUSH)
558 printf(" TCF_RCV_PUSH");
559 if (tcp_conn->tc_flags & TCF_MORE2WRITE)
560 printf(" TCF_MORE2WRITE");
561 if (tcp_conn->tc_flags & TCF_SEND_ACK)
562 printf(" TCF_SEND_ACK");
563 if (tcp_conn->tc_flags & TCF_FIN_SENT)
564 printf(" TCF_FIN_SENT");
565 if (tcp_conn->tc_flags & TCF_BSD_URG)
566 printf(" TCF_BSD_URG");
567 if (tcp_conn->tc_flags & TCF_NO_PUSH)
568 printf(" TCF_NO_PUSH");
569 if (tcp_conn->tc_flags & TCF_PUSH_NOW)
570 printf(" TCF_PUSH_NOW");
571 if (tcp_conn->tc_flags & TCF_PMTU)
572 printf(" TCF_PMTU");
573 printf("\n");
574 writeIpAddr(tcp_conn->tc_locaddr);
575 printf(", %u -> ", ntohs(tcp_conn->tc_locport));
576 writeIpAddr(tcp_conn->tc_remaddr);
577 printf(", %u\n", ntohs(tcp_conn->tc_remport));
578 tcp_fd= tcp_conn->tc_fd;
579 if (!tcp_fd)
580 printf("tc_fd NULL");
581 else
582 {
583 printf("tc_fd #%d: flags 0x%x, r %u@%u, w %u@%u",
584 tcp_fd-tcp_fd_table, tcp_fd->tf_flags,
585 tcp_fd->tf_read_count, tcp_fd->tf_read_offset,
586 tcp_fd->tf_write_count, tcp_fd->tf_write_offset);
587 }
588}
589
590/*
591 * $PchId: tcp_lib.c,v 1.14 2005/01/31 21:41:38 philip Exp $
592 */
Note: See TracBrowser for help on using the repository browser.