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>
28 #include <minix/sysinfo.h>
30 #include <inet/generic/buf.h>
31 #include <inet/generic/clock.h>
32 #include <inet/generic/event.h>
33 #include <inet/generic/type.h>
34 #include <inet/generic/tcp.h>
35 #include <inet/generic/tcp_int.h>
39 tcp_conn_t tcp_conn_table
[TCP_CONN_NR
];
40 char values
[2 * sizeof(tcp_conn_table
) + 1];
41 int inclListen
, numerical
, verbose
;
43 void print_conn(int i
, clock_t now
);
46 int main(int argc
, char*argv
[])
52 struct timeval uptime
;
55 int a_flag
, n_flag
, v_flag
;
58 getsysinfo_up(PM_PROC_NR
, SIU_SYSTEMHZ
, sizeof(system_hz
), &system_hz
);
60 (prog_name
=strrchr(argv
[0], '/')) ? prog_name
++ : (prog_name
=argv
[0]);
65 while ((fl
= getopt(argc
, argv
, "?anv")) != -1)
81 fprintf(stderr
, "%s: getopt failed: '%c'\n",
90 ipstat_device
= IPSTAT_DEVICE
;
91 if ((fd
= open(ipstat_device
, O_RDWR
)) == -1)
93 fprintf(stderr
, "%s: unable to open '%s': %s\n", prog_name
,
94 ipstat_device
, strerror(errno
));
98 query
= "tcp_conn_table";
100 r
= write(fd
, query
, len
);
103 fprintf(stderr
, "%s: write to %s failed: %s\n",
104 prog_name
, ipstat_device
, r
< 0 ? strerror(errno
) :
108 r
= read(fd
, values
, sizeof(values
));
111 fprintf(stderr
, "%s: read from %s failed: %s\n", prog_name
,
112 ipstat_device
, strerror(errno
));
116 if (paramvalue(&pval
, tcp_conn_table
, sizeof(tcp_conn_table
)) !=
117 sizeof(tcp_conn_table
))
120 "%s: unable to decode the results from queryparam\n",
126 /* Get the uptime in clock ticks. */
127 if (sysutime(UTIME_UPTIME
, &uptime
) == -1)
129 fprintf(stderr
, "%s: sysutime failed: %s\n", prog_name
,
133 now
= uptime
.tv_sec
* HZ
+ (uptime
.tv_usec
*HZ
/1000000);
138 for (i
= 0; i
<TCP_CONN_NR
; i
++)
143 void print_conn(int i
, clock_t now
)
145 tcp_conn_t
*tcp_conn
;
147 struct hostent
*hostent
;
148 struct servent
*servent
;
153 clock_t rtt
, artt
, drtt
;
155 tcp_conn
= &tcp_conn_table
[i
];
156 if (!(tcp_conn
->tc_flags
& TCF_INUSE
))
158 if (tcp_conn
->tc_state
== TCS_LISTEN
&& !inclListen
)
160 if (tcp_conn
->tc_state
== TCS_CLOSED
&& tcp_conn
->tc_fd
== NULL
&&
161 tcp_conn
->tc_senddis
< now
)
168 a1
= tcp_conn
->tc_locaddr
;
169 p1
= tcp_conn
->tc_locport
;
170 a2
= tcp_conn
->tc_remaddr
;
171 p2
= tcp_conn
->tc_remport
;
175 else if (!numerical
&&
176 (hostent
= gethostbyaddr((char *)&a1
,
177 sizeof(a1
), AF_INET
)) != NULL
)
179 addr_str
= hostent
->h_name
;
182 addr_str
= inet_ntoa(a1
);
183 printf(" %s:", addr_str
);
187 else if ((servent
= getservbyport(p1
, "tcp")) != NULL
)
189 printf("%s", servent
->s_name
);
192 printf("%u", ntohs(p1
));
194 if (tcp_conn
->tc_orglisten
)
201 else if (!numerical
&&
202 (hostent
= gethostbyaddr((char *)&a2
,
203 sizeof(a2
), AF_INET
)) != NULL
)
205 addr_str
= hostent
->h_name
;
208 addr_str
= inet_ntoa(a2
);
209 printf("%s:", addr_str
);
213 else if ((servent
= getservbyport(p2
, "tcp")) !=
216 printf("%s", servent
->s_name
);
219 printf("%u", ntohs(p2
));
223 switch(tcp_conn
->tc_state
)
225 case TCS_CLOSED
: printf("CLOSED");
226 if (tcp_conn
->tc_senddis
>= now
)
228 printf("(time wait %ld s)",
229 (tcp_conn
->tc_senddis
-now
)/system_hz
);
233 case TCS_LISTEN
: printf("LISTEN"); no_verbose
= 1; break;
234 case TCS_SYN_RECEIVED
: printf("SYN_RECEIVED"); break;
235 case TCS_SYN_SENT
: printf("SYN_SENT"); break;
236 case TCS_ESTABLISHED
: printf("ESTABLISHED"); break;
237 case TCS_CLOSING
: printf("CLOSING"); break;
238 default: printf("state(%d)", tcp_conn
->tc_state
);
242 if (tcp_conn
->tc_flags
& TCF_FIN_RECV
)
244 if (tcp_conn
->tc_flags
& TCF_FIN_SENT
)
247 if (tcp_conn
->tc_SND_UNA
== tcp_conn
->tc_SND_NXT
)
250 if (tcp_conn
->tc_state
!= TCS_CLOSED
&&
251 tcp_conn
->tc_state
!= TCS_LISTEN
)
254 printf("RQ: %lu, SQ: %lu, RWnd: %u, SWnd: %lu, SWThresh: %lu",
255 tcp_conn
->tc_RCV_NXT
- tcp_conn
->tc_RCV_LO
,
256 tcp_conn
->tc_SND_NXT
- tcp_conn
->tc_SND_UNA
,
257 tcp_conn
->tc_rcv_wnd
,
258 tcp_conn
->tc_snd_cwnd
- tcp_conn
->tc_SND_UNA
,
259 tcp_conn
->tc_snd_cthresh
);
264 if (!verbose
|| no_verbose
)
266 rtt
= tcp_conn
->tc_rtt
;
267 artt
= tcp_conn
->tc_artt
;
268 drtt
= tcp_conn
->tc_drtt
;
269 printf("\tmss %u, mtu %u%s, rtt %.3f (%.3f+%d*%.3f) s\n",
270 tcp_conn
->tc_max_mtu
-IP_TCP_MIN_HDR_SIZE
,
272 (tcp_conn
->tc_flags
& TCF_PMTU
) ? "" : " (no PMTU)",
274 artt
/(system_hz
+0.0)/TCP_RTT_SCALE
, TCP_DRTT_MULT
,
275 drtt
/(system_hz
+0.0)/TCP_RTT_SCALE
);
276 flags
= tcp_conn
->tc_flags
;
279 printf(" TCF_EMPTY");
280 if (flags
& TCF_INUSE
)
282 if (flags
& TCF_FIN_RECV
)
284 printf(" TCF_FIN_RECV");
285 flags
&= ~TCF_FIN_RECV
;
287 if (flags
& TCF_RCV_PUSH
)
289 printf(" TCF_RCV_PUSH");
290 flags
&= ~TCF_RCV_PUSH
;
292 if (flags
& TCF_MORE2WRITE
)
294 printf(" TCF_MORE2WRITE");
295 flags
&= ~TCF_MORE2WRITE
;
297 if (flags
& TCF_SEND_ACK
)
299 printf(" TCF_SEND_ACK");
300 flags
&= ~TCF_SEND_ACK
;
302 if (flags
& TCF_FIN_SENT
)
304 printf(" TCF_FIN_SENT");
305 flags
&= ~TCF_FIN_SENT
;
307 if (flags
& TCF_BSD_URG
)
309 printf(" TCF_BSD_URG");
310 flags
&= ~TCF_BSD_URG
;
312 if (flags
& TCF_NO_PUSH
)
314 printf(" TCF_NO_PUSH");
315 flags
&= ~TCF_NO_PUSH
;
317 if (flags
& TCF_PUSH_NOW
)
319 printf(" TCF_PUSH_NOW");
320 flags
&= ~TCF_PUSH_NOW
;
322 if (flags
& TCF_PMTU
)
325 printf(" 0x%x", flags
);
327 printf("\ttimer: ref %d, time %f, active %d\n",
328 tcp_conn
->tc_transmit_timer
.tim_ref
,
329 (0.0+tcp_conn
->tc_transmit_timer
.tim_time
-now
)/system_hz
,
330 tcp_conn
->tc_transmit_timer
.tim_active
);
335 fprintf(stderr
, "Usage: %s [-anv]\n", prog_name
);
340 * $PchId: tcpstat.c,v 1.8 2005/01/30 01:04:38 philip Exp $