Implement RFC-6842 (Client-ids in DHCP replies.)

This commit is contained in:
Simon Kelley
2017-02-11 17:02:02 +00:00
parent 3e2496fb16
commit 88a77a78ad
2 changed files with 26 additions and 12 deletions

View File

@@ -74,6 +74,9 @@ version 2.77
of "local addresses only" entries. Thanks to Hannu Nyman for of "local addresses only" entries. Thanks to Hannu Nyman for
the patch. the patch.
Implement RFC 6842. Thanks to Reddeiah Raju Konduru for
pointing out that this was missing.
version 2.76 version 2.76
Include 0.0.0.0/8 in DNS rebind checks. This range Include 0.0.0.0/8 in DNS rebind checks. This range

View File

@@ -38,7 +38,7 @@ static void log_packet(char *type, void *addr, unsigned char *ext_mac,
static unsigned char *option_find(struct dhcp_packet *mess, size_t size, int opt_type, int minsize); static unsigned char *option_find(struct dhcp_packet *mess, size_t size, int opt_type, int minsize);
static unsigned char *option_find1(unsigned char *p, unsigned char *end, int opt, int minsize); static unsigned char *option_find1(unsigned char *p, unsigned char *end, int opt, int minsize);
static size_t dhcp_packet_size(struct dhcp_packet *mess, unsigned char *agent_id, unsigned char *real_end); static size_t dhcp_packet_size(struct dhcp_packet *mess, unsigned char *agent_id, unsigned char *real_end);
static void clear_packet(struct dhcp_packet *mess, unsigned char *end); static void clear_packet(struct dhcp_packet *mess, unsigned char *end, unsigned int sz);
static int in_list(unsigned char *list, int opt); static int in_list(unsigned char *list, int opt);
static void do_options(struct dhcp_context *context, static void do_options(struct dhcp_context *context,
struct dhcp_packet *mess, struct dhcp_packet *mess,
@@ -611,7 +611,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
now); now);
lease_set_interface(lease, int_index, now); lease_set_interface(lease, int_index, now);
clear_packet(mess, end); clear_packet(mess, end, 0);
do_options(context, mess, end, NULL, hostname, get_domain(mess->yiaddr), do_options(context, mess, end, NULL, hostname, get_domain(mess->yiaddr),
netid, subnet_addr, 0, 0, -1, NULL, vendor_class_len, now, 0xffffffff, 0); netid, subnet_addr, 0, 0, -1, NULL, vendor_class_len, now, 0xffffffff, 0);
} }
@@ -814,7 +814,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
if (!service || !service->basename || !context) if (!service || !service->basename || !context)
return 0; return 0;
clear_packet(mess, end); clear_packet(mess, end, sz);
mess->yiaddr = mess->ciaddr; mess->yiaddr = mess->ciaddr;
mess->ciaddr.s_addr = 0; mess->ciaddr.s_addr = 0;
@@ -882,7 +882,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
mess->flags |= htons(0x8000); /* broadcast */ mess->flags |= htons(0x8000); /* broadcast */
} }
clear_packet(mess, end); clear_packet(mess, end, sz);
/* Redirect EFI clients to port 4011 */ /* Redirect EFI clients to port 4011 */
if (pxearch >= 6) if (pxearch >= 6)
@@ -1062,7 +1062,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
log_packet("DHCPOFFER" , &mess->yiaddr, emac, emac_len, iface_name, NULL, NULL, mess->xid); log_packet("DHCPOFFER" , &mess->yiaddr, emac, emac_len, iface_name, NULL, NULL, mess->xid);
time = calc_time(context, config, option_find(mess, sz, OPTION_LEASE_TIME, 4)); time = calc_time(context, config, option_find(mess, sz, OPTION_LEASE_TIME, 4));
clear_packet(mess, end); clear_packet(mess, end, sz);
option_put(mess, end, OPTION_MESSAGE_TYPE, 1, DHCPOFFER); option_put(mess, end, OPTION_MESSAGE_TYPE, 1, DHCPOFFER);
option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ, ntohl(server_id(context, override, fallback).s_addr)); option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ, ntohl(server_id(context, override, fallback).s_addr));
option_put(mess, end, OPTION_LEASE_TIME, 4, time); option_put(mess, end, OPTION_LEASE_TIME, 4, time);
@@ -1245,7 +1245,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
log_packet("DHCPNAK", &mess->yiaddr, emac, emac_len, iface_name, NULL, message, mess->xid); log_packet("DHCPNAK", &mess->yiaddr, emac, emac_len, iface_name, NULL, message, mess->xid);
mess->yiaddr.s_addr = 0; mess->yiaddr.s_addr = 0;
clear_packet(mess, end); clear_packet(mess, end, sz);
option_put(mess, end, OPTION_MESSAGE_TYPE, 1, DHCPNAK); option_put(mess, end, OPTION_MESSAGE_TYPE, 1, DHCPNAK);
option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ, ntohl(server_id(context, override, fallback).s_addr)); option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ, ntohl(server_id(context, override, fallback).s_addr));
option_put_string(mess, end, OPTION_MESSAGE, message, borken_opt); option_put_string(mess, end, OPTION_MESSAGE, message, borken_opt);
@@ -1401,7 +1401,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
log_packet("DHCPACK", &mess->yiaddr, emac, emac_len, iface_name, hostname, NULL, mess->xid); log_packet("DHCPACK", &mess->yiaddr, emac, emac_len, iface_name, hostname, NULL, mess->xid);
clear_packet(mess, end); clear_packet(mess, end, sz);
option_put(mess, end, OPTION_MESSAGE_TYPE, 1, DHCPACK); option_put(mess, end, OPTION_MESSAGE_TYPE, 1, DHCPACK);
option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ, ntohl(server_id(context, override, fallback).s_addr)); option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ, ntohl(server_id(context, override, fallback).s_addr));
option_put(mess, end, OPTION_LEASE_TIME, 4, time); option_put(mess, end, OPTION_LEASE_TIME, 4, time);
@@ -1452,7 +1452,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
override = lease->override; override = lease->override;
} }
clear_packet(mess, end); clear_packet(mess, end, sz);
option_put(mess, end, OPTION_MESSAGE_TYPE, 1, DHCPACK); option_put(mess, end, OPTION_MESSAGE_TYPE, 1, DHCPACK);
option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ, ntohl(server_id(context, override, fallback).s_addr)); option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ, ntohl(server_id(context, override, fallback).s_addr));
@@ -2181,11 +2181,22 @@ static struct dhcp_opt *pxe_opts(int pxe_arch, struct dhcp_netid *netid, struct
return ret; return ret;
} }
static void clear_packet(struct dhcp_packet *mess, unsigned char *end) static void clear_packet(struct dhcp_packet *mess, unsigned char *end, unsigned int sz)
{ {
unsigned char *opt;
unsigned int clid_tot = 0;
/* If sz is non-zero, save any client-id option by copying it as the first
option in the new packet */
if (sz != 0 && (opt = option_find(mess, sz, OPTION_CLIENT_ID, 1)))
{
clid_tot = option_len(opt) + 2u;
memmove(&mess->options[0] + sizeof(u32), opt, clid_tot);
}
memset(mess->sname, 0, sizeof(mess->sname)); memset(mess->sname, 0, sizeof(mess->sname));
memset(mess->file, 0, sizeof(mess->file)); memset(mess->file, 0, sizeof(mess->file));
memset(&mess->options[0] + sizeof(u32), 0, end - (&mess->options[0] + sizeof(u32))); memset(&mess->options[0] + sizeof(u32) + clid_tot, 0, end - (&mess->options[0] + sizeof(u32) + clid_tot));
mess->siaddr.s_addr = 0; mess->siaddr.s_addr = 0;
} }