
(Custom- and Vendor-Options)
Created: 2023-03-30 Thu 19:38


Welcome to our Webinar on DHCP Options with Kea DHCP (with focus on vendor specific DHCP options)










0 and 255, DHCP options are
of variable size and have 3 fields
0 is the padding option to align the bytes in an DHCPv4
packet to word boundaries255 is the end marker option













"Dhcp4": {
"option-data": [{
"name": "domain-name-servers",
"code": 6,
"space": "dhcp4",
"csv-format": true,
"data": "192.0.2.1, 192.0.2.2"
},
...
]}


code, space and
csv-format can be omitted
"Dhcp4": {
"option-data": [{
"name": "domain-name-servers",
"data": "192.0.2.1, 192.0.2.2"
},
...
]}


[...]
"subnet4": [ {
"subnet": "192.0.2.0/24",
"pools": [ { "pool": "192.0.2.100 - 192.0.2.200" } ],
"option-data": [{
"name": "routers",
"data": "192.0.2.1" },
{
"name": "domain-name",
"data": "a.example.com" }
]},
[...]




{
"Dhcp4": {
"option-def": [{
"name": "my-message",
"code": 234,
"type": "string",
"array": false,
"record-types": "",
"space": "dhcp4",
"encapsulate": "" }],
"option-data": [{
"name": "my-message",
"space": "dhcp4",
"csv-format": true,
"data": "Hello World" }],
[...]














"Dhcp4": {
"option-def": [
{
"name": "vendor-option01",
"code": 1,
"space": "vendor-encapsulated-options-space",
"type": "string",
"array": false,
"record-types": "",
"encapsulate": ""
}
],
...
}


"Dhcp4": {
"option-data": [
{
"name": "vendor-option01",
"space": "vendor-encapsulated-options-space",
"code": 1,
"csv-format": true,
"data": "Hello World"
}
],
...
}






vendor-class-identifier DHCP option send by the client
"client-classes": [{
"name": "Foo-Bar-Device",
"test": "option[vendor-class-identifier].text == 'foo.bar.example'",
"option-data": [ {
"name": "log-servers",
"data": "192.0.2.42"
}]
}],
[...]














vendor-class-identifier or the VIVSO option and
can request the vendor specific options
vendor-class-identifier set to foo.bar.example# dhclient -v -V foo.bar.example


env to
print the environment variables, the ISC-DHCP client will print all
DHCP options received from the DHCP server/usr/local/bin/dhcp-debug.sh)#!/bin/sh env
# dhclient -v -V foo.bar.example -sf /usr/local/bin/dhcp-debug.sh


dhclient does not request the vendor-encapsulated-options by
default
/etc/dhclient.conf with the line request
vendor-encapsulated-options; to have dhclient request these options:# cat /etc/dhclient.conf also request vendor-encapsulated-options;


# dhclient -v -V ciscopnp -sf dhclient-debug.sh client-eth0 -cf /etc/dhclient.conf | grep new Internet Systems Consortium DHCP Client 4.4.3 Copyright 2004-2022 Internet Systems Consortium. All rights reserved. For info, please visit https://www.isc.org/software/dhcp/ Listening on LPF/client-eth0/4e:20:31:9e:50:31 Sending on LPF/client-eth0/4e:20:31:9e:50:31 Sending on Socket/fallback DHCPDISCOVER on client-eth0 to 255.255.255.255 port 67 interval 6 (xid=0xc14f112c) DHCPOFFER of 192.0.2.100 from 192.0.2.1 DHCPREQUEST for 192.0.2.100 on client-eth0 to 255.255.255.255 port 67 (xid=0xc14f112c) DHCPACK of 192.0.2.100 from 192.0.2.1 (xid=0xc14f112c) new_network_number=192.0.2.0 new_routers=192.0.2.1 new_dhcp_server_identifier=100.64.0.1 new_vendor_encapsulated_options=1:1a:35:41:31:44:3b:4b:34:3b:42:32:3b:49:31:39:32:2e:31:36:38:2e:31:30:30:2e:31:30 new_dhcp_lease_time=3600 new_dhcp_message_type=5 new_expiry=1680020260 new_broadcast_address=192.0.2.255 new_dhcp_rebinding_time=1800 new_ip_address=192.0.2.100 new_dhcp_renewal_time=900 new_next_server=0.0.0.0 old_dhcp_renewal_time=900 new_subnet_mask=255.255.255.0 bound to 192.0.2.100 -- renewal in 887 seconds.


tcpdump or wireshark
tcpdump -v -i eth0 port 67 and port 68
[...]
15:21:05.358570 IP (tos 0x10, ttl 128, id 0, offset 0, flags [none], proto UDP (17), length 338)
474ede70076e.bootps > 192.0.2.100.bootpc: BOOTP/DHCP, Reply, length 310, hops 1, xid 0x5be18f2f, Flags [none]
Your-IP 192.0.2.100
Gateway-IP 474ede70076e
Client-Ethernet-Address 4e:20:31:9e:50:31 (oui Unknown)
Vendor-rfc1048 Extensions
Magic Cookie 0x63825363
DHCP-Message (53), length 1: ACK
Subnet-Mask (1), length 4: 255.255.255.0
Default-Gateway (3), length 4: 474ede70076e
Vendor-Option (43), length 28: 1.26.53.65.49.68.59.75.52.59.66.50.59.73.49.57.50.46.49.54.56.46.49.48.48.46.49.48
Lease-Time (51), length 4: 3600
Server-ID (54), length 4: 100.64.0.1
RN (58), length 4: 900
RB (59), length 4: 1800


D
% ./dhcptest --query
dhcptest v0.7 - Created by Vladimir Panteleev
https://github.com/CyberShadow/dhcptest
Run with --help for a list of command-line options.
Listening for DHCP replies on port 68.
Sending packet:
op=BOOTREQUEST chaddr=2E:78:71:CA:DA:26 hops=0 xid=8DDD0A71 secs=0 flags=8000
ciaddr=0.0.0.0 yiaddr=0.0.0.0 siaddr=0.0.0.0 giaddr=0.0.0.0 sname= file=
1 options:
53 (DHCP Message Type): discover
Received packet from 192.0.2.8:67:
op=BOOTREPLY chaddr=2E:78:71:CA:DA:26 hops=0 xid=8DDD0A71 secs=0 flags=8000
ciaddr=0.0.0.0 yiaddr=192.0.2.115 siaddr=0.0.0.0 giaddr=0.0.0.0 sname= file=
9 options:
53 (DHCP Message Type): offer
1 (Subnet Mask): 255.255.255.0
3 (Router Option): 192.0.2.1
6 (Domain Name Server Option): 192.0.2.8, 172.16.1.105
15 (Domain Name): home.example.com
51 (IP Address Lease Time): 14400 (4 hours)
54 (Server Identifier): 192.0.2.8
58 (Renewal (T1) Time Value): 3600 (1 hour)
59 (Rebinding (T2) Time Value): 7200 (2 hours)




option space CISCOPNP;
option CISCOPNP.pnpserver code 43 = string;
class "ciscopnp" {
match if option vendor-class-identifier = "ciscopnp";
option vendor-class-identifier "ciscopnp";
vendor-option-space CISCOPNP;
option CISCOPNP.pnpserver = "5A1D;K4;B2;I192.168.100.10";
}
subnet 192.168.100.0 netmask 255.255.255.0 {
range 192.168.100.24 192.168.100.63;
option domain-name "example.org";
default-lease-time 600;
max-lease-time 7200;
}


"Dhcp4": {
"option-def": [{
"name": "pnpserver",
"code": 43, # Option code /inside/ option 43
"space": "vendor-encapsulated-options-space",
"type": "string",
"array": false
}],
"client-classes": [{
"name": "ciscopnpserver",
"test": "option[vendor-class-identifier].text == 'ciscopnp'",
"option-data": [{
"name": "vendor-encapsulated-options", "always-send": true },{
"name": "pnpserver",
"space": "vendor-encapsulated-options-space",
"code": 43, # Option code /inside/ option 43
"data": "5A1D;K4;B2;I192.168.100.10"
}]}],
"subnet4": [{
"subnet": "192.168.100.0/24",
"client-class": "ciscopnpserver",
"option-data": [
{"name": "routers","data": "192.168.100.1"}
],
"pools": [{ 'pool": "192.168.100.24 - 192.168.100.63" }]
},






{
"Dhcp4": {
"option-def": [{
"name": "discovery-control",
"code": 6,
"space": "vendor-encapsulated-options-space",
"type": "uint8",
"array": false
},{
"name": "boot-server",
"code": 8,
"type": "record",
"record-types": "uint16, uint8, ipv4-address",
"space": "vendor-encapsulated-options-space",
"array": false
},{
"name": "boot-menu",
"code": 9,
"type": "record",
"record-types": "uint16, uint8, string",
"space": "vendor-encapsulated-options-space",
"array": false
},{
"name": "menu-prompt",
"code": 10,
"type": "record",
"record-types": "uint8, string",
"space": "vendor-encapsulated-options-space",
"array": false
}],
[...]


[...]
"client-classes": [{
"name": "pxeclient",
"test": "option[60].text == 'PXEClient'",
"option-data": [
{ "name": "vendor-encapsulated-options", "always-send": false },
{ "name": "discovery-control", "space": "vendor-encapsulated-options-space", "data": "7" },
{ "name": "boot-menu", "space": "vendor-encapsulated-options-space", "data": "15,5,REMBO" },
{ "name": "menu-prompt", "space": "vendor-encapsulated-options-space", "data": "0,REMBO" }
]}],
[...]


[...]
"subnet4": [
{
"subnet": "192.0.2.0/24",
"client-class": "pxeclient",
"pools": [ { "pool": "192.0.2.100 - 192.0.2.200" } ],
"option-data": [
{ "name": "routers", "data": "192.0.2.1" }
]
}
],
[...]


tcpdump or Wireshark and compare the actual DHCP requests
and responses send"csv-format": false, "data": "C0 00 03 01 C0 00 03 02"






