Changeset View
Changeset View
Standalone View
Standalone View
sbin/ifconfig/ifclone.c
Show First 20 Lines • Show All 42 Lines • ▼ Show 20 Lines | |||||
#include <err.h> | #include <err.h> | ||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <string.h> | #include <string.h> | ||||
#include <unistd.h> | #include <unistd.h> | ||||
#include "ifconfig.h" | #include "ifconfig.h" | ||||
typedef enum { | |||||
MT_PREFIX, | |||||
MT_FILTER, | |||||
} clone_match_type; | |||||
static void | static void | ||||
list_cloners(void) | list_cloners(void) | ||||
{ | { | ||||
struct if_clonereq ifcr; | struct if_clonereq ifcr; | ||||
char *cp, *buf; | char *cp, *buf; | ||||
int idx; | int idx; | ||||
int s; | int s; | ||||
Show All 29 Lines | list_cloners(void) | ||||
} | } | ||||
putchar('\n'); | putchar('\n'); | ||||
free(buf); | free(buf); | ||||
close(s); | close(s); | ||||
} | } | ||||
struct clone_defcb { | struct clone_defcb { | ||||
union { | |||||
char ifprefix[IFNAMSIZ]; | char ifprefix[IFNAMSIZ]; | ||||
clone_match_func *ifmatch; | |||||
}; | |||||
clone_match_type clone_mt; | |||||
clone_callback_func *clone_cb; | clone_callback_func *clone_cb; | ||||
SLIST_ENTRY(clone_defcb) next; | SLIST_ENTRY(clone_defcb) next; | ||||
}; | }; | ||||
static SLIST_HEAD(, clone_defcb) clone_defcbh = | static SLIST_HEAD(, clone_defcb) clone_defcbh = | ||||
SLIST_HEAD_INITIALIZER(clone_defcbh); | SLIST_HEAD_INITIALIZER(clone_defcbh); | ||||
void | void | ||||
clone_setdefcallback(const char *ifprefix, clone_callback_func *p) | clone_setdefcallback_prefix(const char *ifprefix, clone_callback_func *p) | ||||
{ | { | ||||
struct clone_defcb *dcp; | struct clone_defcb *dcp; | ||||
dcp = malloc(sizeof(*dcp)); | dcp = malloc(sizeof(*dcp)); | ||||
strlcpy(dcp->ifprefix, ifprefix, IFNAMSIZ-1); | strlcpy(dcp->ifprefix, ifprefix, IFNAMSIZ-1); | ||||
dcp->clone_mt = MT_PREFIX; | |||||
dcp->clone_cb = p; | dcp->clone_cb = p; | ||||
SLIST_INSERT_HEAD(&clone_defcbh, dcp, next); | SLIST_INSERT_HEAD(&clone_defcbh, dcp, next); | ||||
} | } | ||||
void | |||||
clone_setdefcallback_filter(clone_match_func *filter, clone_callback_func *p) | |||||
{ | |||||
struct clone_defcb *dcp; | |||||
dcp = malloc(sizeof(*dcp)); | |||||
dcp->ifmatch = filter; | |||||
dcp->clone_mt = MT_FILTER; | |||||
dcp->clone_cb = p; | |||||
SLIST_INSERT_HEAD(&clone_defcbh, dcp, next); | |||||
} | |||||
/* | /* | ||||
* Do the actual clone operation. Any parameters must have been | * Do the actual clone operation. Any parameters must have been | ||||
* setup by now. If a callback has been setup to do the work | * setup by now. If a callback has been setup to do the work | ||||
* then defer to it; otherwise do a simple create operation with | * then defer to it; otherwise do a simple create operation with | ||||
* no parameters. | * no parameters. | ||||
*/ | */ | ||||
static void | static void | ||||
ifclonecreate(int s, void *arg) | ifclonecreate(int s, void *arg) | ||||
{ | { | ||||
struct ifreq ifr; | struct ifreq ifr; | ||||
struct clone_defcb *dcp; | struct clone_defcb *dcp; | ||||
clone_callback_func *clone_cb = NULL; | clone_callback_func *clone_cb = NULL; | ||||
memset(&ifr, 0, sizeof(ifr)); | memset(&ifr, 0, sizeof(ifr)); | ||||
(void) strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); | (void) strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); | ||||
if (clone_cb == NULL) { | if (clone_cb == NULL) { | ||||
/* Try to find a default callback */ | /* Try to find a default callback */ | ||||
SLIST_FOREACH(dcp, &clone_defcbh, next) { | SLIST_FOREACH(dcp, &clone_defcbh, next) { | ||||
if (strncmp(dcp->ifprefix, ifr.ifr_name, | if ((dcp->clone_mt == MT_PREFIX) && | ||||
strlen(dcp->ifprefix)) == 0) { | (strncmp(dcp->ifprefix, ifr.ifr_name, | ||||
strlen(dcp->ifprefix)) == 0)) { | |||||
clone_cb = dcp->clone_cb; | |||||
break; | |||||
} | |||||
if ((dcp->clone_mt == MT_FILTER) && | |||||
dcp->ifmatch(ifr.ifr_name)) { | |||||
clone_cb = dcp->clone_cb; | clone_cb = dcp->clone_cb; | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
if (clone_cb == NULL) { | if (clone_cb == NULL) { | ||||
/* NB: no parameters */ | /* NB: no parameters */ | ||||
if (ioctl(s, SIOCIFCREATE2, &ifr) < 0) | if (ioctl(s, SIOCIFCREATE2, &ifr) < 0) | ||||
▲ Show 20 Lines • Show All 53 Lines • Show Last 20 Lines |