#!/usr/bin/awk -f

# Author: wilsonj@cs.baylor.edu
# Date:   I think I wrote this January 2002

# Disclaimer: at one point, it worked with the lease file for ISC DHCPD v3.0pl2

# legalese: Copyright © 1998-2003 Baylor University
# THIS SOFTWARE, DATA AND/OR DOCUMENTATION ARE PROVIDED "AS IS"
# AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
# LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE.

# Expected input: /var/lib/dhcp/db/dhcpd.leases

# (For best results, pre-process the lease 
#  file with 'grep -v "uid \""')

# Usually invoked as, 'leases.awk /var/lib/dhcp/db/dhcpd.leases'

# Format of output (tab-delimited): 
#    ip,hardware[ip],compname[ip],state[ip],expiration-time-in-GMT[ip]

# set the RECORD SEPARATOR, RS, to "}" ... records span multiple lines
BEGIN {RS="}"}

# we only care about records that are greater than so-many-characters
# (why 5? I guess a CRLF may be 2 bytes ... isn't it just LF in BSD?)
length($0) > 5 { total++

  # only want record those variables we've captured,
  # so reset values to null
  endtime = ""
  hwaddr = ""
  cn = ""
  st = ""

  for(i=1;i<=NF;i++) {


    # if this field matches the word "lease"
    if($i ~ /lease/)

      # capture the next field into ipaddr
      ipaddr=$(i+1)

    # if this field matches the word "ethernet"
    else if($i ~ /ethernet/) {

      # get rid of the trailing semi-colon
      split($(i+1),arr,";")

      # and capture the hwaddr with ipaddr as key
      hwaddr=arr[1]
    }

    # if this field matches the word "client-hostname"
    else if($i ~ /client-hostname/) {

      # get rid of the enclosing quotes
      split($(i+1),arr,"\"")

      # capture the computer name
      cn=arr[2]
    }

    # if this field matches the word "binding"
    else if($i ~ /binding/) {

      # we don't care about what the next binding state is
      # so go on and process the rest of this record
      if($(i-1) ~ /next/) { # do nothing 
      }
      else {
        split($(i+2),arr,";")
        st=arr[1]
      }
    }

    # give me a timestamp or two
    else if($i ~ /ends/) {

      #if $i == "ends" then $i+2 is enddate, and $i+3 is endtime
      dtstmp = $(i+2);
      split($(i+3),arr,";")
      tmstmp = arr[1];
      endtime=sprintf("%s %s",dtstmp,tmstmp)
    }
  }
  if( length(hwaddr) > 0 )
    hardware[ipaddr]=hwaddr
  else
    hardward[ipaddr]="NONE"
  if( length(cn) > 0 )
    compname[ipaddr]=cn
  else
    compname[ipaddr]="NONE"
  if( length(st) > 0 )
    state[ipaddr]=st
  else
    state[ipaddr]="NONE"
  if( length(endtime) > 0 )
    mytime[ipaddr]=endtime
  else
    mytime[ipaddr]="NONE"
}

# for every ipaddr we captured, display ip, hardware, and compname
END { for(ip in hardware) {
       if(length(IP_ONLY)>0)
         print ip
       else
         printf("%s\t%s\t%s\t%s\t%s\n",\
                 ip,hardware[ip],compname[ip],state[ip],mytime[ip])
      }
}