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