Changeset View
Changeset View
Standalone View
Standalone View
sbin/dumpon/dumpon.c
Show First 20 Lines • Show All 80 Lines • ▼ Show 20 Lines | |||||
#endif | #endif | ||||
static int verbose; | static int verbose; | ||||
static void _Noreturn | static void _Noreturn | ||||
usage(void) | usage(void) | ||||
{ | { | ||||
fprintf(stderr, | fprintf(stderr, | ||||
"usage: dumpon [-v] [-k <pubkey>] [-Zz] <device>\n" | "usage: dumpon [-i index] [-r] [-v] [-k <pubkey>] [-Zz] <device>\n" | ||||
" dumpon [-v] [-k <pubkey>] [-Zz]\n" | " dumpon [-i index] [-r] [-v] [-k <pubkey>] [-Zz]\n" | ||||
" [-g <gateway>] -s <server> -c <client> <iface>\n" | " [-g <gateway>] -s <server> -c <client> <iface>\n" | ||||
" dumpon [-v] off\n" | " dumpon [-v] off\n" | ||||
" dumpon [-v] -l\n"); | " dumpon [-v] -l\n"); | ||||
exit(EX_USAGE); | exit(EX_USAGE); | ||||
} | } | ||||
/* | /* | ||||
* Look for a default route on the specified interface. | * Look for a default route on the specified interface. | ||||
▲ Show 20 Lines • Show All 204 Lines • ▼ Show 20 Lines | if (errno == ENOMEM) { | ||||
sysctlname); | sysctlname); | ||||
} else { | } else { | ||||
err(EX_OSERR, "Sysctl get '%s'\n", sysctlname); | err(EX_OSERR, "Sysctl get '%s'\n", sysctlname); | ||||
} | } | ||||
} | } | ||||
if (strlen(dumpdev) == 0) | if (strlen(dumpdev) == 0) | ||||
(void)strlcpy(dumpdev, _PATH_DEVNULL, sizeof(dumpdev)); | (void)strlcpy(dumpdev, _PATH_DEVNULL, sizeof(dumpdev)); | ||||
if (verbose) | if (verbose) { | ||||
printf("kernel dumps on "); | char *ctx, *dd; | ||||
unsigned idx; | |||||
printf("kernel dumps on priority: device\n"); | |||||
idx = 0; | |||||
ctx = dumpdev; | |||||
while ((dd = strsep(&ctx, ",")) != NULL) | |||||
printf("%u: %s\n", idx++, dd); | |||||
} else | |||||
printf("%s\n", dumpdev); | printf("%s\n", dumpdev); | ||||
/* If netdump is enabled, print the configuration parameters. */ | /* If netdump is enabled, print the configuration parameters. */ | ||||
scottl: Consider using strsep() here, it'll make the code more resilient to input errors and eliminate… | |||||
Done Inline ActionsSure, I can convert it to that API. In this case, the input comes from a trusted source (kernel) so I'm not especially worried about handling invalid input. I do like that the interface seems more ergonomic. cem: Sure, I can convert it to that API. In this case, the input comes from a trusted source… | |||||
if (verbose) { | if (verbose) { | ||||
fd = open(_PATH_NETDUMP, O_RDONLY); | fd = open(_PATH_NETDUMP, O_RDONLY); | ||||
if (fd < 0) { | if (fd < 0) { | ||||
if (errno != ENOENT) | if (errno != ENOENT) | ||||
err(EX_OSERR, "opening %s", _PATH_NETDUMP); | err(EX_OSERR, "opening %s", _PATH_NETDUMP); | ||||
return; | return; | ||||
} | } | ||||
if (ioctl(fd, NETDUMPGCONF, &ndconf) != 0) { | if (ioctl(fd, NETDUMPGCONF, &ndconf) != 0) { | ||||
Show All 35 Lines | |||||
main(int argc, char *argv[]) | main(int argc, char *argv[]) | ||||
{ | { | ||||
char dumpdev[PATH_MAX]; | char dumpdev[PATH_MAX]; | ||||
struct diocskerneldump_arg _kda, *kdap; | struct diocskerneldump_arg _kda, *kdap; | ||||
struct netdump_conf ndconf; | struct netdump_conf ndconf; | ||||
struct addrinfo hints, *res; | struct addrinfo hints, *res; | ||||
const char *dev, *pubkeyfile, *server, *client, *gateway; | const char *dev, *pubkeyfile, *server, *client, *gateway; | ||||
int ch, error, fd; | int ch, error, fd; | ||||
bool enable, gzip, list, netdump, zstd; | bool gzip, list, netdump, zstd, insert, remove; | ||||
uint8_t ins_idx; | |||||
gzip = list = netdump = zstd = false; | gzip = list = netdump = zstd = insert = remove = false; | ||||
kdap = NULL; | kdap = NULL; | ||||
pubkeyfile = NULL; | pubkeyfile = NULL; | ||||
server = client = gateway = NULL; | server = client = gateway = NULL; | ||||
ins_idx = KDA_APPEND; | |||||
while ((ch = getopt(argc, argv, "c:g:k:ls:vZz")) != -1) | while ((ch = getopt(argc, argv, "c:g:i:k:lrs:vZz")) != -1) | ||||
switch ((char)ch) { | switch ((char)ch) { | ||||
case 'c': | case 'c': | ||||
client = optarg; | client = optarg; | ||||
break; | break; | ||||
case 'g': | case 'g': | ||||
gateway = optarg; | gateway = optarg; | ||||
break; | break; | ||||
case 'i': | |||||
{ | |||||
int i; | |||||
i = atoi(optarg); | |||||
if (i < 0 || i >= KDA_APPEND - 1) | |||||
errx(EX_USAGE, | |||||
"-i index must be between zero and %d.", | |||||
(int)KDA_APPEND - 2); | |||||
insert = true; | |||||
ins_idx = i + 1; | |||||
} | |||||
break; | |||||
case 'k': | case 'k': | ||||
pubkeyfile = optarg; | pubkeyfile = optarg; | ||||
break; | break; | ||||
case 'l': | case 'l': | ||||
list = true; | list = true; | ||||
break; | break; | ||||
case 'r': | |||||
remove = true; | |||||
break; | |||||
case 's': | case 's': | ||||
server = optarg; | server = optarg; | ||||
break; | break; | ||||
case 'v': | case 'v': | ||||
verbose = 1; | verbose = 1; | ||||
break; | break; | ||||
case 'Z': | case 'Z': | ||||
zstd = true; | zstd = true; | ||||
break; | break; | ||||
case 'z': | case 'z': | ||||
gzip = true; | gzip = true; | ||||
break; | break; | ||||
default: | default: | ||||
usage(); | usage(); | ||||
} | } | ||||
if (gzip && zstd) | if (gzip && zstd) | ||||
errx(EX_USAGE, "The -z and -Z options are mutually exclusive."); | errx(EX_USAGE, "The -z and -Z options are mutually exclusive."); | ||||
if (insert && remove) | |||||
errx(EX_USAGE, "The -i and -r options are mutually exclusive."); | |||||
argc -= optind; | argc -= optind; | ||||
argv += optind; | argv += optind; | ||||
if (list) { | if (list) { | ||||
listdumpdev(); | listdumpdev(); | ||||
exit(EX_OK); | exit(EX_OK); | ||||
} | } | ||||
if (argc != 1) | if (argc != 1) | ||||
usage(); | usage(); | ||||
#ifndef HAVE_CRYPTO | #ifndef HAVE_CRYPTO | ||||
if (pubkeyfile != NULL) | if (pubkeyfile != NULL) | ||||
errx(EX_UNAVAILABLE,"Unable to use the public key." | errx(EX_UNAVAILABLE,"Unable to use the public key." | ||||
" Recompile dumpon with OpenSSL support."); | " Recompile dumpon with OpenSSL support."); | ||||
#endif | #endif | ||||
if (server != NULL && client != NULL) { | if (server != NULL && client != NULL) { | ||||
enable = true; | |||||
dev = _PATH_NETDUMP; | dev = _PATH_NETDUMP; | ||||
netdump = true; | netdump = true; | ||||
kdap = &ndconf.ndc_kda; | kdap = &ndconf.ndc_kda; | ||||
} else if (server == NULL && client == NULL && argc > 0) { | } else if (server == NULL && client == NULL && argc > 0) { | ||||
enable = strcmp(argv[0], "off") != 0; | if (strcmp(argv[0], "off") == 0) { | ||||
dev = enable ? argv[0] : _PATH_DEVNULL; | remove = true; | ||||
dev = _PATH_DEVNULL; | |||||
} else | |||||
dev = argv[0]; | |||||
netdump = false; | netdump = false; | ||||
kdap = &_kda; | kdap = &_kda; | ||||
} else | } else | ||||
usage(); | usage(); | ||||
fd = opendumpdev(dev, dumpdev); | fd = opendumpdev(dev, dumpdev); | ||||
if (!netdump && !gzip) | if (!netdump && !gzip && !remove) | ||||
check_size(fd, dumpdev); | check_size(fd, dumpdev); | ||||
bzero(kdap, sizeof(*kdap)); | bzero(kdap, sizeof(*kdap)); | ||||
kdap->kda_enable = 0; | |||||
if (ioctl(fd, DIOCSKERNELDUMP, kdap) != 0) | |||||
err(EX_OSERR, "ioctl(DIOCSKERNELDUMP)"); | |||||
if (!enable) | |||||
exit(EX_OK); | |||||
explicit_bzero(kdap, sizeof(*kdap)); | if (remove) | ||||
kdap->kda_enable = 1; | kdap->kda_index = KDA_REMOVE; | ||||
else | |||||
kdap->kda_index = ins_idx; | |||||
kdap->kda_compression = KERNELDUMP_COMP_NONE; | kdap->kda_compression = KERNELDUMP_COMP_NONE; | ||||
if (zstd) | if (zstd) | ||||
kdap->kda_compression = KERNELDUMP_COMP_ZSTD; | kdap->kda_compression = KERNELDUMP_COMP_ZSTD; | ||||
else if (gzip) | else if (gzip) | ||||
kdap->kda_compression = KERNELDUMP_COMP_GZIP; | kdap->kda_compression = KERNELDUMP_COMP_GZIP; | ||||
if (netdump) { | if (netdump) { | ||||
memset(&hints, 0, sizeof(hints)); | memset(&hints, 0, sizeof(hints)); | ||||
▲ Show 20 Lines • Show All 54 Lines • ▼ Show 20 Lines | #endif | ||||
explicit_bzero(kdap->kda_encryptedkey, | explicit_bzero(kdap->kda_encryptedkey, | ||||
kdap->kda_encryptedkeysize); | kdap->kda_encryptedkeysize); | ||||
free(kdap->kda_encryptedkey); | free(kdap->kda_encryptedkey); | ||||
explicit_bzero(kdap, sizeof(*kdap)); | explicit_bzero(kdap, sizeof(*kdap)); | ||||
if (error != 0) | if (error != 0) | ||||
errc(EX_OSERR, error, "ioctl(DIOCSKERNELDUMP)"); | errc(EX_OSERR, error, "ioctl(DIOCSKERNELDUMP)"); | ||||
} | } | ||||
if (verbose) | if (verbose) | ||||
printf("kernel dumps on %s\n", dumpdev); | listdumpdev(); | ||||
exit(EX_OK); | exit(EX_OK); | ||||
} | } |
Consider using strsep() here, it'll make the code more resilient to input errors and eliminate one of the two calls.