void ipv6ll_db_store(struct sockaddr_in6 *sin6, struct sockaddr_in6 *sin6mask, int dbflag, char *ifname) { /* * If linklocal, store a version that will match conf output * with no scope id, ifname in separate database field */ if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) || IN6_IS_ADDR_MC_LINKLOCAL(&sin6->sin6_addr) || IN6_IS_ADDR_MC_INTFACELOCAL(&sin6->sin6_addr)) { sin6->sin6_addr.s6_addr[2] = sin6->sin6_addr.s6_addr[3] = 0; sin6->sin6_scope_id = 0; db_delete_flag_x_ctl_data("ipv6linklocal", ifname, netname6(sin6, sin6mask)); if (dbflag != DB_X_REMOVE) db_insert_flag_x("ipv6linklocal", ifname, 0, dbflag, netname6(sin6, sin6mask)); } }
/* * Return the name of the network whose address is given. */ const char * netname(struct sockaddr *sa, struct sockaddr *mask) { switch (sa->sa_family) { case AF_INET: if (mask != NULL) return (netname4(satosin(sa)->sin_addr.s_addr, satosin(mask)->sin_addr.s_addr)); else return (netname4(satosin(sa)->sin_addr.s_addr, INADDR_ANY)); break; #ifdef INET6 case AF_INET6: return (netname6(satosin6(sa), satosin6(mask))); #endif /* INET6 */ default: return (NULL); } }
int ipv6ll_db_compare(struct sockaddr_in6 *sin6, struct sockaddr_in6 *sin6mask, char *ifname) { int count, scope; StringList *data; struct in6_addr store; if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) || IN6_IS_ADDR_MC_LINKLOCAL(&sin6->sin6_addr) || IN6_IS_ADDR_MC_INTFACELOCAL(&sin6->sin6_addr)) { /* * Save any scope or embedded scope. * The kernel does not set sin6_scope_id. * But if it ever does, we're already prepared. */ store.s6_addr[0] = sin6->sin6_addr.s6_addr[2]; store.s6_addr[1] = sin6->sin6_addr.s6_addr[3]; sin6->sin6_addr.s6_addr[2] = sin6->sin6_addr.s6_addr[3] = 0; scope = sin6->sin6_scope_id; sin6->sin6_scope_id = 0; data = sl_init(); db_select_flag_x_ctl_data(data, "ipv6linklocal", ifname, netname6(sin6, sin6mask)); count = data->sl_cur; sl_free(data, 1); /* restore any scope or embedded scope */ sin6->sin6_addr.s6_addr[2] = store.s6_addr[0]; sin6->sin6_addr.s6_addr[3] = store.s6_addr[1]; sin6->sin6_scope_id = scope; return(count); } return 1; }
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 print_addr(struct sockaddr *sa, struct sockaddr **rtinfo, struct if_data *ifd) { struct sockaddr_dl *sdl; struct sockaddr_in *sin; struct sockaddr_in6 *sin6; char *cp; int m, n; switch (sa->sa_family) { case AF_UNSPEC: printf("%-11.11s ", "none"); printf("%-17.17s ", "none"); break; case AF_INET: sin = (struct sockaddr_in *)sa; cp = netname4(sin->sin_addr.s_addr, ((struct sockaddr_in *)rtinfo[RTAX_NETMASK])->sin_addr.s_addr); if (vflag) n = strlen(cp) < 11 ? 11 : strlen(cp); else n = 11; printf("%-*.*s ", n, n, cp); cp = routename4(sin->sin_addr.s_addr); if (vflag) n = strlen(cp) < 17 ? 17 : strlen(cp); else n = 17; printf("%-*.*s ", n, n, cp); #if 0 if (aflag) { u_long multiaddr; struct in_multi inm; multiaddr = (u_long)LIST_FIRST(&ifaddr.in.ia_multiaddrs); while (multiaddr != 0) { kread(multiaddr, &inm, sizeof inm); printf("\n%25s %-17.17s ", "", routename4(inm.inm_addr.s_addr)); multiaddr = (u_long)LIST_NEXT(&inm, inm_list); } } #endif break; case AF_INET6: sin6 = (struct sockaddr_in6 *)sa; #ifdef __KAME__ if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { sin6->sin6_scope_id = ntohs(*(u_int16_t *) &sin6->sin6_addr.s6_addr[2]); sin6->sin6_addr.s6_addr[2] = 0; sin6->sin6_addr.s6_addr[3] = 0; } #endif cp = netname6(sin6, (struct sockaddr_in6 *)rtinfo[RTAX_NETMASK]); if (vflag) n = strlen(cp) < 11 ? 11 : strlen(cp); else n = 11; printf("%-*.*s ", n, n, cp); cp = routename6(sin6); if (vflag) n = strlen(cp) < 17 ? 17 : strlen(cp); else n = 17; printf("%-*.*s ", n, n, cp); #if 0 if (aflag) { u_long multiaddr; struct in6_multi inm; struct sockaddr_in6 m6; multiaddr = (u_long)LIST_FIRST(&ifaddr.in6.ia6_multiaddrs); while (multiaddr != 0) { kread(multiaddr, &inm, sizeof inm); memset(&m6, 0, sizeof(m6)); m6.sin6_len = sizeof(struct sockaddr_in6); m6.sin6_family = AF_INET6; m6.sin6_addr = inm.in6m_addr; #ifdef __KAME__ if (IN6_IS_ADDR_MC_LINKLOCAL(&m6.sin6_addr) || IN6_IS_ADDR_MC_INTFACELOCAL(&m6.sin6_addr)) { m6.sin6_scope_id = ntohs(*(u_int16_t *) &m6.sin6_addr.s6_addr[2]); m6.sin6_addr.s6_addr[2] = 0; m6.sin6_addr.s6_addr[3] = 0; } #endif cp = routename6(&m6); if (vflag) n = strlen(cp) < 17 ? 17 : strlen(cp); else n = 17; printf("\n%25s %-*.*s ", "", n, n, cp); multiaddr = (u_long)LIST_NEXT(&inm, in6m_entry); } } #endif break; case AF_LINK: sdl = (struct sockaddr_dl *)sa; m = printf("%-11.11s ", "<Link>"); if (sdl->sdl_type == IFT_ETHER || sdl->sdl_type == IFT_CARP || sdl->sdl_type == IFT_FDDI || sdl->sdl_type == IFT_ISO88025) printf("%-17.17s ", ether_ntoa((struct ether_addr *)LLADDR(sdl))); else { cp = (char *)LLADDR(sdl); n = sdl->sdl_alen; goto hexprint; } break; default: m = printf("(%d)", sa->sa_family); for (cp = sa->sa_len + (char *)sa; --cp > sa->sa_data && (*cp == 0);) {} n = cp - sa->sa_data + 1; cp = sa->sa_data; hexprint: while (--n >= 0) m += printf("%x%c", *cp++ & 0xff, n > 0 ? '.' : ' '); m = 30 - m; while (m-- > 0) putchar(' '); break; } if (bflag) { if (hflag) { char ibytes[FMT_SCALED_STRSIZE]; char obytes[FMT_SCALED_STRSIZE]; fmt_scaled(ifd->ifi_ibytes, ibytes); fmt_scaled(ifd->ifi_obytes, obytes); printf("%10s %10s", ibytes, obytes); } else printf("%10llu %10llu", ifd->ifi_ibytes, ifd->ifi_obytes); } else printf("%8llu %5llu %8llu %5llu %5llu", ifd->ifi_ipackets, ifd->ifi_ierrors, ifd->ifi_opackets, ifd->ifi_oerrors, ifd->ifi_collisions); if (tflag) printf(" %4d", 0 /* XXX ifnet.if_timer */); if (dflag) printf(" %4d", 0 /* XXX ifnet.if_snd.ifq_drops */); putchar('\n'); }
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); }
int conf_ifaddrs(FILE *output, char *ifname, int flags, int af) { struct ifaddrs *ifa, *ifap; struct sockaddr_in *sin, *sinmask, *sindest; struct sockaddr_in6 *sin6, *sin6mask, *sin6dest; struct in6_ifreq ifr6; int ippntd = 0; if (getifaddrs(&ifap) != 0) { printf("%% conf: getifaddrs failed: %s\n", strerror(errno)); return(-1); } /* * Cycle through getifaddrs for interfaces with our * desired name that sport af or (AF_INET | AF_INET6). * Print the IP and related information. */ for (ifa = ifap; ifa; ifa = ifa->ifa_next) { if (strncmp(ifname, ifa->ifa_name, IFNAMSIZ)) continue; switch (ifa->ifa_addr->sa_family) { int s; case AF_INET: if (af != AF_INET && af != 0) continue; sin = (struct sockaddr_in *)ifa->ifa_addr; if (sin->sin_addr.s_addr == INADDR_ANY) continue; sinmask = (struct sockaddr_in *)ifa->ifa_netmask; if (flags & IFF_POINTOPOINT) { sindest = (struct sockaddr_in *)ifa->ifa_dstaddr; fprintf(output, " ip %s", routename4(sin->sin_addr.s_addr)); fprintf(output, " %s", inet_ntoa(sindest->sin_addr)); } else if (flags & IFF_BROADCAST) { sindest = (struct sockaddr_in *)ifa->ifa_broadaddr; fprintf(output, " ip %s", netname4(sin->sin_addr.s_addr, sinmask)); /* * no reason to save the broadcast addr * if it is standard (this should always * be true unless someone has messed up their * network or they are playing around...) */ if (ntohl(sindest->sin_addr.s_addr) != in4_brdaddr(sin->sin_addr.s_addr, sinmask->sin_addr.s_addr)) fprintf(output, " %s", inet_ntoa(sindest->sin_addr)); } else { fprintf(output, " ip %s", netname4(sin->sin_addr.s_addr, sinmask)); } ippntd = 1; break; case AF_INET6: if (af != AF_INET6 && af != 0) continue; sin6 = (struct sockaddr_in6 *)ifa->ifa_addr; sin6mask = (struct sockaddr_in6 *)ifa->ifa_netmask; if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) continue; if (!ipv6ll_db_compare(sin6, sin6mask, ifname)) continue; in6_fillscopeid(sin6); /* get address flags */ memset(&ifr6, 0, sizeof(ifr6)); strlcpy(ifr6.ifr_name, ifname, sizeof(ifr6.ifr_name)); memcpy(&ifr6.ifr_addr, &sin6, sizeof(ifr6.ifr_addr)); s = socket(PF_INET6, SOCK_DGRAM, 0); if (s < 0) printf("%% conf_ifaddrs: socket: %s\n", strerror(errno)); if (ioctl(s, SIOCGIFAFLAG_IN6, (caddr_t)&ifr6) < 0) { if (errno != EADDRNOTAVAIL) printf("%% conf_ifaddrs: " \ "SIOCGIFAFLAG_IN6: %s\n", strerror(errno)); } else { /* skip autoconf addresses */ if (ifr6.ifr_ifru.ifru_flags6 & IN6_IFF_AUTOCONF) continue; } if (flags & IFF_POINTOPOINT) { fprintf(output, " ip %s", routename6(sin6)); sin6dest = (struct sockaddr_in6 *)ifa->ifa_dstaddr; in6_fillscopeid(sin6dest); fprintf(output, " %s", routename6(sin6dest)); } else { fprintf(output, " ip %s", netname6(sin6, sin6mask)); } ippntd = 1; break; default: continue; } fprintf(output, "\n"); } freeifaddrs(ifap); return ippntd; }
static void encap_print(struct rtentry *rt) { struct sockaddr_encap sen1, sen2, sen3; struct ipsec_policy ipo; struct sockaddr_in6 s61, s62; bcopy(kgetsa(rt_key(rt)), &sen1, sizeof(sen1)); bcopy(kgetsa(rt_mask(rt)), &sen2, sizeof(sen2)); bcopy(kgetsa(rt->rt_gateway), &sen3, sizeof(sen3)); if (sen1.sen_type == SENT_IP4) { printf("%-18s %-5u ", netname4(sen1.sen_ip_src.s_addr, sen2.sen_ip_src.s_addr), ntohs(sen1.sen_sport)); printf("%-18s %-5u %-5u ", netname4(sen1.sen_ip_dst.s_addr, sen2.sen_ip_dst.s_addr), ntohs(sen1.sen_dport), sen1.sen_proto); } if (sen1.sen_type == SENT_IP6) { bzero(&s61, sizeof(s61)); bzero(&s62, sizeof(s62)); s61.sin6_family = s62.sin6_family = AF_INET6; s61.sin6_len = s62.sin6_len = sizeof(s61); bcopy(&sen1.sen_ip6_src, &s61.sin6_addr, sizeof(struct in6_addr)); #ifdef __KAME__ if (IN6_IS_ADDR_LINKLOCAL(&s61.sin6_addr) || IN6_IS_ADDR_MC_LINKLOCAL(&s61.sin6_addr) || IN6_IS_ADDR_MC_INTFACELOCAL(&s61.sin6_addr)) { s61.sin6_scope_id = ((u_int16_t)s61.sin6_addr.s6_addr[2] << 8) | s61.sin6_addr.s6_addr[3]; s61.sin6_addr.s6_addr[2] = s61.sin6_addr.s6_addr[3] = 0; } #endif bcopy(&sen2.sen_ip6_src, &s62.sin6_addr, sizeof(struct in6_addr)); #ifdef __KAME__ if (IN6_IS_ADDR_LINKLOCAL(&s62.sin6_addr) || IN6_IS_ADDR_MC_LINKLOCAL(&s62.sin6_addr) || IN6_IS_ADDR_MC_INTFACELOCAL(&s62.sin6_addr)) { s62.sin6_scope_id = ((u_int16_t)s62.sin6_addr.s6_addr[2] << 8) | s62.sin6_addr.s6_addr[3]; s62.sin6_addr.s6_addr[2] = s62.sin6_addr.s6_addr[3] = 0; } #endif printf("%-42s %-5u ", netname6(&s61, &s62), ntohs(sen1.sen_ip6_sport)); bzero(&s61, sizeof(s61)); bzero(&s62, sizeof(s62)); s61.sin6_family = s62.sin6_family = AF_INET6; s61.sin6_len = s62.sin6_len = sizeof(s61); bcopy(&sen1.sen_ip6_dst, &s61.sin6_addr, sizeof(struct in6_addr)); #ifdef __KAME__ if (IN6_IS_ADDR_LINKLOCAL(&s61.sin6_addr) || IN6_IS_ADDR_MC_LINKLOCAL(&s61.sin6_addr) || IN6_IS_ADDR_MC_INTFACELOCAL(&s61.sin6_addr)) { s61.sin6_scope_id = ((u_int16_t)s61.sin6_addr.s6_addr[2] << 8) | s61.sin6_addr.s6_addr[3]; s61.sin6_addr.s6_addr[2] = s61.sin6_addr.s6_addr[3] = 0; } #endif bcopy(&sen2.sen_ip6_dst, &s62.sin6_addr, sizeof(struct in6_addr)); #ifdef __KAME__ if (IN6_IS_ADDR_LINKLOCAL(&s62.sin6_addr) || IN6_IS_ADDR_MC_LINKLOCAL(&s62.sin6_addr) || IN6_IS_ADDR_MC_INTFACELOCAL(&s62.sin6_addr)) { s62.sin6_scope_id = ((u_int16_t)s62.sin6_addr.s6_addr[2] << 8) | s62.sin6_addr.s6_addr[3]; s62.sin6_addr.s6_addr[2] = s62.sin6_addr.s6_addr[3] = 0; } #endif printf("%-42s %-5u %-5u ", netname6(&s61, &s62), ntohs(sen1.sen_ip6_dport), sen1.sen_ip6_proto); } if (sen3.sen_type == SENT_IPSP) { char hostn[NI_MAXHOST]; kread((u_long)sen3.sen_ipsp, &ipo, sizeof(ipo)); if (getnameinfo(&ipo.ipo_dst.sa, ipo.ipo_dst.sa.sa_len, hostn, NI_MAXHOST, NULL, 0, NI_NUMERICHOST) != 0) strlcpy (hostn, "none", NI_MAXHOST); printf("%s", hostn); printf("/%-u", ipo.ipo_sproto); switch (ipo.ipo_type) { case IPSP_IPSEC_REQUIRE: printf("/require"); break; case IPSP_IPSEC_ACQUIRE: printf("/acquire"); break; case IPSP_IPSEC_USE: printf("/use"); break; case IPSP_IPSEC_DONTACQ: printf("/dontacq"); break; case IPSP_PERMIT: printf("/bypass"); break; case IPSP_DENY: printf("/deny"); break; default: printf("/<unknown type!>"); break; } if ((ipo.ipo_addr.sen_type == SENT_IP4 && ipo.ipo_addr.sen_direction == IPSP_DIRECTION_IN) || (ipo.ipo_addr.sen_type == SENT_IP6 && ipo.ipo_addr.sen_ip6_direction == IPSP_DIRECTION_IN)) printf("/in\n"); else if ((ipo.ipo_addr.sen_type == SENT_IP4 && ipo.ipo_addr.sen_direction == IPSP_DIRECTION_OUT) || (ipo.ipo_addr.sen_type == SENT_IP6 && ipo.ipo_addr.sen_ip6_direction == IPSP_DIRECTION_OUT)) printf("/out\n"); else printf("/<unknown>\n"); } }
int conf_ifaddrs(FILE *output, char *ifname, int flags, int af) { struct ifaddrs *ifa, *ifap; struct sockaddr_in *sin, *sinmask, *sindest; struct sockaddr_in6 *sin6, *sin6mask, *sin6dest; int ippntd = 0; if (getifaddrs(&ifap) != 0) { printf("%% conf: getifaddrs failed: %s\n", strerror(errno)); return(-1); } /* * Cycle through getifaddrs for interfaces with our * desired name that sport AF_INET | AF_INET6. Print * the IP and related information. */ for (ifa = ifap; ifa; ifa = ifa->ifa_next) { if (strncmp(ifname, ifa->ifa_name, IFNAMSIZ)) continue; switch (ifa->ifa_addr->sa_family) { case AF_INET: if (af != AF_INET && af != 0) continue; sin = (struct sockaddr_in *)ifa->ifa_addr; if (sin->sin_addr.s_addr == 0) continue; sinmask = (struct sockaddr_in *)ifa->ifa_netmask; if (flags & IFF_POINTOPOINT) { sindest = (struct sockaddr_in *)ifa->ifa_dstaddr; fprintf(output, " ip %s", routename4(sin->sin_addr.s_addr)); fprintf(output, " %s", inet_ntoa(sindest->sin_addr)); } else if (flags & IFF_BROADCAST) { sindest = (struct sockaddr_in *)ifa->ifa_broadaddr; fprintf(output, " ip %s", netname4(sin->sin_addr.s_addr, sinmask)); /* * no reason to save the broadcast addr * if it is standard (this should always * be true unless someone has messed up their * network or they are playing around...) */ if (ntohl(sindest->sin_addr.s_addr) != in4_brdaddr(sin->sin_addr.s_addr, sinmask->sin_addr.s_addr)) fprintf(output, " %s", inet_ntoa(sindest->sin_addr)); } else { fprintf(output, " ip %s", netname4(sin->sin_addr.s_addr, sinmask)); } ippntd = 1; break; case AF_INET6: if (af != AF_INET6 && af != 0) continue; sin6 = (struct sockaddr_in6 *)ifa->ifa_addr; sin6mask = (struct sockaddr_in6 *)ifa->ifa_netmask; if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) continue; if (!ipv6ll_db_compare(sin6, sin6mask, ifname)) continue; in6_fillscopeid(sin6); if (flags & IFF_POINTOPOINT) { fprintf(output, " ip %s", routename6(sin6)); sin6dest = (struct sockaddr_in6 *)ifa->ifa_dstaddr; in6_fillscopeid(sin6dest); fprintf(output, " %s", routename6(sin6dest)); } else { fprintf(output, " ip %s", netname6(sin6, sin6mask)); } ippntd = 1; break; default: continue; } fprintf(output, "\n"); } freeifaddrs(ifap); return ippntd; }
int show_int(int argc, char **argv) { struct ifaddrs *ifap, *ifa; struct if_nameindex *ifn_list, *ifnp; struct ifreq ifr, ifrdesc; struct if_data if_data; struct sockaddr_in *sin = NULL, *sinmask = NULL, *sindest; struct sockaddr_in6 *sin6 = NULL, *sin6mask = NULL, *sin6dest; struct timeval tv; short tmp; int ifs, br, flags, days, hours, mins, pntd; int ippntd = 0; int physrt, physttl; time_t c; char *type, *lladdr, *ifname = NULL; char tmp_str[512], tmp_str2[512], ifdescr[IFDESCRSIZE]; if (argc == 3) ifname = argv[2]; /* * Show all interfaces when no ifname specified. */ if (ifname == NULL) { if ((ifn_list = if_nameindex()) == NULL) { printf("%% show_int: if_nameindex failed\n"); return 0; } for (ifnp = ifn_list; ifnp->if_name != NULL; ifnp++) { char *args[] = { NULL, NULL, ifnp->if_name }; show_int(3, args); } if_freenameindex(ifn_list); return(0); } else if (!is_valid_ifname(ifname)) { printf("%% interface %s not found\n", ifname); return(1); } if ((ifs = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { printf("%% show_int: %s\n", strerror(errno)); return(1); } if (!(br = is_bridge(ifs, (char *)ifname))) br = 0; strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); /* * Show up/down status and last change time */ flags = get_ifflags(ifname, ifs); ifr.ifr_data = (caddr_t)&if_data; if (ioctl(ifs, SIOCGIFDATA, (caddr_t)&ifr) < 0) { printf("%% show_int: SIOCGIFDATA: %s\n", strerror(errno)); close(ifs); return(1); } printf("%% %s", ifname); /* description */ memset(&ifrdesc, 0, sizeof(ifrdesc)); strlcpy(ifrdesc.ifr_name, ifname, sizeof(ifrdesc.ifr_name)); ifrdesc.ifr_data = (caddr_t)&ifdescr; if (ioctl(ifs, SIOCGIFDESCR, &ifrdesc) == 0 && strlen(ifrdesc.ifr_data)) printf(" (%s)", ifrdesc.ifr_data); putchar('\n'); printf(" %s is %s", br ? "Bridge" : "Interface", flags & IFF_UP ? "up" : "down"); if (if_data.ifi_lastchange.tv_sec) { gettimeofday(&tv, (struct timezone *)0); c = difftime(tv.tv_sec, if_data.ifi_lastchange.tv_sec); days = c / (24 * 60 * 60); c %= (24 * 60 * 60); hours = c / (60 * 60); c %= (60 * 60); mins = c / 60; c %= 60; printf(" (last change "); if (days) printf("%id ", days); printf("%02i:%02i:%02i)", hours, mins, (int)c); } printf(", protocol is %s", flags & IFF_RUNNING ? "up" : "down"); printf("\n"); type = iftype(if_data.ifi_type); printf(" Interface type %s", type); if (flags & IFF_BROADCAST) printf(" (Broadcast)"); else if (flags & IFF_POINTOPOINT) printf(" (PointToPoint)"); if ((lladdr = get_hwdaddr(ifname)) != NULL) printf(", hardware address %s", lladdr); printf("\n"); show_trunk(ifs, ifname); media_status(ifs, ifname, " Media type "); /* * Print interface IP address, and broadcast or * destination if available. But, don't print broadcast * if it is what we would expect given the ip and netmask! */ if (getifaddrs(&ifap) != 0) { printf("%% show_int: getifaddrs failed: %s\n", strerror(errno)); return(1); } /* * Cycle through getifaddrs for interfaces with our * desired name that sport AF_INET, print the IP and * related information. */ for (ifa = ifap; ifa; ifa = ifa->ifa_next) { if (strncmp(ifname, ifa->ifa_name, IFNAMSIZ)) continue; switch (ifa->ifa_addr->sa_family) { case AF_INET: sin = (struct sockaddr_in *)ifa->ifa_addr; sinmask = (struct sockaddr_in *)ifa->ifa_netmask; if (sin->sin_addr.s_addr == INADDR_ANY) continue; break; case AF_INET6: sin6 = (struct sockaddr_in6 *)ifa->ifa_addr; sin6mask = (struct sockaddr_in6 *)ifa->ifa_netmask; if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) continue; in6_fillscopeid(sin6); break; default: continue; } if (!ippntd) printf(" Internet address"); printf("%s %s", ippntd ? "," : "", ifa->ifa_addr->sa_family == AF_INET ? netname4(sin->sin_addr.s_addr, sinmask) : netname6(sin6, sin6mask)); ippntd = 1; switch (ifa->ifa_addr->sa_family) { case AF_INET: if (flags & IFF_POINTOPOINT) { sindest = (struct sockaddr_in *) ifa->ifa_dstaddr; printf(" (Destination %s)", routename4(sindest->sin_addr.s_addr)); } else if (flags & IFF_BROADCAST) { sindest = (struct sockaddr_in *) ifa->ifa_broadaddr; /* * no reason to show the broadcast addr * if it is standard (this should always * be true unless someone has messed up their * network or they are playing around...) */ if (ntohl(sindest->sin_addr.s_addr) != in4_brdaddr(sin->sin_addr.s_addr, sinmask->sin_addr.s_addr) && ntohl(sindest->sin_addr.s_addr) != INADDR_ANY) printf(" (Broadcast %s)", inet_ntoa(sindest->sin_addr)); } break; case AF_INET6: if (flags & IFF_POINTOPOINT) { sin6dest = (struct sockaddr_in6 *) ifa->ifa_dstaddr; in6_fillscopeid(sin6dest); printf(" (Destination %s)", routename6(sin6dest)); } break; default: printf(" unknown"); break; } } if (ippntd) { printf("\n"); } freeifaddrs(ifap); if (!br) { if (phys_status(ifs, ifname, tmp_str, tmp_str2, sizeof(tmp_str), sizeof(tmp_str2)) > 0) { printf(" Tunnel source %s destination %s", tmp_str, tmp_str2); if (((physrt = get_physrtable(ifs, ifname)) != 0)) printf(" destination rdomain %i", physrt); if (((physttl = get_physttl(ifs, ifname)) != 0)) printf(" ttl %i", physttl); printf("\n"); } carp_state(ifs, ifname); printf(" "); show_vnet_parent(ifs, ifname); if (ioctl(ifs, SIOCGIFRDOMAIN, (caddr_t)&ifr) != -1) printf(" rdomain %d,", ifr.ifr_rdomainid); /* * Display MTU, line rate */ printf(" MTU %u bytes", if_data.ifi_mtu); if (ioctl(ifs, SIOCGIFHARDMTU, (caddr_t)&ifr) != -1) { if (ifr.ifr_hardmtu) printf(" (hardmtu %u)", ifr.ifr_hardmtu); } if (if_data.ifi_baudrate) printf(", Line Rate %qu %s", MBPS(if_data.ifi_baudrate) ? MBPS(if_data.ifi_baudrate) : if_data.ifi_baudrate / 1000, MBPS(if_data.ifi_baudrate) ? "Mbps" : "Kbps"); printf("\n"); } if (get_nwinfo(ifname, tmp_str, sizeof(tmp_str), NWID) != 0) { printf(" SSID %s", tmp_str); if(get_nwinfo(ifname, tmp_str, sizeof(tmp_str), NWKEY) != 0) printf(", key %s", tmp_str); if ((tmp = get_nwinfo(ifname, tmp_str, sizeof(tmp_str), POWERSAVE)) != 0) printf(", powersaving (%s ms)\n", tmp_str); printf("\n"); } /* * Display remaining info from if_data structure */ printf(" %qu packets input, %qu bytes, %qu errors, %qu drops\n", if_data.ifi_ipackets, if_data.ifi_ibytes, if_data.ifi_ierrors, if_data.ifi_iqdrops); printf(" %qu packets output, %qu bytes, %qu errors, %qu unsupported\n", if_data.ifi_opackets, if_data.ifi_obytes, if_data.ifi_oerrors, if_data.ifi_noproto); if (if_data.ifi_ibytes && if_data.ifi_ipackets && (if_data.ifi_ibytes / if_data.ifi_ipackets) >= ETHERMIN) { /* < ETHERMIN means byte counter probably rolled over */ printf(" %qu input", if_data.ifi_ibytes / if_data.ifi_ipackets); pntd = 1; } else pntd = 0; if (if_data.ifi_obytes && if_data.ifi_opackets && (if_data.ifi_obytes / if_data.ifi_opackets) >= ETHERMIN) { /* < ETHERMIN means byte counter probably rolled over */ printf("%s%qu output", pntd ? ", " : " ", if_data.ifi_obytes / if_data.ifi_opackets); pntd = 1; } if (pntd) printf(" (average bytes/packet)\n"); switch(if_data.ifi_type) { /* * These appear to be the only interface types to increase collision * count in the OpenBSD 3.2 kernel. */ case IFT_ETHER: case IFT_SLIP: case IFT_PROPVIRTUAL: case IFT_IEEE80211: printf(" %qu collisions\n", if_data.ifi_collisions); break; default: break; } if(verbose) { if (flags) { printf(" Flags:\n "); bprintf(stdout, flags, ifnetflags); printf("\n"); } printifhwfeatures(ifs, ifname); if (br) { if ((tmp = bridge_list(ifs, ifname, " ", tmp_str, sizeof(tmp_str), SHOW_STPSTATE))) { printf(" STP member state%s:\n", tmp > 1 ? "s" : ""); printf("%s", tmp_str); } bridge_addrs(ifs, ifname, " ", " "); } media_supported(ifs, ifname, " ", " "); } close(ifs); return(0); }