]> git.saurik.com Git - apple/network_cmds.git/blobdiff - netstat.tproj/inet6.c
network_cmds-543.tar.gz
[apple/network_cmds.git] / netstat.tproj / inet6.c
index 164cb51ce2f64a7a8bf0f7eb5f34d05b4812dc12..ae502787521959bcf53f7c437d47619d101f0e45 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008 Apple Inc. All rights reserved.
+ * Copyright (c) 2008-2015 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  *
  * $FreeBSD: src/usr.bin/netstat/inet6.c,v 1.3.2.9 2001/08/10 09:07:09 ru Exp $
  */
 
-#ifndef lint
-/*
-static char sccsid[] = "@(#)inet6.c    8.4 (Berkeley) 4/20/94";
-*/
-#endif /* not lint */
-
 #ifdef INET6
 #include <sys/param.h>
 #include <sys/socket.h>
@@ -78,6 +72,7 @@ static char sccsid[] = "@(#)inet6.c   8.4 (Berkeley) 4/20/94";
 #include <net/route.h>
 #include <net/if.h>
 #include <net/if_var.h>
+#include <net/net_perf.h>
 #include <netinet/in.h>
 #include <netinet/ip6.h>
 #include <netinet/icmp6.h>
@@ -85,7 +80,6 @@ static char sccsid[] = "@(#)inet6.c   8.4 (Berkeley) 4/20/94";
 #include <netinet6/in6_pcb.h>
 #include <netinet6/in6_var.h>
 #include <netinet6/ip6_var.h>
-#include <netinet6/pim6_var.h>
 #include <netinet6/raw_ip6.h>
 
 #include <arpa/inet.h>
