Parse config options with ragel and support a configuration file.
This commit is contained in:
214
src/ndhc.c
214
src/ndhc.c
@ -32,7 +32,6 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/file.h>
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
@ -57,6 +56,7 @@
|
||||
|
||||
#include "ndhc.h"
|
||||
#include "ndhc-defines.h"
|
||||
#include "cfg.h"
|
||||
#include "seccomp.h"
|
||||
#include "state.h"
|
||||
#include "options.h"
|
||||
@ -94,13 +94,42 @@ struct client_config_t client_config = {
|
||||
.foreground = 1,
|
||||
};
|
||||
|
||||
static void show_usage(void)
|
||||
void set_client_addr(const char *v) { cs.clientAddr = inet_addr(v); }
|
||||
|
||||
void print_version(void)
|
||||
{
|
||||
printf("ndhc %s, dhcp client.\n", NDHC_VERSION);
|
||||
printf("Copyright (c) 2004-2014 Nicholas J. Kain\n"
|
||||
"All rights reserved.\n\n"
|
||||
"Redistribution and use in source and binary forms, with or without\n"
|
||||
"modification, are permitted provided that the following conditions are met:\n\n"
|
||||
"- Redistributions of source code must retain the above copyright notice,\n"
|
||||
" this list of conditions and the following disclaimer.\n"
|
||||
"- Redistributions in binary form must reproduce the above copyright notice,\n"
|
||||
" this list of conditions and the following disclaimer in the documentation\n"
|
||||
" and/or other materials provided with the distribution.\n\n"
|
||||
"THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n"
|
||||
"AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n"
|
||||
"IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n"
|
||||
"ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE\n"
|
||||
"LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n"
|
||||
"CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n"
|
||||
"SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n"
|
||||
"INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n"
|
||||
"CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n"
|
||||
"ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n"
|
||||
"POSSIBILITY OF SUCH DAMAGE.\n");
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
void show_usage(void)
|
||||
{
|
||||
printf(
|
||||
"ndhc " NDHC_VERSION ", dhcp client. Licensed under 2-clause BSD.\n"
|
||||
"Copyright (C) 2004-2014 Nicholas J. Kain\n"
|
||||
"Usage: ndhc [OPTIONS]\n\n"
|
||||
" -c, --clientid=CLIENTID Client identifier\n"
|
||||
" -c, --config=FILE Path to ndhc configuration file\n"
|
||||
" -I, --clientid=CLIENTID Client identifier\n"
|
||||
" -h, --hostname=HOSTNAME Client hostname\n"
|
||||
" -V, --vendorid=VENDORID Client vendor identification string\n"
|
||||
" -b, --background Fork to background if lease cannot be\n"
|
||||
@ -127,7 +156,7 @@ static void show_usage(void)
|
||||
" -M, --arp-probe-max Max ms to wait for ARP response\n"
|
||||
" -t, --gw-metric Route metric for default gw (default: 0)\n"
|
||||
" -R, --resolve-conf=FILE Path to resolv.conf or equivalent\n"
|
||||
" -H, --dhcp-hostname Allow DHCP to set machine hostname\n"
|
||||
" -H, --dhcp-set-hostname Allow DHCP to set machine hostname\n"
|
||||
" -v, --version Display version\n"
|
||||
);
|
||||
exit(EXIT_SUCCESS);
|
||||
@ -205,7 +234,7 @@ static int is_string_hwaddr(char *str, size_t slen)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_clientid_string(char *str, size_t slen)
|
||||
int get_clientid_string(char *str, size_t slen)
|
||||
{
|
||||
if (!slen)
|
||||
return -1;
|
||||
@ -333,9 +362,9 @@ jumpstart:
|
||||
char state_dir[PATH_MAX] = "/etc/ndhc";
|
||||
char chroot_dir[PATH_MAX] = "";
|
||||
char resolv_conf_d[PATH_MAX] = "";
|
||||
static char pidfile[PATH_MAX] = PID_FILE_DEFAULT;
|
||||
static uid_t ndhc_uid = 0;
|
||||
static gid_t ndhc_gid = 0;
|
||||
char pidfile[PATH_MAX] = PID_FILE_DEFAULT;
|
||||
uid_t ndhc_uid = 0;
|
||||
gid_t ndhc_gid = 0;
|
||||
int ifchSock[2];
|
||||
int ifchPipe[2];
|
||||
int sockdSock[2];
|
||||
@ -432,176 +461,9 @@ void background(void)
|
||||
write_pid(pidfile);
|
||||
}
|
||||
|
||||
static void parse_program_options(int argc, char *argv[])
|
||||
{
|
||||
static const struct option arg_options[] = {
|
||||
{"clientid", required_argument, 0, 'c'},
|
||||
{"background", no_argument, 0, 'b'},
|
||||
{"pidfile", required_argument, 0, 'p'},
|
||||
{"hostname", required_argument, 0, 'h'},
|
||||
{"interface", required_argument, 0, 'i'},
|
||||
{"now", no_argument, 0, 'n'},
|
||||
{"quit", no_argument, 0, 'q'},
|
||||
{"request", required_argument, 0, 'r'},
|
||||
{"vendorid", required_argument, 0, 'V'},
|
||||
{"user", required_argument, 0, 'u'},
|
||||
{"ifch-user", required_argument, 0, 'U'},
|
||||
{"sockd-user", required_argument, 0, 'D'},
|
||||
{"chroot", required_argument, 0, 'C'},
|
||||
{"state-dir", required_argument, 0, 's'},
|
||||
{"seccomp-enforce", no_argument, 0, 'S'},
|
||||
{"relentless-defense", no_argument, 0, 'd'},
|
||||
{"arp-probe-wait", required_argument, 0, 'w'},
|
||||
{"arp-probe-num", required_argument, 0, 'W'},
|
||||
{"arp-probe-min", required_argument, 0, 'm'},
|
||||
{"arp-probe-max", required_argument, 0, 'M'},
|
||||
{"gw-metric", required_argument, 0, 't'},
|
||||
{"resolv-conf", required_argument, 0, 'R'},
|
||||
{"dhcp-set-hostname", no_argument, 0, 'H'},
|
||||
{"version", no_argument, 0, 'v'},
|
||||
{"help", no_argument, 0, '?'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
while (1) {
|
||||
int c;
|
||||
c = getopt_long(argc, argv, "c:bp:P:h:i:nqr:V:u:U:D:C:s:Sdw:W:m:M:t:R:Hv?",
|
||||
arg_options, NULL);
|
||||
if (c < 0) break;
|
||||
|
||||
switch (c) {
|
||||
case 'c':
|
||||
get_clientid_string(optarg, strlen(optarg));
|
||||
break;
|
||||
case 'b':
|
||||
client_config.background_if_no_lease = 1;
|
||||
gflags_detach = 1;
|
||||
break;
|
||||
case 'p':
|
||||
copy_cmdarg(pidfile, optarg, sizeof pidfile, "pidfile");
|
||||
break;
|
||||
case 'h':
|
||||
copy_cmdarg(client_config.hostname, optarg,
|
||||
sizeof client_config.hostname, "hostname");
|
||||
break;
|
||||
case 'i':
|
||||
copy_cmdarg(client_config.interface, optarg,
|
||||
sizeof client_config.interface, "interface");
|
||||
break;
|
||||
case 'n':
|
||||
client_config.abort_if_no_lease = 1;
|
||||
break;
|
||||
case 'q':
|
||||
client_config.quit_after_lease = 1;
|
||||
break;
|
||||
case 'r':
|
||||
cs.clientAddr = inet_addr(optarg);
|
||||
break;
|
||||
case 'u':
|
||||
if (nk_uidgidbyname(optarg, &ndhc_uid, &ndhc_gid))
|
||||
suicide("invalid ndhc user '%s' specified", optarg);
|
||||
break;
|
||||
case 'U':
|
||||
if (nk_uidgidbyname(optarg, &ifch_uid, &ifch_gid))
|
||||
suicide("invalid ifch user '%s' specified", optarg);
|
||||
break;
|
||||
case 'D':
|
||||
if (nk_uidgidbyname(optarg, &sockd_uid, &sockd_gid))
|
||||
suicide("invalid sockd user '%s' specified", optarg);
|
||||
break;
|
||||
case 'C':
|
||||
copy_cmdarg(chroot_dir, optarg, sizeof chroot_dir, "chroot");
|
||||
break;
|
||||
case 's':
|
||||
copy_cmdarg(state_dir, optarg, sizeof state_dir, "state-dir");
|
||||
break;
|
||||
case 'S':
|
||||
seccomp_enforce = true;
|
||||
break;
|
||||
case 'd':
|
||||
set_arp_relentless_def();
|
||||
break;
|
||||
case 'w':
|
||||
case 'W': {
|
||||
int t = atoi(optarg);
|
||||
if (t < 0)
|
||||
break;
|
||||
if (c == 'w')
|
||||
arp_probe_wait = t;
|
||||
else
|
||||
arp_probe_num = t;
|
||||
break;
|
||||
}
|
||||
case 'm':
|
||||
case 'M': {
|
||||
int t = atoi(optarg);
|
||||
if (c == 'm')
|
||||
arp_probe_min = t;
|
||||
else
|
||||
arp_probe_max = t;
|
||||
if (arp_probe_min > arp_probe_max) {
|
||||
t = arp_probe_max;
|
||||
arp_probe_max = arp_probe_min;
|
||||
arp_probe_min = t;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'v':
|
||||
printf("ndhc %s, dhcp client.\n", NDHC_VERSION);
|
||||
printf("Copyright (c) 2004-2014 Nicholas J. Kain\n"
|
||||
"All rights reserved.\n\n"
|
||||
"Redistribution and use in source and binary forms, with or without\n"
|
||||
"modification, are permitted provided that the following conditions are met:\n\n"
|
||||
"- Redistributions of source code must retain the above copyright notice,\n"
|
||||
" this list of conditions and the following disclaimer.\n"
|
||||
"- Redistributions in binary form must reproduce the above copyright notice,\n"
|
||||
" this list of conditions and the following disclaimer in the documentation\n"
|
||||
" and/or other materials provided with the distribution.\n\n"
|
||||
"THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n"
|
||||
"AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n"
|
||||
"IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n"
|
||||
"ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE\n"
|
||||
"LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n"
|
||||
"CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n"
|
||||
"SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n"
|
||||
"INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n"
|
||||
"CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n"
|
||||
"ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n"
|
||||
"POSSIBILITY OF SUCH DAMAGE.\n");
|
||||
exit(EXIT_SUCCESS);
|
||||
break;
|
||||
case 'V':
|
||||
copy_cmdarg(client_config.vendor, optarg,
|
||||
sizeof client_config.vendor, "vendorid");
|
||||
break;
|
||||
case 't': {
|
||||
char *p;
|
||||
long mt = strtol(optarg, &p, 10);
|
||||
if (p == optarg)
|
||||
suicide("gw-metric arg '%s' isn't a valid number", optarg);
|
||||
if (mt > INT_MAX)
|
||||
suicide("gw-metric arg '%s' is too large", optarg);
|
||||
if (mt < 0)
|
||||
mt = 0;
|
||||
client_config.metric = (int)mt;
|
||||
break;
|
||||
}
|
||||
case 'R':
|
||||
copy_cmdarg(resolv_conf_d, optarg, sizeof resolv_conf_d,
|
||||
"resolv-conf");
|
||||
break;
|
||||
case 'H':
|
||||
allow_hostname = 1;
|
||||
break;
|
||||
default:
|
||||
show_usage();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
parse_program_options(argc, argv);
|
||||
parse_cmdline(argc, argv);
|
||||
|
||||
nk_random_u32_init(&cs.rnd32_state);
|
||||
|
||||
|
Reference in New Issue
Block a user