Commit 88a77a78 authored by Simon Kelley's avatar Simon Kelley

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

parent 3e2496fb
...@@ -74,7 +74,10 @@ version 2.77 ...@@ -74,7 +74,10 @@ 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
translates to hosts on the local network, or, at translates to hosts on the local network, or, at
......
...@@ -38,7 +38,7 @@ static void log_packet(char *type, void *addr, unsigned char *ext_mac, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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));
...@@ -2180,12 +2180,23 @@ static struct dhcp_opt *pxe_opts(int pxe_arch, struct dhcp_netid *netid, struct ...@@ -2180,12 +2180,23 @@ 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;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment