Категории

среда, 19 июня 2013 г.

isc-dhcpd - Скрипт для просмотра и удаления арендованных адресов из файла dhcpd.leases.

Скрипт парсит 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 $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 ${file}.new $file
        done

        [ -f "${file}~" ] && rm -f "${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

Комментариев нет:

Отправить комментарий