DHCPv6 vendor class option includes an enterprise number. Handle that.

This commit is contained in:
Simon Kelley
2012-02-10 13:42:47 +00:00
parent ceae00dddf
commit a5c72ab51d
4 changed files with 51 additions and 13 deletions

View File

@@ -566,7 +566,8 @@ struct pxe_service {
/* vendorclass, userclass, remote-id or cicuit-id */ /* vendorclass, userclass, remote-id or cicuit-id */
struct dhcp_vendor { struct dhcp_vendor {
int len, match_type, option; int len, match_type;
unsigned int enterprise;
char *data; char *data;
struct dhcp_netid netid; struct dhcp_netid netid;
struct dhcp_vendor *next; struct dhcp_vendor *next;

View File

@@ -467,11 +467,17 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
buf = grab_extradata(buf, end, "DNSMASQ_VENDOR_CLASS", &err); buf = grab_extradata(buf, end, "DNSMASQ_VENDOR_CLASS", &err);
#ifdef HAVE_DHCP6 #ifdef HAVE_DHCP6
else else
for (i = 0; i < data.hwaddr_len; i++) {
{ if (data.hwaddr_len != 0)
sprintf(daemon->dhcp_buff2, "DNSMASQ_VENDOR_CLASS%i", i); {
buf = grab_extradata(buf, end, daemon->dhcp_buff2, &err); buf = grab_extradata(buf, end, "DNSMASQ_VENDOR_CLASS_ID", &err);
} for (i = 0; i < data.hwaddr_len - 1; i++)
{
sprintf(daemon->dhcp_buff2, "DNSMASQ_VENDOR_CLASS%i", i);
buf = grab_extradata(buf, end, daemon->dhcp_buff2, &err);
}
}
}
#endif #endif
buf = grab_extradata(buf, end, "DNSMASQ_SUPPLIED_HOSTNAME", &err); buf = grab_extradata(buf, end, "DNSMASQ_SUPPLIED_HOSTNAME", &err);

View File

@@ -2870,6 +2870,18 @@ static char *one_opt(int option, char *arg, char *gen_prob, int command_line)
new->netid.net = opt_string_alloc(set_prefix(arg)); new->netid.net = opt_string_alloc(set_prefix(arg));
/* check for hex string - must digits may include : must not have nothing else, /* check for hex string - must digits may include : must not have nothing else,
only allowed for agent-options. */ only allowed for agent-options. */
arg = comma;
if ((comma = split(arg)))
{
if (option != 'U' || strstr(arg, "enterprise:") != arg)
option = '?';
else
new->enterprise = atoi(arg+11);
}
else
comma = arg;
for (p = (unsigned char *)comma; *p; p++) for (p = (unsigned char *)comma; *p; p++)
if (isxdigit(*p)) if (isxdigit(*p))
dig = 1; dig = 1;

View File

@@ -269,7 +269,20 @@ static int dhcp6_no_relay(int msg_type, struct dhcp_netid *tags, struct dhcp_con
if ((opt = opt6_find(packet_options, end, mopt, 2))) if ((opt = opt6_find(packet_options, end, mopt, 2)))
{ {
void *enc_opt, *enc_end = opt6_ptr(opt, opt6_len(opt)); void *enc_opt, *enc_end = opt6_ptr(opt, opt6_len(opt));
for (enc_opt = opt6_ptr(opt, 0); enc_opt; enc_opt = opt6_next(enc_opt, enc_end)) int offset = 0;
if (mopt == OPTION6_VENDOR_CLASS)
{
if (opt6_len(opt) < 4)
continue;
if (vendor->enterprise != opt6_uint(opt, 0, 4))
continue;
offset = 4;
}
for (enc_opt = opt6_ptr(opt, offset); enc_opt; enc_opt = opt6_next(enc_opt, enc_end))
for (i = 0; i <= (opt6_len(enc_opt) - vendor->len); i++) for (i = 0; i <= (opt6_len(enc_opt) - vendor->len); i++)
if (memcmp(vendor->data, opt6_ptr(enc_opt, i), vendor->len) == 0) if (memcmp(vendor->data, opt6_ptr(enc_opt, i), vendor->len) == 0)
{ {
@@ -620,14 +633,20 @@ static int dhcp6_no_relay(int msg_type, struct dhcp_netid *tags, struct dhcp_con
lease->extradata_size = lease->extradata_len = 0; lease->extradata_size = lease->extradata_len = 0;
lease->hwaddr_len = 0; /* surrogate for no of vendor classes */ lease->hwaddr_len = 0; /* surrogate for no of vendor classes */
if ((class_opt = opt6_find(packet_options, end, OPTION6_VENDOR_CLASS, 2))) if ((class_opt = opt6_find(packet_options, end, OPTION6_VENDOR_CLASS, 4)))
{ {
void *enc_opt, *enc_end = opt6_ptr(class_opt, opt6_len(class_opt)); void *enc_opt, *enc_end = opt6_ptr(class_opt, opt6_len(class_opt));
for (enc_opt = opt6_ptr(class_opt, 0); enc_opt; enc_opt = opt6_next(enc_opt, enc_end)) lease->hwaddr_len++;
{ /* send enterprise number first */
lease->hwaddr_len++; sprintf(daemon->dhcp_buff2, "%u", opt6_uint(class_opt, 0, 4));
lease_add_extradata(lease, opt6_ptr(enc_opt, 0), opt6_len(enc_opt), 0); lease_add_extradata(lease, (unsigned char *)daemon->dhcp_buff2, strlen(daemon->dhcp_buff2), 0);
}
if (opt6_len(class_opt) >= 6)
for (enc_opt = opt6_ptr(class_opt, 4); enc_opt; enc_opt = opt6_next(enc_opt, enc_end))
{
lease->hwaddr_len++;
lease_add_extradata(lease, opt6_ptr(enc_opt, 0), opt6_len(enc_opt), 0);
}
} }
lease_add_extradata(lease, (unsigned char *)client_hostname, lease_add_extradata(lease, (unsigned char *)client_hostname,