summaryrefslogtreecommitdiffstats
path: root/freebsd-userspace/commands/sbin/ifconfig/ifgroup.c
diff options
context:
space:
mode:
Diffstat (limited to 'freebsd-userspace/commands/sbin/ifconfig/ifgroup.c')
-rw-r--r--freebsd-userspace/commands/sbin/ifconfig/ifgroup.c186
1 files changed, 186 insertions, 0 deletions
diff --git a/freebsd-userspace/commands/sbin/ifconfig/ifgroup.c b/freebsd-userspace/commands/sbin/ifconfig/ifgroup.c
new file mode 100644
index 00000000..9eaac3b6
--- /dev/null
+++ b/freebsd-userspace/commands/sbin/ifconfig/ifgroup.c
@@ -0,0 +1,186 @@
+/*-
+ * Copyright (c) 2006 Max Laier. 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 */
+
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <net/if.h>
+
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "ifconfig.h"
+
+/* ARGSUSED */
+static void
+setifgroup(const char *group_name, int d, int s, const struct afswtch *rafp)
+{
+ struct ifgroupreq ifgr;
+
+ memset(&ifgr, 0, sizeof(ifgr));
+ strlcpy(ifgr.ifgr_name, name, IFNAMSIZ);
+
+ if (group_name[0] && isdigit(group_name[strlen(group_name) - 1]))
+ errx(1, "setifgroup: group names may not end in a digit");
+
+ if (strlcpy(ifgr.ifgr_group, group_name, IFNAMSIZ) >= IFNAMSIZ)
+ errx(1, "setifgroup: group name too long");
+ if (ioctl(s, SIOCAIFGROUP, (caddr_t)&ifgr) == -1)
+ err(1," SIOCAIFGROUP");
+}
+
+/* ARGSUSED */
+static void
+unsetifgroup(const char *group_name, int d, int s, const struct afswtch *rafp)
+{
+ struct ifgroupreq ifgr;
+
+ memset(&ifgr, 0, sizeof(ifgr));
+ strlcpy(ifgr.ifgr_name, name, IFNAMSIZ);
+
+ if (group_name[0] && isdigit(group_name[strlen(group_name) - 1]))
+ errx(1, "unsetifgroup: group names may not end in a digit");
+
+ if (strlcpy(ifgr.ifgr_group, group_name, IFNAMSIZ) >= IFNAMSIZ)
+ errx(1, "unsetifgroup: group name too long");
+ if (ioctl(s, SIOCDIFGROUP, (caddr_t)&ifgr) == -1)
+ err(1, "SIOCDIFGROUP");
+}
+
+static void
+getifgroups(int s)
+{
+ int len, cnt;
+ struct ifgroupreq ifgr;
+ struct ifg_req *ifg;
+
+ if (!verbose)
+ return;
+
+ memset(&ifgr, 0, sizeof(ifgr));
+ strlcpy(ifgr.ifgr_name, name, IFNAMSIZ);
+
+ if (ioctl(s, SIOCGIFGROUP, (caddr_t)&ifgr) == -1) {
+ if (errno == EINVAL || errno == ENOTTY)
+ return;
+ else
+ err(1, "SIOCGIFGROUP");
+ }
+
+ len = ifgr.ifgr_len;
+ ifgr.ifgr_groups =
+ (struct ifg_req *)calloc(len / sizeof(struct ifg_req),
+ sizeof(struct ifg_req));
+ if (ifgr.ifgr_groups == NULL)
+ err(1, "getifgroups");
+ if (ioctl(s, SIOCGIFGROUP, (caddr_t)&ifgr) == -1)
+ err(1, "SIOCGIFGROUP");
+
+ cnt = 0;
+ ifg = ifgr.ifgr_groups;
+ for (; ifg && len >= sizeof(struct ifg_req); ifg++) {
+ len -= sizeof(struct ifg_req);
+ if (strcmp(ifg->ifgrq_group, "all")) {
+ if (cnt == 0)
+ printf("\tgroups: ");
+ cnt++;
+ printf("%s ", ifg->ifgrq_group);
+ }
+ }
+ if (cnt)
+ printf("\n");
+}
+
+static void
+printgroup(const char *groupname)
+{
+ struct ifgroupreq ifgr;
+ struct ifg_req *ifg;
+ int len, cnt = 0;
+ int s;
+
+ s = socket(AF_LOCAL, SOCK_DGRAM, 0);
+ if (s == -1)
+ err(1, "socket(AF_LOCAL,SOCK_DGRAM)");
+ bzero(&ifgr, sizeof(ifgr));
+ strlcpy(ifgr.ifgr_name, groupname, sizeof(ifgr.ifgr_name));
+ if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr) == -1) {
+ if (errno == EINVAL || errno == ENOTTY ||
+ errno == ENOENT)
+ exit(0);
+ else
+ err(1, "SIOCGIFGMEMB");
+ }
+
+ len = ifgr.ifgr_len;
+ if ((ifgr.ifgr_groups = calloc(1, len)) == NULL)
+ err(1, "printgroup");
+ if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr) == -1)
+ err(1, "SIOCGIFGMEMB");
+
+ for (ifg = ifgr.ifgr_groups; ifg && len >= sizeof(struct ifg_req);
+ ifg++) {
+ len -= sizeof(struct ifg_req);
+ printf("%s\n", ifg->ifgrq_member);
+ cnt++;
+ }
+ free(ifgr.ifgr_groups);
+
+ exit(0);
+}
+
+static struct cmd group_cmds[] = {
+ DEF_CMD_ARG("group", setifgroup),
+ DEF_CMD_ARG("-group", unsetifgroup),
+};
+static struct afswtch af_group = {
+ .af_name = "af_group",
+ .af_af = AF_UNSPEC,
+ .af_other_status = getifgroups,
+};
+static struct option group_gopt = { "g:", "[-g groupname]", printgroup };
+
+static __constructor void
+group_ctor(void)
+{
+#define N(a) (sizeof(a) / sizeof(a[0]))
+ int i;
+
+ for (i = 0; i < N(group_cmds); i++)
+ cmd_register(&group_cmds[i]);
+ af_register(&af_group);
+ opt_register(&group_gopt);
+#undef N
+}