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