Annotation of src/usr.bin/netstat/inet6.c, Revision 1.50
1.50 ! jca 1: /* $OpenBSD: inet6.c,v 1.49 2015/09/11 19:35:37 mpi Exp $ */
1.1 itojun 2: /* BSDI inet.c,v 2.3 1995/10/24 02:19:29 prb Exp */
3: /*
4: * Copyright (c) 1983, 1988, 1993
5: * The Regents of the University of California. All rights reserved.
6: *
7: * Redistribution and use in source and binary forms, with or without
8: * modification, are permitted provided that the following conditions
9: * are met:
10: * 1. Redistributions of source code must retain the above copyright
11: * notice, this list of conditions and the following disclaimer.
12: * 2. Redistributions in binary form must reproduce the above copyright
13: * notice, this list of conditions and the following disclaimer in the
14: * documentation and/or other materials provided with the distribution.
1.29 millert 15: * 3. Neither the name of the University nor the names of its contributors
1.1 itojun 16: * may be used to endorse or promote products derived from this software
17: * without specific prior written permission.
18: *
19: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29: * SUCH DAMAGE.
30: */
31:
1.47 deraadt 32: #include <sys/types.h>
1.1 itojun 33: #include <sys/socket.h>
34: #include <sys/socketvar.h>
35: #include <sys/ioctl.h>
36: #include <sys/protosw.h>
1.35 deraadt 37: #include <sys/sysctl.h>
1.1 itojun 38:
39: #include <net/route.h>
40: #include <net/if.h>
41: #include <netinet/in.h>
42: #include <netinet/ip6.h>
43: #include <netinet/icmp6.h>
44: #include <netinet/ip.h>
45: #include <netinet/ip_var.h>
1.5 itojun 46: #include <netinet6/ip6_var.h>
1.1 itojun 47: #include <netinet6/in6_var.h>
48: #include <netinet6/pim6_var.h>
1.21 itojun 49: #include <netinet6/raw_ip6.h>
1.40 michele 50: #include <netinet6/ip6_divert.h>
1.1 itojun 51:
52: #include <arpa/inet.h>
53: #include <netdb.h>
54:
1.37 chl 55: #include <err.h>
56: #include <errno.h>
1.1 itojun 57: #include <stdio.h>
58: #include <string.h>
59: #include <unistd.h>
1.47 deraadt 60: #include <limits.h>
1.1 itojun 61: #include "netstat.h"
62:
63: struct socket sockb;
64:
1.18 millert 65: char *inet6name(struct in6_addr *);
1.1 itojun 66:
67: static char *ip6nh[] = {
68: "hop by hop",
69: "ICMP",
70: "IGMP",
71: "#3",
72: "IP",
73: "#5",
74: "TCP",
75: "#7",
76: "#8",
77: "#9",
78: "#10",
79: "#11",
80: "#12",
81: "#13",
82: "#14",
83: "#15",
84: "#16",
85: "UDP",
86: "#18",
1.17 mickey 87: "#19",
1.1 itojun 88: "#20",
89: "#21",
90: "IDP",
91: "#23",
92: "#24",
93: "#25",
94: "#26",
95: "#27",
96: "#28",
1.17 mickey 97: "TP",
1.1 itojun 98: "#30",
99: "#31",
100: "#32",
101: "#33",
102: "#34",
103: "#35",
104: "#36",
105: "#37",
106: "#38",
1.17 mickey 107: "#39",
1.1 itojun 108: "#40",
109: "IP6",
110: "#42",
111: "routing",
112: "fragment",
113: "#45",
114: "#46",
115: "#47",
116: "#48",
1.17 mickey 117: "#49",
1.1 itojun 118: "ESP",
119: "AH",
120: "#52",
121: "#53",
122: "#54",
123: "#55",
124: "#56",
125: "#57",
126: "ICMP6",
1.17 mickey 127: "no next header",
1.1 itojun 128: "destination option",
129: "#61",
130: "#62",
131: "#63",
132: "#64",
133: "#65",
134: "#66",
135: "#67",
136: "#68",
1.17 mickey 137: "#69",
1.1 itojun 138: "#70",
139: "#71",
140: "#72",
141: "#73",
142: "#74",
143: "#75",
144: "#76",
145: "#77",
146: "#78",
1.17 mickey 147: "#79",
1.1 itojun 148: "ISOIP",
149: "#81",
150: "#82",
151: "#83",
152: "#84",
153: "#85",
154: "#86",
155: "#87",
156: "#88",
1.17 mickey 157: "OSPF",
1.1 itojun 158: "#80",
159: "#91",
160: "#92",
161: "#93",
162: "#94",
163: "#95",
164: "#96",
165: "Ethernet",
166: "#98",
1.17 mickey 167: "#99",
1.1 itojun 168: "#100",
169: "#101",
170: "#102",
171: "PIM",
172: "#104",
173: "#105",
174: "#106",
175: "#107",
176: "#108",
1.17 mickey 177: "#109",
1.1 itojun 178: "#110",
179: "#111",
180: "#112",
181: "#113",
182: "#114",
183: "#115",
184: "#116",
185: "#117",
186: "#118",
1.17 mickey 187: "#119",
1.1 itojun 188: "#120",
189: "#121",
190: "#122",
191: "#123",
192: "#124",
193: "#125",
194: "#126",
195: "#127",
196: "#128",
1.17 mickey 197: "#129",
1.1 itojun 198: "#130",
199: "#131",
200: "#132",
201: "#133",
202: "#134",
203: "#135",
204: "#136",
205: "#137",
206: "#138",
1.17 mickey 207: "#139",
1.1 itojun 208: "#140",
209: "#141",
210: "#142",
211: "#143",
212: "#144",
213: "#145",
214: "#146",
215: "#147",
216: "#148",
1.17 mickey 217: "#149",
1.1 itojun 218: "#150",
219: "#151",
220: "#152",
221: "#153",
222: "#154",
223: "#155",
224: "#156",
225: "#157",
226: "#158",
1.17 mickey 227: "#159",
1.1 itojun 228: "#160",
229: "#161",
230: "#162",
231: "#163",
232: "#164",
233: "#165",
234: "#166",
235: "#167",
236: "#168",
1.17 mickey 237: "#169",
1.1 itojun 238: "#170",
239: "#171",
240: "#172",
241: "#173",
242: "#174",
243: "#175",
244: "#176",
245: "#177",
246: "#178",
1.17 mickey 247: "#179",
1.1 itojun 248: "#180",
249: "#181",
250: "#182",
251: "#183",
252: "#184",
253: "#185",
254: "#186",
255: "#187",
256: "#188",
1.17 mickey 257: "#189",
1.1 itojun 258: "#180",
259: "#191",
260: "#192",
261: "#193",
262: "#194",
263: "#195",
264: "#196",
265: "#197",
266: "#198",
1.17 mickey 267: "#199",
1.1 itojun 268: "#200",
269: "#201",
270: "#202",
271: "#203",
272: "#204",
273: "#205",
274: "#206",
275: "#207",
276: "#208",
1.17 mickey 277: "#209",
1.1 itojun 278: "#210",
279: "#211",
280: "#212",
281: "#213",
282: "#214",
283: "#215",
284: "#216",
285: "#217",
286: "#218",
1.17 mickey 287: "#219",
1.1 itojun 288: "#220",
289: "#221",
290: "#222",
291: "#223",
292: "#224",
293: "#225",
294: "#226",
295: "#227",
296: "#228",
1.17 mickey 297: "#229",
1.1 itojun 298: "#230",
299: "#231",
300: "#232",
301: "#233",
302: "#234",
303: "#235",
304: "#236",
305: "#237",
306: "#238",
1.17 mickey 307: "#239",
1.1 itojun 308: "#240",
309: "#241",
310: "#242",
311: "#243",
312: "#244",
313: "#245",
314: "#246",
315: "#247",
316: "#248",
1.17 mickey 317: "#249",
1.1 itojun 318: "#250",
319: "#251",
320: "#252",
321: "#253",
322: "#254",
323: "#255",
324: };
325:
326: /*
327: * Dump IP6 statistics structure.
328: */
329: void
1.35 deraadt 330: ip6_stats(char *name)
1.1 itojun 331: {
332: struct ip6stat ip6stat;
333: int first, i;
1.14 itojun 334: struct protoent *ep;
335: const char *n;
1.45 guenther 336: int mib[] = { CTL_NET, PF_INET6, IPPROTO_IPV6, IPV6CTL_STATS };
1.35 deraadt 337: size_t len = sizeof(ip6stat);
1.1 itojun 338:
1.35 deraadt 339: if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
340: &ip6stat, &len, NULL, 0) == -1) {
341: if (errno != ENOPROTOOPT)
1.44 guenther 342: warn("%s", name);
1.1 itojun 343: return;
1.35 deraadt 344: }
1.1 itojun 345:
346: printf("%s:\n", name);
347: #define p(f, m) if (ip6stat.f || sflag <= 1) \
1.20 deraadt 348: printf(m, (unsigned long long)ip6stat.f, plural(ip6stat.f))
1.1 itojun 349: #define p1(f, m) if (ip6stat.f || sflag <= 1) \
1.20 deraadt 350: printf(m, (unsigned long long)ip6stat.f)
1.1 itojun 351:
1.14 itojun 352: p(ip6s_total, "\t%llu total packet%s received\n");
353: p1(ip6s_toosmall, "\t%llu with size smaller than minimum\n");
354: p1(ip6s_tooshort, "\t%llu with data size < data length\n");
355: p1(ip6s_badoptions, "\t%llu with bad options\n");
356: p1(ip6s_badvers, "\t%llu with incorrect version number\n");
357: p(ip6s_fragments, "\t%llu fragment%s received\n");
358: p(ip6s_fragdropped,
1.23 jsyn 359: "\t%llu fragment%s dropped (duplicates or out of space)\n");
1.14 itojun 360: p(ip6s_fragtimeout, "\t%llu fragment%s dropped after timeout\n");
361: p(ip6s_fragoverflow, "\t%llu fragment%s that exceeded limit\n");
362: p(ip6s_reassembled, "\t%llu packet%s reassembled ok\n");
363: p(ip6s_delivered, "\t%llu packet%s for this host\n");
364: p(ip6s_forward, "\t%llu packet%s forwarded\n");
365: p(ip6s_cantforward, "\t%llu packet%s not forwardable\n");
366: p(ip6s_redirectsent, "\t%llu redirect%s sent\n");
367: p(ip6s_localout, "\t%llu packet%s sent from this host\n");
368: p(ip6s_rawout, "\t%llu packet%s sent with fabricated ip header\n");
369: p(ip6s_odropped,
370: "\t%llu output packet%s dropped due to no bufs, etc.\n");
371: p(ip6s_noroute, "\t%llu output packet%s discarded due to no route\n");
372: p(ip6s_fragmented, "\t%llu output datagram%s fragmented\n");
373: p(ip6s_ofragments, "\t%llu fragment%s created\n");
374: p(ip6s_cantfrag, "\t%llu datagram%s that can't be fragmented\n");
375: p(ip6s_badscope, "\t%llu packet%s that violated scope rules\n");
376: p(ip6s_notmember, "\t%llu multicast packet%s which we don't join\n");
1.39 tedu 377: for (first = 1, i = 0; i < 256; i++)
1.1 itojun 378: if (ip6stat.ip6s_nxthist[i] != 0) {
1.39 tedu 379: if (first) {
380: printf("\tInput packet histogram:\n");
381: first = 0;
382: }
1.14 itojun 383: n = NULL;
384: if (ip6nh[i])
385: n = ip6nh[i];
386: else if ((ep = getprotobynumber(i)) != NULL)
387: n = ep->p_name;
388: if (n)
1.39 tedu 389: printf("\t\t%s: %llu\n", n,
390: (unsigned long long)ip6stat.ip6s_nxthist[i]);
1.14 itojun 391: else
1.39 tedu 392: printf("\t\t#%d: %llu\n", i,
393: (unsigned long long)ip6stat.ip6s_nxthist[i]);
1.1 itojun 394: }
1.10 itojun 395: printf("\tMbuf statistics:\n");
1.14 itojun 396: p(ip6s_m1, "\t\t%llu one mbuf%s\n");
1.1 itojun 397: for (first = 1, i = 0; i < 32; i++) {
398: char ifbuf[IFNAMSIZ];
1.17 mickey 399: if (ip6stat.ip6s_m2m[i] != 0) {
1.1 itojun 400: if (first) {
1.39 tedu 401: printf("\t\ttwo or more mbuf:\n");
1.1 itojun 402: first = 0;
403: }
1.14 itojun 404: printf("\t\t\t%s = %llu\n",
1.20 deraadt 405: if_indextoname(i, ifbuf),
406: (unsigned long long)ip6stat.ip6s_m2m[i]);
1.1 itojun 407: }
408: }
1.14 itojun 409: p(ip6s_mext1, "\t\t%llu one ext mbuf%s\n");
410: p(ip6s_mext2m, "\t\t%llu two or more ext mbuf%s\n");
411: p(ip6s_nogif, "\t%llu tunneling packet%s that can't find gif\n");
412: p(ip6s_toomanyhdr,
413: "\t%llu packet%s discarded due to too many headers\n");
1.5 itojun 414:
415: /* for debugging source address selection */
416: #define PRINT_SCOPESTAT(s,i) do {\
417: switch(i) { /* XXX hardcoding in each case */\
418: case 1:\
1.14 itojun 419: p(s, "\t\t%llu node-local%s\n");\
1.5 itojun 420: break;\
421: case 2:\
1.14 itojun 422: p(s, "\t\t%llu link-local%s\n");\
1.5 itojun 423: break;\
424: case 5:\
1.14 itojun 425: p(s, "\t\t%llu site-local%s\n");\
1.5 itojun 426: break;\
427: case 14:\
1.14 itojun 428: p(s, "\t\t%llu global%s\n");\
1.5 itojun 429: break;\
430: default:\
1.14 itojun 431: printf("\t\t%llu addresses scope=%x\n",\
1.20 deraadt 432: (unsigned long long)ip6stat.s, i);\
1.5 itojun 433: }\
434: } while(0);
435:
436: p(ip6s_sources_none,
1.20 deraadt 437: "\t%llu failure%s of source address selection\n");
1.5 itojun 438: for (first = 1, i = 0; i < 16; i++) {
439: if (ip6stat.ip6s_sources_sameif[i]) {
440: if (first) {
441: printf("\tsource addresses on an outgoing I/F\n");
442: first = 0;
443: }
444: PRINT_SCOPESTAT(ip6s_sources_sameif[i], i);
445: }
446: }
447: for (first = 1, i = 0; i < 16; i++) {
448: if (ip6stat.ip6s_sources_otherif[i]) {
449: if (first) {
450: printf("\tsource addresses on a non-outgoing I/F\n");
451: first = 0;
452: }
453: PRINT_SCOPESTAT(ip6s_sources_otherif[i], i);
454: }
455: }
456: for (first = 1, i = 0; i < 16; i++) {
457: if (ip6stat.ip6s_sources_samescope[i]) {
458: if (first) {
459: printf("\tsource addresses of same scope\n");
460: first = 0;
461: }
462: PRINT_SCOPESTAT(ip6s_sources_samescope[i], i);
463: }
464: }
465: for (first = 1, i = 0; i < 16; i++) {
466: if (ip6stat.ip6s_sources_otherscope[i]) {
467: if (first) {
468: printf("\tsource addresses of a different scope\n");
469: first = 0;
470: }
471: PRINT_SCOPESTAT(ip6s_sources_otherscope[i], i);
472: }
473: }
474: for (first = 1, i = 0; i < 16; i++) {
475: if (ip6stat.ip6s_sources_deprecated[i]) {
476: if (first) {
477: printf("\tdeprecated source addresses\n");
478: first = 0;
479: }
480: PRINT_SCOPESTAT(ip6s_sources_deprecated[i], i);
481: }
482: }
1.8 itojun 483:
484: p1(ip6s_forward_cachehit, "\t%llu forward cache hit\n");
485: p1(ip6s_forward_cachemiss, "\t%llu forward cache miss\n");
1.1 itojun 486: #undef p
487: #undef p1
488: }
489:
490: static char *icmp6names[] = {
491: "#0",
492: "unreach",
493: "packet too big",
494: "time exceed",
495: "parameter problem",
496: "#5",
497: "#6",
498: "#7",
499: "#8",
500: "#9",
501: "#10",
502: "#11",
503: "#12",
504: "#13",
505: "#14",
506: "#15",
507: "#16",
508: "#17",
509: "#18",
1.17 mickey 510: "#19",
1.1 itojun 511: "#20",
512: "#21",
513: "#22",
514: "#23",
515: "#24",
516: "#25",
517: "#26",
518: "#27",
519: "#28",
1.17 mickey 520: "#29",
1.1 itojun 521: "#30",
522: "#31",
523: "#32",
524: "#33",
525: "#34",
526: "#35",
527: "#36",
528: "#37",
529: "#38",
1.17 mickey 530: "#39",
1.1 itojun 531: "#40",
532: "#41",
533: "#42",
534: "#43",
535: "#44",
536: "#45",
537: "#46",
538: "#47",
539: "#48",
1.17 mickey 540: "#49",
1.1 itojun 541: "#50",
542: "#51",
543: "#52",
544: "#53",
545: "#54",
546: "#55",
547: "#56",
548: "#57",
549: "#58",
1.17 mickey 550: "#59",
1.1 itojun 551: "#60",
552: "#61",
553: "#62",
554: "#63",
555: "#64",
556: "#65",
557: "#66",
558: "#67",
559: "#68",
1.17 mickey 560: "#69",
1.1 itojun 561: "#70",
562: "#71",
563: "#72",
564: "#73",
565: "#74",
566: "#75",
567: "#76",
568: "#77",
569: "#78",
1.17 mickey 570: "#79",
1.1 itojun 571: "#80",
572: "#81",
573: "#82",
574: "#83",
575: "#84",
576: "#85",
577: "#86",
578: "#87",
579: "#88",
1.17 mickey 580: "#89",
1.1 itojun 581: "#80",
582: "#91",
583: "#92",
584: "#93",
585: "#94",
586: "#95",
587: "#96",
588: "#97",
589: "#98",
1.17 mickey 590: "#99",
1.1 itojun 591: "#100",
592: "#101",
593: "#102",
594: "#103",
595: "#104",
596: "#105",
597: "#106",
598: "#107",
599: "#108",
1.17 mickey 600: "#109",
1.1 itojun 601: "#110",
602: "#111",
603: "#112",
604: "#113",
605: "#114",
606: "#115",
607: "#116",
608: "#117",
609: "#118",
1.17 mickey 610: "#119",
1.1 itojun 611: "#120",
612: "#121",
613: "#122",
614: "#123",
615: "#124",
616: "#125",
617: "#126",
618: "#127",
619: "echo",
1.17 mickey 620: "echo reply",
1.1 itojun 621: "multicast listener query",
622: "multicast listener report",
623: "multicast listener done",
624: "router solicitation",
1.15 itojun 625: "router advertisement",
1.1 itojun 626: "neighbor solicitation",
1.15 itojun 627: "neighbor advertisement",
1.1 itojun 628: "redirect",
629: "router renumbering",
630: "node information request",
631: "node information reply",
632: "#141",
633: "#142",
634: "#143",
635: "#144",
636: "#145",
637: "#146",
638: "#147",
639: "#148",
1.17 mickey 640: "#149",
1.1 itojun 641: "#150",
642: "#151",
643: "#152",
644: "#153",
645: "#154",
646: "#155",
647: "#156",
648: "#157",
649: "#158",
1.17 mickey 650: "#159",
1.1 itojun 651: "#160",
652: "#161",
653: "#162",
654: "#163",
655: "#164",
656: "#165",
657: "#166",
658: "#167",
659: "#168",
1.17 mickey 660: "#169",
1.1 itojun 661: "#170",
662: "#171",
663: "#172",
664: "#173",
665: "#174",
666: "#175",
667: "#176",
668: "#177",
669: "#178",
1.17 mickey 670: "#179",
1.1 itojun 671: "#180",
672: "#181",
673: "#182",
674: "#183",
675: "#184",
676: "#185",
677: "#186",
678: "#187",
679: "#188",
1.17 mickey 680: "#189",
1.1 itojun 681: "#180",
682: "#191",
683: "#192",
684: "#193",
685: "#194",
686: "#195",
687: "#196",
688: "#197",
689: "#198",
1.17 mickey 690: "#199",
1.1 itojun 691: "#200",
692: "#201",
693: "#202",
694: "#203",
695: "#204",
696: "#205",
697: "#206",
698: "#207",
699: "#208",
1.17 mickey 700: "#209",
1.1 itojun 701: "#210",
702: "#211",
703: "#212",
704: "#213",
705: "#214",
706: "#215",
707: "#216",
708: "#217",
709: "#218",
1.17 mickey 710: "#219",
1.1 itojun 711: "#220",
712: "#221",
713: "#222",
714: "#223",
715: "#224",
716: "#225",
717: "#226",
718: "#227",
719: "#228",
1.17 mickey 720: "#229",
1.1 itojun 721: "#230",
722: "#231",
723: "#232",
724: "#233",
725: "#234",
726: "#235",
727: "#236",
728: "#237",
729: "#238",
1.17 mickey 730: "#239",
1.1 itojun 731: "#240",
732: "#241",
733: "#242",
734: "#243",
735: "#244",
736: "#245",
737: "#246",
738: "#247",
739: "#248",
1.17 mickey 740: "#249",
1.1 itojun 741: "#250",
742: "#251",
743: "#252",
744: "#253",
745: "#254",
746: "#255",
747: };
748:
749: /*
750: * Dump ICMPv6 statistics.
751: */
752: void
1.35 deraadt 753: icmp6_stats(char *name)
1.1 itojun 754: {
755: struct icmp6stat icmp6stat;
1.39 tedu 756: int i, first;
1.45 guenther 757: int mib[] = { CTL_NET, PF_INET6, IPPROTO_ICMPV6, ICMPV6CTL_STATS };
1.35 deraadt 758: size_t len = sizeof(icmp6stat);
1.1 itojun 759:
1.35 deraadt 760: if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
761: &icmp6stat, &len, NULL, 0) == -1) {
762: if (errno != ENOPROTOOPT)
1.44 guenther 763: warn("%s", name);
1.1 itojun 764: return;
1.35 deraadt 765: }
766:
1.1 itojun 767: printf("%s:\n", name);
768: #define p(f, m) if (icmp6stat.f || sflag <= 1) \
1.20 deraadt 769: printf(m, (unsigned long long)icmp6stat.f, plural(icmp6stat.f))
1.8 itojun 770: #define p_5(f, m) if (icmp6stat.f || sflag <= 1) \
1.20 deraadt 771: printf(m, (unsigned long long)icmp6stat.f)
1.1 itojun 772:
1.14 itojun 773: p(icp6s_error, "\t%llu call%s to icmp6_error\n");
1.1 itojun 774: p(icp6s_canterror,
1.14 itojun 775: "\t%llu error%s not generated because old message was icmp6 or so\n");
1.7 itojun 776: p(icp6s_toofreq,
1.14 itojun 777: "\t%llu error%s not generated because of rate limitation\n");
1.39 tedu 778: for (first = 1, i = 0; i < 256; i++)
1.1 itojun 779: if (icmp6stat.icp6s_outhist[i] != 0) {
1.39 tedu 780: if (first) {
781: printf("\tOutput packet histogram:\n");
782: first = 0;
783: }
1.14 itojun 784: printf("\t\t%s: %llu\n", icmp6names[i],
1.25 deraadt 785: (unsigned long long)icmp6stat.icp6s_outhist[i]);
1.1 itojun 786: }
1.14 itojun 787: p(icp6s_badcode, "\t%llu message%s with bad code fields\n");
788: p(icp6s_tooshort, "\t%llu message%s < minimum length\n");
789: p(icp6s_checksum, "\t%llu bad checksum%s\n");
790: p(icp6s_badlen, "\t%llu message%s with bad length\n");
1.39 tedu 791: for (first = 1, i = 0; i < ICMP6_MAXTYPE; i++)
1.1 itojun 792: if (icmp6stat.icp6s_inhist[i] != 0) {
1.39 tedu 793: if (first) {
794: printf("\tInput packet histogram:\n");
795: first = 0;
796: }
1.14 itojun 797: printf("\t\t%s: %llu\n", icmp6names[i],
1.25 deraadt 798: (unsigned long long)icmp6stat.icp6s_inhist[i]);
1.1 itojun 799: }
1.39 tedu 800: printf("\tHistogram of error messages to be generated:\n");
1.14 itojun 801: p_5(icp6s_odst_unreach_noroute, "\t\t%llu no route\n");
802: p_5(icp6s_odst_unreach_admin, "\t\t%llu administratively prohibited\n");
803: p_5(icp6s_odst_unreach_beyondscope, "\t\t%llu beyond scope\n");
804: p_5(icp6s_odst_unreach_addr, "\t\t%llu address unreachable\n");
805: p_5(icp6s_odst_unreach_noport, "\t\t%llu port unreachable\n");
806: p_5(icp6s_opacket_too_big, "\t\t%llu packet too big\n");
807: p_5(icp6s_otime_exceed_transit, "\t\t%llu time exceed transit\n");
808: p_5(icp6s_otime_exceed_reassembly, "\t\t%llu time exceed reassembly\n");
809: p_5(icp6s_oparamprob_header, "\t\t%llu erroneous header field\n");
810: p_5(icp6s_oparamprob_nextheader, "\t\t%llu unrecognized next header\n");
811: p_5(icp6s_oparamprob_option, "\t\t%llu unrecognized option\n");
812: p_5(icp6s_oredirect, "\t\t%llu redirect\n");
813: p_5(icp6s_ounknown, "\t\t%llu unknown\n");
814:
815: p(icp6s_reflect, "\t%llu message response%s generated\n");
816: p(icp6s_nd_toomanyopt, "\t%llu message%s with too many ND options\n");
817: p(icp6s_nd_badopt, "\t%llu message%s with bad ND options\n");
818: p(icp6s_badns, "\t%llu bad neighbor solicitation message%s\n");
819: p(icp6s_badna, "\t%llu bad neighbor advertisement message%s\n");
820: p(icp6s_badrs, "\t%llu bad router solicitation message%s\n");
821: p(icp6s_badra, "\t%llu bad router advertisement message%s\n");
822: p(icp6s_badredirect, "\t%llu bad redirect message%s\n");
1.12 itojun 823: p(icp6s_pmtuchg, "\t%llu path MTU change%s\n");
1.14 itojun 824: #undef p
1.8 itojun 825: #undef p_5
1.1 itojun 826: }
827:
828: /*
829: * Dump PIM statistics structure.
830: */
831: void
1.35 deraadt 832: pim6_stats(char *name)
1.1 itojun 833: {
834: struct pim6stat pim6stat;
1.45 guenther 835: int mib[] = { CTL_NET, PF_INET6, IPPROTO_PIM, PIM6CTL_STATS };
1.35 deraadt 836: size_t len = sizeof(pim6stat);
1.1 itojun 837:
1.35 deraadt 838: if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
839: &pim6stat, &len, NULL, 0) == -1) {
840: if (errno != ENOPROTOOPT)
1.44 guenther 841: warn("%s", name);
1.1 itojun 842: return;
1.35 deraadt 843: }
844:
1.1 itojun 845: printf("%s:\n", name);
846: #define p(f, m) if (pim6stat.f || sflag <= 1) \
1.20 deraadt 847: printf(m, (unsigned long long)pim6stat.f, plural(pim6stat.f))
848:
1.14 itojun 849: p(pim6s_rcv_total, "\t%llu message%s received\n");
850: p(pim6s_rcv_tooshort, "\t%llu message%s received with too few bytes\n");
851: p(pim6s_rcv_badsum, "\t%llu message%s received with bad checksum\n");
852: p(pim6s_rcv_badversion, "\t%llu message%s received with bad version\n");
853: p(pim6s_rcv_registers, "\t%llu register%s received\n");
854: p(pim6s_rcv_badregisters, "\t%llu bad register%s received\n");
855: p(pim6s_snd_registers, "\t%llu register%s sent\n");
1.21 itojun 856: #undef p
857: }
858:
859: /*
860: * Dump raw ip6 statistics structure.
861: */
862: void
1.35 deraadt 863: rip6_stats(char *name)
1.21 itojun 864: {
865: struct rip6stat rip6stat;
1.34 henning 866: u_int64_t delivered;
1.45 guenther 867: int mib[] = { CTL_NET, PF_INET6, IPPROTO_RAW, RIPV6CTL_STATS };
1.35 deraadt 868: size_t len = sizeof(rip6stat);
1.21 itojun 869:
1.35 deraadt 870: if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
871: &rip6stat, &len, NULL, 0) == -1) {
872: if (errno != ENOPROTOOPT)
1.44 guenther 873: warn("%s", name);
1.21 itojun 874: return;
1.35 deraadt 875: }
876:
1.21 itojun 877: printf("%s:\n", name);
878:
879: #define p(f, m) if (rip6stat.f || sflag <= 1) \
880: printf(m, (unsigned long long)rip6stat.f, plural(rip6stat.f))
881: p(rip6s_ipackets, "\t%llu message%s received\n");
1.24 itojun 882: p(rip6s_isum, "\t%llu checksum calculation%s on inbound\n");
1.21 itojun 883: p(rip6s_badsum, "\t%llu message%s with bad checksum\n");
884: p(rip6s_nosock, "\t%llu message%s dropped due to no socket\n");
885: p(rip6s_nosockmcast,
886: "\t%llu multicast message%s dropped due to no socket\n");
887: p(rip6s_fullsock,
888: "\t%llu message%s dropped due to full socket buffers\n");
889: delivered = rip6stat.rip6s_ipackets -
890: rip6stat.rip6s_badsum -
891: rip6stat.rip6s_nosock -
892: rip6stat.rip6s_nosockmcast -
893: rip6stat.rip6s_fullsock;
894: if (delivered || sflag <= 1)
895: printf("\t%llu delivered\n", (unsigned long long)delivered);
896: p(rip6s_opackets, "\t%llu datagram%s output\n");
1.1 itojun 897: #undef p
1.40 michele 898: }
899:
900: /*
901: * Dump divert6 statistics structure.
902: */
903: void
904: div6_stats(char *name)
905: {
906: struct div6stat div6stat;
1.45 guenther 907: int mib[] = { CTL_NET, PF_INET6, IPPROTO_DIVERT, DIVERT6CTL_STATS };
1.40 michele 908: size_t len = sizeof(div6stat);
909:
910: if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
911: &div6stat, &len, NULL, 0) == -1) {
912: if (errno != ENOPROTOOPT)
1.44 guenther 913: warn("%s", name);
1.40 michele 914: return;
915: }
916:
917: printf("%s:\n", name);
918: #define p(f, m) if (div6stat.f || sflag <= 1) \
919: printf(m, div6stat.f, plural(div6stat.f))
920: #define p1(f, m) if (div6stat.f || sflag <= 1) \
921: printf(m, div6stat.f)
922: p(divs_ipackets, "\t%lu total packet%s received\n");
923: p1(divs_noport, "\t%lu dropped due to no socket\n");
924: p1(divs_fullsock, "\t%lu dropped due to full socket buffers\n");
925: p(divs_opackets, "\t%lu packet%s output\n");
926: p1(divs_errors, "\t%lu errors\n");
927: #undef p
928: #undef p1
1.1 itojun 929: }
930:
931: /*
932: * Pretty print an Internet address (net address + port).
933: * If the nflag was specified, use numbers instead of names.
934: */
935:
936: void
1.48 claudio 937: inet6print(struct in6_addr *in6, int port, const char *proto)
1.1 itojun 938: {
1.25 deraadt 939:
940: #define GETSERVBYPORT6(port, proto, ret) do { \
941: if (strcmp((proto), "tcp6") == 0) \
942: (ret) = getservbyport((int)(port), "tcp"); \
943: else if (strcmp((proto), "udp6") == 0) \
944: (ret) = getservbyport((int)(port), "udp"); \
945: else \
946: (ret) = getservbyport((int)(port), (proto)); \
947: } while (0)
948:
1.1 itojun 949: struct servent *sp = 0;
950: char line[80], *cp;
951: int width;
1.26 deraadt 952: int len = sizeof line;
1.1 itojun 953:
1.14 itojun 954: width = Aflag ? 12 : 16;
955: if (vflag && width < strlen(inet6name(in6)))
956: width = strlen(inet6name(in6));
1.26 deraadt 957: snprintf(line, len, "%.*s.", width, inet6name(in6));
958: len -= strlen(line);
959: if (len <= 0)
960: goto bail;
961:
1.27 sturm 962: cp = strchr(line, '\0');
1.1 itojun 963: if (!nflag && port)
964: GETSERVBYPORT6(port, proto, sp);
965: if (sp || port == 0)
1.26 deraadt 966: snprintf(cp, len, "%.8s", sp ? sp->s_name : "*");
1.1 itojun 967: else
1.26 deraadt 968: snprintf(cp, len, "%d", ntohs((u_short)port));
1.1 itojun 969: width = Aflag ? 18 : 22;
1.14 itojun 970: if (vflag && width < strlen(line))
971: width = strlen(line);
1.26 deraadt 972: bail:
1.1 itojun 973: printf(" %-*.*s", width, width, line);
974: }
975:
976: /*
977: * Construct an Internet address representation.
978: * If the nflag has been supplied, give
979: * numeric value, otherwise try for symbolic name.
980: */
981:
982: char *
1.25 deraadt 983: inet6name(struct in6_addr *in6p)
1.1 itojun 984: {
1.16 mpech 985: char *cp;
1.14 itojun 986: static char line[NI_MAXHOST];
1.1 itojun 987: struct hostent *hp;
1.47 deraadt 988: static char domain[HOST_NAME_MAX+1];
1.1 itojun 989: static int first = 1;
1.14 itojun 990: char hbuf[NI_MAXHOST];
1.1 itojun 991: struct sockaddr_in6 sin6;
992: const int niflag = NI_NUMERICHOST;
993:
994: if (first && !nflag) {
995: first = 0;
1.19 mpech 996: if (gethostname(domain, sizeof(domain)) == 0 &&
1.22 deraadt 997: (cp = strchr(domain, '.')))
1.20 deraadt 998: (void) strlcpy(domain, cp + 1, sizeof domain);
1.1 itojun 999: else
1.20 deraadt 1000: domain[0] = '\0';
1.1 itojun 1001: }
1002: cp = 0;
1003: if (!nflag && !IN6_IS_ADDR_UNSPECIFIED(in6p)) {
1004: hp = gethostbyaddr((char *)in6p, sizeof(*in6p), AF_INET6);
1005: if (hp) {
1.22 deraadt 1006: if ((cp = strchr(hp->h_name, '.')) &&
1.1 itojun 1007: !strcmp(cp + 1, domain))
1008: *cp = 0;
1009: cp = hp->h_name;
1010: }
1011: }
1012: if (IN6_IS_ADDR_UNSPECIFIED(in6p))
1.14 itojun 1013: strlcpy(line, "*", sizeof(line));
1.1 itojun 1014: else if (cp)
1.14 itojun 1015: strlcpy(line, cp, sizeof(line));
1.1 itojun 1016: else {
1017: memset(&sin6, 0, sizeof(sin6));
1018: sin6.sin6_len = sizeof(sin6);
1019: sin6.sin6_family = AF_INET6;
1020: sin6.sin6_addr = *in6p;
1.28 itojun 1021: #ifdef __KAME__
1.30 itojun 1022: if (IN6_IS_ADDR_LINKLOCAL(in6p) ||
1.33 itojun 1023: IN6_IS_ADDR_MC_LINKLOCAL(in6p) ||
1024: IN6_IS_ADDR_MC_INTFACELOCAL(in6p)) {
1.1 itojun 1025: sin6.sin6_scope_id =
1.20 deraadt 1026: ntohs(*(u_int16_t *)&in6p->s6_addr[2]);
1.1 itojun 1027: sin6.sin6_addr.s6_addr[2] = 0;
1028: sin6.sin6_addr.s6_addr[3] = 0;
1029: }
1030: #endif
1031: if (getnameinfo((struct sockaddr *)&sin6, sin6.sin6_len,
1.20 deraadt 1032: hbuf, sizeof(hbuf), NULL, 0, niflag) != 0)
1033: strlcpy(hbuf, "?", sizeof hbuf);
1.14 itojun 1034: strlcpy(line, hbuf, sizeof(line));
1.1 itojun 1035: }
1036: return (line);
1037: }