aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sbin/ifconfig/ifconfig.c165
1 files changed, 98 insertions, 67 deletions
diff --git a/sbin/ifconfig/ifconfig.c b/sbin/ifconfig/ifconfig.c
index 8c3a7b4c0007..16ab651261d1 100644
--- a/sbin/ifconfig/ifconfig.c
+++ b/sbin/ifconfig/ifconfig.c
@@ -407,32 +407,34 @@ list_interfaces(struct ifconfig_args *args)
#endif
}
-int
-main(int argc, char *argv[])
+static char *
+args_peek(struct ifconfig_args *args)
{
- int c;
- const struct afswtch *afp = NULL;
- int ifindex;
- char options[1024], *envformat;
- struct option *p;
- size_t iflen;
- int flags;
+ if (args->argc > 0)
+ return (args->argv[0]);
+ return (NULL);
+}
- f_inet = f_inet6 = f_ether = f_addr = NULL;
+static char *
+args_pop(struct ifconfig_args *args)
+{
+ if (args->argc == 0)
+ return (NULL);
- lifh = ifconfig_open();
- if (lifh == NULL)
- err(EXIT_FAILURE, "ifconfig_open");
+ char *arg = args->argv[0];
- envformat = getenv("IFCONFIG_FORMAT");
- if (envformat != NULL)
- setformat(envformat);
+ args->argc--;
+ args->argv++;
- /*
- * Ensure we print interface name when expected to,
- * even if we terminate early due to error.
- */
- atexit(printifnamemaybe);
+ return (arg);
+}
+
+static void
+args_parse(struct ifconfig_args *args, int argc, char *argv[])
+{
+ char options[1024];
+ struct option *p;
+ int c;
/* Parse leading line options */
strlcpy(options, "G:adf:klmnuv", sizeof(options));
@@ -441,10 +443,10 @@ main(int argc, char *argv[])
while ((c = getopt(argc, argv, options)) != -1) {
switch (c) {
case 'a': /* scan all interfaces */
- args.all = true;
+ args->all = true;
break;
case 'd': /* restrict scan to "down" interfaces */
- args.downonly = true;
+ args->downonly = true;
break;
case 'f':
if (optarg == NULL)
@@ -452,33 +454,33 @@ main(int argc, char *argv[])
setformat(optarg);
break;
case 'G':
- if (optarg == NULL || args.all == 0)
+ if (optarg == NULL || args->all == 0)
usage();
- args.nogroup = optarg;
+ args->nogroup = optarg;
break;
case 'k':
- args.printkeys = true;
+ args->printkeys = true;
break;
case 'l': /* scan interface names only */
- args.namesonly++;
+ args->namesonly++;
break;
case 'm': /* show media choices in status */
- args.supmedia = true;
+ args->supmedia = true;
break;
case 'n': /* suppress module loading */
- args.noload = true;
+ args->noload = true;
break;
case 'u': /* restrict scan to "up" interfaces */
- args.uponly = true;
+ args->uponly = true;
break;
case 'v':
- args.verbose++;
+ args->verbose++;
break;
case 'g':
- if (args.all) {
+ if (args->all) {
if (optarg == NULL)
usage();
- args.matchgroup = optarg;
+ args->matchgroup = optarg;
break;
}
/* FALLTHROUGH */
@@ -496,30 +498,26 @@ main(int argc, char *argv[])
argc -= optind;
argv += optind;
- /* Sync global variables */
- printkeys = args.printkeys;
- verbose = args.verbose;
-
/* -l cannot be used with -a or -m */
- if (args.namesonly && (args.all || args.supmedia))
+ if (args->namesonly && (args->all || args->supmedia))
usage();
/* nonsense.. */
- if (args.uponly && args.downonly)
+ if (args->uponly && args->downonly)
usage();
/* no arguments is equivalent to '-a' */
- if (!args.namesonly && argc < 1)
- args.all = 1;
+ if (!args->namesonly && argc < 1)
+ args->all = 1;
/* -a and -l allow an address family arg to limit the output */
- if (args.all || args.namesonly) {
+ if (args->all || args->namesonly) {
if (argc > 1)
usage();
- ifindex = 0;
if (argc == 1) {
- afp = af_getbyname(*argv);
+ const struct afswtch *afp = af_getbyname(*argv);
+
if (afp == NULL) {
warnx("Address family '%s' unknown.", *argv);
usage();
@@ -527,32 +525,68 @@ main(int argc, char *argv[])
if (afp->af_name != NULL)
argc--, argv++;
/* leave with afp non-zero */
+ args->afp = afp;
}
} else {
/* not listing, need an argument */
if (argc < 1)
usage();
+ }
- args.ifname = *argv;
- argc--, argv++;
+ args->argc = argc;
+ args->argv = argv;
+
+ /* Sync global variables */
+ printkeys = args->printkeys;
+ verbose = args->verbose;
+}
+
+int
+main(int ac, char *av[])
+{
+ char *envformat;
+ size_t iflen;
+ int flags;
+
+ f_inet = f_inet6 = f_ether = f_addr = NULL;
+
+ lifh = ifconfig_open();
+ if (lifh == NULL)
+ err(EXIT_FAILURE, "ifconfig_open");
+
+ envformat = getenv("IFCONFIG_FORMAT");
+ if (envformat != NULL)
+ setformat(envformat);
+
+ /*
+ * Ensure we print interface name when expected to,
+ * even if we terminate early due to error.
+ */
+ atexit(printifnamemaybe);
+
+ args_parse(&args, ac, av);
+
+ if (!args.all && !args.namesonly) {
+ /* not listing, need an argument */
+ args.ifname = args_pop(&args);
/* check and maybe load support for this interface */
ifmaybeload(&args, args.ifname);
- ifindex = if_nametoindex(args.ifname);
- if (ifindex == 0) {
+ char *arg = args_peek(&args);
+ if (if_nametoindex(args.ifname) == 0) {
/*
* NOTE: We must special-case the `create' command
* right here as we would otherwise fail when trying
* to find the interface.
*/
- if (argc > 0 && (strcmp(argv[0], "create") == 0 ||
- strcmp(argv[0], "plumb") == 0)) {
+ if (arg != NULL && (strcmp(arg, "create") == 0 ||
+ strcmp(arg, "plumb") == 0)) {
iflen = strlcpy(name, args.ifname, sizeof(name));
if (iflen >= sizeof(name))
errx(1, "%s: cloning name too long",
args.ifname);
- ifconfig(argc, argv, 1, NULL);
+ ifconfig(args.argc, args.argv, 1, NULL);
exit(exit_code);
}
#ifdef JAIL
@@ -561,12 +595,12 @@ main(int argc, char *argv[])
* right here as we would otherwise fail when trying
* to find the interface as it lives in another vnet.
*/
- if (argc > 0 && (strcmp(argv[0], "-vnet") == 0)) {
+ if (arg != NULL && (strcmp(arg, "-vnet") == 0)) {
iflen = strlcpy(name, args.ifname, sizeof(name));
if (iflen >= sizeof(name))
errx(1, "%s: interface name too long",
args.ifname);
- ifconfig(argc, argv, 0, NULL);
+ ifconfig(args.argc, args.argv, 0, NULL);
exit(exit_code);
}
#endif
@@ -576,21 +610,21 @@ main(int argc, char *argv[])
* Do not allow use `create` command as hostname if
* address family is not specified.
*/
- if (argc > 0 && (strcmp(argv[0], "create") == 0 ||
- strcmp(argv[0], "plumb") == 0)) {
- if (argc == 1)
+ if (arg != NULL && (strcmp(arg, "create") == 0 ||
+ strcmp(arg, "plumb") == 0)) {
+ if (args.argc == 1)
errx(1, "interface %s already exists",
args.ifname);
- argc--, argv++;
+ args_pop(&args);
}
}
}
/* Check for address family */
- if (argc > 0) {
- afp = af_getbyname(*argv);
- if (afp != NULL)
- argc--, argv++;
+ if (args.argc > 0) {
+ args.afp = af_getbyname(args_peek(&args));
+ if (args.afp != NULL)
+ args_pop(&args);
}
/*
@@ -598,7 +632,7 @@ main(int argc, char *argv[])
* which doesn't require building, sorting, and searching the entire
* system address list
*/
- if ((argc > 0) && (args.ifname != NULL)) {
+ if ((args.argc > 0) && (args.ifname != NULL)) {
iflen = strlcpy(name, args.ifname, sizeof(name));
if (iflen >= sizeof(name)) {
warnx("%s: interface name too long, skipping", args.ifname);
@@ -607,15 +641,12 @@ main(int argc, char *argv[])
if (!(((flags & IFF_CANTCONFIG) != 0) ||
(args.downonly && (flags & IFF_UP) != 0) ||
(args.uponly && (flags & IFF_UP) == 0)))
- ifconfig(argc, argv, 0, afp);
+ ifconfig(args.argc, args.argv, 0, args.afp);
}
goto done;
}
- args.afp = afp;
- args.allfamilies = afp == NULL;
- args.argc = argc;
- args.argv = argv;
+ args.allfamilies = args.afp == NULL;
list_interfaces(&args);