ifgroup.c revision 159781
1159781Smlaier/*- 2159781Smlaier * Copyright (c) 2006 Max Laier. All rights reserved. 3159781Smlaier * 4159781Smlaier * Redistribution and use in source and binary forms, with or without 5159781Smlaier * modification, are permitted provided that the following conditions 6159781Smlaier * are met: 7159781Smlaier * 1. Redistributions of source code must retain the above copyright 8159781Smlaier * notice, this list of conditions and the following disclaimer. 9159781Smlaier * 2. Redistributions in binary form must reproduce the above copyright 10159781Smlaier * notice, this list of conditions and the following disclaimer in the 11159781Smlaier * documentation and/or other materials provided with the distribution. 12159781Smlaier * 13159781Smlaier * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 14159781Smlaier * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15159781Smlaier * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16159781Smlaier * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17159781Smlaier * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18159781Smlaier * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19159781Smlaier * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20159781Smlaier * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21159781Smlaier * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22159781Smlaier * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23159781Smlaier * SUCH DAMAGE. 24159781Smlaier */ 25159781Smlaier 26159781Smlaier#ifndef lint 27159781Smlaierstatic const char rcsid[] = 28159781Smlaier "$FreeBSD: head/sbin/ifconfig/ifgroup.c 159781 2006-06-19 22:20:45Z mlaier $"; 29159781Smlaier#endif /* not lint */ 30159781Smlaier 31159781Smlaier#include <sys/types.h> 32159781Smlaier#include <sys/ioctl.h> 33159781Smlaier#include <sys/socket.h> 34159781Smlaier#include <net/if.h> 35159781Smlaier 36159781Smlaier#include <ctype.h> 37159781Smlaier#include <err.h> 38159781Smlaier#include <errno.h> 39159781Smlaier#include <stdio.h> 40159781Smlaier#include <stdlib.h> 41159781Smlaier#include <string.h> 42159781Smlaier#include <unistd.h> 43159781Smlaier 44159781Smlaier#include "ifconfig.h" 45159781Smlaier 46159781Smlaier/* ARGSUSED */ 47159781Smlaierstatic void 48159781Smlaiersetifgroup(const char *group_name, int d, int s, const struct afswtch *rafp) 49159781Smlaier{ 50159781Smlaier struct ifgroupreq ifgr; 51159781Smlaier 52159781Smlaier memset(&ifgr, 0, sizeof(ifgr)); 53159781Smlaier strlcpy(ifgr.ifgr_name, name, IFNAMSIZ); 54159781Smlaier 55159781Smlaier if (group_name[0] && isdigit(group_name[strlen(group_name) - 1])) 56159781Smlaier errx(1, "setifgroup: group names may not end in a digit"); 57159781Smlaier 58159781Smlaier if (strlcpy(ifgr.ifgr_group, group_name, IFNAMSIZ) >= IFNAMSIZ) 59159781Smlaier errx(1, "setifgroup: group name too long"); 60159781Smlaier if (ioctl(s, SIOCAIFGROUP, (caddr_t)&ifgr) == -1) 61159781Smlaier err(1," SIOCAIFGROUP"); 62159781Smlaier} 63159781Smlaier 64159781Smlaier/* ARGSUSED */ 65159781Smlaierstatic void 66159781Smlaierunsetifgroup(const char *group_name, int d, int s, const struct afswtch *rafp) 67159781Smlaier{ 68159781Smlaier struct ifgroupreq ifgr; 69159781Smlaier 70159781Smlaier memset(&ifgr, 0, sizeof(ifgr)); 71159781Smlaier strlcpy(ifgr.ifgr_name, name, IFNAMSIZ); 72159781Smlaier 73159781Smlaier if (group_name[0] && isdigit(group_name[strlen(group_name) - 1])) 74159781Smlaier errx(1, "unsetifgroup: group names may not end in a digit"); 75159781Smlaier 76159781Smlaier if (strlcpy(ifgr.ifgr_group, group_name, IFNAMSIZ) >= IFNAMSIZ) 77159781Smlaier errx(1, "unsetifgroup: group name too long"); 78159781Smlaier if (ioctl(s, SIOCDIFGROUP, (caddr_t)&ifgr) == -1) 79159781Smlaier err(1, "SIOCDIFGROUP"); 80159781Smlaier} 81159781Smlaier 82159781Smlaierstatic void 83159781Smlaiergetifgroups(int s) 84159781Smlaier{ 85159781Smlaier int len, cnt; 86159781Smlaier struct ifgroupreq ifgr; 87159781Smlaier struct ifg_req *ifg; 88159781Smlaier 89159781Smlaier if (!verbose) 90159781Smlaier return; 91159781Smlaier 92159781Smlaier memset(&ifgr, 0, sizeof(ifgr)); 93159781Smlaier strlcpy(ifgr.ifgr_name, name, IFNAMSIZ); 94159781Smlaier 95159781Smlaier if (ioctl(s, SIOCGIFGROUP, (caddr_t)&ifgr) == -1) { 96159781Smlaier if (errno == EINVAL || errno == ENOTTY) 97159781Smlaier return; 98159781Smlaier else 99159781Smlaier err(1, "SIOCGIFGROUP"); 100159781Smlaier } 101159781Smlaier 102159781Smlaier len = ifgr.ifgr_len; 103159781Smlaier ifgr.ifgr_groups = 104159781Smlaier (struct ifg_req *)calloc(len / sizeof(struct ifg_req), 105159781Smlaier sizeof(struct ifg_req)); 106159781Smlaier if (ifgr.ifgr_groups == NULL) 107159781Smlaier err(1, "getifgroups"); 108159781Smlaier if (ioctl(s, SIOCGIFGROUP, (caddr_t)&ifgr) == -1) 109159781Smlaier err(1, "SIOCGIFGROUP"); 110159781Smlaier 111159781Smlaier cnt = 0; 112159781Smlaier ifg = ifgr.ifgr_groups; 113159781Smlaier for (; ifg && len >= sizeof(struct ifg_req); ifg++) { 114159781Smlaier len -= sizeof(struct ifg_req); 115159781Smlaier if (strcmp(ifg->ifgrq_group, "all")) { 116159781Smlaier if (cnt == 0) 117159781Smlaier printf("\tgroups: "); 118159781Smlaier cnt++; 119159781Smlaier printf("%s ", ifg->ifgrq_group); 120159781Smlaier } 121159781Smlaier } 122159781Smlaier if (cnt) 123159781Smlaier printf("\n"); 124159781Smlaier} 125159781Smlaier 126159781Smlaierstatic void 127159781Smlaierprintgroup(char *groupname) 128159781Smlaier{ 129159781Smlaier struct ifgroupreq ifgr; 130159781Smlaier struct ifg_req *ifg; 131159781Smlaier int len, cnt = 0; 132159781Smlaier int s; 133159781Smlaier 134159781Smlaier s = socket(AF_INET, SOCK_DGRAM, 0); 135159781Smlaier if (s == -1) 136159781Smlaier err(1, "socket(AF_INET,SOCK_DGRAM)"); 137159781Smlaier bzero(&ifgr, sizeof(ifgr)); 138159781Smlaier strlcpy(ifgr.ifgr_name, groupname, sizeof(ifgr.ifgr_name)); 139159781Smlaier if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr) == -1) { 140159781Smlaier if (errno == EINVAL || errno == ENOTTY || 141159781Smlaier errno == ENOENT) 142159781Smlaier exit(0); 143159781Smlaier else 144159781Smlaier err(1, "SIOCGIFGMEMB"); 145159781Smlaier } 146159781Smlaier 147159781Smlaier len = ifgr.ifgr_len; 148159781Smlaier if ((ifgr.ifgr_groups = calloc(1, len)) == NULL) 149159781Smlaier err(1, "printgroup"); 150159781Smlaier if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr) == -1) 151159781Smlaier err(1, "SIOCGIFGMEMB"); 152159781Smlaier 153159781Smlaier for (ifg = ifgr.ifgr_groups; ifg && len >= sizeof(struct ifg_req); 154159781Smlaier ifg++) { 155159781Smlaier len -= sizeof(struct ifg_req); 156159781Smlaier printf("%s\n", ifg->ifgrq_member); 157159781Smlaier cnt++; 158159781Smlaier } 159159781Smlaier free(ifgr.ifgr_groups); 160159781Smlaier 161159781Smlaier exit(0); 162159781Smlaier} 163159781Smlaier 164159781Smlaierstatic struct cmd group_cmds[] = { 165159781Smlaier DEF_CMD_ARG("group", setifgroup), 166159781Smlaier DEF_CMD_ARG("-group", unsetifgroup), 167159781Smlaier}; 168159781Smlaierstatic struct afswtch af_group = { 169159781Smlaier .af_name = "af_group", 170159781Smlaier .af_af = AF_UNSPEC, 171159781Smlaier .af_other_status = getifgroups, 172159781Smlaier}; 173159781Smlaierstatic struct option group_gopt = { "g:", "[-g groupname]", printgroup }; 174159781Smlaier 175159781Smlaierstatic __constructor void 176159781Smlaiergroup_ctor(void) 177159781Smlaier{ 178159781Smlaier#define N(a) (sizeof(a) / sizeof(a[0])) 179159781Smlaier int i; 180159781Smlaier 181159781Smlaier for (i = 0; i < N(group_cmds); i++) 182159781Smlaier cmd_register(&group_cmds[i]); 183159781Smlaier af_register(&af_group); 184159781Smlaier opt_register(&group_gopt); 185159781Smlaier#undef N 186159781Smlaier} 187