/* reset the message counter */
state->interval = 0;
+ /* Ensure that no reject options are present */
+ for (i = 1; i < 255; i++) {
+ if (has_option_mask(ifo->rejectmask, i) &&
+ get_option_uint8(iface->ctx, &tmp, dhcp, (uint8_t)i) == 0)
+ {
+ log_dhcp(LOG_WARNING, "reject DHCP", iface, dhcp, from);
+ return;
+ }
+ }
+
if (type == DHCP_NAK) {
/* For NAK, only check if we require the ServerID */
if (has_option_mask(ifo->requiremask, DHO_SERVERID) &&
return;
}
+ /* Ensure that all required options are present */
+ for (i = 1; i < 255; i++) {
+ if (has_option_mask(ifo->requiremask, i) &&
+ get_option_uint8(iface->ctx, &tmp, dhcp, (uint8_t)i) != 0)
+ {
+ /* If we are bootp, then ignore the need for serverid.
+ * To ignore bootp, require dhcp_message_type.
+ * However, nothing really stops bootp from providing
+ * DHCP style options as well so the above isn't
+ * always true. */
+ if (type == 0 && i == DHO_SERVERID)
+ continue;
+ log_dhcp(LOG_WARNING, "reject DHCP", iface, dhcp, from);
+ return;
+ }
+ }
+
/* DHCP Auto-Configure, RFC 2563 */
if (type == DHCP_OFFER && dhcp->yiaddr == 0) {
log_dhcp(LOG_WARNING, "no address given", iface, dhcp, from);
return;
}
- /* Ensure that all required options are present */
- for (i = 1; i < 255; i++) {
- if (has_option_mask(ifo->requiremask, i) &&
- get_option_uint8(iface->ctx, &tmp, dhcp, (uint8_t)i) != 0)
- {
- /* If we are bootp, then ignore the need for serverid.
- * To ignore bootp, require dhcp_message_type.
- * However, nothing really stops bootp from providing
- * DHCP style options as well so the above isn't
- * always true. */
- if (type == 0 && i == DHO_SERVERID)
- continue;
- log_dhcp(LOG_WARNING, "reject DHCP", iface, dhcp, from);
- return;
- }
- }
-
/* Ensure that the address offered is valid */
if ((type == 0 || type == DHCP_OFFER || type == DHCP_ACK) &&
(dhcp->ciaddr == INADDR_ANY || dhcp->ciaddr == INADDR_BROADCAST) &&
#define O_PFXDLGMIX O_BASE + 37
#define O_IPV6RA_AUTOCONF O_BASE + 38
#define O_IPV6RA_NOAUTOCONF O_BASE + 39
+#define O_REJECT O_BASE + 40
const struct option cf_options[] = {
{"background", no_argument, NULL, 'b'},
{"slaac", required_argument, NULL, O_SLAAC},
{"gateway", no_argument, NULL, O_GATEWAY},
{"ia_pd_mix", no_argument, NULL, O_PFXDLGMIX},
+ {"reject", required_argument, NULL, O_REJECT},
{NULL, 0, NULL, '\0'}
};
const struct dhcp_opt **d, size_t *dl,
const struct dhcp_opt **od, size_t *odl,
struct if_options *ifo,
- uint8_t *request[], uint8_t *require[], uint8_t *no[])
+ uint8_t *request[], uint8_t *require[], uint8_t *no[], uint8_t *reject[])
{
#if !defined(INET) && !defined(INET6)
*request = ifo->requestmask6;
*require = ifo->requiremask6;
*no = ifo->nomask6;
+ *reject = ifo->rejectmask6;
return arg + strlen("dhcp6_");
}
#endif
*request = ifo->requestmask;
*require = ifo->requiremask;
*no = ifo->nomask;
+ *reject = ifo->rejectmask;
return arg;
}
in_addr_t *naddr;
struct rt *rt;
const struct dhcp_opt *d, *od;
- uint8_t *request, *require, *no;
+ uint8_t *request, *require, *no, *reject;
struct dhcp_opt **dop, *ndop;
size_t *dop_len, dl, odl;
struct vivco *vivco;
break;
case 'o':
arg = set_option_space(ctx, arg, &d, &dl, &od, &odl, ifo,
- &request, &require, &no);
+ &request, &require, &no, &reject);
if (make_option_mask(d, dl, od, odl, request, arg, 1) != 0 ||
- make_option_mask(d, dl, od, odl, no, arg, -1) != 0)
+ make_option_mask(d, dl, od, odl, no, arg, -1) != 0 ||
+ make_option_mask(d, dl, od, odl, reject, arg, -1) != 0)
+ {
+ syslog(LOG_ERR, "unknown option `%s'", arg);
+ return -1;
+ }
+ break;
+ case O_REJECT:
+ arg = set_option_space(ctx, arg, &d, &dl, &od, &odl, ifo,
+ &request, &require, &no, &reject);
+ if (make_option_mask(d, dl, od, odl, reject, arg, 1) != 0 ||
+ make_option_mask(d, dl, od, odl, request, arg, -1) != 0 ||
+ make_option_mask(d, dl, od, odl, require, arg, -1) != 0)
{
syslog(LOG_ERR, "unknown option `%s'", arg);
return -1;
break;
case 'O':
arg = set_option_space(ctx, arg, &d, &dl, &od, &odl, ifo,
- &request, &require, &no);
+ &request, &require, &no, &reject);
if (make_option_mask(d, dl, od, odl, request, arg, -1) != 0 ||
make_option_mask(d, dl, od, odl, require, arg, -1) != 0 ||
make_option_mask(d, dl, od, odl, no, arg, 1) != 0)
break;
case 'Q':
arg = set_option_space(ctx, arg, &d, &dl, &od, &odl, ifo,
- &request, &require, &no);
+ &request, &require, &no, &reject);
if (make_option_mask(d, dl, od, odl, require, arg, 1) != 0 ||
make_option_mask(d, dl, od, odl, request, arg, 1) != 0 ||
- make_option_mask(d, dl, od, odl, no, arg, -1) != 0)
+ make_option_mask(d, dl, od, odl, no, arg, -1) != 0 ||
+ make_option_mask(d, dl, od, odl, reject, arg, -1) != 0)
{
syslog(LOG_ERR, "unknown option `%s'", arg);
return -1;
break;
case O_DESTINATION:
arg = set_option_space(ctx, arg, &d, &dl, &od, &odl, ifo,
- &request, &require, &no);
+ &request, &require, &no, &reject);
if (make_option_mask(d, dl, od, odl,
ifo->dstmask, arg, 2) != 0)
{