"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/rfc2131.c" between
dnsmasq-2.82.tar.xz and dnsmasq-2.83.tar.xz

About: Dnsmasq is a lightweight caching DNS forwarder and DHCP server.

rfc2131.c  (dnsmasq-2.82.tar.xz):rfc2131.c  (dnsmasq-2.83.tar.xz)
skipping to change at line 33 skipping to change at line 33
#ifdef HAVE_SCRIPT #ifdef HAVE_SCRIPT
static void add_extradata_opt(struct dhcp_lease *lease, unsigned char *opt); static void add_extradata_opt(struct dhcp_lease *lease, unsigned char *opt);
#endif #endif
static int sanitise(unsigned char *opt, char *buf); static int sanitise(unsigned char *opt, char *buf);
static struct in_addr server_id(struct dhcp_context *context, struct in_addr ove rride, struct in_addr fallback); static struct in_addr server_id(struct dhcp_context *context, struct in_addr ove rride, struct in_addr fallback);
static unsigned int calc_time(struct dhcp_context *context, struct dhcp_config * config, unsigned char *opt); static unsigned int calc_time(struct dhcp_context *context, struct dhcp_config * config, unsigned char *opt);
static void option_put(struct dhcp_packet *mess, unsigned char *end, int opt, in t len, unsigned int val); static void option_put(struct dhcp_packet *mess, unsigned char *end, int opt, in t len, unsigned int val);
static void option_put_string(struct dhcp_packet *mess, unsigned char *end, static void option_put_string(struct dhcp_packet *mess, unsigned char *end,
int opt, char *string, int null_term); int opt, const char *string, int null_term);
static struct in_addr option_addr(unsigned char *opt); static struct in_addr option_addr(unsigned char *opt);
static unsigned int option_uint(unsigned char *opt, int offset, int size); static unsigned int option_uint(unsigned char *opt, int offset, int size);
static void log_packet(char *type, void *addr, unsigned char *ext_mac, static void log_packet(char *type, void *addr, unsigned char *ext_mac,
int mac_len, char *interface, char *string, char *err, u32 xid); int mac_len, char *interface, char *string, char *err, u32 xid);
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);
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,
skipping to change at line 57 skipping to change at line 57
char *hostname, char *hostname,
char *domain, char *domain,
struct dhcp_netid *netid, struct dhcp_netid *netid,
struct in_addr subnet_addr, struct in_addr subnet_addr,
unsigned char fqdn_flags, unsigned char fqdn_flags,
int null_term, int pxe_arch, int null_term, int pxe_arch,
unsigned char *uuid, unsigned char *uuid,
int vendor_class_len, int vendor_class_len,
time_t now, time_t now,
unsigned int lease_time, unsigned int lease_time,
unsigned short fuzz); unsigned short fuzz,
const char *pxevendor);
static void match_vendor_opts(unsigned char *opt, struct dhcp_opt *dopt); static void match_vendor_opts(unsigned char *opt, struct dhcp_opt *dopt);
static int do_encap_opts(struct dhcp_opt *opt, int encap, int flag, struct dhcp_ packet *mess, unsigned char *end, int null_term); static int do_encap_opts(struct dhcp_opt *opt, int encap, int flag, struct dhcp_ packet *mess, unsigned char *end, int null_term);
static void pxe_misc(struct dhcp_packet *mess, unsigned char *end, unsigned char *uuid); static void pxe_misc(struct dhcp_packet *mess, unsigned char *end, unsigned char *uuid, const char *pxevendor);
static int prune_vendor_opts(struct dhcp_netid *netid); static int prune_vendor_opts(struct dhcp_netid *netid);
static struct dhcp_opt *pxe_opts(int pxe_arch, struct dhcp_netid *netid, struct in_addr local, time_t now); static struct dhcp_opt *pxe_opts(int pxe_arch, struct dhcp_netid *netid, struct in_addr local, time_t now);
struct dhcp_boot *find_boot(struct dhcp_netid *netid); struct dhcp_boot *find_boot(struct dhcp_netid *netid);
static int pxe_uefi_workaround(int pxe_arch, struct dhcp_netid *netid, struct dh cp_packet *mess, struct in_addr local, time_t now, int pxe); static int pxe_uefi_workaround(int pxe_arch, struct dhcp_netid *netid, struct dh cp_packet *mess, struct in_addr local, time_t now, int pxe);
static void apply_delay(u32 xid, time_t recvtime, struct dhcp_netid *netid); static void apply_delay(u32 xid, time_t recvtime, struct dhcp_netid *netid);
static int is_pxe_client(struct dhcp_packet *mess, size_t sz, const char **pxe_v endor);
size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index, size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
size_t sz, time_t now, int unicast_dest, int loopback, size_t sz, time_t now, int unicast_dest, int loopback,
int *is_inform, int pxe, struct in_addr fallback, time_t recvti me) int *is_inform, int pxe, struct in_addr fallback, time_t recvti me)
{ {
unsigned char *opt, *clid = NULL; unsigned char *opt, *clid = NULL;
struct dhcp_lease *ltmp, *lease = NULL; struct dhcp_lease *ltmp, *lease = NULL;
struct dhcp_vendor *vendor; struct dhcp_vendor *vendor;
struct dhcp_mac *mac; struct dhcp_mac *mac;
struct dhcp_netid_list *id_list; struct dhcp_netid_list *id_list;
int clid_len = 0, ignore = 0, do_classes = 0, rapid_commit = 0, selecting = 0, pxearch = -1; int clid_len = 0, ignore = 0, do_classes = 0, rapid_commit = 0, selecting = 0, pxearch = -1;
const char *pxevendor = NULL;
struct dhcp_packet *mess = (struct dhcp_packet *)daemon->dhcp_packet.iov_base; struct dhcp_packet *mess = (struct dhcp_packet *)daemon->dhcp_packet.iov_base;
unsigned char *end = (unsigned char *)(mess + 1); unsigned char *end = (unsigned char *)(mess + 1);
unsigned char *real_end = (unsigned char *)(mess + 1); unsigned char *real_end = (unsigned char *)(mess + 1);
char *hostname = NULL, *offer_hostname = NULL, *client_hostname = NULL, *domai n = NULL; char *hostname = NULL, *offer_hostname = NULL, *client_hostname = NULL, *domai n = NULL;
int hostname_auth = 0, borken_opt = 0; int hostname_auth = 0, borken_opt = 0;
unsigned char *req_options = NULL; unsigned char *req_options = NULL;
char *message = NULL; char *message = NULL;
unsigned int time; unsigned int time;
struct dhcp_config *config; struct dhcp_config *config;
struct dhcp_netid *netid, *tagif_netid; struct dhcp_netid *netid, *tagif_netid;
skipping to change at line 649 skipping to change at line 652
if (hostname) if (hostname)
lease_set_hostname(lease, hostname, 1, get_domain(lease->addr), d omain); lease_set_hostname(lease, hostname, 1, get_domain(lease->addr), d omain);
/* infinite lease unless nailed in dhcp-host line. */ /* infinite lease unless nailed in dhcp-host line. */
lease_set_expires(lease, lease_set_expires(lease,
have_config(config, CONFIG_TIME) ? config->lease_ time : 0xffffffff, have_config(config, CONFIG_TIME) ? config->lease_ time : 0xffffffff,
now); now);
lease_set_interface(lease, int_index, now); lease_set_interface(lease, int_index, now);
clear_packet(mess, end); clear_packet(mess, end);
do_options(context, mess, end, NULL, hostname, get_domain(mess->yia ddr), do_options(context, mess, end, NULL, hostname, get_domain(mess->yia ddr),
netid, subnet_addr, 0, 0, -1, NULL, vendor_class_len, no w, 0xffffffff, 0); netid, subnet_addr, 0, 0, -1, NULL, vendor_class_len, no w, 0xffffffff, 0, NULL);
} }
} }
daemon->metrics[METRIC_BOOTP]++; daemon->metrics[METRIC_BOOTP]++;
log_packet("BOOTP", logaddr, mess->chaddr, mess->hlen, iface_name, NULL, m essage, mess->xid); log_packet("BOOTP", logaddr, mess->chaddr, mess->hlen, iface_name, NULL, m essage, mess->xid);
return message ? 0 : dhcp_packet_size(mess, agent_id, real_end); return message ? 0 : dhcp_packet_size(mess, agent_id, real_end);
} }
if ((opt = option_find(mess, sz, OPTION_CLIENT_FQDN, 3))) if ((opt = option_find(mess, sz, OPTION_CLIENT_FQDN, 3)))
skipping to change at line 838 skipping to change at line 841
override = mess->giaddr; override = mess->giaddr;
} }
} }
/* Can have setting to ignore the client ID for a particular MAC address or ho stname */ /* Can have setting to ignore the client ID for a particular MAC address or ho stname */
if (have_config(config, CONFIG_NOCLID)) if (have_config(config, CONFIG_NOCLID))
clid = NULL; clid = NULL;
/* Check if client is PXE client. */ /* Check if client is PXE client. */
if (daemon->enable_pxe && if (daemon->enable_pxe &&
(opt = option_find(mess, sz, OPTION_VENDOR_ID, 9)) && is_pxe_client(mess, sz, &pxevendor))
strncmp(option_ptr(opt, 0), "PXEClient", 9) == 0)
{ {
if ((opt = option_find(mess, sz, OPTION_PXE_UUID, 17))) if ((opt = option_find(mess, sz, OPTION_PXE_UUID, 17)))
{ {
memcpy(pxe_uuid, option_ptr(opt, 0), 17); memcpy(pxe_uuid, option_ptr(opt, 0), 17);
uuid = pxe_uuid; uuid = pxe_uuid;
} }
/* Check if this is really a PXE bootserver request, and handle specially if so. */ /* Check if this is really a PXE bootserver request, and handle specially if so. */
if ((mess_type == DHCPREQUEST || mess_type == DHCPINFORM) && if ((mess_type == DHCPREQUEST || mess_type == DHCPINFORM) &&
(opt = option_find(mess, sz, OPTION_VENDOR_CLASS_OPT, 1)) && (opt = option_find(mess, sz, OPTION_VENDOR_CLASS_OPT, 1)) &&
skipping to change at line 901 skipping to change at line 903
if (strchr(service->basename, '.')) if (strchr(service->basename, '.'))
snprintf((char *)mess->file, sizeof(mess->file), snprintf((char *)mess->file, sizeof(mess->file),
"%s", service->basename); "%s", service->basename);
else else
snprintf((char *)mess->file, sizeof(mess->file), snprintf((char *)mess->file, sizeof(mess->file),
"%s.%d", service->basename, layer); "%s.%d", service->basename, layer);
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, htonl(context ->local.s_addr)); option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ, htonl(context ->local.s_addr));
pxe_misc(mess, end, uuid); pxe_misc(mess, end, uuid, pxevendor);
prune_vendor_opts(tagif_netid); prune_vendor_opts(tagif_netid);
opt71.val = save71; opt71.val = save71;
opt71.opt = SUBOPT_PXE_BOOT_ITEM; opt71.opt = SUBOPT_PXE_BOOT_ITEM;
opt71.len = 4; opt71.len = 4;
opt71.flags = DHOPT_VENDOR_MATCH; opt71.flags = DHOPT_VENDOR_MATCH;
opt71.netid = NULL; opt71.netid = NULL;
opt71.next = daemon->dhcp_opts; opt71.next = daemon->dhcp_opts;
do_encap_opts(&opt71, OPTION_VENDOR_CLASS_OPT, DHOPT_VENDOR_MATCH, mess , end, 0); do_encap_opts(&opt71, OPTION_VENDOR_CLASS_OPT, DHOPT_VENDOR_MATCH, mess , end, 0);
skipping to change at line 981 skipping to change at line 983
else if (boot->tftp_sname) else if (boot->tftp_sname)
mess->siaddr = a_record_from_hosts(boot->tftp_sname, now) ; mess->siaddr = a_record_from_hosts(boot->tftp_sname, now) ;
if (boot->file) if (boot->file)
safe_strncpy((char *)mess->file, boot->file, sizeof(mess- >file)); safe_strncpy((char *)mess->file, boot->file, sizeof(mess- >file));
} }
option_put(mess, end, OPTION_MESSAGE_TYPE, 1, option_put(mess, end, OPTION_MESSAGE_TYPE, 1,
mess_type == DHCPDISCOVER ? DHCPOFFER : DHCPACK); mess_type == DHCPDISCOVER ? DHCPOFFER : DHCPACK);
option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ, htonl (tmp->local.s_addr)); option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ, htonl (tmp->local.s_addr));
pxe_misc(mess, end, uuid); pxe_misc(mess, end, uuid, pxevendor);
prune_vendor_opts(tagif_netid); prune_vendor_opts(tagif_netid);
if ((pxe && !workaround) || !redirect4011) if ((pxe && !workaround) || !redirect4011)
do_encap_opts(pxe_opts(pxearch, tagif_netid, tmp->local, now) , OPTION_VENDOR_CLASS_OPT, DHOPT_VENDOR_MATCH, mess, end, 0); do_encap_opts(pxe_opts(pxearch, tagif_netid, tmp->local, now) , OPTION_VENDOR_CLASS_OPT, DHOPT_VENDOR_MATCH, mess, end, 0);
daemon->metrics[METRIC_PXE]++; daemon->metrics[METRIC_PXE]++;
log_packet("PXE", NULL, emac, emac_len, iface_name, ignore ? "p roxy-ignored" : "proxy", NULL, mess->xid); log_packet("PXE", NULL, emac, emac_len, iface_name, ignore ? "p roxy-ignored" : "proxy", NULL, mess->xid);
log_tags(tagif_netid, ntohl(mess->xid)); log_tags(tagif_netid, ntohl(mess->xid));
if (!ignore) if (!ignore)
apply_delay(mess->xid, recvtime, tagif_netid); apply_delay(mess->xid, recvtime, tagif_netid);
return ignore ? 0 : dhcp_packet_size(mess, agent_id, real_end); return ignore ? 0 : dhcp_packet_size(mess, agent_id, real_end);
skipping to change at line 1152 skipping to change at line 1154
daemon->metrics[METRIC_DHCPOFFER]++; daemon->metrics[METRIC_DHCPOFFER]++;
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);
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);
/* T1 and T2 are required in DHCPOFFER by HP's wacky Jetdirect client. */ /* T1 and T2 are required in DHCPOFFER by HP's wacky Jetdirect client. */
do_options(context, mess, end, req_options, offer_hostname, get_domain(mes s->yiaddr), do_options(context, mess, end, req_options, offer_hostname, get_domain(mes s->yiaddr),
netid, subnet_addr, fqdn_flags, borken_opt, pxearch, uuid, vendo r_class_len, now, time, fuzz); netid, subnet_addr, fqdn_flags, borken_opt, pxearch, uuid, vendo r_class_len, now, time, fuzz, pxevendor);
return dhcp_packet_size(mess, agent_id, real_end); return dhcp_packet_size(mess, agent_id, real_end);
case DHCPREQUEST: case DHCPREQUEST:
if (ignore || have_config(config, CONFIG_DISABLE)) if (ignore || have_config(config, CONFIG_DISABLE))
return 0; return 0;
if ((opt = option_find(mess, sz, OPTION_REQUESTED_IP, INADDRSZ))) if ((opt = option_find(mess, sz, OPTION_REQUESTED_IP, INADDRSZ)))
{ {
/* SELECTING or INIT_REBOOT */ /* SELECTING or INIT_REBOOT */
mess->yiaddr = option_addr(opt); mess->yiaddr = option_addr(opt);
skipping to change at line 1500 skipping to change at line 1502
daemon->metrics[METRIC_DHCPACK]++; daemon->metrics[METRIC_DHCPACK]++;
log_packet("DHCPACK", &mess->yiaddr, emac, emac_len, iface_name, hostna me, NULL, mess->xid); log_packet("DHCPACK", &mess->yiaddr, emac, emac_len, iface_name, hostna me, NULL, mess->xid);
clear_packet(mess, end); clear_packet(mess, end);
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);
if (rapid_commit) if (rapid_commit)
option_put(mess, end, OPTION_RAPID_COMMIT, 0, 0); option_put(mess, end, OPTION_RAPID_COMMIT, 0, 0);
do_options(context, mess, end, req_options, hostname, get_domain(mess- >yiaddr), do_options(context, mess, end, req_options, hostname, get_domain(mess- >yiaddr),
netid, subnet_addr, fqdn_flags, borken_opt, pxearch, uuid, v endor_class_len, now, time, fuzz); netid, subnet_addr, fqdn_flags, borken_opt, pxearch, uuid, v endor_class_len, now, time, fuzz, pxevendor);
} }
return dhcp_packet_size(mess, agent_id, real_end); return dhcp_packet_size(mess, agent_id, real_end);
case DHCPINFORM: case DHCPINFORM:
if (ignore || have_config(config, CONFIG_DISABLE)) if (ignore || have_config(config, CONFIG_DISABLE))
message = _("ignored"); message = _("ignored");
daemon->metrics[METRIC_DHCPINFORM]++; daemon->metrics[METRIC_DHCPINFORM]++;
log_packet("DHCPINFORM", &mess->ciaddr, emac, emac_len, iface_name, messag e, NULL, mess->xid); log_packet("DHCPINFORM", &mess->ciaddr, emac, emac_len, iface_name, messag e, NULL, mess->xid);
skipping to change at line 1567 skipping to change at line 1569
if (lease && in_list(req_options, OPTION_LEASE_TIME)) if (lease && in_list(req_options, OPTION_LEASE_TIME))
{ {
if (lease->expires == 0) if (lease->expires == 0)
time = 0xffffffff; time = 0xffffffff;
else else
time = (unsigned int)difftime(lease->expires, now); time = (unsigned int)difftime(lease->expires, now);
option_put(mess, end, OPTION_LEASE_TIME, 4, time); option_put(mess, end, OPTION_LEASE_TIME, 4, time);
} }
do_options(context, mess, end, req_options, hostname, get_domain(mess->cia ddr), do_options(context, mess, end, req_options, hostname, get_domain(mess->cia ddr),
netid, subnet_addr, fqdn_flags, borken_opt, pxearch, uuid, vendo r_class_len, now, 0xffffffff, 0); netid, subnet_addr, fqdn_flags, borken_opt, pxearch, uuid, vendo r_class_len, now, 0xffffffff, 0, pxevendor);
*is_inform = 1; /* handle reply differently */ *is_inform = 1; /* handle reply differently */
return dhcp_packet_size(mess, agent_id, real_end); return dhcp_packet_size(mess, agent_id, real_end);
} }
return 0; return 0;
} }
/* find a good value to use as MAC address for logging and address-allocation ha shing. /* find a good value to use as MAC address for logging and address-allocation ha shing.
This is normally just the chaddr field from the DHCP packet, This is normally just the chaddr field from the DHCP packet,
skipping to change at line 1948 skipping to change at line 1950
{ {
int i; int i;
unsigned char *p = free_space(mess, end, opt, len); unsigned char *p = free_space(mess, end, opt, len);
if (p) if (p)
for (i = 0; i < len; i++) for (i = 0; i < len; i++)
*(p++) = val >> (8 * (len - (i + 1))); *(p++) = val >> (8 * (len - (i + 1)));
} }
static void option_put_string(struct dhcp_packet *mess, unsigned char *end, int opt, static void option_put_string(struct dhcp_packet *mess, unsigned char *end, int opt,
char *string, int null_term) const char *string, int null_term)
{ {
unsigned char *p; unsigned char *p;
size_t len = strlen(string); size_t len = strlen(string);
if (null_term && len != 255) if (null_term && len != 255)
len++; len++;
if ((p = free_space(mess, end, opt, len))) if ((p = free_space(mess, end, opt, len)))
memcpy(p, string, len); memcpy(p, string, len);
} }
skipping to change at line 2026 skipping to change at line 2028
/* mark vendor-encapsulated options which match the client-supplied or /* mark vendor-encapsulated options which match the client-supplied or
config-supplied vendor class */ config-supplied vendor class */
static void match_vendor_opts(unsigned char *opt, struct dhcp_opt *dopt) static void match_vendor_opts(unsigned char *opt, struct dhcp_opt *dopt)
{ {
for (; dopt; dopt = dopt->next) for (; dopt; dopt = dopt->next)
{ {
dopt->flags &= ~DHOPT_VENDOR_MATCH; dopt->flags &= ~DHOPT_VENDOR_MATCH;
if (opt && (dopt->flags & DHOPT_VENDOR)) if (opt && (dopt->flags & DHOPT_VENDOR))
{ {
int i, len = 0; const struct dhcp_pxe_vendor *pv;
if (dopt->u.vendor_class) struct dhcp_pxe_vendor dummy_vendor = {
len = strlen((char *)dopt->u.vendor_class); .data = (char *)dopt->u.vendor_class,
for (i = 0; i <= (option_len(opt) - len); i++) .next = NULL,
if (len == 0 || memcmp(dopt->u.vendor_class, option_ptr(opt, i), len) };
== 0) if (dopt->flags & DHOPT_VENDOR_PXE)
{ pv = daemon->dhcp_pxe_vendors;
dopt->flags |= DHOPT_VENDOR_MATCH; else
break; pv = &dummy_vendor;
} for (; pv; pv = pv->next)
{
int i, len = 0, matched = 0;
if (pv->data)
len = strlen(pv->data);
for (i = 0; i <= (option_len(opt) - len); i++)
if (len == 0 || memcmp(pv->data, option_ptr(opt, i), len) == 0)
{
matched = 1;
break;
}
if (matched)
{
dopt->flags |= DHOPT_VENDOR_MATCH;
break;
}
}
} }
} }
} }
static int do_encap_opts(struct dhcp_opt *opt, int encap, int flag, static int do_encap_opts(struct dhcp_opt *opt, int encap, int flag,
struct dhcp_packet *mess, unsigned char *end, int null_t erm) struct dhcp_packet *mess, unsigned char *end, int null_t erm)
{ {
int len, enc_len, ret = 0; int len, enc_len, ret = 0;
struct dhcp_opt *start; struct dhcp_opt *start;
unsigned char *p; unsigned char *p;
skipping to change at line 2087 skipping to change at line 2106
*(p++) = start->opt; *(p++) = start->opt;
*(p++) = len; *(p++) = len;
p += len; p += len;
} }
*p = OPTION_END; *p = OPTION_END;
} }
return ret; return ret;
} }
static void pxe_misc(struct dhcp_packet *mess, unsigned char *end, unsigned char *uuid) static void pxe_misc(struct dhcp_packet *mess, unsigned char *end, unsigned char *uuid, const char *pxevendor)
{ {
unsigned char *p; unsigned char *p;
option_put_string(mess, end, OPTION_VENDOR_ID, "PXEClient", 0); if (!pxevendor)
pxevendor="PXEClient";
option_put_string(mess, end, OPTION_VENDOR_ID, pxevendor, 0);
if (uuid && (p = free_space(mess, end, OPTION_PXE_UUID, 17))) if (uuid && (p = free_space(mess, end, OPTION_PXE_UUID, 17)))
memcpy(p, uuid, 17); memcpy(p, uuid, 17);
} }
static int prune_vendor_opts(struct dhcp_netid *netid) static int prune_vendor_opts(struct dhcp_netid *netid)
{ {
int force = 0; int force = 0;
struct dhcp_opt *opt; struct dhcp_opt *opt;
/* prune vendor-encapsulated options based on netid, and look if we're forcing them to be sent */ /* prune vendor-encapsulated options based on netid, and look if we're forcing them to be sent */
skipping to change at line 2307 skipping to change at line 2328
break; break;
if (!boot) if (!boot)
/* No match, look for one without a netid */ /* No match, look for one without a netid */
for (boot = daemon->boot_config; boot; boot = boot->next) for (boot = daemon->boot_config; boot; boot = boot->next)
if (match_netid(boot->netid, netid, 1)) if (match_netid(boot->netid, netid, 1))
break; break;
return boot; return boot;
} }
static int is_pxe_client(struct dhcp_packet *mess, size_t sz, const char **pxe_v
endor)
{
const unsigned char *opt = NULL;
ssize_t conf_len = 0;
const struct dhcp_pxe_vendor *conf = daemon->dhcp_pxe_vendors;
opt = option_find(mess, sz, OPTION_VENDOR_ID, 0);
if (!opt)
return 0;
for (; conf; conf = conf->next)
{
conf_len = strlen(conf->data);
if (option_len(opt) < conf_len)
continue;
if (strncmp(option_ptr(opt, 0), conf->data, conf_len) == 0)
{
if (pxe_vendor)
*pxe_vendor = conf->data;
return 1;
}
}
return 0;
}
static void do_options(struct dhcp_context *context, static void do_options(struct dhcp_context *context,
struct dhcp_packet *mess, struct dhcp_packet *mess,
unsigned char *end, unsigned char *end,
unsigned char *req_options, unsigned char *req_options,
char *hostname, char *hostname,
char *domain, char *domain,
struct dhcp_netid *netid, struct dhcp_netid *netid,
struct in_addr subnet_addr, struct in_addr subnet_addr,
unsigned char fqdn_flags, unsigned char fqdn_flags,
int null_term, int pxe_arch, int null_term, int pxe_arch,
unsigned char *uuid, unsigned char *uuid,
int vendor_class_len, int vendor_class_len,
time_t now, time_t now,
unsigned int lease_time, unsigned int lease_time,
unsigned short fuzz) unsigned short fuzz,
const char *pxevendor)
{ {
struct dhcp_opt *opt, *config_opts = daemon->dhcp_opts; struct dhcp_opt *opt, *config_opts = daemon->dhcp_opts;
struct dhcp_boot *boot; struct dhcp_boot *boot;
unsigned char *p; unsigned char *p;
int i, len, force_encap = 0; int i, len, force_encap = 0;
unsigned char f0 = 0, s0 = 0; unsigned char f0 = 0, s0 = 0;
int done_file = 0, done_server = 0; int done_file = 0, done_server = 0;
int done_vendor_class = 0; int done_vendor_class = 0;
struct dhcp_netid *tagif; struct dhcp_netid *tagif;
struct dhcp_netid_list *id_list; struct dhcp_netid_list *id_list;
skipping to change at line 2695 skipping to change at line 2740
} }
} }
} }
} }
} }
force_encap = prune_vendor_opts(tagif); force_encap = prune_vendor_opts(tagif);
if (context && pxe_arch != -1) if (context && pxe_arch != -1)
{ {
pxe_misc(mess, end, uuid); pxe_misc(mess, end, uuid, pxevendor);
if (!pxe_uefi_workaround(pxe_arch, tagif, mess, context->local, now, 0)) if (!pxe_uefi_workaround(pxe_arch, tagif, mess, context->local, now, 0))
config_opts = pxe_opts(pxe_arch, tagif, context->local, now); config_opts = pxe_opts(pxe_arch, tagif, context->local, now);
} }
if ((force_encap || in_list(req_options, OPTION_VENDOR_CLASS_OPT)) && if ((force_encap || in_list(req_options, OPTION_VENDOR_CLASS_OPT)) &&
do_encap_opts(config_opts, OPTION_VENDOR_CLASS_OPT, DHOPT_VENDOR_MATCH, me ss, end, null_term) && do_encap_opts(config_opts, OPTION_VENDOR_CLASS_OPT, DHOPT_VENDOR_MATCH, me ss, end, null_term) &&
pxe_arch == -1 && !done_vendor_class && vendor_class_len != 0 && pxe_arch == -1 && !done_vendor_class && vendor_class_len != 0 &&
(p = free_space(mess, end, OPTION_VENDOR_ID, vendor_class_len))) (p = free_space(mess, end, OPTION_VENDOR_ID, vendor_class_len)))
/* If we send vendor encapsulated options, and haven't already sent option 6 0, /* If we send vendor encapsulated options, and haven't already sent option 6 0,
echo back the value we got from the client. */ echo back the value we got from the client. */
 End of changes. 19 change blocks. 
26 lines changed or deleted 71 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)