summaryrefslogtreecommitdiff
path: root/sys/net/if.c
diff options
context:
space:
mode:
authorHenning Brauer <henning@cvs.openbsd.org>2005-06-12 00:41:34 +0000
committerHenning Brauer <henning@cvs.openbsd.org>2005-06-12 00:41:34 +0000
commit74b3a519f7c73314c1514d9fbf22c8dd6cebad8d (patch)
tree093348e3d0fe5db40e36630ddea59444f4c8fd7f /sys/net/if.c
parentaf0efa7ccb2bbf2231a0630eb91facc24e5d4f96 (diff)
add SIOCGIFGMEMB ioctl, returns a list of all interfaces who are member of
the given group, markus ok
Diffstat (limited to 'sys/net/if.c')
-rw-r--r--sys/net/if.c48
1 files changed, 47 insertions, 1 deletions
diff --git a/sys/net/if.c b/sys/net/if.c
index 8cc996aa18f..36ccbee3ecd 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if.c,v 1.132 2005/06/08 07:36:50 henning Exp $ */
+/* $OpenBSD: if.c,v 1.133 2005/06/12 00:41:33 henning Exp $ */
/* $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $ */
/*
@@ -136,6 +136,9 @@ int if_detached_ioctl(struct ifnet *, u_long, caddr_t);
int if_detached_init(struct ifnet *);
void if_detached_watchdog(struct ifnet *);
+int if_getgroup(caddr_t, struct ifnet *);
+int if_getgroupmembers(caddr_t);
+
int if_clone_list(struct if_clonereq *);
struct if_clone *if_clone_lookup(const char *, int *);
@@ -1194,6 +1197,8 @@ ifioctl(struct socket *so, u_long cmd, caddr_t data, struct proc *p)
if_clone_destroy(ifr->ifr_name));
case SIOCIFGCLONERS:
return (if_clone_list((struct if_clonereq *)data));
+ case SIOCGIFGMEMB:
+ return (if_getgroupmembers(data));
}
ifp = ifunit(ifr->ifr_name);
@@ -1715,6 +1720,47 @@ if_getgroup(caddr_t data, struct ifnet *ifp)
return (0);
}
+/*
+ * Stores all members of a group in memory pointed to by data
+ */
+int
+if_getgroupmembers(caddr_t data)
+{
+ struct ifgroupreq *ifgr = (struct ifgroupreq *)data;
+ struct ifg_group *ifg;
+ struct ifg_member *ifgm;
+ struct ifg_req ifgrq, *ifgp;
+ int len, error;
+
+ TAILQ_FOREACH(ifg, &ifg_head, ifg_next)
+ if (!strcmp(ifg->ifg_group, ifgr->ifgr_name))
+ break;
+ if (ifg == NULL)
+ return (ENOENT);
+
+ if (ifgr->ifgr_len == 0) {
+ TAILQ_FOREACH(ifgm, &ifg->ifg_members, ifgm_next)
+ ifgr->ifgr_len += sizeof(ifgrq);
+ return (0);
+ }
+
+ len = ifgr->ifgr_len;
+ ifgp = ifgr->ifgr_groups;
+ TAILQ_FOREACH(ifgm, &ifg->ifg_members, ifgm_next) {
+ if (len < sizeof(ifgrq))
+ return (EINVAL);
+ strlcpy(ifgrq.ifgrq_member, ifgm->ifgm_ifp->if_xname,
+ sizeof(ifgrq.ifgrq_member));
+ if ((error = copyout((caddr_t)&ifgrq, (caddr_t)ifgp,
+ sizeof(struct ifg_req))))
+ return (error);
+ len -= sizeof(ifgrq);
+ ifgp++;
+ }
+
+ return (0);
+}
+
void
if_group_routechange(struct sockaddr *dst, struct sockaddr *mask)
{