Commit 785c1a51 authored by Francis Dupont's avatar Francis Dupont

Merged rt35711c (DHCPv4-over-DHCPv6 support)

parent 08ad1e3c
......@@ -227,6 +227,15 @@ by Eric Young (eay@cryptsoft.com).
- Corrected minor Coverity issues.
[ISC-Bugs #35144]
- Add support for RFC 7341 DHCPv4 over DHCPv6 with a new configuration
option "--enable-dhcpv4o6". Note this feature requires DHCPv6 support
and is not compatible with delayed-ack. Both client and server use 2
processes which communicate over UDP on a pair of sockets. The new
"-4o6 <port>" command line argment enables DHCPv4 over DHCPv6 support
and specifies the consecutive ports to use for inter-process communication.
Please look at doc/DHCPv4-over-DHCPv6 for more details.
[ISC-Bugs #35711]
Changes since 4.3.3b1
- None
......
......@@ -3,7 +3,7 @@
Parser for dhclient config and lease files... */
/*
* Copyright (c) 2004-2014 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 2004-2014,2016 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1996-2003 by Internet Software Consortium
*
* Permission to use, copy, modify, and distribute this software for any
......@@ -32,7 +32,8 @@
struct client_config top_level_config;
#define NUM_DEFAULT_REQUESTED_OPTS 9
struct option *default_requested_options[NUM_DEFAULT_REQUESTED_OPTS + 1];
/* There can be 2 extra requested options for DHCPv4-over-DHCPv6. */
struct option *default_requested_options[NUM_DEFAULT_REQUESTED_OPTS + 2 + 1];
static void parse_client_default_duid(struct parse *cfile);
static void parse_client6_lease_statement(struct parse *cfile);
......@@ -120,6 +121,43 @@ isc_result_t read_client_conf ()
"assembly.", code);
}
#ifdef DHCP4o6
/* DHCPv4-over-DHCPv6 extra requested options in code order */
if (dhcpv4_over_dhcpv6 == 1) {
/* The DHCP4o6 server option should be requested */
code = D6O_DHCP4_O_DHCP6_SERVER;
option_code_hash_lookup(&default_requested_options[9],
dhcpv6_universe.code_hash,
&code, 0, MDL);
if (default_requested_options[9] == NULL) {
log_fatal("Unable to find option definition for "
"index %u during default parameter request "
"assembly.", code);
}
} else if (dhcpv4_over_dhcpv6 > 1) {
/* Called from run_stateless so the IRT should
be requested too */
code = D6O_INFORMATION_REFRESH_TIME;
option_code_hash_lookup(&default_requested_options[9],
dhcpv6_universe.code_hash,
&code, 0, MDL);
if (default_requested_options[9] == NULL) {
log_fatal("Unable to find option definition for "
"index %u during default parameter request "
"assembly.", code);
}
code = D6O_DHCP4_O_DHCP6_SERVER;
option_code_hash_lookup(&default_requested_options[10],
dhcpv6_universe.code_hash,
&code, 0, MDL);
if (default_requested_options[10] == NULL) {
log_fatal("Unable to find option definition for "
"index %u during default parameter request "
"assembly.", code);
}
}
#endif
/* Initialize the top level client configuration. */
memset (&top_level_config, 0, sizeof top_level_config);
......
......@@ -4835,6 +4835,11 @@ start_bound(struct client_state *client)
script_go(client);
}
#ifdef DHCP4o6
if (dhcpv4_over_dhcpv6)
dhcp4o6_start();
#endif
go_daemon();
if (client->old_lease != NULL) {
......@@ -5314,8 +5319,12 @@ dhc6_check_irt(struct client_state *client)
}
}
/* Simply return gives a endless loop waiting for nothing. */
if (!found)
if (!found) {
#ifdef DHCP4o6
if (!dhcpv4_over_dhcpv6)
#endif
exit(0);
}
oc = lookup_option(&dhcpv6_universe, client->active_lease->options,
D6O_INFORMATION_REFRESH_TIME);
......@@ -5368,6 +5377,11 @@ start_informed(struct client_state *client)
script_write_requested6(client);
script_go(client);
#ifdef DHCP4o6
if (dhcpv4_over_dhcpv6)
dhcp4o6_start();
#endif
go_daemon();
if (client->old_lease != NULL) {
......
.\" $Id: dhclient.8,v 1.36 2011/04/15 21:58:12 sar Exp $
.\"
.\" Copyright (c) 2004,2007-2015 by Internet Systems Consortium, Inc. ("ISC")
.\" Copyright (c) 2004,2007-2016 by Internet Systems Consortium, Inc. ("ISC")
.\" Copyright (c) 1996-2003 by Internet Software Consortium
.\"
.\" Permission to use, copy, modify, and distribute this software for any
......@@ -64,6 +64,10 @@ dhclient - Dynamic Host Configuration Protocol Client
.B -I
]
[
.B -4o6
.I port
]
[
.B -D
.I LL|LLT
]
......@@ -239,6 +243,14 @@ along with configuration parameters. It cannot be combined with
processing. Note: it is not recommended to mix queries of different
types together or even to share the lease file between them.
.TP
.BI \-4o6 \ port
Participate in the DHCPv4 over DHCPv6 protocol specified by RFC 7341.
This associates a DHCPv4 and a DHCPv6 client to allow the v4 client to
send v4 requests encapuslated in a v6 packet. Communication
between the two clients is done on a pair of UDP sockets bound
to ::1 \fIport\fR and \fIport + 1\fR. Both clients must
be launched using the same \fIport\fR argument.
.TP
.BI \-1
Try to get a lease once. On failure exit with code 2. In DHCPv6 this
sets the maximum duration of the initial exchange to
......
This diff is collapsed.
......@@ -2,11 +2,11 @@ AM_CPPFLAGS = -I$(top_srcdir) -DLOCALSTATEDIR='"@localstatedir@"'
AM_CFLAGS = $(LDAP_CFLAGS)
noinst_LIBRARIES = libdhcp.a
libdhcp_a_SOURCES = alloc.c bpf.c comapi.c conflex.c ctrace.c discover.c \
dispatch.c dlpi.c dns.c ethernet.c execute.c fddi.c \
icmp.c inet.c lpf.c memory.c nit.c ns_name.c options.c \
packet.c parse.c print.c raw.c resolv.c socket.c \
tables.c tr.c tree.c upf.c
libdhcp_a_SOURCES = alloc.c bpf.c comapi.c conflex.c ctrace.c dhcp4o6.c \
discover.c dispatch.c dlpi.c dns.c ethernet.c execute.c \
fddi.c icmp.c inet.c lpf.c memory.c nit.c ns_name.c \
options.c packet.c parse.c print.c raw.c resolv.c \
socket.c tables.c tr.c tree.c upf.c
man_MANS = dhcp-eval.5 dhcp-options.5
EXTRA_DIST = $(man_MANS)
......
......@@ -107,14 +107,15 @@ am__v_AR_1 =
libdhcp_a_AR = $(AR) $(ARFLAGS)
libdhcp_a_LIBADD =
am_libdhcp_a_OBJECTS = alloc.$(OBJEXT) bpf.$(OBJEXT) comapi.$(OBJEXT) \
conflex.$(OBJEXT) ctrace.$(OBJEXT) discover.$(OBJEXT) \
dispatch.$(OBJEXT) dlpi.$(OBJEXT) dns.$(OBJEXT) \
ethernet.$(OBJEXT) execute.$(OBJEXT) fddi.$(OBJEXT) \
icmp.$(OBJEXT) inet.$(OBJEXT) lpf.$(OBJEXT) memory.$(OBJEXT) \
nit.$(OBJEXT) ns_name.$(OBJEXT) options.$(OBJEXT) \
packet.$(OBJEXT) parse.$(OBJEXT) print.$(OBJEXT) raw.$(OBJEXT) \
resolv.$(OBJEXT) socket.$(OBJEXT) tables.$(OBJEXT) \
tr.$(OBJEXT) tree.$(OBJEXT) upf.$(OBJEXT)
conflex.$(OBJEXT) ctrace.$(OBJEXT) dhcp4o6.$(OBJEXT) \
discover.$(OBJEXT) dispatch.$(OBJEXT) dlpi.$(OBJEXT) \
dns.$(OBJEXT) ethernet.$(OBJEXT) execute.$(OBJEXT) \
fddi.$(OBJEXT) icmp.$(OBJEXT) inet.$(OBJEXT) lpf.$(OBJEXT) \
memory.$(OBJEXT) nit.$(OBJEXT) ns_name.$(OBJEXT) \
options.$(OBJEXT) packet.$(OBJEXT) parse.$(OBJEXT) \
print.$(OBJEXT) raw.$(OBJEXT) resolv.$(OBJEXT) \
socket.$(OBJEXT) tables.$(OBJEXT) tr.$(OBJEXT) tree.$(OBJEXT) \
upf.$(OBJEXT)
libdhcp_a_OBJECTS = $(am_libdhcp_a_OBJECTS)
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
......@@ -358,11 +359,11 @@ top_srcdir = @top_srcdir@
AM_CPPFLAGS = -I$(top_srcdir) -DLOCALSTATEDIR='"@localstatedir@"'
AM_CFLAGS = $(LDAP_CFLAGS)
noinst_LIBRARIES = libdhcp.a
libdhcp_a_SOURCES = alloc.c bpf.c comapi.c conflex.c ctrace.c discover.c \
dispatch.c dlpi.c dns.c ethernet.c execute.c fddi.c \
icmp.c inet.c lpf.c memory.c nit.c ns_name.c options.c \
packet.c parse.c print.c raw.c resolv.c socket.c \
tables.c tr.c tree.c upf.c
libdhcp_a_SOURCES = alloc.c bpf.c comapi.c conflex.c ctrace.c dhcp4o6.c \
discover.c dispatch.c dlpi.c dns.c ethernet.c execute.c \
fddi.c icmp.c inet.c lpf.c memory.c nit.c ns_name.c \
options.c packet.c parse.c print.c raw.c resolv.c \
socket.c tables.c tr.c tree.c upf.c
man_MANS = dhcp-eval.5 dhcp-options.5
EXTRA_DIST = $(man_MANS)
......@@ -425,6 +426,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/comapi.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/conflex.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ctrace.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dhcp4o6.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/discover.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dispatch.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dlpi.Po@am__quote@
......
......@@ -3,7 +3,7 @@
Find and identify the network interfaces. */
/*
* Copyright (c) 2013-2014 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 2013-2014,2016 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 2004-2009,2011 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1995-2003 by Internet Software Consortium
*
......@@ -45,6 +45,7 @@ int interfaces_invalidated;
int quiet_interface_discovery;
u_int16_t local_port;
u_int16_t remote_port;
int dhcpv4_over_dhcpv6 = 0;
int (*dhcp_interface_setup_hook) (struct interface_info *, struct iaddr *);
int (*dhcp_interface_discovery_hook) (struct interface_info *);
isc_result_t (*dhcp_interface_startup_hook) (struct interface_info *);
......@@ -1002,7 +1003,8 @@ discover_interfaces(int state) {
/* We don't want the loopback interface. */
if (a->sin_addr.s_addr == htonl(INADDR_LOOPBACK) &&
((tmp->flags & INTERFACE_AUTOMATIC) &&
state == DISCOVER_SERVER))
((state == DISCOVER_SERVER) ||
(state == DISCOVER_SERVER46))))
continue;
/* If the only address we have is 0.0.0.0, we
......@@ -1029,7 +1031,8 @@ discover_interfaces(int state) {
/* We don't want the loopback interface. */
if (IN6_IS_ADDR_LOOPBACK(&a->sin6_addr) &&
((tmp->flags & INTERFACE_AUTOMATIC) &&
state == DISCOVER_SERVER))
((state == DISCOVER_SERVER) ||
(state == DISCOVER_SERVER46))))
continue;
/* If the only address we have is 0.0.0.0, we
......@@ -1226,31 +1229,48 @@ discover_interfaces(int state) {
tmp -> index = -1;
/* Register the interface... */
if (local_family == AF_INET) {
if_register_receive(tmp);
if_register_send(tmp);
switch (local_family) {
case AF_INET:
if (!dhcpv4_over_dhcpv6) {
if_register_receive(tmp);
if_register_send(tmp);
} else {
/* get_hw_addr() was called by register. */
get_hw_addr(tmp->name, &tmp->hw_address);
}
break;
#ifdef DHCPv6
} else {
case AF_INET6:
if ((state == DISCOVER_SERVER) ||
(state == DISCOVER_RELAY)) {
if_register6(tmp, 1);
} else if (state == DISCOVER_SERVER46) {
/* get_hw_addr() was called by if_register*6
so now we have to call it explicitly
to not leave the hardware address unknown
(some code expects it cannot be. */
get_hw_addr(tmp->name, &tmp->hw_address);
} else {
if_register_linklocal6(tmp);
}
break;
#endif /* DHCPv6 */
}
interface_stash (tmp);
wifcount++;
#if defined (F_SETFD)
if (fcntl (tmp -> rfdesc, F_SETFD, 1) < 0)
/* if_register*() are no longer always called so
descriptors must be checked. */
if ((tmp -> rfdesc >= 0) &&
(fcntl (tmp -> rfdesc, F_SETFD, 1) < 0))
log_error ("Can't set close-on-exec on %s: %m",
tmp -> name);
if ((tmp -> wfdesc != tmp -> rfdesc) &&
(tmp -> wfdesc >= 0) &&
(fcntl (tmp -> wfdesc, F_SETFD, 1) < 0))
log_error ("Can't set close-on-exec on %s: %m",
tmp -> name);
if (tmp -> rfdesc != tmp -> wfdesc) {
if (fcntl (tmp -> wfdesc, F_SETFD, 1) < 0)
log_error ("Can't set close-on-exec on %s: %m",
tmp -> name);
}
#endif
next:
interface_dereference (&tmp, MDL);
......@@ -1308,7 +1328,8 @@ discover_interfaces(int state) {
log_fatal ("Not configured to listen on any interfaces!");
}
if ((local_family == AF_INET) && !setup_fallback) {
if ((local_family == AF_INET) &&
!setup_fallback && !dhcpv4_over_dhcpv6) {
setup_fallback = 1;
maybe_setup_fallback();
}
......
......@@ -4,7 +4,7 @@
way... */
/*
* Copyright (c) 2011,2013,2014 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 2011,2013,2014,2016 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 2007-2009 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 2004,2005 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1995-2003 by Internet Software Consortium
......@@ -622,3 +622,29 @@ validate_port(char *port) {
return htons((u_int16_t)local_port);
}
/* \brief Validate that the string represents a valid port pair (i.e. n,n+1)
*
* \param the string to validate
* \return the first port number in network byte order
*/
u_int16_t
validate_port_pair(char *port) {
long local_port = 0;
long lower = 1;
long upper = 65534;
char *endptr;
errno = 0;
local_port = strtol(port, &endptr, 10);
if ((*endptr != '\0') || (errno == ERANGE) || (errno == EINVAL))
log_fatal ("Invalid port pair specification: %s", port);
if (local_port < lower || local_port > upper)
log_fatal("Port pair specified is out of range (%ld-%ld).",
lower, upper);
return htons((u_int16_t)local_port);
}
......@@ -3955,6 +3955,9 @@ do_packet6(struct interface_info *interface, const char *packet,
unsigned char msg_type;
const struct dhcpv6_packet *msg;
const struct dhcpv6_relay_packet *relay;
#ifdef DHCP4o6
const struct dhcpv4_over_dhcpv6_packet *msg46;
#endif
struct packet *decoded_packet;
#if defined (DEBUG_MEMORY_LEAKAGE)
unsigned long previous_outstanding = dmalloc_outstanding;
......@@ -4016,6 +4019,28 @@ do_packet6(struct interface_info *interface, const char *packet,
packet_dereference(&decoded_packet, MDL);
return;
}
#ifdef DHCP4o6
} else if ((msg_type == DHCPV6_DHCPV4_QUERY) ||
(msg_type == DHCPV6_DHCPV4_RESPONSE)) {
int msglen =
(int)(offsetof(struct dhcpv4_over_dhcpv6_packet, options));
msg46 = (struct dhcpv4_over_dhcpv6_packet *)packet;
decoded_packet->dhcpv6_msg_type = msg46->msg_type;
/* message-specific data */
memcpy(decoded_packet->dhcp4o6_flags,
msg46->flags,
sizeof(decoded_packet->dhcp4o6_flags));
if (!parse_option_buffer(decoded_packet->options,
msg46->options, len - msglen,
&dhcpv6_universe)) {
/* no logging here, as parse_option_buffer() logs all
cases where it fails */
packet_dereference(&decoded_packet, MDL);
return;
}
#endif
} else {
int msglen = (int)(offsetof(struct dhcpv6_packet, options));
msg = (const struct dhcpv6_packet *)packet;
......
......@@ -3,7 +3,7 @@
Tables of information... */
/*
* Copyright (c) 2011-2014 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 2011-2014, 2016 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 2004-2009 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1995-2003 by Internet Software Consortium
*
......@@ -565,13 +565,20 @@ static struct option dhcpv6_options[] = {
{ "ipv6-address-andsf", "6A", &dhcpv6_universe, 143, 1 },
#endif
/* RFC7341 OPTIONS */
#if defined(RFC7341_OPTIONS)
{ "dhcpv4-msg", "X", &dhcpv6_universe, 87, 1 },
{ "dhcp4-o-dhcp6-server", "6A", &dhcpv6_universe, 88, 1 },
#endif
{ NULL, NULL, NULL, 0, 0 }
};
struct enumeration_value dhcpv6_duid_type_values[] = {
{ "duid-llt", DUID_LLT }, /* Link-Local Plus Time */
{ "duid-en", DUID_EN }, /* DUID based upon enterprise-ID. */
{ "duid-ll", DUID_LL }, /* DUID from Link Local address only. */
{ "duid-llt", DUID_LLT }, /* Link-Local Plus Time */
{ "duid-en", DUID_EN }, /* DUID based upon enterprise-ID. */
{ "duid-ll", DUID_LL }, /* DUID from Link Local address only. */
{ "duid-uuid", DUID_UUID }, /* DUID based upon UUID */
{ NULL, 0 }
};
......@@ -593,6 +600,7 @@ struct enumeration_value dhcpv6_status_code_values[] = {
{ "MalformedQuery", 8 }, /* Leasequery not valid. */
{ "NotConfigured", 9 }, /* The target address is not in config. */
{ "NotAllowed", 10 }, /* Server doesn't allow the leasequery. */
{ "QueryTerminated", 11 }, /* Leasequery terminated. */
{ NULL, 0 }
};
......@@ -605,6 +613,9 @@ struct enumeration dhcpv6_status_codes = {
struct enumeration_value lq6_query_type_values[] = {
{ "query-by-address", 1 },
{ "query-by-clientid", 2 },
{ "query-by-relay-id", 3 },
{ "query-by-link-address", 4 },
{ "query-by-remote-id", 5 },
{ NULL, 0 }
};
......@@ -630,6 +641,12 @@ struct enumeration_value dhcpv6_message_values[] = {
{ "RELAY-REPL", 13 },
{ "LEASEQUERY", 14 },
{ "LEASEQUERY-REPLY", 15 },
{ "LEASEQUERY-DONE", 16 },
{ "LEASEQUERY-DATA", 17 },
{ "RECONFIGURE-REQUEST", 18 },
{ "RECONFIGURE-REPLY", 19 },
{ "DHCPV4-QUERY", 20 },
{ "DHCPV4-RESPONSE", 21 },
{ NULL, 0 }
};
......@@ -650,7 +667,13 @@ const char *dhcpv6_type_names[] = {
"Relay-forward",
"Relay-reply",
"Leasequery",
"Leasequery-reply"
"Leasequery-reply",
"Leasequery-done",
"Leasequery-data",
"Reconfigure-request",
"Reconfigure-reply",
"Dhcpv4-query",
"Dhcpv4-response"
};
const int dhcpv6_type_name_max =
(sizeof(dhcpv6_type_names) / sizeof(dhcpv6_type_names[0]));
......@@ -670,7 +693,9 @@ static struct option vsio_options[] = {
struct universe isc6_universe;
static struct option isc6_options[] = {
{ "media", "t", &isc6_universe, 1, 1 },
{ "update-assist", "X", &isc6_universe, 2, 1 },
{ "update-assist", "X", &isc6_universe, 2, 1 },
{ "4o6-interface", "t", &isc6_universe, 60000, 1 },
{ "4o6-source-address", "6", &isc6_universe, 60001, 1 },
{ NULL, NULL, NULL, 0, 0 }
};
......
......@@ -753,6 +753,7 @@ enable_execute
enable_tracing
enable_delayed_ack
enable_dhcpv6
enable_dhcpv4o6
enable_paranoia
enable_early_chroot
enable_ipv4_pktinfo
......@@ -1423,6 +1424,8 @@ Optional Features:
is yes)
--enable-delayed-ack queues multiple DHCPACK replies (default is no)
--enable-dhcpv6 enable support for DHCPv6 (default is yes)
--enable-dhcpv4o6 enable support for DHCPv4-over-DHCPv6 (default is
no)
--enable-paranoia enable support for chroot/setuid (default is no)
--enable-early-chroot enable chrooting prior to configuration (default is
no)
......@@ -5430,6 +5433,27 @@ $as_echo "#define DHCPv6 1" >>confdefs.h
fi
# DHCPv4o6 optional compile-time feature.
# Check whether --enable-dhcpv4o6 was given.
if test "${enable_dhcpv4o6+set}" = set; then :
enableval=$enable_dhcpv4o6;
fi
# DHCPv4o6 is off by default, so define if it is explicitly enabled.
if test "$enable_dhcpv4o6" = "yes"; then
# DHCPv4o6 requires DHCPv6
if test "$enable_dhcpv6" = "no"; then
as_fn_error $? "dhcpv4o6 requires dhcpv6" "$LINENO" 5
fi
# DHCPv4o6 is not yet compatible with delayed-ack
if test "$enable_delayed_ack" = "yes"; then
as_fn_error $? "dhcpv4o6 is not compatible with delayed-ack" "$LINENO" 5
fi
$as_echo "#define DHCP4o6 1" >>confdefs.h
fi
# PARANOIA is off by default (until we can test it with all features)
# Check whether --enable-paranoia was given.
if test "${enable_paranoia+set}" = set; then :
......@@ -8641,6 +8665,14 @@ $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
fi
if test "$enable_dhcpv4o6" = "yes"; then
DHCP_VERSIONS="DHCPv4, DHCPv6 and DHCPv4-over-DHCPv6"
elif test "$enable_dhcpv6" != "no"; then
DHCP_VERSIONS="DHCPv4 and DHCPv6"
else
DHCP_VERSIONS="DHCPv4"
fi
(cd $srcdir
sh util/bindvar.sh
if test $? -ne 0; then
......@@ -8663,6 +8695,8 @@ Flags:
DEFS: $DEFS
CFLAGS: $CFLAGS
DHCP versions: $DHCP_VERSIONS
Features:
debug: $enable_debug
failover: $enable_failover
......
......@@ -149,6 +149,23 @@ if test "$enable_dhcpv6" != "no"; then
[Define to 1 to include DHCPv6 support.])
fi
# DHCPv4o6 optional compile-time feature.
AC_ARG_ENABLE(dhcpv4o6,
AS_HELP_STRING([--enable-dhcpv4o6],[enable support for DHCPv4-over-DHCPv6 (default is no)]))
# DHCPv4o6 is off by default, so define if it is explicitly enabled.
if test "$enable_dhcpv4o6" = "yes"; then
# DHCPv4o6 requires DHCPv6
if test "$enable_dhcpv6" = "no"; then
AC_MSG_ERROR([dhcpv4o6 requires dhcpv6])
fi
# DHCPv4o6 is not yet compatible with delayed-ack
if test "$enable_delayed_ack" = "yes"; then
AC_MSG_ERROR([dhcpv4o6 is not compatible with delayed-ack])
fi
AC_DEFINE([DHCP4o6], [1],
[Define to 1 to include DHCPv4 over DHCPv6 support.])
fi
# PARANOIA is off by default (until we can test it with all features)
AC_ARG_ENABLE(paranoia,
AS_HELP_STRING([--enable-paranoia],[enable support for chroot/setuid (default is no)]))
......@@ -799,6 +816,14 @@ AC_CONFIG_FILES([
])
AC_OUTPUT
if test "$enable_dhcpv4o6" = "yes"; then
DHCP_VERSIONS="DHCPv4, DHCPv6 and DHCPv4-over-DHCPv6"
elif test "$enable_dhcpv6" != "no"; then
DHCP_VERSIONS="DHCPv4 and DHCPv6"
else
DHCP_VERSIONS="DHCPv4"
fi
(cd $srcdir
sh util/bindvar.sh
if test $? -ne 0; then
......@@ -821,6 +846,8 @@ Flags:
DEFS: $DEFS
CFLAGS: $CFLAGS
DHCP versions: $DHCP_VERSIONS
Features:
debug: $enable_debug
failover: $enable_failover
......
......@@ -12,6 +12,9 @@
/* Define to queue multiple DHCPACK replies per fsync. */
#undef DELAYED_ACK
/* Define to 1 to include DHCPv4 over DHCPv6 support. */
#undef DHCP4o6
/* Define to BIG_ENDIAN for MSB (Motorola or SPARC CPUs) or LITTLE_ENDIAN for
LSB (Intel CPUs). */
#undef DHCP_BYTE_ORDER
......
......@@ -76,10 +76,49 @@
#define D6O_CLT_TIME 46 /* RFC5007 */
#define D6O_LQ_RELAY_DATA 47 /* RFC5007 */
#define D6O_LQ_CLIENT_LINK 48 /* RFC5007 */
#define D6O_MIP6_HNIDF 49 /* RFC6610 */
#define D6O_MIP6_VDINF 50 /* RFC6610 */
#define D6O_V6_LOST 51 /* RFC5223 */
#define D6O_CAPWAP_AC_V6 52 /* RFC5417 */
#define D6O_RELAY_ID 53 /* RFC5460 */
#define D6O_IPV6_ADDRESS_MOS 54 /* RFC5678 */
#define D6O_IPV6_FQDN_MOS 55 /* RFC5678 */
#define D6O_NTP_SERVER 56 /* RFC5908 */
#define D6O_V6_ACCESS_DOMAIN 57 /* RFC5986 */
#define D6O_SIP_UA_CS_LIST 58 /* RFC6011 */
#define D6O_BOOTFILE_URL 59 /* RFC5970 */
#define D6O_BOOTFILE_PARAM 60 /* RFC5970 */
#define D6O_CLIENT_ARCH_TYPE 61 /* RFC5970 */
#define D6O_NII 62 /* RFC5970 */
#define D6O_GEOLOCATION 63 /* RFC6225 */
#define D6O_AFTR_NAME 64 /* RFC6334 */
#define D6O_ERP_LOCAL_DOMAIN_NAME 65 /* RFC6440 */
#define D6O_RSOO 66 /* RFC6422 */
#define D6O_PD_EXCLUDE 67 /* RFC6603 */
#define D6O_VSS 68 /* RFC6607 */
#define D6O_MIP6_IDINF 69 /* RFC6610 */
#define D6O_MIP6_UDINF 70 /* RFC6610 */
#define D6O_MIP6_HNP 71 /* RFC6610 */
#define D6O_MIP6_HAA 72 /* RFC6610 */
#define D6O_MIP6_HAF 73 /* RFC6610 */
#define D6O_RDNSS_SELECTION 74 /* RFC6731 */
#define D6O_KRB_PRINCIPAL_NAME 75 /* RFC6784 */
#define D6O_KRB_REALM_NAME 76 /* RFC6784 */
#define D6O_KRB_DEFAULT_REALM_NAME 77 /* RFC6784 */
#define D6O_KRB_KDC 78 /* RFC6784 */
#define D6O_CLIENT_LINKLAYER_ADDR 79 /* RFC6939 */
#define D6O_LINK_ADDRESS 80 /* RFC6977 */
#define D6O_RADIUS 81 /* RFC7037 */
#define D6O_SOL_MAX_RT 82 /* RFC7083 */
#define D6O_INF_MAX_RT 83 /* RFC7083 */
#define D6O_ADDRSEL 84 /* RFC7078 */
#define D6O_ADDRSEL_TABLE 85 /* RFC7078 */
#define D6O_V6_PCP_SERVER 86 /* RFC7291 */
#define D6O_DHCPV4_MSG 87 /* RFC7341 */
#define D6O_DHCP4_O_DHCP6_SERVER 88 /* RFC7341 */
/*
* Status Codes, from RFC 3315 section 24.4, and RFC 3633, 5007.
* Status Codes, from RFC 3315 section 24.4, and RFC 3633, 5007, 5460.
*/