Changeset View
Changeset View
Standalone View
Standalone View
sbin/ifconfig/ifconfig.c
Show First 20 Lines • Show All 99 Lines • ▼ Show 20 Lines | |||||
int supmedia = 0; | int supmedia = 0; | ||||
int printkeys = 0; /* Print keying material for interfaces. */ | int printkeys = 0; /* Print keying material for interfaces. */ | ||||
int exit_code = 0; | int exit_code = 0; | ||||
/* Formatter Strings */ | /* Formatter Strings */ | ||||
char *f_inet, *f_inet6, *f_ether, *f_addr; | char *f_inet, *f_inet6, *f_ether, *f_addr; | ||||
static bool group_member(const char *ifname, const char *match); | |||||
static int ifconfig(int argc, char *const *argv, int iscreate, | static int ifconfig(int argc, char *const *argv, int iscreate, | ||||
const struct afswtch *afp); | const struct afswtch *afp); | ||||
static void status(const struct afswtch *afp, const struct sockaddr_dl *sdl, | static void status(const struct afswtch *afp, const struct sockaddr_dl *sdl, | ||||
struct ifaddrs *ifa); | struct ifaddrs *ifa); | ||||
static void tunnel_status(int s); | static void tunnel_status(int s); | ||||
static _Noreturn void usage(void); | static _Noreturn void usage(void); | ||||
static int getifflags(const char *ifname, int us); | static int getifflags(const char *ifname, int us); | ||||
▲ Show 20 Lines • Show All 281 Lines • ▼ Show 20 Lines | main(int argc, char *argv[]) | ||||
const struct afswtch *afp = NULL; | const struct afswtch *afp = NULL; | ||||
int ifindex; | int ifindex; | ||||
struct ifaddrs *ifap, *sifap, *ifa; | struct ifaddrs *ifap, *sifap, *ifa; | ||||
struct ifreq paifr; | struct ifreq paifr; | ||||
const struct sockaddr_dl *sdl; | const struct sockaddr_dl *sdl; | ||||
char options[1024], *cp, *envformat, *namecp = NULL; | char options[1024], *cp, *envformat, *namecp = NULL; | ||||
struct ifa_queue q = TAILQ_HEAD_INITIALIZER(q); | struct ifa_queue q = TAILQ_HEAD_INITIALIZER(q); | ||||
struct ifa_order_elt *cur, *tmp; | struct ifa_order_elt *cur, *tmp; | ||||
const char *ifname; | const char *ifname, *matchgroup; | ||||
struct option *p; | struct option *p; | ||||
size_t iflen; | size_t iflen; | ||||
int flags; | int flags; | ||||
all = downonly = uponly = namesonly = noload = verbose = 0; | all = downonly = uponly = namesonly = noload = verbose = 0; | ||||
f_inet = f_inet6 = f_ether = f_addr = NULL; | f_inet = f_inet6 = f_ether = f_addr = NULL; | ||||
matchgroup = NULL; | |||||
envformat = getenv("IFCONFIG_FORMAT"); | envformat = getenv("IFCONFIG_FORMAT"); | ||||
if (envformat != NULL) | if (envformat != NULL) | ||||
setformat(envformat); | setformat(envformat); | ||||
/* | /* | ||||
* Ensure we print interface name when expected to, | * Ensure we print interface name when expected to, | ||||
* even if we terminate early due to error. | * even if we terminate early due to error. | ||||
Show All 30 Lines | case 'n': /* suppress module loading */ | ||||
noload++; | noload++; | ||||
break; | break; | ||||
case 'u': /* restrict scan to "up" interfaces */ | case 'u': /* restrict scan to "up" interfaces */ | ||||
uponly++; | uponly++; | ||||
break; | break; | ||||
case 'v': | case 'v': | ||||
verbose++; | verbose++; | ||||
break; | break; | ||||
case 'g': | |||||
if (all) { | |||||
if (optarg == NULL) | |||||
usage(); | |||||
matchgroup = optarg; | |||||
break; | |||||
} | |||||
/* FALLTHROUGH */ | |||||
default: | default: | ||||
for (p = opts; p != NULL; p = p->next) | for (p = opts; p != NULL; p = p->next) | ||||
if (p->opt[0] == c) { | if (p->opt[0] == c) { | ||||
p->cb(optarg); | p->cb(optarg); | ||||
break; | break; | ||||
} | } | ||||
if (p == NULL) | if (p == NULL) | ||||
usage(); | usage(); | ||||
▲ Show 20 Lines • Show All 155 Lines • ▼ Show 20 Lines | for (ifa = sifap; ifa; ifa = ifa->ifa_next) { | ||||
cp = ifa->ifa_name; | cp = ifa->ifa_name; | ||||
if ((ifa->ifa_flags & IFF_CANTCONFIG) != 0) | if ((ifa->ifa_flags & IFF_CANTCONFIG) != 0) | ||||
continue; | continue; | ||||
if (downonly && (ifa->ifa_flags & IFF_UP) != 0) | if (downonly && (ifa->ifa_flags & IFF_UP) != 0) | ||||
continue; | continue; | ||||
if (uponly && (ifa->ifa_flags & IFF_UP) == 0) | if (uponly && (ifa->ifa_flags & IFF_UP) == 0) | ||||
continue; | continue; | ||||
if (matchgroup && !group_member(ifa->ifa_name, matchgroup)) | |||||
continue; | |||||
/* | /* | ||||
* Are we just listing the interfaces? | * Are we just listing the interfaces? | ||||
*/ | */ | ||||
if (namesonly) { | if (namesonly) { | ||||
if (namecp == cp) | if (namecp == cp) | ||||
continue; | continue; | ||||
if (afp != NULL) { | if (afp != NULL) { | ||||
/* special case for "ether" address family */ | /* special case for "ether" address family */ | ||||
Show All 26 Lines | #endif | ||||
} | } | ||||
if (namesonly) | if (namesonly) | ||||
printf("\n"); | printf("\n"); | ||||
freeifaddrs(ifap); | freeifaddrs(ifap); | ||||
done: | done: | ||||
freeformat(); | freeformat(); | ||||
exit(exit_code); | exit(exit_code); | ||||
} | |||||
/* | |||||
* Returns true if an interface ifname should be listed based on rules: | |||||
* 1) ifname is a member of interface group; | |||||
* 2) ifname is NOT a member of interface group prepended | |||||
* with caret: "^group". | |||||
*/ | |||||
static bool | |||||
group_member(const char *ifname, const char *match) | |||||
{ | |||||
static int sock = -1; | |||||
struct ifgroupreq ifgr; | |||||
struct ifg_req *ifg; | |||||
int len; | |||||
bool findmatch; | |||||
/* Sanity checks. */ | |||||
if (ifname == NULL || match == NULL) | |||||
return (false); | |||||
memset(&ifgr, 0, sizeof(ifgr)); | |||||
strlcpy(ifgr.ifgr_name, ifname, IFNAMSIZ); | |||||
/* The socket is opened once. Let _exit() close it. */ | |||||
if (sock == -1) { | |||||
sock = socket(AF_LOCAL, SOCK_DGRAM, 0); | |||||
if (sock == -1) | |||||
errx(1, "%s: socket(AF_LOCAL,SOCK_DGRAM)", __func__); | |||||
} | |||||
/* Determine amount of memory for the list of groups. */ | |||||
if (ioctl(sock, SIOCGIFGROUP, (caddr_t)&ifgr) == -1) { | |||||
if (errno == EINVAL || errno == ENOTTY) | |||||
return (false); | |||||
else | |||||
errx(1, "%s: SIOCGIFGROUP", __func__); | |||||
} | |||||
/* Obtain the list of groups. */ | |||||
len = ifgr.ifgr_len; | |||||
ifgr.ifgr_groups = | |||||
(struct ifg_req *)calloc(len / sizeof(*ifg), sizeof(*ifg)); | |||||
if (ifgr.ifgr_groups == NULL) | |||||
errx(1, "%s: no memory", __func__); | |||||
if (ioctl(sock, SIOCGIFGROUP, (caddr_t)&ifgr) == -1) | |||||
errx(1, "%s: SIOCGIFGROUP", __func__); | |||||
/* Perform matching. */ | |||||
findmatch = true; | |||||
if (match[0] == '^') { | |||||
findmatch = false; | |||||
match++; | |||||
/* Sanity check. */ | |||||
if (!*match) | |||||
return (false); | |||||
} | |||||
ifg = ifgr.ifgr_groups; | |||||
for (; ifg && len >= sizeof(struct ifg_req); ifg++) { | |||||
len -= sizeof(struct ifg_req); | |||||
if (strcmp(ifg->ifgrq_group, match) == 0) | |||||
return (findmatch); | |||||
} | |||||
return (!findmatch); | |||||
} | } | ||||
static struct afswtch *afs = NULL; | static struct afswtch *afs = NULL; | ||||
void | void | ||||
af_register(struct afswtch *p) | af_register(struct afswtch *p) | ||||
{ | { | ||||
p->af_next = afs; | p->af_next = afs; | ||||
▲ Show 20 Lines • Show All 938 Lines • Show Last 20 Lines |