1 /* BSDI inet.c,v 2.3 1995/10/24 02:19:29 prb Exp */
3 * Copyright (c) 1983, 1988, 1993
4 * The Regents of the University of California. All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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 * 4. Neither the name of the University nor the names of its contributors
15 * may be used to endorse or promote products derived from this software
16 * without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 static char sccsid[] = "@(#)inet6.c 8.4 (Berkeley) 4/20/94";
37 #include <sys/cdefs.h>
38 __FBSDID("$FreeBSD$");
41 #include <sys/param.h>
42 #include <sys/socket.h>
43 #include <sys/socketvar.h>
44 #include <sys/ioctl.h>
46 #include <sys/protosw.h>
48 #include <net/route.h>
50 #include <net/if_var.h>
51 #include <netinet/in.h>
52 #include <netinet/ip6.h>
53 #include <netinet/icmp6.h>
54 #include <netinet/in_systm.h>
55 #include <netinet6/in6_pcb.h>
56 #include <netinet6/in6_var.h>
57 #include <netinet6/ip6_var.h>
58 #include <netinet6/pim6_var.h>
59 #include <netinet6/raw_ip6.h>
61 #include <arpa/inet.h>
74 char *inet6name(struct in6_addr *);
76 static char ntop_buf[INET6_ADDRSTRLEN];
78 static const char *ip6nh[] = {
139 "destination option",
337 static const char *srcrule_str[] = {
341 "deprecated address",
343 "outgoing interface",
345 "public/temporary address",
347 "better virtual status",
357 * Dump IP6 statistics structure.
360 ip6_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
362 struct ip6stat ip6stat;
365 if (fetch_stats("net.inet6.ip6.stats", off, &ip6stat,
366 sizeof(ip6stat), kread_counters) != 0)
369 printf("%s:\n", name);
371 #define p(f, m) if (ip6stat.f || sflag <= 1) \
372 printf(m, (uintmax_t)ip6stat.f, plural(ip6stat.f))
373 #define p1a(f, m) if (ip6stat.f || sflag <= 1) \
374 printf(m, (uintmax_t)ip6stat.f)
376 p(ip6s_total, "\t%ju total packet%s received\n");
377 p1a(ip6s_toosmall, "\t%ju with size smaller than minimum\n");
378 p1a(ip6s_tooshort, "\t%ju with data size < data length\n");
379 p1a(ip6s_badoptions, "\t%ju with bad options\n");
380 p1a(ip6s_badvers, "\t%ju with incorrect version number\n");
381 p(ip6s_fragments, "\t%ju fragment%s received\n");
382 p(ip6s_fragdropped, "\t%ju fragment%s dropped (dup or out of space)\n");
383 p(ip6s_fragtimeout, "\t%ju fragment%s dropped after timeout\n");
384 p(ip6s_fragoverflow, "\t%ju fragment%s that exceeded limit\n");
385 p(ip6s_reassembled, "\t%ju packet%s reassembled ok\n");
386 p(ip6s_delivered, "\t%ju packet%s for this host\n");
387 p(ip6s_forward, "\t%ju packet%s forwarded\n");
388 p(ip6s_cantforward, "\t%ju packet%s not forwardable\n");
389 p(ip6s_redirectsent, "\t%ju redirect%s sent\n");
390 p(ip6s_localout, "\t%ju packet%s sent from this host\n");
391 p(ip6s_rawout, "\t%ju packet%s sent with fabricated ip header\n");
392 p(ip6s_odropped, "\t%ju output packet%s dropped due to no bufs, etc.\n");
393 p(ip6s_noroute, "\t%ju output packet%s discarded due to no route\n");
394 p(ip6s_fragmented, "\t%ju output datagram%s fragmented\n");
395 p(ip6s_ofragments, "\t%ju fragment%s created\n");
396 p(ip6s_cantfrag, "\t%ju datagram%s that can't be fragmented\n");
397 p(ip6s_badscope, "\t%ju packet%s that violated scope rules\n");
398 p(ip6s_notmember, "\t%ju multicast packet%s which we don't join\n");
399 for (first = 1, i = 0; i < IP6S_HDRCNT; i++)
400 if (ip6stat.ip6s_nxthist[i] != 0) {
402 printf("\tInput histogram:\n");
405 printf("\t\t%s: %ju\n", ip6nh[i],
406 (uintmax_t)ip6stat.ip6s_nxthist[i]);
408 printf("\tMbuf statistics:\n");
409 printf("\t\t%ju one mbuf\n", (uintmax_t)ip6stat.ip6s_m1);
410 for (first = 1, i = 0; i < IP6S_M2MMAX; i++) {
411 char ifbuf[IFNAMSIZ];
412 if (ip6stat.ip6s_m2m[i] != 0) {
414 printf("\t\ttwo or more mbuf:\n");
417 printf("\t\t\t%s= %ju\n",
418 if_indextoname(i, ifbuf),
419 (uintmax_t)ip6stat.ip6s_m2m[i]);
422 printf("\t\t%ju one ext mbuf\n",
423 (uintmax_t)ip6stat.ip6s_mext1);
424 printf("\t\t%ju two or more ext mbuf\n",
425 (uintmax_t)ip6stat.ip6s_mext2m);
426 p(ip6s_exthdrtoolong,
427 "\t%ju packet%s whose headers are not contiguous\n");
428 p(ip6s_nogif, "\t%ju tunneling packet%s that can't find gif\n");
430 "\t%ju packet%s discarded because of too many headers\n");
432 /* for debugging source address selection */
433 #define PRINT_SCOPESTAT(s,i) do {\
434 switch(i) { /* XXX hardcoding in each case */\
436 p(s, "\t\t%ju interface-local%s\n");\
439 p(s,"\t\t%ju link-local%s\n");\
442 p(s,"\t\t%ju site-local%s\n");\
445 p(s,"\t\t%ju global%s\n");\
448 printf("\t\t%ju addresses scope=%x\n",\
449 (uintmax_t)ip6stat.s, i);\
454 "\t%ju failure%s of source address selection\n");
455 for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) {
456 if (ip6stat.ip6s_sources_sameif[i]) {
458 printf("\tsource addresses on an outgoing I/F\n");
461 PRINT_SCOPESTAT(ip6s_sources_sameif[i], i);
464 for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) {
465 if (ip6stat.ip6s_sources_otherif[i]) {
467 printf("\tsource addresses on a non-outgoing I/F\n");
470 PRINT_SCOPESTAT(ip6s_sources_otherif[i], i);
473 for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) {
474 if (ip6stat.ip6s_sources_samescope[i]) {
476 printf("\tsource addresses of same scope\n");
479 PRINT_SCOPESTAT(ip6s_sources_samescope[i], i);
482 for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) {
483 if (ip6stat.ip6s_sources_otherscope[i]) {
485 printf("\tsource addresses of a different scope\n");
488 PRINT_SCOPESTAT(ip6s_sources_otherscope[i], i);
491 for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) {
492 if (ip6stat.ip6s_sources_deprecated[i]) {
494 printf("\tdeprecated source addresses\n");
497 PRINT_SCOPESTAT(ip6s_sources_deprecated[i], i);
501 printf("\tSource addresses selection rule applied:\n");
502 for (i = 0; i < IP6S_RULESMAX; i++) {
503 if (ip6stat.ip6s_sources_rule[i])
504 printf("\t\t%ju %s\n",
505 (uintmax_t)ip6stat.ip6s_sources_rule[i],
513 * Dump IPv6 per-interface statistics based on RFC 2465.
516 ip6_ifstats(char *ifname)
518 struct in6_ifreq ifr;
520 #define p(f, m) if (ifr.ifr_ifru.ifru_stat.f || sflag <= 1) \
521 printf(m, (uintmax_t)ifr.ifr_ifru.ifru_stat.f, plural(ifr.ifr_ifru.ifru_stat.f))
522 #define p_5(f, m) if (ifr.ifr_ifru.ifru_stat.f || sflag <= 1) \
523 printf(m, (uintmax_t)ip6stat.f)
525 if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
526 perror("Warning: socket(AF_INET6)");
530 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
531 if (ioctl(s, SIOCGIFSTAT_IN6, (char *)&ifr) < 0) {
532 if (errno != EPFNOSUPPORT)
533 perror("Warning: ioctl(SIOCGIFSTAT_IN6)");
537 printf("ip6 on %s:\n", ifr.ifr_name);
538 p(ifs6_in_receive, "\t%ju total input datagram%s\n");
539 p(ifs6_in_hdrerr, "\t%ju datagram%s with invalid header received\n");
540 p(ifs6_in_toobig, "\t%ju datagram%s exceeded MTU received\n");
541 p(ifs6_in_noroute, "\t%ju datagram%s with no route received\n");
542 p(ifs6_in_addrerr, "\t%ju datagram%s with invalid dst received\n");
543 p(ifs6_in_protounknown, "\t%ju datagram%s with unknown proto received\n");
544 p(ifs6_in_truncated, "\t%ju truncated datagram%s received\n");
545 p(ifs6_in_discard, "\t%ju input datagram%s discarded\n");
547 "\t%ju datagram%s delivered to an upper layer protocol\n");
548 p(ifs6_out_forward, "\t%ju datagram%s forwarded to this interface\n");
550 "\t%ju datagram%s sent from an upper layer protocol\n");
551 p(ifs6_out_discard, "\t%ju total discarded output datagram%s\n");
552 p(ifs6_out_fragok, "\t%ju output datagram%s fragmented\n");
553 p(ifs6_out_fragfail, "\t%ju output datagram%s failed on fragment\n");
554 p(ifs6_out_fragcreat, "\t%ju output datagram%s succeeded on fragment\n");
555 p(ifs6_reass_reqd, "\t%ju incoming datagram%s fragmented\n");
556 p(ifs6_reass_ok, "\t%ju datagram%s reassembled\n");
557 p(ifs6_reass_fail, "\t%ju datagram%s failed on reassembly\n");
558 p(ifs6_in_mcast, "\t%ju multicast datagram%s received\n");
559 p(ifs6_out_mcast, "\t%ju multicast datagram%s sent\n");
568 static const char *icmp6names[] = {
699 "multicast listener query",
700 "MLDv1 listener report",
701 "MLDv1 listener done",
702 "router solicitation",
703 "router advertisement",
704 "neighbor solicitation",
705 "neighbor advertisement",
707 "router renumbering",
708 "node information request",
709 "node information reply",
710 "inverse neighbor solicitation",
711 "inverse neighbor advertisement",
712 "MLDv2 listener report",
828 * Dump ICMP6 statistics.
831 icmp6_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
833 struct icmp6stat icmp6stat;
836 if (fetch_stats("net.inet6.icmp6.stats", off, &icmp6stat,
837 sizeof(icmp6stat), kread_counters) != 0)
840 printf("%s:\n", name);
842 #define p(f, m) if (icmp6stat.f || sflag <= 1) \
843 printf(m, (uintmax_t)icmp6stat.f, plural(icmp6stat.f))
844 #define p_5(f, m) if (icmp6stat.f || sflag <= 1) \
845 printf(m, (uintmax_t)icmp6stat.f)
847 p(icp6s_error, "\t%ju call%s to icmp6_error\n");
849 "\t%ju error%s not generated in response to an icmp6 message\n");
851 "\t%ju error%s not generated because of rate limitation\n");
852 #define NELEM (int)(sizeof(icmp6stat.icp6s_outhist)/sizeof(icmp6stat.icp6s_outhist[0]))
853 for (first = 1, i = 0; i < NELEM; i++)
854 if (icmp6stat.icp6s_outhist[i] != 0) {
856 printf("\tOutput histogram:\n");
859 printf("\t\t%s: %ju\n", icmp6names[i],
860 (uintmax_t)icmp6stat.icp6s_outhist[i]);
863 p(icp6s_badcode, "\t%ju message%s with bad code fields\n");
864 p(icp6s_tooshort, "\t%ju message%s < minimum length\n");
865 p(icp6s_checksum, "\t%ju bad checksum%s\n");
866 p(icp6s_badlen, "\t%ju message%s with bad length\n");
867 #define NELEM (int)(sizeof(icmp6stat.icp6s_inhist)/sizeof(icmp6stat.icp6s_inhist[0]))
868 for (first = 1, i = 0; i < NELEM; i++)
869 if (icmp6stat.icp6s_inhist[i] != 0) {
871 printf("\tInput histogram:\n");
874 printf("\t\t%s: %ju\n", icmp6names[i],
875 (uintmax_t)icmp6stat.icp6s_inhist[i]);
878 printf("\tHistogram of error messages to be generated:\n");
879 p_5(icp6s_odst_unreach_noroute, "\t\t%ju no route\n");
880 p_5(icp6s_odst_unreach_admin, "\t\t%ju administratively prohibited\n");
881 p_5(icp6s_odst_unreach_beyondscope, "\t\t%ju beyond scope\n");
882 p_5(icp6s_odst_unreach_addr, "\t\t%ju address unreachable\n");
883 p_5(icp6s_odst_unreach_noport, "\t\t%ju port unreachable\n");
884 p_5(icp6s_opacket_too_big, "\t\t%ju packet too big\n");
885 p_5(icp6s_otime_exceed_transit, "\t\t%ju time exceed transit\n");
886 p_5(icp6s_otime_exceed_reassembly, "\t\t%ju time exceed reassembly\n");
887 p_5(icp6s_oparamprob_header, "\t\t%ju erroneous header field\n");
888 p_5(icp6s_oparamprob_nextheader, "\t\t%ju unrecognized next header\n");
889 p_5(icp6s_oparamprob_option, "\t\t%ju unrecognized option\n");
890 p_5(icp6s_oredirect, "\t\t%ju redirect\n");
891 p_5(icp6s_ounknown, "\t\t%ju unknown\n");
893 p(icp6s_reflect, "\t%ju message response%s generated\n");
894 p(icp6s_nd_toomanyopt, "\t%ju message%s with too many ND options\n");
895 p(icp6s_nd_badopt, "\t%ju message%s with bad ND options\n");
896 p(icp6s_badns, "\t%ju bad neighbor solicitation message%s\n");
897 p(icp6s_badna, "\t%ju bad neighbor advertisement message%s\n");
898 p(icp6s_badrs, "\t%ju bad router solicitation message%s\n");
899 p(icp6s_badra, "\t%ju bad router advertisement message%s\n");
900 p(icp6s_badredirect, "\t%ju bad redirect message%s\n");
901 p(icp6s_pmtuchg, "\t%ju path MTU change%s\n");
907 * Dump ICMPv6 per-interface statistics based on RFC 2466.
910 icmp6_ifstats(char *ifname)
912 struct in6_ifreq ifr;
914 #define p(f, m) if (ifr.ifr_ifru.ifru_icmp6stat.f || sflag <= 1) \
915 printf(m, (uintmax_t)ifr.ifr_ifru.ifru_icmp6stat.f, plural(ifr.ifr_ifru.ifru_icmp6stat.f))
916 #define p2(f, m) if (ifr.ifr_ifru.ifru_icmp6stat.f || sflag <= 1) \
917 printf(m, (uintmax_t)ifr.ifr_ifru.ifru_icmp6stat.f, pluralies(ifr.ifr_ifru.ifru_icmp6stat.f))
919 if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
920 perror("Warning: socket(AF_INET6)");
924 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
925 if (ioctl(s, SIOCGIFSTAT_ICMP6, (char *)&ifr) < 0) {
926 if (errno != EPFNOSUPPORT)
927 perror("Warning: ioctl(SIOCGIFSTAT_ICMP6)");
931 printf("icmp6 on %s:\n", ifr.ifr_name);
932 p(ifs6_in_msg, "\t%ju total input message%s\n");
933 p(ifs6_in_error, "\t%ju total input error message%s\n");
934 p(ifs6_in_dstunreach, "\t%ju input destination unreachable error%s\n");
935 p(ifs6_in_adminprohib, "\t%ju input administratively prohibited error%s\n");
936 p(ifs6_in_timeexceed, "\t%ju input time exceeded error%s\n");
937 p(ifs6_in_paramprob, "\t%ju input parameter problem error%s\n");
938 p(ifs6_in_pkttoobig, "\t%ju input packet too big error%s\n");
939 p(ifs6_in_echo, "\t%ju input echo request%s\n");
940 p2(ifs6_in_echoreply, "\t%ju input echo repl%s\n");
941 p(ifs6_in_routersolicit, "\t%ju input router solicitation%s\n");
942 p(ifs6_in_routeradvert, "\t%ju input router advertisement%s\n");
943 p(ifs6_in_neighborsolicit, "\t%ju input neighbor solicitation%s\n");
944 p(ifs6_in_neighboradvert, "\t%ju input neighbor advertisement%s\n");
945 p(ifs6_in_redirect, "\t%ju input redirect%s\n");
946 p2(ifs6_in_mldquery, "\t%ju input MLD quer%s\n");
947 p(ifs6_in_mldreport, "\t%ju input MLD report%s\n");
948 p(ifs6_in_mlddone, "\t%ju input MLD done%s\n");
950 p(ifs6_out_msg, "\t%ju total output message%s\n");
951 p(ifs6_out_error, "\t%ju total output error message%s\n");
952 p(ifs6_out_dstunreach, "\t%ju output destination unreachable error%s\n");
953 p(ifs6_out_adminprohib, "\t%ju output administratively prohibited error%s\n");
954 p(ifs6_out_timeexceed, "\t%ju output time exceeded error%s\n");
955 p(ifs6_out_paramprob, "\t%ju output parameter problem error%s\n");
956 p(ifs6_out_pkttoobig, "\t%ju output packet too big error%s\n");
957 p(ifs6_out_echo, "\t%ju output echo request%s\n");
958 p2(ifs6_out_echoreply, "\t%ju output echo repl%s\n");
959 p(ifs6_out_routersolicit, "\t%ju output router solicitation%s\n");
960 p(ifs6_out_routeradvert, "\t%ju output router advertisement%s\n");
961 p(ifs6_out_neighborsolicit, "\t%ju output neighbor solicitation%s\n");
962 p(ifs6_out_neighboradvert, "\t%ju output neighbor advertisement%s\n");
963 p(ifs6_out_redirect, "\t%ju output redirect%s\n");
964 p2(ifs6_out_mldquery, "\t%ju output MLD quer%s\n");
965 p(ifs6_out_mldreport, "\t%ju output MLD report%s\n");
966 p(ifs6_out_mlddone, "\t%ju output MLD done%s\n");
974 * Dump PIM statistics structure.
977 pim6_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
979 struct pim6stat pim6stat;
981 if (fetch_stats("net.inet6.pim.stats", off, &pim6stat,
982 sizeof(pim6stat), kread) != 0)
985 printf("%s:\n", name);
987 #define p(f, m) if (pim6stat.f || sflag <= 1) \
988 printf(m, (uintmax_t)pim6stat.f, plural(pim6stat.f))
989 p(pim6s_rcv_total, "\t%ju message%s received\n");
990 p(pim6s_rcv_tooshort, "\t%ju message%s received with too few bytes\n");
991 p(pim6s_rcv_badsum, "\t%ju message%s received with bad checksum\n");
992 p(pim6s_rcv_badversion, "\t%ju message%s received with bad version\n");
993 p(pim6s_rcv_registers, "\t%ju register%s received\n");
994 p(pim6s_rcv_badregisters, "\t%ju bad register%s received\n");
995 p(pim6s_snd_registers, "\t%ju register%s sent\n");
1000 * Dump raw ip6 statistics structure.
1003 rip6_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
1005 struct rip6stat rip6stat;
1008 if (fetch_stats("net.inet6.ip6.rip6stats", off, &rip6stat,
1009 sizeof(rip6stat), kread_counters) != 0)
1012 printf("%s:\n", name);
1014 #define p(f, m) if (rip6stat.f || sflag <= 1) \
1015 printf(m, (uintmax_t)rip6stat.f, plural(rip6stat.f))
1016 p(rip6s_ipackets, "\t%ju message%s received\n");
1017 p(rip6s_isum, "\t%ju checksum calculation%s on inbound\n");
1018 p(rip6s_badsum, "\t%ju message%s with bad checksum\n");
1019 p(rip6s_nosock, "\t%ju message%s dropped due to no socket\n");
1020 p(rip6s_nosockmcast,
1021 "\t%ju multicast message%s dropped due to no socket\n");
1023 "\t%ju message%s dropped due to full socket buffers\n");
1024 delivered = rip6stat.rip6s_ipackets -
1025 rip6stat.rip6s_badsum -
1026 rip6stat.rip6s_nosock -
1027 rip6stat.rip6s_nosockmcast -
1028 rip6stat.rip6s_fullsock;
1029 if (delivered || sflag <= 1)
1030 printf("\t%ju delivered\n", (uintmax_t)delivered);
1031 p(rip6s_opackets, "\t%ju datagram%s output\n");
1036 * Pretty print an Internet address (net address + port).
1037 * Take numeric_addr and numeric_port into consideration.
1039 #define GETSERVBYPORT6(port, proto, ret)\
1041 if (strcmp((proto), "tcp6") == 0)\
1042 (ret) = getservbyport((int)(port), "tcp");\
1043 else if (strcmp((proto), "udp6") == 0)\
1044 (ret) = getservbyport((int)(port), "udp");\
1046 (ret) = getservbyport((int)(port), (proto));\
1050 inet6print(struct in6_addr *in6, int port, const char *proto, int numeric)
1052 struct servent *sp = 0;
1056 sprintf(line, "%.*s.", Wflag ? 39 :
1057 (Aflag && !numeric) ? 12 : 16, inet6name(in6));
1058 cp = strchr(line, '\0');
1059 if (!numeric && port)
1060 GETSERVBYPORT6(port, proto, sp);
1061 if (sp || port == 0)
1062 sprintf(cp, "%.15s", sp ? sp->s_name : "*");
1064 sprintf(cp, "%d", ntohs((u_short)port));
1065 width = Wflag ? 45 : Aflag ? 18 : 22;
1066 printf("%-*.*s ", width, width, line);
1070 * Construct an Internet address representation.
1071 * If the numeric_addr has been supplied, give
1072 * numeric value, otherwise try for symbolic name.
1076 inet6name(struct in6_addr *in6p)
1078 struct sockaddr_in6 sin6;
1079 char hbuf[NI_MAXHOST], *cp;
1080 static char line[50];
1081 static char domain[MAXHOSTNAMELEN];
1082 static int first = 1;
1085 if (IN6_IS_ADDR_UNSPECIFIED(in6p)) {
1089 if (first && !numeric_addr) {
1091 if (gethostname(domain, MAXHOSTNAMELEN) == 0 &&
1092 (cp = strchr(domain, '.')))
1093 (void) strcpy(domain, cp + 1);
1097 memset(&sin6, 0, sizeof(sin6));
1098 memcpy(&sin6.sin6_addr, in6p, sizeof(*in6p));
1099 sin6.sin6_family = AF_INET6;
1100 /* XXX: in6p.s6_addr[2] can contain scopeid. */
1101 in6_fillscopeid(&sin6);
1102 flags = (numeric_addr) ? NI_NUMERICHOST : 0;
1103 error = getnameinfo((struct sockaddr *)&sin6, sizeof(sin6), hbuf,
1104 sizeof(hbuf), NULL, 0, flags);
1106 if ((flags & NI_NUMERICHOST) == 0 &&
1107 (cp = strchr(hbuf, '.')) &&
1108 !strcmp(cp + 1, domain))
1112 /* XXX: this should not happen. */
1114 inet_ntop(AF_INET6, (void *)&sin6.sin6_addr, ntop_buf,