Viewing multicast group membership?

Harti Brandt brandt at fokus.fraunhofer.de
Tue Nov 11 00:29:52 PST 2003


On Mon, 10 Nov 2003, Bruce M Simpson wrote:

BMS>On Mon, Nov 10, 2003 at 08:49:40PM +0100, Harti Brandt wrote:
BMS>> I have a patch that creates a sysctl that returns the per-interface
BMS>> multicast address lists that mimics the sysctl that returns the interface
BMS>> address lists. If you can wait until tomorrow I'll send you the patch.
BMS>> This is running for more than two years on all my machines.
BMS>
BMS>Sounds like what I was planning to do anyway. Ok, look forward to it. :^)

Here you are. This was even once (about a year ago) reviewed by someone,
but did make it into the tree, because I did not insist.

harti
-- 
harti brandt,
http://www.fokus.fraunhofer.de/research/cc/cats/employees/hartmut.brandt/private
brandt at fokus.fraunhofer.de, harti at freebsd.org
-------------- next part --------------
Index: sys/socket.h
===================================================================
RCS file: /export/cvs/freebsd/src/sys/sys/socket.h,v
retrieving revision 1.72
diff -u -r1.72 socket.h
--- sys/socket.h	5 Mar 2003 19:24:24 -0000	1.72
+++ sys/socket.h	11 Nov 2003 08:29:35 -0000
@@ -351,13 +351,15 @@
 #define NET_RT_DUMP	1		/* dump; may limit to a.f. */
 #define NET_RT_FLAGS	2		/* by flags, e.g. RESOLVING */
 #define NET_RT_IFLIST	3		/* survey interface list */
-#define	NET_RT_MAXID	4
+#define	NET_RT_IFMALIST	4		/* return multicast address list */
+#define	NET_RT_MAXID	5
 
 #define CTL_NET_RT_NAMES { \
 	{ 0, 0 }, \
 	{ "dump", CTLTYPE_STRUCT }, \
 	{ "flags", CTLTYPE_STRUCT }, \
 	{ "iflist", CTLTYPE_STRUCT }, \
+	{ "ifmalist", CTLTYPE_STRUCT }, \
 }
 #endif /* __BSD_VISIBLE */
 
Index: net/rtsock.c
===================================================================
RCS file: /export/cvs/freebsd/src/sys/net/rtsock.c,v
retrieving revision 1.94
diff -u -r1.94 rtsock.c
--- net/rtsock.c	8 Nov 2003 23:36:30 -0000	1.94
+++ net/rtsock.c	11 Nov 2003 08:29:35 -0000
@@ -85,6 +85,7 @@
 static int	rt_xaddrs(caddr_t, caddr_t, struct rt_addrinfo *);
 static int	sysctl_dumpentry(struct radix_node *rn, void *vw);
 static int	sysctl_iflist(int af, struct walkarg *w);
+static int	sysctl_ifmalist(int af, struct walkarg *w);
 static int	route_output(struct mbuf *, struct socket *);
 static void	rt_setmetrics(u_long, struct rt_metrics *, struct rt_metrics *);
 static void	rt_dispatch(struct mbuf *, struct sockaddr *);
@@ -684,6 +685,10 @@
 		len = sizeof(struct if_msghdr);
 		break;
 
+	case RTM_NEWMADDR:
+		len = sizeof(struct ifma_msghdr);
+		break;
+
 	default:
 		len = sizeof(struct rt_msghdr);
 	}
@@ -1014,6 +1019,59 @@
 	return (error);
 }
 
+int
+sysctl_ifmalist(af, w)
+	int	af;
+	register struct	walkarg *w;
+{
+	register struct ifnet *ifp;
+	struct ifmultiaddr *ifma;
+	struct	rt_addrinfo info;
+	int	len, error = 0;
+
+	bzero((caddr_t)&info, sizeof(info));
+	/* IFNET_RLOCK(); */		/* could sleep XXX */
+	TAILQ_FOREACH(ifp, &ifnet, if_link) {
+		if (w->w_arg && w->w_arg != ifp->if_index)
+			continue;
+		TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
+			if (af && af != ifma->ifma_addr->sa_family)
+				continue;
+			if (jailed(curproc->p_ucred) &&
+			    prison_if(curproc->p_ucred, ifma->ifma_addr))
+				continue;
+			info.rti_info[RTAX_IFA] = ifma->ifma_addr;
+			info.rti_info[RTAX_IFP] = NULL;
+			if (TAILQ_FIRST(&ifp->if_addrhead))
+				info.rti_info[RTAX_IFP] =
+				    TAILQ_FIRST(&ifp->if_addrhead)->ifa_addr;
+
+			info.rti_info[RTAX_GATEWAY] = NULL;
+			if (ifma->ifma_addr->sa_family != AF_LINK)
+				info.rti_info[RTAX_GATEWAY] = ifma->ifma_lladdr;
+
+			len = rt_msg2(RTM_NEWMADDR, &info, 0, w);
+			if (w->w_req && w->w_tmem) {
+				register struct ifma_msghdr *ifmam;
+
+				ifmam = (struct ifma_msghdr *)w->w_tmem;
+				ifmam->ifmam_index = ifma->ifma_ifp->if_index;
+				ifmam->ifmam_flags = 0;
+				ifmam->ifmam_addrs = info.rti_addrs;
+				error = SYSCTL_OUT(w->w_req, w->w_tmem, len);
+				if (error)
+					goto done;
+			}
+		}
+		info.rti_info[RTAX_IFA] = NULL;
+		info.rti_info[RTAX_IFP] = NULL;
+		info.rti_info[RTAX_GATEWAY] = NULL;
+	}
+done:
+	/* IFNET_RUNLOCK(); */ /* XXX */
+	return (error);
+}
+
 static int
 sysctl_rtsock(SYSCTL_HANDLER_ARGS)
 {
@@ -1066,6 +1124,11 @@
 
 	case NET_RT_IFLIST:
 		error = sysctl_iflist(af, &w);
+		break;
+
+	case NET_RT_IFMALIST:
+		error = sysctl_ifmalist(af, &w);
+		break;
 	}
 	splx(s);
 	if (w.w_tmem)


More information about the freebsd-net mailing list