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