Merge pull request #131 from SirLagz/master

Created interface to configure Static / DHCP settings
This commit is contained in:
Lawrence 2017-11-05 19:29:22 +08:00 committed by GitHub
commit 5cb5cf1d6a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 442 additions and 30 deletions

View File

@ -0,0 +1,42 @@
<?php
session_start();
include_once('../../includes/config.php');
include_once('../../includes/functions.php');
if(isset($_POST['generate']) && isset($_POST['csrf_token']) && CSRFValidate()) {
$cnfNetworking = array_diff(scandir(RASPI_CONFIG_NETWORKING, 1),array('..','.'));
$cnfNetworking = array_combine($cnfNetworking,$cnfNetworking);
$strConfFile = "";
foreach($cnfNetworking as $index=>$file) {
if($index != "defaults") {
$cnfFile = parse_ini_file(RASPI_CONFIG_NETWORKING.'/'.$file);
if($cnfFile['static'] === 'true') {
$strConfFile .= "interface ".$cnfFile['interface']."\n";
$strConfFile .= "static ip_address=".$cnfFile['ip_address']."\n";
$strConfFile .= "static routers=".$cnfFile['routers']."\n";
$strConfFile .= "static domain_name_servers=".$cnfFile['domain_name_server']."\n";
} elseif($cnfFile['static'] === 'false' && $cnfFile['failover'] === 'true') {
$strConfFile .= "profile static_".$cnfFile['interface']."\n";
$strConfFile .= "static ip_address=".$cnfFile['ip_address']."\n";
$strConfFile .= "static routers=".$cnfFile['routers']."\n";
$strConfFile .= "static domain_name_servers=".$cnfFile['domain_name_server']."\n\n";
$strConfFile .= "interface ".$cnfFile['interface']."\n";
$strConfFile .= "fallback static_".$cnfFile['interface']."\n\n";
} else {
$strConfFile .= "#DHCP configured for ".$cnfFile['interface']."\n\n";
}
} else {
$strConfFile .= file_get_contents(RASPI_CONFIG_NETWORKING.'/'.$index)."\n\n";
}
}
if(file_put_contents(RASPI_CONFIG_NETWORKING.'/dhcpcd.conf',$strConfFile)) {
exec('sudo /bin/cp /etc/raspap/networking/dhcpcd.conf /etc/dhcpcd.conf');
$output = ['return'=>0,'output'=>'Settings successfully applied'];
} else {
$output = ['return'=>2,'output'=>'Unable to write to apply settings'];
}
echo json_encode($output);
}
?>

View File

@ -0,0 +1,4 @@
<?php
exec("ls /sys/class/net | grep -v lo", $interfaces);
echo json_encode($interfaces);
?>

View File

@ -0,0 +1,24 @@
<?php
session_start();
include_once('../../includes/config.php');
include_once('../../includes/functions.php');
if(isset($_POST['interface']) && isset($_POST['csrf_token']) && CSRFValidate()) {
$int = $_POST['interface'];
if(!file_exists(RASPI_CONFIG_NETWORKING.'/'.$int.'.ini')) {
touch(RASPI_CONFIG_NETWORKING.'/'.$int.'.ini');
}
$intConfig = parse_ini_file(RASPI_CONFIG_NETWORKING.'/'.$int.'.ini');
$jsonData = ['return'=>1,'output'=>['intConfig'=>$intConfig]];
echo json_encode($jsonData);
// Todo - get dhcp lease information from `dhcpcd -U eth0` ? maybe ?
} else {
$jsonData = ['return'=>2,'output'=>['Error getting data']];
echo json_encode($jsonData);
}
?>

View File

@ -0,0 +1,15 @@
<?php
session_start();
include_once('../../includes/functions.php');
if(isset($_POST['interface']) && isset($_POST['csrf_token']) && CSRFValidate()) {
$int = preg_replace('/[^a-z0-9]/','',$_POST['interface']);
exec('ip a s '.$int,$intOutput,$intResult);
$jsonData = ['return'=>$intResult,'output'=>$intOutput];
echo json_encode($jsonData);
} else {
$jsonData = ['return'=>2,'output'=>['Error getting data']];
echo json_encode($jsonData);
}
?>

View File

@ -0,0 +1,31 @@
<?php
session_start();
include_once('../../includes/config.php');
include_once('../../includes/functions.php');
if(isset($_POST['interface']) && isset($_POST['csrf_token']) && CSRFValidate()) {
$int = $_POST['interface'];
$cfg = [];
$file = $int.".ini";
$ip = $_POST[$int.'-ipaddress'];
$netmask = mask2cidr($_POST[$int.'-netmask']);
$dns1 = $_POST[$int.'-dnssvr'];
$dns2 = $_POST[$int.'-dnssvralt'];
$cfg['interface'] = $int;
$cfg['routers'] = $_POST[$int.'-gateway'];
$cfg['ip_address'] = $ip."/".$netmask;
$cfg['domain_name_server'] = $dns1." ".$dns2;
$cfg['static'] = $_POST[$int.'-static'];
$cfg['failover'] = $_POST[$int.'-failover'];
if(write_php_ini($cfg,RASPI_CONFIG_NETWORKING.'/'.$file)) {
$jsonData = ['return'=>0,'output'=>['Successfully Updated Network Configuration']];
} else {
$jsonData = ['return'=>1,'output'=>['Error saving network configuration to file']];
}
} else {
$jsonData = ['return'=>2,'output'=>'Unable to detect interface'];
}
echo json_encode($jsonData);
?>

23
includes/config.php Normal file
View File

@ -0,0 +1,23 @@
<?php
define('RASPI_CONFIG', '/etc/raspap');
define('RASPI_CONFIG_NETWORKING',RASPI_CONFIG.'/networking');
define('RASPI_ADMIN_DETAILS', RASPI_CONFIG.'/raspap.auth');
// Constants for configuration file paths.
// These are typical for default RPi installs. Modify if needed.
define('RASPI_DNSMASQ_CONFIG', '/etc/dnsmasq.conf');
define('RASPI_DNSMASQ_LEASES', '/var/lib/misc/dnsmasq.leases');
define('RASPI_HOSTAPD_CONFIG', '/etc/hostapd/hostapd.conf');
define('RASPI_WPA_SUPPLICANT_CONFIG', '/etc/wpa_supplicant/wpa_supplicant.conf');
define('RASPI_HOSTAPD_CTRL_INTERFACE', '/var/run/hostapd');
define('RASPI_WPA_CTRL_INTERFACE', '/var/run/wpa_supplicant');
define('RASPI_OPENVPN_CLIENT_CONFIG', '/etc/openvpn/client.conf');
define('RASPI_OPENVPN_SERVER_CONFIG', '/etc/openvpn/server.conf');
define('RASPI_TORPROXY_CONFIG', '/etc/tor/torrc');
// Optional services, set to true to enable.
define('RASPI_OPENVPN_ENABLED', false );
define('RASPI_TORPROXY_ENABLED', false );
?>

View File

