From 74b3a519f7c73314c1514d9fbf22c8dd6cebad8d Mon Sep 17 00:00:00 2001 From: Henning Brauer Date: Sun, 12 Jun 2005 00:41:34 +0000 Subject: add SIOCGIFGMEMB ioctl, returns a list of all interfaces who are member of the given group, markus ok --- sys/net/if.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) (limited to 'sys/net/if.c') 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) { -- cgit v1.2.3