source: rtems-libbsd/freebsd-userspace/commands/usr.bin/netstat/inet6.c @ f1710b6

4.1155-freebsd-126-freebsd-12freebsd-9.3
Last change on this file since f1710b6 was f1710b6, checked in by Joel Sherrill <joel.sherrill@…>, on 09/07/12 at 17:50:18

netstat: New command - Almost completely compiles

Currently disable in Makefile until all builds. Adding it so
others can assist in debugging issues.

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