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