diff options
author | bms <bms@FreeBSD.org> | 2004-03-25 08:43:59 +0000 |
---|---|---|
committer | bms <bms@FreeBSD.org> | 2004-03-25 08:43:59 +0000 |
commit | af30ef411877ee85c0a9a04733de71036b589e8c (patch) | |
tree | a695bae8ffb01d7075aed8972058d23973039eab /usr.bin/netstat | |
parent | 57efe0d11e10072b9cc7f8b04f3de0bb7e2dd356 (diff) | |
download | FreeBSD-src-af30ef411877ee85c0a9a04733de71036b589e8c.zip FreeBSD-src-af30ef411877ee85c0a9a04733de71036b589e8c.tar.gz |
Teach netstat(1) how to print the multicast group memberships present
within the running system.
Sponsored by: Ralf the Wonder Llama
Diffstat (limited to 'usr.bin/netstat')
-rw-r--r-- | usr.bin/netstat/Makefile | 2 | ||||
-rw-r--r-- | usr.bin/netstat/main.c | 2 | ||||
-rw-r--r-- | usr.bin/netstat/mcast.c | 150 | ||||
-rw-r--r-- | usr.bin/netstat/netstat.h | 2 |
4 files changed, 154 insertions, 2 deletions
diff --git a/usr.bin/netstat/Makefile b/usr.bin/netstat/Makefile index ba9adf4..760cc4e 100644 --- a/usr.bin/netstat/Makefile +++ b/usr.bin/netstat/Makefile @@ -2,7 +2,7 @@ # $FreeBSD$ PROG= netstat -SRCS= if.c inet.c inet6.c main.c mbuf.c mroute.c ipx.c route.c \ +SRCS= if.c inet.c inet6.c main.c mbuf.c mroute.c mcast.c ipx.c route.c \ unix.c atalk.c netgraph.c mroute6.c ipsec.c CFLAGS+=-DIPSEC CFLAGS+=-DINET6 diff --git a/usr.bin/netstat/main.c b/usr.bin/netstat/main.c index b70dbef..b665bfe 100644 --- a/usr.bin/netstat/main.c +++ b/usr.bin/netstat/main.c @@ -493,6 +493,8 @@ main(int argc, char *argv[]) nl[N_MIF6TABLE].n_value); #endif } + putchar('\n'); + ifmalist_dump(); exit(0); } diff --git a/usr.bin/netstat/mcast.c b/usr.bin/netstat/mcast.c new file mode 100644 index 0000000..6a7afab --- /dev/null +++ b/usr.bin/netstat/mcast.c @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2004 Bruce M Simpson <bms@spc.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#ifndef lint +static const char rcsid[] = + "$FreeBSD$"; +#endif /* not lint */ + +/* + * Print the system's current multicast group memberships. + */ + +#include <sys/types.h> +#include <sys/socket.h> + +#include <net/if.h> +#include <net/if_var.h> +#include <net/if_mib.h> +#include <net/if_types.h> +#include <net/if_dl.h> +#include <net/route.h> +#include <netinet/in.h> +#include <netinet/if_ether.h> +#include <arpa/inet.h> +#include <netdb.h> + +#include <ctype.h> +#include <err.h> +#include <ifaddrs.h> +#include <sysexits.h> + +#include <stddef.h> +#include <stdarg.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "netstat.h" + +union sockunion { + struct sockaddr_storage ss; + struct sockaddr sa; + struct sockaddr_dl sdl; + struct sockaddr_in sin; + struct sockaddr_in6 sin6; +}; +typedef union sockunion sockunion_t; + +#define MYIFNAME_SIZE 128 + +void +ifmalist_dump(void) +{ + struct ifmaddrs *ifmap, *ifma; + sockunion_t *psa; + char myifname[MYIFNAME_SIZE]; + char addrbuf[INET6_ADDRSTRLEN]; + char *pcolon; + void *addr; + char *pifname, *plladdr, *pgroup; + + if (getifmaddrs(&ifmap)) + err(EX_OSERR, "getifmaddrs"); + + fputs("IPv4/IPv6 Multicast Group Memberships\n", stdout); + fprintf(stdout, "%-20s\t%-16s\t%s\n", "Group", "Gateway", "Netif"); + + for (ifma = ifmap; ifma; ifma = ifma->ifma_next) { + + if (ifma->ifma_name == NULL || ifma->ifma_addr == NULL) + continue; + + /* Group address */ + psa = (sockunion_t *)ifma->ifma_addr; + switch (psa->sa.sa_family) { + case AF_INET: + pgroup = inet_ntoa(psa->sin.sin_addr); + break; + case AF_INET6: + addr = &psa->sin6.sin6_addr; + inet_ntop(psa->sa.sa_family, addr, addrbuf, + sizeof(addrbuf)); + pgroup = addrbuf; + break; + default: + continue; /* XXX */ + } + + /* 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; + } + } 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); + pcolon = strchr(myifname, ':'); + if (pcolon) + *pcolon = '\0'; + pifname = myifname; + break; + default: + pifname = ""; + break; + } + + fprintf(stdout, "%-20s\t%-16s\t%s\n", pgroup, plladdr, pifname); + } + + freeifmaddrs(ifmap); +} diff --git a/usr.bin/netstat/netstat.h b/usr.bin/netstat/netstat.h index ded6f78..c59b7e8 100644 --- a/usr.bin/netstat/netstat.h +++ b/usr.bin/netstat/netstat.h @@ -149,6 +149,6 @@ void tp_protopr(u_long, const char *, int); void tp_inproto(u_long); void tp_stats(caddr_t, caddr_t); +void ifmalist_dump(void); void mroutepr(u_long, u_long); void mrt_stats(u_long); - |