@ -55,7 +55,7 @@ function safefilerewrite($fileName, $dataToSave) {
*/
function CSRFToken() {
?>
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>" />
<input id="csrf_token" type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>" />
<?php
}

125
includes/networking.php Normal file
View File

@ -0,0 +1,125 @@
<?php
include_once( 'includes/status_messages.php' );
/**
*
*
*/
function DisplayNetworkingConfig(){
$status = new StatusMessages();
exec("ls /sys/class/net | grep -v lo", $interfaces);
foreach($interfaces as $interface) {
exec("ip a show $interface",$$interface);
}
CSRFToken();
?>
<div class="row">
<div class="col-lg-12">
<div class="panel panel-primary">
<div class="panel panel-heading">
<i class="fa fa-sitemap fa-fw"></i> Configure Networking
</div>
<div class="panel-body">
<div id="msgNetworking"></div>
<ul class="nav nav-tabs">
<li role="presentation" class="active"><a href="#summary" aria-controls="summary" role="tab" data-toggle="tab">Summary</a></li>
<?php
foreach($interfaces as $interface) {
echo '<li role="presentation"><a href="#'.$interface.'" aria-controls="'.$interface.'" role="tab" data-toggle="tab">'.$interface.'</a></li>';
}
?>
</ul>
<div class="tab-content">
<div role="tabpanel" class="tab-pane active" id="summary">
<h4>Current Settings</h4>
<div class="row">
<?php
foreach($interfaces as $interface) {
echo '<div class="col-md-6">
<div class="panel panel-default">
<div class="panel-heading">'.$interface.'</div>
<div class="panel-body" id="'.$interface.'-summary"></div>
</div>
</div>';
}
?>
</div><!-- /.row -->
<div class="col-lg-12">
<div class="row">
<a href="#" class="btn btn-outline btn-primary" id="btnSummaryRefresh"><i class="fa fa-refresh"></i> Refresh</a>
</div><!-- /.row -->
</div><!-- /.col-lg-12 -->
</div><!-- /.tab-pane -->
<?php
foreach($interfaces as $interface) {
echo '
<div role="tabpanel" class="tab-pane fade in" id="'.$interface.'">
<div class="row">
<div class="col-lg-6">
<form id="frm-'.$interface.'">
<div class="form-group">
<h4>Adapter IP Address Settings</h4>
<div class="btn-group" data-toggle="buttons">
<label class="btn btn-primary">
<input type="radio" name="'.$interface.'-addresstype" id="'.$interface.'-dhcp" autocomplete="off">DHCP
</label>
<label class="btn btn-primary">
<input type="radio" name="'.$interface.'-addresstype" id="'.$interface.'-static" autocomplete="off">Static IP
</label>
</div><!-- /.btn-group -->
<h4>Enable Fallback to Static Option</h4>
<div class="btn-group" data-toggle="buttons">
<label class="btn btn-primary">
<input type="radio" name="'.$interface.'-dhcpfailover" id="'.$interface.'-failover" autocomplete="off">Enabled
</label>
<label class="btn btn-warning">
<input type="radio" name="'.$interface.'-dhcpfailover" id="'.$interface.'-nofailover" autocomplete="off">Disabled
</label>
</div><!-- /.btn-group -->
</div><!-- /.form-group -->
<hr />
<h4>Static IP Options</h4>
<div class="form-group">
<label for="'.$interface.'-ipaddress">IP Address</label>
<input type="text" class="form-control" id="'.$interface.'-ipaddress" placeholder="0.0.0.0">
</div>
<div class="form-group">
<label for="'.$interface.'-netmask">Subnet Mask</label>
<input type="text" class="form-control" id="'.$interface.'-netmask" placeholder="255.255.255.0">
</div>
<div class="form-group">
<label for="'.$interface.'-gateway">Default Gateway</label>
<input type="text" class="form-control" id="'.$interface.'-gateway" placeholder="0.0.0.0">
</div>
<div class="form-group">
<label for="'.$interface.'-dnssvr">DNS Server</label>
<input type="text" class="form-control" id="'.$interface.'-dnssvr" placeholder="0.0.0.0">
</div>
<div class="form-group">
<label for="'.$interface.'-dnssvralt">Alternate DNS Server</label>
<input type="text" class="form-control" id="'.$interface.'-dnssvralt" placeholder="0.0.0.0">
</div>
<a href="#" class="btn btn-outline btn-primary intsave" data-int="'.$interface.'">Save Settings</a>
<a href="#" class="btn btn-warning intapply" data-int="'.$interface.'">Apply Settings</a>
</form>
</div>
</div><!-- /.tab-panel -->
</div>';
}
?>
</div><!-- /.tab-content -->
</div><!-- /.panel-body -->
<div class="panel-footer">Information provided by /sys/class/net</div>
</div><!-- /.panel-primary -->
</div><!-- /.col-lg-12 -->
</div>
<?php
}
?>

View File

@ -13,36 +13,12 @@
* @author Lawrence Yau <sirlagz@gmail.com>
* @author Bill Zimmerman <billzimmerman@gmail.com>
* @license GNU General Public License, version 3 (GPL-3.0)
* @version 1.2.2
* @version 1.3.0
* @link https://github.com/billz/raspap-webgui
* @see http://sirlagz.net/2013/02/08/raspap-webgui/
*/
define('RASPI_CONFIG', '/etc/raspap');
define('RASPI_ADMIN_DETAILS', RASPI_CONFIG.'/raspap.auth');
//if(file_exists(RASPI_CONFIG.'/raspap.auth')) {
// define('RASPI_ADMIN_DETAILS', RASPI_CONFIG.'/raspap.auth');
//} else {
// define('RASPI_ADMIN_DETAILS','');
//}
// Constants for configuration file paths.
// These are typical for default RPi installs. Modify if needed.
define('RASPI_DNSMASQ_CONFIG', '/etc/dnsmasq.conf');
define('RASPI_DNSMASQ_LEASES', '/var/lib/misc/dnsmasq.leases');
define('RASPI_HOSTAPD_CONFIG', '/etc/hostapd/hostapd.conf');
define('RASPI_WPA_SUPPLICANT_CONFIG', '/etc/wpa_supplicant/wpa_supplicant.conf');
define('RASPI_HOSTAPD_CTRL_INTERFACE', '/var/run/hostapd');
define('RASPI_WPA_CTRL_INTERFACE', '/var/run/wpa_supplicant');
define('RASPI_OPENVPN_CLIENT_CONFIG', '/etc/openvpn/client.conf');
define('RASPI_OPENVPN_SERVER_CONFIG', '/etc/openvpn/server.conf');
define('RASPI_TORPROXY_CONFIG', '/etc/tor/torrc');
// Optional services, set to true to enable.
define('RASPI_OPENVPN_ENABLED', false );
define('RASPI_TORPROXY_ENABLED', false );
include_once( 'includes/config.php' );
include_once( RASPI_CONFIG.'/raspap.php' );
include_once( 'includes/functions.php' );
include_once( 'includes/dashboard.php' );
@ -52,6 +28,7 @@ include_once( 'includes/dhcp.php' );
include_once( 'includes/hostapd.php' );
include_once( 'includes/system.php' );
include_once( 'includes/configure_client.php' );
include_once( 'includes/networking.php' );
include_once( 'includes/themes.php' );
$output = $return = 0;
@ -127,7 +104,7 @@ $theme_url = 'dist/css/' . $theme;
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="index.php">RaspAP Wifi Portal v1.2.2</a>
<a class="navbar-brand" href="index.php">RaspAP Wifi Portal v1.3.0</a>
</div>
<!-- /.navbar-header -->
@ -139,11 +116,14 @@ $theme_url = 'dist/css/' . $theme;
<a href="index.php?page=wlan0_info"><i class="fa fa-dashboard fa-fw"></i> Dashboard</a>
</li>
<li>
<a href="index.php?page=wpa_conf"><i class="fa fa-signal fa-fw"></i> Configure client</a>
<a href="index.php?page=wpa_conf"><i class="fa fa-signal fa-fw"></i> Configure WiFi Client</a>
</li>
<li>
<a href="index.php?page=hostapd_conf"><i class="fa fa-dot-circle-o fa-fw"></i> Configure hotspot</a>
<a href="index.php?page=hostapd_conf"><i class="fa fa-dot-circle-o fa-fw"></i> Configure Hotspot</a>
</li>
<li>
<a href="index.php?page=network_conf"><i class="fa fa-sitemap fa-fw"></i> Configure Networking</a>
</li>
<li>
<a href="index.php?page=dhcpd_conf"><i class="fa fa-exchange fa-fw"></i> Configure DHCP Server</a>
</li>
@ -194,6 +174,9 @@ $theme_url = 'dist/css/' . $theme;
case "wpa_conf":
DisplayWPAConfig();
break;
case "network_conf":
DisplayNetworkingConfig();
break;
case "hostapd_conf":
DisplayHostAPDConfig();
break;
@ -241,5 +224,8 @@ $theme_url = 'dist/css/' . $theme;
<!-- Custom Theme JavaScript -->
<script src="dist/js/sb-admin-2.js"></script>
<!-- Custom RaspAP JS -->
<script src="js/custom.js"></script>
</body>
</html>

View File

@ -91,10 +91,18 @@ function create_raspap_directories() {
sudo mv $raspap_dir "$raspap_dir.`date +%F-%R`" || install_error "Unable to move old '$raspap_dir' out of the way"
fi
sudo mkdir -p "$raspap_dir" || install_error "Unable to create directory '$raspap_dir'"
# Create a directory for existing file backups.
sudo mkdir -p "$raspap_dir/backups"
# Create a directory to store networking configs
sudo mkdir -p "$raspap_dir/networking"
# Copy existing dhcpcd.conf to use as base config
cat /etc/dhcpcd.conf > "$raspap_dir/networking/defaults"
sudo chown -R $raspap_user:$raspap_user "$raspap_dir" || install_error "Unable to change file ownership for '$raspap_dir'"
}
# Generate logging enable/disable files for hostapd
@ -192,6 +200,7 @@ function default_configuration() {
done
}
# Add a single entry to the sudoers file
function sudo_add() {
sudo bash -c "echo \"www-data ALL=(ALL) NOPASSWD:$1\" | (EDITOR=\"tee -a\" visudo)" \
@ -220,6 +229,7 @@ function patch_system_files() {
'/sbin/ip link set wlan0 down'
'/sbin/ip link set wlan0 up'
'/sbin/ip -s a f label wlan0'
'/bin/cp /etc/raspap/networking/dhcpcd.conf /etc/dhcpcd.conf'
'/etc/raspap/hostapd/enablelog.sh'
'/etc/raspap/hostapd/disablelog.sh'
)

152
js/custom.js Normal file
View File

@ -0,0 +1,152 @@
function msgShow(retcode,msg) {
if(retcode == 0) {
var alertType = 'success';
} else if(retcode == 2 || retcode == 1) {
var alertType = 'danger';
}
var htmlMsg = '<div class="alert alert-'+alertType+' alert-dismissible" role="alert"><button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>'+msg+'</div>';
return htmlMsg;
}
function createNetmaskAddr(bitCount) {
var mask=[];
for(i=0;i<4;i++) {
var n = Math.min(bitCount, 8);
mask.push(256 - Math.pow(2, 8-n));
bitCount -= n;
}
return mask.join('.');
}
function loadSummary(strInterface) {
$.post('/ajax/networking/get_ip_summary.php',{interface:strInterface,csrf_token:csrf},function(data){
jsonData = JSON.parse(data);
console.log(jsonData);
if(jsonData['return'] == 0) {
$('#'+strInterface+'-summary').html(jsonData['output'].join('<br />'));
} else if(jsonData['return'] == 2) {
$('#'+strInterface+'-summary').append('<div class="alert alert-danger alert-dismissible" role="alert"><button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>'+jsonData['output'].join('<br />')+'</div>');
}
});
}
function getAllInterfaces() {
$.get('/ajax/networking/get_all_interfaces.php',function(data){
jsonData = JSON.parse(data);
$.each(jsonData,function(ind,value){
loadSummary(value)
});
});
}
function setupTabs() {
$('a[data-toggle="tab"]').on('shown.bs.tab',function(e){
var target = $(e.target).attr('href');
if(!target.match('summary')) {
var int = target.replace("#","");
loadCurrentSettings(int);
}
});
}
function loadCurrentSettings(strInterface) {
$.post('/ajax/networking/get_int_config.php',{interface:strInterface,csrf_token:csrf},function(data){
jsonData = JSON.parse(data);
$.each(jsonData['output'],function(i,v) {
var int = v['interface'];
$.each(v,function(i2,v2) {
switch(i2) {
case "static":
if(v2 == 'true') {
$('#'+int+'-static').click();
$('#'+int+'-nofailover').click();
} else {
$('#'+int+'-dhcp').click();
}
break;
case "failover":
if(v2 === 'true') {
$('#'+int+'-failover').click();
} else {
$('#'+int+'-nofailover').click();
}
break;
case "ip_address":
var arrIPNetmask = v2.split('/');
$('#'+int+'-ipaddress').val(arrIPNetmask[0]);
$('#'+int+'-netmask').val(createNetmaskAddr(arrIPNetmask[1]));
break;
case "routers":
$('#'+int+'-gateway').val(v2);
break;
case "domain_name_server":
svrsDNS = v2.split(" ");
$('#'+int+'-dnssvr').val(svrsDNS[0]);
$('#'+int+'-dnssvralt').val(svrsDNS[1]);
break;
}
});
});
});
}
function saveNetworkSettings(int) {
var frmInt = $('#frm-'+int).find(':input');
var arrFormData = {};
$.each(frmInt,function(i3,v3){
if($(v3).attr('type') == 'radio') {
arrFormData[$(v3).attr('id')] = $(v3).prop('checked');
} else {
arrFormData[$(v3).attr('id')] = $(v3).val();
}
});
arrFormData['interface'] = int;
arrFormData['csrf_token'] = csrf;
$.post('/ajax/networking/save_int_config.php',arrFormData,function(data){
//console.log(data);
var jsonData = JSON.parse(data);
$('#msgNetworking').html(msgShow(jsonData['return'],jsonData['output']));
});
}
function applyNetworkSettings() {
var int = $(this).data('int');
arrFormData = {};
arrFormData['csrf_token'] = csrf;
arrFormData['generate'] = '';
$.post('/ajax/networking/gen_int_config.php',arrFormData,function(data){
console.log(data);
var jsonData = JSON.parse(data);
$('#msgNetworking').html(msgShow(jsonData['return'],jsonData['output']));
});
}
function setupBtns() {
$('#btnSummaryRefresh').click(function(){getAllInterfaces();});
$('.intsave').click(function(){
var int = $(this).data('int');
saveNetworkSettings(int);
});
$('.intapply').click(function(){
applyNetworkSettings();
});
}
$().ready(function(){
csrf = $('#csrf_token').val();
pageCurrent = window.location.href.split("?")[1].split("=")[1];
pageCurrent = pageCurrent.replace("#","");
$('#side-menu').metisMenu();
switch(pageCurrent) {
case "network_conf":
getAllInterfaces();
setupTabs();
setupBtns();
break;
}
});