Browse Source

Implement Client configuration

- add mobile date network devices and configuration
- add client configuration via udev
- add GUI under networking tab
- add scripts to handle mobile data devices
pull/1087/head
Christian Zeitnitz 1 year ago
parent
commit
8b0383dd20
  1. 100
      ajax/networking/save_net_dev_config.php
  2. 19
      app/js/custom.js
  3. 4
      config/client_config/70-mobile-data-sticks.rules
  4. 3
      config/client_config/80-raspap-net-devices.rules
  5. 106
      config/client_config/info_huawei.sh
  6. 49
      config/client_config/info_huawei_hilink.sh
  7. 52
      config/client_config/info_huawei_modem.sh
  8. 13
      config/client_config/interfaces
  9. 1691
      config/client_config/mcc-mnc-table.csv
  10. 138
      config/client_config/onoff_huawei_hilink.sh
  11. 21
      config/client_config/ppp0_route.sh
  12. 21
      config/client_config/ppp0_setpin.sh
  13. 13
      config/client_config/start_huawei_hilink.service
  14. 16
      config/client_config/start_ppp0_device.service
  15. 49
      config/client_config/switchClientState.sh
  16. 21
      config/client_config/wvdial.conf
  17. 134
      includes/dashboard.php
  18. 10
      includes/functions.php
  19. 170
      includes/get_clients.php
  20. 12
      includes/networking.php
  21. 2
      installers/configauth.sh
  22. 7
      installers/raspap.sudoers
  23. 90
      templates/dashboard.php
  24. 137
      templates/networking.php

100
ajax/networking/save_net_dev_config.php

