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