eliminate most calls to usage() in conf()

Nearly all of the calls to usage() in conf() occur immediately after
logging a more detailed error message, and the fact that these errors
are occuring indicates that the user has already seen the passt usage
message (or read the manpage). Spamming the logfile with the complete
contents of the usage message serves only to obscure the more detailed
error message. The only time when the full usage message should be output
is if the user explicitly asks for it with -h (or its synonyms)

As a start to eliminating the excessive calls to usage(), this patch
replaces most calls to err() followed by usage() with a call to die()
instead. A few other usage() calls remain, but their removal involves
bit more nuance that should be properly explained in separate commit
messages.

Signed-off-by: Laine Stump <laine@redhat.com>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
This commit is contained in:
Laine Stump 2023-02-15 03:24:31 -05:00 committed by Stefano Brivio
parent dac4af81e3
commit c864c60047

336
conf.c
View file

@ -1156,69 +1156,57 @@ void conf(struct ctx *c, int argc, char **argv)
case 0: case 0:
break; break;
case 2: case 2:
if (c->mode != MODE_PASTA) { if (c->mode != MODE_PASTA)
err("--userns is for pasta mode only"); die("--userns is for pasta mode only");
usage(argv[0]);
}
ret = snprintf(userns, sizeof(userns), "%s", optarg); ret = snprintf(userns, sizeof(userns), "%s", optarg);
if (ret <= 0 || ret >= (int)sizeof(userns)) { if (ret <= 0 || ret >= (int)sizeof(userns))
err("Invalid userns: %s", optarg); die("Invalid userns: %s", optarg);
usage(argv[0]);
}
break; break;
case 3: case 3:
if (c->mode != MODE_PASTA) { if (c->mode != MODE_PASTA)
err("--netns is for pasta mode only"); die("--netns is for pasta mode only");
usage(argv[0]);
}
ret = conf_netns_opt(netns, optarg); ret = conf_netns_opt(netns, optarg);
if (ret < 0) if (ret < 0)
usage(argv[0]); usage(argv[0]);
break; break;
case 4: case 4:
if (c->mode != MODE_PASTA) { if (c->mode != MODE_PASTA)
err("--ns-mac-addr is for pasta mode only"); die("--ns-mac-addr is for pasta mode only");
usage(argv[0]);
}
for (i = 0; i < ETH_ALEN; i++) { for (i = 0; i < ETH_ALEN; i++) {
errno = 0; errno = 0;
b = strtol(optarg + (intptr_t)i * 3, NULL, 16); b = strtol(optarg + (intptr_t)i * 3, NULL, 16);
if (b < 0 || b > UCHAR_MAX || errno) { if (b < 0 || b > UCHAR_MAX || errno)
err("Invalid MAC address: %s", optarg); die("Invalid MAC address: %s", optarg);
usage(argv[0]);
}
c->mac_guest[i] = b; c->mac_guest[i] = b;
} }
break; break;
case 5: case 5:
if (c->mode != MODE_PASTA) { if (c->mode != MODE_PASTA)
err("--dhcp-dns is for pasta mode only"); die("--dhcp-dns is for pasta mode only");
usage(argv[0]);
}
c->no_dhcp_dns = 0; c->no_dhcp_dns = 0;
break; break;
case 6: case 6:
if (c->mode != MODE_PASST) { if (c->mode != MODE_PASST)
err("--no-dhcp-dns is for passt mode only"); die("--no-dhcp-dns is for passt mode only");
usage(argv[0]);
}
c->no_dhcp_dns = 1; c->no_dhcp_dns = 1;
break; break;
case 7: case 7:
if (c->mode != MODE_PASTA) { if (c->mode != MODE_PASTA)
err("--dhcp-search is for pasta mode only"); die("--dhcp-search is for pasta mode only");
usage(argv[0]);
}
c->no_dhcp_dns_search = 0; c->no_dhcp_dns_search = 0;
break; break;
case 8: case 8:
if (c->mode != MODE_PASST) { if (c->mode != MODE_PASST)
err("--no-dhcp-search is for passt mode only"); die("--no-dhcp-search is for passt mode only");
usage(argv[0]);
}
c->no_dhcp_dns_search = 1; c->no_dhcp_dns_search = 1;
break; break;
case 9: case 9:
@ -1235,50 +1223,39 @@ void conf(struct ctx *c, int argc, char **argv)
!IN4_IS_ADDR_LOOPBACK(&c->ip4.dns_match)) !IN4_IS_ADDR_LOOPBACK(&c->ip4.dns_match))
break; break;
err("Invalid DNS forwarding address: %s", optarg); die("Invalid DNS forwarding address: %s", optarg);
usage(argv[0]);
break; break;
case 10: case 10:
if (c->mode != MODE_PASTA) { if (c->mode != MODE_PASTA)
err("--no-netns-quit is for pasta mode only"); die("--no-netns-quit is for pasta mode only");
usage(argv[0]);
}
c->no_netns_quit = 1; c->no_netns_quit = 1;
break; break;
case 11: case 11:
if (c->trace) { if (c->trace)
err("Multiple --trace options given"); die("Multiple --trace options given");
usage(argv[0]);
}
if (c->quiet) { if (c->quiet)
err("Either --trace or --quiet"); die("Either --trace or --quiet");
usage(argv[0]);
}
c->trace = c->debug = 1; c->trace = c->debug = 1;
break; break;
case 12: case 12:
if (runas) { if (runas)
err("Multiple --runas options given"); die("Multiple --runas options given");
usage(argv[0]);
}
runas = optarg; runas = optarg;
break; break;
case 13: case 13:
if (logsize) { if (logsize)
err("Multiple --log-size options given"); die("Multiple --log-size options given");
usage(argv[0]);
}
errno = 0; errno = 0;
logsize = strtol(optarg, NULL, 0); logsize = strtol(optarg, NULL, 0);
if (logsize < LOGFILE_SIZE_MIN || errno) { if (logsize < LOGFILE_SIZE_MIN || errno)
err("Invalid --log-size: %s", optarg); die("Invalid --log-size: %s", optarg);
usage(argv[0]);
}
break; break;
case 14: case 14:
fprintf(stdout, fprintf(stdout,
@ -1286,138 +1263,102 @@ void conf(struct ctx *c, int argc, char **argv)
fprintf(stdout, VERSION_BLOB); fprintf(stdout, VERSION_BLOB);
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
case 'd': case 'd':
if (c->debug) { if (c->debug)
err("Multiple --debug options given"); die("Multiple --debug options given");
usage(argv[0]);
}
if (c->quiet) { if (c->quiet)
err("Either --debug or --quiet"); die("Either --debug or --quiet");
usage(argv[0]);
}
c->debug = 1; c->debug = 1;
break; break;
case 'e': case 'e':
if (logfile) { if (logfile)
err("Can't log to both file and stderr"); die("Can't log to both file and stderr");
usage(argv[0]);
}
if (c->stderr) { if (c->stderr)
err("Multiple --stderr options given"); die("Multiple --stderr options given");
usage(argv[0]);
}
c->stderr = 1; c->stderr = 1;
break; break;
case 'l': case 'l':
if (c->stderr) { if (c->stderr)
err("Can't log to both stderr and file"); die("Can't log to both stderr and file");
usage(argv[0]);
}
if (logfile) { if (logfile)
err("Multiple --log-file options given"); die("Multiple --log-file options given");
usage(argv[0]);
}
logfile = optarg; logfile = optarg;
break; break;
case 'q': case 'q':
if (c->quiet) { if (c->quiet)
err("Multiple --quiet options given"); die("Multiple --quiet options given");
usage(argv[0]);
}
if (c->debug) { if (c->debug)
err("Either --debug or --quiet"); die("Either --debug or --quiet");
usage(argv[0]);
}
c->quiet = 1; c->quiet = 1;
break; break;
case 'f': case 'f':
if (c->foreground) { if (c->foreground)
err("Multiple --foreground options given"); die("Multiple --foreground options given");
usage(argv[0]);
}
c->foreground = 1; c->foreground = 1;
break; break;
case 's': case 's':
if (*c->sock_path) { if (*c->sock_path)
err("Multiple --socket options given"); die("Multiple --socket options given");
usage(argv[0]);
}
ret = snprintf(c->sock_path, UNIX_SOCK_MAX - 1, "%s", ret = snprintf(c->sock_path, UNIX_SOCK_MAX - 1, "%s",
optarg); optarg);
if (ret <= 0 || ret >= (int)sizeof(c->sock_path)) { if (ret <= 0 || ret >= (int)sizeof(c->sock_path))
err("Invalid socket path: %s", optarg); die("Invalid socket path: %s", optarg);
usage(argv[0]);
}
break; break;
case 'F': case 'F':
if (c->fd_tap >= 0) { if (c->fd_tap >= 0)
err("Multiple --fd options given"); die("Multiple --fd options given");
usage(argv[0]);
}
errno = 0; errno = 0;
c->fd_tap = strtol(optarg, NULL, 0); c->fd_tap = strtol(optarg, NULL, 0);
if (c->fd_tap < 0 || errno) { if (c->fd_tap < 0 || errno)
err("Invalid --fd: %s", optarg); die("Invalid --fd: %s", optarg);
usage(argv[0]);
}
c->one_off = true; c->one_off = true;
break; break;
case 'I': case 'I':
if (*c->pasta_ifn) { if (*c->pasta_ifn)
err("Multiple --ns-ifname options given"); die("Multiple --ns-ifname options given");
usage(argv[0]);
}
ret = snprintf(c->pasta_ifn, IFNAMSIZ - 1, "%s", ret = snprintf(c->pasta_ifn, IFNAMSIZ - 1, "%s",
optarg); optarg);
if (ret <= 0 || ret >= IFNAMSIZ - 1) { if (ret <= 0 || ret >= IFNAMSIZ - 1)
err("Invalid interface name: %s", optarg); die("Invalid interface name: %s", optarg);
usage(argv[0]);
}
break; break;
case 'p': case 'p':
if (*c->pcap) { if (*c->pcap)
err("Multiple --pcap options given"); die("Multiple --pcap options given");
usage(argv[0]);
}
ret = snprintf(c->pcap, sizeof(c->pcap), "%s", optarg); ret = snprintf(c->pcap, sizeof(c->pcap), "%s", optarg);
if (ret <= 0 || ret >= (int)sizeof(c->pcap)) { if (ret <= 0 || ret >= (int)sizeof(c->pcap))
err("Invalid pcap path: %s", optarg); die("Invalid pcap path: %s", optarg);
usage(argv[0]);
}
break; break;
case 'P': case 'P':
if (*c->pid_file) { if (*c->pid_file)
err("Multiple --pid options given"); die("Multiple --pid options given");
usage(argv[0]);
}
ret = snprintf(c->pid_file, sizeof(c->pid_file), "%s", ret = snprintf(c->pid_file, sizeof(c->pid_file), "%s",
optarg); optarg);
if (ret <= 0 || ret >= (int)sizeof(c->pid_file)) { if (ret <= 0 || ret >= (int)sizeof(c->pid_file))
err("Invalid PID file: %s", optarg); die("Invalid PID file: %s", optarg);
usage(argv[0]);
}
break; break;
case 'm': case 'm':
if (c->mtu) { if (c->mtu)
err("Multiple --mtu options given"); die("Multiple --mtu options given");
usage(argv[0]);
}
errno = 0; errno = 0;
c->mtu = strtol(optarg, NULL, 0); c->mtu = strtol(optarg, NULL, 0);
@ -1428,10 +1369,9 @@ void conf(struct ctx *c, int argc, char **argv)
} }
if (c->mtu < ETH_MIN_MTU || c->mtu > (int)ETH_MAX_MTU || if (c->mtu < ETH_MIN_MTU || c->mtu > (int)ETH_MAX_MTU ||
errno) { errno)
err("Invalid MTU: %s", optarg); die("Invalid MTU: %s", optarg);
usage(argv[0]);
}
break; break;
case 'a': case 'a':
if (IN6_IS_ADDR_UNSPECIFIED(&c->ip6.addr) && if (IN6_IS_ADDR_UNSPECIFIED(&c->ip6.addr) &&
@ -1451,24 +1391,21 @@ void conf(struct ctx *c, int argc, char **argv)
!IN4_IS_ADDR_MULTICAST(&c->ip4.addr)) !IN4_IS_ADDR_MULTICAST(&c->ip4.addr))
break; break;
err("Invalid address: %s", optarg); die("Invalid address: %s", optarg);
usage(argv[0]);
break; break;
case 'n': case 'n':
c->ip4.prefix_len = conf_ip4_prefix(optarg); c->ip4.prefix_len = conf_ip4_prefix(optarg);
if (c->ip4.prefix_len < 0) { if (c->ip4.prefix_len < 0)
err("Invalid netmask: %s", optarg); die("Invalid netmask: %s", optarg);
usage(argv[0]);
}
break; break;
case 'M': case 'M':
for (i = 0; i < ETH_ALEN; i++) { for (i = 0; i < ETH_ALEN; i++) {
errno = 0; errno = 0;
b = strtol(optarg + (intptr_t)i * 3, NULL, 16); b = strtol(optarg + (intptr_t)i * 3, NULL, 16);
if (b < 0 || b > UCHAR_MAX || errno) { if (b < 0 || b > UCHAR_MAX || errno)
err("Invalid MAC address: %s", optarg); die("Invalid MAC address: %s", optarg);
usage(argv[0]);
}
c->mac[i] = b; c->mac[i] = b;
} }
break; break;
@ -1486,41 +1423,30 @@ void conf(struct ctx *c, int argc, char **argv)
!IN4_IS_ADDR_LOOPBACK(&c->ip4.gw)) !IN4_IS_ADDR_LOOPBACK(&c->ip4.gw))
break; break;
err("Invalid gateway address: %s", optarg); die("Invalid gateway address: %s", optarg);
usage(argv[0]);
break; break;
case 'i': case 'i':
if (ifi) { if (ifi)
err("Redundant interface: %s", optarg); die("Redundant interface: %s", optarg);
usage(argv[0]);
}
if (!(ifi = if_nametoindex(optarg))) { if (!(ifi = if_nametoindex(optarg)))
err("Invalid interface name %s: %s", optarg, die("Invalid interface name %s: %s", optarg,
strerror(errno)); strerror(errno));
usage(argv[0]);
}
break; break;
case 'D': case 'D':
if (!strcmp(optarg, "none")) { if (!strcmp(optarg, "none")) {
if (c->no_dns) { if (c->no_dns)
err("Redundant DNS options"); die("Redundant DNS options");
usage(argv[0]);
}
if (dns4 - c->ip4.dns || dns6 - c->ip6.dns) { if (dns4 - c->ip4.dns || dns6 - c->ip6.dns)
err("Conflicting DNS options"); die("Conflicting DNS options");
usage(argv[0]);
}
c->no_dns = 1; c->no_dns = 1;
break; break;
} }
if (c->no_dns) { if (c->no_dns)
err("Conflicting DNS options"); die("Conflicting DNS options");
usage(argv[0]);
}
if (dns4 - &c->ip4.dns[0] < ARRAY_SIZE(c->ip4.dns) && if (dns4 - &c->ip4.dns[0] < ARRAY_SIZE(c->ip4.dns) &&
inet_pton(AF_INET, optarg, dns4)) { inet_pton(AF_INET, optarg, dns4)) {
@ -1534,29 +1460,22 @@ void conf(struct ctx *c, int argc, char **argv)
break; break;
} }
err("Cannot use DNS address %s", optarg); die("Cannot use DNS address %s", optarg);
usage(argv[0]);
break; break;
case 'S': case 'S':
if (!strcmp(optarg, "none")) { if (!strcmp(optarg, "none")) {
if (c->no_dns_search) { if (c->no_dns_search)
err("Redundant DNS search options"); die("Redundant DNS search options");
usage(argv[0]);
}
if (dnss != c->dns_search) { if (dnss != c->dns_search)
err("Conflicting DNS search options"); die("Conflicting DNS search options");
usage(argv[0]);
}
c->no_dns_search = 1; c->no_dns_search = 1;
break; break;
} }
if (c->no_dns_search) { if (c->no_dns_search)
err("Conflicting DNS search options"); die("Conflicting DNS search options");
usage(argv[0]);
}
if (dnss - c->dns_search < ARRAY_SIZE(c->dns_search)) { if (dnss - c->dns_search < ARRAY_SIZE(c->dns_search)) {
ret = snprintf(dnss->n, sizeof(*c->dns_search), ret = snprintf(dnss->n, sizeof(*c->dns_search),
@ -1568,8 +1487,7 @@ void conf(struct ctx *c, int argc, char **argv)
break; break;
} }
err("Cannot use DNS search domain %s", optarg); die("Cannot use DNS search domain %s", optarg);
usage(argv[0]);
break; break;
case '4': case '4':
v4_only = true; v4_only = true;
@ -1578,15 +1496,11 @@ void conf(struct ctx *c, int argc, char **argv)
v6_only = true; v6_only = true;
break; break;
case '1': case '1':
if (c->mode != MODE_PASST) { if (c->mode != MODE_PASST)
err("--one-off is for passt mode only"); die("--one-off is for passt mode only");
usage(argv[0]);
}
if (c->one_off) { if (c->one_off)
err("Redundant --one-off option"); die("Redundant --one-off option");
usage(argv[0]);
}
c->one_off = true; c->one_off = true;
break; break;
@ -1604,15 +1518,11 @@ void conf(struct ctx *c, int argc, char **argv)
} }
} while (name != -1); } while (name != -1);
if (v4_only && v6_only) { if (v4_only && v6_only)
err("Options ipv4-only and ipv6-only are mutually exclusive"); die("Options ipv4-only and ipv6-only are mutually exclusive");
usage(argv[0]);
}
if (*c->sock_path && c->fd_tap >= 0) { if (*c->sock_path && c->fd_tap >= 0)
err("Options --socket and --fd are mutually exclusive"); die("Options --socket and --fd are mutually exclusive");
usage(argv[0]);
}
ret = conf_ugid(runas, &uid, &gid); ret = conf_ugid(runas, &uid, &gid);
if (ret) if (ret)
@ -1628,10 +1538,8 @@ void conf(struct ctx *c, int argc, char **argv)
c->ifi4 = conf_ip4(ifi, &c->ip4, c->mac); c->ifi4 = conf_ip4(ifi, &c->ip4, c->mac);
if (!v4_only) if (!v4_only)
c->ifi6 = conf_ip6(ifi, &c->ip6, c->mac); c->ifi6 = conf_ip6(ifi, &c->ip6, c->mac);
if (!c->ifi4 && !c->ifi6) { if (!c->ifi4 && !c->ifi6)
err("External interface not usable"); die("External interface not usable");
exit(EXIT_FAILURE);
}
/* Inbound port options can be parsed now (after IPv4/IPv6 settings) */ /* Inbound port options can be parsed now (after IPv4/IPv6 settings) */
optind = 1; optind = 1;