From: Roy Marples Date: Mon, 14 Apr 2008 03:45:54 +0000 (+0000) Subject: Add -o opt1,opt2 and -O to disable requesting optional options. Rejig our defaults... X-Git-Tag: v4.0.2~499 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=be100443a3d5ec2a4a97da1325002c63573e93ec;p=thirdparty%2Fdhcpcd.git Add -o opt1,opt2 and -O to disable requesting optional options. Rejig our defaults around this. --- diff --git a/dhcp.c b/dhcp.c index 2dd2e5a9..a352fc1d 100644 --- a/dhcp.c +++ b/dhcp.c @@ -65,19 +65,46 @@ const struct dhcp_option dhcp_options[] = { { DHCP_MTU, OPT_UINT16R, "MTU" }, { DHCP_STATICROUTE, OPT_IPV4R, NULL }, { DHCP_ROUTER, OPT_IPV4R, NULL }, - { DHCP_HOSTNAME, OPT_STRINGR, "HOSTNAME" }, - { DHCP_DNSSERVER, OPT_IPV4R, "DNSSERVER" }, - { DHCP_DNSDOMAIN, OPT_STRINGR, "DNSDOMAIN" }, - { DHCP_DNSSEARCH, OPT_STRINGR | OPT_RFC3397, "DNSSEARCH" }, - { DHCP_NTPSERVER, OPT_IPV4R, "NTPSERVER" }, - { DHCP_NISSERVER, OPT_IPV4R, "NISSERVER" }, - { DHCP_NISDOMAIN, OPT_IPV4R, "NISDOMAIN" }, - { DHCP_ROOTPATH, OPT_STRINGR, "ROOTPATH" }, - { DHCP_SIPSERVER, OPT_STRINGR | OPT_RFC3361, "SIPSERVER" }, + { DHCP_HOSTNAME, OPT_STRING, "HOSTNAME" }, + { DHCP_DNSSERVER, OPT_IPV4, "DNSSERVER" }, + { DHCP_DNSDOMAIN, OPT_STRING, "DNSDOMAIN" }, + { DHCP_DNSSEARCH, OPT_STRING | OPT_RFC3397, "DNSSEARCH" }, + { DHCP_NTPSERVER, OPT_IPV4, "NTPSERVER" }, + { DHCP_NISSERVER, OPT_IPV4, "NISSERVER" }, + { DHCP_NISDOMAIN, OPT_IPV4, "NISDOMAIN" }, + { DHCP_ROOTPATH, OPT_STRING, "ROOTPATH" }, + { DHCP_SIPSERVER, OPT_STRING | OPT_RFC3361, "SIPSERVER" }, { DHCP_MESSAGE, OPT_STRING, NULL}, { 0, 0, NULL } }; +int make_reqmask(struct options *options, char **opts) +{ + char *token; + char *p = *opts; + uint8_t i; + const char *v; + int max = sizeof(dhcp_options) / sizeof(dhcp_options[0]); + + while ((token = strsep(&p, ","))) { + for (i = 0; i < max; i++) { + if (!(v = dhcp_options[i].var)) + continue; + if (strcmp(v, token) == 0) { + add_reqmask(options->reqmask, + dhcp_options[i].option); + break; + } + } + if (i >= max) { + *opts = token; + errno = ENOENT; + return -1; + } + } + return 0; +} + static int valid_length(uint8_t option, const uint8_t *data, int *type) { @@ -512,6 +539,7 @@ make_message(struct dhcp_message **message, time_t up = uptime() - iface->start_uptime; uint32_t ul; uint16_t sz; + uint8_t o; dhcp = xzalloc(sizeof (*dhcp)); m = (uint8_t *)dhcp; @@ -656,9 +684,11 @@ make_message(struct dhcp_message **message, n_params = p; *p++ = 0; for (l = 0; l < sizeof(dhcp_options) / sizeof(dhcp_options[0]); l++) { - if (!(dhcp_options[l].type & OPT_REQUEST)) + o = dhcp_options[l].option; + if (!(dhcp_options[l].type & OPT_REQUEST) && + !has_reqmask(options->reqmask, o)) continue; - switch (dhcp_options[l].option) { + switch (o) { case DHCP_RENEWALTIME: /* FALLTHROUGH */ case DHCP_REBINDTIME: if (type == DHCP_INFORM) @@ -669,7 +699,7 @@ make_message(struct dhcp_message **message, continue; break; } - *p++ = dhcp_options[l].option; + *p++ = o; } if (options->domscsr) *p++ = DHCP_MSCSR; diff --git a/dhcp.h b/dhcp.h index 1aa38ecd..7c279601 100644 --- a/dhcp.h +++ b/dhcp.h @@ -170,6 +170,9 @@ struct dhcp_lease { uint8_t frominfo; }; +#define add_reqmask(var, val) (var[val >> 3] |= 1 << (val & 7)) +#define has_reqmask(var, val) (var[val >> 3] & (1 << (val & 7))) +int make_reqmask(struct options *options, char **opts); const uint8_t *get_option(const struct dhcp_message *, uint8_t); char *get_option_string(const struct dhcp_message *, uint8_t); int get_option_addr(uint32_t *a, const struct dhcp_message *dhcp, uint8_t option); diff --git a/dhcpcd.8.in b/dhcpcd.8.in index 71d964de..1f90d8b3 100644 --- a/dhcpcd.8.in +++ b/dhcpcd.8.in @@ -29,12 +29,13 @@ .Nd an RFC 2131 compliant DHCP client .Sh SYNOPSIS .Nm -.Op Fl dknpAEGHMLNRSTY +.Op Fl dknpAEGHMOLNRSTY .Op Fl c , -script Ar script .Op Fl h , -hostname Ar hostname .Op Fl i , -classid Ar classid .Op Fl l , -leasetime Ar seconds .Op Fl m , -metric Ar metric +.Op Fl o , -option Ar option .Op Fl r , -request Ar address .Op Fl t , -timeout Ar seconds .Op Fl u , -userclass Ar class @@ -167,6 +168,11 @@ presently only Linux .Pc . Route metrics allow the addition of routes to the same destination across different interfaces, the lower the metric the more it is preferred. +.It Fl o , -option Ar option +Request the DHCP +.Ar option +variable for use in +.Pa @PREFIX@/etc/dhcpcd.sh . .It Fl n , -renew Notifies an existing .Nm @@ -278,6 +284,8 @@ Don't set the MTU of the Don't touch .Pa /etc/ntpd.conf or restart the ntp service. +.It Fl O , -nooptions +Don't request any options beyond what is needed to configure the interface. .It Fl R , -nodns Don't send DNS information to resolvconf or touch .Pa /etc/resolv.conf . diff --git a/dhcpcd.c b/dhcpcd.c index 490ebc2f..af080f03 100644 --- a/dhcpcd.c +++ b/dhcpcd.c @@ -62,6 +62,7 @@ static const struct option longopts[] = { {"leasetime", required_argument, NULL, 'l'}, {"metric", required_argument, NULL, 'm'}, {"renew", no_argument, NULL, 'n'}, + {"option", required_argument, NULL, 'o'}, {"persistent", no_argument, NULL, 'p'}, {"inform", optional_argument, NULL, 's'}, {"request", optional_argument, NULL, 'r'}, @@ -76,6 +77,7 @@ static const struct option longopts[] = { {"noipv4ll", no_argument, NULL, 'L'}, {"nomtu", no_argument, NULL, 'M'}, {"nontp", no_argument, NULL, 'N'}, + {"nooptions", no_argument, NULL, 'O'}, {"nodns", no_argument, NULL, 'R'}, {"msscr", no_argument, NULL, 'S'}, {"test", no_argument, NULL, 'T'}, @@ -136,9 +138,9 @@ read_pid(const char *pidfile) static void usage(void) { - printf("usage: "PACKAGE" [-adknpEGHMNRSTY] [-c script] [-h hostname] [-i classID]\n" - " [-l leasetime] [-m metric] [-r ipaddress] [-s ipaddress]\n" - " [-t timeout] [-u userclass] [-F none | ptr | both]\n" + printf("usage: "PACKAGE" [-adknpEGHMNORSTY] [-c script] [-h hostname] [-i classID]\n" + " [-l leasetime] [-m metric] [-o option] [-r ipaddress]\n" + " [-s ipaddress] [-t timeout] [-u userclass] [-F none | ptr | both]\n" " [-I clientID] \n"); } @@ -158,6 +160,7 @@ main(int argc, char **argv) int sig = 0; int retval = EXIT_FAILURE; char *p; + int doopts = 1, dodns = 1, dohostname = 0, donis = 1, dontp = 1; /* Close any un-needed fd's */ for (i = getdtablesize() - 1; i >= 3; --i) @@ -179,15 +182,10 @@ main(int argc, char **argv) strcmp(options->hostname, "localhost") == 0) *options->hostname = '\0'; - setenv("PEERDNS", "yes", 1); - setenv("PEERHOSTNAME", "no", 1); - setenv("PEERNIS", "yes", 1); - setenv("PEERNTP", "yes", 1); - /* Don't set any optional arguments here so we retain POSIX * compatibility with getopt */ while ((opt = getopt_long(argc, argv, EXTRA_OPTS - "c:dh:i:kl:m:npr:s:t:u:xAEF:GHI:LMNRSTY", + "c:dh:i:kl:m:no:pr:s:t:u:xAEF:GHI:LMNORSTY", longopts, &option_index)) != -1) { switch (opt) { @@ -271,6 +269,11 @@ main(int argc, char **argv) case 'n': sig = SIGALRM; break; + case 'o': + if (make_reqmask(options, &optarg) != 0) { + logger(LOG_ERR, "unknown option `%s'", optarg); + goto abort; + } case 'p': options->options |= DHCPCD_PERSISTENT; break; @@ -367,7 +370,7 @@ main(int argc, char **argv) options->options &= ~DHCPCD_GATEWAY; break; case 'H': - setenv("PEERHOSTNAME", "yes", 1); + dohostname = 1; break; case 'I': if (optarg) { @@ -394,10 +397,13 @@ main(int argc, char **argv) options->options &= ~DHCPCD_MTU; break; case 'N': - setenv("PEERNTP", "no", 1); + dontp = 0; + break; + case 'O': + doopts = 0; break; case 'R': - setenv("PEERDNS", "no", 1); + dodns = 0; break; case 'S': options->domscsr++; @@ -406,7 +412,7 @@ main(int argc, char **argv) options->options |= DHCPCD_TEST | DHCPCD_PERSISTENT; break; case 'Y': - setenv("PEERNIS", "no", 1); + donis = 0; break; case '?': usage(); @@ -440,6 +446,22 @@ main(int argc, char **argv) if (dohelp) usage(); + if (doopts) { + if (dodns) { + add_reqmask(options->reqmask, DHCP_DNSSERVER); + add_reqmask(options->reqmask, DHCP_DNSDOMAIN); + add_reqmask(options->reqmask, DHCP_DNSSEARCH); + } + if (dohostname) + add_reqmask(options->reqmask, DHCP_HOSTNAME); + if (donis) { + add_reqmask(options->reqmask, DHCP_NISSERVER); + add_reqmask(options->reqmask, DHCP_NISDOMAIN); + } + if (dontp) + add_reqmask(options->reqmask, DHCP_NTPSERVER); + } + #ifdef THERE_IS_NO_FORK dhcpcd_argv = argv; dhcpcd_argc = argc; diff --git a/dhcpcd.h b/dhcpcd.h index d3b6bb3b..23b184eb 100644 --- a/dhcpcd.h +++ b/dhcpcd.h @@ -76,6 +76,7 @@ struct options { char classid[CLASS_ID_MAX_LEN]; char clientid[CLIENT_ID_MAX_LEN]; char userclass[USERCLASS_MAX_LEN]; + uint8_t reqmask[256 / 8]; size_t userclass_len; uint32_t leasetime; time_t timeout; diff --git a/dhcpcd.sh b/dhcpcd.sh index 1861e3e1..caaa4f37 100755 --- a/dhcpcd.sh +++ b/dhcpcd.sh @@ -116,7 +116,6 @@ restore_conf() } make_nis_conf() { - yesno "${PEERNIS}" || return 0 [ -z "${NISDOMAIN}" -a -z "${NISSERVER}" ] && return 0 local cf=/etc/yp.conf."${INTERFACE}" prefix= x= pidfile= echo "# Generated by dhcpcd for interface ${INTERFACE}" > "${cf}" @@ -143,7 +142,6 @@ make_nis_conf() { restore_nis_conf() { - yesno "${PEERNIS}" || return 0 restore_conf /etc/yp.conf || return 0 pidfile="$(service_pidfile ypbind)" if [ -s "${pidfile}" ]; then @@ -153,7 +151,6 @@ restore_nis_conf() make_ntp_conf() { - yesno "${PEERNTP}" || return 0 [ -z "${NTPSERVER}" ] && return 0 local cf=/etc/ntp.conf."${INTERFACE}" x= echo "# Generated by dhcpcd for interface ${INTERFACE}" > "${cf}" @@ -181,14 +178,12 @@ make_ntp_conf() restore_ntp_conf() { - yesno "${PEERNTP}" || return 0 restore_conf /etc/ntp.conf || return 0 do_service ntp restart } make_resolv_conf() { - yesno "${PEERDNS}" || return 0 if [ -z "${DNSSERVER}" -a -z "${DNSDOMAIN}" -a -z "${DNSSEARCH}" ]; then return 0 fi @@ -212,7 +207,6 @@ make_resolv_conf() restore_resolv_conf() { - yesno "${PEERDNS}" || return 0 if type resolvconf >/dev/null 2>&1; then resolvconf -d "${INTERFACE}" else @@ -242,7 +236,7 @@ lookup_hostname() make_hostname() { - if yesno "${PEERHOSTNAME}" || need_hostname; then + if need_hostname; then local name="${HOSTNAME}" [ -z "${name}" ] && name="$(lookup_hostname)" [ -n "${name}" ] && hostname "${name}"