Скрипт парсит dhcpd.leases
файл и отображает список подсетей 0/24
на выбор, после выбора подсети выдается список арендованных ip
со статусом free
или active
,
где можно выбрать один или несколько ip
и удалить.
Скрипт использует dialog
, за счет чего меню получается очень привлекательным :) - писал под FreeBSD,
на Linux не тестировал (возможно будут проблемы из-за несовместимости BSD awk и GNU awk), хотя думаю, что должен работать и под Linux.
#!/bin/sh
# загружаем /etc/rc.conf.
. /etc/rc.conf
#TODO - установить имя файла более точнее, см. /usr/local/etc/rc.d/isc-dhcpd.
file=$dhcpd_rootdir/var/db/dhcpd/dhcpd.leases
tempfile=$(mktemp 2>/dev/null) || tempfile=/tmp/$(basename $0)_$$
trap "rm -f $tempfile" 0 1 2 5 15
### functions: BEGIN
# Функция запуска команд в информационном окошке.
exec_fun() {
dialog --sleep 1 --title "$2" \
--msgbox "`echo ;$1 2>&1;echo`" 15 85
}
# Функция удаления lease.
del_lease() {
exec_fun "service isc-dhcpd stop" "Status Daemon:"
#TODO - убедиться, что демон остановлен.
# Бекап базы.
DATE=$(date "+%Y%m%d%H%M")
cp -vf $file ${file}.$DATE
for i in $1; do
awk 'BEGIN { FLG=0; } {
if ($0=="lease '$i' {") FLG=1;
if (FLG=="0") printf "%s",$0"\n";
if ($0=="}" && FLG=="1") FLG=0;
}' $file > ${file}.new
mv -vf ${file}.new $file
done
[ -f "${file}~" ] && rm -vf "${file}~"
exec_fun "service isc-dhcpd start" "Status Daemon:"
#TODO - убедиться, что демон запущен.
}
# Функция получения списка subnet из dhcpd.leasees файла.
get_subnet_list() {
grep -oE '^lease [0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.' $file | sort -u \
| awk 'BEGIN { n=1; }{ print n" "$2"0/24 off"; n++; }'
}
# Функция получения списка ip по subnet'у /24 и вывод списка в виде dialog.
get_leases() {
while [ true ]; do
LIST=`awk '{ out=""; sub(/[;#].*/,"",$0); \
if ($1" "$2" "$3 ~ /^lease '$(echo $1 | sed 's|\.|\\.|g')'[0-9]?[0-9]?[0-9] \{$/ ) { out=" "$2; FLG=1; } \
if ($1=="binding" && FLG=="1") out=" "$3; \
if ($1=="}" && FLG=="1") { out="\n"; FLG=0; } \
printf out," "; }' $file | \
sort -un -t . -k 1,1 -k 2,2 -k 3,3 -k 4,4 | \
awk 'BEGIN { n=1; }{ print n" \""$1" "$2"\" off"; n++; }'`
DIALOG='dialog --backtitle "Редактирование '$file'"
--cancel-label Back
--ok-label Delete
--title "Редактирование '$1'0/24" --clear
--checklist "Выбор lease" 20 61 10
'$LIST' 2> '$tempfile
eval $DIALOG
# Собственно удаление выбранных lease. $(cat $tempfile)
if [ "$?" -eq 0 ]; then
# Формируем и передаваем в функцию удаления список ip.
DEL_LIST=''
for i in $(cat $tempfile); do
DEL_LIST="$DEL_LIST "$(echo "$LIST" | awk '{
if ($1=="'$i'") {
sub(/0\/24$/,"",$2);
sub(/"/,"",$2);
print $2;
}
}')
done
del_lease "$DEL_LIST"
else
break; # Выходим из while [true].
fi
done
}
### functions: END
[ ! -f $file ] && echo 'ERROR: File "'$file'" not exist or not readable!' && exit 1
while [ true ]; do
LIST="$(get_subnet_list)"
dialog --backtitle "Редактирование $file" \
--cancel-label Exit \
--title "Редактирование $file" --clear \
--radiolist "Выбор subnet" 20 61 10 \
$LIST 2> $tempfile
if [ "$?" -eq 0 ]; then
$(echo "$LIST" | awk '{ if ($1=="'$(cat $tempfile)'") { \
sub(/0\/24$/,"",$2); print "get_leases "$2 }}')
else
break; # Выходим из while [true].
fi
done
Comments
comments powered by Disqus