Skip to content

Instantly share code, notes, and snippets.

@wrobelda
Last active August 7, 2025 18:44
Show Gist options
  • Save wrobelda/403fe4e7ff542ce14a4bba9a06e40777 to your computer and use it in GitHub Desktop.
Save wrobelda/403fe4e7ff542ce14a4bba9a06e40777 to your computer and use it in GitHub Desktop.
Convert OPNHome ISC DHCP mappings to Dnsmasq CSV import
import xml.etree.ElementTree as ET
import csv
import sys
csv_writer = csv.writer(sys.stdout)
# Write header
csv_writer.writerow([
"host", "domain", "ip", "client_id", "hwaddr",
"lease_time", "ignore", "set_tag", "descr", "aliases"
])
# Read entire XML config from stdin
xml_data = sys.stdin.read()
root = ET.fromstring(xml_data)
dhcpd = root.find('dhcpd')
if dhcpd is None:
sys.exit("No <dhcpd> section found in config.xml")
for iface in dhcpd:
for staticmap in iface.findall('staticmap'):
mac = staticmap.findtext('mac', '').strip()
ip = staticmap.findtext('ipaddr', '').strip()
hostname = staticmap.findtext('hostname', '').strip()
if mac and ip:
csv_writer.writerow([
"", # host
"", # domain
ip,
"", # client_id
mac,
"", "", "",
hostname, # descr
"" # aliases
])
@wrobelda
Copy link
Author

wrobelda commented May 16, 2025

This extracts the ISC static DHCP mappings and converts them into CSV file, which you can then import in OPNSense (starting with 25.1.6).

Note: The script downgrades the mapping's hostname field into the description field. In my previous experience with ISC, clients were not able to report their hostnames correctly — they would end up with no hostname at all, which is why I was enforcing (overriding) the hostname. This is not needed with Dnsmasq anymore, as it picks up client's own hostname just fine, hence the hostname -> description mapping.

However, If you actually prefer to keep your hostname overrides, you can do so by moving the hostname variable in writerow() method to the first column, i.e. csv_writer.writerow([hostname, ...

You can run the script easily by downloading it to your desktop and executing with:

ssh user@opnsense 'cat /conf/config.xml' | python3 your_download_folder/convert_opnhome_isc_to_dnsmasq_csv.py > dhcp-mappings.csv

It connects to your opnsense host via SSH and pipes its config.xml file (which contains the DHCP mappings) onto the convert_opnhome_isc_to_dnsmasq_csv.py python script, which runs on your desktop and saves the mappings into dhcp-mappings.csv file.

@kwazieharry
Copy link

hi, what folder is /conf/config.xml located?

@aric89
Copy link

aric89 commented Aug 6, 2025

hi, what folder is /conf/config.xml located?

On opnsense. I downloaded it right to the firewall using fetch and then ran the command that way.

fetch https://gist.githubusercontent.com/wrobelda/403fe4e7ff542ce14a4bba9a06e40777/raw/a55012cd669e1f0b20e26fb65193b7e009ca52d4/convert_opnhome_isc_to_dnsmasq_csv.py

cat /conf/config.xml | python3 convert_opnhome_isc_to_dnsmasq_csv.py > dhcp-mappings.csv

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment