static void link_status(int s __unused, const struct ifaddrs *ifa) { /* XXX no const 'cuz LLADDR is defined wrong */ struct sockaddr_dl *sdl = (struct sockaddr_dl *) ifa->ifa_addr; if (sdl != NULL && sdl->sdl_alen > 0) { #ifdef notyet if (sdl->sdl_type == IFT_ETHER && sdl->sdl_alen == ETHER_ADDR_LEN) printf("\tether %s\n", ether_ntoa((struct ether_addr *)LLADDR(sdl))); else { int n = sdl->sdl_nlen > 0 ? sdl->sdl_nlen + 1 : 0; printf("\tlladdr %s\n", link_ntoa(sdl) + n); } #else char *cp = (char *)LLADDR(sdl); int n = sdl->sdl_alen; if (sdl->sdl_type == IFT_ETHER) printf ("\tether "); else printf ("\tlladdr "); while (--n >= 0) printf("%02x%c",*cp++ & 0xff, n>0? ':' : ' '); putchar('\n'); #endif } }
/*- * Convert a network address from binary to printable numeric format. * This API is copied from INRIA's IPv6 implementation, but it is a * bit bogus in two ways: * * 1) There is no value in passing both an address family and * an address length; either one should imply the other, * or we should be passing sockaddrs instead. * 2) There should by contrast be /added/ a length for the buffer * that we pass in, so that programmers are spared the need to * manually calculate (read: ``guess'') the maximum length. * * Flash: the API is also the same in the NRL implementation, and seems to * be some sort of standard, so we appear to be stuck with both the bad * naming and the poor choice of arguments. */ char *addr2ascii (int af, const void *addrp, int len, char *buf) { static char staticbuf[64]; /* 64 for AF_LINK > 16 for AF_INET */ if (!buf) buf = staticbuf; switch (af) { case AF_INET: if (len != sizeof (struct in_addr)) { SOCK_ERR (ENAMETOOLONG); return (NULL); } strcpy (buf, inet_ntoa (*(const struct in_addr *) addrp)); break; case AF_LINK: if (len != sizeof (struct sockaddr_dl)) { SOCK_ERR (ENAMETOOLONG); return (NULL); } strcpy (buf, link_ntoa ((const struct sockaddr_dl *) addrp)); break; default: SOCK_ERR (EPROTONOSUPPORT); return (NULL); } return (buf); }
int sockaddr_to_string(const struct sockaddr * addr, char * str, size_t size) { char buffer[64]; unsigned short port = 0; int n = -1; switch(addr->sa_family) { #ifdef AF_INET6 case AF_INET6: if(inet_ntop(addr->sa_family, &((struct sockaddr_in6 *)addr)->sin6_addr, buffer, sizeof(buffer)) == NULL) { snprintf(buffer, sizeof(buffer), "inet_ntop: %s", strerror(errno)); } port = ntohs(((struct sockaddr_in6 *)addr)->sin6_port); n = snprintf(str, size, "[%s]:%hu", buffer, port); break; #endif /* AF_INET6 */ case AF_INET: if(inet_ntop(addr->sa_family, &((struct sockaddr_in *)addr)->sin_addr, buffer, sizeof(buffer)) == NULL) { snprintf(buffer, sizeof(buffer), "inet_ntop: %s", strerror(errno)); } port = ntohs(((struct sockaddr_in *)addr)->sin_port); n = snprintf(str, size, "%s:%hu", buffer, port); break; #ifdef AF_LINK #if defined(__sun) /* solaris does not seem to have link_ntoa */ /* #define link_ntoa _link_ntoa */ #define link_ntoa(x) "dummy-link_ntoa" #endif case AF_LINK: { struct sockaddr_dl * sdl = (struct sockaddr_dl *)addr; n = snprintf(str, size, "index=%hu type=%d %s", sdl->sdl_index, sdl->sdl_type, link_ntoa(sdl)); } break; #endif /* AF_LINK */ default: n = snprintf(str, size, "unknown address family %d", addr->sa_family); #if 0 n = snprintf(str, size, "unknown address family %d " "%02x %02x %02x %02x %02x %02x %02x %02x", addr->sa_family, addr->sa_data[0], addr->sa_data[1], (unsigned)addr->sa_data[2], addr->sa_data[3], addr->sa_data[4], addr->sa_data[5], (unsigned)addr->sa_data[6], addr->sa_data[7]); #endif } return n; }
int sockaddr_to_string(const struct sockaddr * addr, char * str, size_t size) { char buffer[64]; unsigned short port = 0; int n = -1; switch(addr->sa_family) { case AF_INET6: inet_ntop(addr->sa_family, &((struct sockaddr_in6 *)addr)->sin6_addr, buffer, sizeof(buffer)); port = ntohs(((struct sockaddr_in6 *)addr)->sin6_port); n = snprintf(str, size, "[%s]:%hu", buffer, port); break; case AF_INET: inet_ntop(addr->sa_family, &((struct sockaddr_in *)addr)->sin_addr, buffer, sizeof(buffer)); port = ntohs(((struct sockaddr_in *)addr)->sin_port); n = snprintf(str, size, "%s:%hu", buffer, port); break; #ifdef AF_LINK case AF_LINK: { struct sockaddr_dl * sdl = (struct sockaddr_dl *)addr; n = snprintf(str, size, "index=%hu type=%d %s", sdl->sdl_index, sdl->sdl_type, link_ntoa(sdl)); } break; #endif default: n = snprintf(str, size, "unknown address family %d", addr->sa_family); #if 0 n = snprintf(str, size, "unknown address family %d " "%02x %02x %02x %02x %02x %02x %02x %02x", addr->sa_family, addr->sa_data[0], addr->sa_data[1], (unsigned)addr->sa_data[2], addr->sa_data[3], addr->sa_data[4], addr->sa_data[5], (unsigned)addr->sa_data[6], addr->sa_data[7]); #endif } return n; }
static void mpe_status(int s) { struct if_laddrreq iflr; struct sockaddr_mpls *smpls; struct sockaddr_dl *sdl; (void)memset(&iflr, 0, sizeof(iflr)); (void)memcpy(iflr.iflr_name, name, IFNAMSIZ); smpls = (struct sockaddr_mpls *)&iflr.addr; smpls->smpls_len = sizeof(*smpls); smpls->smpls_family = AF_MPLS; sdl = (struct sockaddr_dl *)&iflr.dstaddr; sdl->sdl_len = sizeof(*sdl); sdl->sdl_family = AF_LINK; if (ioctl(s, SIOCGLIFPHYADDR, (caddr_t)&iflr) < 0) return; /* * Following code-section is reused from implementation * of in af_link.c defined link_status procedure, part of * ifconfig(8) implementation. */ (void)printf("\tlink "); if (sdl != NULL && sdl->sdl_alen > 0) { if ((sdl->sdl_type == IFT_ETHER || sdl->sdl_type == IFT_L2VLAN || sdl->sdl_type == IFT_BRIDGE) && sdl->sdl_alen == ETHER_ADDR_LEN) { (void)printf("%s ", ether_ntoa((struct ether_addr *)LLADDR(sdl))); } else { int n = sdl->sdl_nlen > 0 ? sdl->sdl_nlen + 1 : 0; (void)printf("%s ", link_ntoa(sdl) + n); } } }
static void link_status(int s __unused, const struct ifaddrs *ifa) { /* XXX no const 'cuz LLADDR is defined wrong */ struct sockaddr_dl *sdl = (struct sockaddr_dl *) ifa->ifa_addr; if (sdl != NULL && sdl->sdl_alen > 0) { if ((sdl->sdl_type == IFT_ETHER || sdl->sdl_type == IFT_L2VLAN || sdl->sdl_type == IFT_BRIDGE) && sdl->sdl_alen == ETHER_ADDR_LEN) printf("\tether %s\n", ether_ntoa((struct ether_addr *)LLADDR(sdl))); else { int n = sdl->sdl_nlen > 0 ? sdl->sdl_nlen + 1 : 0; printf("\tlladdr %s\n", link_ntoa(sdl) + n); } } }
const char * satos(const struct sockaddr *sa) { switch (sa->sa_family) { case AF_INET: { const struct sockaddr_in *sin = (const struct sockaddr_in *)sa; if (inet_ntop(AF_INET, &(sin->sin_addr), satos_str, sizeof(satos_str)) == NULL) return "INET ERROR"; break; } case AF_INET6: { const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)sa; if (inet_ntop(AF_INET6, &(sin6->sin6_addr), satos_str, sizeof(satos_str)) == NULL) return "INET6 ERROR"; break; } case AF_LINK: { strlcpy(satos_str, link_ntoa((const struct sockaddr_dl *)sa), sizeof(satos_str)); break; } case AF_MPLS: { strlcpy(satos_str, mpls_ntoa((const struct sockaddr_mpls *)sa), sizeof(satos_str)); break; } default: return "UNKNOWN AF"; } return satos_str; }
static const char * fmt_sockaddr(struct sockaddr *sa, struct sockaddr *mask, int flags) { static char workbuf[128]; const char *cp; if (sa == NULL) return ("null"); switch(sa->sa_family) { case AF_INET: { struct sockaddr_in *sockin = (struct sockaddr_in *)sa; if ((sockin->sin_addr.s_addr == INADDR_ANY) && mask && ntohl(((struct sockaddr_in *)mask)->sin_addr.s_addr) ==0L) cp = "default" ; else if (flags & RTF_HOST) cp = routename(sockin->sin_addr.s_addr); else if (mask) cp = netname(sockin->sin_addr.s_addr, ntohl(((struct sockaddr_in *)mask) ->sin_addr.s_addr)); else cp = netname(sockin->sin_addr.s_addr, 0L); break; } #ifdef INET6 case AF_INET6: { struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)sa; in6_fillscopeid(sa6); if (flags & RTF_HOST) cp = routename6(sa6); else if (mask) cp = netname6(sa6, &((struct sockaddr_in6 *)mask)->sin6_addr); else { cp = netname6(sa6, NULL); } break; } #endif /*INET6*/ case AF_IPX: { struct ipx_addr work = ((struct sockaddr_ipx *)sa)->sipx_addr; if (ipx_nullnet(satoipx_addr(work))) cp = "default"; else cp = ipx_print(sa); break; } case AF_APPLETALK: { if (!(flags & RTF_HOST) && mask) cp = atalk_print2(sa,mask,9); else cp = atalk_print(sa,11); break; } case AF_NETGRAPH: { strlcpy(workbuf, ((struct sockaddr_ng *)sa)->sg_data, sizeof(workbuf)); cp = workbuf; break; } case AF_LINK: { struct sockaddr_dl *sdl = (struct sockaddr_dl *)sa; if (sdl->sdl_nlen == 0 && sdl->sdl_alen == 0 && sdl->sdl_slen == 0) { (void) sprintf(workbuf, "link#%d", sdl->sdl_index); cp = workbuf; } else switch (sdl->sdl_type) { case IFT_ETHER: case IFT_L2VLAN: case IFT_BRIDGE: if (sdl->sdl_alen == ETHER_ADDR_LEN) { cp = ether_ntoa((struct ether_addr *) (sdl->sdl_data + sdl->sdl_nlen)); break; } /* FALLTHROUGH */ default: cp = link_ntoa(sdl); break; } break; } default: { u_char *s = (u_char *)sa->sa_data, *slim; char *cq, *cqlim; cq = workbuf; slim = sa->sa_len + (u_char *) sa; cqlim = cq + sizeof(workbuf) - 6; cq += sprintf(cq, "(%d)", sa->sa_family); while (s < slim && cq < cqlim) { cq += sprintf(cq, " %02x", *s++); if (s < slim) cq += sprintf(cq, "%02x", *s++); } cp = workbuf; } } return (cp); }
static void link_status(int s __unused, const struct ifaddrs *ifa) { /* XXX no const 'cuz LLADDR is defined wrong */ struct sockaddr_dl *sdl = (struct sockaddr_dl *) ifa->ifa_addr; char *ether_format, *format_char; if (sdl != NULL && sdl->sdl_alen > 0) { if ((sdl->sdl_type == IFT_ETHER || sdl->sdl_type == IFT_L2VLAN || sdl->sdl_type == IFT_BRIDGE) && sdl->sdl_alen == ETHER_ADDR_LEN) { ether_format = ether_ntoa((struct ether_addr *)LLADDR(sdl)); if (f_ether != NULL && strcmp(f_ether, "dash") == 0) { for (format_char = strchr(ether_format, ':'); format_char != NULL; format_char = strchr(ether_format, ':')) *format_char = '-'; } printf("\tether %s\n", ether_format); } else { int n = sdl->sdl_nlen > 0 ? sdl->sdl_nlen + 1 : 0; printf("\tlladdr %s\n", link_ntoa(sdl) + n); } /* Best-effort (i.e. failures are silent) to get original * hardware address, as read by NIC driver at attach time. Only * applies to Ethernet NICs (IFT_ETHER). However, laggX * interfaces claim to be IFT_ETHER, and re-type their component * Ethernet NICs as IFT_IEEE8023ADLAG. So, check for both. If * the MAC is zeroed, then it's actually a lagg. */ if ((sdl->sdl_type == IFT_ETHER || sdl->sdl_type == IFT_IEEE8023ADLAG) && sdl->sdl_alen == ETHER_ADDR_LEN) { struct ifreq ifr; int sock_hw; int rc; static const u_char laggaddr[6] = {0}; strncpy(ifr.ifr_name, ifa->ifa_name, sizeof(ifr.ifr_name)); memcpy(&ifr.ifr_addr, ifa->ifa_addr, sizeof(ifa->ifa_addr->sa_len)); ifr.ifr_addr.sa_family = AF_LOCAL; if ((sock_hw = socket(AF_LOCAL, SOCK_DGRAM, 0)) < 0) { warn("socket(AF_LOCAL,SOCK_DGRAM)"); return; } rc = ioctl(sock_hw, SIOCGHWADDR, &ifr); close(sock_hw); if (rc != 0) { return; } /* * If this is definitely a lagg device or the hwaddr * matches the link addr, don't bother. */ if (memcmp(ifr.ifr_addr.sa_data, laggaddr, sdl->sdl_alen) == 0 || memcmp(ifr.ifr_addr.sa_data, LLADDR(sdl), sdl->sdl_alen) == 0) { return; } ether_format = ether_ntoa((const struct ether_addr *) &ifr.ifr_addr.sa_data); if (f_ether != NULL && strcmp(f_ether, "dash") == 0) { for (format_char = strchr(ether_format, ':'); format_char != NULL; format_char = strchr(ether_format, ':')) *format_char = '-'; } printf("\thwaddr %s\n", ether_format); } } }
static const char * fmt_sockaddr(struct sockaddr *sa, struct sockaddr *mask, int flags) { static char workbuf[128]; const char *cp; switch(sa->sa_family) { case AF_INET: { struct sockaddr_in *sockin = (struct sockaddr_in *)sa; if ((sockin->sin_addr.s_addr == INADDR_ANY) && mask && ntohl(((struct sockaddr_in *)mask)->sin_addr.s_addr) ==0L) cp = "default" ; else if (flags & RTF_HOST) cp = routename(sockin->sin_addr.s_addr); else if (mask) cp = netname(sockin->sin_addr.s_addr, ntohl(((struct sockaddr_in *)mask) ->sin_addr.s_addr)); else cp = netname(sockin->sin_addr.s_addr, 0L); break; } #ifdef INET6 case AF_INET6: { struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)sa; struct in6_addr *in6 = &sa6->sin6_addr; /* * XXX: This is a special workaround for KAME kernels. * sin6_scope_id field of SA should be set in the future. */ if (IN6_IS_ADDR_LINKLOCAL(in6) || IN6_IS_ADDR_MC_LINKLOCAL(in6) || IN6_IS_ADDR_MC_NODELOCAL(in6)) { /* XXX: override is ok? */ sa6->sin6_scope_id = (u_int32_t)ntohs(*(u_short *)&in6->s6_addr[2]); *(u_short *)&in6->s6_addr[2] = 0; } if (flags & RTF_HOST) cp = routename6(sa6); else if (mask) cp = netname6(sa6, &((struct sockaddr_in6 *)mask)->sin6_addr); else { cp = netname6(sa6, NULL); } break; } #endif /*INET6*/ case AF_IPX: { struct ipx_addr work = ((struct sockaddr_ipx *)sa)->sipx_addr; if (ipx_nullnet(satoipx_addr(work))) cp = "default"; else cp = ipx_print(sa); break; } case AF_APPLETALK: { if (!(flags & RTF_HOST) && mask) cp = atalk_print2(sa,mask,9); else cp = atalk_print(sa,11); break; } case AF_NETGRAPH: { printf("%s", ((struct sockaddr_ng *)sa)->sg_data); break; } case AF_LINK: { struct sockaddr_dl *sdl = (struct sockaddr_dl *)sa; if (sdl->sdl_nlen == 0 && sdl->sdl_alen == 0 && sdl->sdl_slen == 0) { (void) sprintf(workbuf, "link#%d", sdl->sdl_index); cp = workbuf; } else switch (sdl->sdl_type) { case IFT_ETHER: case IFT_L2VLAN: if (sdl->sdl_alen == ETHER_ADDR_LEN) { cp = ether_ntoa((struct ether_addr *) (sdl->sdl_data + sdl->sdl_nlen)); break; } /* FALLTHROUGH */ default: cp = link_ntoa(sdl); break; } break; } default: { u_char *s = (u_char *)sa->sa_data, *slim; char *cq, *cqlim; cq = workbuf; slim = sa->sa_len + (u_char *) sa; cqlim = cq + sizeof(workbuf) - 6; cq += sprintf(cq, "(%d)", sa->sa_family); while (s < slim && cq < cqlim) { cq += sprintf(cq, " %02x", *s++); if (s < slim) cq += sprintf(cq, "%02x", *s++); } cp = workbuf; } } return (cp); }
static int p_sockaddr(struct sockaddr *sa, int flags, int width) { char workbuf[128]; char *cp = workbuf; const char *cplim; int len = sizeof(workbuf); int count; switch(sa->sa_family) { case AF_LINK: { struct sockaddr_dl *sdl = (struct sockaddr_dl *)sa; if (sdl->sdl_nlen == 0 && sdl->sdl_alen == 0 && sdl->sdl_slen == 0) { snprintf(workbuf, sizeof(workbuf), "link#%d", sdl->sdl_index); } else { switch (sdl->sdl_type) { case IFT_ETHER: { int i; u_char *lla = (u_char *)sdl->sdl_data + sdl->sdl_nlen; cplim = ""; for (i = 0; i < sdl->sdl_alen; i++, lla++) { snprintf(cp, len, "%s%x", cplim, *lla); len -= strlen(cp); cp += strlen(cp); if (len <= 0) break; /* overflow */ cplim = ":"; } cp = workbuf; break; } default: cp = link_ntoa(sdl); break; } } break; } case AF_INET: { struct sockaddr_in *in = (struct sockaddr_in *)sa; if (in->sin_addr.s_addr == 0) { /* cp points to workbuf */ strncpy(cp, "default", len); } else cp = (flags & RTF_HOST) ? routename(sa) : netname(sa); break; } #ifdef INET6 case AF_INET6: { struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)sa; if (IN6_IS_ADDR_UNSPECIFIED(&in6->sin6_addr)) { /* cp points to workbuf */ strncpy(cp, "default", len); } else { cp = ((flags & RTF_HOST) ? routename(sa) : netname(sa)); } /* make sure numeric address is not truncated */ if (strchr(cp, ':') != NULL && (width < 0 || strlen(cp) > (size_t)width)) width = strlen(cp); break; } #endif /* INET6 */ default: { u_char *s = (u_char *)sa->sa_data, *slim; slim = sa->sa_len + (u_char *) sa; cplim = cp + sizeof(workbuf) - 6; snprintf(cp, len, "(%d)", sa->sa_family); len -= strlen(cp); cp += strlen(cp); if (len <= 0) { cp = workbuf; break; /* overflow */ } while (s < slim && cp < cplim) { snprintf(cp, len, " %02x", *s++); len -= strlen(cp); cp += strlen(cp); if (len <= 0) break; /* overflow */ if (s < slim) { snprintf(cp, len, "%02x", *s++); len -= strlen(cp); cp += strlen(cp); if (len <= 0) break; /* overflow */ } } cp = workbuf; } } if (width < 0) { count = printf("%s ", cp); } else { if (nflag || wflag) count = printf("%-*s ", width, cp); else count = printf("%-*.*s ", width, width, cp); } return(count); }
int sockaddr_snprintf(char * const sbuf, const size_t len, const char * const fmt, const struct sockaddr * const sa) { const void *a = NULL; char abuf[1024], nbuf[1024], *addr = NULL; char Abuf[1024], pbuf[32], *name = NULL, *port = NULL; char *ebuf = &sbuf[len - 1], *buf = sbuf; const char *ptr, *s; int p = -1; #ifdef HAVE_NETATALK_AT_H const struct sockaddr_at *sat = NULL; #endif const struct sockaddr_in *sin4 = NULL; const struct sockaddr_in6 *sin6 = NULL; const struct sockaddr_un *sun = NULL; #ifdef HAVE_NET_IF_DL_H const struct sockaddr_dl *sdl = NULL; char *w = NULL; #endif int na = 1; #define ADDC(c) do { if (buf < ebuf) *buf++ = c; else buf++; } \ while (/*CONSTCOND*/0) #define ADDS(p) do { for (s = p; *s; s++) ADDC(*s); } \ while (/*CONSTCOND*/0) #define ADDNA() do { if (na) ADDS("N/A"); } \ while (/*CONSTCOND*/0) switch (sa->sa_family) { case AF_UNSPEC: goto done; #ifdef HAVE_NETATALK_AT_H case AF_APPLETALK: sat = ((const struct sockaddr_at *)(const void *)sa); p = ntohs(sat->sat_port); (void)snprintf(addr = abuf, sizeof(abuf), "%u.%u", ntohs(sat->sat_addr.s_net), sat->sat_addr.s_node); (void)snprintf(port = pbuf, sizeof(pbuf), "%d", p); break; #endif case AF_LOCAL: sun = ((const struct sockaddr_un *)(const void *)sa); (void)strlcpy(addr = abuf, sun->sun_path, sizeof(abuf)); break; case AF_INET: sin4 = ((const struct sockaddr_in *)(const void *)sa); p = ntohs(sin4->sin_port); a = &sin4->sin_addr; break; case AF_INET6: sin6 = ((const struct sockaddr_in6 *)(const void *)sa); p = ntohs(sin6->sin6_port); a = &sin6->sin6_addr; break; #ifdef HAVE_NET_IF_DL_H case AF_LINK: sdl = ((const struct sockaddr_dl *)(const void *)sa); (void)strlcpy(addr = abuf, link_ntoa(sdl), sizeof(abuf)); if ((w = strchr(addr, ':')) != NULL) { *w++ = '\0'; addr = w; } break; #endif default: errno = EAFNOSUPPORT; return -1; } if (addr == abuf) name = addr; if (a && getnameinfo(sa, (socklen_t)SLEN(sa), addr = abuf, (unsigned int)sizeof(abuf), NULL, 0, NI_NUMERICHOST|NI_NUMERICSERV) != 0) return -1; for (ptr = fmt; *ptr; ptr++) { if (*ptr != '%') { ADDC(*ptr); continue; } next_char: switch (*++ptr) { case '?': na = 0; goto next_char; case 'a': ADDS(addr); break; case 'p': if (p != -1) { (void)snprintf(nbuf, sizeof(nbuf), "%d", p); ADDS(nbuf); } else ADDNA(); break; case 'f': (void)snprintf(nbuf, sizeof(nbuf), "%d", sa->sa_family); ADDS(nbuf); break; case 'l': (void)snprintf(nbuf, sizeof(nbuf), "%d", SLEN(sa)); ADDS(nbuf); break; case 'A': if (name) ADDS(name); else if (!a) ADDNA(); else { getnameinfo(sa, (socklen_t)SLEN(sa), name = Abuf, (unsigned int)sizeof(nbuf), NULL, 0, 0); ADDS(name); } break; case 'P': if (port) ADDS(port); else if (p == -1) ADDNA(); else { getnameinfo(sa, (socklen_t)SLEN(sa), NULL, 0, port = pbuf, (unsigned int)sizeof(pbuf), 0); ADDS(port); } break; case 'I': #ifdef HAVE_NET_IF_DL_H if (sdl && addr != abuf) { ADDS(abuf); } else #endif { ADDNA(); } break; case 'F': if (sin6) { (void)snprintf(nbuf, sizeof(nbuf), "%d", sin6->sin6_flowinfo); ADDS(nbuf); break; } else { ADDNA(); } break; case 'S': if (sin6) { (void)snprintf(nbuf, sizeof(nbuf), "%d", sin6->sin6_scope_id); ADDS(nbuf); break; } else { ADDNA(); } break; case 'R': #ifdef HAVE_NETATALK_AT_H if (sat) { const struct netrange *n = &sat->sat_range.r_netrange; (void)snprintf(nbuf, sizeof(nbuf), "%d:[%d,%d]", n->nr_phase , n->nr_firstnet, n->nr_lastnet); ADDS(nbuf); } else #endif { ADDNA(); } break; case 'D': switch (sa->sa_family) { #ifdef HAVE_NETATALK_AT_H case AF_APPLETALK: debug_at(nbuf, sizeof(nbuf), sat); break; #endif case AF_LOCAL: debug_un(nbuf, sizeof(nbuf), sun); break; case AF_INET: debug_in(nbuf, sizeof(nbuf), sin4); break; case AF_INET6: debug_in6(nbuf, sizeof(nbuf), sin6); break; #ifdef HAVE_NET_IF_DL_H case AF_LINK: debug_dl(nbuf, sizeof(nbuf), sdl); break; #endif default: abort(); } ADDS(nbuf); break; default: ADDC('%'); if (na == 0) ADDC('?'); if (*ptr == '\0') goto done; /*FALLTHROUGH*/ case '%': ADDC(*ptr); break; } na = 1; } done: if (buf < ebuf) *buf = '\0'; else if (len != 0) sbuf[len - 1] = '\0'; return (int)(buf - sbuf); }