Skip to content

Instantly share code, notes, and snippets.

@mattpascoe
Last active April 2, 2024 08:18
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save mattpascoe/4039747 to your computer and use it in GitHub Desktop.
Save mattpascoe/4039747 to your computer and use it in GitHub Desktop.
An AWK script to parse ISC dhcpd configuration files into dcm.pl output to load into OpenNetAdmin
#!/usr/bin/awk -f
#
# Author: Matt Pascoe - matt@opennetadmin.com
#
# This awk script is used to extract relavant information from a dhcpd.conf
# config file and build dcm.pl output with appropriate fields. This can be
# used to bootstrap a new database from existing site data.
# As usual, inspect the output for accuracy.
# Also you will get three types of output, subnet,pool,host. You must
# add the subnet information first, then pool, then host.
# Note that for hosts, it will try a reverse lookup on the IP address
# to determine an appropriate dns name
#
# USAGE:
# make this script executable with `chmod +x dhcpparse.awk` and then
#
# cat dhcpd.conf|./dhcpparse.awk|sort
# set the RECORD SEPARATOR, RS, to "}" ... records span multiple lines
BEGIN {RS="}"}
# TODO: figure out how to skip comment lines without having to use sed first
length($0) > 5 { total++
for(i=1;i<=NF;i++) {
counter[total] = total
# if this field matches the word "host"
if($i ~ /^host$/) {
type[total] = "host"
hostname[total]=$(i+1)
# Remove the trailing { that might be there
gsub(/{/, "", hostname[total])
}
# if this field matches the word "hardware"
else if($i ~ /^hardware$/) {
# get rid of the trailing semi-colon
split($(i+2),arr,";")
mac[total]=arr[1]
}
# if this field matches the word "hardware"
else if($i ~ /^fixed-address$/) {
# get rid of the trailing semi-colon
split($(i+1),arr,";")
ip[total]=arr[1]
}
# if this field matches the word "subnet"
else if($i ~ /^subnet$/) {
type[total] = "subnet"
# get rid of the enclosing quotes
split($(i+1),arr,"\"")
subnetip[total]=arr[1]
}
# if this field matches the word "netmask"
else if($i ~ /^netmask$/) {
subnetmask[total]=$(i+1)
}
# if this field matches the word "range"
else if($i ~ /^range$/) {
total++
type[total] = "pool"
poolstart[total]=$(i+1)
# get rid of the trailing semi-colon
split($(i+2),arr,";")
poolend[total]=arr[1]
}
# if this field matches the word "failover"
if($i ~ /^#failover$/) {
# get rid of the enclosing quotes
split($(i+2),arr,"\"")
failover[total]=arr[2]
}
}
# do a host command reverse lookup on the IP to try and find a dns name
if( length(ip[total]) > 0 ) {
command = ("host " ip[total])
command | getline tmpname
close(command)
split(tmpname,n,"pointer")
# trim off leading spaces etc
gsub(/^[ \t]+/, "", n[2])
name[total] = substr(n[2],0,length(n[2])-1)
}
if( length(name[total]) == 0 ) {
gsub(/\./, "-", hostname[total])
# This option turns the ip into a fake name
#name[total]="dhcpload-" ip[total]
# This option just uses the text found in the conf for host
name[total]=hostname[total]
}
}
# for every entry we captured, display its appropriate info
END { for(entry in counter) {
if(type[entry] == "subnet") {
printf("dcm.pl -r %s_add ip=%s netmask=%s name='DHCPLOAD-%s' type='LAN'\n",\
type[entry],subnetip[entry],subnetmask[entry],subnetip[entry])
}
if(type[entry] == "pool") {
printf("dcm.pl -r dhcp_pool_add start=%s end=%s\n",\
poolstart[entry],poolend[entry])
}
if(type[entry] == "host") {
printf("dcm.pl -r %s_add ip=%s mac=%s host=%s type='Unknown, Unknown (Manually loaded)'\n",\
type[entry],ip[entry],mac[entry],name[entry])
}
}
}
@crlsgms
Copy link

crlsgms commented Apr 13, 2016

well, I managed to get the script running, but nothing appeared on the interface, besides the DHCP Pools. So I tried to run one line at a time to troubleshoot where it stopped. After adding the pools, on the first host it prompts the syntaxe, maybe its something wrong on the host_add line:


dcm.pl -r host_add ip=20.14.11.11 mac=00:22:71:69:85:40 name=AP01_AD2_S11

host_add-v1.11
Add a new host

  Synopsis: host_add [KEY=VALUE] ...

  Required:
    host=NAME[.DOMAIN]        Hostname for new DNS record
    type=TYPE or ID           Device/model type or ID
    ip=ADDRESS                IP address (numeric or dotted)

  Optional:
    notes=NOTES               Textual notes
    location=REF              Reference of location
    device=NAME|ID            The device this host is associated with

  Optional, add an interface too:
    mac=ADDRESS               Mac address (most formats are ok)
    name=NAME                 Interface name (i.e. "FastEthernet0/1.100")
    description=TEXT          Brief description of the interface
    addptr=Y|N                Auto add a PTR record for new host/IP (default: Y)


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