mirror of
https://gitlab.isc.org/isc-projects/dhcp
synced 2025-08-31 22:35:25 +00:00
[master] Add support for relayed client-linklayer-address option (RFC 6939)
Merges in rt40334.
This commit is contained in:
135
server/dhcpv6.c
135
server/dhcpv6.c
@@ -147,8 +147,6 @@ static isc_result_t reply_process_send_prefix(struct reply_state *reply,
|
||||
static struct iasubopt *prefix_compare(struct reply_state *reply,
|
||||
struct iasubopt *alpha,
|
||||
struct iasubopt *beta);
|
||||
static int find_hosts_by_duid_chaddr(struct host_decl **host,
|
||||
const struct data_string *client_id);
|
||||
static void schedule_lease_timeout_reply(struct reply_state *reply);
|
||||
|
||||
static int eval_prefix_mode(int thislen, int preflen, int prefix_mode);
|
||||
@@ -1643,27 +1641,10 @@ lease_to_client(struct data_string *reply_ret,
|
||||
}
|
||||
|
||||
/*
|
||||
* Find a host record that matches from the packet, if any, and is
|
||||
* Find a host record that matches the packet, if any, and is
|
||||
* valid for the shared network the client is on.
|
||||
*/
|
||||
if (find_hosts_by_uid(&reply.host, client_id->data, client_id->len,
|
||||
MDL)) {
|
||||
packet->known = 1;
|
||||
seek_shared_host(&reply.host, reply.shared);
|
||||
}
|
||||
|
||||
if ((reply.host == NULL) &&
|
||||
find_hosts_by_option(&reply.host, packet, packet->options, MDL)) {
|
||||
packet->known = 1;
|
||||
seek_shared_host(&reply.host, reply.shared);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for 'hardware' matches last, as some of the synthesis methods
|
||||
* are not considered to be as reliable.
|
||||
*/
|
||||
if ((reply.host == NULL) &&
|
||||
find_hosts_by_duid_chaddr(&reply.host, client_id)) {
|
||||
if (find_hosts6(&reply.host, packet, client_id, MDL)) {
|
||||
packet->known = 1;
|
||||
seek_shared_host(&reply.host, reply.shared);
|
||||
}
|
||||
@@ -5552,24 +5533,7 @@ iterate_over_ia_na(struct data_string *reply_ret,
|
||||
* Find the host record that matches from the packet, if any.
|
||||
*/
|
||||
packet_host = NULL;
|
||||
if (!find_hosts_by_uid(&packet_host,
|
||||
client_id->data, client_id->len, MDL)) {
|
||||
packet_host = NULL;
|
||||
/*
|
||||
* Note: In general, we don't expect a client to provide
|
||||
* enough information to match by option for these
|
||||
* types of messages, but if we don't have a UID
|
||||
* match we can check anyway.
|
||||
*/
|
||||
if (!find_hosts_by_option(&packet_host,
|
||||
packet, packet->options, MDL)) {
|
||||
packet_host = NULL;
|
||||
|
||||
if (!find_hosts_by_duid_chaddr(&packet_host,
|
||||
client_id))
|
||||
packet_host = NULL;
|
||||
}
|
||||
}
|
||||
find_hosts6(&packet_host, packet, client_id, MDL);
|
||||
|
||||
/*
|
||||
* Set our reply information.
|
||||
@@ -6081,24 +6045,7 @@ iterate_over_ia_pd(struct data_string *reply_ret,
|
||||
* Find the host record that matches from the packet, if any.
|
||||
*/
|
||||
packet_host = NULL;
|
||||
if (!find_hosts_by_uid(&packet_host,
|
||||
client_id->data, client_id->len, MDL)) {
|
||||
packet_host = NULL;
|
||||
/*
|
||||
* Note: In general, we don't expect a client to provide
|
||||
* enough information to match by option for these
|
||||
* types of messages, but if we don't have a UID
|
||||
* match we can check anyway.
|
||||
*/
|
||||
if (!find_hosts_by_option(&packet_host,
|
||||
packet, packet->options, MDL)) {
|
||||
packet_host = NULL;
|
||||
|
||||
if (!find_hosts_by_duid_chaddr(&packet_host,
|
||||
client_id))
|
||||
packet_host = NULL;
|
||||
}
|
||||
}
|
||||
find_hosts6(&packet_host, packet, client_id, MDL);
|
||||
|
||||
/*
|
||||
* Build our option state for reply.
|
||||
@@ -6922,79 +6869,6 @@ fixed_matches_shared(struct host_decl *host, struct shared_network *shared) {
|
||||
return matched;
|
||||
}
|
||||
|
||||
/*
|
||||
* find_host_by_duid_chaddr() synthesizes a DHCPv4-like 'hardware'
|
||||
* parameter from a DHCPv6 supplied DUID (client-identifier option),
|
||||
* and may seek to use client or relay supplied hardware addresses.
|
||||
*/
|
||||
static int
|
||||
find_hosts_by_duid_chaddr(struct host_decl **host,
|
||||
const struct data_string *client_id) {
|
||||
static int once_htype;
|
||||
int htype, hlen;
|
||||
const unsigned char *chaddr;
|
||||
|
||||
/*
|
||||
* The DUID-LL and DUID-LLT must have a 2-byte DUID type and 2-byte
|
||||
* htype.
|
||||
*/
|
||||
if (client_id->len < 4)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* The third and fourth octets of the DUID-LL and DUID-LLT
|
||||
* is the hardware type, but in 16 bits.
|
||||
*/
|
||||
htype = getUShort(client_id->data + 2);
|
||||
hlen = 0;
|
||||
chaddr = NULL;
|
||||
|
||||
/* The first two octets of the DUID identify the type. */
|
||||
switch(getUShort(client_id->data)) {
|
||||
case DUID_LLT:
|
||||
if (client_id->len > 8) {
|
||||
hlen = client_id->len - 8;
|
||||
chaddr = client_id->data + 8;
|
||||
}
|
||||
break;
|
||||
|
||||
case DUID_LL:
|
||||
/*
|
||||
* Note that client_id->len must be greater than or equal
|
||||
* to four to get to this point in the function.
|
||||
*/
|
||||
hlen = client_id->len - 4;
|
||||
chaddr = client_id->data + 4;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if ((hlen == 0) || (hlen > HARDWARE_ADDR_LEN))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* XXX: DHCPv6 gives a 16-bit field for the htype. DHCPv4 gives an
|
||||
* 8-bit field. To change the semantics of the generic 'hardware'
|
||||
* structure, we would have to adjust many DHCPv4 sources (from
|
||||
* interface to DHCPv4 lease code), and we would have to update the
|
||||
* 'hardware' config directive (probably being reverse compatible and
|
||||
* providing a new upgrade/replacement primitive). This is a little
|
||||
* too much to change for now. Hopefully we will revisit this before
|
||||
* hardware types exceeding 8 bits are assigned.
|
||||
*/
|
||||
if ((htype & 0xFF00) && !once_htype) {
|
||||
once_htype = 1;
|
||||
log_error("Attention: At least one client advertises a "
|
||||
"hardware type of %d, which exceeds the software "
|
||||
"limitation of 255.", htype);
|
||||
}
|
||||
|
||||
return find_hosts_by_haddr(host, htype, chaddr, hlen, MDL);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
*
|
||||
* \brief Constructs a REPLY with status of UseMulticast to a given packet
|
||||
@@ -7305,4 +7179,3 @@ get_first_ia_addr_val (struct packet* packet, int addr_type,
|
||||
}
|
||||
|
||||
#endif /* DHCPv6 */
|
||||
|
||||
|
Reference in New Issue
Block a user