4 Created: June 1995 by Philip Homburg <philip@f-mnx.phicoh.com>
7 #define _POSIX_C_SOURCE 2
8 #define _NETBSD_SOURCE 1
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>
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
[])
52 struct timeval uptime
;
56 int a_flag
, n_flag
, v_flag
;
59 system_hz
= (u32_t
) sysconf(_SC_CLK_TCK
);
61 (prog_name
=strrchr(argv
[0], '/')) ? prog_name
++ : (prog_name
=argv
[0]);
66 while ((fl
= getopt(argc
, argv
, "?anv")) != -1)
82 fprintf(stderr
, "%s: getopt failed: '%c'\n",
91 ipstat_device
= IPSTAT_DEVICE
;
92 if ((fd
= open(ipstat_device
, O_RDWR
)) == -1)
94 fprintf(stderr
, "%s: unable to open '%s': %s\n", prog_name
,
95 ipstat_device
, strerror(errno
));
99 query
= "tcp_conn_table";
101 r
= write(fd
, query
, len
);
104 fprintf(stderr
, "%s: write to %s failed: %s\n",
105 prog_name
, ipstat_device
, r
< 0 ? strerror(errno
) :
109 r
= read(fd
, values
, sizeof(values
));
112 fprintf(stderr
, "%s: read from %s failed: %s\n", prog_name
,
113 ipstat_device
, strerror(errno
));
117 if (paramvalue(&pval
, tcp_conn_table
, sizeof(tcp_conn_table
)) !=
118 sizeof(tcp_conn_table
))
121 "%s: unable to decode the results from queryparam\n",
127 /* Get the uptime in clock ticks. */
128 if (sysutime(UTIME_UPTIME
, &uptime
) == -1)
130 fprintf(stderr
, "%s: sysutime failed: %s\n", prog_name
,
134 now
= uptime
.tv_sec
* HZ
+ (uptime
.tv_usec
*HZ
/1000000);
139 for (i
= 0; i
<TCP_CONN_NR
; i
++)
144 void print_conn(int i
, clock_t now
)
146 tcp_conn_t
*tcp_conn
;
148 struct hostent
*hostent
;
149 struct servent
*servent
;
154 clock_t rtt
, artt
, drtt
;
156 tcp_conn
= &tcp_conn_table
[i
];
157 if (!(tcp_conn
->tc_flags
& TCF_INUSE
))
159 if (tcp_conn
->tc_state
== TCS_LISTEN
&& !inclListen
)
161 if (tcp_conn
->tc_state
== TCS_CLOSED
&& tcp_conn
->tc_fd
== NULL
&&
162 tcp_conn
->tc_senddis
< now
)
169 a1
= tcp_conn
->tc_locaddr
;
170 p1
= tcp_conn
->tc_locport
;
171 a2
= tcp_conn
->tc_remaddr
;
172 p2
= tcp_conn
->tc_remport
;
176 else if (!numerical
&&
177 (hostent
= gethostbyaddr((char *)&a1
,
178 sizeof(a1
), AF_INET
)) != NULL
)
180 addr_str
= hostent
->h_name
;
183 addr_str
= inet_ntoa(a1
);
184 printf(" %s:", addr_str
);
188 else if ((servent
= getservbyport(p1
, "tcp")) != NULL
)
190 printf("%s", servent
->s_name
);
193 printf("%u", ntohs(p1
));
195 if (tcp_conn
->tc_orglisten
)
202 else if (!numerical
&&
203 (hostent
= gethostbyaddr((char *)&a2
,
204 sizeof(a2
), AF_INET
)) != NULL
)
206 addr_str
= hostent
->h_name
;
209 addr_str
= inet_ntoa(a2
);
210 printf("%s:", addr_str
);
214 else if ((servent
= getservbyport(p2
, "tcp")) !=
217 printf("%s", servent
->s_name
);
220 printf("%u", ntohs(p2
));
224 switch(tcp_conn
->tc_state
)
226 case TCS_CLOSED
: printf("CLOSED");
227 if (tcp_conn
->tc_senddis
>= now
)
229 printf("(time wait %d s)",
230 (tcp_conn
->tc_senddis
-now
)/system_hz
);
234 case TCS_LISTEN
: printf("LISTEN"); no_verbose
= 1; break;
235 case TCS_SYN_RECEIVED
: printf("SYN_RECEIVED"); break;
236 case TCS_SYN_SENT
: printf("SYN_SENT"); break;
237 case TCS_ESTABLISHED
: printf("ESTABLISHED"); break;
238 case TCS_CLOSING
: printf("CLOSING"); break;
239 default: printf("state(%d)", tcp_conn
->tc_state
);
243 if (tcp_conn
->tc_flags
& TCF_FIN_RECV
)
245 if (tcp_conn
->tc_flags
& TCF_FIN_SENT
)
248 if (tcp_conn
->tc_SND_UNA
== tcp_conn
->tc_SND_NXT
)
251 if (tcp_conn
->tc_state
!= TCS_CLOSED
&&
252 tcp_conn
->tc_state
!= TCS_LISTEN
)
255 printf("RQ: %u, SQ: %u, RWnd: %u, SWnd: %u, SWThresh: %u",
256 tcp_conn
->tc_RCV_NXT
- tcp_conn
->tc_RCV_LO
,
257 tcp_conn
->tc_SND_NXT
- tcp_conn
->tc_SND_UNA
,
258 tcp_conn
->tc_rcv_wnd
,
259 tcp_conn
->tc_snd_cwnd
- tcp_conn
->tc_SND_UNA
,
260 tcp_conn
->tc_snd_cthresh
);
265 if (!verbose
|| no_verbose
)
267 rtt
= tcp_conn
->tc_rtt
;
268 artt
= tcp_conn
->tc_artt
;
269 drtt
= tcp_conn
->tc_drtt
;
270 printf("\tmss %u, mtu %u%s, rtt %.3f (%.3f+%d*%.3f) s\n",
271 tcp_conn
->tc_max_mtu
-IP_TCP_MIN_HDR_SIZE
,
273 (tcp_conn
->tc_flags
& TCF_PMTU
) ? "" : " (no PMTU)",
275 artt
/(system_hz
+0.0)/TCP_RTT_SCALE
, TCP_DRTT_MULT
,
276 drtt
/(system_hz
+0.0)/TCP_RTT_SCALE
);
277 flags
= tcp_conn
->tc_flags
;
280 printf(" TCF_EMPTY");
281 if (flags
& TCF_INUSE
)
283 if (flags
& TCF_FIN_RECV
)
285 printf(" TCF_FIN_RECV");
286 flags
&= ~TCF_FIN_RECV
;
288 if (flags
& TCF_RCV_PUSH
)
290 printf(" TCF_RCV_PUSH");
291 flags
&= ~TCF_RCV_PUSH
;
293 if (flags
& TCF_MORE2WRITE
)
295 printf(" TCF_MORE2WRITE");
296 flags
&= ~TCF_MORE2WRITE
;
298 if (flags
& TCF_SEND_ACK
)
300 printf(" TCF_SEND_ACK");
301 flags
&= ~TCF_SEND_ACK
;
303 if (flags
& TCF_FIN_SENT
)
305 printf(" TCF_FIN_SENT");
306 flags
&= ~TCF_FIN_SENT
;
308 if (flags
& TCF_BSD_URG
)
310 printf(" TCF_BSD_URG");
311 flags
&= ~TCF_BSD_URG
;
313 if (flags
& TCF_NO_PUSH
)
315 printf(" TCF_NO_PUSH");
316 flags
&= ~TCF_NO_PUSH
;
318 if (flags
& TCF_PUSH_NOW
)
320 printf(" TCF_PUSH_NOW");
321 flags
&= ~TCF_PUSH_NOW
;
323 if (flags
& TCF_PMTU
)
326 printf(" 0x%x", flags
);
328 printf("\ttimer: ref %d, time %f, active %d\n",
329 tcp_conn
->tc_transmit_timer
.tim_ref
,
330 (0.0+tcp_conn
->tc_transmit_timer
.tim_time
-now
)/system_hz
,
331 tcp_conn
->tc_transmit_timer
.tim_active
);
336 fprintf(stderr
, "Usage: %s [-anv]\n", prog_name
);
341 * $PchId: tcpstat.c,v 1.8 2005/01/30 01:04:38 philip Exp $