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