Remove some unnecessary casts.
[dragonfly.git] / usr.bin / netstat / inet.c
CommitLineData
984263bc
MD
1/*
2 * Copyright (c) 1983, 1988, 1993, 1995
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
1de703da
MD
32 *
33 * @(#)inet.c 8.5 (Berkeley) 5/24/95
58b6d24a 34 * $FreeBSD: src/usr.bin/netstat/inet.c,v 1.37.2.11 2003/11/27 14:46:49 ru Exp $
26d88339 35 * $DragonFly: src/usr.bin/netstat/inet.c,v 1.21 2007/12/29 22:15:06 hasso Exp $
984263bc
MD
36 */
37
984263bc
MD
38#include <sys/param.h>
39#include <sys/queue.h>
40#include <sys/socket.h>
41#include <sys/socketvar.h>
42#include <sys/sysctl.h>
43#include <sys/protosw.h>
ae94c427 44#include <sys/time.h>
984263bc
MD
45
46#include <net/route.h>
47#include <netinet/in.h>
48#include <netinet/in_systm.h>
49#include <netinet/ip.h>
0d16ba1d 50#include <netinet/ip_carp.h>
984263bc
MD
51#ifdef INET6
52#include <netinet/ip6.h>
53#endif /* INET6 */
54#include <netinet/in_pcb.h>
55#include <netinet/ip_icmp.h>
56#include <netinet/icmp_var.h>
57#include <netinet/igmp_var.h>
58#include <netinet/ip_var.h>
ef73cf6c 59#include <netinet/pim_var.h>
984263bc
MD
60#include <netinet/tcp.h>
61#include <netinet/tcpip.h>
62#include <netinet/tcp_seq.h>
63#define TCPSTATES
64#include <netinet/tcp_fsm.h>
65#include <netinet/tcp_timer.h>
66#include <netinet/tcp_var.h>
67#include <netinet/tcp_debug.h>
68#include <netinet/udp.h>
69#include <netinet/udp_var.h>
70
71#include <arpa/inet.h>
72#include <err.h>
73#include <errno.h>
74#include <libutil.h>
75#include <netdb.h>
76#include <stdio.h>
77#include <stdlib.h>
78#include <string.h>
79#include <unistd.h>
80#include "netstat.h"
81
82char *inetname (struct in_addr *);
d2e9e54c 83void inetprint (struct in_addr *, int, const char *, int);
984263bc 84#ifdef INET6
d2e9e54c 85extern void inet6print (struct in6_addr *, int, const char *, int);
984263bc
MD
86static int udp_done, tcp_done;
87#endif /* INET6 */
88
89/*
90 * Print a summary of connections related to an Internet
91 * protocol. For TCP, also give state of connection.
92 * Listening processes (aflag) are suppressed unless the
93 * -a (all) flag is specified.
94 */
d2e9e54c
MD
95
96static int ppr_first = 1;
8d7c364e 97static void outputpcb(int proto, const char *name, struct inpcb *inp, struct xsocket *so, struct tcpcb *tp);
d2e9e54c 98
984263bc 99void
d2e9e54c 100protopr(u_long proto, char *name, int af)
984263bc
MD
101{
102 int istcp;
d2e9e54c 103 int i;
8d7c364e 104 void *buf;
d2e9e54c 105 const char *mibvar;
984263bc
MD
106 size_t len;
107
108 istcp = 0;
109 switch (proto) {
110 case IPPROTO_TCP:
111#ifdef INET6
112 if (tcp_done != 0)
113 return;
114 else
115 tcp_done = 1;
116#endif
117 istcp = 1;
118 mibvar = "net.inet.tcp.pcblist";
119 break;
120 case IPPROTO_UDP:
121#ifdef INET6
122 if (udp_done != 0)
123 return;
124 else
125 udp_done = 1;
126#endif
127 mibvar = "net.inet.udp.pcblist";
128 break;
129 case IPPROTO_DIVERT:
130 mibvar = "net.inet.divert.pcblist";
131 break;
132 default:
133 mibvar = "net.inet.raw.pcblist";
134 break;
135 }
136 len = 0;
137 if (sysctlbyname(mibvar, 0, &len, 0, 0) < 0) {
138 if (errno != ENOENT)
139 warn("sysctl: %s", mibvar);
140 return;
141 }
8d7c364e
JS
142 if (len == 0)
143 return;
984263bc
MD
144 if ((buf = malloc(len)) == 0) {
145 warn("malloc %lu bytes", (u_long)len);
146 return;
147 }
148 if (sysctlbyname(mibvar, buf, &len, 0, 0) < 0) {
149 warn("sysctl: %s", mibvar);
150 free(buf);
151 return;
152 }
153
8d7c364e
JS
154 if (istcp) {
155 struct xtcpcb *tcp = buf;
156 len /= sizeof(*tcp);
157 for (i = 0; i < len; i++) {
158 if (tcp[i].xt_len != sizeof(*tcp))
159 break;
160 outputpcb(proto, name, &tcp[i].xt_inp,
161 &tcp[i].xt_socket, &tcp[i].xt_tp);
d2e9e54c 162 }
8d7c364e
JS
163 } else {
164 struct xinpcb *in = buf;
165 len /= sizeof(*in);
166 for (i = 0; i < len; i++) {
167 if (in[i].xi_len != sizeof(*in))
168 break;
169 outputpcb(proto, name, &in[i].xi_inp,
170 &in[i].xi_socket, NULL);
984263bc 171 }
d2e9e54c 172 }
d2e9e54c
MD
173 free(buf);
174}
984263bc 175
d2e9e54c 176static void
8d7c364e 177outputpcb(int proto, const char *name, struct inpcb *inp, struct xsocket *so, struct tcpcb *tp)
d2e9e54c
MD
178{
179 const char *vchar;
ae94c427
MD
180 static struct clockinfo clockinfo;
181
182 if (clockinfo.hz == 0) {
183 int size = sizeof(clockinfo);
184 sysctlbyname("kern.clockrate", &clockinfo, &size, NULL, 0);
185 if (clockinfo.hz == 0)
186 clockinfo.hz = 100;
187 }
984263bc 188
d2e9e54c
MD
189 /* Ignore sockets for protocols other than the desired one. */
190 if (so->xso_protocol != (int)proto)
191 return;
984263bc 192
d2e9e54c 193 if ((af == AF_INET && (inp->inp_vflag & INP_IPV4) == 0)
984263bc 194#ifdef INET6
d2e9e54c 195 || (af == AF_INET6 && (inp->inp_vflag & INP_IPV6) == 0)
984263bc 196#endif /* INET6 */
d2e9e54c 197 || (af == AF_UNSPEC && ((inp->inp_vflag & INP_IPV4) == 0
984263bc 198#ifdef INET6
d2e9e54c 199 && (inp->inp_vflag & INP_IPV6) == 0
984263bc 200#endif /* INET6 */
d2e9e54c
MD
201 ))
202 ) {
203 return;
204 }
205 if (!aflag && (
26d88339 206 (proto == IPPROTO_TCP && tp->t_state == TCPS_LISTEN) ||
d2e9e54c 207 (af == AF_INET && inet_lnaof(inp->inp_laddr) == INADDR_ANY)
984263bc 208#ifdef INET6
d2e9e54c 209 || (af == AF_INET6 && IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr))
984263bc 210#endif /* INET6 */
d2e9e54c
MD
211 || (af == AF_UNSPEC && (((inp->inp_vflag & INP_IPV4) != 0 &&
212 inet_lnaof(inp->inp_laddr) == INADDR_ANY)
984263bc 213#ifdef INET6
d2e9e54c
MD
214 || ((inp->inp_vflag & INP_IPV6) != 0 &&
215 IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr))
984263bc 216#endif
d2e9e54c
MD
217 ))
218 )) {
219 return;
220 }
221
222 if (ppr_first) {
223 if (!Lflag) {
224 printf("Active Internet connections");
225 if (aflag)
226 printf(" (including servers)");
227 } else {
228 printf("Current listen queue sizes "
229 "(qlen/incqlen/maxqlen)");
984263bc 230 }
d2e9e54c
MD
231 putchar('\n');
232 if (Aflag)
233 printf("%-8.8s ", "Socket");
ae94c427
MD
234 if (Pflag)
235 printf("%8.8s %8.8s %8.8s ", "TxWin", "Unacked", "RTT/ms");
d2e9e54c 236 if (Lflag) {
8d7c364e
JS
237 printf("%-5.5s %-14.14s %-22.22s\n",
238 "Proto", "Listen", "Local Address");
d2e9e54c
MD
239 } else {
240 printf((Aflag && !Wflag) ?
8d7c364e
JS
241 "%-5.5s %-6.6s %-6.6s %-17.17s %-17.17s %s\n" :
242 "%-5.5s %-6.6s %-6.6s %-21.21s %-21.21s %s\n",
243 "Proto", "Recv-Q", "Send-Q",
d2e9e54c
MD
244 "Local Address", "Foreign Address",
245 "(state)");
984263bc 246 }
d2e9e54c
MD
247 ppr_first = 0;
248 }
249 if (Lflag && so->so_qlimit == 0)
250 return;
251 if (Aflag) {
252 if (tp)
253 printf("%8lx ", (u_long)inp->inp_ppcb);
984263bc 254 else
d2e9e54c
MD
255 printf("%8lx ", (u_long)so->so_pcb);
256 }
ae94c427
MD
257 if (Pflag) {
258 if (tp) {
259 int window = MIN(tp->snd_cwnd, tp->snd_bwnd);
260 if (window == 1073725440)
261 printf("%8s ", "max");
262 else
263 printf("%8d ", (int)MIN(tp->snd_cwnd, tp->snd_bwnd));
264 printf("%8d ", (int)(tp->snd_max - tp->snd_una));
265 if (tp->t_srtt == 0)
266 printf("%8s ", "-");
267 else
268 printf("%8.3f ", (double)tp->t_srtt * 1000.0 / TCP_RTT_SCALE / clockinfo.hz);
269 } else {
270 printf("%8s %8s %8s ", "-", "-", "-");
271 }
272 }
d2e9e54c
MD
273#ifdef INET6
274 if ((inp->inp_vflag & INP_IPV6) != 0)
275 vchar = ((inp->inp_vflag & INP_IPV4) != 0) ? "46" : "6 ";
276 else
984263bc 277#endif
d2e9e54c
MD
278 vchar = ((inp->inp_vflag & INP_IPV4) != 0) ? "4 " : " ";
279
8d7c364e 280 printf("%-3.3s%-2.2s ", name, vchar);
d2e9e54c
MD
281 if (Lflag) {
282 char buf[15];
283
284 snprintf(buf, sizeof(buf), "%d/%d/%d", so->so_qlen,
285 so->so_incqlen, so->so_qlimit);
286 printf("%-13.13s ", buf);
287 } else if (Bflag) {
288 printf("%6ld %6ld ",
289 so->so_rcv.sb_hiwat,
290 so->so_snd.sb_hiwat);
291 } else {
292 printf("%6ld %6ld ",
293 so->so_rcv.sb_cc,
294 so->so_snd.sb_cc);
295 }
296 if (numeric_port) {
297 if (inp->inp_vflag & INP_IPV4) {
298 inetprint(&inp->inp_laddr, (int)inp->inp_lport,
299 name, 1);
300 if (!Lflag)
301 inetprint(&inp->inp_faddr,
302 (int)inp->inp_fport, name, 1);
984263bc 303 }
984263bc 304#ifdef INET6
d2e9e54c
MD
305 else if (inp->inp_vflag & INP_IPV6) {
306 inet6print(&inp->in6p_laddr,
307 (int)inp->inp_lport, name, 1);
308 if (!Lflag)
309 inet6print(&inp->in6p_faddr,
310 (int)inp->inp_fport, name, 1);
311 } /* else nothing printed now */
984263bc 312#endif /* INET6 */
d2e9e54c
MD
313 } else if (inp->inp_flags & INP_ANONPORT) {
314 if (inp->inp_vflag & INP_IPV4) {
315 inetprint(&inp->inp_laddr, (int)inp->inp_lport,
316 name, 1);
317 if (!Lflag)
318 inetprint(&inp->inp_faddr,
319 (int)inp->inp_fport, name, 0);
320 }
984263bc 321#ifdef INET6
d2e9e54c
MD
322 else if (inp->inp_vflag & INP_IPV6) {
323 inet6print(&inp->in6p_laddr,
324 (int)inp->inp_lport, name, 1);
325 if (!Lflag)
326 inet6print(&inp->in6p_faddr,
327 (int)inp->inp_fport, name, 0);
328 } /* else nothing printed now */
984263bc 329#endif /* INET6 */
d2e9e54c
MD
330 } else {
331 if (inp->inp_vflag & INP_IPV4) {
332 inetprint(&inp->inp_laddr, (int)inp->inp_lport,
333 name, 0);
334 if (!Lflag)
335 inetprint(&inp->inp_faddr,
336 (int)inp->inp_fport, name,
337 inp->inp_lport !=
338 inp->inp_fport);
339 }
984263bc 340#ifdef INET6
d2e9e54c
MD
341 else if (inp->inp_vflag & INP_IPV6) {
342 inet6print(&inp->in6p_laddr,
343 (int)inp->inp_lport, name, 0);
344 if (!Lflag)
345 inet6print(&inp->in6p_faddr,
346 (int)inp->inp_fport, name,
347 inp->inp_lport !=
348 inp->inp_fport);
349 } /* else nothing printed now */
984263bc 350#endif /* INET6 */
d2e9e54c
MD
351 }
352 if (tp && !Lflag) {
353 if (tp->t_state < 0 || tp->t_state >= TCP_NSTATES)
354 printf("%d", tp->t_state);
355 else {
356 printf("%s", tcpstates[tp->t_state]);
984263bc 357#if defined(TF_NEEDSYN) && defined(TF_NEEDFIN)
d2e9e54c
MD
358 /* Show T/TCP `hidden state' */
359 if (tp->t_flags & (TF_NEEDSYN|TF_NEEDFIN))
360 putchar('*');
984263bc 361#endif /* defined(TF_NEEDSYN) && defined(TF_NEEDFIN) */
d2e9e54c 362 }
984263bc 363 }
d2e9e54c 364 putchar('\n');
984263bc
MD
365}
366
d2e9e54c
MD
367
368
fc9c7b4f
HP
369#define CPU_STATS_FUNC(proto,type) \
370static void \
371proto ##_stats_agg(type *ary, type *ttl, int cpucnt) \
372{ \
373 int i, off, siz; \
374 siz = sizeof(type); \
375 \
376 if (!ary && !ttl) \
377 return; \
378 \
379 bzero(ttl, siz); \
380 if (cpucnt == 1) { \
381 *ttl = ary[0]; \
382 } else { \
383 for (i = 0; i < cpucnt; ++i) { \
384 for (off = 0; off < siz; off += sizeof(u_long)) { \
385 *(u_long *)((char *)(*(&ttl)) + off) += \
386 *(u_long *)((char *)&ary[i] + off); \
387 } \
388 } \
389 } \
2b57d013 390}
fc9c7b4f
HP
391CPU_STATS_FUNC(tcp, struct tcp_stats);
392CPU_STATS_FUNC(ip, struct ip_stats);
2b57d013 393
984263bc
MD
394/*
395 * Dump TCP statistics structure.
396 */
397void
398tcp_stats(u_long off __unused, char *name, int af __unused)
399{
2b57d013
MD
400 struct tcp_stats tcpstat, *stattmp;
401 struct tcp_stats zerostat[SMP_MAXCPU];
402 size_t len = sizeof(struct tcp_stats) * SMP_MAXCPU;
403 int cpucnt;
984263bc
MD
404
405 if (zflag)
2b57d013
MD
406 memset(zerostat, 0, len);
407
408 if ((stattmp = malloc(len)) == NULL) {
984263bc 409 return;
2b57d013
MD
410 } else {
411 if (sysctlbyname("net.inet.tcp.stats", stattmp, &len,
412 zflag ? zerostat : NULL, zflag ? len : 0) < 0) {
413 warn("sysctl: net.inet.tcp.stats");
414 free(stattmp);
415 return;
416 } else {
417 if ((stattmp = realloc(stattmp, len)) == NULL) {
418 warn("tcp_stats");
419 return;
420 }
421 }
984263bc 422 }
2b57d013
MD
423 cpucnt = len / sizeof(struct tcp_stats);
424 tcp_stats_agg(stattmp, &tcpstat, cpucnt);
984263bc
MD
425
426#ifdef INET6
427 if (tcp_done != 0)
428 return;
429 else
430 tcp_done = 1;
431#endif
432
433 printf ("%s:\n", name);
434
435#define p(f, m) if (tcpstat.f || sflag <= 1) \
436 printf(m, tcpstat.f, plural(tcpstat.f))
437#define p1a(f, m) if (tcpstat.f || sflag <= 1) \
438 printf(m, tcpstat.f)
439#define p2(f1, f2, m) if (tcpstat.f1 || tcpstat.f2 || sflag <= 1) \
440 printf(m, tcpstat.f1, plural(tcpstat.f1), tcpstat.f2, plural(tcpstat.f2))
441#define p2a(f1, f2, m) if (tcpstat.f1 || tcpstat.f2 || sflag <= 1) \
442 printf(m, tcpstat.f1, plural(tcpstat.f1), tcpstat.f2)
443#define p3(f, m) if (tcpstat.f || sflag <= 1) \
444 printf(m, tcpstat.f, plurales(tcpstat.f))
445
446 p(tcps_sndtotal, "\t%lu packet%s sent\n");
447 p2(tcps_sndpack,tcps_sndbyte,
448 "\t\t%lu data packet%s (%lu byte%s)\n");
449 p2(tcps_sndrexmitpack, tcps_sndrexmitbyte,
450 "\t\t%lu data packet%s (%lu byte%s) retransmitted\n");
ae8922cc
JH
451 p2a(tcps_sndfastrexmit, tcps_sndearlyrexmit,
452 "\t\t%lu Fast Retransmit%s (%lu early)\n");
453 p(tcps_sndlimited, "\t\t%lu packet%s sent by Limited Transmit\n");
7f8fbc35 454 p(tcps_sndrtobad, "\t\t%lu spurious RTO retransmit%s\n");
ae8922cc
JH
455 p2a(tcps_sndfastrexmitbad, tcps_sndearlyrexmitbad,
456 "\t\t%lu spurious Fast Retransmit%s (%lu early)\n");
88f7ddb2
JH
457 p(tcps_eifeldetected, "\t\t%lu Eifel-detected spurious retransmit%s\n");
458 p(tcps_rttdetected, "\t\t%lu RTT-detected spurious retransmit%s\n");
984263bc
MD
459 p(tcps_mturesent, "\t\t%lu resend%s initiated by MTU discovery\n");
460 p2a(tcps_sndacks, tcps_delack,
461 "\t\t%lu ack-only packet%s (%lu delayed)\n");
462 p(tcps_sndurg, "\t\t%lu URG only packet%s\n");
463 p(tcps_sndprobe, "\t\t%lu window probe packet%s\n");
464 p(tcps_sndwinup, "\t\t%lu window update packet%s\n");
465 p(tcps_sndctrl, "\t\t%lu control packet%s\n");
466 p(tcps_rcvtotal, "\t%lu packet%s received\n");
467 p2(tcps_rcvackpack, tcps_rcvackbyte, "\t\t%lu ack%s (for %lu byte%s)\n");
468 p(tcps_rcvdupack, "\t\t%lu duplicate ack%s\n");
469 p(tcps_rcvacktoomuch, "\t\t%lu ack%s for unsent data\n");
470 p2(tcps_rcvpack, tcps_rcvbyte,
471 "\t\t%lu packet%s (%lu byte%s) received in-sequence\n");
472 p2(tcps_rcvduppack, tcps_rcvdupbyte,
473 "\t\t%lu completely duplicate packet%s (%lu byte%s)\n");
474 p(tcps_pawsdrop, "\t\t%lu old duplicate packet%s\n");
475 p2(tcps_rcvpartduppack, tcps_rcvpartdupbyte,
476 "\t\t%lu packet%s with some dup. data (%lu byte%s duped)\n");
477 p2(tcps_rcvoopack, tcps_rcvoobyte,
478 "\t\t%lu out-of-order packet%s (%lu byte%s)\n");
479 p2(tcps_rcvpackafterwin, tcps_rcvbyteafterwin,
480 "\t\t%lu packet%s (%lu byte%s) of data after window\n");
481 p(tcps_rcvwinprobe, "\t\t%lu window probe%s\n");
482 p(tcps_rcvwinupd, "\t\t%lu window update packet%s\n");
483 p(tcps_rcvafterclose, "\t\t%lu packet%s received after close\n");
484 p(tcps_rcvbadsum, "\t\t%lu discarded for bad checksum%s\n");
485 p(tcps_rcvbadoff, "\t\t%lu discarded for bad header offset field%s\n");
486 p1a(tcps_rcvshort, "\t\t%lu discarded because packet too short\n");
487 p(tcps_connattempt, "\t%lu connection request%s\n");
488 p(tcps_accepts, "\t%lu connection accept%s\n");
489 p(tcps_badsyn, "\t%lu bad connection attempt%s\n");
490 p(tcps_listendrop, "\t%lu listen queue overflow%s\n");
491 p(tcps_connects, "\t%lu connection%s established (including accepts)\n");
492 p2(tcps_closed, tcps_drops,
493 "\t%lu connection%s closed (including %lu drop%s)\n");
494 p(tcps_cachedrtt, "\t\t%lu connection%s updated cached RTT on close\n");
495 p(tcps_cachedrttvar,
496 "\t\t%lu connection%s updated cached RTT variance on close\n");
497 p(tcps_cachedssthresh,
498 "\t\t%lu connection%s updated cached ssthresh on close\n");
499 p(tcps_conndrops, "\t%lu embryonic connection%s dropped\n");
500 p2(tcps_rttupdated, tcps_segstimed,
501 "\t%lu segment%s updated rtt (of %lu attempt%s)\n");
502 p(tcps_rexmttimeo, "\t%lu retransmit timeout%s\n");
503 p(tcps_timeoutdrop, "\t\t%lu connection%s dropped by rexmit timeout\n");
504 p(tcps_persisttimeo, "\t%lu persist timeout%s\n");
505 p(tcps_persistdrop, "\t\t%lu connection%s dropped by persist timeout\n");
506 p(tcps_keeptimeo, "\t%lu keepalive timeout%s\n");
507 p(tcps_keepprobe, "\t\t%lu keepalive probe%s sent\n");
508 p(tcps_keepdrops, "\t\t%lu connection%s dropped by keepalive\n");
509 p(tcps_predack, "\t%lu correct ACK header prediction%s\n");
510 p(tcps_preddat, "\t%lu correct data packet header prediction%s\n");
511
6de4f7ba
HP
512 p1a(tcps_sc_added, "\t%lu syncache entries added\n");
513 p1a(tcps_sc_retransmitted, "\t\t%lu retransmitted\n");
514 p1a(tcps_sc_dupsyn, "\t\t%lu dupsyn\n");
515 p1a(tcps_sc_dropped, "\t\t%lu dropped\n");
516 p1a(tcps_sc_completed, "\t\t%lu completed\n");
517 p1a(tcps_sc_bucketoverflow, "\t\t%lu bucket overflow\n");
518 p1a(tcps_sc_cacheoverflow, "\t\t%lu cache overflow\n");
519 p1a(tcps_sc_reset, "\t\t%lu reset\n");
520 p1a(tcps_sc_stale, "\t\t%lu stale\n");
521 p1a(tcps_sc_aborted, "\t\t%lu aborted\n");
522 p1a(tcps_sc_badack, "\t\t%lu badack\n");
523 p1a(tcps_sc_unreach, "\t\t%lu unreach\n");
524 p1a(tcps_sc_zonefail, "\t\t%lu zone failures\n");
525 p1a(tcps_sc_sendcookie, "\t%lu cookies sent\n");
526 p1a(tcps_sc_recvcookie, "\t%lu cookies received\n");
2b57d013 527 free(stattmp);
984263bc
MD
528#undef p
529#undef p1a
530#undef p2
531#undef p2a
532#undef p3
533}
534
535/*
536 * Dump UDP statistics structure.
537 */
538void
539udp_stats(u_long off __unused, char *name, int af __unused)
540{
541 struct udpstat udpstat, zerostat;
542 size_t len = sizeof udpstat;
543 u_long delivered;
544
545 if (zflag)
546 memset(&zerostat, 0, len);
547 if (sysctlbyname("net.inet.udp.stats", &udpstat, &len,
548 zflag ? &zerostat : NULL, zflag ? len : 0) < 0) {
549 warn("sysctl: net.inet.udp.stats");
550 return;
551 }
552
553#ifdef INET6
554 if (udp_done != 0)
555 return;
556 else
557 udp_done = 1;
558#endif
559
560 printf("%s:\n", name);
561#define p(f, m) if (udpstat.f || sflag <= 1) \
562 printf(m, udpstat.f, plural(udpstat.f))
563#define p1a(f, m) if (udpstat.f || sflag <= 1) \
564 printf(m, udpstat.f)
565 p(udps_ipackets, "\t%lu datagram%s received\n");
566 p1a(udps_hdrops, "\t%lu with incomplete header\n");
567 p1a(udps_badlen, "\t%lu with bad data length field\n");
568 p1a(udps_badsum, "\t%lu with bad checksum\n");
569 p1a(udps_nosum, "\t%lu with no checksum\n");
570 p1a(udps_noport, "\t%lu dropped due to no socket\n");
571 p(udps_noportbcast,
572 "\t%lu broadcast/multicast datagram%s dropped due to no socket\n");
573 p1a(udps_fullsock, "\t%lu dropped due to full socket buffers\n");
574 p1a(udpps_pcbhashmiss, "\t%lu not for hashed pcb\n");
575 delivered = udpstat.udps_ipackets -
576 udpstat.udps_hdrops -
577 udpstat.udps_badlen -
578 udpstat.udps_badsum -
579 udpstat.udps_noport -
580 udpstat.udps_noportbcast -
581 udpstat.udps_fullsock;
582 if (delivered || sflag <= 1)
583 printf("\t%lu delivered\n", delivered);
584 p(udps_opackets, "\t%lu datagram%s output\n");
585#undef p
586#undef p1a
587}
588
0d16ba1d
MD
589/*
590 * Dump CARP statistics structure.
591 */
592void
593carp_stats(u_long off, const char *name, int af1 __unused)
594{
595 struct carpstats carpstat, zerostat;
596 size_t len = sizeof(struct carpstats);
597
598 if (zflag)
599 memset(&zerostat, 0, len);
600 if (sysctlbyname("net.inet.carp.stats", &carpstat, &len,
601 zflag ? &zerostat : NULL, zflag ? len : 0) < 0) {
602 warn("sysctl: net.inet.carp.stats");
603 return;
604 }
605
606 printf("%s:\n", name);
607
608#define p(f, m) if (carpstat.f || sflag <= 1) \
609 printf(m, (unsigned long long)carpstat.f, plural((int)carpstat.f))
610#define p2(f, m) if (carpstat.f || sflag <= 1) \
611 printf(m, (unsigned long long)carpstat.f)
612
613 p(carps_ipackets, "\t%llu packet%s received (IPv4)\n");
614 p(carps_ipackets6, "\t%llu packet%s received (IPv6)\n");
615 p(carps_badttl, "\t\t%llu packet%s discarded for wrong TTL\n");
616 p(carps_hdrops, "\t\t%llu packet%s shorter than header\n");
617 p(carps_badsum, "\t\t%llu discarded for bad checksum%s\n");
618 p(carps_badver, "\t\t%llu discarded packet%s with a bad version\n");
619 p2(carps_badlen, "\t\t%llu discarded because packet too short\n");
620 p2(carps_badauth, "\t\t%llu discarded for bad authentication\n");
621 p2(carps_badvhid, "\t\t%llu discarded for bad vhid\n");
622 p2(carps_badaddrs, "\t\t%llu discarded because of a bad address list\n");
623 p(carps_opackets, "\t%llu packet%s sent (IPv4)\n");
624 p(carps_opackets6, "\t%llu packet%s sent (IPv6)\n");
625 p2(carps_onomem, "\t\t%llu send failed due to mbuf memory error\n");
626#if notyet
627 p(carps_ostates, "\t\t%s state update%s sent\n");
628#endif
629#undef p
630#undef p2
631}
632
984263bc
MD
633/*
634 * Dump IP statistics structure.
635 */
636void
637ip_stats(u_long off __unused, char *name, int af __unused)
638{
fc9c7b4f
HP
639 struct ip_stats ipstat, *stattmp;
640 struct ip_stats zerostat[SMP_MAXCPU];
641 size_t len = sizeof(struct ip_stats) * SMP_MAXCPU;
642 int cpucnt;
984263bc
MD
643
644 if (zflag)
fc9c7b4f
HP
645 memset(zerostat, 0, len);
646 if ((stattmp = malloc(len)) == NULL) {
984263bc 647 return;
fc9c7b4f
HP
648 } else {
649 if (sysctlbyname("net.inet.ip.stats", stattmp, &len,
650 zflag ? zerostat : NULL, zflag ? len : 0) < 0) {
651 warn("sysctl: net.inet.ip.stats");
652 free(stattmp);
653 return;
654 } else {
655 if ((stattmp = realloc(stattmp, len)) == NULL) {
656 warn("ip_stats");
657 return;
658 }
659 }
984263bc 660 }
fc9c7b4f
HP
661 cpucnt = len / sizeof(struct ip_stats);
662 ip_stats_agg(stattmp, &ipstat, cpucnt);
984263bc
MD
663
664 printf("%s:\n", name);
665
666#define p(f, m) if (ipstat.f || sflag <= 1) \
667 printf(m, ipstat.f, plural(ipstat.f))
668#define p1a(f, m) if (ipstat.f || sflag <= 1) \
669 printf(m, ipstat.f)
670
671 p(ips_total, "\t%lu total packet%s received\n");
672 p(ips_badsum, "\t%lu bad header checksum%s\n");
673 p1a(ips_toosmall, "\t%lu with size smaller than minimum\n");
674 p1a(ips_tooshort, "\t%lu with data size < data length\n");
675 p1a(ips_toolong, "\t%lu with ip length > max ip packet size\n");
676 p1a(ips_badhlen, "\t%lu with header length < data size\n");
677 p1a(ips_badlen, "\t%lu with data length < header length\n");
678 p1a(ips_badoptions, "\t%lu with bad options\n");
679 p1a(ips_badvers, "\t%lu with incorrect version number\n");
680 p(ips_fragments, "\t%lu fragment%s received\n");
681 p(ips_fragdropped, "\t%lu fragment%s dropped (dup or out of space)\n");
682 p(ips_fragtimeout, "\t%lu fragment%s dropped after timeout\n");
683 p(ips_reassembled, "\t%lu packet%s reassembled ok\n");
684 p(ips_delivered, "\t%lu packet%s for this host\n");
685 p(ips_noproto, "\t%lu packet%s for unknown/unsupported protocol\n");
686 p(ips_forward, "\t%lu packet%s forwarded");
687 p(ips_fastforward, " (%lu packet%s fast forwarded)");
688 if (ipstat.ips_forward || sflag <= 1)
689 putchar('\n');
690 p(ips_cantforward, "\t%lu packet%s not forwardable\n");
691 p(ips_notmember,
692 "\t%lu packet%s received for unknown multicast group\n");
693 p(ips_redirectsent, "\t%lu redirect%s sent\n");
694 p(ips_localout, "\t%lu packet%s sent from this host\n");
695 p(ips_rawout, "\t%lu packet%s sent with fabricated ip header\n");
696 p(ips_odropped,
697 "\t%lu output packet%s dropped due to no bufs, etc.\n");
698 p(ips_noroute, "\t%lu output packet%s discarded due to no route\n");
699 p(ips_fragmented, "\t%lu output datagram%s fragmented\n");
700 p(ips_ofragments, "\t%lu fragment%s created\n");
701 p(ips_cantfrag, "\t%lu datagram%s that can't be fragmented\n");
702 p(ips_nogif, "\t%lu tunneling packet%s that can't find gif\n");
703 p(ips_badaddr, "\t%lu datagram%s with bad address in header\n");
fc9c7b4f 704 free(stattmp);
984263bc
MD
705#undef p
706#undef p1a
707}
708
709static char *icmpnames[] = {
710 "echo reply",
711 "#1",
712 "#2",
713 "destination unreachable",
714 "source quench",
715 "routing redirect",
716 "#6",
717 "#7",
718 "echo",
719 "router advertisement",
720 "router solicitation",
721 "time exceeded",
722 "parameter problem",
723 "time stamp",
724 "time stamp reply",
725 "information request",
726 "information request reply",
727 "address mask request",
728 "address mask reply",
729};
730
731/*
732 * Dump ICMP statistics.
733 */
734void
735icmp_stats(u_long off __unused, char *name, int af __unused)
736{
737 struct icmpstat icmpstat, zerostat;
738 int i, first;
739 int mib[4]; /* CTL_NET + PF_INET + IPPROTO_ICMP + req */
740 size_t len;
741
742 mib[0] = CTL_NET;
743 mib[1] = PF_INET;
744 mib[2] = IPPROTO_ICMP;
745 mib[3] = ICMPCTL_STATS;
746
747 len = sizeof icmpstat;
748 if (zflag)
749 memset(&zerostat, 0, len);
750 if (sysctl(mib, 4, &icmpstat, &len,
751 zflag ? &zerostat : NULL, zflag ? len : 0) < 0) {
752 warn("sysctl: net.inet.icmp.stats");
753 return;
754 }
755
756 printf("%s:\n", name);
757
758#define p(f, m) if (icmpstat.f || sflag <= 1) \
759 printf(m, icmpstat.f, plural(icmpstat.f))
760#define p1a(f, m) if (icmpstat.f || sflag <= 1) \
761 printf(m, icmpstat.f)
762#define p2(f, m) if (icmpstat.f || sflag <= 1) \
763 printf(m, icmpstat.f, plurales(icmpstat.f))
764
765 p(icps_error, "\t%lu call%s to icmp_error\n");
766 p(icps_oldicmp,
767 "\t%lu error%s not generated 'cuz old message was icmp\n");
768 for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++)
769 if (icmpstat.icps_outhist[i] != 0) {
770 if (first) {
771 printf("\tOutput histogram:\n");
772 first = 0;
773 }
774 printf("\t\t%s: %lu\n", icmpnames[i],
775 icmpstat.icps_outhist[i]);
776 }
777 p(icps_badcode, "\t%lu message%s with bad code fields\n");
778 p(icps_tooshort, "\t%lu message%s < minimum length\n");
779 p(icps_checksum, "\t%lu bad checksum%s\n");
780 p(icps_badlen, "\t%lu message%s with bad length\n");
781 p1a(icps_bmcastecho, "\t%lu multicast echo requests ignored\n");
782 p1a(icps_bmcasttstamp, "\t%lu multicast timestamp requests ignored\n");
783 for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++)
784 if (icmpstat.icps_inhist[i] != 0) {
785 if (first) {
786 printf("\tInput histogram:\n");
787 first = 0;
788 }
789 printf("\t\t%s: %lu\n", icmpnames[i],
790 icmpstat.icps_inhist[i]);
791 }
792 p(icps_reflect, "\t%lu message response%s generated\n");
793 p2(icps_badaddr, "\t%lu invalid return address%s\n");
58b6d24a 794 p(icps_noroute, "\t%lu no return route%s\n");
984263bc
MD
795#undef p
796#undef p1a
797#undef p2
798 mib[3] = ICMPCTL_MASKREPL;
799 len = sizeof i;
800 if (sysctl(mib, 4, &i, &len, (void *)0, 0) < 0)
801 return;
802 printf("\tICMP address mask responses are %sabled\n",
803 i ? "en" : "dis");
804}
805
806/*
807 * Dump IGMP statistics structure.
808 */
809void
810igmp_stats(u_long off __unused, char *name, int af __unused)
811{
812 struct igmpstat igmpstat, zerostat;
813 size_t len = sizeof igmpstat;
814
815 if (zflag)
816 memset(&zerostat, 0, len);
817 if (sysctlbyname("net.inet.igmp.stats", &igmpstat, &len,
818 zflag ? &zerostat : NULL, zflag ? len : 0) < 0) {
819 warn("sysctl: net.inet.igmp.stats");
820 return;
821 }
822
823 printf("%s:\n", name);
824
825#define p(f, m) if (igmpstat.f || sflag <= 1) \
826 printf(m, igmpstat.f, plural(igmpstat.f))
827#define py(f, m) if (igmpstat.f || sflag <= 1) \
828 printf(m, igmpstat.f, igmpstat.f != 1 ? "ies" : "y")
829 p(igps_rcv_total, "\t%u message%s received\n");
830 p(igps_rcv_tooshort, "\t%u message%s received with too few bytes\n");
831 p(igps_rcv_badsum, "\t%u message%s received with bad checksum\n");
832 py(igps_rcv_queries, "\t%u membership quer%s received\n");
833 py(igps_rcv_badqueries, "\t%u membership quer%s received with invalid field(s)\n");
834 p(igps_rcv_reports, "\t%u membership report%s received\n");
835 p(igps_rcv_badreports, "\t%u membership report%s received with invalid field(s)\n");
836 p(igps_rcv_ourreports, "\t%u membership report%s received for groups to which we belong\n");
837 p(igps_snd_reports, "\t%u membership report%s sent\n");
838#undef p
839#undef py
840}
841
842/*
ef73cf6c
JH
843 * Dump PIM statistics structure.
844 */
845void
846pim_stats(u_long off __unused, char *name, int af1 __unused)
847{
848 struct pimstat pimstat, zerostat;
849 size_t len = sizeof pimstat;
850
851 if (zflag)
852 memset(&zerostat, 0, len);
8aa3893e
HP
853 if (sysctlbyname("net.inet.pim.stats", &pimstat, &len,
854 zflag ? &zerostat : NULL, zflag ? len : 0) < 0) {
855 if (errno != ENOENT)
04652ffc 856 warn("sysctl: net.inet.pim.stats");
8aa3893e 857 return;
ef73cf6c
JH
858 }
859
860 printf("%s:\n", name);
861
862#define p(f, m) if (pimstat.f || sflag <= 1) \
863 printf(m, pimstat.f, plural(pimstat.f))
864#define py(f, m) if (pimstat.f || sflag <= 1) \
865 printf(m, pimstat.f, pimstat.f != 1 ? "ies" : "y")
866 p(pims_rcv_total_msgs, "\t%llu message%s received\n");
867 p(pims_rcv_total_bytes, "\t%llu byte%s received\n");
868 p(pims_rcv_tooshort, "\t%llu message%s received with too few bytes\n");
869 p(pims_rcv_badsum, "\t%llu message%s received with bad checksum\n");
870 p(pims_rcv_badversion, "\t%llu message%s received with bad version\n");
871 p(pims_rcv_registers_msgs, "\t%llu data register message%s received\n");
872 p(pims_rcv_registers_bytes, "\t%llu data register byte%s received\n");
873 p(pims_rcv_registers_wrongiif, "\t%llu data register message%s received on wrong iif\n");
874 p(pims_rcv_badregisters, "\t%llu bad register%s received\n");
875 p(pims_snd_registers_msgs, "\t%llu data register message%s sent\n");
876 p(pims_snd_registers_bytes, "\t%llu data register byte%s sent\n");
877#undef p
878#undef py
879}
880
881/*
984263bc
MD
882 * Pretty print an Internet address (net address + port).
883 */
884void
d2e9e54c 885inetprint(struct in_addr *in, int port, const char *proto, int numeric_port)
984263bc
MD
886{
887 struct servent *sp = 0;
888 char line[80], *cp;
889 int width;
890
891 if (Wflag)
892 sprintf(line, "%s.", inetname(in));
893 else
894 sprintf(line, "%.*s.", (Aflag && !numeric_port) ? 12 : 16, inetname(in));
43b4d1bd 895 cp = strchr(line, '\0');
984263bc
MD
896 if (!numeric_port && port)
897 sp = getservbyport((int)port, proto);
898 if (sp || port == 0)
899 sprintf(cp, "%.15s ", sp ? sp->s_name : "*");
900 else
901 sprintf(cp, "%d ", ntohs((u_short)port));
d2e9e54c 902 width = (Aflag && !Wflag) ? 17 : 21;
984263bc
MD
903 if (Wflag)
904 printf("%-*s ", width, line);
905 else
906 printf("%-*.*s ", width, width, line);
907}
908
909/*
910 * Construct an Internet address representation.
911 * If numeric_addr has been supplied, give
912 * numeric value, otherwise try for symbolic name.
913 */
914char *
915inetname(struct in_addr *inp)
916{
6bd457ed 917 char *cp;
984263bc
MD
918 static char line[MAXHOSTNAMELEN];
919 struct hostent *hp;
920 struct netent *np;
921
922 cp = 0;
923 if (!numeric_addr && inp->s_addr != INADDR_ANY) {
924 int net = inet_netof(*inp);
925 int lna = inet_lnaof(*inp);
926
927 if (lna == INADDR_ANY) {
928 np = getnetbyaddr(net, AF_INET);
929 if (np)
930 cp = np->n_name;
931 }
932 if (cp == 0) {
15b85273 933 hp = gethostbyaddr(inp, sizeof (*inp), AF_INET);
984263bc
MD
934 if (hp) {
935 cp = hp->h_name;
936 trimdomain(cp, strlen(cp));
937 }
938 }
939 }
940 if (inp->s_addr == INADDR_ANY)
941 strcpy(line, "*");
942 else if (cp) {
943 strncpy(line, cp, sizeof(line) - 1);
944 line[sizeof(line) - 1] = '\0';
945 } else {
946 inp->s_addr = ntohl(inp->s_addr);
947#define C(x) ((u_int)((x) & 0xff))
948 sprintf(line, "%u.%u.%u.%u", C(inp->s_addr >> 24),
949 C(inp->s_addr >> 16), C(inp->s_addr >> 8), C(inp->s_addr));
950 }
951 return (line);
952}