Bedis9 website

Customize DHCP response from the Freebox Server

Posted on 2026-14-05

If you're managing a local lab or a home network with multiple services, you've likely run into the limitation of the Freebox DHCP interface. While it's a solid piece of hardware, the web UI doesn't always make it obvious how to pass complex configurations, specifically for Option 119 (Domain Search List).

Freebox server and custom DHCP options

From your LAN connection, browse the following URL to access your Freebox admin page: https://mafreebox.freebox.fr/. Click on the bottom left "f" image, then Connexion, then type your password.

Once connected: * double click on the "Paramètres de la Freebox" icon .. image:: /posts/images/freebox_connexion.png * double click on DHCP * scroll down to the bottom of the page * Click on "Ajouter une option"

  • Select the option name
  • Set the "valeur", which must be an hexadecimal string

I guess, Free does this to just have to send a bunch of bytes on the wire without processing them beforehand.

The Hexadecimal Puzzle

When you try to add multiple search domains (option name "Domain search" or ID 119) (e.g., int.bedis9.net and ui.bedis9.net), the Freebox Server expects a raw hexadecimal string rather than a comma-separated list. This is because it follows RFC 3397, which requires domains to be encoded as a series of labels, each prefixed by its length.

Note

Standard ASCII won't work here. You need to transform "example.com" into 076578616d706c6503636f6d00.

Translation with Bash

To save ourselves from manual hex conversion every time we update our infrastructure, I wrote a small utility script. It's bi-directional: give it a semicolon-separated list of domains to get the hex code, or paste a hex string to see what's hidden inside.

#!/bin/bash
# RFC 3397 Converter for Freebox DHCP Option 119

encode_rfc() {
    local input=$1
    local hex_result=""
    IFS=';' read -ra ADDR <<< "$input"
    for domain in "${ADDR[@]}"; do
        IFS='.' read -ra LABELS <<< "$domain"
        for label in "${LABELS[@]}"; do
            len=$(printf "%02x" ${#label})
            hex_label=$(echo -n "$label" | xxd -p)
            hex_result+="${len}${hex_label}"
        done
        hex_result+="00"
    done
    echo "$hex_result"
}

decode_rfc() {
    local hex=$1
    local i=0
    local result=""
    while [ $i -lt ${#hex} ]; do
        len_hex=${hex:$i:2}
        len=$((16#$len_hex))
        i=$((i + 2))
        if [ "$len" -eq 0 ]; then
            result+=";"
        else
            label_hex=${hex:$i:$((len * 2))}
            label=$(echo -n "$label_hex" | xxd -r -p)
            result+="$label"
            i=$((i + (len * 2)))
            next_len_hex=${hex:$i:2}
            if [ "$next_len_hex" != "00" ] && [ "$i" -lt ${#hex} ]; then
                result+="."
            fi
        fi
    done
    echo "${result%;}"
}

# Main logic
INPUT=$1
if [[ -z "$INPUT" ]]; then
    echo "Usage: $0 <string_or_hex>"
    exit 1
fi

if [[ "$INPUT" =~ ^[0-9a-fA-F]+$ ]]; then
    decode_rfc "$INPUT"
else
    encode_rfc "$INPUT"
fi

Example

Once set in the Freebox, the option should look like:

/posts/images/freebox_dhcp_option.png