@ -0,0 +1,100 @@
<?php
/*
Save settings of network devices (type, name, PW, APN ...)
Called by js saveNetDeviceSettings (App/js/custom.js)
*/
require '../../includes/csrf.php';
require_once '../../includes/config.php';
require_once '../../includes/functions.php';
if (isset($_POST['interface'])) {
$int = $_POST['interface'];
$cfg = [];
$file = $int.".ini";
$cfgfile="/etc/wvdial.conf";
if ( $int == "mobiledata") {
$cfg['pin'] = $_POST["pin-mobile"];
$cfg['apn'] = $_POST["apn-mobile"];
$cfg['apn_user'] = $_POST["apn-user-mobile"];
$cfg['apn_pw'] = $_POST["apn-pw-mobile"];
if (file_exists($cfgfile)) {
if($cfg["pin"] !== "") exec('sudo /bin/sed -i "s/CPIN=\".*\"/CPIN=\"'.$cfg["pin"].'\"/gi" '.$cfgfile);
if($cfg["apn"] !== "") exec('sudo /bin/sed -i "s/\"IP\"\,\".*\"/\"IP\"\,\"'.$cfg["apn"].'\"/gi" '.$cfgfile);
if($cfg["apn_user"] !== "") exec('sudo /bin/sed -i "s/^username = .*$/Username = '.$cfg["apn_user"].'/gi" '.$cfgfile);
if($cfg["apn_pw"] !== "") exec('sudo /bin/sed -i "s/^password = .*$/Password = '.$cfg["apn_pw"].'/gi" '.$cfgfile);
}
} else if ( preg_match("/netdevices/",$int)) {
if(!isset($_POST['opts']) ) {
$jsonData = ['return'=>0,'output'=>['No valid data to add/delete udev rule ']];
echo json_encode($jsonData);
return;
} else {
$opts=explode(" ",$_POST['opts'] );
$dev=$opts[0];
$vid=$_POST["int-vid-".$dev];
$pid=$_POST["int-pid-".$dev];
$mac=$_POST["int-mac-".$dev];
$name=trim($_POST["int-name-".$dev]);
$type=$_POST["int-type-".$dev];
$newtype=$_POST["int-new-type-".$dev];
$udevfile=$_SESSION["udevrules"]["udev_rules_file"];
// $udevfile="/etc/udev/rules.d/80-net-devices.rules";
// find the rule prototype and prefix
$rule = "";
foreach($_SESSION["udevrules"]["network_devices"] as $devt) {
if($devt["type"]==$newtype) {
$rule = $devt["udev_rule"];
$prefix = $devt["name_prefix"];
}
}
if(!empty($mac)) $rule = preg_replace("/\\\$MAC\\\$/i",$mac,$rule);
if(!empty($vid)) $rule = preg_replace("/\\\$IDVENDOR\\\$/i",$vid,$rule);
if(!empty($pid)) $rule = preg_replace("/\\\$IDPRODUCT\\\$/i",$pid,$rule);
// check for existing rule
$pre="";
if(preg_match("/^(\w+)[0-9]$/",$dev,$match)=== 1) $pre=$match[1];
$ruleold = preg_replace("/\\\$DEVNAME\\\$/i",$pre.".",$rule);
exec("grep -oP '".$ruleold."' $udevfile",$ret);
$newRule = empty($ret) || !empty($name);
// delete current entry
if(!empty($ret)) exec("sudo sed -i '/^".$ruleold."$/d' ".$udevfile);
exec('sudo sed -i "/^.*'.$mac.'.*$/d" '.$udevfile);
if($newRule) {
// create new entry
if(empty($name)) $name = $prefix."0";
if(!empty($name)) $rule = preg_replace("/\\\$DEVNAME\\\$/i",$name,$rule);
if (!empty($rule) ) exec('echo \''.$rule.'\' | sudo /usr/bin/tee -a '.$udevfile);
}
$ret=print_r($ret,true);
$jsonData = ['return'=>0,'output'=>['Udev rules changed for device '.$dev ] ];
echo json_encode($jsonData);
return;
}
} else {
$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);

19
app/js/custom.js

@ -130,6 +130,7 @@ function setupBtns() {
$('#btnSummaryRefresh').click(function(){getAllInterfaces();});
$('.intsave').click(function(){
var int = $(this).data('int');
saveNetDeviceSettings(int);
saveNetworkSettings(int);
});
$('.intapply').click(function(){
@ -173,6 +174,24 @@ function loadWifiStations(refresh) {
}
$(".js-reload-wifi-stations").on("click", loadWifiStations(true));
function saveNetDeviceSettings(int,opts="") {
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['opts'] = opts;
$.post('ajax/networking/save_net_dev_config.php',arrFormData,function(data){
var jsonData = JSON.parse(data);
$('#msgNetworking').html(msgShow(jsonData['return'],jsonData['output']));
});
}
/*
Populates the DHCP server form fields
Option toggles are set dynamically depending on the loaded configuration

4
config/client_config/70-mobile-data-sticks.rules

@ -0,0 +1,4 @@
# mobile data modem - ttyUSB0 device appears
SUBSYSTEM=="tty", KERNEL=="ttyUSB0", TAG+="systemd", ENV{SYSTEMD_WANTS}="start start_ppp0_device.service"

3
config/client_config/80-raspap-net-devices.rules

@ -0,0 +1,3 @@
SUBSYSTEM=="net", ACTION=="add", SUBSYSTEMS=="usb", ATTRS{idVendor}=="12d1", ATTRS{idProduct}=="14db", NAME="hilink0", TAG+="systemd", ENV{SYSTEMD_WANTS}="start start_huawei_hilink.service"

106
config/client_config/info_huawei.sh

@ -0,0 +1,106 @@
#!/bin/bash
# get info about device and signal of Huawei mobile USB devices
# parm:
# $1 : requested information (manufacturer, device, imei, imsi, telnumber, ipaddress, mode, signal, operator)
# $2 : (optional) type - hilink or modem (default: hilink)
# $3 : (optional) for hilink: ip address of the device (default: 192.168.8.1)
# for modem: tty interface for communication (default: /dev/ttypUSB2)
#
# requires: bc
# calls the scripts info_huawei_hilink.sh and info_huawei_modem.sh (same path as this script)
#
# zbchristian 2020
#
opt="device"
if [ ! -z $1 ]; then opt=${1,,}; fi
type="hilink"
if [ ! -z $2 ]; then type=${2,,}; fi
path=`dirname $0`
if [[ $type == "hilink" ]]; then
connect="192.168.8.1"
if [ ! -z $3 ]; then connect=$3; fi
script="$path/info_huawei_hilink.sh"
else
connect="/dev/ttyUSB2"
if [ ! -z $3 ]; then connect=$3; fi
script="$path/info_huawei_modem.sh"
fi
res=`$script $opt $connect`
# some results require special treatment
case $opt in
# manufacturer)
# if [[ $res == "none" ]]; then res="Huawei"; fi
# ;;
# device)
# if [[ ! $res == "none" ]]; then res="Huawei $res";
# else res="Huawei"; fi
# ;;
mode)
if [[ ! $res == "none" ]]; then
if [[ $type == "hilink" ]]; then
if [[ $res == "LTE" ]]; then res="4G"
elif [[ $res == "WCDMA" ]]; then res="3G";
else res="2G"; fi
else
if [[ $res == 7 ]]; then res="4G"
elif [[ $res < 7 ]] && [[ $res > 2 ]] ; then res="3G";
else res="2G"; fi
fi
fi
;;
signal)
# return signal strength/quality in %
if [[ $type == "hilink" ]]; then
# signal request tries to get RSRQ value
# try to get RSRQ (4G), EC/IO (3G) or RSSI (2G) value
if [[ $res == "none" ]]; then res=`$script "ecio"`; fi
if [[ ! $res == "none" ]]; then
# for rsrq and ecio assume: -3dB (100%) downto -20dB (0%)
qual=${res//dB/}
if [[ ! "$qual" =~ [-0-9\.]* ]]; then qual=-100; fi
qual=$(bc <<< "scale=0;res=$qual-0.5;res/1") # just round to next integer
if [[ $qual -le -20 ]]; then qual=0;
elif [[ $qual -ge -3 ]]; then qual=100;
else qual=$(bc <<< "scale=0;res=100.0/17.0*$qual+2000.0/17.0;res/1"); fi
else
# try rssi: >-70dBm (100%) downto -100dBm (0%)
res=`$script "rssi"`;
if [[ ! $res == "none" ]]; then
if [[ $res =~ [-0-9\.]* ]]; then res="-120 dBm"; fi
qual=${res//dBm/}
qual=$(bc <<< "scale=0;res=$qual+0.5;res/1") # just round to next integer
if [[ $qual -le -110 ]]; then qual=0;
elif [[ $qual -ge -70 ]]; then qual=100;
else qual=$(bc <<< "scale=0;res=2.5*$qual+275;res/1"); fi
fi
fi
else
# modem returns RSSI as number 0-31 - 0 = -113dB (0%), 1 = -111dB, 31 = >=51dB (100%)
qual=$(bc <<< "scale=0;res=$res*3.5+0.5;res/1")
if [[ $qual -gt 100 ]]; then res=100; fi
fi
if [[ ! "$res" == "none" ]]; then res="$res (${qual}%)"; fi
;;
operator)
# check if operator/network is just a 5 digit number -> extract network name from table
if [[ $res =~ ^[0-9]{5}$ ]]; then
mcc=${res:0:3}
mnc=${res:3:2}
op=$(cat $path/mcc-mnc-table.csv | sed -rn 's/^'$mcc'\,[0-9]*\,'$mnc'\,(.*\,){4}(.*)$/\2/p')
if [[ ! -z $op ]]; then res="$op ($res)"; fi
fi
;;
*)
;;
esac
echo $res

49
config/client_config/info_huawei_hilink.sh

@ -0,0 +1,49 @@
#!/bin/bash
# Infosramtion about HUAWEI hilink (router) modem
# -----------------------------------------------
# get info about the device and signal
# parameter: $1 - see opts list below
# $2 - host ip address for API calls (optional)
# returns the value of the parameter, or "none" if not found or empty
#
# zbchristian 2020
opts=("device" "imei" "imsi" "telnumber" "ipaddress" "mode" "signal" "rssi" "rsrq" "rsrp" "sinr" "ecio" "operator")
# xml tags to extract information from
tags=("devicename" "imei" "imsi" "msisdn" "wanipaddress" "workmode" "rsrq" "rssi" "rsrq" "rsrp" "sinr" "ecio" "fullname")
iurl=( 0 0 0 0 0 0 1 1 1 1 1 1 2)
# api urls
urls=("api/device/information" "api/device/signal" "api/net/current-plmn")
host="192.168.8.1"
if [ ! -z $2 ]; then host=$2; fi
avail=`timeout 0.5 ping -c 1 $host | sed -rn 's/.*time=.*/1/p'`
if [[ -z $avail ]]; then echo "none"; exit; fi
idx=-1
opt=${opts[0]}
if [ ! -z $1 ]; then opt=$1; fi
for i in "${!opts[@]}"; do
if [[ ${opts[$i]} == $opt ]]; then idx=$i; fi
done
if [[ $idx == -1 ]];then echo "none"; exit; fi
par=${tags[$idx]}
iu=${iurl[$idx]}
url="http://$host/${urls[$iu]}"
# echo "Found option $opt at index $idx - tag $par url $url "
info=""
if [ ! -z $url ]; then info=`curl -s $url`; fi
result=`echo $info | sed -rn 's/.*<'"$par"'>(.*)<\/'"$par"'>.*/\1/pi'`
if [ -z "$result" ]; then result="none"; fi
echo $result

52
config/client_config/info_huawei_modem.sh

@ -0,0 +1,52 @@
#!/bin/bash
# Information about HUAWEI modem - via AT commands
# ------------------------------------------------
# get info about the device and signal
# parameter: $1 - see opts list below
# $2 - tty device name for the communicaton (optional)
# returns the value of the parameter, or "none" if not found or empty
#
# requires: socat
#
# zbchristian 2020
opts=("manufacturer" "device" "imei" "imsi" "telnumber" "mode" "signal" "operator")
# at command to extract information
atcmds=("AT+CGMI" "AT+CGMM" "AT+CGSN" "AT+CIMI" "AT+CNUM" "AT+COPS?" "AT+CSQ" "AT+COPS?")
# regexp pattern to extract wanted information from result string
pats=( " " " " " " " " ".*\,\"([0-9\+]*)\".*" '.*\,([0-9])$' ".*: ([0-9]*).*" '.*\,\"([^ ]*)\".*$')
# tty device for communication - usually 3 tty devices are created and the 3rd ttyUSB2 is available, even, when the device is connected
dev="/dev/ttyUSB2"
atsilent="AT^CURC=0"
if [ ! -z $2 ]; then dev=$2; fi
idx=-1
opt=${opts[0]}
if [ ! -z $1 ]; then opt=$1; fi
for i in "${!opts[@]}"; do
if [[ ${opts[$i]} == $opt ]]; then idx=$i; fi
done
if [[ $idx == -1 ]];then echo "none"; exit; fi
atcmd=${atcmds[$idx]}
pat=${pats[$idx]}
result=`(echo $atsilent; echo $atcmd) | sudo /usr/bin/socat - $dev`
# escape the AT command to be used in the regexp
atesc=${atcmd//[\+]/\\+}
atesc=${atesc//[\?]/\\?}
result=`echo $result | sed -rn 's/.*'"$atesc"'\s([^ ]+|[^ ]+ [^ ]+)\sOK.*$/\1/pg'`
if [[ $pat != " " ]]; then
result=`echo $result | sed -rn 's/'"$pat"'/\1/pg'`
fi
if [ -z "$result" ]; then result="none"; fi
echo $result

13
config/client_config/interfaces

@ -0,0 +1,13 @@
# interfaces(5) file used by ifup(8) and ifdown(8)
# Please note that this file is written to be used with dhcpcd
# For static IP, consult /etc/dhcpcd.conf and 'man dhcpcd.conf'
# Include files from /etc/network/interfaces.d:
source-directory /etc/network/interfaces.d
auto ppp0
iface ppp0 inet wvdial
provider connect
pre-up /usr/local/sbin/ppp0_setpin.sh
up /usr/local/sbin/ppp0_route.sh

1691
config/client_config/mcc-mnc-table.csv
File diff suppressed because it is too large
View File

138
config/client_config/onoff_huawei_hilink.sh

@ -0,0 +1,138 @@
#!/bin/bash
# connect/disconnect Huawei mobile data stick in Hilink mode (e.g. E3372h)
# ========================================================================
# - send xml formatted string via HTTP API to stick
# - Requires session and verification token, which is obtained by an API call
#
# options: -l "user":"password" - login data - DOES NOT WORK YET
# -h 192.168.8.1 - host ip address
# -p 1234 - PIN of SIM card
# -c 0/1 - connect - set datamode off/on
# required software: curl, base64
#
# TODO: implement login into API - currently the login has to be disabled!
#
# zbchristian 2020
# obtain session and verification token
function _SessToken() {
SesTok=`sudo curl -s http://$host/api/webserver/SesTokInfo -m 5 2> /dev/null`
if [ -z "$SesTok" ]; then exit; fi
token=`echo $SesTok | sed -r 's/.*<TokInfo>(.*)<\/TokInfo>.*/\1/'`
sesinfo=`echo $SesTok | sed -r 's/.*<SesInfo>(.*)<\/SesInfo>.*/\1/'`
}
function _login() {
# ----------------------- THIS DOES NOT WORK ------------------------------------------
# login to web api
_SessToken
if [[ ! -z $user ]] && [[ ! -z $pw ]]; then
# password encoding
# type 3 : base64(pw) encoded
# type 4 : base64(sha256sum(user + base64(sha256sum(pw)) + token))
pwtype3=$(echo $pw | base64 --wrap=0)
hashedpw=$(echo -n "$pw" | sha256sum -b | cut -d " " -f1 | base64 --wrap=0)
pwtype4=$(echo -n "$user$hashedpw$token" | sha256sum -b | cut -d " " -f1 | base64 --wrap=0)
apiurl="api/user/login"
xmldata="<?xml version='1.0' encoding='UTF-8'?><request><Username>$user</Username><Password>$pwtype4</Password><password_type>4</password_type></request>"
# xmldata="<?xml version='1.0' encoding='UTF-8'?><request><Username>$user</Username><Password>$pwtype3</Password><password_type>3</password_type></request>"
xtraopts="--dump-header /tmp/hilink_login_hdr.txt"
_sendRequest
# get updated session cookie
sesinfo=$(grep "SessionID=" /tmp/hilink_login_hdr.txt | cut -d ':' -f2 | cut -d ';' -f1)
token=$(grep "__RequestVerificationTokenone" /tmp/hilink_login_hdr.txt | cut -d ':' -f2)
echo "Login Cookie $sesinfo"
echo "Login Token $token"
fi
# ------------------------------ DO NOT USE THE LOGIN CODE ----------------------------------
}
function _switchMobileData() {
# switch mobile data on/off
if [[ $datamode -ge 0 ]]; then
xmldata="<?xml version: '1.0' encoding='UTF-8'?><request><dataswitch>$datamode</dataswitch></request>"
apiurl="api/dialup/mobile-dataswitch"
_sendRequest
fi
}
function _enableSIM() {
#SimState:
#255 - no SIM,
#256 - error CPIN,
#257 - ready,
#258 - PIN disabled,
#259 - check PIN,
#260 - PIN required,
#261 - PUK required
status=`curl -s http://$host/api/pin/status -m 10`
state=`echo $status | sed -rn 's/.*<simstate>(.*)<\/simstate>.*/\1/pi'`
if [[ $state -eq 257 ]]; then echo "Hilink: SIM ready"|systemd-cat; return; fi
if [[ $state -eq 260 ]]; then echo "Hilink: Set PIN"|systemd-cat; _setPIN; fi
}
function _setPIN() {
if [[ ! -z $pin ]]; then
xmldata="<?xml version: '1.0' encoding='UTF-8'?><request><OperateType>0</OperateType><CurrentPin>$pin</CurrentPin><NewPin></NewPin><PukCode></PukCode></request>"
apiurl="api/pin/operate"
_sendRequest
fi
}
function _sendRequest() {
result=""
if [[ -z $xmldata ]]; then return; fi
result=`curl -s http://$host/$apiurl -m 10 \
-H "Content-Type: application/xml" \
-H "Cookie: $sesinfo" \
-H "__RequestVerificationToken: $token" \
-d "$xmldata" $xtraopts 2> /dev/null`
xtraopts=""
}
# handle options
host="192.168.8.1"
pin=""
user=""
pw=""
datamode=-1
connect=-1
while getopts ":c:h:l:m:p:" opt; do
case $opt in
h) if [[ $OPTARG =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then host="$OPTARG"; fi
;;
p) if [[ $OPTARG =~ ^[0-9]{4,8} ]]; then pin="$OPTARG"; fi
;;
l) if [[ $OPTARG =~ ^[0-9a-zA-Z]*:.*$ ]]; then
user=$(echo "$OPTARG" | cut -d':' -f1);
pw=$(echo "$OPTARG" | cut -d':' -f2);
fi
;;
c) if [[ $OPTARG == "1" ]]; then datamode=1; else datamode=0; fi
;;
esac
done
echo "Hilink: switch device at $host to mode $datamode" | systemd-cat
# check if device is reachable
avail=`timeout 0.5 ping -c 1 $host | sed -rn 's/.*time=.*/1/p'`
if [[ -z $avail ]]; then
echo "Hilink: no link to host" | systemd-cat
exit
fi
token=""
Sesinfo=""
xmldata=""
xtraopts=""
result=""
_SessToken
_enableSIM
_switchMobileData # check and perform enable/disable mobile data connection

21
config/client_config/ppp0_route.sh

@ -0,0 +1,21 @@
#!/bin/bash
#
# get gateway and ip address of UTMS modem connected to ppp0
# add a default route
# called by /etc/network/interfaces.d/ppp0, when device is coming up
#
ppp0rt=""
let i=1
while [ -z "$ppp0rt" ] ; do
let i+=1
if [ $i -gt 20 ]; then
exit 1
fi
sleep 1
ppp0rt=`ip route list | grep -m 1 ppp0`
done
gate=`echo $ppp0rt | sed -rn 's/(([0-9]{1,3}\.){3}[0-9]{1,3}).*ppp0.*src (([0-9]{1,3}\.){3}[0-9]{1,3})/\1/p'`
src=`echo $ppp0rt | sed -rn 's/(([0-9]{1,3}\.){3}[0-9]{1,3}).*ppp0.*src (([0-9]{1,3}\.){3}[0-9]{1,3})/\3/p'`
ip route add default via $gate proto dhcp src $src metric 10
exit 0

21
config/client_config/ppp0_setpin.sh

@ -0,0 +1,21 @@
#!/bin/bash
# in case /dev/ttyUSB0 does not exist, wait for it at most 30 seconds
let i=1
while ! test -c /dev/ttyUSB0; do
let i+=1
if [ $i -gt 2 ]; then
logger -s -t setpin "/dev/ttyUSB0 does not exist"
exit 3
fi
logger -s -t setpin "waiting 3 seconds for /dev/ttyUSB0"
sleep 3
done
# check for pin and set it if necessary
wvdial pinstatus 2>&1 | grep -q '^+CPIN: READY'
if [ $? -eq 0 ]; then
logger -s -t setpin "SIM card is ready to use :-)"
else
logger -s -t setpin "setting PIN"
wvdial pin 2>/dev/null
fi
exit 0

13
config/client_config/start_huawei_hilink.service

@ -0,0 +1,13 @@
[Unit]
Description=Bring up HUAWEI mobile hilink device
[Service]
Type=oneshot
RemainAfterExit=no
ExecStart=/bin/sleep 15
ExecStart=/usr/local/sbin/switchClientState.sh up
[Install]
Alias=start_ltemodem.service
WantedBy=multi-user.target

16
config/client_config/start_ppp0_device.service

@ -0,0 +1,16 @@
[Unit]
Description=Start ppp0 interface
BindsTo=dev-ttyUSB0.device
After=dev-ttyUSB0.device
[Service]
Type=forking
RemainAfterExit=yes
ExecStart=/sbin/ifup ppp0
ExecStop=/sbin/ifdown ppp0
[Install]
Alias=startppp0.service
WantedBy=multi-user.target

49
config/client_config/switchClientState.sh

@ -0,0 +1,49 @@
#!/bin/bash
#
# parameters: up or down
# current client from getClients.sh
#
# requires: getClients.sh, onoff_huawei_hilink.sh in same path
# ifconfig, ifup, ifdown, systemd-cat
#
#
# zbchristian 2020
path=`dirname $0`
clients=$($path/getClients.sh simple)
if [[ -z $clients ]] || [[ $(echo $clients| grep -oP '(?<="clients": )\d') == 0 ]]; then echo "$0 : No client found"|systemd-cat; exit; fi
devs=( $(echo $clients | grep -oP '(?<="name": ")\w*(?=")') )
types=( $(echo $clients | grep -oP '(?<="type": )\d') )
# find the device with the max type number
imax=0
type=0
for i in "${!devs[@]}"; do
if [[ ${types[$i]} > $type ]]; then imax=$i; type=${types[$i]}; fi
done
device=${devs[$imax]}
echo "$0: try to set $device $1" | systemd-cat
connected=`ifconfig -a | grep -i $device -A 1 | grep -oP "(?<=inet )([0-9]{1,3}\.){3}[0-9]{1,3}"`
if [ -z "$connected" ] && [[ $1 == "up" ]]; then
if [[ $type == 3 ]]; then ip link set $device up; fi
if [[ $type == 5 ]]; then ifup $device; fi
fi
if [[ ! -z "$connected" ]] && [[ $1 == "down" ]]; then
if [[ $type == 3 ]]; then ip link set $device down; fi
if [[ $type == 5 ]]; then ifdown $device; fi
fi
if [[ $type == 4 ]]; then
ipadd=$(echo $connected | grep -oP "([0-9]{1,3}\.){2}[0-9]{1,3}")".1" # get ip address of the Hilink API
mode=0
if [[ $1 == "up" ]]; then mode=1; fi
if [[ -f /etc/raspap/networking/mobiledata.ini ]]; then
pin=$(cat /etc/raspap/networking/mobiledata.ini | sed -rn 's/pin = ([0-9]*)$/\1/p' )
fi
$path/onoff_huawei_hilink.sh -c $mode -h $ipadd -p $pin
fi

21
config/client_config/wvdial.conf

@ -0,0 +1,21 @@
[Dialer Defaults]
Modem Type = Analog Modem
ISDN = 0
Baud = 9600
Modem = /dev/ttyUSB0
[Dialer pin]
Init1 = AT+CPIN="XXXX"
[Dialer connect]
Init1 = ATZ
Init2 = ATQ0 V1 E1 S0=0 &C1 &D2 +FCLASS=0
Init3 = AT+CGDCONT=1,"IP","web.vodafone.de"
New PPPD = yes
Phone = *99#
Password = me
Username = vodafone
Stupid Mode = 1
[Dialer pinstatus]
Init1 = AT+CPIN?

134
includes/dashboard.php

@ -3,6 +3,7 @@
require_once 'includes/config.php';
require_once 'includes/wifi_functions.php';
require_once 'includes/functions.php';
require_once 'includes/get_clients.php';
/**
* Show dashboard page.
@ -23,6 +24,9 @@ function DisplayDashboard(&$extraFooterScripts)
$status->showMessages();
return;
}
// ----------------------------- INFOS ABOUT THE ACCESS POINT -------------------------------------------------------------
exec('ip a show '.$_SESSION['ap_interface'], $stdoutIp);
$stdoutIpAllLinesGlued = implode(" ", $stdoutIp);
$stdoutIpWRepeatedSpaces = preg_replace('/\s\s+/', ' ', $stdoutIpAllLinesGlued);
@ -88,73 +92,42 @@ function DisplayDashboard(&$extraFooterScripts)
$strTxBytes .= getHumanReadableDatasize($strTxBytes);
}
define('SSIDMAXLEN', 32);
// Warning iw comes with: "Do NOT screenscrape this tool, we don't consider its output stable."
exec('iw dev ' .$_SESSION['wifi_client_interface']. ' link ', $stdoutIw);
$stdoutIwAllLinesGlued = implode('+', $stdoutIw); // Break lines with character illegal in SSID and MAC addr
$stdoutIwWRepSpaces = preg_replace('/\s\s+/', ' ', $stdoutIwAllLinesGlued);
preg_match('/Connected to (([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2}))/', $stdoutIwWRepSpaces, $matchesBSSID) || $matchesBSSID[1] = '';
$connectedBSSID = $matchesBSSID[1];
$connectedBSSID = empty($connectedBSSID) ? "-" : $connectedBSSID;
$wlanHasLink = false;
if ($interfaceState === 'UP') {
$wlanHasLink = true;
}
if (!preg_match('/SSID: ([^+]{1,'.SSIDMAXLEN.'})/', $stdoutIwWRepSpaces, $matchesSSID)) {
$wlanHasLink = false;
$matchesSSID[1] = 'None';
}
$connectedSSID = $matchesSSID[1];
preg_match('/freq: (\d+)/i', $stdoutIwWRepSpaces, $matchesFrequency) || $matchesFrequency[1] = '';
$frequency = $matchesFrequency[1].' MHz';
preg_match('/signal: (-?[0-9]+ dBm)/i', $stdoutIwWRepSpaces, $matchesSignal) || $matchesSignal[1] = '';
$signalLevel = $matchesSignal[1];
$signalLevel = empty($signalLevel) ? "-" : $signalLevel;
preg_match('/tx bitrate: ([0-9\.]+ [KMGT]?Bit\/s)/', $stdoutIwWRepSpaces, $matchesBitrate) || $matchesBitrate[1] = '';
$bitrate = $matchesBitrate[1];
$bitrate = empty($bitrate) ? "-" : $bitrate;
// txpower is now displayed on iw dev(..) info command, not on link command.
exec('iw dev '.$_SESSION['wifi_client_interface'].' info ', $stdoutIwInfo);
$stdoutIwInfoAllLinesGlued = implode(' ', $stdoutIwInfo);
$stdoutIpInfoWRepSpaces = preg_replace('/\s\s+/', ' ', $stdoutIwInfoAllLinesGlued);
preg_match('/txpower ([0-9\.]+ dBm)/i', $stdoutIpInfoWRepSpaces, $matchesTxPower) || $matchesTxPower[1] = '';
$txPower = $matchesTxPower[1];
// iw does not have the "Link Quality". This is a is an aggregate value,
// and depends on the driver and hardware.
// Display link quality as signal quality for now.
$strLinkQuality = 0;
if ($signalLevel > -100 && $wlanHasLink) {
if ($signalLevel >= 0) {
$strLinkQuality = 100;
} else {
$strLinkQuality = 100 + intval($signalLevel);
// ------------------------ INFOS ABOUT THE CLIENT---------------------------------------------------------------
$clientinfo=array("name"=>"none","type"=>-1,"connected"=>"n");
$raspi_client=$_SESSION['wifi_client_interface'];
load_client_config();
$clients = getClients(false);
if(!empty($clients)) {
$ncl=$clients["clients"];
if($ncl > 0) {
$ty=-1;
foreach($clients["device"] as $dev) {
if(($id=array_search($dev["type"],$_SESSION["net-device-types"])) > $ty && !$dev["isAP"]) {
$ty=$id;
$clientinfo=$dev;
}
}
}
}
$wlan0up = false;
if ($clientinfo["name"] != "none") $raspi_client = $clientinfo["name"];
$interfaceState = $clientinfo["connected"] == "y" ? 'UP' : 'DOWN';
$txPower="";
if ($clientinfo["type"] == "wlan") {
// txpower is now displayed on iw dev(..) info command, not on link command.
exec('iw dev '.$clientinfo["name"].' info | sed -rn "s/.*txpower ([0-9]*)[0-9\.]*( dBm).*/\1\2/p"', $stdoutIwInfo);
if (!empty($stdoutIwInfo)) $txPower=$stdoutIwInfo[0];
}
$classMsgDevicestatus = 'warning';
if ($interfaceState === 'UP') {
$wlan0up = true;
$classMsgDevicestatus = 'success';
}
if (!RASPI_MONITOR_ENABLED) {
if (isset($_POST['ifdown_wlan0'])) {
// Pressed stop button
if ($interfaceState === 'UP') {
$status->addMessage(sprintf(_('Interface is going %s.'), _('down')), 'warning');
exec('sudo ip link set '.$_SESSION['wifi_client_interface'].' down');
$wlan0up = false;
exec('sudo /usr/local/sbin/switchClientState.sh down');
$status->addMessage(sprintf(_('Interface is now %s.'), _('down')), 'success');
} elseif ($interfaceState === 'unknown') {
$status->addMessage(_('Interface state unknown.'), 'danger');
@ -165,9 +138,8 @@ function DisplayDashboard(&$extraFooterScripts)
// Pressed start button
if ($interfaceState === 'DOWN') {
$status->addMessage(sprintf(_('Interface is going %s.'), _('up')), 'warning');
exec('sudo ip link set ' .$_SESSION['wifi_client_interface']. ' up');
exec('sudo ip -s a f label ' . $_SESSION['wifi_client_interface']);
$wlan0up = true;
exec('sudo /usr/local/sbin/switchClientState.sh up');
exec('sudo ip -s a f label ' . $raspi_client);
$status->addMessage(sprintf(_('Interface is now %s.'), _('up')), 'success');
} elseif ($interfaceState === 'unknown') {
$status->addMessage(_('Interface state unknown.'), 'danger');
@ -178,13 +150,19 @@ function DisplayDashboard(&$extraFooterScripts)
$status->addMessage(sprintf(_('Interface is %s.'), strtolower($interfaceState)), $classMsgDevicestatus);
}
}
// brought in from template
$arrHostapdConf = parse_ini_file(RASPI_CONFIG.'/hostapd.ini');
$bridgedEnable = $arrHostapdConf['BridgedEnable'];
$clientInterface = $_SESSION['wifi_client_interface'];
if ($arrHostapdConf['WifiAPEnable'] == 1) {
$client_interface = 'uap0';
} else {
$client_interface = $clientinfo["name"];
}
$apInterface = $_SESSION['ap_interface'];
$MACPattern = '"([[:xdigit:]]{2}:){5}[[:xdigit:]]{2}"';
if (getBridgedState()) {
$moreLink = "hostapd_conf";
exec('iw dev ' . $apInterface . ' station dump | grep -oE ' . $MACPattern, $clients);
@ -192,11 +170,35 @@ function DisplayDashboard(&$extraFooterScripts)
$moreLink = "dhcpd_conf";
exec('cat ' . RASPI_DNSMASQ_LEASES . '| grep -E $(iw dev ' . $apInterface . ' station dump | grep -oE ' . $MACPattern . ' | paste -sd "|")', $clients);
}
$ifaceStatus = $wlan0up ? "up" : "down";
$ifaceStatus = $clientinfo["connected"]=="y" ? "up" : "down";
switch($clientinfo["type"]) {
case "eth":
$client_title = "Client: Ethernet cable";
$type_name = "Ethernet";
break;
case "phone":
$client_title = "Client: Smartphone (USB tethering)";
$type_name = "Smartphone";
break;
case "wlan":
$client_title = "Wireless Client";
$type_name = "Wifi";
break;
case "ppp":
case "hilink":
$client_title = "Mobile Data Client";
$type_name = "Mobile Data";
break;
default:
$client_title = "No information for client available";
$type_name = "No Client";
}
echo renderTemplate(
"dashboard", compact(
"clients",
"client_title",
"type_name",
"moreLink",
"apInterface",
"clientInterface",
@ -211,14 +213,8 @@ function DisplayDashboard(&$extraFooterScripts)
"strRxBytes",
"strTxPackets",
"strTxBytes",
"connectedSSID",
"connectedBSSID",
"bitrate",
"signalLevel",
"txPower",
"frequency",
"strLinkQuality",
"wlan0up"
"clientinfo"
)
);
$extraFooterScripts[] = array('src'=>'app/js/dashboardchart.js', 'defer'=>false);

10
includes/functions.php

@ -728,5 +728,15 @@ function getNightmode(){
} else {
return false;
}
// search array for matching string and return only first matching group
function preg_only_match($pat,$haystack) {
$match = "";
if(!empty($haystack) && !empty($pat)) {
if(!is_array($haystack)) $haystack = array($haystack);
$str = preg_grep($pat,$haystack);
if (!empty($str) && preg_match($pat,array_shift($str),$match) === 1 ) $match = $match[1];
}
return $match;
}
}

170
includes/get_clients.php

@ -0,0 +1,170 @@
<?php
require_once 'includes/functions.php';
function getClients($simple=true) {
exec ('ifconfig -a | grep -oP "^(?!lo)(\w*)"',$rawdevs); // all devices except loopback
$path=RASPI_CLIENT_SCRIPT_PATH;
$cl=array();
if(!empty($rawdevs) && is_array($rawdevs)) {
$cl["clients"]=count($rawdevs);
// search for possibly not connected modem
exec("find /sys/bus/usb/devices/usb*/ -name dev ",$devtty); // search for ttyUSB
$devtty = preg_only_match("/(ttyUSB0)/",$devtty);
if( empty(preg_only_match("/(ppp)[0-9]/",$rawdevs))) {
if(!empty($devtty)) {
$rawdevs[]="ppp0";
exec("udevadm info --name='$devtty' 2> /dev/null");
}
}
foreach ($rawdevs as $i => $dev) {
$cl["device"][$i]["name"]=$dev;
if (preg_match("/^(\w+)[0-9]$/",$dev,$nam) === 1) $nam=$nam[1];
else $nam="none";
if (($n = array_search($nam,$_SESSION["net-device-name-prefix"])) === false) $n = count($_SESSION["net-device-types"])-1;
$ty = $_SESSION["net-device-types"][$n];
$cl["device"][$i]["type"]=$ty;
unset($udevinfo);
exec("udevadm info /sys/class/net/$dev 2> /dev/null",$udevinfo);
if ( $nam == "ppp" && isset($devtty)) exec("udevadm info --name='$devtty' 2> /dev/null", $udevinfo);
if(!empty($udevinfo) && is_array($udevinfo)) {
$model = preg_only_match("/ID_MODEL_ENC=(.*)$/",$udevinfo);
if(empty($model) || preg_match("/^[0-9a-f]{4}$/",$model) === 1) {
$model = preg_only_match("/ID_MODEL_FROM_DATABASE=(.*)$/",$udevinfo);
}
$vendor = preg_only_match("/ID_VENDOR_ENC=(.*)$/",$udevinfo);
if(empty($vendor) || preg_match("/^[0-9a-f]{4}$/",$vendor) === 1) {
$vendor = preg_only_match("/ID_VENDOR_FROM_DATABASE=(.*)$/",$udevinfo);
}
$driver = preg_only_match("/ID_NET_DRIVER=(.*)$/",$udevinfo);
$vendorid = preg_only_match("/ID_VENDOR_ID=(.*)$/",$udevinfo);
$productid = preg_only_match("/ID_MODEL_ID=(.*)$/",$udevinfo);
}
$cl["device"][$i]["model"] = preg_replace("/\\\\x20/"," ",$model);
$cl["device"][$i]["vendor"] = preg_replace("/\\\\x20/"," ",$vendor);
$cl["device"][$i]["vid"] = $vendorid;
$cl["device"][$i]["pid"] = $productid;
unset($mac);
exec("cat /sys/class/net/$dev/address 2> /dev/null",$mac);
$cl["device"][$i]["mac"] = empty($mac) ? "":$mac[0];
unset($ip);
exec("ifconfig $dev 2> /dev/null",$ip);
$cl["device"][$i]["ipaddress"] = preg_only_match("/.*inet ([0-9\.]+) .*/",$ip);
switch($ty) {
case "eth":
unset($res);
exec("ip link show $dev 2> /dev/null | grep -oP ' UP '",$res);
if(empty($res) && empty($ipadd)) $cl["device"][$i]["connected"] = "n";
else $cl["device"][$i]["connected"] = "y";
break;
case "wlan":
unset($retiw);
exec("iwconfig $dev 2> /dev/null | sed -rn 's/.*(mode:master).*/1/ip'",$retiw);
$cl["device"][$i]["isAP"] = !empty($retiw);
unset($retiw);
exec("iw dev $dev link 2> /dev/null",$retiw);
if(!$simple && !empty($ssid=preg_only_match("/.*SSID: (\w*).*/",$retiw)) ) {
$cl["device"][$i]["connected"] = "y";
$cl["device"][$i]["ssid"] = $ssid;
$cl["device"][$i]["ap-mac"] = preg_only_match("/^Connected to ([0-9a-f\:]*).*$/",$retiw);
$sig = preg_only_match("/.*signal: (.*)$/",$retiw);
$val = preg_only_match("/^([0-9\.-]*).*$/",$sig);
if (!is_numeric($val)) $val = -100;
if( $val >= -50 ) $qual=100;
else if( $val < -100) $qual=0;
else $qual=round($val*2+200);
$cl["device"][$i]["signal"] = "$sig (".$qual."%)";
$cl["device"][$i]["bitrate"] = preg_only_match("/.*bitrate: ([0-9\.]* \w*\/s).*$/",$retiw);
$cl["device"][$i]["freq"] = preg_only_match("/.*freq: (.*)$/",$retiw);
$cl["device"][$i]["ap-mac"] = preg_only_match("/^Connected to ([0-9a-f\:]*).*$/",$retiw);
} else $cl["device"][$i]["connected"] = "n";
break;
case "ppp":
unset($res);
exec("ip link show $dev 2> /dev/null | grep -oP '( UP | UNKNOWN)'",$res);
if($simple) {
if(empty($res)) {
$cl["device"][$i]["connected"] = "n";
$cl["device"][$i]["signal"] = "-100 dB (0%)";
} else {
$cl["device"][$i]["connected"] = "y";
$cl["device"][$i]["signal"] = "-0 dB (0%)";
}
break;
}
if(empty($res) && empty($ipadd)) $cl["device"][$i]["connected"] = "n";
else $cl["device"][$i]["connected"] = "y";
unset($res);
exec("$path/info_huawei.sh mode modem",$res);
$cl["device"][$i]["mode"] = $res[0];
unset($res);
exec("$path/info_huawei.sh device modem",$res);
if( $res[0] != "none" ) $cl["device"][$i]["model"] = $res[0];
unset($res);
exec("$path/info_huawei.sh signal modem",$res);
$cl["device"][$i]["signal"] = $res[0];
unset($res);
exec("$path/info_huawei.sh operator modem",$res);
$cl["device"][$i]["operator"] = $res[0];
break;
case "hilink":
unset($res);
// exec("ip link show $dev 2> /dev/null | grep -oP ' UP '",$res);
exec("ifconfig -a | grep -i $dev -A 1 | grep -oP '(?<=inet )([0-9]{1,3}\.){3}'",$apiadd);
$apiadd = !empty($apiadd) ? $apiadd[0]."1" : "";
unset($res);
exec("$path/info_huawei.sh mode hilink $apiadd",$res);
$cl["device"][$i]["mode"] = $res[0];
unset($res);
exec("$path/info_huawei.sh device hilink $apiadd",$res);
if( $res[0] != "none" ) $cl["device"][$i]["model"] = $res[0];
unset($res);
exec("$path/info_huawei.sh signal hilink $apiadd",$res);
$cl["device"][$i]["signal"] = $res[0];
unset($ipadd);
exec("$path/info_huawei.sh ipaddress hilink $apiadd",$ipadd);
if(!empty($ipadd) && $ipadd[0] !== "none" ) {
$cl["device"][$i]["connected"] = "y";
$cl["device"][$i]["wan_ip"] = $ipadd[0];
}
else $cl["device"][$i]["connected"] = "n";
unset($res);
exec("$path/info_huawei.sh operator hilink $apiadd",$res);
$cl["device"][$i]["operator"] = $res[0];
break;
case "phone":
break;
default:
}
}
}
return $cl;
}
function load_client_config() {
// load network device config file for UDEV rules into $_SESSION
if(true) {
// if(!isset($_SESSION["udevrules"])) {
$_SESSION["net-device-types"]=array();
$_SESSION["net-device-name-prefix"]=array();
try {
$udevrules = file_get_contents(RASPI_CLIENT_CONFIG_PATH);
$_SESSION["udevrules"] = json_decode($udevrules, true);
// get device types
foreach ($_SESSION["udevrules"]["network_devices"] as $dev) {
$_SESSION["net-device-name-prefix"][]=$dev["name_prefix"];
$_SESSION["net-device-types"][]=$dev["type"];
$_SESSION["net-device-types-info"][]=$dev["type_info"];
}
} catch (Exception $e) {
$_SESSION["udevrules"]= NULL;
}
$_SESSION["net-device-types"][]="none";
$_SESSION["net-device-types-info"][]="unknown";
$_SESSION["net-device-name-prefix"][]="none";
}
}
?>

12
includes/networking.php

@ -2,6 +2,8 @@
require_once 'includes/status_messages.php';
require_once 'includes/internetRoute.php';
require_once 'includes/functions.php';
require_once 'includes/get_clients.php';
/**
*
@ -17,10 +19,18 @@ function DisplayNetworkingConfig()
$arrHostapdConf = parse_ini_file(RASPI_CONFIG.'/hostapd.ini');
$bridgedEnabled = $arrHostapdConf['BridgedEnable'];
foreach ($interfaces as $interface) {
exec("ip a show $interface", $$interface);
}
load_client_config();
$clients=getClients();
echo renderTemplate("networking", compact(
"status",
"interfaces",
"routeInfo",
"bridgedEnabled")
"bridgedEnabled",
"clients")
);
}
?>

2
installers/configauth.sh

@ -35,7 +35,7 @@ echo "Checking iptables rules"
rules=(
"-A POSTROUTING -o tun0 -j MASQUERADE"
"-A FORWARD -i tun0 -o ${interface} -m state --state RELATED,ESTABLISHED -j ACCEPT"
"-A FORWARD -i wlan0 -o tun0 -j ACCEPT"
"-A FORWARD -i ${interface} -o tun0 -j ACCEPT"
)
for rule in "${rules[@]}"; do

7
installers/raspap.sudoers

@ -42,4 +42,11 @@ www-data ALL=(ALL) NOPASSWD:/bin/chmod o+r /tmp/dnsmasq.log
www-data ALL=(ALL) NOPASSWD:/bin/cp /tmp/dnsmasqdata /etc/dnsmasq.d/090_adblock.conf
www-data ALL=(ALL) NOPASSWD:/bin/cp /tmp/dnsmasq_custom /etc/raspap/adblock/custom.txt
www-data ALL=(ALL) NOPASSWD:/etc/raspap/adblock/update_blocklist.sh
www-data ALL=(ALL) NOPASSWD:/usr/bin/socat - /dev/ttyUSB[0-9]
www-data ALL=(ALL) NOPASSWD:/usr/local/sbin/switchClientState.sh up
www-data ALL=(ALL) NOPASSWD:/usr/local/sbin/switchClientState.sh down
www-data ALL=(ALL) NOPASSWD:/bin/sed -i * /etc/wvdial.conf
www-data ALL=(ALL) NOPASSWD:/bin/sed -i * /etc/udev/rules.d/80-raspap-net-devices.rules
www-data ALL=(ALL) NOPASSWD:/usr/bin/tee -a /etc/udev/rules.d/80-raspap-net-devices.rules

90
templates/dashboard.php

@ -3,18 +3,17 @@
<div class="card">
<div class="card-header">
<div class="row">
<div class="col">
<i class="fas fa-tachometer-alt fa-fw mr-2"></i><?php echo _("Dashboard"); ?>
</div>
<div class="col">
<button class="btn btn-light btn-icon-split btn-sm service-status float-right">
<span class="icon"><i class="fas fa-circle service-status-<?php echo $ifaceStatus ?>"></i></span>
<span class="text service-status"><?php echo strtolower($apInterface) .' '. _($ifaceStatus) ?></span>
</button>
</div>
<div class="col">
<i class="fas fa-tachometer-alt fa-fw mr-2"></i><?php echo _("Dashboard"); ?>
</div>
<div class="col">
<button class="btn btn-light btn-icon-split btn-sm service-status float-right">
<span class="icon"><i class="fas fa-circle service-status-<?php echo $ifaceStatus ?>"></i></span>
<span class="text service-status"><?php echo $type_name .' '. _($ifaceStatus) ?></span>
</button>
</div>
</div><!-- /.row -->
</div><!-- /.card-header -->
<div class="card-body">
<div class="row">
@ -33,25 +32,54 @@
<div class="col-sm-6 align-items-stretch">
<div class="card h-100">
<div class="card-body wireless">
<h4><?php echo _("Wireless Client"); ?></h4>
<h4><?php echo _("$client_title"); ?></h4>
<div class="row justify-content-md-center">
<div class="col-md">
<div class="info-item"><?php echo _("Connected To"); ?></div><div><?php echo htmlspecialchars($connectedSSID, ENT_QUOTES); ?></div>
<div class="info-item"><?php echo _("Interface"); ?></div><div><?php echo htmlspecialchars($clientInterface); ?></div>
<div class="info-item"><?php echo _("AP Mac Address"); ?></div><div><?php echo htmlspecialchars($connectedBSSID, ENT_QUOTES); ?></div>
<div class="info-item"><?php echo _("Bitrate"); ?></div><div><?php echo htmlspecialchars($bitrate, ENT_QUOTES); ?></div>
<div class="info-item"><?php echo _("Signal Level"); ?></div><div><?php echo htmlspecialchars($signalLevel, ENT_QUOTES); ?></div>
<div class="info-item"><?php echo _("Transmit Power"); ?></div><div><?php echo htmlspecialchars($txPower, ENT_QUOTES); ?></div>
<div class="info-item"><?php echo _("Frequency"); ?></div><div><?php echo htmlspecialchars($frequency, ENT_QUOTES); ?></div>
</div>
<div class="col-md mt-2 d-flex justify-content-center">
<script>var linkQ = <?php echo json_encode($strLinkQuality); ?>;</script>
<div class="chart-container">
<canvas id="divChartLinkQ"></canvas>
</div>
<div class="col-md">
<?php if ($clientinfo["type"] == "wlan") : // WIRELESS ?>
<div class="info-item"><?php echo _("Connected To"); ?></div><div><?php echo htmlspecialchars($clientinfo["ssid"], ENT_QUOTES); ?></div>
<div class="info-item"><?php echo _("AP Mac Address"); ?></div><div><?php echo htmlspecialchars($clientinfo["ap-mac"], ENT_QUOTES); ?></div>
<div class="info-item"><?php echo _("Bitrate"); ?></div><div><?php echo htmlspecialchars($clientinfo["bitrate"], ENT_QUOTES); ?></div>
<div class="info-item"><?php echo _("Signal Level"); ?></div><div><?php echo htmlspecialchars($clientinfo["signal"], ENT_QUOTES); ?></div>
<div class="info-item"><?php echo _("Transmit Power"); ?></div><div><?php echo htmlspecialchars($txPower, ENT_QUOTES); ?></div>
<div class="info-item"><?php echo _("Frequency"); ?></div><div><?php echo htmlspecialchars($clientinfo["freq"]." MHz", ENT_QUOTES); ?></div>
<?php elseif ($clientinfo["type"] == "phone" ) : // Smartphones (tethering over USB) ?>
<div class="info-item"><?php echo _("Device"); ?></div><div><?php echo htmlspecialchars($clientinfo["vendor"]." ".$clientinfo["model"], ENT_QUOTES); ?></div>
<div class="info-item"><?php echo _("IP Address"); ?></div><div><?php echo htmlspecialchars($clientinfo["ipaddress"], ENT_QUOTES); ?></div>
<?php elseif ($clientinfo["type"] == "hilink" ) : // MOBILE DATA - ROUTER MODE (HILINK) ?>
<?php
exec('ip route list | sed -rn "s/default via (([0-9]{1,3}\.){3}[0-9]{1,3}).*dev '.$clientinfo["name"].'.*/\1/p"',$gw); // get gateway
$gw=empty($gw) ? "" : $gw[0];
?>
<div class="info-item"><?php echo _("Device"); ?></div><div><?php echo htmlspecialchars($clientinfo["model"], ENT_QUOTES)." (Hilink)"; ?></div>
<div class="info-item"><?php echo _("Connection mode"); ?></div><div><?php echo htmlspecialchars($clientinfo["mode"], ENT_QUOTES); ?></div>
<div class="info-item"><?php echo _("Signal quality"); ?></div><div><?php echo htmlspecialchars($clientinfo["signal"], ENT_QUOTES); ?></div>
<div class="info-item"><?php echo _("Network"); ?></div><div><?php echo htmlspecialchars($clientinfo["operator"], ENT_QUOTES); ?></div>
<div class="info-item"><?php echo _("WAN IP"); ?></div><div><?php echo htmlspecialchars($clientinfo["ipaddress"], ENT_QUOTES); ?></div>
<div class="info-item"><?php echo _("Web-GUI"); ?></div><div><?php if(!empty($gw)) echo '<a href="http://'.$gw.'" >'.$gw."</a>"; ?></div>
<?php elseif ($clientinfo["type"] == "ppp" ) : // MOBILE DATA MODEM) ?>
<div class="info-item"><?php echo _("Device"); ?></div><div><?php echo htmlspecialchars($clientinfo["model"], ENT_QUOTES); ?></div>
<div class="info-item"><?php echo _("Connection mode"); ?></div><div><?php echo htmlspecialchars($clientinfo["mode"], ENT_QUOTES); ?></div>
<div class="info-item"><?php echo _("Signal strength"); ?></div><div><?php echo htmlspecialchars($clientinfo["signal"], ENT_QUOTES); ?></div>
<div class="info-item"><?php echo _("Network"); ?></div><div><?php echo htmlspecialchars($clientinfo["operator"], ENT_QUOTES); ?></div>
<?php elseif ($clientinfo["type"] == "eth" ) : // ETHERNET ?>
<div class="info-item"><?php echo _("Device"); ?></div><div><?php echo htmlspecialchars($clientinfo["vendor"]." ".$clientinfo["model"], ENT_QUOTES); ?></div>
<div class="info-item"><?php echo _("IP Address"); ?></div><div><?php echo htmlspecialchars($clientinfo["ipaddress"], ENT_QUOTES); ?></div>
<?php else : // NO CLIENT ?>
<div class="info-item"><?php echo _("No Client device found"); ?></div>
<?php endif; ?>
</div>
<div class="col-md mt-2 d-flex justify-content-center">
<?php
preg_match("/.*\((\s*\d*)\s*%\s*\)/",$clientinfo["signal"],$match);
$strLinkQuality=array_key_exists(1,$match) ? $match[1] : 0;
?>
<script>var linkQ = <?php echo json_encode($strLinkQuality); ?>;</script>
<div class="chart-container">
<canvas id="divChartLinkQ"></canvas>
</div>
</div>
</div><!--row-->
</div>
</div><!-- /.card-body -->
</div><!-- /.card-body -->
</div><!-- /.card -->
</div><!-- /.col-md-6 -->
<div class="col-sm-6">
@ -103,23 +131,21 @@
</div><!-- /.card -->
</div><!-- /.col-md-6 -->
</div><!-- /.row -->
<div class="col-lg-12 mt-3">
<div class="row">
<form action="wlan0_info" method="POST">
<?php echo CSRFTokenFieldTag() ?>
<?php if (!RASPI_MONITOR_ENABLED) : ?>
<?php if (!$wlan0up) : ?>
<input type="submit" class="btn btn-success" value="<?php echo _("Start").' '.$clientInterface ?>" name="ifup_wlan0" />
<?php if ($ifaceStatus == "down") : ?>
<input type="submit" class="btn btn-success" value="<?php echo _("Start").' '.$type_name ?>" name="ifup_wlan0" />
<?php else : ?>
<input type="submit" class="btn btn-warning" value="<?php echo _("Stop").' '.$clientInterface ?>" name="ifdown_wlan0" />
<input type="submit" class="btn btn-warning" value="<?php echo _("Stop").' '.$type_name ?>" name="ifdown_wlan0" />
<?php endif ?>
<?php endif ?>
<button type="button" onClick="window.location.reload();" class="btn btn-outline btn-primary"><i class="fas fa-sync-alt"></i> <?php echo _("Refresh") ?></a>
</form>
</div>
</div>
</div><!-- /.card-body -->
<div class="card-footer"><?php echo _("Information provided by ip and iw and from system"); ?></div>
</div><!-- /.card -->

137
templates/networking.php

@ -1,23 +1,27 @@
<div class="row">
<div class="col-lg-12">
<div class="card">
<div class="card-header">
<div class="row">
<div class="col">
<i class="fas fa-network-wired mr-2"></i><?php echo _("Networking"); ?>
</div>
</div><!-- ./row -->
</div><!-- ./card-header -->
<div class="card">
<div class="card-header">
<div class="row">
<div class="col">
<i class="fas fa-network-wired mr-2"></i><?php echo _("Networking"); ?>
</div>
</div><!-- ./row -->
</div><!-- ./card-header -->
<div class="card-body">
<div id="msgNetworking"></div>
<ul class="nav nav-tabs">
<li role="presentation" class="nav-item"><a class="nav-link active" href="#summary" aria-controls="summary" role="tab" data-toggle="tab"><?php echo _("Summary"); ?></a></li>
<?php if (!$bridgedEnabled) : // no interface details when bridged ?>
<li role="presentation" class="nav-item"><a class="nav-link" href="#mobiledata" aria-controls="mobiledata" role="tab" data-toggle="tab">Mobile Data Settings</a></li>
<li role="presentation" class="nav-item"><a class="nav-link" href="#netdevices" aria-controls="netdevices" role="tab" data-toggle="tab">Network Devices</a></li>
<?php endif ?>
</ul>
<div class="tab-content">
<div role="tabpanel" class="tab-pane active" id="summary">
<h4 class="mt-3"><?php echo _("Internet connection"); ?></h4>
<div class="row">
<div class="col-sm-12"">
<div class="col-sm-12">
<div class="card ">
<div class="card-body">
<div class="table-responsive">
@ -74,9 +78,122 @@
<div class="col-lg-12">
<div class="row">
<button type="button" onClick="window.location.reload();" class="btn btn-outline btn-primary"><i class="fas fa-sync-alt"></i> <?php echo _("Refresh") ?></a>
</div>
</div>
</div>
<?php $arrMD = parse_ini_file('/etc/raspap/networking/mobiledata.ini');
if ($arrMD==false) { $arrMD=[]; $arrMD["pin"]=$arrMD["apn"]=$arrMD["apn_user"]=$arrMD["apn_pw"]=$arrMD["router_user"]=$arrMD["router_pw"]=""; }
?>
<div role="tabpanel" class="tab-pane fade in" id="mobiledata">
<div class="row">
<div class="col-lg-6">
<h4 class="mt-3"><?php echo _("Settings for Mobile Data Devices") ?></h4>
<hr />
<form id="frm-mobiledata">
<?php echo CSRFTokenFieldTag() ?>
<div class="form-group">
<label for="pin-mobile"><?php echo _("PIN of SIM card") ?></label>
<input type="number" class="form-control" id="pin-mobile" placeholder="1234" value="<?php echo $arrMD["pin"]?>" >
</div>
<h4 class="mt-3"><?php echo _("APN Settings (Modem device ppp0)") ?></h4>
<div class="form-group">
<label for="apn-mobile"><?php echo _("Access Point Name (APN)") ?></label>
<input type="text" class="form-control" id="apn-mobile" placeholder="web.myprovider.com" value="<?php echo $arrMD["apn"]?>" >
<label for="apn-user-mobile"><?php echo _("Username") ?></label>
<input type="text" class="form-control" id="apn-user-mobile" value="<?php echo $arrMD["apn_user"]?>" >
<label for="apn-pw-mobile"><?php echo _("Password") ?></label>
<input type="text" class="form-control" id="apn-pw-mobile" value="<?php echo $arrMD["apn_pw"]?>" >
</div>
<a href="#" class="btn btn-outline btn-primary intsave" data-int="mobiledata"><?php echo _("Save settings") ?></a>
</form>
</div>
</div>
</div><!-- /.tab-panel -->
<div role="tabpanel" class="tab-pane fade in" id="netdevices">
<h4 class="mt-3"><?php echo _("Properties of network devices") ?></h4>
<div class="row">
<div class="col-sm-12">
<div class="card ">
<div class="card-body">
<form id="frm-netdevices">
<?php echo CSRFTokenFieldTag() ?>
<div class="table-responsive">
<table class="table table-hover">
<thead>
<tr>
<th><?php echo _("Device"); ?></th>
<th><?php echo _("Interface"); ?></th>
<th></th>
<th><?php echo _("MAC"); ?></th>
<th><?php echo _("USB vid/pid"); ?></th>
<th><?php echo _("Device type"); ?></th>
<th style="min-width:6em"><?php echo _("Fixed name"); ?></th>
<th></th>
</tr>
</thead>
<tbody>
<?php
if(!empty($clients)) {
$ncl=$clients["clients"];
if($ncl > 0) {
foreach($clients["device"] as $id => $dev) {
echo "<tr>";
echo "<td>".$dev["vendor"]." ".$dev["model"]."</td>\n";
echo "<td>".$dev["name"]."</td>\n";
$ty="Client";
if(isset($dev["isAP"]) && $dev["isAP"]) $ty="Access Point";
echo "<td>".$ty."</td>\n";
echo "<td>".$dev["mac"]."</td>\n";
echo "<td>".$dev["vid"]."/".$dev["pid"]."</td>\n";
$udevfile=$_SESSION["udevrules"]["udev_rules_file"];
$isStatic=array();
exec('find /etc/udev/rules.d/ -type f \( -iname "*.rules" ! -iname "'.basename($udevfile).'" \) -exec grep -i '.$dev["mac"].' {} \; ',$isStatic);
if(empty($isStatic))
exec('find /etc/udev/rules.d/ -type f \( -iname "*.rules" ! -iname "'.basename($udevfile).'" \) -exec grep -i '.$dev["vid"].' {} \; | grep -i '.$dev["pid"].' ',$isStatic);
$isStatic = empty($isStatic) ? false : true;
$devname=array();
exec('grep -i '.$dev["vid"].' '.$udevfile.' | grep -i '.$dev["pid"].' | sed -rn \'s/.*name=\"(\w*)\".*/\1/ip\' ',$devname);
if(!empty($devname)) $devname=$devname[0];
else {
exec('grep -i '.$dev["mac"].' '.$udevfile.' | sed -rn \'s/.*name=\"(\w*)\".*/\1/ip\' ',$devname);
if(!empty($devname)) $devname=$devname[0];
}
if(empty($devname)) $devname="";
$isStatic = $isStatic || $dev["type"] === "ppp";
$txtdisabled=$isStatic ? "disabled":"";
echo '<td><select '.$txtdisabled.' class="selectpicker" id="int-new-type-'.$dev["name"].'">';
foreach($_SESSION["net-device-types"] as $i => $type) {
$txt=$_SESSION["net-device-types-info"][$i];
$txtdisabled = $type == "ppp" ? "disabled":"";
if(preg_match("/^".$_SESSION["net-device-name-prefix"][$i]."[0-9]*$/",$dev["name"])===1) echo '<option '.$txtdisabled.' selected value="'.$type.'">'.$txt.'</option>';
else echo '<option '.$txtdisabled.' value="'.$type.'">'.$txt.'</option>';
}
echo "</select></td>";
echo '<td>';
if (! $isStatic ) echo '<input type="text" class="form-control" id="int-name-'.$dev["name"].'" value="'.$devname.'" >'."\n";
else echo $dev["name"];
echo '<input type="hidden" class="form-control" id="int-vid-'.$dev["name"].'" value="'.$dev["vid"].'" >'."\n";
echo '<input type="hidden" class="form-control" id="int-pid-'.$dev["name"].'" value="'.$dev["pid"].'" >'."\n";
echo '<input type="hidden" class="form-control" id="int-mac-'.$dev["name"].'" value="'.$dev["mac"].'" >'."\n";
echo '<input type="hidden" class="form-control" id="int-type-'.$dev["name"].'" value="'.$dev["type"].'" >'."\n";
echo '</td>'."\n";
echo '<td>';
if (! $isStatic) echo '<a href="#" class="btn btn-secondary intsave" data-opts="'.$dev["name"].'" data-int="netdevices">Change</a>';