2024-09-07 19:51:44 +10:00
package SrvMngr::Controller::Dhcpd ;
#----------------------------------------------------------------------
# heading : Network
# description : DHCP manager
# navigation : 6000 550
#
# name : dhcpd, method : get, url : /dhcpd, ctlact : Dhcpd#main
# name : dhcpd1, method : get, url : /dhcpd1, ctlact : Dhcpd#do_leases
# name : dhcpd2, method : get, url : /dhcpd2, ctlact : Dhcpd#do_winpopup
# name : dhcpd3, method : get, url : /dhcpd3, ctlact : Dhcpd#do_scan
# name : dhcpd4, method : get, url : /dhcpd4, ctlact : Dhcpd#do_delete_all_leases
# name : dhcpd5, method : post, url : /dhcpd5, ctlact : Dhcpd#do_update_config
# name : dhcpd6, method : get, url : /dhcpd6, ctlact : Dhcpd#do_delete_one_lease
# name : dhcpd7, method : get, url : /dhcpd7, ctlact : Dhcpd#do_refresh_leases
# name : dhcpd8, method : get, url : /dhcpd8, ctlact : Dhcpd#do_winpopup
# name : dhcpd9, method : get, url : /dhcpd9, ctlact : Dhcpd#do_wol
# name : dhcpd10, method : post, url : /dhcpd10, ctlact : Dhcpd#do_update_check
#
# routes : end
#
#
# Documentation: https://wiki.koozali.org/Dhcpmanager
#
use strict ;
use warnings ;
use Mojo::Base 'Mojolicious::Controller' ;
use constant FALSE = > 0 ;
use constant TRUE = > 1 ;
use Locale::gettext ;
use SrvMngr::I18N ;
use SrvMngr qw( theme_list init_session ) ;
use Data::Dumper ;
use esmith::util ;
use esmith::HostsDB ;
use esmith::AccountsDB ;
use Net::Ping ;
use esmith::util::network qw( :all ) ;
use Socket qw( inet_aton ) ;
#our $adb = esmith::AccountsDB->open() or die("Unable to open accounts DB");
my % dhcp_data = ( ) ;
sub main {
#
# Initial page - full summary of parameters etc
# Initial para from the Wiki.
#
my $ c = shift ;
% dhcp_data = ( ) ;
do_display ( $ c ) ;
}
sub do_display {
#
# Front parameters page
#
my $ c = shift ;
$ c - > app - > log - > info ( $ c - > log_req ) ;
my $ title = $ c - > l ( "dhcpd_DHCP manager" ) ;
my $ modul = '' ;
my $ trt = "SETTINGS" ;
our $ db = esmith::ConfigDB - > open ( ) or die ( "Unable to open Configuration DB" ) ;
our % sme_conf = $ db - > get ( 'dhcpd' ) - > props ;
our % smb_conf = $ db - > get ( 'smb' ) - > props ;
$ dhcp_data { trt } = $ trt ;
$ dhcp_data { "status" } = [ [ $ c - > l ( 'dhcpd_ENABLED' ) , 'enabled' ] ,
[ $ c - > l ( 'dhcpd_DISABLED' ) , 'disabled' ]
] ;
$ dhcp_data { "check" } = [ [ $ c - > l ( 'dhcpd_ENABLED' ) , 'enabled' ] ,
[ $ c - > l ( 'dhcpd_DISABLED' ) , 'disabled' ]
] ;
if ( ! $ sme_conf { 'winscustom' } ) {
$ sme_conf { 'winscustom' } = 'disabled' ;
}
if ( ! $ sme_conf { 'dnscustom' } ) {
$ sme_conf { 'dnscustom' } = 'disabled' ;
}
if ( ! $ sme_conf { 'leasetime' } )
{ $ sme_conf { 'leasetime' } = "86400" ;
}
if ( ! $ sme_conf { 'gatewaycustom' } ) {
$ sme_conf { 'gatewaycustom' } = 'disabled' ;
}
# Accumulate parameters for Configuration DB
$ dhcp_data { 'params' } = \ % sme_conf ;
$ dhcp_data { 'smbparams' } = \ % smb_conf ;
$ c - > stash ( title = > $ title ,
modul = > $ modul ,
dhcp_data = > \ % dhcp_data
) ;
#die("here");
$ c - > render ( template = > 'dhcpd' ) ;
}
sub do_leases {
#
# Show a table of the leases
#
my $ c = shift ;
my $ title = $ c - > l ( "dhcpd_MANAGING_DHCP_CLIENT" ) ;
my $ modul = '' ;
my $ trt = "LEASES" ;
$ dhcp_data { "check" } = [ [ $ c - > l ( 'dhcpd_ENABLED' ) , 'enabled' ] ,
[ $ c - > l ( 'dhcpd_DISABLED' ) , 'disabled' ]
] ;
$ dhcp_data { trt } = $ trt ;
$ dhcp_data { "first" } = '' ;
my @ leases = get_leases_in_array ( $ c ) ;
$ c - > stash ( title = > $ title , modul = > $ modul , dhcp_data = > \ % dhcp_data , leases = > \ @ leases ) ;
$ c - > render ( template = > 'dhcpd' ) ;
}
sub do_winpopup {
#
# call to win pop up
#
my $ c = shift ;
my $ title = $ c - > l ( "dhcpd_GLOBAL_WINPOPUP" ) ;
my $ modul = '' ;
my $ trt = "WINPOPUP" ;
$ dhcp_data { trt } = $ trt ;
$ dhcp_data { "first" } = '' ;
#..... get winpopup details
$ c - > stash ( title = > $ title , modul = > $ modul , dhcp_data = > \ % dhcp_data ) ;
$ c - > render ( template = > 'dhcpd' ) ;
}
sub do_scan {
#
# call to show scan results
#
my $ c = shift ;
my $ title = $ c - > l ( "dhcpd_SCANNING_NETWORK_TITLE" ) ;
my $ modul = '' ;
my $ trt = "SCAN" ;
$ dhcp_data { trt } = $ trt ;
$ dhcp_data { "first" } = '' ;
# ..... get scan results into stash for passing to html template
my $ dhcp_scanresults = get_scan_results ( $ c ) ;
$ c - > stash ( title = > $ title , modul = > $ modul , "dhcp_data" = > \ % dhcp_data , "scanresults" = > $ dhcp_scanresults ) ;
$ c - > render ( template = > 'dhcpd' ) ;
}
sub do_update_config {
#
# Update config dhcp parameters
# called through form submit.
#
my $ c = shift ;
# Input results are in $c->param(<fieldname>).
# If parameters do not validate, then return error message.
# else write into config DB, and...
# signal-event and ...return ok
$ dhcp_data { "success" } = "" ;
my $ ret = Main_Save ( $ c ) ;
if ( $ ret eq 'ok' ) {
$ dhcp_data { "success" } = "dhcpd_SUCCESSFULLY_SAVED_SETTINGS" ;
} else {
$ dhcp_data { "error" } = $ ret ;
}
do_display ( $ c ) ;
return ;
}
sub do_update_check {
#Just update the check parameter
my $ c = shift ;
my $ dhcpd_check = $ c - > param ( 'dhcp_check' ) ;
###Update SME configuration dbase
my $ dbh_sme = esmith::ConfigDB - > open ( '/home/e-smith/db/configuration' ) ;
##Initiate get method --> create record object
my $ sme_record = $ dbh_sme - > get ( 'dhcpd' ) ;
$ sme_record - > set_prop ( 'check' , $ dhcpd_check ) ;
$ dhcp_data { "success" } = "dhcpd_SUCCESSFULLY_SAVED_SETTINGS" ;
do_display ( $ c ) ;
return ;
}
sub Main_Save ($) {
##Pull CGI object from parameters array
my $ q = shift ;
###Build Hash of config parameters to update from cgi submit
my $ dhcpd_status = $ q - > param ( 'dhcp_enable' ) ;
my $ dhcpd_winscustom = $ q - > param ( 'dhcp_winscustom' ) ;
my $ dhcpd_check = $ q - > param ( 'dhcp_check' ) ;
my $ dhcpd_start = $ q - > param ( 'dhcp_start' ) ;
my $ dhcpd_end = $ q - > param ( 'dhcp_end' ) ;
my $ dhcpd_winsserver = $ q - > param ( 'dhcp_winsserver' ) ;
my $ dhcpd_leasetime = $ q - > param ( 'dhcp_leasetime' ) ;
my $ dhcpd_dnscustom = $ q - > param ( 'dhcp_dnscustom' ) ;
my $ dhcpd_dns1server = $ q - > param ( 'dhcp_dns1server' ) ;
my $ dhcpd_dns2server = $ q - > param ( 'dhcp_dns2server' ) ;
my $ dhcpd_dns3server = $ q - > param ( 'dhcp_dns3server' ) ;
my $ dhcpd_gatewaycustom = $ q - > param ( 'dhcp_gatewaycustom' ) ;
my $ dhcpd_gateway = $ q - > param ( 'dhcp_gateway' ) ;
###Update SME configuration dbase
my $ dbh_sme = esmith::ConfigDB - > open ( '/home/e-smith/db/configuration' ) ;
##Initiate get method --> create record object
my $ sme_record = $ dbh_sme - > get ( 'dhcpd' ) ;
#get localip of server
my $ local_ip = $ dbh_sme - > get_value ( 'LocalIP' ) ;
##Set status of service
$ sme_record - > set_prop ( 'status' , $ dhcpd_status ) ;
$ sme_record - > set_prop ( 'check' , $ dhcpd_check ) ;
$ sme_record - > set_prop ( 'winscustom' , $ dhcpd_winscustom ) ;
$ sme_record - > set_prop ( 'leasetime' , $ dhcpd_leasetime ) ;
$ sme_record - > set_prop ( 'dnscustom' , $ dhcpd_dnscustom ) ;
$ sme_record - > set_prop ( 'gatewaycustom' , $ dhcpd_gatewaycustom ) ;
#checkip to the dhcpserver, perform the save in DB configuration or display an error if value != of a valid ip or if dhcp_start is greater than dhcp_end
if ( $ dhcpd_status eq "enabled" )
{
if ( isValidIP ( $ dhcpd_start ) && isValidIP ( $ dhcpd_end ) )
{
#check if $dhcpd_start is greater than $dhcpd_end and if yes, display an error message.
if ( inet_aton ( $ dhcpd_start ) ge inet_aton ( $ dhcpd_end ) )
{
return $ q - > l ( 'dhcpd_DHCP_START_GREATER_DHCP_END_ERRORS' ) . ' (' . $ dhcpd_start . '/' . $ dhcpd_end . ')' ;
}
elsif ( ( ( inet_aton ( $ dhcpd_start ) le inet_aton ( $ local_ip ) ) && ( inet_aton ( $ dhcpd_end ) ) ge inet_aton ( $ local_ip ) ) )
{
#display an error if the range of dhcp server include the ip of the server address
return $ q - > l ( 'dhcpd_DHCP_RANGE_MUST_NOT_INCLUDE_SERVER_IP' ) . ' (' . $ local_ip . ')' ;
}
else
{
#set value
my $ dhcpd_start = cleanIP ( $ dhcpd_start ) ;
my $ dhcpd_end = cleanIP ( $ dhcpd_end ) ;
$ sme_record - > set_prop ( 'end' , $ dhcpd_end ) ;
$ sme_record - > set_prop ( 'start' , $ dhcpd_start ) ;
}
}
#if $dhcpd_start or $dhcpd_end are not valid ip then display an error
else
{
return $ q - > l ( 'dhcpd_DHCP_RANGE_WITH_BAD_IP' ) . ' (' . $ dhcpd_start . '/' . $ dhcpd_end . ')' ;
}
}
#checkip to the winserver perform the save in DB configuration or display an error if value != of a valid ip
if ( $ dhcpd_winscustom eq "enabled" )
{
if ( isValidIP ( $ dhcpd_winsserver ) )
{
#set value
my $ dhcpd_winsserver = cleanIP ( $ dhcpd_winsserver ) ;
$ dbh_sme - > set_prop ( 'smb' , 'WINSServer' , $ dhcpd_winsserver ) ;
}
else
{
#if $dhcpd_winsserver is not valid ip then display an error
return $ q - > l ( 'dhcpd_WINSSERVER_BAD_IP' ) . ' (' . $ dhcpd_winsserver . ')' ;
}
}
elsif ( $ dhcpd_winscustom eq "disabled" )
{
my $ delws = $ dbh_sme - > get ( 'smb' ) ;
$ delws - > delete_prop ( 'WINSServer' ) ;
}
#checkip to the dnsserver custom, perform the save in DB configuration or display an error if value != of a valid ip
if ( $ dhcpd_dnscustom eq "enabled" )
{
#check if $dhcpd_dns1server and ( $dhcpd_dns2server are valid ip or $dhcpd_dns2server = null )
if ( isValidIP ( $ dhcpd_dns1server ) && ( isValidIP ( $ dhcpd_dns2server ) || ( $ dhcpd_dns2server eq "" ) ) && ( isValidIP ( $ dhcpd_dns3server ) || ( $ dhcpd_dns3server eq "" ) ) )
{
#set value
my $ dhcpd_dns1server = cleanIP ( $ dhcpd_dns1server ) ;
$ sme_record - > set_prop ( 'dns1server' , $ dhcpd_dns1server ) ;
my $ dhcpd_dns2server = cleanIP ( $ dhcpd_dns2server ) ;
$ sme_record - > set_prop ( 'dns2server' , $ dhcpd_dns2server ) ;
my $ dhcpd_dns3server = cleanIP ( $ dhcpd_dns3server ) ;
$ sme_record - > set_prop ( 'dns3server' , $ dhcpd_dns3server ) ;
}
else
{
##if $dhcpd_dns1server or $dhcpd_dns2server or $dhcpd_dns3server are not valid ip then display an error
return $ q - > l ( 'dhcpd_DNS_SERVER_WITH_BAD_IP' ) . ' (' . $ dhcpd_dns1server . '/' . $ dhcpd_dns2server . '/' . $ dhcpd_dns3server . ')' ;
}
}
#checkip to the gateway_custom perform the save in DB configuration or display an error if value != of a valid ip
if ( $ dhcpd_gatewaycustom eq "enabled" )
{
if ( isValidIP ( $ dhcpd_gateway ) )
{
#set value
my $ dhcpd_gateway = cleanIP ( $ dhcpd_gateway ) ;
$ sme_record - > set_prop ( 'gateway' , $ dhcpd_gateway ) ;
}
else
{
#if $dhcpd_gateway is not valid ip then display an error
return $ q - > l ( 'dhcpd_GATEWAY_BAD_IP' ) . ' (' . $ dhcpd_gateway . ')' ;
}
}
# - 4 expand templates
# changed to new sme standard signal-event
system ( "/sbin/e-smith/signal-event" , "workgroup-update" ) == 0
or die "Error while saving settings: $!" ;
return 'ok' ;
exit ;
}
sub do_delete_all_leases {
#
# Delete all the specified lease
# Called from button at top of leases list panel
#
my $ c = shift ;
my $ ret = delete_all_leases ( $ c ) ;
if ( $ ret == 'ok' ) {
$ dhcp_data { "success" } = "dhcpd_SUCCESSFULLY_SAVED_SETTINGS" ;
do_leases ( $ c ) ;
}
else { $ dhcp_data { "error" } = $ ret ; }
return ;
}
sub do_delete_one_lease {
#
# Delete the specified lease
# Called from link in table of leases
#
my $ c = shift ;
# Lease in $c->param("lease")
# Validate - if not return error message
# delete it
# If deletion not ok return message
# else return "ok"
my $ ret = delete_one_lease ( $ c ) ;
if ( $ ret == 'ok' ) {
$ dhcp_data { "success" } = "dhcpd_SUCCESSFULLY_SAVED_SETTINGS" ;
do_leases ( $ c ) ;
}
else { $ dhcp_data { "error" } = $ ret ; }
return ;
}
sub get_scan_results {
my $ c = shift ;
#...do it
return Scan_Local_Network ( $ c ) ;
}
sub update_config {
my $ c = shift ;
#...do it
return "ok" ;
}
sub delete_one_lease {
my $ c = shift ;
Perform_Del_Lease ( $ c ) ;
return "ok" ;
}
sub delete_all_leases {
my $ c = shift ;
Perform_del_all_Lease ( $ c ) ;
return "ok" ;
}
sub get_leases_in_array {
my $ c = shift ;
my @ leases = Load_leases ( $ c ) ;
# ...do it
return @ leases ;
}
sub Perform_del_all_Lease ($) {
system ( '/bin/echo "" > /var/lib/dhcpd/dhcpd.leases' ) == 0
or die "Error while removing all leases: $!" ;
system ( "/sbin/e-smith/signal-event" , "workgroup-update" ) == 0
or die "Error while saving settings: $!" ;
return 'ok' ;
exit ;
}
#===============================================================================
#SUBROUTINE: Perform delete lease
#===============================================================================
sub Perform_Del_Lease ($) {
###Pull CGI object from parameters array
my $ c = shift ;
#my $fred = 1/0;
###Pull entry to delete
my $ ip = $ c - > param ( 'ip' ) ;
my $ name = $ c - > param ( 'name' ) ;
my $ name_in_file = '/var/lib/dhcpd/dhcpd.leases' ;
my $ name_tmp_file = '/var/lib/dhcpd/dhcpd.leases.tmp' ;
my $ name_out_file = '/var/lib/dhcpd/dhcpd.leases~' ;
my $ del_current = "0" ;
open ( INFILE , "<$name_in_file" ) || die "Read Error $name_in_file, Read: $!" ;
open ( OUTFILE , ">$name_tmp_file" ) || die "Write error $name_in_file, Write: $!" ;
while ( <INFILE> ) {
if ( "$_" =~ /lease $ip/ ) {
$ del_current = "1" ;
}
if ( $ del_current == "0" ) { print OUTFILE "$_" ; }
if ( "$_" =~ /}/ ) {
$ del_current = "0" ;
}
}
rename ( $ name_tmp_file , $ name_in_file ) ;
system ( "/bin/cp" , "-f" , "$name_in_file" , "$name_out_file" ) ;
close ( INFILE ) ;
close ( OUTFILE ) ;
# changed to new sme standard signal-event
system ( "/sbin/e-smith/signal-event" , "workgroup-update" ) == 0
or die "Error while saving settings: $!" ;
###Return action message
return $ c - > l ( 'SUCCESSFULLY_DELETED_THE_CLIENT' ) . ' (' . $ name . '/' . $ ip . ')' ;
}
#===============================================================================
#SUBROUTINE: Scan The Local Network
#===============================================================================
sub dec2bin {
my $ str = unpack ( "B32" , pack ( "N" , shift ) ) ;
return $ str ;
}
sub netmask2cidr {
my ( $ mask , $ network ) = @ _ ;
my @ octet = split ( /\./ , $ mask ) ;
my @ bits ;
my $ binmask ;
my $ binoct ;
my $ bitcount = 0 ;
foreach ( @ octet ) {
$ binoct = dec2bin ( $ _ ) ;
$ binmask = $ binmask . substr $ binoct , - 8 ;
}
# let's count the 1s
@ bits = split ( // , $ binmask ) ;
foreach ( @ bits ) {
if ( $ _ eq "1" ) {
$ bitcount + + ;
}
}
my $ cidr = $ network . "/" . $ bitcount ;
return $ cidr ;
}
sub get_mac_address {
# From the leases file
my ( $ ip , $ file ) = @ _ ;
open ( my $ fh , '<' , $ file ) or die "Could not open file '$file' $!" ;
my $ mac_address = undef ;
my $ lease_block ;
2025-09-27 15:51:46 +01:00
my $ in_lease ;
while ( my $ line = <$fh> ) {
# Start of the lease block for the requested IP
if ( $ line =~ /^lease\s+\Q$ip\E\s*{/ ) {
$ in_lease = 1 ;
$ lease_block = $ line ;
next ;
}
# If inside the lease block, accumulate lines
if ( $ in_lease ) {
$ lease_block . = $ line ;
# Look for hardware ethernet line to capture MAC
if ( $ line =~ /hardware ethernet\s+(\S+);/ ) {
$ mac_address = $ 1 ;
}
# End of lease block
if ( $ line =~ /^}/ ) {
$ in_lease = 0 ;
last if $ mac_address ; # Exit if MAC found
$ lease_block = '' ; # Reset if MAC not found
}
}
}
2024-09-07 19:51:44 +10:00
close $ fh ;
return $ mac_address ;
}
sub trim { my $ s = shift ; $ s =~ s/^\s+|\s+$//g ; return $ s } ;
sub get_mac_address_by_ping {
my ( $ ip ) = trim ( @ _ ) ;
# Ping the IP to ensure it's in the ARP table
my $ ping_result = `ping -c 1 -W 1 $ip` ;
#return $ping_result;
if ( $ ping_result =~ m/1 packets transmitted, 1 received/ ) {
# Fetch the ARP table and find the line with the IP address
my $ mac_result = `nmap -PR -sn $ip` ;
#return "*$arp_result *$ip*";
# If found, return the MAC address
#if ($arp_result =~ m/.*at ((?:[0-9a-f]{2}\:){5}[0-9a-f]{2})/) {
if ( $ mac_result =~ /MAC Address: (..:..:..:..:..:..) / ) {
return $ 1 ;
} else { return "mac not in nmap result" ; }
} else { return "no ping" ; }
return undef ;
}
sub Scan_Local_Network ($) {
my $ nmap_sme = esmith::ConfigDB - > open ( '/home/e-smith/db/configuration' ) ;
my $ mask = $ nmap_sme - > get_value ( 'LocalNetmask' ) ;
my $ network = $ nmap_sme - > get_prop ( 'InternalInterface' , 'Network' ) ;
#we start to calculate the method to find the cidr (we want to use network/cidr with nmap)
my $ cidr = netmask2cidr ( $ mask , $ network ) ;
#ok go to use nmap with nmap -T4 -sP network/cidr
my @ nmap_output = ` /usr/ bin / nmap - - script smb - os - discovery . nse - p U:137 , T:139 $ cidr |
/bin/g rep - Ev "MAC|NetBIOS|OS CPE" | /bin/g rep - E "scan|done|Computer|OS" |
/bin/s ed - e 's/Nmap scan/-- Scan/g' | /bin/s ed - e 's/done/Done/g' |
/bin/s ed - e 's/Nmap//g' | /bin/s ed - e 's/|/ /g' ` ;
my @ extracted_output ;
my $ leasefile = "/var/lib/dhcpd/dhcpd.leases" ;
foreach my $ line ( @ nmap_output ) {
if ( $ line =~ m/Scan report for ([\w\.-]+) \(([\d\.\:]+)\)/ ) {
my $ ip = $ 2 ;
my $ mac = get_mac_address ( $ ip , $ leasefile ) ;
if ( ! $ mac ) {
$ mac = get_mac_address_by_ping ( $ ip ) ;
}
# if (!$mac) {$mac = "unknown";}
my % pair = ( 'Network' = > $ 1 , 'ip' = > $ ip , 'mac' = > $ mac ) ; # $1 => PC Name, $2 => IP Address
push @ extracted_output , \ % pair ;
}
}
return \ @ extracted_output ;
}
#=========================================================================
# Procedure qui charge le dhcpd.conf
# retourne un tableau contenant les informations
#=========================================================================
sub Load_leases ($) {
my $ q = shift ;
#Definition de variable
use vars qw /
@ detail $ work_line $ header / ;
my $ name_file = '/var/lib/dhcpd/dhcpd.leases' ;
our @ liste_computer = '' ;
our $ db = esmith::ConfigDB - > open ( ) or die ( "Unable to open Configuration DB" ) ;
our % sme_conf = $ db - > get ( 'dhcpd' ) - > props ;
#Ouverture du fichier en lecture seule
open ( FILE , "<$name_file" ) || die "Read error $name_file, Error: $!" ;
#Parcours du fichier dhcpd.leases
while ( <FILE> ) {
# suppression des commentaires
if ( $ _ =~ /^#/ ) { next ; }
#spurresion des lignes vides
if ( $ _ =~ /^$/ ) { next ; }
#supression de la ligne uid de windows
if ( $ _ =~ /uid/ ) { next ; }
#supression de la ligne tstp de XP
if ( $ _ =~ /tstp/ ) { next ; }
#supression de la ligne "binding state active"
if ( $ _ =~ /binding/ ) { next ; }
#supression de la ligne "next binding state"
if ( $ _ =~ /next/ ) { next ; }
#suprresion des commentaire et des ;
$ _ =~ s/\s#.*$// ;
$ _ =~ s/(;|{) *$// ;
#supression des espace en debut de lignes
$ _ =~ s/^ *\s// ;
#Suppression des retours chariot en fin de lignes.
chomp $ _ ;
#Chargement d'un tableau avec le contenu de la ligne.
( @ detail ) = split ( / / , $ _ ) ;
#initialisation d'un nouveau poste connect<63>
if ( $ _ =~ /lease/ ) {
$ work_line = "" ;
}
$ header = shift ( @ detail ) ;
$ work_line = $ work_line . ";" . join ( " " , @ detail ) ;
if ( $ header =~ /}/ ) {
$ work_line =~ s/ /;/g ;
$ work_line =~ s/^;// ;
$ work_line =~ s/"//g ;
$ work_line =~ s/;$// ;
#we want the last entry is the first element of the array
unshift ( @ liste_computer , $ work_line ) ;
}
}
close ( FILE ) ;
# Now check if up and extract details
my @ mac = ( ) ;
my @ count = ( ) ;
my @ results = ( ) ;
my @ liste_connected = ( ) ;
foreach ( @ liste_computer ) {
my @ computer = split ( /;/ , $ _ ) ;
#we want to sort elements the array by mac address
$ computer [ 11 ] = uc ( $ computer [ 11 ] ) ;
push @ mac , ( $ computer [ 11 ] ) ;
my @ count ;
push @ count , ( grep /$computer[11]/ , @ mac ) ;
next if ( scalar @ count > 1 ) ;
#we start the table if it is a valid IP
if ( $ computer [ 0 ] ) {
$ computer [ 12 ] = uc ( $ computer [ 12 ] ) ;
my $ datedeb = $ computer [ 2 ] . "-" . $ computer [ 3 ] ;
my $ datefin = $ computer [ 5 ] . "-" . $ computer [ 6 ] ;
my $ status = 'dhcpd_NOT_CHECKED' ;
#my $status = '<a href=/smanager/dhcpd1'."?state=wake_up&MAC=" . $computer[11] . "&name=" . $computer[12].">".$q->l('dhcpd_NOT_CHECKED')."</a>";
if ( $ sme_conf { 'check' } =~ /enabled/ ) {
use Net::Ping ;
my ( $ ping_obj ) = Net::Ping - > new ( "icmp" ) ;
# formatage des dates
$ computer [ 3 ] = substr ( $ computer [ 3 ] , 0 , 5 ) ;
$ computer [ 6 ] = substr ( $ computer [ 6 ] , 0 , 5 ) ;
if ( $ ping_obj - > ping ( "$computer[0]" ) ) {
push ( @ liste_connected , $ computer [ 12 ] ) ;
$ status = 'dhcpd_ACTIVE_DEVICE' ;
#alimentation de la liste des connect<63>
}
else { $ status = 'dhcpd_WAKE_UP_ACTION' ; }
#else { $status = '<a href=/smanager/dhcpd1'."?state=wake_up&MAC=" . $computer[11] . "&name=" . $computer[12].">".$q->l('dhcpd_WAKE_UP_ACTION')."</a>";
}
my % ipdetails = ( ip = > $ computer [ 0 ] , name = > $ computer [ 12 ] , wol = > $ status , start = > $ datedeb , end = > $ datefin , mac = > $ computer [ 11 ] ) ;
push ( @ results , \ % ipdetails ) ;
}
else {
push ( @ liste_connected , $ computer [ 12 ] ) ;
}
}
return @ results ;
}
sub winpopup {
my $ c = shift ;
# Message in $c->param("winpopupmsg")
# .... do it
return TRUE ;
}
sub do_wol {
my $ c = shift ;
my $ retVal = Perform_Wake_Up ( $ c ) ;
if ( $ retVal ) { $ dhcp_data { "success" } = $ retVal ; }
do_leases ( $ c ) ;
return TRUE ;
}
#===============================================================================
#SUBROUTINE: Perform wake UP
#===============================================================================
sub Perform_Wake_Up ($) {
###Pull CGI object from parameters array
my $ q = shift ;
###Get Mac Adress
my $ mac = uc ( $ q - > param ( 'mac' ) ) ;
my $ name = uc ( $ q - > param ( 'name' ) ) ;
#Send Wake Up to the station
#Old version obsolete since 1.5.0 - system ("/usr/bin/wol","$mac") ;
system ( "/sbin/ether-wake" , "$mac" ) ;
###Return action message
return 'dhcpd_SUCCESSFULLY_CLIENT_WOL_REQUEST' ;
}
2025-09-27 15:51:46 +01:00
1 ;