On Fri Sep 14 16:31:55 BST 2007, Simon Kelleys wrote:
> The existing support for non-vendor-identifying encapsulated options is
> in two places. The data gets laid out in the packet in the second half
> of do_options() in src/rfc2131.c. That's quite hairy code, but it should
> be extendable to option 125 without too many problems.
>
> dhcp-option lines in the config file and command line are parsed into a
> linked-list of struct dhcp_opt in parse_dhcp_opt() in src/option.c.
> That's hairy too (sorry!). option-60 encapsulated options look like:
>
> dhcp-option=vendor:,
>
> That could be extended to cope with something like
>
> dhcp-option=vendor-id:,
> From: dnsmasq-discuss-requ...@lists.thekelleys.org.uk
> Subject: Welcome to the "Dnsmasq-discuss" mailing list
> Date: Thu, 04 Dec 2008 20:48:06 +
I have implemented something along these lines, which, in effect, allows
me to add following lines in dnsmasq.conf:
dhcp-option-force= net:iscsi-client0, net:gpxe, vendor-id:175, 190,
"iscsi-client0"
dhcp-option-force= net:iscsi-client0, net:gpxe, vendor-id:175, 191,
"iscsi-client0-secret"
and have the username and password fed to gPXE for iSCSI boot.
(Yes, I know, specifying those via DHCP is a recipe for a breaking.)
The patch works in just that scenario for me, but is otherwise untested.
Feel free to include it, if it looks interesting enough, and/or provide
feedback.
On the future side, it'd be nice to define symbolic names for custom
options and encapsulated options, ala ISC DHCP.
regards, Samium Gromoff
commit f1b1747ac88ac3dbfe44be9ce8e6c3400a6056dc
Author: Samium Gromoff
Date: Fri Dec 5 03:20:37 2008 +0300
Custom enterprise id support.
diff --git a/src/dnsmasq.h b/src/dnsmasq.h
index 24b4204..e7d5847 100644
--- a/src/dnsmasq.h
+++ b/src/dnsmasq.h
@@ -463,7 +463,7 @@ struct dhcp_config {
#define CONFIG_BANK 2048/* from dhcp hosts file */
struct dhcp_opt {
- int opt, len, flags;
+ int opt, encapsulating_opt, len, flags;
unsigned char *val, *vendor_class;
struct dhcp_netid *netid;
struct dhcp_opt *next;
diff --git a/src/option.c b/src/option.c
index 6b336fb..04b7c3f 100644
--- a/src/option.c
+++ b/src/option.c
@@ -19,6 +19,8 @@
#include "dnsmasq.h"
#include
+#define OPTION_VENDOR_CLASS_OPT 43/* Should be defined elsewhere. */
+
/* Solaris headers don't have facility names. */
#ifdef HAVE_SOLARIS_NETWORK
static const struct {
@@ -673,8 +675,14 @@ static char *parse_dhcp_opt(char *arg, int flags)
/* option: must follow tag and vendor string. */
break;
}
+ else if (strstr(arg, "vendor-id:") == arg)
+ {
+ new->encapsulating_opt = atoi(arg+10);
+ new->flags |= DHOPT_ENCAPSULATE;
+ }
else if (strstr(arg, "vendor:") == arg)
{
+ new->encapsulating_opt = OPTION_VENDOR_CLASS_OPT;
new->vendor_class = (unsigned char *)opt_string_alloc(arg+7);
new->flags |= DHOPT_ENCAPSULATE;
}
diff --git a/src/rfc2131.c b/src/rfc2131.c
index e3f50ba..0f53e95 100644
--- a/src/rfc2131.c
+++ b/src/rfc2131.c
@@ -1842,9 +1842,9 @@ static void do_options(struct dhcp_context *context,
/* prune encapsulated options based on netid, and look if we're forcing them
to be sent */
for (opt = config_opts; opt; opt = opt->next)
-if (opt->flags & DHOPT_VENDOR_MATCH)
+if (opt->flags & DHOPT_ENCAPSULATE)
{
- if (!match_netid(opt->netid, netid, 1) && !match_netid(opt->netid,
netid, 0))
+ if ((opt->flags & DHOPT_VENDOR_MATCH) && !match_netid(opt->netid,
netid, 1) && !match_netid(opt->netid, netid, 0))
opt->flags &= ~DHOPT_VENDOR_MATCH;
else if (opt->flags & DHOPT_FORCE)
force_encap = 1;
@@ -1857,16 +1857,16 @@ static void do_options(struct dhcp_context *context,
/* find size in advance */
for (start = opt = config_opts; opt; opt = opt->next)
- if (opt->flags & DHOPT_VENDOR_MATCH)
+ if (opt->flags & DHOPT_ENCAPSULATE)
{
int new = do_opt(opt, NULL, context->local, null_term) + 2;
if (enc_len + new <= 255)
enc_len += new;
else
{
- p = free_space(mess, end, OPTION_VENDOR_CLASS_OPT, enc_len);
+ p = free_space(mess, end, opt->encapsulating_opt, enc_len);
for (; start && start != opt; start = start->next)
- if (p && (start->flags & DHOPT_VENDOR_MATCH))
+ if (p && (start->flags & DHOPT_ENCAPSULATE))
{
len = do_opt(start, p + 2, context->local, null_term);
*(p++) = start->opt;
@@ -1879,10 +1879,10 @@ static void do_options(struct dhcp_context *context,
}
if (enc_len != 0 &&
- (p = free_space(mess, end, OPTION_VENDOR_CLASS_OPT, enc_len + 1)))
+ (p = free_space(mess, end, start->encapsulating_opt, enc_len + 1)))
{
fo