Subject: | VIVSO encapsulation bug fix |
Date: | Sat, 03 May 2014 11:57:59 -0700 |
To: | dhcp-bugs@isc.org |
From: | Bob Richmond <robert.richmond@greenwavereality.com> |
I originally sent this to dhcp-hackers, but this address seems more
appropriate.
The behavior when defining an option space to encapsulate inside the
vendor.* universe, that's supposed to be sent as option 125 in the
leases the server hands out is not working as advertised in the "VENDOR
ENCAPSULATED OPTIONS" section. Option 125 is never sent this way.
Googling indicates the most common workaround is to either manually
encapsulate vendor options in a big hex blob, or to redefine an option
space for option 125, and not use the implicit vendor.* universe. The
latter solution presents its own set of problems. To poke the value in a
way that causes 125 to be sent ends up encapsulating an extra bogus vendor.
The problem is that there's an early return in
hashed_option_space_encapsulate. Its job seems to be to determine when
there are values set in a particular universe that should be included as
outgoing encapsulated options. There's an early return when the universe
it's examining is NULL, and in the case of the vendor.* universe, it
will always be NULL because nothing directly sets its value. The magic
that checks whether there are suboptions that should be encapsulated in
its value never gets a chance to execute.
The attached patch fixes it for me.
And here's a dhcpd.conf that demonstrates the bug:
option space dslforum-org code width 1 length width 1 hash size 6;
option dslforum-org.DeviceManufacturerOUI code 1 = text;
option dslforum-org.DeviceSerialNumber code 2 = text;
option dslforum-org.DeviceProductClass code 3 = text;
option dslforum-org.GatewayManufacturerOUI code 4 = text;
option dslforum-org.GatewaySerialNumber code 5 = text;
option dslforum-org.GatewayProductClass code 6 = text;
option vendor.dslforum-org code 3561 = encapsulate dslforum-org;
class "dslforum.org" {
vendor-option-space dslforum-org;
match if (
exists dslforum-org.DeviceManufacturerOUI or
exists dslforum-org.DeviceSerialNumber or
exists dslforum-org.DeviceProductClass
);
set DeviceManufacturerOUI = option dslforum-org.DeviceManufacturerOUI;
set DeviceSerialNumber = option dslforum-org.DeviceSerialNumber;
set DeviceProductClass = option dslforum-org.DeviceProductClass;
option dslforum-org.GatewayManufacturerOUI "MyGatewayOUI";
option dslforum-org.GatewaySerialNumber "MyGatewaySerial";
option dslforum-org.GatewayProductClass "MyGatewayProductClass";
option dhcp-parameter-request-list = concat(option
dhcp-parameter-request-list, 7D);
}
subnet 192.168.1.0 netmask 255.255.255.0 {
range 192.168.1.100 192.168.1.200;
option routers 192.168.1.1;
option domain-name "yourdomainhere.com";
option domain-name-servers 192.168.1.1;
}
-----
And a corresponding dhclient.conf
option space dslforum-org code width 1 length width 1 hash size 6;
option dslforum-org.DeviceManufacturerOUI code 1 = text;
option dslforum-org.DeviceSerialNumber code 2 = text;
option dslforum-org.DeviceProductClass code 3 = text;
option dslforum-org.GatewayManufacturerOUI code 4 = text;
option dslforum-org.GatewayserialNumber code 5 = text;
option dslforum-org.GatewayProductClass code 6 = text;
option vendor.dslforum-org code 3561 = encapsulate dslforum-org;
interface "eth1" {
vendor option space dslforum-org;
send vivso
00:00:0D:E9:1A:01:05:4D:79:4F:55:49:02:08:4D:79:53:65:72:69:61:6C:03:07:4D:79:43:6C:61:73:73;
send vendor-class-identifier "MyClass:dslforum.org";
request subnet-mask, broadcast-address, time-offset, routers,
domain-name, domain-name-servers, host-name, vivso;
script "/dev/null";
}
alias { interface "eth1"; fixed-address 192.168.2.1; option subnet-mask
255.255.255.0; }
-----
I haven't yet figured out what the expected syntax is for defining an
encapsulated string that should be sent in a lease request via dhclient,
other than creating a hex blob. In the mean time, this perl one-liner
can generate an appropriate client vivso:
perl -e 'print join(":", map { sprintf("%02X", $_) } unpack("C*",
pack("NC/a*", 3561, pack("(CC/a)*", 1, "MyOUI", 2, "MySerial", 3,
"MyClass"))))."\n";'
Message body is not shown because sender requested not to inline it.