diff options
author | bms <bms@FreeBSD.org> | 2007-02-21 13:59:21 +0000 |
---|---|---|
committer | bms <bms@FreeBSD.org> | 2007-02-21 13:59:21 +0000 |
commit | b9c5bc7e709393df8e88981b34eff0d954f92697 (patch) | |
tree | e478a30c19cc1a7b322c728d3bddcc9476e336df /usr.bin | |
parent | 37b367b5c82c622bab5e7eb62e33bf7a72b20b9c (diff) | |
download | FreeBSD-src-b9c5bc7e709393df8e88981b34eff0d954f92697.zip FreeBSD-src-b9c5bc7e709393df8e88981b34eff0d954f92697.tar.gz |
Update host-mode multicast group information output.
Display IPv4 and IPv6 memberships separately.
Obey the MK_INET6_SUPPORT flag.
Display link-layer memberships.
Use addr2ascii() to correctly print non-IEEE 802 sockaddr_dl instances.
Eliminate redundant switch..case blocks.
Update copyright.
Misc style changes.
MFC after: 3 weeks
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/netstat/mcast.c | 120 |
1 files changed, 87 insertions, 33 deletions
diff --git a/usr.bin/netstat/mcast.c b/usr.bin/netstat/mcast.c index afd382a..cc12f09 100644 --- a/usr.bin/netstat/mcast.c +++ b/usr.bin/netstat/mcast.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Bruce M Simpson <bms@spc.org> + * Copyright (c) 2007 Bruce M. Simpson <bms@FreeBSD.org> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,7 +29,8 @@ __FBSDID("$FreeBSD$"); /* - * Print the system's current multicast group memberships. + * Print the running system's current multicast group memberships. + * As this relies on getifmaddrs(), it may not be used with a core file. */ #include <sys/types.h> @@ -69,24 +70,40 @@ union sockunion { }; typedef union sockunion sockunion_t; -#define MYIFNAME_SIZE 128 +void ifmalist_dump_af(const struct ifmaddrs * const ifmap, int const af); void -ifmalist_dump(void) +ifmalist_dump_af(const struct ifmaddrs * const ifmap, int const af) { - struct ifmaddrs *ifmap, *ifma; + const struct ifmaddrs *ifma; sockunion_t *psa; - char myifname[MYIFNAME_SIZE]; + char myifname[IFNAMSIZ]; char addrbuf[INET6_ADDRSTRLEN]; char *pcolon; - void *addr; - char *pifname, *plladdr, *pgroup; - - if (getifmaddrs(&ifmap)) - err(EX_OSERR, "getifmaddrs"); + char *pafname, *pifname, *plladdr, *pgroup; +#ifdef INET6 + void *in6addr; +#endif + + switch (af) { + case AF_INET: + pafname = "IPv4"; + break; +#ifdef INET6 + case AF_INET6: + pafname = "IPv6"; + break; +#endif + case AF_LINK: + pafname = "Link-layer"; + break; + default: + return; /* XXX */ + } - fputs("IPv4/IPv6 Multicast Group Memberships\n", stdout); - fprintf(stdout, "%-20s\t%-16s\t%s\n", "Group", "Gateway", "Netif"); + fprintf(stdout, "%s Multicast Group Memberships\n", pafname); + fprintf(stdout, "%-20s\t%-16s\t%s\n", "Group", "Link-layer Address", + "Netif"); for (ifma = ifmap; ifma; ifma = ifma->ifma_next) { @@ -95,16 +112,33 @@ ifmalist_dump(void) /* Group address */ psa = (sockunion_t *)ifma->ifma_addr; + if (psa->sa.sa_family != af) + continue; + switch (psa->sa.sa_family) { case AF_INET: pgroup = inet_ntoa(psa->sin.sin_addr); break; +#ifdef INET6 case AF_INET6: - addr = &psa->sin6.sin6_addr; - inet_ntop(psa->sa.sa_family, addr, addrbuf, + in6addr = &psa->sin6.sin6_addr; + inet_ntop(psa->sa.sa_family, in6addr, addrbuf, sizeof(addrbuf)); pgroup = addrbuf; break; +#endif + case AF_LINK: + if ((psa->sdl.sdl_alen == ETHER_ADDR_LEN) || + (psa->sdl.sdl_type == IFT_ETHER)) { + pgroup = +ether_ntoa((struct ether_addr *)&psa->sdl.sdl_data); + } else { + pgroup = addr2ascii(AF_LINK, + &psa->sdl, + sizeof(struct sockaddr_dl), + addrbuf); + } + break; default: continue; /* XXX */ } @@ -112,38 +146,58 @@ ifmalist_dump(void) /* Link-layer mapping, if any */ psa = (sockunion_t *)ifma->ifma_lladdr; if (psa != NULL) { - switch (psa->sa.sa_family) { - case AF_INET: - plladdr = inet_ntoa(psa->sin.sin_addr); - break; - case AF_LINK: - if (psa->sdl.sdl_type == IFT_ETHER) - plladdr = ether_ntoa((struct ether_addr *)&psa->sdl.sdl_data); - else - plladdr = link_ntoa(&psa->sdl); - break; + if (psa->sa.sa_family == AF_LINK) { + if ((psa->sdl.sdl_alen == ETHER_ADDR_LEN) || + (psa->sdl.sdl_type == IFT_ETHER)) { + /* IEEE 802 */ + plladdr = +ether_ntoa((struct ether_addr *)&psa->sdl.sdl_data); + } else { + /* something more exotic */ + plladdr = addr2ascii(AF_LINK, + &psa->sdl, + sizeof(struct sockaddr_dl), + addrbuf); + } + } else { + /* not a link-layer address */ + plladdr = "<invalid>"; } - } else + } else { plladdr = "<none>"; + } /* Interface upon which the membership exists */ psa = (sockunion_t *)ifma->ifma_name; - switch (psa->sa.sa_family) { - case AF_LINK: - strlcpy(myifname, link_ntoa(&psa->sdl), - MYIFNAME_SIZE); + if (psa != NULL && psa->sa.sa_family == AF_LINK) { + strlcpy(myifname, link_ntoa(&psa->sdl), IFNAMSIZ); pcolon = strchr(myifname, ':'); if (pcolon) *pcolon = '\0'; pifname = myifname; - break; - default: + } else { pifname = ""; - break; } fprintf(stdout, "%-20s\t%-16s\t%s\n", pgroup, plladdr, pifname); } +} + +void +ifmalist_dump(void) +{ + struct ifmaddrs *ifmap; + + if (getifmaddrs(&ifmap)) + err(EX_OSERR, "getifmaddrs"); + + ifmalist_dump_af(ifmap, AF_LINK); + fputs("\n", stdout); + ifmalist_dump_af(ifmap, AF_INET); +#ifdef INET6 + fputs("\n", stdout); + ifmalist_dump_af(ifmap, AF_INET6); +#endif freeifmaddrs(ifmap); } |