1/* $KAME: ifmcstat.c,v 1.48 2006/11/15 05:13:59 itojun Exp $ */ 2 3/* 4 * Copyright (c) 2007-2009 Bruce Simpson. 5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 17 unchanged lines hidden (view full) --- 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 */ 32 33#include <sys/cdefs.h> |
34__FBSDID("$FreeBSD: head/usr.sbin/ifmcstat/ifmcstat.c 191672 2009-04-29 19:19:13Z bms $"); |
35 36#include <sys/types.h> 37#include <sys/param.h> 38#include <sys/sysctl.h> 39#include <sys/socket.h> 40#include <sys/queue.h> 41#include <sys/tree.h> 42 --- 119 unchanged lines hidden (view full) --- 162#endif /* WITH_KVM */ 163 164static int ifmcstat_getifmaddrs(void); 165#ifdef INET 166static void in_ifinfo(struct igmp_ifinfo *); 167static const char * inm_mode(u_int mode); 168#endif 169#ifdef INET6 |
170static void in6_ifinfo(struct mld_ifinfo *); |
171static const char * inet6_n2a(struct in6_addr *); 172#endif 173int main(int, char **); 174 175static void 176usage() 177{ 178 --- 258 unchanged lines hidden (view full) --- 437 ifmp = TAILQ_NEXT(&ifm, ifma_link); 438 } 439 } 440} 441 442#ifdef INET6 443 444static void |
445in6_ifinfo(struct mld_ifinfo *mli) 446{ 447 448 printf("\t"); 449 switch (mli->mli_version) { 450 case MLD_VERSION_1: 451 case MLD_VERSION_2: 452 printf("mldv%d", mli->mli_version); 453 break; 454 default: 455 printf("mldv?(%d)", mli->mli_version); 456 break; 457 } 458 printb(" flags", mli->mli_flags, "\020\1SILENT"); 459 if (mli->mli_version == MLD_VERSION_2) { 460 printf(" rv %u qi %u qri %u uri %u", 461 mli->mli_rv, mli->mli_qi, mli->mli_qri, mli->mli_uri); 462 } 463 if (vflag >= 2) { 464 printf(" v1timer %u v2timer %u", mli->mli_v1_timer, 465 mli->mli_v2_timer); 466 } 467 printf("\n"); 468} 469 470static void |
471if6_addrlist(struct ifaddr *ifap) 472{ |
473 struct ifnet ifnet; |
474 struct ifaddr ifa; 475 struct sockaddr sa; 476 struct in6_ifaddr if6a; 477 struct ifaddr *ifap0; 478 479 if (af && af != AF_INET6) 480 return; 481 ifap0 = ifap; 482 while (ifap) { 483 KREAD(ifap, &ifa, struct ifaddr); 484 if (ifa.ifa_addr == NULL) 485 goto nextifap; 486 KREAD(ifa.ifa_addr, &sa, struct sockaddr); 487 if (sa.sa_family != PF_INET6) 488 goto nextifap; 489 KREAD(ifap, &if6a, struct in6_ifaddr); 490 printf("\tinet6 %s\n", inet6_n2a(&if6a.ia_addr.sin6_addr)); |
491 /* 492 * Print per-link MLD information, if available. 493 */ 494 if (ifa.ifa_ifp != NULL) { 495 struct in6_ifextra ie; 496 struct mld_ifinfo mli; 497 498 KREAD(ifa.ifa_ifp, &ifnet, struct ifnet); 499 KREAD(ifnet.if_afdata[AF_INET6], &ie, 500 struct in6_ifextra); 501 if (ie.mld_ifinfo != NULL) { 502 KREAD(ie.mld_ifinfo, &mli, struct mld_ifinfo); 503 in6_ifinfo(&mli); 504 } 505 } |
506 nextifap: 507 ifap = ifa.ifa_link.tqe_next; 508 } 509 if (ifap0) { 510 struct ifnet ifnet; 511 struct ifmultiaddr ifm, *ifmp = 0; 512 struct sockaddr_dl sdl; 513 --- 366 unchanged lines hidden (view full) --- 880 881out_free: 882 free(buf); 883#undef MAX_SYSCTL_TRY 884} 885 886#endif /* INET */ 887 |
888#ifdef INET6 889/* 890 * Retrieve MLD per-group source filter mode and lists via sysctl. 891 * 892 * Note: The 128-bit IPv6 group addres needs to be segmented into 893 * 32-bit pieces for marshaling to sysctl. So the MIB name ends 894 * up looking like this: 895 * a.b.c.d.e.ifindex.g[0].g[1].g[2].g[3] 896 * Assumes that pgroup originated from the kernel, so its components 897 * are already in network-byte order. 898 */ 899static void 900in6m_print_sources_sysctl(uint32_t ifindex, struct in6_addr *pgroup) 901{ 902#define MAX_SYSCTL_TRY 5 903 char addrbuf[INET6_ADDRSTRLEN]; 904 int mib[10]; 905 int ntry = 0; 906 int *pi; 907 size_t mibsize; 908 size_t len; 909 size_t needed; 910 size_t cnt; 911 int i; 912 char *buf; 913 struct in6_addr *pina; 914 uint32_t *p; 915 uint32_t fmode; 916 const char *modestr; 917 918 mibsize = sizeof(mib) / sizeof(mib[0]); 919 if (sysctlnametomib("net.inet6.ip6.mcast.filters", mib, 920 &mibsize) == -1) { 921 perror("sysctlnametomib"); 922 return; 923 } 924 925 needed = 0; 926 mib[5] = ifindex; 927 pi = (int *)pgroup; 928 for (i = 0; i < 4; i++) 929 mib[6 + i] = *pi++; 930 931 mibsize = sizeof(mib) / sizeof(mib[0]); 932 do { 933 if (sysctl(mib, mibsize, NULL, &needed, NULL, 0) == -1) { 934 perror("sysctl net.inet6.ip6.mcast.filters"); 935 return; 936 } 937 if ((buf = malloc(needed)) == NULL) { 938 perror("malloc"); 939 return; 940 } 941 if (sysctl(mib, mibsize, buf, &needed, NULL, 0) == -1) { 942 if (errno != ENOMEM || ++ntry >= MAX_SYSCTL_TRY) { 943 perror("sysctl"); 944 goto out_free; 945 } 946 free(buf); 947 buf = NULL; 948 } 949 } while (buf == NULL); 950 951 len = needed; 952 if (len < sizeof(uint32_t)) { 953 perror("sysctl"); 954 goto out_free; 955 } 956 957 p = (uint32_t *)buf; 958 fmode = *p++; 959 len -= sizeof(uint32_t); 960 961 modestr = inm_mode(fmode); 962 if (modestr) 963 printf(" mode %s", modestr); 964 else 965 printf(" mode (%u)", fmode); 966 967 if (vflag == 0) 968 goto out_free; 969 970 cnt = len / sizeof(struct in6_addr); 971 pina = (struct in6_addr *)p; 972 973 for (i = 0; i < cnt; i++) { 974 if (i == 0) 975 printf(" srcs "); 976 inet_ntop(AF_INET6, (const char *)pina++, addrbuf, 977 INET6_ADDRSTRLEN); 978 fprintf(stdout, "%s%s", (i == 0 ? "" : ","), addrbuf); 979 len -= sizeof(struct in6_addr); 980 } 981 if (len > 0) { 982 fprintf(stderr, "warning: %u trailing bytes from %s\n", 983 (unsigned int)len, "net.inet6.ip6.mcast.filters"); 984 } 985 986out_free: 987 free(buf); 988#undef MAX_SYSCTL_TRY 989} 990#endif /* INET6 */ 991 |
992static int 993ifmcstat_getifmaddrs(void) 994{ 995 char thisifname[IFNAMSIZ]; 996 char addrbuf[NI_MAXHOST]; 997 struct ifaddrs *ifap, *ifa; 998 struct ifmaddrs *ifmap, *ifma; 999 sockunion_t lastifasa; --- 157 unchanged lines hidden (view full) --- 1157 len = sizeof(struct igmp_ifinfo); 1158 if (sysctl(mib, mibsize + 1, &igi, &len, NULL, 1159 0) == -1) { 1160 perror("sysctl net.inet.igmp.ifinfo"); 1161 goto next_ifnet; 1162 } 1163 in_ifinfo(&igi); 1164 } |
1165#endif /* INET */ 1166#ifdef INET6 1167 /* 1168 * Print per-link MLD information, if available. 1169 */ 1170 if (pifasa->sa.sa_family == AF_INET6) { 1171 struct mld_ifinfo mli; 1172 size_t mibsize, len; 1173 int mib[5]; 1174 1175 mibsize = sizeof(mib) / sizeof(mib[0]); 1176 if (sysctlnametomib("net.inet6.mld.ifinfo", 1177 mib, &mibsize) == -1) { 1178 perror("sysctlnametomib"); 1179 goto next_ifnet; 1180 } 1181 mib[mibsize] = thisifindex; 1182 len = sizeof(struct mld_ifinfo); 1183 if (sysctl(mib, mibsize + 1, &mli, &len, NULL, 1184 0) == -1) { 1185 perror("sysctl net.inet6.mld.ifinfo"); 1186 goto next_ifnet; 1187 } 1188 in6_ifinfo(&mli); 1189 } 1190#endif /* INET6 */ 1191#if defined(INET) || defined(INET6) |
1192next_ifnet: 1193#endif 1194 lastifasa = *pifasa; 1195 } 1196 1197 /* Print this group address. */ 1198#ifdef INET6 1199 if (pgsa->sa.sa_family == AF_INET6) { --- 10 unchanged lines hidden (view full) --- 1210 1211 fprintf(stdout, "\t\tgroup %s", addrbuf); 1212#ifdef INET 1213 if (pgsa->sa.sa_family == AF_INET) { 1214 inm_print_sources_sysctl(thisifindex, 1215 pgsa->sin.sin_addr); 1216 } 1217#endif |
1218#ifdef INET6 1219 if (pgsa->sa.sa_family == AF_INET6) { 1220 in6m_print_sources_sysctl(thisifindex, 1221 &pgsa->sin6.sin6_addr); 1222 } 1223#endif |
1224 fprintf(stdout, "\n"); 1225 1226 /* Link-layer mapping, if present. */ 1227 pllsa = (sockunion_t *)ifma->ifma_lladdr; 1228 if (pllsa != NULL) { 1229 error = getnameinfo(&pllsa->sa, pllsa->sa.sa_len, 1230 addrbuf, sizeof(addrbuf), NULL, 0, NI_NUMERICHOST); 1231 fprintf(stdout, "\t\t\tmcast-macaddr %s\n", addrbuf); 1232 } 1233 } 1234out: 1235 if (ifmap != NULL) 1236 freeifmaddrs(ifmap); 1237 if (ifap != NULL) 1238 freeifaddrs(ifap); 1239 1240 return (error); 1241} |