mirror of
https://github.com/rsmarples/dhcpcd.git
synced 2024-11-24 10:35:03 +08:00
The require directive now requires that the required options are present in each DHCP message. A few variables and functions have also been renamed to make this part more readable.
This commit is contained in:
parent
bac03ede3d
commit
cc45fbd76e
12
client.c
12
client.c
@ -1357,7 +1357,7 @@ handle_dhcp(struct if_state *state, struct dhcp_message **dhcpp,
|
||||
struct dhcp_message *dhcp = *dhcpp;
|
||||
struct interface *iface = state->interface;
|
||||
struct dhcp_lease *lease = &state->lease;
|
||||
uint8_t type;
|
||||
uint8_t type, tmp;
|
||||
struct in_addr addr;
|
||||
size_t i;
|
||||
int r;
|
||||
@ -1415,6 +1415,16 @@ handle_dhcp(struct if_state *state, struct dhcp_message **dhcpp,
|
||||
/* No NAK, so reset the backoff */
|
||||
state->nakoff = 1;
|
||||
|
||||
/* Ensure that all required options are present */
|
||||
for (i = 1; i < 255; i++) {
|
||||
if (has_option_mask(options->requiremask, i) &&
|
||||
get_option_uint8(&tmp, dhcp, i) != 0)
|
||||
{
|
||||
log_dhcp(LOG_WARNING, "reject", dhcp);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (type == DHCP_OFFER && state->state == STATE_DISCOVERING) {
|
||||
lease->addr.s_addr = dhcp->yiaddr;
|
||||
get_option_addr(&lease->server.s_addr, dhcp, DHO_SERVERID);
|
||||
|
16
dhcp.c
16
dhcp.c
@ -166,7 +166,7 @@ print_options(void)
|
||||
printf("%03d %s\n", opt->option, opt->var);
|
||||
}
|
||||
|
||||
int make_reqmask(uint8_t *mask, char **opts, int add)
|
||||
int make_option_mask(uint8_t *mask, char **opts, int add)
|
||||
{
|
||||
char *token, *p = *opts, *t;
|
||||
const struct dhcp_opt *opt;
|
||||
@ -190,11 +190,11 @@ int make_reqmask(uint8_t *mask, char **opts, int add)
|
||||
}
|
||||
if (match) {
|
||||
if (add == 1)
|
||||
add_reqmask(mask,
|
||||
opt->option);
|
||||
add_option_mask(mask,
|
||||
opt->option);
|
||||
else
|
||||
del_reqmask(mask,
|
||||
opt->option);
|
||||
del_option_mask(mask,
|
||||
opt->option);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -908,7 +908,7 @@ make_message(struct dhcp_message **message,
|
||||
*p++ = 0;
|
||||
for (opt = dhcp_opts; opt->option; opt++) {
|
||||
if (!(opt->type & REQUEST ||
|
||||
has_reqmask(options->reqmask, opt->option)))
|
||||
has_option_mask(options->requestmask, opt->option)))
|
||||
continue;
|
||||
switch (opt->option) {
|
||||
case DHO_RENEWALTIME: /* FALLTHROUGH */
|
||||
@ -1176,7 +1176,7 @@ configure_env(char **env, const char *prefix, const struct dhcp_message *dhcp,
|
||||
for (opt = dhcp_opts; opt->option; opt++) {
|
||||
if (!opt->var)
|
||||
continue;
|
||||
if (has_reqmask(options->nomask, opt->option))
|
||||
if (has_option_mask(options->nomask, opt->option))
|
||||
continue;
|
||||
if (get_option_raw(dhcp, opt->option))
|
||||
e++;
|
||||
@ -1219,7 +1219,7 @@ configure_env(char **env, const char *prefix, const struct dhcp_message *dhcp,
|
||||
for (opt = dhcp_opts; opt->option; opt++) {
|
||||
if (!opt->var)
|
||||
continue;
|
||||
if (has_reqmask(options->nomask, opt->option))
|
||||
if (has_option_mask(options->nomask, opt->option))
|
||||
continue;
|
||||
val = NULL;
|
||||
p = get_option(dhcp, opt->option, &pl, NULL);
|
||||
|
8
dhcp.h
8
dhcp.h
@ -154,10 +154,10 @@ struct dhcp_lease {
|
||||
uint8_t frominfo;
|
||||
};
|
||||
|
||||
#define add_reqmask(var, val) (var[val >> 3] |= 1 << (val & 7))
|
||||
#define del_reqmask(var, val) (var[val >> 3] &= ~(1 << (val & 7)))
|
||||
#define has_reqmask(var, val) (var[val >> 3] & (1 << (val & 7)))
|
||||
int make_reqmask(uint8_t *, char **, int);
|
||||
#define add_option_mask(var, val) (var[val >> 3] |= 1 << (val & 7))
|
||||
#define del_option_mask(var, val) (var[val >> 3] &= ~(1 << (val & 7)))
|
||||
#define has_option_mask(var, val) (var[val >> 3] & (1 << (val & 7)))
|
||||
int make_option_mask(uint8_t *, char **, int);
|
||||
void print_options(void);
|
||||
char *get_option_string(const struct dhcp_message *, uint8_t);
|
||||
int get_option_addr(uint32_t *, const struct dhcp_message *, uint8_t);
|
||||
|
@ -22,7 +22,7 @@
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd August 13, 2008
|
||||
.Dd August 18, 2008
|
||||
.Dt DHCPCD 8 SMM
|
||||
.Sh NAME
|
||||
.Nm dhcpcd
|
||||
@ -46,6 +46,7 @@
|
||||
.Op Fl F , -fqdn Ar FQDN
|
||||
.Op Fl I , -clientid Ar clientid
|
||||
.Op Fl O , -nooption Ar option
|
||||
.Op Fl Q , -require Ar option
|
||||
.Op Fl X , -blacklist Ar address
|
||||
.Ar interface
|
||||
.Nm
|
||||
@ -351,6 +352,10 @@ Don't use IPv4LL (aka APIPA, aka Bonjour, aka ZeroConf).
|
||||
Don't request the specified option.
|
||||
If no option given, then don't request any options other than those to
|
||||
configure the interface and routing.
|
||||
.It Fl Q , -require Ar option
|
||||
Requires the
|
||||
.Ar option
|
||||
to be present in all DHCP messages, otherwise the message is ignored.
|
||||
.It Fl T, -test
|
||||
On receipt of OFFER messages just call
|
||||
.Pa @SCRIPT@
|
||||
|
48
dhcpcd.c
48
dhcpcd.c
@ -53,7 +53,7 @@ const char copyright[] = "Copyright (c) 2006-2008 Roy Marples";
|
||||
|
||||
/* Don't set any optional arguments here so we retain POSIX
|
||||
* compatibility with getopt */
|
||||
#define OPTS "bc:df:h:i:kl:m:no:pqr:s:t:u:v:xABC:DEF:GI:KLO:TVX:"
|
||||
#define OPTS "bc:df:h:i:kl:m:no:pqr:s:t:u:v:xABC:DEF:GI:KLO:Q:TVX:"
|
||||
|
||||
static int doversion = 0;
|
||||
static int dohelp = 0;
|
||||
@ -88,6 +88,7 @@ static const struct option longopts[] = {
|
||||
{"nolink", no_argument, NULL, 'K'},
|
||||
{"noipv4ll", no_argument, NULL, 'L'},
|
||||
{"nooption", optional_argument, NULL, 'O'},
|
||||
{"require", required_argument, NULL, 'Q'},
|
||||
{"test", no_argument, NULL, 'T'},
|
||||
{"variables", no_argument, NULL, 'V'},
|
||||
{"blacklist", required_argument, NULL, 'X'},
|
||||
@ -154,7 +155,7 @@ usage(void)
|
||||
printf("usage: "PACKAGE" [-dknpqxADEGHKLOTV] [-c script] [-f file ] [-h hostname]\n"
|
||||
" [-i classID ] [-l leasetime] [-m metric] [-o option] [-r ipaddr]\n"
|
||||
" [-s ipaddr] [-t timeout] [-u userclass] [-F none|ptr|both]\n"
|
||||
" [-I clientID] [-C hookscript] [-X ipaddr] <interface>\n");
|
||||
" [-I clientID] [-C hookscript] [-Q option] [-X ipaddr] <interface>\n");
|
||||
}
|
||||
|
||||
static char *
|
||||
@ -361,7 +362,7 @@ parse_option(int opt, char *oarg, struct options *options)
|
||||
}
|
||||
break;
|
||||
case 'o':
|
||||
if (make_reqmask(options->reqmask, &oarg, 1) != 0) {
|
||||
if (make_option_mask(options->requestmask, &oarg, 1) != 0) {
|
||||
logger(LOG_ERR, "unknown option `%s'", oarg);
|
||||
return -1;
|
||||
}
|
||||
@ -531,13 +532,22 @@ parse_option(int opt, char *oarg, struct options *options)
|
||||
options->options &= ~DHCPCD_IPV4LL;
|
||||
break;
|
||||
case 'O':
|
||||
if (make_reqmask(options->reqmask, &optarg, -1) != 0 ||
|
||||
make_reqmask(options->nomask, &optarg, 1) != 0)
|
||||
if (make_option_mask(options->requestmask, &oarg, -1) != 0 ||
|
||||
make_option_mask(options->requiremask, &oarg, -1) != 0 ||
|
||||
make_option_mask(options->nomask, &oarg, 1) != 0)
|
||||
{
|
||||
logger(LOG_ERR, "unknown option `%s'", optarg);
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case 'Q':
|
||||
if (make_option_mask(options->requiremask, &oarg, 1) != 0 ||
|
||||
make_option_mask(options->requestmask, &oarg, 1) != 0)
|
||||
{
|
||||
logger(LOG_ERR, "unknown option `%s'", oarg);
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case 'X':
|
||||
if (!inet_aton(oarg, &addr)) {
|
||||
logger(LOG_ERR, "`%s' is not a valid IP address",
|
||||
@ -617,12 +627,12 @@ main(int argc, char **argv)
|
||||
"%s %s", PACKAGE, VERSION);
|
||||
|
||||
#ifdef CMDLINE_COMPAT
|
||||
add_reqmask(options->reqmask, DHO_DNSSERVER);
|
||||
add_reqmask(options->reqmask, DHO_DNSDOMAIN);
|
||||
add_reqmask(options->reqmask, DHO_DNSSEARCH);
|
||||
add_reqmask(options->reqmask, DHO_NISSERVER);
|
||||
add_reqmask(options->reqmask, DHO_NISDOMAIN);
|
||||
add_reqmask(options->reqmask, DHO_NTPSERVER);
|
||||
add_requestmask(options->requestmask, DHO_DNSSERVER);
|
||||
add_requestmask(options->reqmask, DHO_DNSDOMAIN);
|
||||
add_requestmask(options->reqmask, DHO_DNSSEARCH);
|
||||
add_requestmask(options->reqmask, DHO_NISSERVER);
|
||||
add_requestmask(options->reqmask, DHO_NISDOMAIN);
|
||||
add_requestmask(options->reqmask, DHO_NTPSERVER);
|
||||
|
||||
/* If the duid file exists, then enable duid by default
|
||||
* This means we don't break existing clients that easily :) */
|
||||
@ -771,22 +781,22 @@ main(int argc, char **argv)
|
||||
#ifdef CMDLINE_COMPAT
|
||||
case 'H': /* FALLTHROUGH */
|
||||
case 'M':
|
||||
del_reqmask(options->reqmask, DHO_MTU);
|
||||
del_requestmask(options->reqmask, DHO_MTU);
|
||||
break;
|
||||
case 'N':
|
||||
del_reqmask(options->reqmask, DHO_NTPSERVER);
|
||||
del_requestmask(options->reqmask, DHO_NTPSERVER);
|
||||
break;
|
||||
case 'R':
|
||||
del_reqmask(options->reqmask, DHO_DNSSERVER);
|
||||
del_reqmask(options->reqmask, DHO_DNSDOMAIN);
|
||||
del_reqmask(options->reqmask, DHO_DNSSEARCH);
|
||||
del_requestmask(options->reqmask, DHO_DNSSERVER);
|
||||
del_requestmask(options->reqmask, DHO_DNSDOMAIN);
|
||||
del_requestmask(options->reqmask, DHO_DNSSEARCH);
|
||||
break;
|
||||
case 'S':
|
||||
add_reqmask(options->reqmask, DHO_MSCSR);
|
||||
add_requestmask(options->reqmask, DHO_MSCSR);
|
||||
break;
|
||||
case 'Y':
|
||||
del_reqmask(options->reqmask, DHO_NISSERVER);
|
||||
del_reqmask(options->reqmask, DHO_NISDOMAIN);
|
||||
del_requestmask(options->reqmask, DHO_NISSERVER);
|
||||
del_requestmask(options->reqmask, DHO_NISDOMAIN);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
|
@ -22,7 +22,7 @@
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd August 17, 2008
|
||||
.Dd August 18, 2008
|
||||
.Dt DHCPCD.CONF 5 SMM
|
||||
.Sh NAME
|
||||
.Nm dhcpcd.conf
|
||||
@ -103,14 +103,22 @@ See
|
||||
.It Ic nolink
|
||||
Don't receive link messages about carrier status.
|
||||
You should only set this for buggy interface drivers.
|
||||
.It Ic option Ar dhcp-option
|
||||
.It Ic option Ar option
|
||||
Requests the
|
||||
.Ar dhcp-option
|
||||
.Ar option
|
||||
from the server.
|
||||
It can be a variable to be used in
|
||||
.Xr dhcpcd-run-hooks 8
|
||||
or the numerical value.
|
||||
You can specify more seperated by commas, spaces or more option lines.
|
||||
You can specify more options seperated by commas, spaces or more option lines.
|
||||
.It Ic require Ar option
|
||||
Requires the
|
||||
.Ar option
|
||||
to be present in all DHCP messages, otherwise the message is ignored.
|
||||
It can be a variable to be used in
|
||||
.Xr dhcpcd-run-hooks 8
|
||||
or the numerical value.
|
||||
You can specify more options seperated by commas, spaces or more require lines.
|
||||
.It Ic script Ar script
|
||||
Use
|
||||
.Ar script
|
||||
|
Loading…
Reference in New Issue
Block a user