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