#!/bin/ksh93 # Usage: see $0 -h typeset -r VERSION='1.0' FPROG=${.sh.file} PROG=${FPROG##*/} SDIR=${FPROG%/*} function showUsage { [[ -n $1 ]] && X='-?' || X='--man' getopts -a ${PROG} "${ print ${USAGE} ; }" OPT $X } function doMain { typeset -Ai HSEEN ASEEN typeset A LINE HNAME H integer N [[ -z $1 || ! -r "$1" ]] && showUsage 1 && exit 1 # sort on timestamp, newest first sort -k3nr $1 | \ while read LINE ; do A=( ${LINE} ) # EA\tIP\tTIMESTAMP\tHOSTNAME\tINTERFACE (( ${#A[@]} == 5 )) || continue # ignore comments and for "backward compat" entries with unresolved # hostname, i.e. raw IP [[ ${A:0:1} == '#' || ${A[3]} =~ \.[0-9][0-9]*$ ]] && continue # make unique: take into account only the 1st, most recent ea seen (( ASEEN["$A"] )) && continue ASEEN["$A"]=1 # append '-ip' to DECnet entry hostnames [[ ${A:0:7} == 'aa:0:4:' ]] && A[3]+='-ip' # append -old[N] suffix to duped hostnames HNAME="${A[3]}" if (( HSEEN["${HNAME}"] )); then H="${A[3]}-old" N=0 while (( HSEEN["$H"] )); do (( N++ )) H="${A[3]}-old$N" done A[3]="$H" fi HSEEN["${A[3]}"]=1 print "${A[0]}\t${A[3]}" done | sort # sort by ethernet address } USAGE="[-?${VERSION}"' ] [-copyright?Copyright (c) 2016 Jens Elkner. All rights reserved.] [-license?CDDL 1.0] [+NAME?'"${PROG}"' - ethers(4) generator] [+DESCRIPTION?This script prints out entries of the arpwatch database \afile\a (usually \b/var/arpwatch/arp.dat\b) in \bethers\b(4) format. Only the most recent, resolvable entries are taken into account, so it is normal, that the number of entries in the produced output and the database file differ.] [h:help?Print this help and exit.] [F:functions?Print a list of all functions available.] [T:trace]:[functionList?A comma separated list of functions of this script to trace (convinience for troubleshooting).] [+SEE ALSO?\barpwatch\b(1M).] \n\n\afile\a ' X="${ print ${USAGE} ; }" while getopts "${X}" OPT ; do case ${OPT} in h) showUsage ; exit 0 ;; T) if [[ ${OPTARG} == 'ALL' ]]; then typeset -ft ${ typeset +f ; } else typeset -ft ${OPTARG//,/ } fi ;; F) typeset +f && exit 0 ;; *) showUsage 1 ; exit 1 ;; esac done X=$((OPTIND-1)) shift $X && OPTIND=1 unset X doMain "$@"