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