Last active
April 2, 2024 08:18
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/awk -f | |
# | |
# Author: Matt Pascoe - [email protected] | |
# | |
# 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]) | |
} | |
} | |
} |
Thanks very much matt on the troubleshooting and line of though using the import script. Ill test up the parse update and give some feedback asap.
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
My latest update now outputs direct dcm.pl command output instead of csv. There are goods and bads of both but the dcm.pl output seemed the most direct and simple for new users to understand and deal with. I also am defaulting hosts to the name field as defined in the dhcp.conf file. You can choose to switch to an IP mode here instead by adjusting comment lines at about line 112.