ifgroup.c revision 159781
198184Sgordon/*- 298184Sgordon * Copyright (c) 2006 Max Laier. All rights reserved. 398184Sgordon * 498184Sgordon * Redistribution and use in source and binary forms, with or without 598184Sgordon * modification, are permitted provided that the following conditions 698184Sgordon * are met: 798184Sgordon * 1. Redistributions of source code must retain the above copyright 898184Sgordon * notice, this list of conditions and the following disclaimer. 998184Sgordon * 2. Redistributions in binary form must reproduce the above copyright 1098184Sgordon * notice, this list of conditions and the following disclaimer in the 1198184Sgordon * documentation and/or other materials provided with the distribution. 1298184Sgordon * 1398184Sgordon * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1498184Sgordon * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1598184Sgordon * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1698184Sgordon * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1798184Sgordon * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1898184Sgordon * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19101851Sgordon * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2098184Sgordon * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21101851Sgordon * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22101851Sgordon * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23101851Sgordon * SUCH DAMAGE. 24101851Sgordon */ 25101851Sgordon 26101851Sgordon#ifndef lint 27101851Sgordonstatic const char rcsid[] = 28101851Sgordon "$FreeBSD: head/sbin/ifconfig/ifgroup.c 159781 2006-06-19 22:20:45Z mlaier $"; 29101851Sgordon#endif /* not lint */ 30101851Sgordon 31101851Sgordon#include <sys/types.h> 3298184Sgordon#include <sys/ioctl.h> 3398184Sgordon#include <sys/socket.h> 34#include <net/if.h> 35 36#include <ctype.h> 37#include <err.h> 38#include <errno.h> 39#include <stdio.h> 40#include <stdlib.h> 41#include <string.h> 42#include <unistd.h> 43 44#include "ifconfig.h" 45 46/* ARGSUSED */ 47static void 48setifgroup(const char *group_name, int d, int s, const struct afswtch *rafp) 49{ 50 struct ifgroupreq ifgr; 51 52 memset(&ifgr, 0, sizeof(ifgr)); 53 strlcpy(ifgr.ifgr_name, name, IFNAMSIZ); 54 55 if (group_name[0] && isdigit(group_name[strlen(group_name) - 1])) 56 errx(1, "setifgroup: group names may not end in a digit"); 57 58 if (strlcpy(ifgr.ifgr_group, group_name, IFNAMSIZ) >= IFNAMSIZ) 59 errx(1, "setifgroup: group name too long"); 60 if (ioctl(s, SIOCAIFGROUP, (caddr_t)&ifgr) == -1) 61 err(1," SIOCAIFGROUP"); 62} 63 64/* ARGSUSED */ 65static void 66unsetifgroup(const char *group_name, int d, int s, const struct afswtch *rafp) 67{ 68 struct ifgroupreq ifgr; 69 70 memset(&ifgr, 0, sizeof(ifgr)); 71 strlcpy(ifgr.ifgr_name, name, IFNAMSIZ); 72 73 if (group_name[0] && isdigit(group_name[strlen(group_name) - 1])) 74 errx(1, "unsetifgroup: group names may not end in a digit"); 75 76 if (strlcpy(ifgr.ifgr_group, group_name, IFNAMSIZ) >= IFNAMSIZ) 77 errx(1, "unsetifgroup: group name too long"); 78 if (ioctl(s, SIOCDIFGROUP, (caddr_t)&ifgr) == -1) 79 err(1, "SIOCDIFGROUP"); 80} 81 82static void 83getifgroups(int s) 84{ 85 int len, cnt; 86 struct ifgroupreq ifgr; 87 struct ifg_req *ifg; 88 89 if (!verbose) 90 return; 91 92 memset(&ifgr, 0, sizeof(ifgr)); 93 strlcpy(ifgr.ifgr_name, name, IFNAMSIZ); 94 95 if (ioctl(s, SIOCGIFGROUP, (caddr_t)&ifgr) == -1) { 96 if (errno == EINVAL || errno == ENOTTY) 97 return; 98 else 99 err(1, "SIOCGIFGROUP"); 100 } 101 102 len = ifgr.ifgr_len; 103 ifgr.ifgr_groups = 104 (struct ifg_req *)calloc(len / sizeof(struct ifg_req), 105 sizeof(struct ifg_req)); 106 if (ifgr.ifgr_groups == NULL) 107 err(1, "getifgroups"); 108 if (ioctl(s, SIOCGIFGROUP, (caddr_t)&ifgr) == -1) 109 err(1, "SIOCGIFGROUP"); 110 111 cnt = 0; 112 ifg = ifgr.ifgr_groups; 113 for (; ifg && len >= sizeof(struct ifg_req); ifg++) { 114 len -= sizeof(struct ifg_req); 115 if (strcmp(ifg->ifgrq_group, "all")) { 116 if (cnt == 0) 117 printf("\tgroups: "); 118 cnt++; 119 printf("%s ", ifg->ifgrq_group); 120 } 121 } 122 if (cnt) 123 printf("\n"); 124} 125 126static void 127printgroup(char *groupname) 128{ 129 struct ifgroupreq ifgr; 130 struct ifg_req *ifg; 131 int len, cnt = 0; 132 int s; 133 134 s = socket(AF_INET, SOCK_DGRAM, 0); 135 if (s == -1) 136 err(1, "socket(AF_INET,SOCK_DGRAM)"); 137 bzero(&ifgr, sizeof(ifgr)); 138 strlcpy(ifgr.ifgr_name, groupname, sizeof(ifgr.ifgr_name)); 139 if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr) == -1) { 140 if (errno == EINVAL || errno == ENOTTY || 141 errno == ENOENT) 142 exit(0); 143 else 144 err(1, "SIOCGIFGMEMB"); 145 } 146 147 len = ifgr.ifgr_len; 148 if ((ifgr.ifgr_groups = calloc(1, len)) == NULL) 149 err(1, "printgroup"); 150 if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr) == -1) 151 err(1, "SIOCGIFGMEMB"); 152 153 for (ifg = ifgr.ifgr_groups; ifg && len >= sizeof(struct ifg_req); 154 ifg++) { 155 len -= sizeof(struct ifg_req); 156 printf("%s\n", ifg->ifgrq_member); 157 cnt++; 158 } 159 free(ifgr.ifgr_groups); 160 161 exit(0); 162} 163 164static struct cmd group_cmds[] = { 165 DEF_CMD_ARG("group", setifgroup), 166 DEF_CMD_ARG("-group", unsetifgroup), 167}; 168static struct afswtch af_group = { 169 .af_name = "af_group", 170 .af_af = AF_UNSPEC, 171 .af_other_status = getifgroups, 172}; 173static struct option group_gopt = { "g:", "[-g groupname]", printgroup }; 174 175static __constructor void 176group_ctor(void) 177{ 178#define N(a) (sizeof(a) / sizeof(a[0])) 179 int i; 180 181 for (i = 0; i < N(group_cmds); i++) 182 cmd_register(&group_cmds[i]); 183 af_register(&af_group); 184 opt_register(&group_gopt); 185#undef N 186} 187