@@ -166,7 +160,7 @@ static      char *ip6nh[] = {
        "no next header",       
        "destination option",
        "#61",
-       "#62",
+       "mobility",
        "#63",
        "#64",
        "#65",
@@ -362,6 +356,26 @@ static     char *ip6nh[] = {
        "#255",
 };
 
+
+static const char *srcrulenames[IP6S_SRCRULE_COUNT] = {
+       "default",                      // IP6S_SRCRULE_0
+       "prefer same address",          // IP6S_SRCRULE_1
+       "prefer appropriate scope",     // IP6S_SRCRULE_2
+       "avoid deprecated addresses",   // IP6S_SRCRULE_3
+       "prefer home addresses",        // IP6S_SRCRULE_4
+       "prefer outgoing interface",    // IP6S_SRCRULE_5
+       "prefer matching label",        // IP6S_SRCRULE_6
+       "prefer temporary addresses",   // IP6S_SRCRULE_7
+       "prefer addresses on alive interfaces", // IP6S_SRCRULE_7x
+       "use longest matching prefix",  // IP6S_SRCRULE_8
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL
+};
+
 /*
  * Dump IP6 statistics structure.
  */
@@ -373,6 +387,20 @@ ip6_stats(uint32_t off __unused, char *name, int af __unused)
        int first, i;
        int mib[4];
        size_t len;
+       static net_perf_t pout_net_perf, pin_net_perf;
+       net_perf_t out_net_perf, in_net_perf;
+       size_t out_net_perf_len = sizeof (out_net_perf);
+       size_t in_net_perf_len = sizeof (in_net_perf);
+
+       if (sysctlbyname("net.inet6.ip6.output_perf_data", &out_net_perf, &out_net_perf_len, 0, 0) < 0) {
+               perror("sysctl: net.inet6.ip6.output_perf_data");
+               return;
+       }
+
+       if (sysctlbyname("net.inet6.ip6.input_perf_data", &in_net_perf, &in_net_perf_len, 0, 0) < 0) {
+               perror("sysctl: net.inet6.ip6.input_perf_data");
+               return;
+       }
 
        mib[0] = CTL_NET;
        mib[1] = PF_INET6;
@@ -383,6 +411,8 @@ ip6_stats(uint32_t off __unused, char *name, int af __unused)
        memset(&ip6stat, 0, len);
        if (sysctl(mib, 4, &ip6stat, &len, (void *)0, 0) < 0)
                return;
+    if (interval && vflag > 0)
+        print_time();
        printf("%s:\n", name);
 
 #define        IP6DIFF(f) (ip6stat.f - pip6stat.f)
@@ -392,28 +422,94 @@ ip6_stats(uint32_t off __unused, char *name, int af __unused)
     printf(m, (unsigned long long)IP6DIFF(f))
 
        p(ip6s_total, "\t%llu total packet%s received\n");
-       p1a(ip6s_toosmall, "\t%llu with size smaller than minimum\n");
-       p1a(ip6s_tooshort, "\t%llu with data size < data length\n");
-       p1a(ip6s_badoptions, "\t%llu with bad options\n");
-       p1a(ip6s_badvers, "\t%llu with incorrect version number\n");
-       p(ip6s_fragments, "\t%llu fragment%s received\n");
-       p(ip6s_fragdropped, "\t%llu fragment%s dropped (dup or out of space)\n");
-       p(ip6s_fragtimeout, "\t%llu fragment%s dropped after timeout\n");
-       p(ip6s_fragoverflow, "\t%llu fragment%s that exceeded limit\n");
-       p(ip6s_reassembled, "\t%llu packet%s reassembled ok\n");
-       p(ip6s_delivered, "\t%llu packet%s for this host\n");
-       p(ip6s_forward, "\t%llu packet%s forwarded\n");
-       p(ip6s_cantforward, "\t%llu packet%s not forwardable\n");
-       p(ip6s_redirectsent, "\t%llu redirect%s sent\n");
+       p1a(ip6s_toosmall, "\t\t%llu with size smaller than minimum\n");
+       p1a(ip6s_tooshort, "\t\t%llu with data size < data length\n");
+       p1a(ip6s_adj, "\t\t%llu with data size > data length\n");
+       p(ip6s_adj_hwcsum_clr,
+           "\t\t\t%llu packet%s forced to software checksum\n");
+       p1a(ip6s_badoptions, "\t\t%llu with bad options\n");
+       p1a(ip6s_badvers, "\t\t%llu with incorrect version number\n");
+       p(ip6s_fragments, "\t\t%llu fragment%s received\n");
+       p1a(ip6s_fragdropped,
+           "\t\t\t%llu dropped (dup or out of space)\n");
+       p1a(ip6s_fragtimeout, "\t\t\t%llu dropped after timeout\n");
+       p1a(ip6s_fragoverflow, "\t\t\t%llu exceeded limit\n");
+       p1a(ip6s_reassembled, "\t\t\t%llu reassembled ok\n");
+       p1a(ip6s_atmfrag_rcvd, "\t\t\t%llu atomic fragments received\n");
+       p(ip6s_delivered, "\t\t%llu packet%s for this host\n");
+       p(ip6s_forward, "\t\t%llu packet%s forwarded\n");
+       p(ip6s_cantforward, "\t\t%llu packet%s not forwardable\n");
+       p(ip6s_redirectsent, "\t\t%llu redirect%s sent\n");
+       p(ip6s_notmember, "\t\t%llu multicast packet%s which we don't join\n");
+       p(ip6s_exthdrtoolong,
+           "\t\t%llu packet%s whose headers are not continuous\n");
+       p(ip6s_nogif, "\t\t%llu tunneling packet%s that can't find gif\n");
+       p(ip6s_toomanyhdr,
+           "\t\t%llu packet%s discarded due to too may headers\n");
+       p1a(ip6s_forward_cachehit, "\t\t%llu forward cache hit\n");
+       p1a(ip6s_forward_cachemiss, "\t\t%llu forward cache miss\n");
+       p(ip6s_pktdropcntrl,
+           "\t\t%llu packet%s dropped due to no bufs for control data\n");
+
+#define INPERFDIFF(f) (in_net_perf.f - pin_net_perf.f)
+       if (INPERFDIFF(np_total_pkts) > 0 && in_net_perf.np_total_usecs > 0) {
+               printf("\tInput Performance Stats:\n");
+               printf("\t\t%llu total packets measured\n", INPERFDIFF(np_total_pkts));
+               printf("\t\t%llu total usec elapsed\n", INPERFDIFF(np_total_usecs));
+               printf("\t\t%f usec per packet\n",
+                   (double)in_net_perf.np_total_usecs/(double)in_net_perf.np_total_pkts);
+               printf("\t\tPerformance Histogram:\n");
+               printf("\t\t\t x <= %u: %llu\n", in_net_perf.np_hist_bars[0],
+                   INPERFDIFF(np_hist1));
+               printf("\t\t\t %u < x <= %u: %llu\n",
+                   in_net_perf.np_hist_bars[0], in_net_perf.np_hist_bars[1],
+                   INPERFDIFF(np_hist2));
+               printf("\t\t\t %u < x <= %u: %llu\n",
+                   in_net_perf.np_hist_bars[1], in_net_perf.np_hist_bars[2],
+                   INPERFDIFF(np_hist3));
+               printf("\t\t\t %u < x <= %u: %llu\n",
+                   in_net_perf.np_hist_bars[2], in_net_perf.np_hist_bars[3],
+                   INPERFDIFF(np_hist4));
+               printf("\t\t\t %u < x: %llu\n",
+                   in_net_perf.np_hist_bars[3], INPERFDIFF(np_hist5));
+       }
+#undef INPERFDIFF
+
        p(ip6s_localout, "\t%llu packet%s sent from this host\n");
-       p(ip6s_rawout, "\t%llu packet%s sent with fabricated ip header\n");
-       p(ip6s_odropped, "\t%llu output packet%s dropped due to no bufs, etc.\n");
-       p(ip6s_noroute, "\t%llu output packet%s discarded due to no route\n");
-       p(ip6s_fragmented, "\t%llu output datagram%s fragmented\n");
-       p(ip6s_ofragments, "\t%llu fragment%s created\n");
-       p(ip6s_cantfrag, "\t%llu datagram%s that can't be fragmented\n");
-       p(ip6s_badscope, "\t%llu packet%s that violated scope rules\n");
-       p(ip6s_notmember, "\t%llu multicast packet%s which we don't join\n");
+       p(ip6s_rawout, "\t\t%llu packet%s sent with fabricated ip header\n");
+       p(ip6s_odropped,
+           "\t\t%llu output packet%s dropped due to no bufs, etc.\n");
+       p(ip6s_noroute, "\t\t%llu output packet%s discarded due to no route\n");
+       p(ip6s_fragmented, "\t\t%llu output datagram%s fragmented\n");
+       p(ip6s_ofragments, "\t\t%llu fragment%s created\n");
+       p(ip6s_cantfrag, "\t\t%llu datagram%s that can't be fragmented\n");
+       p(ip6s_badscope, "\t\t%llu packet%s that violated scope rules\n");
+       p(ip6s_necp_policy_drop, "\t\t%llu packet%s dropped due to NECP policy\n");
+
+#define OUTPERFDIFF(f) (out_net_perf.f - pout_net_perf.f)
+       if (OUTPERFDIFF(np_total_pkts) > 0 && out_net_perf.np_total_usecs > 0) {
+               printf("\tOutput Performance Stats:\n");
+               printf("\t\t%llu total packets measured\n", OUTPERFDIFF(np_total_pkts));
+               printf("\t\t%llu total usec elapsed\n", OUTPERFDIFF(np_total_usecs));
+               printf("\t\t%f usec per packet\n",
+                   (double)out_net_perf.np_total_usecs/(double)out_net_perf.np_total_pkts);
+               printf("\t\tHistogram:\n");
+               printf("\t\t\t x <= %u: %llu\n", out_net_perf.np_hist_bars[0],
+                   OUTPERFDIFF(np_hist1));
+               printf("\t\t\t %u < x <= %u: %llu\n",
+                   out_net_perf.np_hist_bars[0], out_net_perf.np_hist_bars[1],
+                   OUTPERFDIFF(np_hist2));
+               printf("\t\t\t %u < x <= %u: %llu\n",
+                   out_net_perf.np_hist_bars[1], out_net_perf.np_hist_bars[2],
+                   OUTPERFDIFF(np_hist3));
+               printf("\t\t\t %u < x <= %u: %llu\n",
+                   out_net_perf.np_hist_bars[2], out_net_perf.np_hist_bars[3],
+                   OUTPERFDIFF(np_hist4));
+               printf("\t\t\t %u < x: %llu\n",
+                   out_net_perf.np_hist_bars[3], OUTPERFDIFF(np_hist5));
+       }
+#undef OUTPERFDIFF
+
        for (first = 1, i = 0; i < 256; i++)
                if (IP6DIFF(ip6s_nxthist[i]) != 0) {
                        if (first) {
@@ -441,87 +537,104 @@ ip6_stats(uint32_t off __unused, char *name, int af __unused)
            (unsigned long long)IP6DIFF(ip6s_mext1));
        printf("\t\t%llu two or more ext mbuf\n",
            (unsigned long long)IP6DIFF(ip6s_mext2m));
-       p(ip6s_exthdrtoolong,
-           "\t%llu packet%s whose headers are not continuous\n");
-       p(ip6s_nogif, "\t%llu tunneling packet%s that can't find gif\n");
-       p(ip6s_toomanyhdr,
-           "\t%llu packet%s discarded due to too may headers\n");
 
        /* for debugging source address selection */
 #define PRINT_SCOPESTAT(s,i) do {\
                switch(i) { /* XXX hardcoding in each case */\
                case 1:\
-                       p(s, "\t\t%llu node-local%s\n");\
+                       p(s, "\t\t\t%llu node-local%s\n");\
                        break;\
                case 2:\
-                       p(s,"\t\t%llu link-local%s\n");\
+                       p(s,"\t\t\t%llu link-local%s\n");\
                        break;\
                case 5:\
-                       p(s,"\t\t%llu site-local%s\n");\
+                       p(s,"\t\t\t%llu site-local%s\n");\
                        break;\
                case 14:\
-                       p(s,"\t\t%llu global%s\n");\
+                       p(s,"\t\t\t%llu global%s\n");\
                        break;\
                default:\
-                       printf("\t\t%llu addresses scope=%x\n",\
+                       printf("\t\t\t%llu addresses scope=%x\n",\
                            (unsigned long long)IP6DIFF(s), i);\
                }\
        } while (0);
 
        p(ip6s_sources_none,
-         "\t%llu failure%s of source address selection\n");
-       for (first = 1, i = 0; i < 16; i++) {
-               if (IP6DIFF(ip6s_sources_sameif[i])) {
+         "\t\t%llu failure%s of source address selection\n");
+       for (first = 1, i = 0; i < SCOPE6_ID_MAX; i++) {
+               if (IP6DIFF(ip6s_sources_sameif[i]) || 1) {
                        if (first) {
-                               printf("\tsource addresses on an outgoing I/F\n");
+                               printf("\t\tsource addresses on an outgoing I/F\n");
                                first = 0;
                        }
                        PRINT_SCOPESTAT(ip6s_sources_sameif[i], i);
                }
        }
-       for (first = 1, i = 0; i < 16; i++) {
-               if (IP6DIFF(ip6s_sources_otherif[i])) {
+       for (first = 1, i = 0; i < SCOPE6_ID_MAX; i++) {
+               if (IP6DIFF(ip6s_sources_otherif[i]) || 1) {
                        if (first) {
-                               printf("\tsource addresses on a non-outgoing I/F\n");
+                               printf("\t\tsource addresses on a non-outgoing I/F\n");
                                first = 0;
                        }
                        PRINT_SCOPESTAT(ip6s_sources_otherif[i], i);
                }
        }
-       for (first = 1, i = 0; i < 16; i++) {
-               if (IP6DIFF(ip6s_sources_samescope[i])) {
+       for (first = 1, i = 0; i < SCOPE6_ID_MAX; i++) {
+               if (IP6DIFF(ip6s_sources_samescope[i]) || 1) {
                        if (first) {
-                               printf("\tsource addresses of same scope\n");
+                               printf("\t\tsource addresses of same scope\n");
                                first = 0;
                        }
                        PRINT_SCOPESTAT(ip6s_sources_samescope[i], i);
                }
        }
-       for (first = 1, i = 0; i < 16; i++) {
-               if (IP6DIFF(ip6s_sources_otherscope[i])) {
+       for (first = 1, i = 0; i < SCOPE6_ID_MAX; i++) {
+               if (IP6DIFF(ip6s_sources_otherscope[i]) || 1) {
                        if (first) {
-                               printf("\tsource addresses of a different scope\n");
+                               printf("\t\tsource addresses of a different scope\n");
                                first = 0;
                        }
                        PRINT_SCOPESTAT(ip6s_sources_otherscope[i], i);
                }
        }
-       for (first = 1, i = 0; i < 16; i++) {
-               if (IP6DIFF(ip6s_sources_deprecated[i])) {
+       for (first = 1, i = 0; i < SCOPE6_ID_MAX; i++) {
+               if (IP6DIFF(ip6s_sources_deprecated[i]) || 1) {
                        if (first) {
-                               printf("\tdeprecated source addresses\n");
+                               printf("\t\tdeprecated source addresses\n");
                                first = 0;
                        }
                        PRINT_SCOPESTAT(ip6s_sources_deprecated[i], i);
                }
        }
+#define PRINT_SRCRULESTAT(s,i) do {\
+       if (srcrulenames[i] != NULL) \
+               printf("\t\t\t%llu rule%s %s\n", \
+                       (unsigned long long)IP6DIFF(s), \
+                       plural(IP6DIFF(s)), \
+                       srcrulenames[i]); \
+} while (0);
 
-       p1a(ip6s_forward_cachehit, "\t%llu forward cache hit\n");
-       p1a(ip6s_forward_cachemiss, "\t%llu forward cache miss\n");
+       for (first = 1, i = 0; i < IP6S_SRCRULE_COUNT; i++) {
+               if (IP6DIFF(ip6s_sources_rule[i]) || 1) {
+                       if (first) {
+                               printf("\t\tsource address selection\n");
+                               first = 0;
+                       }
+                       PRINT_SRCRULESTAT(ip6s_sources_rule[i], i);
+               }
+       }
+       
+       p(ip6s_dad_collide, "\t\t%llu duplicate address detection collision%s\n");
+       
+       p(ip6s_dad_loopcount, "\t\t%llu duplicate address detection NS loop%s\n");
 
-       if (interval > 0)
-               bcopy(&ip6stat, &pip6stat, len);
+       p(ip6s_sources_skip_expensive_secondary_if, "\t\t%llu time%s ignored source on secondary expensive I/F\n");
 
+       if (interval > 0) {
+               bcopy(&ip6stat, &pip6stat, len);
+               bcopy(&in_net_perf, &pin_net_perf, in_net_perf_len);
+               bcopy(&out_net_perf, &pout_net_perf, out_net_perf_len);
+       }
 #undef IP6DIFF
 #undef p
 #undef p1a
@@ -545,7 +658,9 @@ ip6_ifstats(char *ifname)
                return;
        }
 
-       strcpy(ifr.ifr_name, ifname);
+    if (interval && vflag > 0)
+        print_time();
+       strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
        printf("ip6 on %s:\n", ifr.ifr_name);
 
        if (ioctl(s, SIOCGIFSTAT_IN6, (char *)&ifr) < 0) {
@@ -572,10 +687,15 @@ ip6_ifstats(char *ifname)
        p(ifs6_out_fragcreat, "\t%llu output datagram%s succeeded on fragment\n");
        p(ifs6_reass_reqd, "\t%llu incoming datagram%s fragmented\n");
        p(ifs6_reass_ok, "\t%llu datagram%s reassembled\n");
+       p(ifs6_atmfrag_rcvd, "\t%llu atomic fragments%s received\n");
        p(ifs6_reass_fail, "\t%llu datagram%s failed on reassembling\n");
        p(ifs6_in_mcast, "\t%llu multicast datagram%s received\n");
        p(ifs6_out_mcast, "\t%llu multicast datagram%s sent\n");
 
+       p(ifs6_cantfoward_icmp6, "\t%llu ICMPv6 packet%s received for unreachable destination\n");
+       p(ifs6_addr_expiry_cnt, "\t%llu address expiry event%s reported\n");
+       p(ifs6_pfx_expiry_cnt, "\t%llu prefix expiry event%s reported\n");
+       p(ifs6_defrtr_expiry_cnt, "\t%llu default router expiry event%s reported\n");
   end:
        close(s);
 
@@ -715,8 +835,8 @@ static      char *icmp6names[] = {
        "echo",
        "echo reply",   
        "multicast listener query",
-       "multicast listener report",
-       "multicast listener done",
+       "MLDv1 listener report",
+       "MLDv1 listener done",
        "router solicitation",
        "router advertisement",
        "neighbor solicitation",
@@ -727,7 +847,7 @@ static      char *icmp6names[] = {
        "node information reply",
        "inverse neighbor solicitation",
        "inverse neighbor advertisement",
-       "#143",
+       "MLDv2 listener report",
        "#144",
        "#145",
        "#146",
@@ -863,6 +983,8 @@ icmp6_stats(uint32_t off __unused, char *name, int af __unused)
        memset(&icmp6stat, 0, len);
        if (sysctl(mib, 4, &icmp6stat, &len, (void *)0, 0) < 0)
                return;
+    if (interval && vflag > 0)
+        print_time();
        printf("%s:\n", name);
 
 #define        ICMP6DIFF(f) (icmp6stat.f - picmp6stat.f)
@@ -925,6 +1047,7 @@ icmp6_stats(uint32_t off __unused, char *name, int af __unused)
        p(icp6s_badra, "\t%qu bad router advertisement message%s\n");
        p(icp6s_badredirect, "\t%qu bad redirect message%s\n");
        p(icp6s_pmtuchg, "\t%llu path MTU change%s\n");
+       p(icp6s_rfc6980_drop, "\t%qu dropped fragmented NDP message%s\n");
 
        if (interval > 0)
                bcopy(&icmp6stat, &picmp6stat, len);
@@ -950,7 +1073,9 @@ icmp6_ifstats(char *ifname)
                return;
        }
 
-       strcpy(ifr.ifr_name, ifname);
+    if (interval && vflag > 0)
+        print_time();
+       strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
        printf("icmp6 on %s:\n", ifr.ifr_name);
 
        if (ioctl(s, SIOCGIFSTAT_ICMP6, (char *)&ifr) < 0) {
@@ -999,40 +1124,6 @@ icmp6_ifstats(char *ifname)
 #undef p
 }
 
-/*
- * Dump PIM statistics structure.
- */
-#ifdef notyet 
-void
-pim6_stats(void)
-{
-       static struct pim6stat ppim6stat;
-       struct pim6stat pim6stat;
-       size_t len = sizeof(struct pim6stat);
-
-       if (sysctlbyname("net.inet6.ip6.pim6stat", &pim6stat, &len, 0, 0) == -1)
-               return;
-       printf("%s:\n", name);
-
-#define        PIM6DIFF(f) (pim6stat.f - ppim6stat.f)
-#define        p(f, m) if (PIM6DIFF(f) || sflag <= 1) \
-    printf(m, (unsigned long long)PIM6DIFF(f), plural(PIM6DIFF(f)))
-       p(pim6s_rcv_total, "\t%llu message%s received\n");
-       p(pim6s_rcv_tooshort, "\t%llu message%s received with too few bytes\n");
-       p(pim6s_rcv_badsum, "\t%llu message%s received with bad checksum\n");
-       p(pim6s_rcv_badversion, "\t%llu message%s received with bad version\n");
-       p(pim6s_rcv_registers, "\t%llu register%s received\n");
-       p(pim6s_rcv_badregisters, "\t%llu bad register%s received\n");
-       p(pim6s_snd_registers, "\t%llu register%s sent\n");
-
-       if (interval > 0)
-               bcopy(&pim6stat, &ppim6stat, len);
-
-#undef PIM6DIFF
-#undef p
-}
-#endif
-
 /*
  * Dump raw ip6 statistics structure.
  */
@@ -1055,13 +1146,15 @@ rip6_stats(uint32_t off __unused, char *name, int af __unused)
                return;
        }
 
+    if (interval && vflag > 0)
+        print_time();
        printf("%s:\n", name);
 
 #define        RIP6DIFF(f) (rip6stat.f - prip6stat.f)
 #define        p(f, m) if (RIP6DIFF(f) || sflag <= 1) \
     printf(m, (unsigned long long)RIP6DIFF(f), plural(RIP6DIFF(f)))
        p(rip6s_ipackets, "\t%llu message%s received\n");
-       p(rip6s_isum, "\t%llu checksum calcuration%s on inbound\n");
+       p(rip6s_isum, "\t%llu checksum calculation%s on inbound\n");
        p(rip6s_badsum, "\t%llu message%s with bad checksum\n");
        p(rip6s_nosock, "\t%llu message%s dropped due to no socket\n");
        p(rip6s_nosockmcast,
@@ -1118,15 +1211,15 @@ inet6print(struct in6_addr *in6, int port, char *proto, int numeric)
        char line[80], *cp;
        int width;
 
-       sprintf(line, "%.*s.", lflag ? 39 :
+       snprintf(line, sizeof(line), "%.*s.", lflag ? 39 :
                (Aflag && !numeric) ? 12 : 16, inet6name(in6));
        cp = index(line, '\0');
        if (!numeric && port)
                GETSERVBYPORT6(port, proto, sp);
        if (sp || port == 0)
-               sprintf(cp, "%.8s", sp ? sp->s_name : "*");
+               snprintf(cp, sizeof(line) - (cp - line), "%.15s", sp ? sp->s_name : "*");
        else
-               sprintf(cp, "%d", ntohs((u_short)port));
+               snprintf(cp, sizeof(line) - (cp - line), "%d", ntohs((u_short)port));
        width = lflag ? 45 : Aflag ? 18 : 22;
        printf("%-*.*s ", width, width, line);
 }
@@ -1153,7 +1246,7 @@ inet6name(struct in6_addr *in6p)
                first = 0;
                if (gethostname(domain, MAXHOSTNAMELEN) == 0 &&
                    (cp = index(domain, '.')))
-                       (void) strcpy(domain, cp + 1);
+                       (void) memmove(domain, cp + 1, strlen(cp + 1) + 1);
                else
                        domain[0] = 0;
        }
@@ -1168,7 +1261,7 @@ inet6name(struct in6_addr *in6p)
                }
        }
        if (IN6_IS_ADDR_UNSPECIFIED(in6p))
-               strcpy(line, "*");
+               strlcpy(line, "*", sizeof(line));
        else if (cp)
                strlcpy(line, cp, sizeof(line));
        else {
@@ -1178,6 +1271,7 @@ inet6name(struct in6_addr *in6p)
                sin6.sin6_addr = *in6p;
 
                if (IN6_IS_ADDR_LINKLOCAL(in6p) ||
+                   IN6_IS_ADDR_MC_NODELOCAL(in6p) ||
                    IN6_IS_ADDR_MC_LINKLOCAL(in6p)) {
                        sin6.sin6_scope_id =
                            ntohs(*(u_int16_t *)&in6p->s6_addr[2]);