4 Created: June 1995 by Philip Homburg <philip@f-mnx.phicoh.com>
8 #define _POSIX_C_SOURCE 2
10 #include <inet/inet.h>
18 #include <sys/svrctl.h>
20 #include <sys/times.h>
22 #include <net/netlib.h>
23 #include <net/gen/inet.h>
24 #include <net/gen/netdb.h>
25 #include <net/gen/socket.h>
26 #include <minix/queryparam.h>
27 #include <minix/com.h>
29 #include <inet/generic/buf.h>
30 #include <inet/generic/clock.h>
31 #include <inet/generic/event.h>
32 #include <inet/generic/type.h>
33 #include <inet/generic/tcp.h>
34 #include <inet/generic/tcp_int.h>
38 tcp_conn_t tcp_conn_table
[TCP_CONN_NR
];
39 char values
[2 * sizeof(tcp_conn_table
) + 1];
40 int inclListen
, numerical
, verbose
;
42 void print_conn(int i
, clock_t now
);
45 int main(int argc
, char*argv
[])
51 struct timeval uptime
;
54 int a_flag
, n_flag
, v_flag
;
57 system_hz
= (u32_t
) sysconf(_SC_CLK_TCK
);
59 (prog_name
=strrchr(argv
[0], '/')) ? prog_name
++ : (prog_name
=argv
[0]);
64 while ((fl
= getopt(argc
, argv
, "?anv")) != -1)
80 fprintf(stderr
, "%s: getopt failed: '%c'\n",
89 ipstat_device
= IPSTAT_DEVICE
;
90 if ((fd
= open(ipstat_device
, O_RDWR
)) == -1)
92 fprintf(stderr
, "%s: unable to open '%s': %s\n", prog_name
,
93 ipstat_device
, strerror(errno
));
97 query
= "tcp_conn_table";
99 r
= write(fd
, query
, len
);
102 fprintf(stderr
, "%s: write to %s failed: %s\n",
103 prog_name
, ipstat_device
, r
< 0 ? strerror(errno
) :
107 r
= read(fd
, values
, sizeof(values
));
110 fprintf(stderr
, "%s: read from %s failed: %s\n", prog_name
,
111 ipstat_device
, strerror(errno
));
115 if (paramvalue(&pval
, tcp_conn_table
, sizeof(tcp_conn_table
)) !=
116 sizeof(tcp_conn_table
))
119 "%s: unable to decode the results from queryparam\n",
125 /* Get the uptime in clock ticks. */
126 if (sysutime(UTIME_UPTIME
, &uptime
) == -1)
128 fprintf(stderr
, "%s: sysutime failed: %s\n", prog_name
,
132 now
= uptime
.tv_sec
* HZ
+ (uptime
.tv_usec
*HZ
/1000000);
137 for (i
= 0; i
<TCP_CONN_NR
; i
++)
142 void print_conn(int i
, clock_t now
)
144 tcp_conn_t
*tcp_conn
;
146 struct hostent
*hostent
;
147 struct servent
*servent
;
152 clock_t rtt
, artt
, drtt
;
154 tcp_conn
= &tcp_conn_table
[i
];
155 if (!(tcp_conn
->tc_flags
& TCF_INUSE
))
157 if (tcp_conn
->tc_state
== TCS_LISTEN
&& !inclListen
)
159 if (tcp_conn
->tc_state
== TCS_CLOSED
&& tcp_conn
->tc_fd
== NULL
&&
160 tcp_conn
->tc_senddis
< now
)
167 a1
= tcp_conn
->tc_locaddr
;
168 p1
= tcp_conn
->tc_locport
;
169 a2
= tcp_conn
->tc_remaddr
;
170 p2
= tcp_conn
->tc_remport
;
174 else if (!numerical
&&
175 (hostent
= gethostbyaddr((char *)&a1
,
176 sizeof(a1
), AF_INET
)) != NULL
)
178 addr_str
= hostent
->h_name
;
181 addr_str
= inet_ntoa(a1
);
182 printf(" %s:", addr_str
);
186 else if ((servent
= getservbyport(p1
, "tcp")) != NULL
)
188 printf("%s", servent
->s_name
);
191 printf("%u", ntohs(p1
));
193 if (tcp_conn
->tc_orglisten
)
200 else if (!numerical
&&
201 (hostent
= gethostbyaddr((char *)&a2
,
202 sizeof(a2
), AF_INET
)) != NULL
)
204 addr_str
= hostent
->h_name
;
207 addr_str
= inet_ntoa(a2
);
208 printf("%s:", addr_str
);
212 else if ((servent
= getservbyport(p2
, "tcp")) !=
215 printf("%s", servent
->s_name
);
218 printf("%u", ntohs(p2
));
222 switch(tcp_conn
->tc_state
)
224 case TCS_CLOSED
: printf("CLOSED");
225 if (tcp_conn
->tc_senddis
>= now
)
227 printf("(time wait %ld s)",
228 (tcp_conn
->tc_senddis
-now
)/system_hz
);
232 case TCS_LISTEN
: printf("LISTEN"); no_verbose
= 1; break;
233 case TCS_SYN_RECEIVED
: printf("SYN_RECEIVED"); break;
234 case TCS_SYN_SENT
: printf("SYN_SENT"); break;
235 case TCS_ESTABLISHED
: printf("ESTABLISHED"); break;
236 case TCS_CLOSING
: printf("CLOSING"); break;
237 default: printf("state(%d)", tcp_conn
->tc_state
);
241 if (tcp_conn
->tc_flags
& TCF_FIN_RECV
)
243 if (tcp_conn
->tc_flags
& TCF_FIN_SENT
)
246 if (tcp_conn
->tc_SND_UNA
== tcp_conn
->tc_SND_NXT
)
249 if (tcp_conn
->tc_state
!= TCS_CLOSED
&&
250 tcp_conn
->tc_state
!= TCS_LISTEN
)
253 printf("RQ: %lu, SQ: %lu, RWnd: %u, SWnd: %lu, SWThresh: %lu",
254 tcp_conn
->tc_RCV_NXT
- tcp_conn
->tc_RCV_LO
,
255 tcp_conn
->tc_SND_NXT
- tcp_conn
->tc_SND_UNA
,
256 tcp_conn
->tc_rcv_wnd
,
257 tcp_conn
->tc_snd_cwnd
- tcp_conn
->tc_SND_UNA
,
258 tcp_conn
->tc_snd_cthresh
);
263 if (!verbose
|| no_verbose
)
265 rtt
= tcp_conn
->tc_rtt
;
266 artt
= tcp_conn
->tc_artt
;
267 drtt
= tcp_conn
->tc_drtt
;
268 printf("\tmss %u, mtu %u%s, rtt %.3f (%.3f+%d*%.3f) s\n",
269 tcp_conn
->tc_max_mtu
-IP_TCP_MIN_HDR_SIZE
,
271 (tcp_conn
->tc_flags
& TCF_PMTU
) ? "" : " (no PMTU)",
273 artt
/(system_hz
+0.0)/TCP_RTT_SCALE
, TCP_DRTT_MULT
,
274 drtt
/(system_hz
+0.0)/TCP_RTT_SCALE
);
275 flags
= tcp_conn
->tc_flags
;
278 printf(" TCF_EMPTY");
279 if (flags
& TCF_INUSE
)
281 if (flags
& TCF_FIN_RECV
)
283 printf(" TCF_FIN_RECV");
284 flags
&= ~TCF_FIN_RECV
;
286 if (flags
& TCF_RCV_PUSH
)
288 printf(" TCF_RCV_PUSH");
289 flags
&= ~TCF_RCV_PUSH
;
291 if (flags
& TCF_MORE2WRITE
)
293 printf(" TCF_MORE2WRITE");
294 flags
&= ~TCF_MORE2WRITE
;
296 if (flags
& TCF_SEND_ACK
)
298 printf(" TCF_SEND_ACK");
299 flags
&= ~TCF_SEND_ACK
;
301 if (flags
& TCF_FIN_SENT
)
303 printf(" TCF_FIN_SENT");
304 flags
&= ~TCF_FIN_SENT
;
306 if (flags
& TCF_BSD_URG
)
308 printf(" TCF_BSD_URG");
309 flags
&= ~TCF_BSD_URG
;
311 if (flags
& TCF_NO_PUSH
)
313 printf(" TCF_NO_PUSH");
314 flags
&= ~TCF_NO_PUSH
;
316 if (flags
& TCF_PUSH_NOW
)
318 printf(" TCF_PUSH_NOW");
319 flags
&= ~TCF_PUSH_NOW
;
321 if (flags
& TCF_PMTU
)
324 printf(" 0x%x", flags
);
326 printf("\ttimer: ref %d, time %f, active %d\n",
327 tcp_conn
->tc_transmit_timer
.tim_ref
,
328 (0.0+tcp_conn
->tc_transmit_timer
.tim_time
-now
)/system_hz
,
329 tcp_conn
->tc_transmit_timer
.tim_active
);
334 fprintf(stderr
, "Usage: %s [-anv]\n", prog_name
);
339 * $PchId: tcpstat.c,v 1.8 2005/01/30 01:04:38 philip Exp $