Commit 0a0702b8 authored by Ad Schellevis's avatar Ad Schellevis Committed by Franco Fichtner

(legacy) refactor status_dhcp_leases.php

(cherry picked from commit 493a3d18)
parent 87b9f56e
<?php <?php
/* /*
Copyright (C) 2014 Deciso B.V. Copyright (C) 2014-2016 Deciso B.V.
Copyright (C) 2004-2009 Scott Ullrich <sullrich@gmail.com> Copyright (C) 2004-2009 Scott Ullrich <sullrich@gmail.com>
Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>. Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
All rights reserved. All rights reserved.
...@@ -34,57 +34,6 @@ require_once("services.inc"); ...@@ -34,57 +34,6 @@ require_once("services.inc");
require_once("pfsense-utils.inc"); require_once("pfsense-utils.inc");
require_once("interfaces.inc"); require_once("interfaces.inc");
$service_hook = 'dhcpd';
$leasesfile = "{$g['dhcpd_chroot_path']}/var/db/dhcpd.leases";
if (($_GET['deleteip']) && (is_ipaddr($_GET['deleteip']))) {
/* Stop DHCPD */
killbyname("dhcpd");
/* Read existing leases */
/* $leases_contents has the lines of the file, including the newline char at the end of each line. */
$leases_contents = file($leasesfile);
$newleases_contents = array();
$i=0;
while ($i < count($leases_contents)) {
/* Find the lease(s) we want to delete */
if ($leases_contents[$i] == "lease {$_GET['deleteip']} {\n") {
/* Skip to the end of the lease declaration */
do {
$i++;
} while ($leases_contents[$i] != "}\n");
} else {
/* It's a line we want to keep, copy it over. */
$newleases_contents[] = $leases_contents[$i];
}
$i++;
}
/* Write out the new leases file */
$fd = fopen($leasesfile, 'w');
fwrite($fd, implode("\n", $newleases_contents));
fclose($fd);
/* Restart DHCP Service */
services_dhcpd_configure();
header("Location: status_dhcp_leases.php?all={$_GET['all']}");
}
include("head.inc");
?>
<body>
<?php include("fbegin.inc"); ?>
<section class="page-content-main">
<div class="container-fluid">
<div class="row">
<?php
function leasecmp($a, $b) function leasecmp($a, $b)
{ {
return strcmp($a[$_GET['order']], $b[$_GET['order']]); return strcmp($a[$_GET['order']], $b[$_GET['order']]);
...@@ -101,9 +50,10 @@ function adjust_gmt($dt) ...@@ -101,9 +50,10 @@ function adjust_gmt($dt)
foreach ($dhcpd as $dhcpditem) { foreach ($dhcpd as $dhcpditem) {
$dhcpleaseinlocaltime = $dhcpditem['dhcpleaseinlocaltime']; $dhcpleaseinlocaltime = $dhcpditem['dhcpleaseinlocaltime'];
if ($dhcpleaseinlocaltime == "yes") if ($dhcpleaseinlocaltime == "yes") {
break; break;
} }
}
if ($dhcpleaseinlocaltime == "yes") { if ($dhcpleaseinlocaltime == "yes") {
$ts = strtotime($dt . " GMT"); $ts = strtotime($dt . " GMT");
...@@ -115,43 +65,48 @@ function adjust_gmt($dt) ...@@ -115,43 +65,48 @@ function adjust_gmt($dt)
function remove_duplicate($array, $field) function remove_duplicate($array, $field)
{ {
foreach ($array as $sub) foreach ($array as $sub) {
$cmp[] = $sub[$field]; $cmp[] = $sub[$field];
}
$unique = array_unique(array_reverse($cmp,true)); $unique = array_unique(array_reverse($cmp,true));
foreach ($unique as $k => $rien) foreach ($unique as $k => $rien) {
$new[] = $array[$k]; $new[] = $array[$k];
}
return $new; return $new;
} }
$awk = "/usr/bin/awk"; $leasesfile = "{$g['dhcpd_chroot_path']}/var/db/dhcpd.leases";
/* this pattern sticks comments into a single array item */
$cleanpattern = "'{ gsub(\"#.*\", \"\");} { gsub(\";\", \"\"); print;}'"; if ($_SERVER['REQUEST_METHOD'] === 'GET') {
/* We then split the leases file by } */ $awk = "/usr/bin/awk";
$splitpattern = "'BEGIN { RS=\"}\";} {for (i=1; i<=NF; i++) printf \"%s \", \$i; printf \"}\\n\";}'"; /* this pattern sticks comments into a single array item */
$cleanpattern = "'{ gsub(\"#.*\", \"\");} { gsub(\";\", \"\"); print;}'";
/* stuff the leases file in a proper format into a array by line */ /* We then split the leases file by } */
exec("/bin/cat {$leasesfile} | {$awk} {$cleanpattern} | {$awk} {$splitpattern}", $leases_content); $splitpattern = "'BEGIN { RS=\"}\";} {for (i=1; i<=NF; i++) printf \"%s \", \$i; printf \"}\\n\";}'";
$leases_count = count($leases_content);
exec("/usr/sbin/arp -an", $rawdata); /* stuff the leases file in a proper format into a array by line */
$arpdata_ip = array(); exec("/bin/cat {$leasesfile} | {$awk} {$cleanpattern} | {$awk} {$splitpattern}", $leases_content);
$arpdata_mac = array(); $leases_count = count($leases_content);
foreach ($rawdata as $line) { exec("/usr/sbin/arp -an", $rawdata);
$arpdata_ip = array();
$arpdata_mac = array();
foreach ($rawdata as $line) {
$elements = explode(' ',$line); $elements = explode(' ',$line);
if ($elements[3] != "(incomplete)") { if ($elements[3] != "(incomplete)") {
$arpent = array(); $arpent = array();
$arpdata_ip[] = trim(str_replace(array('(',')'),'',$elements[1])); $arpdata_ip[] = trim(str_replace(array('(',')'),'',$elements[1]));
$arpdata_mac[] = strtolower(trim($elements[3])); $arpdata_mac[] = strtolower(trim($elements[3]));
} }
} }
unset($rawdata); unset($rawdata);
$pools = array(); $pools = array();
$leases = array(); $leases = array();
$i = 0; $i = 0;
$l = 0; $l = 0;
$p = 0; $p = 0;
// Put everything together again // Put everything together again
foreach($leases_content as $lease) { foreach($leases_content as $lease) {
/* split the line by space */ /* split the line by space */
$data = explode(" ", $lease); $data = explode(" ", $lease);
/* walk the fields */ /* walk the fields */
...@@ -242,7 +197,7 @@ foreach($leases_content as $lease) { ...@@ -242,7 +197,7 @@ foreach($leases_content as $lease) {
$leases[$l]['hostname'] = preg_replace('/"/','',$data[$f+1]); $leases[$l]['hostname'] = preg_replace('/"/','',$data[$f+1]);
} else { } else {
$hostname = gethostbyaddr($leases[$l]['ip']); $hostname = gethostbyaddr($leases[$l]['ip']);
if($hostname <> "") { if ($hostname <> "") {
$leases[$l]['hostname'] = $hostname; $leases[$l]['hostname'] = $hostname;
} }
} }
...@@ -258,21 +213,21 @@ foreach($leases_content as $lease) { ...@@ -258,21 +213,21 @@ foreach($leases_content as $lease) {
$i++; $i++;
/* slowly chisel away at the source array */ /* slowly chisel away at the source array */
array_shift($leases_content); array_shift($leases_content);
} }
/* remove the old array */ /* remove the old array */
unset($lease_content); unset($lease_content);
/* remove duplicate items by mac address */ /* remove duplicate items by mac address */
if(count($leases) > 0) { if(count($leases) > 0) {
$leases = remove_duplicate($leases,"ip"); $leases = remove_duplicate($leases,"ip");
} }
if(count($pools) > 0) { if(count($pools) > 0) {
$pools = remove_duplicate($pools,"name"); $pools = remove_duplicate($pools,"name");
asort($pools); asort($pools);
} }
foreach($config['interfaces'] as $ifname => $ifarr) { foreach($config['interfaces'] as $ifname => $ifarr) {
if (isset($config['dhcpd'][$ifname]['staticmap'])) { if (isset($config['dhcpd'][$ifname]['staticmap'])) {
foreach($config['dhcpd'][$ifname]['staticmap'] as $static) { foreach($config['dhcpd'][$ifname]['staticmap'] as $static) {
$slease = array(); $slease = array();
...@@ -288,77 +243,139 @@ foreach($config['interfaces'] as $ifname => $ifarr) { ...@@ -288,77 +243,139 @@ foreach($config['interfaces'] as $ifname => $ifarr) {
$leases[] = $slease; $leases[] = $slease;
} }
} }
} }
if ($_GET['order']) if ($_GET['order']) {
usort($leases, "leasecmp"); usort($leases, "leasecmp");
}
} elseif ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (!empty($_POST['deleteip']) && is_ipaddr($_POST['deleteip'])) {
// delete dhcp lease
/* Stop DHCPD */
killbyname("dhcpd");
$fin = @fopen($leasesfile, "r");
$fout = @fopen($leasesfile.".new", "w");
if ($fin) {
$ip_to_remove = $_POST['deleteip'];
$lease = "";
while (($line = fgets($fin, 4096)) !== false) {
$fields = explode(' ', $line);
if ($fields[0] == 'lease') {
// lease segment, record ip
$lease = trim($fields[1]);
}
if ($lease != $ip_to_remove) {
fputs($fout, $line);
}
if ($line == "}\n") {
// end of segment
$lease = "";
}
}
fclose($fin);
fclose($fout);
@unlink($leasesfile);
@rename($leasesfile.".new", $leasesfile);
/* Restart DHCP Service */
services_dhcpd_configure();
}
}
exit;
}
/* only print pool status when we have one */
if(count($pools) > 0) {
?> $service_hook = 'dhcpd';
include("head.inc");?>
<body>
<script>
$( document ).ready(function() {
$(".act_delete").click(function(){
$.post(window.location, {deleteip: $(this).data('deleteip')}, function(data) {
location.reload();
});
});
// keep sorting in place.
$(".act_sort").click(function(){
var all = <?=!empty($_GET['all']) ? 1 : 0;?> ;
document.location = document.location.origin + window.location.pathname +"?all="+all+"&order="+$(this).data('field');
});
});
</script>
<?php include("fbegin.inc"); ?>
<section class="page-content-main">
<div class="container-fluid">
<div class="row">
<?php
/* only print pool status when we have one */
legacy_html_escape_form_data($pools);
if(count($pools) > 0):?>
<section class="col-xs-12"> <section class="col-xs-12">
<div class="content-box"> <div class="content-box">
<div class="table-responsive"> <div class="table-responsive">
<table class="table table-striped table-sort sortable __nomb"> <table class="table table-striped">
<thead>
<tr> <tr>
<td class="listhdrr"><?=gettext("Failover Group"); ?></a></td> <th><?=gettext("Failover Group"); ?></th>
<td class="listhdrr"><?=gettext("My State"); ?></a></td> <th><?=gettext("My State"); ?></th>
<td class="listhdrr"><?=gettext("Since"); ?></a></td> <th><?=gettext("Since"); ?></th>
<td class="listhdrr"><?=gettext("Peer State"); ?></a></td> <th><?=gettext("Peer State"); ?></th>
<td class="listhdrr"><?=gettext("Since"); ?></a></td> <th><?=gettext("Since"); ?></th>
</tr> </tr>
<?php </thead>
foreach ($pools as $data) { <tbody>
echo "<tr>\n"; <?php
echo "<td class=\"listlr\">{$fspans}{$data['name']}{$fspane}</td>\n"; foreach ($pools as $data):?>
echo "<td class=\"listr\">{$fspans}{$data['mystate']}{$fspane}</td>\n"; <tr>
echo "<td class=\"listr\">{$fspans}" . adjust_gmt($data['mydate']) . "{$fspane}</td>\n"; <td><?=$data['name'];?></td>
echo "<td class=\"listr\">{$fspans}{$data['peerstate']}{$fspane}</td>\n"; <td><?=$data['mystate'];?></td>
echo "<td class=\"listr\">{$fspans}" . adjust_gmt($data['peerdate']) . "{$fspane}</td>\n"; <td><?=adjust_gmt($data['mydate']);?></td>
echo "<td class=\"list\" valign=\"middle\" width=\"17\">&nbsp;</td>\n"; <td><?=$data['peerstate'];?></td>
echo "<td class=\"list\" valign=\"middle\" width=\"17\">&nbsp;</td>\n"; <td><?=adjust_gmt($data['peerdate']);?></td>
echo "</tr>\n"; </tr>
} <?php
endforeach;?>
?> </tbody>
</table> </table>
</div> </div>
</div> </div>
</section> </section>
<?php <?php
/* only print pool status when we have one */ endif;?>
}
?>
<section class="col-xs-12"> <section class="col-xs-12">
<div class="content-box"> <div class="content-box">
<div class="table-responsive"> <div class="table-responsive">
<table class="table table-striped table-sort sortable __nomb"> <table class="table table-striped">
<thead>
<tr> <tr>
<td class="listhdrr"><?=gettext("IP address"); ?></td> <td class="act_sort" data-field="ip"><?=gettext("IP address"); ?></td>
<td class="listhdrr"><?=gettext("MAC address"); ?></td> <td class="act_sort" data-field="mac"><?=gettext("MAC address"); ?></td>
<td class="listhdrr"><?=gettext("Hostname"); ?></td> <td class="act_sort" data-field="hostname"><?=gettext("Hostname"); ?></td>
<td class="listhdrr"><?=gettext("Description"); ?></td> <td class="act_sort" data-field="desc"><?=gettext("Description"); ?></td>
<td class="listhdrr"><?=gettext("Start"); ?></td> <td class="act_sort" data-field="start"><?=gettext("Start"); ?></td>
<td class="listhdrr"><?=gettext("End"); ?></td> <td class="act_sort" data-field="end"><?=gettext("End"); ?></td>
<td class="listhdrr"><?=gettext("Status"); ?></td> <td class="act_sort" data-field="status"><?=gettext("Status"); ?></td>
<td class="listhdrr"><?=gettext("Lease type"); ?></td> <td class="act_sort" data-field="type"><?=gettext("Lease type"); ?></td>
<td class="listhdrr">&nbsp;</td> <td>&nbsp;</td>
</tr> </tr>
<?php </thead>
<tbody>
<?php
// Load MAC-Manufacturer table // Load MAC-Manufacturer table
$mac_man = load_mac_manufacturer_table(); $mac_man = load_mac_manufacturer_table();
foreach ($leases as $data) { legacy_html_escape_form_data($leases);
if (($data['act'] == "active") || ($data['act'] == "static") || ($_GET['all'] == 1)) { foreach ($leases as $data):
if ($data['act'] != "active" && $data['act'] != "static") { if (!($data['act'] == "active" || $data['act'] == "static" || $_GET['all'] == 1)) {
$fspans = "<span class=\"gray\">"; continue;
$fspane = "&nbsp;</span>";
} else {
$fspans = "";
$fspane = "&nbsp;";
} }
$dhcpd = array(); $dhcpd = array();
if (isset($config['dhcpd'])) { if (isset($config['dhcpd'])) {
$dhcpd = $config['dhcpd']; $dhcpd = $config['dhcpd'];
...@@ -376,94 +393,86 @@ if(count($pools) > 0) { ...@@ -376,94 +393,86 @@ if(count($pools) > 0) {
} }
} }
/* exit as soon as we have an interface */ /* exit as soon as we have an interface */
if ($data['if'] != "") if ($data['if'] != "") {
break; break;
} }
}
} else { } else {
foreach ($dhcpd as $dhcpif => $dhcpifconf) { foreach ($dhcpd as $dhcpif => $dhcpifconf) {
if (!is_array($dhcpifconf['range'])) if (empty($dhcpifconf['range'])) {
continue; continue;
}
if (($lip >= ip2ulong($dhcpifconf['range']['from'])) && ($lip <= ip2ulong($dhcpifconf['range']['to']))) { if (($lip >= ip2ulong($dhcpifconf['range']['from'])) && ($lip <= ip2ulong($dhcpifconf['range']['to']))) {
$data['if'] = $dhcpif; $data['if'] = $dhcpif;
break; break;
} }
} }
} }
echo "<tr>\n"; $mac_hi = strtoupper($data['mac'][0] . $data['mac'][1] . $data['mac'][3] . $data['mac'][4] . $data['mac'][6] . $data['mac'][7]);
echo "<td class=\"listlr\">{$fspans}{$data['ip']}{$fspane}</td>\n"; ?>
$mac = $data['mac']; <tr>
$mac_hi = strtoupper($mac[0] . $mac[1] . $mac[3] . $mac[4] . $mac[6] . $mac[7]); <td><?=$data['ip'];?></td>
if ($data['online'] != "online") { <td>
if (isset($mac_man[$mac_hi])) { // Manufacturer for this MAC is defined <a href="services_wol.php?if=<?=$data['if'];?>&amp;mac=<?=$data['mac'];?>" title="<?=gettext("send Wake on LAN packet to this MAC address");?>">
echo "<td class=\"listr\">{$fspans}<a href=\"services_wol.php?if={$data['if']}&amp;mac=$mac\" title=\"" . gettext("$mac - send Wake on LAN packet to this MAC address") ."\">{$mac}</a><br /><font size=\"-2\"><i>{$mac_man[$mac_hi]}</i></font>{$fspane}</td>\n"; <?=$data['mac'];?>
} else { </a>
echo "<td class=\"listr\">{$fspans}<a href=\"services_wol.php?if={$data['if']}&amp;mac={$data['mac']}\" title=\"" . gettext("send Wake on LAN packet to this MAC address") ."\">{$data['mac']}</a>{$fspane}</td>\n"; <br />
} <small><i><?=!empty($mac_man[$mac_hi]) ? $mac_man[$mac_hi] : "";?></i></small>
} else { </td>
if (isset($mac_man[$mac_hi])) { // Manufacturer for this MAC is defined <td><?=$data['hostname'];?></td>
echo "<td class=\"listr\">{$fspans}{$mac}<br /><font size=\"-2\"><i>{$mac_man[$mac_hi]}</i></font>{$fspane}</td>\n"; <td><?=$data['descr'];?></td>
} else { <td><?=!empty($data['start']) ? adjust_gmt($data['start']) : "";?></td>
echo "<td class=\"listr\">{$fspans}{$data['mac']}{$fspane}</td>\n"; <td><?=!empty($data['end']) ? adjust_gmt($data['end']) : "";?></td>
} <td><?=$data['online'];?></td>
} <td><?=$data['act'];?></td>
echo "<td class=\"listr\">{$fspans}" . htmlentities($data['hostname']) . "{$fspane}</td>\n"; <td>
if (isset($data['descr'])) { <?php
echo "<td class=\"listr\">{$fspans}" . htmlentities($data['descr']) . "{$fspane}</td>\n"; if ($data['type'] == "dynamic"):?>
} else { <a class="btn btn-default btn-xs" href="services_dhcp_edit.php?if=<?=$data['if'];?>&amp;mac=<?=$data['mac'];?>&amp;hostname=<?=$data['hostname'];?>">
echo "<td class=\"listr\">{$fspans} n/a {$fspane}</td>\n"; <span class="glyphicon glyphicon-plus" data-toggle="tooltip" title="<?=gettext("add a static mapping for this MAC address");?>" alt="add" ></span>
} </a>
if ($data['type'] != "static") { <?php
echo "<td class=\"listr\">{$fspans}" . adjust_gmt($data['start']) . "{$fspane}</td>\n"; endif;?>
echo "<td class=\"listr\">{$fspans}" . adjust_gmt($data['end']) . "{$fspane}</td>\n"; <a class="btn btn-default btn-xs" href="services_wol_edit.php?if=<?=$data['if'];?>&amp;mac=<?=$data['mac'];?>&amp;descr=<?=$data['hostname'];?>">
} else { <span class="glyphicon glyphicon-flash" data-toggle="tooltip" title="<?=gettext("add a Wake on LAN mapping for this MAC address");?>" alt="add"></span>
echo "<td class=\"listr\">{$fspans} n/a {$fspane}</td>\n"; </a>
echo "<td class=\"listr\">{$fspans} n/a {$fspane}</td>\n"; <?php
} if (($data['type'] == "dynamic") && ($data['online'] != "online")):?>
echo "<td class=\"listr\">{$fspans}{$data['online']}{$fspane}</td>\n";
echo "<td class=\"listr\">{$fspans}{$data['act']}{$fspane}</td>\n";
echo "<td valign=\"middle\">&nbsp;";
if ($data['type'] == "dynamic") {
echo "<a class=\"btn btn-default btn-xs\" href=\"services_dhcp_edit.php?if={$data['if']}&amp;mac={$data['mac']}&amp;hostname={$data['hostname']}\">";
echo "<span class=\"glyphicon glyphicon-plus\" title=\"" . gettext("add a static mapping for this MAC address") ."\" alt=\"add\" ></span></a>&nbsp;\n";
} else {
echo "<span class=\"glyphicon glyphicon-plus\" alt=\"add\"></span>&nbsp;\n";
}
echo "<a class=\"btn btn-default btn-xs\" href=\"services_wol_edit.php?if={$data['if']}&amp;mac={$data['mac']}&amp;descr={$data['hostname']}\">";
echo "<span class=\"glyphicon glyphicon-flash\" title=\"" . gettext("add a Wake on LAN mapping for this MAC address") ."\" alt=\"add\"></span></a>&nbsp;\n";
/* Only show the button for offline dynamic leases */ <a class="act_delete btn btn-default btn-xs" href="#" data-deleteip="<?=$data['ip'];?>">
if (($data['type'] == "dynamic") && ($data['online'] != "online")) { <span class="fa fa-trash text-muted" title="<?=gettext("delete this DHCP lease");?>" data-toggle="tooltip" alt="delete" ></span>
echo "<a class=\"btn btn-default btn-xs\" href=\"status_dhcp_leases.php?deleteip={$data['ip']}&amp;all=" . htmlspecialchars($_GET['all']) . "\">"; </a>
echo "<span class=\"glyphicon glyphicon-remove\" title=\"" . gettext("delete this DHCP lease") . "\" alt=\"delete\" ></span></a>&nbsp;\n"; <?php
} endif;?>
echo "</td></tr>\n";
}
}
?> </td>
</tr>
<?php
endforeach;?>
</tbody>
</table> </table>
</div> </div>
</div> </div>
</section> </section>
<section class="col-xs-12"> <section class="col-xs-12">
<form action="status_dhcp_leases.php" method="get"> <form action="status_dhcp_leases.php" method="get">
<input type="hidden" name="order" value="<?=htmlspecialchars($_GET['order']);?>" /> <input type="hidden" name="order" value="<?=htmlspecialchars($_GET['order']);?>" />
<?php if ($_GET['all']): ?> <?php
if (!empty($_GET['all'])): ?>
<input type="hidden" name="all" value="0" /> <input type="hidden" name="all" value="0" />
<input type="submit" class="btn btn-default" value="<?=gettext("Show active and static leases only"); ?>" /> <input type="submit" class="btn btn-default" value="<?=gettext("Show active and static leases only"); ?>" />
<?php else: ?> <?php
else: ?>
<input type="hidden" name="all" value="1" /> <input type="hidden" name="all" value="1" />
<input type="submit" class="btn btn-default" value="<?=gettext("Show all configured leases"); ?>" /> <input type="submit" class="btn btn-default" value="<?=gettext("Show all configured leases"); ?>" />
<?php endif; ?> <?php
endif; ?>
</form> </form>
<?php if($leases == 0): ?> <?php
if($leases == 0): ?>
<p><strong><?=gettext("No leases file found. Is the DHCP server active"); ?>?</strong></p> <p><strong><?=gettext("No leases file found. Is the DHCP server active"); ?>?</strong></p>
<?php endif; ?> <?php
endif; ?>
</section> </section>
</div> </div>
</div> </div>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment