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 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. Neither the name of the project nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 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>
| 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 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. Neither the name of the project nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 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 189592 2009-03-09 17:53:05Z bms $");
| 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 43#include <net/if.h> 44#include <net/if_var.h> 45#include <net/if_types.h> 46#include <net/if_dl.h> 47#include <net/route.h> 48 49#include <netinet/in.h> 50#include <netinet/in_var.h> 51#include <netinet/in_systm.h> 52#include <netinet/ip.h> 53#include <netinet/igmp.h> 54#define KERNEL 55# include <netinet/if_ether.h> 56#undef KERNEL 57#define _KERNEL 58#define SYSCTL_DECL(x) 59# include <netinet/igmp_var.h> 60#undef SYSCTL_DECL 61#undef _KERNEL 62 63#ifdef INET6 64#include <netinet/icmp6.h> 65#define _KERNEL 66# include <netinet6/mld6_var.h> 67#undef _KERNEL 68#endif /* INET6 */ 69 70#include <arpa/inet.h> 71#include <netdb.h> 72 73#include <stddef.h> 74#include <stdarg.h> 75#include <stdlib.h> 76#include <stdint.h> 77#include <stdio.h> 78#include <stdlib.h> 79#include <string.h> 80 81#include <ctype.h> 82#include <err.h> 83#include <errno.h> 84#include <fcntl.h> 85#include <kvm.h> 86#include <limits.h> 87#include <ifaddrs.h> 88#include <nlist.h> 89#include <sysexits.h> 90#include <unistd.h> 91 92/* XXX: This file currently assumes INET and KVM support in the base system. */ 93#ifndef INET 94#define INET 95#endif 96 97extern void printb(const char *, unsigned int, const char *); 98 99union sockunion { 100 struct sockaddr_storage ss; 101 struct sockaddr sa; 102 struct sockaddr_dl sdl; 103#ifdef INET 104 struct sockaddr_in sin; 105#endif 106#ifdef INET6 107 struct sockaddr_in6 sin6; 108#endif 109}; 110typedef union sockunion sockunion_t; 111 112uint32_t ifindex = 0; 113int af = AF_UNSPEC; 114#ifdef WITH_KVM 115int Kflag = 0; 116#endif 117int vflag = 0; 118 119#define sa_equal(a1, a2) \ 120 (bcmp((a1), (a2), ((a1))->sa_len) == 0) 121 122#define sa_dl_equal(a1, a2) \ 123 ((((struct sockaddr_dl *)(a1))->sdl_len == \ 124 ((struct sockaddr_dl *)(a2))->sdl_len) && \ 125 (bcmp(LLADDR((struct sockaddr_dl *)(a1)), \ 126 LLADDR((struct sockaddr_dl *)(a2)), \ 127 ((struct sockaddr_dl *)(a1))->sdl_alen) == 0)) 128 129/* 130 * Most of the code in this utility is to support the use of KVM for 131 * post-mortem debugging of the multicast code. 132 */ 133#ifdef WITH_KVM 134 135#ifdef INET 136static void if_addrlist(struct ifaddr *); 137static struct in_multi * 138 in_multientry(struct in_multi *); 139#endif /* INET */ 140 141#ifdef INET6 142static void if6_addrlist(struct ifaddr *); 143static struct in6_multi * 144 in6_multientry(struct in6_multi *); 145#endif /* INET6 */ 146 147static void kread(u_long, void *, int); 148static void ll_addrlist(struct ifaddr *); 149 150static int ifmcstat_kvm(const char *kernel, const char *core); 151 152#define KREAD(addr, buf, type) \ 153 kread((u_long)addr, (void *)buf, sizeof(type)) 154 155kvm_t *kvmd; 156struct nlist nl[] = { 157 { "_ifnet", 0, 0, 0, 0, }, 158 { "", 0, 0, 0, 0, }, 159}; 160#define N_IFNET 0 161 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
| 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 43#include <net/if.h> 44#include <net/if_var.h> 45#include <net/if_types.h> 46#include <net/if_dl.h> 47#include <net/route.h> 48 49#include <netinet/in.h> 50#include <netinet/in_var.h> 51#include <netinet/in_systm.h> 52#include <netinet/ip.h> 53#include <netinet/igmp.h> 54#define KERNEL 55# include <netinet/if_ether.h> 56#undef KERNEL 57#define _KERNEL 58#define SYSCTL_DECL(x) 59# include <netinet/igmp_var.h> 60#undef SYSCTL_DECL 61#undef _KERNEL 62 63#ifdef INET6 64#include <netinet/icmp6.h> 65#define _KERNEL 66# include <netinet6/mld6_var.h> 67#undef _KERNEL 68#endif /* INET6 */ 69 70#include <arpa/inet.h> 71#include <netdb.h> 72 73#include <stddef.h> 74#include <stdarg.h> 75#include <stdlib.h> 76#include <stdint.h> 77#include <stdio.h> 78#include <stdlib.h> 79#include <string.h> 80 81#include <ctype.h> 82#include <err.h> 83#include <errno.h> 84#include <fcntl.h> 85#include <kvm.h> 86#include <limits.h> 87#include <ifaddrs.h> 88#include <nlist.h> 89#include <sysexits.h> 90#include <unistd.h> 91 92/* XXX: This file currently assumes INET and KVM support in the base system. */ 93#ifndef INET 94#define INET 95#endif 96 97extern void printb(const char *, unsigned int, const char *); 98 99union sockunion { 100 struct sockaddr_storage ss; 101 struct sockaddr sa; 102 struct sockaddr_dl sdl; 103#ifdef INET 104 struct sockaddr_in sin; 105#endif 106#ifdef INET6 107 struct sockaddr_in6 sin6; 108#endif 109}; 110typedef union sockunion sockunion_t; 111 112uint32_t ifindex = 0; 113int af = AF_UNSPEC; 114#ifdef WITH_KVM 115int Kflag = 0; 116#endif 117int vflag = 0; 118 119#define sa_equal(a1, a2) \ 120 (bcmp((a1), (a2), ((a1))->sa_len) == 0) 121 122#define sa_dl_equal(a1, a2) \ 123 ((((struct sockaddr_dl *)(a1))->sdl_len == \ 124 ((struct sockaddr_dl *)(a2))->sdl_len) && \ 125 (bcmp(LLADDR((struct sockaddr_dl *)(a1)), \ 126 LLADDR((struct sockaddr_dl *)(a2)), \ 127 ((struct sockaddr_dl *)(a1))->sdl_alen) == 0)) 128 129/* 130 * Most of the code in this utility is to support the use of KVM for 131 * post-mortem debugging of the multicast code. 132 */ 133#ifdef WITH_KVM 134 135#ifdef INET 136static void if_addrlist(struct ifaddr *); 137static struct in_multi * 138 in_multientry(struct in_multi *); 139#endif /* INET */ 140 141#ifdef INET6 142static void if6_addrlist(struct ifaddr *); 143static struct in6_multi * 144 in6_multientry(struct in6_multi *); 145#endif /* INET6 */ 146 147static void kread(u_long, void *, int); 148static void ll_addrlist(struct ifaddr *); 149 150static int ifmcstat_kvm(const char *kernel, const char *core); 151 152#define KREAD(addr, buf, type) \ 153 kread((u_long)addr, (void *)buf, sizeof(type)) 154 155kvm_t *kvmd; 156struct nlist nl[] = { 157 { "_ifnet", 0, 0, 0, 0, }, 158 { "", 0, 0, 0, 0, }, 159}; 160#define N_IFNET 0 161 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 *);
|
170static const char * inet6_n2a(struct in6_addr *); 171#endif 172int main(int, char **); 173 174static void 175usage() 176{ 177 178 fprintf(stderr, 179 "usage: ifmcstat [-i interface] [-f address family]" 180 " [-v]" 181#ifdef WITH_KVM 182 " [-K] [-M core] [-N system]" 183#endif 184 "\n"); 185 exit(EX_USAGE); 186} 187 188static const char *options = "i:f:vM:N:" 189#ifdef WITH_KVM 190 "K" 191#endif 192 ; 193 194int 195main(int argc, char **argv) 196{ 197 int c, error; 198#ifdef WITH_KVM 199 const char *kernel = NULL; 200 const char *core = NULL; 201#endif 202 203 while ((c = getopt(argc, argv, options)) != -1) { 204 switch (c) { 205 case 'i': 206 if ((ifindex = if_nametoindex(optarg)) == 0) { 207 fprintf(stderr, "%s: unknown interface\n", 208 optarg); 209 exit(EX_NOHOST); 210 } 211 break; 212 213 case 'f': 214#ifdef INET 215 if (strcmp(optarg, "inet") == 0) { 216 af = AF_INET; 217 break; 218 } 219#endif 220#ifdef INET6 221 if (strcmp(optarg, "inet6") == 0) { 222 af = AF_INET6; 223 break; 224 } 225#endif 226 if (strcmp(optarg, "link") == 0) { 227 af = AF_LINK; 228 break; 229 } 230 fprintf(stderr, "%s: unknown address family\n", optarg); 231 exit(EX_USAGE); 232 /*NOTREACHED*/ 233 break; 234 235#ifdef WITH_KVM 236 case 'K': 237 ++Kflag; 238 break; 239#endif 240 241 case 'v': 242 ++vflag; 243 break; 244 245#ifdef WITH_KVM 246 case 'M': 247 core = strdup(optarg); 248 break; 249 250 case 'N': 251 kernel = strdup(optarg); 252 break; 253#endif 254 255 default: 256 usage(); 257 break; 258 /*NOTREACHED*/ 259 } 260 } 261 262 if (af == AF_LINK && vflag) 263 usage(); 264 265#ifdef WITH_KVM 266 if (!Kflag) 267 error = ifmcstat_kvm(kernel, core); 268 /* 269 * If KVM failed, and user did not explicitly specify a core file, 270 * or force KVM backend to be disabled, try the sysctl backend. 271 */ 272 if (Kflag || (error != 0 && (core == NULL && kernel == NULL))) 273#endif 274 error = ifmcstat_getifmaddrs(); 275 if (error != 0) 276 exit(EX_OSERR); 277 278 exit(EX_OK); 279 /*NOTREACHED*/ 280} 281 282#ifdef INET 283 284static void 285in_ifinfo(struct igmp_ifinfo *igi) 286{ 287 288 printf("\t"); 289 switch (igi->igi_version) { 290 case IGMP_VERSION_1: 291 case IGMP_VERSION_2: 292 case IGMP_VERSION_3: 293 printf("igmpv%d", igi->igi_version); 294 break; 295 default: 296 printf("igmpv?(%d)", igi->igi_version); 297 break; 298 } 299 printb(" flags", igi->igi_flags, "\020\1SILENT\2LOOPBACK"); 300 if (igi->igi_version == IGMP_VERSION_3) { 301 printf(" rv %u qi %u qri %u uri %u", 302 igi->igi_rv, igi->igi_qi, igi->igi_qri, igi->igi_uri); 303 } 304 if (vflag >= 2) { 305 printf(" v1timer %u v2timer %u v3timer %u", 306 igi->igi_v1_timer, igi->igi_v2_timer, igi->igi_v3_timer); 307 } 308 printf("\n"); 309} 310 311static const char *inm_modes[] = { 312 "undefined", 313 "include", 314 "exclude", 315}; 316 317static const char * 318inm_mode(u_int mode) 319{ 320 321 if (mode >= MCAST_UNDEFINED && mode <= MCAST_EXCLUDE) 322 return (inm_modes[mode]); 323 return (NULL); 324} 325 326#endif /* INET */ 327 328#ifdef WITH_KVM 329 330static int 331ifmcstat_kvm(const char *kernel, const char *core) 332{ 333 char buf[_POSIX2_LINE_MAX], ifname[IFNAMSIZ]; 334 struct ifnet *ifp, *nifp, ifnet; 335 336 if ((kvmd = kvm_openfiles(kernel, core, NULL, O_RDONLY, buf)) == 337 NULL) { 338 perror("kvm_openfiles"); 339 return (-1); 340 } 341 if (kvm_nlist(kvmd, nl) < 0) { 342 perror("kvm_nlist"); 343 return (-1); 344 } 345 if (nl[N_IFNET].n_value == 0) { 346 printf("symbol %s not found\n", nl[N_IFNET].n_name); 347 return (-1); 348 } 349 KREAD(nl[N_IFNET].n_value, &ifp, struct ifnet *); 350 while (ifp) { 351 KREAD(ifp, &ifnet, struct ifnet); 352 nifp = ifnet.if_link.tqe_next; 353 if (ifindex && ifindex != ifnet.if_index) 354 goto next; 355 356 printf("%s:\n", if_indextoname(ifnet.if_index, ifname)); 357#ifdef INET 358 if_addrlist(TAILQ_FIRST(&ifnet.if_addrhead)); 359#endif 360#ifdef INET6 361 if6_addrlist(TAILQ_FIRST(&ifnet.if_addrhead)); 362#endif 363 if (vflag) 364 ll_addrlist(TAILQ_FIRST(&ifnet.if_addrhead)); 365 next: 366 ifp = nifp; 367 } 368 369 return (0); 370} 371 372static void 373kread(u_long addr, void *buf, int len) 374{ 375 376 if (kvm_read(kvmd, addr, buf, len) != len) { 377 perror("kvm_read"); 378 exit(EX_OSERR); 379 } 380} 381 382static void 383ll_addrlist(struct ifaddr *ifap) 384{ 385 char addrbuf[NI_MAXHOST]; 386 struct ifaddr ifa; 387 struct sockaddr sa; 388 struct sockaddr_dl sdl; 389 struct ifaddr *ifap0; 390 int error; 391 392 if (af && af != AF_LINK) 393 return; 394 395 ifap0 = ifap; 396 while (ifap) { 397 KREAD(ifap, &ifa, struct ifaddr); 398 if (ifa.ifa_addr == NULL) 399 goto nextifap; 400 KREAD(ifa.ifa_addr, &sa, struct sockaddr); 401 if (sa.sa_family != PF_LINK) 402 goto nextifap; 403 KREAD(ifa.ifa_addr, &sdl, struct sockaddr_dl); 404 if (sdl.sdl_alen == 0) 405 goto nextifap; 406 addrbuf[0] = '\0'; 407 error = getnameinfo((struct sockaddr *)&sdl, sdl.sdl_len, 408 addrbuf, sizeof(addrbuf), NULL, 0, NI_NUMERICHOST); 409 printf("\tlink %s\n", addrbuf); 410 nextifap: 411 ifap = ifa.ifa_link.tqe_next; 412 } 413 if (ifap0) { 414 struct ifnet ifnet; 415 struct ifmultiaddr ifm, *ifmp = 0; 416 417 KREAD(ifap0, &ifa, struct ifaddr); 418 KREAD(ifa.ifa_ifp, &ifnet, struct ifnet); 419 if (TAILQ_FIRST(&ifnet.if_multiaddrs)) 420 ifmp = TAILQ_FIRST(&ifnet.if_multiaddrs); 421 while (ifmp) { 422 KREAD(ifmp, &ifm, struct ifmultiaddr); 423 if (ifm.ifma_addr == NULL) 424 goto nextmulti; 425 KREAD(ifm.ifma_addr, &sa, struct sockaddr); 426 if (sa.sa_family != AF_LINK) 427 goto nextmulti; 428 KREAD(ifm.ifma_addr, &sdl, struct sockaddr_dl); 429 addrbuf[0] = '\0'; 430 error = getnameinfo((struct sockaddr *)&sdl, 431 sdl.sdl_len, addrbuf, sizeof(addrbuf), 432 NULL, 0, NI_NUMERICHOST); 433 printf("\t\tgroup %s refcnt %d\n", 434 addrbuf, ifm.ifma_refcount); 435 nextmulti: 436 ifmp = TAILQ_NEXT(&ifm, ifma_link); 437 } 438 } 439} 440 441#ifdef INET6 442 443static void
| 171static const char * inet6_n2a(struct in6_addr *); 172#endif 173int main(int, char **); 174 175static void 176usage() 177{ 178 179 fprintf(stderr, 180 "usage: ifmcstat [-i interface] [-f address family]" 181 " [-v]" 182#ifdef WITH_KVM 183 " [-K] [-M core] [-N system]" 184#endif 185 "\n"); 186 exit(EX_USAGE); 187} 188 189static const char *options = "i:f:vM:N:" 190#ifdef WITH_KVM 191 "K" 192#endif 193 ; 194 195int 196main(int argc, char **argv) 197{ 198 int c, error; 199#ifdef WITH_KVM 200 const char *kernel = NULL; 201 const char *core = NULL; 202#endif 203 204 while ((c = getopt(argc, argv, options)) != -1) { 205 switch (c) { 206 case 'i': 207 if ((ifindex = if_nametoindex(optarg)) == 0) { 208 fprintf(stderr, "%s: unknown interface\n", 209 optarg); 210 exit(EX_NOHOST); 211 } 212 break; 213 214 case 'f': 215#ifdef INET 216 if (strcmp(optarg, "inet") == 0) { 217 af = AF_INET; 218 break; 219 } 220#endif 221#ifdef INET6 222 if (strcmp(optarg, "inet6") == 0) { 223 af = AF_INET6; 224 break; 225 } 226#endif 227 if (strcmp(optarg, "link") == 0) { 228 af = AF_LINK; 229 break; 230 } 231 fprintf(stderr, "%s: unknown address family\n", optarg); 232 exit(EX_USAGE); 233 /*NOTREACHED*/ 234 break; 235 236#ifdef WITH_KVM 237 case 'K': 238 ++Kflag; 239 break; 240#endif 241 242 case 'v': 243 ++vflag; 244 break; 245 246#ifdef WITH_KVM 247 case 'M': 248 core = strdup(optarg); 249 break; 250 251 case 'N': 252 kernel = strdup(optarg); 253 break; 254#endif 255 256 default: 257 usage(); 258 break; 259 /*NOTREACHED*/ 260 } 261 } 262 263 if (af == AF_LINK && vflag) 264 usage(); 265 266#ifdef WITH_KVM 267 if (!Kflag) 268 error = ifmcstat_kvm(kernel, core); 269 /* 270 * If KVM failed, and user did not explicitly specify a core file, 271 * or force KVM backend to be disabled, try the sysctl backend. 272 */ 273 if (Kflag || (error != 0 && (core == NULL && kernel == NULL))) 274#endif 275 error = ifmcstat_getifmaddrs(); 276 if (error != 0) 277 exit(EX_OSERR); 278 279 exit(EX_OK); 280 /*NOTREACHED*/ 281} 282 283#ifdef INET 284 285static void 286in_ifinfo(struct igmp_ifinfo *igi) 287{ 288 289 printf("\t"); 290 switch (igi->igi_version) { 291 case IGMP_VERSION_1: 292 case IGMP_VERSION_2: 293 case IGMP_VERSION_3: 294 printf("igmpv%d", igi->igi_version); 295 break; 296 default: 297 printf("igmpv?(%d)", igi->igi_version); 298 break; 299 } 300 printb(" flags", igi->igi_flags, "\020\1SILENT\2LOOPBACK"); 301 if (igi->igi_version == IGMP_VERSION_3) { 302 printf(" rv %u qi %u qri %u uri %u", 303 igi->igi_rv, igi->igi_qi, igi->igi_qri, igi->igi_uri); 304 } 305 if (vflag >= 2) { 306 printf(" v1timer %u v2timer %u v3timer %u", 307 igi->igi_v1_timer, igi->igi_v2_timer, igi->igi_v3_timer); 308 } 309 printf("\n"); 310} 311 312static const char *inm_modes[] = { 313 "undefined", 314 "include", 315 "exclude", 316}; 317 318static const char * 319inm_mode(u_int mode) 320{ 321 322 if (mode >= MCAST_UNDEFINED && mode <= MCAST_EXCLUDE) 323 return (inm_modes[mode]); 324 return (NULL); 325} 326 327#endif /* INET */ 328 329#ifdef WITH_KVM 330 331static int 332ifmcstat_kvm(const char *kernel, const char *core) 333{ 334 char buf[_POSIX2_LINE_MAX], ifname[IFNAMSIZ]; 335 struct ifnet *ifp, *nifp, ifnet; 336 337 if ((kvmd = kvm_openfiles(kernel, core, NULL, O_RDONLY, buf)) == 338 NULL) { 339 perror("kvm_openfiles"); 340 return (-1); 341 } 342 if (kvm_nlist(kvmd, nl) < 0) { 343 perror("kvm_nlist"); 344 return (-1); 345 } 346 if (nl[N_IFNET].n_value == 0) { 347 printf("symbol %s not found\n", nl[N_IFNET].n_name); 348 return (-1); 349 } 350 KREAD(nl[N_IFNET].n_value, &ifp, struct ifnet *); 351 while (ifp) { 352 KREAD(ifp, &ifnet, struct ifnet); 353 nifp = ifnet.if_link.tqe_next; 354 if (ifindex && ifindex != ifnet.if_index) 355 goto next; 356 357 printf("%s:\n", if_indextoname(ifnet.if_index, ifname)); 358#ifdef INET 359 if_addrlist(TAILQ_FIRST(&ifnet.if_addrhead)); 360#endif 361#ifdef INET6 362 if6_addrlist(TAILQ_FIRST(&ifnet.if_addrhead)); 363#endif 364 if (vflag) 365 ll_addrlist(TAILQ_FIRST(&ifnet.if_addrhead)); 366 next: 367 ifp = nifp; 368 } 369 370 return (0); 371} 372 373static void 374kread(u_long addr, void *buf, int len) 375{ 376 377 if (kvm_read(kvmd, addr, buf, len) != len) { 378 perror("kvm_read"); 379 exit(EX_OSERR); 380 } 381} 382 383static void 384ll_addrlist(struct ifaddr *ifap) 385{ 386 char addrbuf[NI_MAXHOST]; 387 struct ifaddr ifa; 388 struct sockaddr sa; 389 struct sockaddr_dl sdl; 390 struct ifaddr *ifap0; 391 int error; 392 393 if (af && af != AF_LINK) 394 return; 395 396 ifap0 = ifap; 397 while (ifap) { 398 KREAD(ifap, &ifa, struct ifaddr); 399 if (ifa.ifa_addr == NULL) 400 goto nextifap; 401 KREAD(ifa.ifa_addr, &sa, struct sockaddr); 402 if (sa.sa_family != PF_LINK) 403 goto nextifap; 404 KREAD(ifa.ifa_addr, &sdl, struct sockaddr_dl); 405 if (sdl.sdl_alen == 0) 406 goto nextifap; 407 addrbuf[0] = '\0'; 408 error = getnameinfo((struct sockaddr *)&sdl, sdl.sdl_len, 409 addrbuf, sizeof(addrbuf), NULL, 0, NI_NUMERICHOST); 410 printf("\tlink %s\n", addrbuf); 411 nextifap: 412 ifap = ifa.ifa_link.tqe_next; 413 } 414 if (ifap0) { 415 struct ifnet ifnet; 416 struct ifmultiaddr ifm, *ifmp = 0; 417 418 KREAD(ifap0, &ifa, struct ifaddr); 419 KREAD(ifa.ifa_ifp, &ifnet, struct ifnet); 420 if (TAILQ_FIRST(&ifnet.if_multiaddrs)) 421 ifmp = TAILQ_FIRST(&ifnet.if_multiaddrs); 422 while (ifmp) { 423 KREAD(ifmp, &ifm, struct ifmultiaddr); 424 if (ifm.ifma_addr == NULL) 425 goto nextmulti; 426 KREAD(ifm.ifma_addr, &sa, struct sockaddr); 427 if (sa.sa_family != AF_LINK) 428 goto nextmulti; 429 KREAD(ifm.ifma_addr, &sdl, struct sockaddr_dl); 430 addrbuf[0] = '\0'; 431 error = getnameinfo((struct sockaddr *)&sdl, 432 sdl.sdl_len, addrbuf, sizeof(addrbuf), 433 NULL, 0, NI_NUMERICHOST); 434 printf("\t\tgroup %s refcnt %d\n", 435 addrbuf, ifm.ifma_refcount); 436 nextmulti: 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
|
444if6_addrlist(struct ifaddr *ifap) 445{
| 471if6_addrlist(struct ifaddr *ifap) 472{
|
| 473 struct ifnet ifnet;
|
446 struct ifaddr ifa; 447 struct sockaddr sa; 448 struct in6_ifaddr if6a; 449 struct ifaddr *ifap0; 450 451 if (af && af != AF_INET6) 452 return; 453 ifap0 = ifap; 454 while (ifap) { 455 KREAD(ifap, &ifa, struct ifaddr); 456 if (ifa.ifa_addr == NULL) 457 goto nextifap; 458 KREAD(ifa.ifa_addr, &sa, struct sockaddr); 459 if (sa.sa_family != PF_INET6) 460 goto nextifap; 461 KREAD(ifap, &if6a, struct in6_ifaddr); 462 printf("\tinet6 %s\n", inet6_n2a(&if6a.ia_addr.sin6_addr));
| 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 }
|
463 nextifap: 464 ifap = ifa.ifa_link.tqe_next; 465 } 466 if (ifap0) { 467 struct ifnet ifnet; 468 struct ifmultiaddr ifm, *ifmp = 0; 469 struct sockaddr_dl sdl; 470 471 KREAD(ifap0, &ifa, struct ifaddr); 472 KREAD(ifa.ifa_ifp, &ifnet, struct ifnet); 473 if (TAILQ_FIRST(&ifnet.if_multiaddrs)) 474 ifmp = TAILQ_FIRST(&ifnet.if_multiaddrs); 475 while (ifmp) { 476 KREAD(ifmp, &ifm, struct ifmultiaddr); 477 if (ifm.ifma_addr == NULL) 478 goto nextmulti; 479 KREAD(ifm.ifma_addr, &sa, struct sockaddr); 480 if (sa.sa_family != AF_INET6) 481 goto nextmulti; 482 (void)in6_multientry((struct in6_multi *) 483 ifm.ifma_protospec); 484 if (ifm.ifma_lladdr == 0) 485 goto nextmulti; 486 KREAD(ifm.ifma_lladdr, &sdl, struct sockaddr_dl); 487 printf("\t\t\tmcast-macaddr %s refcnt %d\n", 488 ether_ntoa((struct ether_addr *)LLADDR(&sdl)), 489 ifm.ifma_refcount); 490 nextmulti: 491 ifmp = TAILQ_NEXT(&ifm, ifma_link); 492 } 493 } 494} 495 496static struct in6_multi * 497in6_multientry(struct in6_multi *mc) 498{ 499 struct in6_multi multi; 500 501 KREAD(mc, &multi, struct in6_multi); 502 printf("\t\tgroup %s", inet6_n2a(&multi.in6m_addr)); 503 printf(" refcnt %u\n", multi.in6m_refcount); 504 505 return (multi.in6m_entry.le_next); 506} 507 508#endif /* INET6 */ 509 510#ifdef INET 511 512static void 513if_addrlist(struct ifaddr *ifap) 514{ 515 struct ifaddr ifa; 516 struct ifnet ifnet; 517 struct sockaddr sa; 518 struct in_ifaddr ia; 519 struct ifaddr *ifap0; 520 521 if (af && af != AF_INET) 522 return; 523 ifap0 = ifap; 524 while (ifap) { 525 KREAD(ifap, &ifa, struct ifaddr); 526 if (ifa.ifa_addr == NULL) 527 goto nextifap; 528 KREAD(ifa.ifa_addr, &sa, struct sockaddr); 529 if (sa.sa_family != PF_INET) 530 goto nextifap; 531 KREAD(ifap, &ia, struct in_ifaddr); 532 printf("\tinet %s\n", inet_ntoa(ia.ia_addr.sin_addr)); 533 /* 534 * Print per-link IGMP information, if available. 535 */ 536 if (ifa.ifa_ifp != NULL) { 537 struct in_ifinfo ii; 538 struct igmp_ifinfo igi; 539 540 KREAD(ifa.ifa_ifp, &ifnet, struct ifnet); 541 KREAD(ifnet.if_afdata[AF_INET], &ii, struct in_ifinfo); 542 if (ii.ii_igmp != NULL) { 543 KREAD(ii.ii_igmp, &igi, struct igmp_ifinfo); 544 in_ifinfo(&igi); 545 } 546 } 547 nextifap: 548 ifap = ifa.ifa_link.tqe_next; 549 } 550 if (ifap0) { 551 struct ifmultiaddr ifm, *ifmp = 0; 552 struct sockaddr_dl sdl; 553 554 KREAD(ifap0, &ifa, struct ifaddr); 555 KREAD(ifa.ifa_ifp, &ifnet, struct ifnet); 556 if (TAILQ_FIRST(&ifnet.if_multiaddrs)) 557 ifmp = TAILQ_FIRST(&ifnet.if_multiaddrs); 558 while (ifmp) { 559 KREAD(ifmp, &ifm, struct ifmultiaddr); 560 if (ifm.ifma_addr == NULL) 561 goto nextmulti; 562 KREAD(ifm.ifma_addr, &sa, struct sockaddr); 563 if (sa.sa_family != AF_INET) 564 goto nextmulti; 565 (void)in_multientry((struct in_multi *) 566 ifm.ifma_protospec); 567 if (ifm.ifma_lladdr == 0) 568 goto nextmulti; 569 KREAD(ifm.ifma_lladdr, &sdl, struct sockaddr_dl); 570 printf("\t\t\tmcast-macaddr %s refcnt %d\n", 571 ether_ntoa((struct ether_addr *)LLADDR(&sdl)), 572 ifm.ifma_refcount); 573 nextmulti: 574 ifmp = TAILQ_NEXT(&ifm, ifma_link); 575 } 576 } 577} 578 579static const char *inm_states[] = { 580 "not-member", 581 "silent", 582 "idle", 583 "lazy", 584 "sleeping", 585 "awakening", 586 "query-pending", 587 "sg-query-pending", 588 "leaving" 589}; 590 591static const char * 592inm_state(u_int state) 593{ 594 595 if (state >= IGMP_NOT_MEMBER && state <= IGMP_LEAVING_MEMBER) 596 return (inm_states[state]); 597 return (NULL); 598} 599 600#if 0 601static struct ip_msource * 602ims_min_kvm(struct in_multi *pinm) 603{ 604 struct ip_msource ims0; 605 struct ip_msource *tmp, *parent; 606 607 parent = NULL; 608 tmp = RB_ROOT(&pinm->inm_srcs); 609 while (tmp) { 610 parent = tmp; 611 KREAD(tmp, &ims0, struct ip_msource); 612 tmp = RB_LEFT(&ims0, ims_link); 613 } 614 return (parent); /* kva */ 615} 616 617/* XXX This routine is buggy. See RB_NEXT in sys/tree.h. */ 618static struct ip_msource * 619ims_next_kvm(struct ip_msource *ims) 620{ 621 struct ip_msource ims0, ims1; 622 struct ip_msource *tmp; 623 624 KREAD(ims, &ims0, struct ip_msource); 625 if (RB_RIGHT(&ims0, ims_link)) { 626 ims = RB_RIGHT(&ims0, ims_link); 627 KREAD(ims, &ims1, struct ip_msource); 628 while ((tmp = RB_LEFT(&ims1, ims_link))) { 629 KREAD(tmp, &ims0, struct ip_msource); 630 ims = RB_LEFT(&ims0, ims_link); 631 } 632 } else { 633 tmp = RB_PARENT(&ims0, ims_link); 634 if (tmp) { 635 KREAD(tmp, &ims1, struct ip_msource); 636 if (ims == RB_LEFT(&ims1, ims_link)) 637 ims = tmp; 638 } else { 639 while ((tmp = RB_PARENT(&ims0, ims_link))) { 640 KREAD(tmp, &ims1, struct ip_msource); 641 if (ims == RB_RIGHT(&ims1, ims_link)) { 642 ims = tmp; 643 KREAD(ims, &ims0, struct ip_msource); 644 } else 645 break; 646 } 647 ims = RB_PARENT(&ims0, ims_link); 648 } 649 } 650 return (ims); /* kva */ 651} 652 653static void 654inm_print_sources_kvm(struct in_multi *pinm) 655{ 656 struct ip_msource ims0; 657 struct ip_msource *ims; 658 struct in_addr src; 659 int cnt; 660 uint8_t fmode; 661 662 cnt = 0; 663 fmode = pinm->inm_st[1].iss_fmode; 664 if (fmode == MCAST_UNDEFINED) 665 return; 666 for (ims = ims_min_kvm(pinm); ims != NULL; ims = ims_next_kvm(ims)) { 667 if (cnt == 0) 668 printf(" srcs "); 669 KREAD(ims, &ims0, struct ip_msource); 670 /* Only print sources in-mode at t1. */ 671 if (fmode != ims_get_mode(pinm, ims, 1)) 672 continue; 673 src.s_addr = htonl(ims0.ims_haddr); 674 printf("%s%s", (cnt++ == 0 ? "" : ","), inet_ntoa(src)); 675 } 676} 677#endif 678 679static struct in_multi * 680in_multientry(struct in_multi *pinm) 681{ 682 struct in_multi inm; 683 const char *state, *mode; 684 685 KREAD(pinm, &inm, struct in_multi); 686 printf("\t\tgroup %s", inet_ntoa(inm.inm_addr)); 687 printf(" refcnt %u", inm.inm_refcount); 688 689 state = inm_state(inm.inm_state); 690 if (state) 691 printf(" state %s", state); 692 else 693 printf(" state (%d)", inm.inm_state); 694 695 mode = inm_mode(inm.inm_st[1].iss_fmode); 696 if (mode) 697 printf(" mode %s", mode); 698 else 699 printf(" mode (%d)", inm.inm_st[1].iss_fmode); 700 701 if (vflag >= 2) { 702 printf(" asm %u ex %u in %u rec %u", 703 (u_int)inm.inm_st[1].iss_asm, 704 (u_int)inm.inm_st[1].iss_ex, 705 (u_int)inm.inm_st[1].iss_in, 706 (u_int)inm.inm_st[1].iss_rec); 707 } 708 709#if 0 710 /* Buggy. */ 711 if (vflag) 712 inm_print_sources_kvm(&inm); 713#endif 714 715 printf("\n"); 716 return (NULL); 717} 718 719#endif /* INET */ 720 721#endif /* WITH_KVM */ 722 723#ifdef INET6 724static const char * 725inet6_n2a(struct in6_addr *p) 726{ 727 static char buf[NI_MAXHOST]; 728 struct sockaddr_in6 sin6; 729 u_int32_t scopeid; 730 const int niflags = NI_NUMERICHOST; 731 732 memset(&sin6, 0, sizeof(sin6)); 733 sin6.sin6_family = AF_INET6; 734 sin6.sin6_len = sizeof(struct sockaddr_in6); 735 sin6.sin6_addr = *p; 736 if (IN6_IS_ADDR_LINKLOCAL(p) || IN6_IS_ADDR_MC_LINKLOCAL(p) || 737 IN6_IS_ADDR_MC_NODELOCAL(p)) { 738 scopeid = ntohs(*(u_int16_t *)&sin6.sin6_addr.s6_addr[2]); 739 if (scopeid) { 740 sin6.sin6_scope_id = scopeid; 741 sin6.sin6_addr.s6_addr[2] = 0; 742 sin6.sin6_addr.s6_addr[3] = 0; 743 } 744 } 745 if (getnameinfo((struct sockaddr *)&sin6, sin6.sin6_len, 746 buf, sizeof(buf), NULL, 0, niflags) == 0) { 747 return (buf); 748 } else { 749 return ("(invalid)"); 750 } 751} 752#endif /* INET6 */ 753 754#ifdef INET 755/* 756 * Retrieve per-group source filter mode and lists via sysctl. 757 */ 758static void 759inm_print_sources_sysctl(uint32_t ifindex, struct in_addr gina) 760{ 761#define MAX_SYSCTL_TRY 5 762 int mib[7]; 763 int ntry = 0; 764 size_t mibsize; 765 size_t len; 766 size_t needed; 767 size_t cnt; 768 int i; 769 char *buf; 770 struct in_addr *pina; 771 uint32_t *p; 772 uint32_t fmode; 773 const char *modestr; 774 775 mibsize = sizeof(mib) / sizeof(mib[0]); 776 if (sysctlnametomib("net.inet.ip.mcast.filters", mib, &mibsize) == -1) { 777 perror("sysctlnametomib"); 778 return; 779 } 780 781 needed = 0; 782 mib[5] = ifindex; 783 mib[6] = gina.s_addr; /* 32 bits wide */ 784 mibsize = sizeof(mib) / sizeof(mib[0]); 785 do { 786 if (sysctl(mib, mibsize, NULL, &needed, NULL, 0) == -1) { 787 perror("sysctl net.inet.ip.mcast.filters"); 788 return; 789 } 790 if ((buf = malloc(needed)) == NULL) { 791 perror("malloc"); 792 return; 793 } 794 if (sysctl(mib, mibsize, buf, &needed, NULL, 0) == -1) { 795 if (errno != ENOMEM || ++ntry >= MAX_SYSCTL_TRY) { 796 perror("sysctl"); 797 goto out_free; 798 } 799 free(buf); 800 buf = NULL; 801 } 802 } while (buf == NULL); 803 804 len = needed; 805 if (len < sizeof(uint32_t)) { 806 perror("sysctl"); 807 goto out_free; 808 } 809 810 p = (uint32_t *)buf; 811 fmode = *p++; 812 len -= sizeof(uint32_t); 813 814 modestr = inm_mode(fmode); 815 if (modestr) 816 printf(" mode %s", modestr); 817 else 818 printf(" mode (%u)", fmode); 819 820 if (vflag == 0) 821 goto out_free; 822 823 cnt = len / sizeof(struct in_addr); 824 pina = (struct in_addr *)p; 825 826 for (i = 0; i < cnt; i++) { 827 if (i == 0) 828 printf(" srcs "); 829 fprintf(stdout, "%s%s", (i == 0 ? "" : ","), 830 inet_ntoa(*pina++)); 831 len -= sizeof(struct in_addr); 832 } 833 if (len > 0) { 834 fprintf(stderr, "warning: %u trailing bytes from %s\n", 835 (unsigned int)len, "net.inet.ip.mcast.filters"); 836 } 837 838out_free: 839 free(buf); 840#undef MAX_SYSCTL_TRY 841} 842 843#endif /* INET */ 844
| 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 514 KREAD(ifap0, &ifa, struct ifaddr); 515 KREAD(ifa.ifa_ifp, &ifnet, struct ifnet); 516 if (TAILQ_FIRST(&ifnet.if_multiaddrs)) 517 ifmp = TAILQ_FIRST(&ifnet.if_multiaddrs); 518 while (ifmp) { 519 KREAD(ifmp, &ifm, struct ifmultiaddr); 520 if (ifm.ifma_addr == NULL) 521 goto nextmulti; 522 KREAD(ifm.ifma_addr, &sa, struct sockaddr); 523 if (sa.sa_family != AF_INET6) 524 goto nextmulti; 525 (void)in6_multientry((struct in6_multi *) 526 ifm.ifma_protospec); 527 if (ifm.ifma_lladdr == 0) 528 goto nextmulti; 529 KREAD(ifm.ifma_lladdr, &sdl, struct sockaddr_dl); 530 printf("\t\t\tmcast-macaddr %s refcnt %d\n", 531 ether_ntoa((struct ether_addr *)LLADDR(&sdl)), 532 ifm.ifma_refcount); 533 nextmulti: 534 ifmp = TAILQ_NEXT(&ifm, ifma_link); 535 } 536 } 537} 538 539static struct in6_multi * 540in6_multientry(struct in6_multi *mc) 541{ 542 struct in6_multi multi; 543 544 KREAD(mc, &multi, struct in6_multi); 545 printf("\t\tgroup %s", inet6_n2a(&multi.in6m_addr)); 546 printf(" refcnt %u\n", multi.in6m_refcount); 547 548 return (multi.in6m_entry.le_next); 549} 550 551#endif /* INET6 */ 552 553#ifdef INET 554 555static void 556if_addrlist(struct ifaddr *ifap) 557{ 558 struct ifaddr ifa; 559 struct ifnet ifnet; 560 struct sockaddr sa; 561 struct in_ifaddr ia; 562 struct ifaddr *ifap0; 563 564 if (af && af != AF_INET) 565 return; 566 ifap0 = ifap; 567 while (ifap) { 568 KREAD(ifap, &ifa, struct ifaddr); 569 if (ifa.ifa_addr == NULL) 570 goto nextifap; 571 KREAD(ifa.ifa_addr, &sa, struct sockaddr); 572 if (sa.sa_family != PF_INET) 573 goto nextifap; 574 KREAD(ifap, &ia, struct in_ifaddr); 575 printf("\tinet %s\n", inet_ntoa(ia.ia_addr.sin_addr)); 576 /* 577 * Print per-link IGMP information, if available. 578 */ 579 if (ifa.ifa_ifp != NULL) { 580 struct in_ifinfo ii; 581 struct igmp_ifinfo igi; 582 583 KREAD(ifa.ifa_ifp, &ifnet, struct ifnet); 584 KREAD(ifnet.if_afdata[AF_INET], &ii, struct in_ifinfo); 585 if (ii.ii_igmp != NULL) { 586 KREAD(ii.ii_igmp, &igi, struct igmp_ifinfo); 587 in_ifinfo(&igi); 588 } 589 } 590 nextifap: 591 ifap = ifa.ifa_link.tqe_next; 592 } 593 if (ifap0) { 594 struct ifmultiaddr ifm, *ifmp = 0; 595 struct sockaddr_dl sdl; 596 597 KREAD(ifap0, &ifa, struct ifaddr); 598 KREAD(ifa.ifa_ifp, &ifnet, struct ifnet); 599 if (TAILQ_FIRST(&ifnet.if_multiaddrs)) 600 ifmp = TAILQ_FIRST(&ifnet.if_multiaddrs); 601 while (ifmp) { 602 KREAD(ifmp, &ifm, struct ifmultiaddr); 603 if (ifm.ifma_addr == NULL) 604 goto nextmulti; 605 KREAD(ifm.ifma_addr, &sa, struct sockaddr); 606 if (sa.sa_family != AF_INET) 607 goto nextmulti; 608 (void)in_multientry((struct in_multi *) 609 ifm.ifma_protospec); 610 if (ifm.ifma_lladdr == 0) 611 goto nextmulti; 612 KREAD(ifm.ifma_lladdr, &sdl, struct sockaddr_dl); 613 printf("\t\t\tmcast-macaddr %s refcnt %d\n", 614 ether_ntoa((struct ether_addr *)LLADDR(&sdl)), 615 ifm.ifma_refcount); 616 nextmulti: 617 ifmp = TAILQ_NEXT(&ifm, ifma_link); 618 } 619 } 620} 621 622static const char *inm_states[] = { 623 "not-member", 624 "silent", 625 "idle", 626 "lazy", 627 "sleeping", 628 "awakening", 629 "query-pending", 630 "sg-query-pending", 631 "leaving" 632}; 633 634static const char * 635inm_state(u_int state) 636{ 637 638 if (state >= IGMP_NOT_MEMBER && state <= IGMP_LEAVING_MEMBER) 639 return (inm_states[state]); 640 return (NULL); 641} 642 643#if 0 644static struct ip_msource * 645ims_min_kvm(struct in_multi *pinm) 646{ 647 struct ip_msource ims0; 648 struct ip_msource *tmp, *parent; 649 650 parent = NULL; 651 tmp = RB_ROOT(&pinm->inm_srcs); 652 while (tmp) { 653 parent = tmp; 654 KREAD(tmp, &ims0, struct ip_msource); 655 tmp = RB_LEFT(&ims0, ims_link); 656 } 657 return (parent); /* kva */ 658} 659 660/* XXX This routine is buggy. See RB_NEXT in sys/tree.h. */ 661static struct ip_msource * 662ims_next_kvm(struct ip_msource *ims) 663{ 664 struct ip_msource ims0, ims1; 665 struct ip_msource *tmp; 666 667 KREAD(ims, &ims0, struct ip_msource); 668 if (RB_RIGHT(&ims0, ims_link)) { 669 ims = RB_RIGHT(&ims0, ims_link); 670 KREAD(ims, &ims1, struct ip_msource); 671 while ((tmp = RB_LEFT(&ims1, ims_link))) { 672 KREAD(tmp, &ims0, struct ip_msource); 673 ims = RB_LEFT(&ims0, ims_link); 674 } 675 } else { 676 tmp = RB_PARENT(&ims0, ims_link); 677 if (tmp) { 678 KREAD(tmp, &ims1, struct ip_msource); 679 if (ims == RB_LEFT(&ims1, ims_link)) 680 ims = tmp; 681 } else { 682 while ((tmp = RB_PARENT(&ims0, ims_link))) { 683 KREAD(tmp, &ims1, struct ip_msource); 684 if (ims == RB_RIGHT(&ims1, ims_link)) { 685 ims = tmp; 686 KREAD(ims, &ims0, struct ip_msource); 687 } else 688 break; 689 } 690 ims = RB_PARENT(&ims0, ims_link); 691 } 692 } 693 return (ims); /* kva */ 694} 695 696static void 697inm_print_sources_kvm(struct in_multi *pinm) 698{ 699 struct ip_msource ims0; 700 struct ip_msource *ims; 701 struct in_addr src; 702 int cnt; 703 uint8_t fmode; 704 705 cnt = 0; 706 fmode = pinm->inm_st[1].iss_fmode; 707 if (fmode == MCAST_UNDEFINED) 708 return; 709 for (ims = ims_min_kvm(pinm); ims != NULL; ims = ims_next_kvm(ims)) { 710 if (cnt == 0) 711 printf(" srcs "); 712 KREAD(ims, &ims0, struct ip_msource); 713 /* Only print sources in-mode at t1. */ 714 if (fmode != ims_get_mode(pinm, ims, 1)) 715 continue; 716 src.s_addr = htonl(ims0.ims_haddr); 717 printf("%s%s", (cnt++ == 0 ? "" : ","), inet_ntoa(src)); 718 } 719} 720#endif 721 722static struct in_multi * 723in_multientry(struct in_multi *pinm) 724{ 725 struct in_multi inm; 726 const char *state, *mode; 727 728 KREAD(pinm, &inm, struct in_multi); 729 printf("\t\tgroup %s", inet_ntoa(inm.inm_addr)); 730 printf(" refcnt %u", inm.inm_refcount); 731 732 state = inm_state(inm.inm_state); 733 if (state) 734 printf(" state %s", state); 735 else 736 printf(" state (%d)", inm.inm_state); 737 738 mode = inm_mode(inm.inm_st[1].iss_fmode); 739 if (mode) 740 printf(" mode %s", mode); 741 else 742 printf(" mode (%d)", inm.inm_st[1].iss_fmode); 743 744 if (vflag >= 2) { 745 printf(" asm %u ex %u in %u rec %u", 746 (u_int)inm.inm_st[1].iss_asm, 747 (u_int)inm.inm_st[1].iss_ex, 748 (u_int)inm.inm_st[1].iss_in, 749 (u_int)inm.inm_st[1].iss_rec); 750 } 751 752#if 0 753 /* Buggy. */ 754 if (vflag) 755 inm_print_sources_kvm(&inm); 756#endif 757 758 printf("\n"); 759 return (NULL); 760} 761 762#endif /* INET */ 763 764#endif /* WITH_KVM */ 765 766#ifdef INET6 767static const char * 768inet6_n2a(struct in6_addr *p) 769{ 770 static char buf[NI_MAXHOST]; 771 struct sockaddr_in6 sin6; 772 u_int32_t scopeid; 773 const int niflags = NI_NUMERICHOST; 774 775 memset(&sin6, 0, sizeof(sin6)); 776 sin6.sin6_family = AF_INET6; 777 sin6.sin6_len = sizeof(struct sockaddr_in6); 778 sin6.sin6_addr = *p; 779 if (IN6_IS_ADDR_LINKLOCAL(p) || IN6_IS_ADDR_MC_LINKLOCAL(p) || 780 IN6_IS_ADDR_MC_NODELOCAL(p)) { 781 scopeid = ntohs(*(u_int16_t *)&sin6.sin6_addr.s6_addr[2]); 782 if (scopeid) { 783 sin6.sin6_scope_id = scopeid; 784 sin6.sin6_addr.s6_addr[2] = 0; 785 sin6.sin6_addr.s6_addr[3] = 0; 786 } 787 } 788 if (getnameinfo((struct sockaddr *)&sin6, sin6.sin6_len, 789 buf, sizeof(buf), NULL, 0, niflags) == 0) { 790 return (buf); 791 } else { 792 return ("(invalid)"); 793 } 794} 795#endif /* INET6 */ 796 797#ifdef INET 798/* 799 * Retrieve per-group source filter mode and lists via sysctl. 800 */ 801static void 802inm_print_sources_sysctl(uint32_t ifindex, struct in_addr gina) 803{ 804#define MAX_SYSCTL_TRY 5 805 int mib[7]; 806 int ntry = 0; 807 size_t mibsize; 808 size_t len; 809 size_t needed; 810 size_t cnt; 811 int i; 812 char *buf; 813 struct in_addr *pina; 814 uint32_t *p; 815 uint32_t fmode; 816 const char *modestr; 817 818 mibsize = sizeof(mib) / sizeof(mib[0]); 819 if (sysctlnametomib("net.inet.ip.mcast.filters", mib, &mibsize) == -1) { 820 perror("sysctlnametomib"); 821 return; 822 } 823 824 needed = 0; 825 mib[5] = ifindex; 826 mib[6] = gina.s_addr; /* 32 bits wide */ 827 mibsize = sizeof(mib) / sizeof(mib[0]); 828 do { 829 if (sysctl(mib, mibsize, NULL, &needed, NULL, 0) == -1) { 830 perror("sysctl net.inet.ip.mcast.filters"); 831 return; 832 } 833 if ((buf = malloc(needed)) == NULL) { 834 perror("malloc"); 835 return; 836 } 837 if (sysctl(mib, mibsize, buf, &needed, NULL, 0) == -1) { 838 if (errno != ENOMEM || ++ntry >= MAX_SYSCTL_TRY) { 839 perror("sysctl"); 840 goto out_free; 841 } 842 free(buf); 843 buf = NULL; 844 } 845 } while (buf == NULL); 846 847 len = needed; 848 if (len < sizeof(uint32_t)) { 849 perror("sysctl"); 850 goto out_free; 851 } 852 853 p = (uint32_t *)buf; 854 fmode = *p++; 855 len -= sizeof(uint32_t); 856 857 modestr = inm_mode(fmode); 858 if (modestr) 859 printf(" mode %s", modestr); 860 else 861 printf(" mode (%u)", fmode); 862 863 if (vflag == 0) 864 goto out_free; 865 866 cnt = len / sizeof(struct in_addr); 867 pina = (struct in_addr *)p; 868 869 for (i = 0; i < cnt; i++) { 870 if (i == 0) 871 printf(" srcs "); 872 fprintf(stdout, "%s%s", (i == 0 ? "" : ","), 873 inet_ntoa(*pina++)); 874 len -= sizeof(struct in_addr); 875 } 876 if (len > 0) { 877 fprintf(stderr, "warning: %u trailing bytes from %s\n", 878 (unsigned int)len, "net.inet.ip.mcast.filters"); 879 } 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
|
845static int 846ifmcstat_getifmaddrs(void) 847{ 848 char thisifname[IFNAMSIZ]; 849 char addrbuf[NI_MAXHOST]; 850 struct ifaddrs *ifap, *ifa; 851 struct ifmaddrs *ifmap, *ifma; 852 sockunion_t lastifasa; 853 sockunion_t *psa, *pgsa, *pllsa, *pifasa; 854 char *pcolon; 855 char *pafname; 856 uint32_t lastifindex, thisifindex; 857 int error; 858 859 error = 0; 860 ifap = NULL; 861 ifmap = NULL; 862 lastifindex = 0; 863 thisifindex = 0; 864 lastifasa.ss.ss_family = AF_UNSPEC; 865 866 if (getifaddrs(&ifap) != 0) { 867 warn("getifmaddrs"); 868 return (-1); 869 } 870 871 if (getifmaddrs(&ifmap) != 0) { 872 warn("getifmaddrs"); 873 error = -1; 874 goto out; 875 } 876 877 for (ifma = ifmap; ifma; ifma = ifma->ifma_next) { 878 error = 0; 879 if (ifma->ifma_name == NULL || ifma->ifma_addr == NULL) 880 continue; 881 882 psa = (sockunion_t *)ifma->ifma_name; 883 if (psa->sa.sa_family != AF_LINK) { 884 fprintf(stderr, 885 "WARNING: Kernel returned invalid data.\n"); 886 error = -1; 887 break; 888 } 889 890 /* Filter on interface name. */ 891 thisifindex = psa->sdl.sdl_index; 892 if (ifindex != 0 && thisifindex != ifindex) 893 continue; 894 895 /* Filter on address family. */ 896 pgsa = (sockunion_t *)ifma->ifma_addr; 897 if (af != 0 && pgsa->sa.sa_family != af) 898 continue; 899 900 strlcpy(thisifname, link_ntoa(&psa->sdl), IFNAMSIZ); 901 pcolon = strchr(thisifname, ':'); 902 if (pcolon) 903 *pcolon = '\0'; 904 905 /* Only print the banner for the first ifmaddrs entry. */ 906 if (lastifindex == 0 || lastifindex != thisifindex) { 907 lastifindex = thisifindex; 908 fprintf(stdout, "%s:\n", thisifname); 909 } 910 911 /* 912 * Currently, multicast joins only take place on the 913 * primary IPv4 address, and only on the link-local IPv6 914 * address, as per IGMPv2/3 and MLDv1/2 semantics. 915 * Therefore, we only look up the primary address on 916 * the first pass. 917 */ 918 pifasa = NULL; 919 for (ifa = ifap; ifa; ifa = ifa->ifa_next) { 920 if ((strcmp(ifa->ifa_name, thisifname) != 0) || 921 (ifa->ifa_addr == NULL) || 922 (ifa->ifa_addr->sa_family != pgsa->sa.sa_family)) 923 continue; 924 /* 925 * For AF_INET6 only the link-local address should 926 * be returned. If built without IPv6 support, 927 * skip this address entirely. 928 */ 929 pifasa = (sockunion_t *)ifa->ifa_addr; 930 if (pifasa->sa.sa_family == AF_INET6 931#ifdef INET6 932 && !IN6_IS_ADDR_LINKLOCAL(&pifasa->sin6.sin6_addr) 933#endif 934 ) { 935 pifasa = NULL; 936 continue; 937 } 938 break; 939 } 940 if (pifasa == NULL) 941 continue; /* primary address not found */ 942 943 if (!vflag && pifasa->sa.sa_family == AF_LINK) 944 continue; 945 946 /* Parse and print primary address, if not already printed. */ 947 if (lastifasa.ss.ss_family == AF_UNSPEC || 948 ((lastifasa.ss.ss_family == AF_LINK && 949 !sa_dl_equal(&lastifasa.sa, &pifasa->sa)) || 950 !sa_equal(&lastifasa.sa, &pifasa->sa))) { 951 952 switch (pifasa->sa.sa_family) { 953 case AF_INET: 954 pafname = "inet"; 955 break; 956 case AF_INET6: 957 pafname = "inet6"; 958 break; 959 case AF_LINK: 960 pafname = "link"; 961 break; 962 default: 963 pafname = "unknown"; 964 break; 965 } 966 967 switch (pifasa->sa.sa_family) { 968 case AF_INET6: 969#ifdef INET6 970 { 971 const char *p = 972 inet6_n2a(&pifasa->sin6.sin6_addr); 973 strlcpy(addrbuf, p, sizeof(addrbuf)); 974 break; 975 } 976#else 977 /* FALLTHROUGH */ 978#endif 979 case AF_INET: 980 case AF_LINK: 981 error = getnameinfo(&pifasa->sa, 982 pifasa->sa.sa_len, 983 addrbuf, sizeof(addrbuf), NULL, 0, 984 NI_NUMERICHOST); 985 if (error) 986 perror("getnameinfo"); 987 break; 988 default: 989 addrbuf[0] = '\0'; 990 break; 991 } 992 993 fprintf(stdout, "\t%s %s\n", pafname, addrbuf); 994#ifdef INET 995 /* 996 * Print per-link IGMP information, if available. 997 */ 998 if (pifasa->sa.sa_family == AF_INET) { 999 struct igmp_ifinfo igi; 1000 size_t mibsize, len; 1001 int mib[5]; 1002 1003 mibsize = sizeof(mib) / sizeof(mib[0]); 1004 if (sysctlnametomib("net.inet.igmp.ifinfo", 1005 mib, &mibsize) == -1) { 1006 perror("sysctlnametomib"); 1007 goto next_ifnet; 1008 } 1009 mib[mibsize] = thisifindex; 1010 len = sizeof(struct igmp_ifinfo); 1011 if (sysctl(mib, mibsize + 1, &igi, &len, NULL, 1012 0) == -1) { 1013 perror("sysctl net.inet.igmp.ifinfo"); 1014 goto next_ifnet; 1015 } 1016 in_ifinfo(&igi); 1017 }
| 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; 1000 sockunion_t *psa, *pgsa, *pllsa, *pifasa; 1001 char *pcolon; 1002 char *pafname; 1003 uint32_t lastifindex, thisifindex; 1004 int error; 1005 1006 error = 0; 1007 ifap = NULL; 1008 ifmap = NULL; 1009 lastifindex = 0; 1010 thisifindex = 0; 1011 lastifasa.ss.ss_family = AF_UNSPEC; 1012 1013 if (getifaddrs(&ifap) != 0) { 1014 warn("getifmaddrs"); 1015 return (-1); 1016 } 1017 1018 if (getifmaddrs(&ifmap) != 0) { 1019 warn("getifmaddrs"); 1020 error = -1; 1021 goto out; 1022 } 1023 1024 for (ifma = ifmap; ifma; ifma = ifma->ifma_next) { 1025 error = 0; 1026 if (ifma->ifma_name == NULL || ifma->ifma_addr == NULL) 1027 continue; 1028 1029 psa = (sockunion_t *)ifma->ifma_name; 1030 if (psa->sa.sa_family != AF_LINK) { 1031 fprintf(stderr, 1032 "WARNING: Kernel returned invalid data.\n"); 1033 error = -1; 1034 break; 1035 } 1036 1037 /* Filter on interface name. */ 1038 thisifindex = psa->sdl.sdl_index; 1039 if (ifindex != 0 && thisifindex != ifindex) 1040 continue; 1041 1042 /* Filter on address family. */ 1043 pgsa = (sockunion_t *)ifma->ifma_addr; 1044 if (af != 0 && pgsa->sa.sa_family != af) 1045 continue; 1046 1047 strlcpy(thisifname, link_ntoa(&psa->sdl), IFNAMSIZ); 1048 pcolon = strchr(thisifname, ':'); 1049 if (pcolon) 1050 *pcolon = '\0'; 1051 1052 /* Only print the banner for the first ifmaddrs entry. */ 1053 if (lastifindex == 0 || lastifindex != thisifindex) { 1054 lastifindex = thisifindex; 1055 fprintf(stdout, "%s:\n", thisifname); 1056 } 1057 1058 /* 1059 * Currently, multicast joins only take place on the 1060 * primary IPv4 address, and only on the link-local IPv6 1061 * address, as per IGMPv2/3 and MLDv1/2 semantics. 1062 * Therefore, we only look up the primary address on 1063 * the first pass. 1064 */ 1065 pifasa = NULL; 1066 for (ifa = ifap; ifa; ifa = ifa->ifa_next) { 1067 if ((strcmp(ifa->ifa_name, thisifname) != 0) || 1068 (ifa->ifa_addr == NULL) || 1069 (ifa->ifa_addr->sa_family != pgsa->sa.sa_family)) 1070 continue; 1071 /* 1072 * For AF_INET6 only the link-local address should 1073 * be returned. If built without IPv6 support, 1074 * skip this address entirely. 1075 */ 1076 pifasa = (sockunion_t *)ifa->ifa_addr; 1077 if (pifasa->sa.sa_family == AF_INET6 1078#ifdef INET6 1079 && !IN6_IS_ADDR_LINKLOCAL(&pifasa->sin6.sin6_addr) 1080#endif 1081 ) { 1082 pifasa = NULL; 1083 continue; 1084 } 1085 break; 1086 } 1087 if (pifasa == NULL) 1088 continue; /* primary address not found */ 1089 1090 if (!vflag && pifasa->sa.sa_family == AF_LINK) 1091 continue; 1092 1093 /* Parse and print primary address, if not already printed. */ 1094 if (lastifasa.ss.ss_family == AF_UNSPEC || 1095 ((lastifasa.ss.ss_family == AF_LINK && 1096 !sa_dl_equal(&lastifasa.sa, &pifasa->sa)) || 1097 !sa_equal(&lastifasa.sa, &pifasa->sa))) { 1098 1099 switch (pifasa->sa.sa_family) { 1100 case AF_INET: 1101 pafname = "inet"; 1102 break; 1103 case AF_INET6: 1104 pafname = "inet6"; 1105 break; 1106 case AF_LINK: 1107 pafname = "link"; 1108 break; 1109 default: 1110 pafname = "unknown"; 1111 break; 1112 } 1113 1114 switch (pifasa->sa.sa_family) { 1115 case AF_INET6: 1116#ifdef INET6 1117 { 1118 const char *p = 1119 inet6_n2a(&pifasa->sin6.sin6_addr); 1120 strlcpy(addrbuf, p, sizeof(addrbuf)); 1121 break; 1122 } 1123#else 1124 /* FALLTHROUGH */ 1125#endif 1126 case AF_INET: 1127 case AF_LINK: 1128 error = getnameinfo(&pifasa->sa, 1129 pifasa->sa.sa_len, 1130 addrbuf, sizeof(addrbuf), NULL, 0, 1131 NI_NUMERICHOST); 1132 if (error) 1133 perror("getnameinfo"); 1134 break; 1135 default: 1136 addrbuf[0] = '\0'; 1137 break; 1138 } 1139 1140 fprintf(stdout, "\t%s %s\n", pafname, addrbuf); 1141#ifdef INET 1142 /* 1143 * Print per-link IGMP information, if available. 1144 */ 1145 if (pifasa->sa.sa_family == AF_INET) { 1146 struct igmp_ifinfo igi; 1147 size_t mibsize, len; 1148 int mib[5]; 1149 1150 mibsize = sizeof(mib) / sizeof(mib[0]); 1151 if (sysctlnametomib("net.inet.igmp.ifinfo", 1152 mib, &mibsize) == -1) { 1153 perror("sysctlnametomib"); 1154 goto next_ifnet; 1155 } 1156 mib[mibsize] = thisifindex; 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)
|
1018next_ifnet: 1019#endif 1020 lastifasa = *pifasa; 1021 } 1022 1023 /* Print this group address. */ 1024#ifdef INET6 1025 if (pgsa->sa.sa_family == AF_INET6) { 1026 const char *p = inet6_n2a(&pgsa->sin6.sin6_addr); 1027 strlcpy(addrbuf, p, sizeof(addrbuf)); 1028 } else 1029#endif 1030 { 1031 error = getnameinfo(&pgsa->sa, pgsa->sa.sa_len, 1032 addrbuf, sizeof(addrbuf), NULL, 0, NI_NUMERICHOST); 1033 if (error) 1034 perror("getnameinfo"); 1035 } 1036 1037 fprintf(stdout, "\t\tgroup %s", addrbuf); 1038#ifdef INET 1039 if (pgsa->sa.sa_family == AF_INET) { 1040 inm_print_sources_sysctl(thisifindex, 1041 pgsa->sin.sin_addr); 1042 } 1043#endif
| 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) { 1200 const char *p = inet6_n2a(&pgsa->sin6.sin6_addr); 1201 strlcpy(addrbuf, p, sizeof(addrbuf)); 1202 } else 1203#endif 1204 { 1205 error = getnameinfo(&pgsa->sa, pgsa->sa.sa_len, 1206 addrbuf, sizeof(addrbuf), NULL, 0, NI_NUMERICHOST); 1207 if (error) 1208 perror("getnameinfo"); 1209 } 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
|
1044 fprintf(stdout, "\n"); 1045 1046 /* Link-layer mapping, if present. */ 1047 pllsa = (sockunion_t *)ifma->ifma_lladdr; 1048 if (pllsa != NULL) { 1049 error = getnameinfo(&pllsa->sa, pllsa->sa.sa_len, 1050 addrbuf, sizeof(addrbuf), NULL, 0, NI_NUMERICHOST); 1051 fprintf(stdout, "\t\t\tmcast-macaddr %s\n", addrbuf); 1052 } 1053 } 1054out: 1055 if (ifmap != NULL) 1056 freeifmaddrs(ifmap); 1057 if (ifap != NULL) 1058 freeifaddrs(ifap); 1059 1060 return (error); 1061}
| 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}
|