From patchwork Sun Oct 18 22:19:58 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Leo-Andres Hofmann X-Patchwork-Id: 3586 Return-Path: Received: from mail01.ipfire.org (mail01.haj.ipfire.org [172.28.1.202]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384 client-signature ECDSA (P-384) client-digest SHA384) (Client CN "mail01.haj.ipfire.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by web04.haj.ipfire.org (Postfix) with ESMTPS id 4CDvTZ38kyz3yC4 for ; Sun, 18 Oct 2020 22:20:18 +0000 (UTC) Received: from mail02.haj.ipfire.org (mail02.haj.ipfire.org [172.28.1.201]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384 client-signature ECDSA (P-384) client-digest SHA384) (Client CN "mail02.haj.ipfire.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mail01.ipfire.org (Postfix) with ESMTPS id 4CDvTX1n2PzhV; Sun, 18 Oct 2020 22:20:16 +0000 (UTC) Received: from mail02.haj.ipfire.org (localhost [127.0.0.1]) by mail02.haj.ipfire.org (Postfix) with ESMTP id 4CDvTV5LYKz305b; Sun, 18 Oct 2020 22:20:14 +0000 (UTC) Received: from mail01.ipfire.org (mail01.haj.ipfire.org [172.28.1.202]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384 client-signature ECDSA (P-384) client-digest SHA384) (Client CN "mail01.haj.ipfire.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mail02.haj.ipfire.org (Postfix) with ESMTPS id 4CDvTT1xRhz2xZt for ; Sun, 18 Oct 2020 22:20:13 +0000 (UTC) Received: from mirfac.uberspace.de (mirfac.uberspace.de [185.26.156.40]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mail01.ipfire.org (Postfix) with ESMTPS id 4CDvTN48GbzsK for ; Sun, 18 Oct 2020 22:20:08 +0000 (UTC) Received: (qmail 13548 invoked from network); 18 Oct 2020 22:20:01 -0000 Received: from localhost (HELO suhail.uberspace.de) (127.0.0.1) by mirfac.uberspace.de with SMTP; 18 Oct 2020 22:20:01 -0000 Received: (qmail 22926 invoked from network); 18 Oct 2020 22:19:59 -0000 Received: from localhost (HELO ?192.168.144.16?) (127.0.0.1) by suhail.uberspace.de with SMTP; 18 Oct 2020 22:19:59 -0000 From: Leo Hofmann Subject: [PATCH] improve DHCP dynamic leases list usability To: development@lists.ipfire.org Message-ID: <3e1fa0ad-9391-362b-9b3e-550333dd565b@leo-andres.de> Date: Mon, 19 Oct 2020 00:19:58 +0200 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:68.0) Gecko/20100101 Thunderbird/68.12.1 MIME-Version: 1.0 ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=lists.ipfire.org; s=202003rsa; t=1603059609; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=o6igbFlesmdiXhP/7SAJYsGg0PWVQZxwmO/yWKAaR8U=; b=FmkwI+ryUiM418mcMbYce19pW2QwM/Fe+9RB+bIM4WJQy2fizTAK/rkulgy2Ck0Asf0v+D xdCJAYhK2Cd1ruM1dMuwuQuL7OdxLj17T9wwUQIWo5CXywH2bRoG+wlrytrXdGgk3zLHdP 8cdeMYWX56P4sz2NcZHViSX0nKqe437Fso6KrTE+0i1JI9xdKX1LraC/8V6E6q3orpY8pT LNnQLrwwpQkWtBc1H24dBD4T/XXb+Yvh1iS4tqFB6Nh8gpW+sq3jkVk0/5BEcNEEoocB5u PeAFnZNjU9IMFGeBaW2Bzrkpd3uapBqBCTCg61TBYAk5HxDZhP/OZ9k1Dj2LjQ== ARC-Authentication-Results: i=1; mail01.ipfire.org; dkim=none; spf=softfail (mail01.ipfire.org: 185.26.156.40 is neither permitted nor denied by domain of hofmann@leo-andres.de) smtp.mailfrom=hofmann@leo-andres.de ARC-Seal: i=1; s=202003rsa; d=lists.ipfire.org; t=1603059609; a=rsa-sha256; cv=none; b=spXRRQ+2vzlRc+ExwDv/VgaxjavjDpsguFMTitL90n8tqRJyUHvtUtyibTD3RFwk1dgFZ0 urlzwiCmxSB7Np1+XJOdgS0Gg99jCLsdSdXt44dLEJLWH3MQucDvgxBVKLv1Wm8/BpTpWd z8Y7V8fEE8/jD47P/MjF0+71HJRRQ9sJcGrYNr1SftVllp1iHF6IItLga0Jh2uF3aD9Z1f MXc0f8liFJCRkQFe11eEfedTNHFpzAz3Q9JaUKuZJY+nSjllaRmzPptztT3jXTKXpOghV+ GrH7BnZqi5xQ1eZf9RF6Q8Zx1qRZ1IoUlxi6lnU2GVxOaYRG/gzGSIGno8izdA== X-Spamd-Result: default: False [-3.11 / 11.00]; MIME_TRACE(0.00)[0:+]; ARC_NA(0.00)[]; FROM_HAS_DN(0.00)[]; TO_MATCH_ENVRCPT_ALL(0.00)[]; IP_REPUTATION_HAM(-0.01)[asn: 205766(0.00), country: DE(-0.00), ip: 185.26.156.40(0.00)]; MIME_GOOD(-0.10)[text/plain]; TO_DN_NONE(0.00)[]; ARC_SIGNED(0.00)[lists.ipfire.org:s=202003rsa:i=1]; R_SPF_SOFTFAIL(0.00)[~all]; RCPT_COUNT_ONE(0.00)[1]; RCVD_COUNT_THREE(0.00)[3]; DMARC_NA(0.00)[leo-andres.de]; FROM_EQ_ENVFROM(0.00)[]; RCVD_TLS_LAST(0.00)[]; R_DKIM_NA(0.00)[]; ASN(0.00)[asn:205766, ipnet:185.26.156.0/24, country:DE]; MID_RHS_MATCH_FROM(0.00)[]; BAYES_HAM(-3.00)[99.99%] Authentication-Results: mail01.ipfire.org; dkim=none; spf=softfail (mail01.ipfire.org: 185.26.156.40 is neither permitted nor denied by domain of hofmann@leo-andres.de) smtp.mailfrom=hofmann@leo-andres.de; dmarc=none X-Rspamd-Server: mail01.haj.ipfire.org X-Rspamd-Queue-Id: 4CDvTN48GbzsK X-BeenThere: development@lists.ipfire.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: IPFire development talk List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: development-bounces@lists.ipfire.org Sender: "Development" Some users have complained that displaying the active and expired leases in one unordered list is confusing. This patch improves the DHCP user interface by visually separating active and expired leases. The list is now sorted by active and expired leases and they are divided by a horizontal line. Sorting by IP/MAC/host/time and creating static leases remains unchanged. See forum topic for context: https://community.ipfire.org/t/dhcp-server-expired-leases/ Signed-off-by: Leo-Andres Hofmann ---  config/cfgroot/header.pl | 167 +++++++++++++++++++++++----------------  1 file changed, 97 insertions(+), 70 deletions(-) diff --git a/config/cfgroot/header.pl b/config/cfgroot/header.pl index 1046f5992..b5d153a55 100644 --- a/config/cfgroot/header.pl +++ b/config/cfgroot/header.pl @@ -403,88 +403,110 @@ sub PrintActualLeases  $tr{'mac address'}  $tr{'hostname'}  $tr{'lease expires'} (local time d/m/y) -Add to fix leases +Add to fix leases    END  ;      open(LEASES,"/var/state/dhcp/dhcpd.leases") or die "Can't open dhcpd.leases"; -    while ($line = ) { -    next if( $line =~ /^\s*#/ ); -    chomp($line); -    @temp = split (' ', $line); - -    if ($line =~ /^\s*lease/) { -        $ip = $temp[1]; -        #All field are not necessarily read. Clear everything -        $endtime = 0; -        $ether = ""; -        $hostname = ""; -    } +    while (my $line = ) { +        next if( $line =~ /^\s*#/ ); +        chomp($line); +        @temp = split (' ', $line); + +        if ($line =~ /^\s*lease/) { +            $ip = $temp[1]; +            #All field are not necessarily read. Clear everything +            $endtime = 0; +            $endtime_print = ""; +            $expired = 0; +            $ether = ""; +            $hostname = ""; +        } -    if ($line =~ /^\s*ends/) { -        $line =~ /(\d+)\/(\d+)\/(\d+) (\d+):(\d+):(\d+)/; -        $endtime = timegm($6, $5, $4, $3, $2 - 1, $1 - 1900); -    } +        if ($line =~ /^\s*ends/) { +            $line =~ /(\d+)\/(\d+)\/(\d+) (\d+):(\d+):(\d+)/; +            $endtime = timegm($6, $5, $4, $3, $2 - 1, $1 - 1900); +            ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $dst) = localtime($endtime); +            $endtime_print = sprintf ("%02d/%02d/%d %02d:%02d:%02d",$mday,$mon+1,$year+1900,$hour,$min,$sec); +            $expired = $endtime < time(); +        } -    if ($line =~ /^\s*hardware ethernet/) { -        $ether = $temp[2]; -        $ether =~ s/;//g; -    } +        if ($line =~ /^\s*hardware ethernet/) { +            $ether = $temp[2]; +            $ether =~ s/;//g; +        } -    if ($line =~ /^\s*client-hostname/) { -        $hostname = "$temp[1] $temp[2] $temp[3]"; -        $hostname =~ s/;//g; -        $hostname =~ s/\"//g; -    } +        if ($line =~ /^\s*client-hostname/) { +            $hostname = "$temp[1] $temp[2] $temp[3]"; +            $hostname =~ s/;//g; +            $hostname =~ s/\"//g; +        } -    if ($line eq "}") { -        @record = ('IPADDR',$ip,'ENDTIME',$endtime,'ETHER',$ether,'HOSTNAME',$hostname); -            $record = {};                                # create a reference to empty hash -        %{$record} = @record;                        # populate that hash with @record -        $entries{$record->{'IPADDR'}} = $record;       # add this to a hash of hashes -    } +        if ($line eq "}") { +            @record = ('IPADDR',$ip,'ENDTIME',$endtime,'ETHER',$ether,'HOSTNAME',$hostname,'endtime_print',$endtime_print,'expired',$expired); +            $record = {};                                # create a reference to empty hash +            %{$record} = @record;                        # populate that hash with @record +            $entries{$record->{'IPADDR'}} = $record;    # add this to a hash of hashes +        }      }      close(LEASES);      my $id = 0; -    my $col=""; +    my $col = ""; +    my $separator_printed = 0;      foreach my $key (sort leasesort keys %entries) { -    print "
\n"; -    my $hostname = &cleanhtml($entries{$key}->{HOSTNAME},"y"); - -    if ($id % 2) { -        print ""; -        $col="bgcolor='$table1colour'"; -    } -    else { -        print ""; -        $col="bgcolor='$table2colour'"; -    } - -    print <{HOSTNAME},"y"); +        my $hostname_print = $hostname; +        if($hostname_print eq "") { #print blank space if no hostname is found +            $hostname_print = "   "; +        } + +        # separate active and expired leases with a horizontal line +        if(($entries{$key}->{expired}) && ($separator_printed == 0)) { +            $separator_printed = 1; +            if ($id % 2) { +                print "
\n"; +            } else { +                print "
\n"; +            } +            $id++; +        } + +        print "\n"; +        if ($id % 2) { +            print ""; +            $col="bgcolor='$table1colour'"; +        } else { +            print ""; +            $col="bgcolor='$table2colour'"; +        } + +        if($entries{$key}->{expired}) { +            print <$entries{$key}->{IPADDR} +$entries{$key}->{ETHER} +$hostname_print +$entries{$key}->{endtime_print} +END +; +        } else { +            print <$entries{$key}->{IPADDR}  $entries{$key}->{ETHER} - $hostname - +$hostname_print +$entries{$key}->{endtime_print}  END -; - -    ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $dst) = localtime ($entries{$key}->{ENDTIME}); -    $enddate = sprintf ("%02d/%02d/%d %02d:%02d:%02d",$mday,$mon+1,$year+1900,$hour,$min,$sec); - -    if ($entries{$key}->{ENDTIME} < time() ){ -        print "$enddate"; -    } else { -        print "$enddate"; -    } -    print < - +; +        } + +        print < +  END -; -    $id++; -    } +; +        $id++; +    }      print "";      &closebox(); @@ -499,11 +521,14 @@ sub leasesort {          if ($qs eq 'IPADDR') {              @a = split(/\./,$entries{$a}->{$qs});              @b = split(/\./,$entries{$b}->{$qs}); +            $entries{$a}->{'expired'} <=> $entries{$b}->{'expired'} ||              ($b[0]<=>$a[0]) ||              ($b[1]<=>$a[1]) ||              ($b[2]<=>$a[2]) ||              ($b[3]<=>$a[3]); -        }else { +            ; +        } else { +            $entries{$a}->{'expired'} <=> $entries{$b}->{'expired'} ||              $entries{$b}->{$qs} cmp $entries{$a}->{$qs};          }      } @@ -511,15 +536,17 @@ sub leasesort {      {          $qs=$dhcpsettings{'SORT_LEASELIST'};          if ($qs eq 'IPADDR') { -        @a = split(/\./,$entries{$a}->{$qs}); +            @a = split(/\./,$entries{$a}->{$qs});              @b = split(/\./,$entries{$b}->{$qs}); +            $entries{$a}->{'expired'} <=> $entries{$b}->{'expired'} ||              ($a[0]<=>$b[0]) || -        ($a[1]<=>$b[1]) || -        ($a[2]<=>$b[2]) || +            ($a[1]<=>$b[1]) || +            ($a[2]<=>$b[2]) ||              ($a[3]<=>$b[3]); -    }else { +        } else { +            $entries{$a}->{'expired'} <=> $entries{$b}->{'expired'} ||              $entries{$a}->{$qs} cmp $entries{$b}->{$qs}; -    } +        }      }  }