Matching User Class (option 77) from RFC 3004 compliant clients in ISC DHCP
  • 04 Nov 2020
  • 2 Minutes To Read
  • Contributors
  • Print
  • Share
  • Dark
    Light

Matching User Class (option 77) from RFC 3004 compliant clients in ISC DHCP

  • Print
  • Share
  • Dark
    Light

ISC DHCP has a built-in definition for option 77 (User Class) of type text (character string) since this is the way that it was already being used before the publication of RFC 3004.

This means that it expects DHCP clients to present this option to the server in the form:
Option Code (1 byte)
Length (1 byte)
Character string ('Length' bytes)

The majority of clients still format option 77 as above, and have done so for many years, despite this not being in compliance with RFC 3004, which instead defines option 77 as an array of text elements, thus making it possible for a client to submit multiple values for User Class (although it seems unlikely to us that it would ever be used in this way). Option 77 presented as an array of text elements will appear like this:

Option Code (1 byte)
Overall array length (1 byte)
First element string length (1 byte)
First element character string ('length' bytes)
....
Nth element string length (1 byte)
Nth element character string

Recently, some DHCP client implementations (for example ThinOS 9) have updated their option 77 format to be compliant with RFC 3004. This is a problem for ISC DHCP because it does not natively recognise the new format.

Additionally, most production environments will most likely already have many clients presenting option 77 as a single string, and could now find themselves needing to cater for both possibilities!

For example, a client with User Class "foobar" would submit Option 77 in traditional format as (hexdecimal bytes):

4d 06 66 6f 6f 62 61 72

This is natively interpreted by ISC DHCP as:
Option Code (0x4d)
Length (0x06)
Character string (6 bytes) "foobar"

But another client using the format specified in RFC 3004 would send instead:

4d 07 06 66 6f 6f 62 61 72

This is intended to be understood as:
Option Code (0x4d)
Overall array length (0x07)
First element string length (0x06)
First element value "foobar"

From ISC DHCP's perspective, there is now an extra length field to be included when string-matching. Happily, it is possible to recognise clients presenting a single User Class in RFC3004 format when matching by prepending the escaped element string length to the string itself.

Therefore, if you wish to identify clients with User Class "foobar" but you don't know in which format they will present option 77 to you, you can test for both possible formats using syntax like this:

class "foobar-clients" {
match if exists user-class and (option user-class = "foobar" or option user-class = "\x06foobar");

NOTE: The match workaround above assumes that clients will send a single User Class only

The syntax for parsing the RFC 3004 format for the User Class assumes that the overall array length is correct for the length of the first string element, consisting of its own element length, plus the string itself. If the client sends more than one User Class value, then the overall length will include all of the strings, not just the first one alone and you will have devise a different matching syntax.