ifclone.c revision 160196
1138593Ssam/* 2138593Ssam * Copyright (c) 1983, 1993 3138593Ssam * The Regents of the University of California. All rights reserved. 4138593Ssam * 5138593Ssam * Redistribution and use in source and binary forms, with or without 6138593Ssam * modification, are permitted provided that the following conditions 7138593Ssam * are met: 8138593Ssam * 1. Redistributions of source code must retain the above copyright 9138593Ssam * notice, this list of conditions and the following disclaimer. 10138593Ssam * 2. Redistributions in binary form must reproduce the above copyright 11138593Ssam * notice, this list of conditions and the following disclaimer in the 12138593Ssam * documentation and/or other materials provided with the distribution. 13138593Ssam * 4. Neither the name of the University nor the names of its contributors 14138593Ssam * may be used to endorse or promote products derived from this software 15138593Ssam * without specific prior written permission. 16138593Ssam * 17138593Ssam * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18138593Ssam * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19138593Ssam * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20138593Ssam * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21138593Ssam * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22138593Ssam * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23138593Ssam * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24138593Ssam * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25138593Ssam * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26138593Ssam * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27138593Ssam * SUCH DAMAGE. 28138593Ssam */ 29138593Ssam 30138593Ssam#ifndef lint 31138593Ssamstatic const char rcsid[] = 32138593Ssam "$FreeBSD: head/sbin/ifconfig/ifclone.c 160196 2006-07-09 06:10:23Z sam $"; 33138593Ssam#endif /* not lint */ 34138593Ssam 35138593Ssam#include <sys/types.h> 36138593Ssam#include <sys/ioctl.h> 37138593Ssam#include <sys/socket.h> 38138593Ssam#include <net/if.h> 39138593Ssam 40138593Ssam#include <err.h> 41138593Ssam#include <stdio.h> 42138593Ssam#include <stdlib.h> 43138593Ssam#include <string.h> 44138593Ssam#include <unistd.h> 45138593Ssam 46138593Ssam#include "ifconfig.h" 47138593Ssam 48138593Ssamstatic void 49138593Ssamlist_cloners(void) 50138593Ssam{ 51138593Ssam struct if_clonereq ifcr; 52138593Ssam char *cp, *buf; 53138593Ssam int idx; 54138593Ssam int s; 55138593Ssam 56138593Ssam s = socket(AF_INET, SOCK_DGRAM, 0); 57138593Ssam if (s == -1) 58138593Ssam err(1, "socket(AF_INET,SOCK_DGRAM)"); 59138593Ssam 60138593Ssam memset(&ifcr, 0, sizeof(ifcr)); 61138593Ssam 62138593Ssam if (ioctl(s, SIOCIFGCLONERS, &ifcr) < 0) 63138593Ssam err(1, "SIOCIFGCLONERS for count"); 64138593Ssam 65138593Ssam buf = malloc(ifcr.ifcr_total * IFNAMSIZ); 66138593Ssam if (buf == NULL) 67138593Ssam err(1, "unable to allocate cloner name buffer"); 68138593Ssam 69138593Ssam ifcr.ifcr_count = ifcr.ifcr_total; 70138593Ssam ifcr.ifcr_buffer = buf; 71138593Ssam 72138593Ssam if (ioctl(s, SIOCIFGCLONERS, &ifcr) < 0) 73138593Ssam err(1, "SIOCIFGCLONERS for names"); 74138593Ssam 75138593Ssam /* 76138593Ssam * In case some disappeared in the mean time, clamp it down. 77138593Ssam */ 78138593Ssam if (ifcr.ifcr_count > ifcr.ifcr_total) 79138593Ssam ifcr.ifcr_count = ifcr.ifcr_total; 80138593Ssam 81138593Ssam for (cp = buf, idx = 0; idx < ifcr.ifcr_count; idx++, cp += IFNAMSIZ) { 82138593Ssam if (idx > 0) 83138593Ssam putchar(' '); 84138593Ssam printf("%s", cp); 85138593Ssam } 86138593Ssam 87138593Ssam putchar('\n'); 88138593Ssam free(buf); 89138593Ssam} 90138593Ssam 91160196Ssamstatic clone_callback_func *clone_cb = NULL; 92160196Ssam 93138593Ssamvoid 94160196Ssamclone_setcallback(clone_callback_func *p) 95138593Ssam{ 96160196Ssam if (clone_cb != NULL && clone_cb != p) 97160196Ssam errx(1, "conflicting device create parameters"); 98160196Ssam clone_cb = p; 99160196Ssam} 100138593Ssam 101160196Ssam/* 102160196Ssam * Do the actual clone operation. Any parameters must have been 103160196Ssam * setup by now. If a callback has been setup to do the work 104160196Ssam * then defer to it; otherwise do a simple create operation with 105160196Ssam * no parameters. 106160196Ssam */ 107160196Ssamstatic void 108160196Ssamifclonecreate(int s, void *arg) 109160196Ssam{ 110160196Ssam struct ifreq ifr; 111138593Ssam 112138593Ssam memset(&ifr, 0, sizeof(ifr)); 113138593Ssam (void) strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); 114160196Ssam if (clone_cb == NULL) { 115160196Ssam /* NB: no parameters */ 116160196Ssam if (ioctl(s, SIOCIFCREATE2, &ifr) < 0) 117160196Ssam err(1, "SIOCIFCREATE2"); 118160196Ssam } else { 119160196Ssam clone_cb(s, &ifr); 120160196Ssam } 121138593Ssam 122138593Ssam /* 123160196Ssam * If we get a different name back than we put in, print it. 124138593Ssam */ 125160196Ssam if (strncmp(name, ifr.ifr_name, sizeof(name)) != 0) { 126138593Ssam strlcpy(name, ifr.ifr_name, sizeof(name)); 127160196Ssam printf("%s\n", name); 128138593Ssam } 129160196Ssam} 130138593Ssam 131160196Ssamstatic 132160196SsamDECL_CMD_FUNC(clone_create, arg, d) 133160196Ssam{ 134160196Ssam callback_register(ifclonecreate, NULL); 135138593Ssam} 136138593Ssam 137160196Ssamstatic 138160196SsamDECL_CMD_FUNC(clone_destroy, arg, d) 139138593Ssam{ 140138593Ssam (void) strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); 141138593Ssam if (ioctl(s, SIOCIFDESTROY, &ifr) < 0) 142138593Ssam err(1, "SIOCIFDESTROY"); 143138593Ssam} 144138593Ssam 145138593Ssamstatic struct cmd clone_cmds[] = { 146160196Ssam DEF_CMD("create", 0, clone_create), 147138593Ssam DEF_CMD("destroy", 0, clone_destroy), 148138593Ssam DEF_CMD("unplumb", 0, clone_destroy), 149138593Ssam}; 150138593Ssam 151138593Ssamstatic void 152138593Ssamclone_Copt_cb(const char *optarg __unused) 153138593Ssam{ 154138593Ssam list_cloners(); 155138593Ssam exit(0); 156138593Ssam} 157138593Ssamstatic struct option clone_Copt = { "C", "[-C]", clone_Copt_cb }; 158138593Ssam 159138593Ssamstatic __constructor void 160138593Ssamclone_ctor(void) 161138593Ssam{ 162138593Ssam#define N(a) (sizeof(a) / sizeof(a[0])) 163138593Ssam int i; 164138593Ssam 165138593Ssam for (i = 0; i < N(clone_cmds); i++) 166138593Ssam cmd_register(&clone_cmds[i]); 167138593Ssam opt_register(&clone_Copt); 168138593Ssam#undef N 169138593Ssam} 170