Skip to content

Commit

Permalink
Merge pull request #376 from pi-hole/new/DHCPstaticleases
Browse files Browse the repository at this point in the history
Add static DHCPv4 leases settings
  • Loading branch information
DL6ER authored Jan 31, 2017
2 parents 494e9c2 + c81e259 commit 4c952da
Show file tree
Hide file tree
Showing 3 changed files with 158 additions and 8 deletions.
19 changes: 16 additions & 3 deletions scripts/pi-hole/js/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,12 @@ $("#DHCPchk").click(function() {
$("#dhcpnotice").prop("hidden", !this.checked).addClass("lookatme");
});

var leasetable;
var leasetable, staticleasetable;
$(document).ready(function() {
if(document.getElementById("DHCPLeasesTable"))
{
leasetable = $("#DHCPLeasesTable").DataTable({
dom: "<'row'<'col-sm-6'i><'col-sm-6'f>>" +
"<'row'<'col-sm-12'tr>>",
dom: "<'row'<'col-sm-12'tr>><'row'<'col-sm-6'i><'col-sm-6'f>>",
"paging": false,
"scrollCollapse": true,
"scrollY": "200px",
Expand All @@ -85,6 +84,20 @@ $(document).ready(function() {
setTimeout(function(){leasetable.draw();},100);
} );
}
if(document.getElementById("DHCPStaticLeasesTable"))
{
staticleasetable = $("#DHCPStaticLeasesTable").DataTable({
dom: "<'row'<'col-sm-12'tr>><'row'<'col-sm-12'i>>",
"columnDefs": [ { "bSortable": false, "orderable": false, targets: -1} ],
"paging": false,
"scrollCollapse": true,
"scrollY": "200px",
"scrollX" : true
});
$("#leaseexpand").on( "click", function () {
setTimeout(function(){staticleasetable.draw();},100);
} );
}
} );

// Handle hiding of alerts
Expand Down
110 changes: 110 additions & 0 deletions scripts/pi-hole/php/savesettings.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,48 @@ function validDomain($domain_name)
return ( $validChars && $lengthCheck && $labelLengthCheck ); //length of each label
}

function validMAC($mac_addr)
{
// Accepted input format: 00:01:02:1A:5F:FF (characters may be lower case)
return (preg_match('/([a-fA-F0-9]{2}[:]?){6}/', $mac_addr) == 1);
}

$dhcp_static_leases = array();
function readStaticLeasesFile()
{
global $dhcp_static_leases;
$dhcp_static_leases = array();
$dhcpstatic = @fopen('/etc/dnsmasq.d/04-pihole-static-dhcp.conf', 'r');

if(!is_resource($dhcpstatic))
return false;

while(!feof($dhcpstatic))
{
// Remove any possibly existing variable with this name
$mac = ""; $one = ""; $two = "";
sscanf(trim(fgets($dhcpstatic)),"dhcp-host=%[^,],%[^,],%[^,]",$mac,$one,$two);
if(strlen($mac) > 0 && validMAC($mac))
{
if(validIP($one) && strlen($two) == 0)
// dhcp-host=mac,IP - no HOST
array_push($dhcp_static_leases,["hwaddr"=>$mac, "IP"=>$one, "host"=>""]);
elseif(strlen($two) == 0)
// dhcp-host=mac,hostname - no IP
array_push($dhcp_static_leases,["hwaddr"=>$mac, "IP"=>"", "host"=>$one]);
else
// dhcp-host=mac,IP,hostname
array_push($dhcp_static_leases,["hwaddr"=>$mac, "IP"=>$one, "host"=>$two]);
}
else if(validIP($one) && validDomain($mac))
{
// dhcp-host=hostname,IP - no MAC
array_push($dhcp_static_leases,["hwaddr"=>"", "IP"=>$one, "host"=>$mac]);
}
}
return true;
}

$DNSserverslist = [
"8.8.8.8" => "Google (Primary)",
"208.67.222.222" => "OpenDNS (Primary)",
Expand Down Expand Up @@ -316,6 +358,74 @@ function validDomain($domain_name)

case "DHCP":

if(isset($_POST["addstatic"]))
{
$mac = $_POST["AddMAC"];
$ip = $_POST["AddIP"];
$hostname = $_POST["AddHostname"];

if(!validMAC($mac))
{
$error .= "MAC address (".htmlentities($mac).") is invalid!<br>";
}
$mac = strtoupper($mac);

if(!validIP($ip) && strlen($ip) > 0)
{
$error .= "IP address (".htmlentities($ip).") is invalid!<br>";
}

if(!validDomain($hostname) && strlen($hostname) > 0)
{
$error .= "Host name (".htmlentities($hostname).") is invalid!<br>";
}

if(strlen($hostname) == 0 && strlen($ip) == 0)
{
$error .= "You can not omit both the IP address and the host name!<br>";
}

if(strlen($hostname) == 0)
$hostname = "nohost";

if(strlen($ip) == 0)
$ip = "noip";

// Test if this MAC address is already included
readStaticLeasesFile();
foreach($dhcp_static_leases as $lease) {
if($lease["hwaddr"] === $mac)
{
$error .= "Static release for MAC address (".htmlentities($mac).") already defined!<br>";
break;
}
}

if(!strlen($error))
{
exec("sudo pihole -a addstaticdhcp ".$mac." ".$ip." ".$hostname);
$success .= "A new static address has been added";
}
break;
}

if(isset($_POST["removestatic"]))
{
$mac = $_POST["removestatic"];
if(!validMAC($mac))
{
$error .= "MAC address (".htmlentities($mac).") is invalid!<br>";
}
$mac = strtoupper($mac);

if(!strlen($error))
{
exec("sudo pihole -a removestaticdhcp ".$mac);
$success .= "The static address with MAC address ".htmlentities($mac)." has been removed";
}
break;
}

if(isset($_POST["active"]))
{
// Validate from IP
Expand Down
37 changes: 32 additions & 5 deletions settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -257,8 +257,10 @@

// Read leases file
$leasesfile = true;
$dhcpleases = fopen('/etc/pihole/dhcp.leases', 'r') or $leasesfile = false;
$dhcp_leases = [];
$dhcpleases = @fopen('/etc/pihole/dhcp.leases', 'r');
if(!is_resource($dhcpleases ))
$leasesfile = false;
$dhcp_leases = array();

function convertseconds($argument) {
$seconds = round($argument);
Expand Down Expand Up @@ -322,29 +324,54 @@ function convertseconds($argument) {
$clid = "<i>unknown</i>";
}

array_push($dhcp_leases,["TIME"=>$time, "hwaddr"=>$line[1], "IP"=>$line[2], "host"=>$host, "clid"=>$clid, "type"=>$type]);
array_push($dhcp_leases,["TIME"=>$time, "hwaddr"=>strtoupper($line[1]), "IP"=>$line[2], "host"=>$host, "clid"=>$clid, "type"=>$type]);
}
}

readStaticLeasesFile();

?>
<div class="col-md-12">
<div class="box box-warning collapsed-box">
<div class="box box-warning <?php if(!isset($_POST["addstatic"])){ ?>collapsed-box<?php } ?>">
<div class="box-header with-border">
<h3 class="box-title">DHCP leases</h3>
<div class="box-tools pull-right"><button type="button" class="btn btn-box-tool" data-widget="collapse" id="leaseexpand"><i class="fa fa-plus"></i></button></div>
</div>
<div class="box-body">
<div class="col-md-12">
<label>Currently active DHCP leases</label>
<table id="DHCPLeasesTable" class="table table-striped table-bordered dt-responsive nowrap" cellspacing="0" width="100%">
<thead>
<tr>
<th>MAC address</th>
<th>IP address</th>
<th>Hostname</th>
</tr>
</thead>
<tbody>
<?php foreach($dhcp_leases as $lease) { ?><tr data-placement="auto" data-container="body" data-toggle="tooltip" title="Lease type: IPv<?php echo $lease["type"]; ?><br/>Remaining lease time: <?php echo $lease["TIME"]; ?><br/>DHCP UID: <?php echo $lease["clid"]; ?>"><td><?php echo $lease["hwaddr"]; ?></td><td><?php echo $lease["IP"]; ?></td><td><?php echo $lease["host"]; ?></td></tr><?php } ?>
</tbody>
</table><br>
</div>
<div class="col-md-12">
<label>Static DHCP leases configuration</label>
<table id="DHCPStaticLeasesTable" class="table table-striped table-bordered dt-responsive nowrap" cellspacing="0" width="100%">
<thead>
<tr>
<th>MAC address</th>
<th>IP address</th>
<th>Hostname</th>
<td></td>
</tr>
</thead>
<tbody>
<?php foreach($dhcp_leases as $lease) { ?><tr data-placement="auto" data-container="body" data-toggle="tooltip" title="Lease type: IPv<?php echo $lease["type"]; ?><br/>Remaining lease time: <?php echo $lease["TIME"]; ?><br/>DHCP UID: <?php echo $lease["clid"]; ?>"><td><?php echo $lease["IP"]; ?></td><td><?php echo $lease["host"]; ?></td></tr><?php } ?>
<?php foreach($dhcp_static_leases as $lease) { ?><tr><td><?php echo $lease["hwaddr"]; ?></td><td><?php echo $lease["IP"]; ?></td><td><?php echo $lease["host"]; ?></td><td><?php if(strlen($lease["hwaddr"]) > 0){ ?><button class="btn btn-danger btn-xs" type="submit" name="removestatic" value="<?php echo $lease["hwaddr"]; ?>"><span class="glyphicon glyphicon-trash"></span></button><?php } ?></td></tr><?php } ?>
</tbody>
<tfoot style="display: table-row-group">
<tr><td><input type="text" name="AddMAC"></td><td><input type="text" name="AddIP"></td><td><input type="text" name="AddHostname"></td><td><button class="btn btn-success btn-xs" type="submit" name="addstatic"><span class="glyphicon glyphicon-plus"></span></button></td></tr>
</tfoot>
</table>
<p>Specifying the MAC address is mandatory and only one entry per MAC address is allowed. If the IP address is omitted and a host name is given, the IP address will still be generated dynamically and the specified host name will be used. If the host name is omitted, only a static release will be added.</p>
</div>
</div>
</div>
Expand Down

0 comments on commit 4c952da

Please sign in to comment.