1
0
mirror of https://github.com/billz/raspap-webgui.git synced 2023-10-10 13:37:24 +02:00

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
This commit is contained in:
Christian Zeitnitz 2021-03-07 18:36:48 +01:00
parent 6d635a96d5
commit 8b0383dd20
24 changed files with 2766 additions and 114 deletions

View File

@ -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);

View File

@ -130,6 +130,7 @@ function setupBtns() {
$('#btnSummaryRefresh').click(function(){getAllInterfaces();}); $('#btnSummaryRefresh').click(function(){getAllInterfaces();});
$('.intsave').click(function(){ $('.intsave').click(function(){
var int = $(this).data('int'); var int = $(this).data('int');
saveNetDeviceSettings(int);
saveNetworkSettings(int); saveNetworkSettings(int);
}); });
$('.intapply').click(function(){ $('.intapply').click(function(){
@ -173,6 +174,24 @@ function loadWifiStations(refresh) {
} }
$(".js-reload-wifi-stations").on("click", loadWifiStations(true)); $(".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 Populates the DHCP server form fields
Option toggles are set dynamically depending on the loaded configuration Option toggles are set dynamically depending on the loaded configuration

View File

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

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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?

View File

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

View File

@ -728,5 +728,15 @@ function getNightmode(){
} else { } else {
return false; 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 Normal file
View File

@ -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";
}
}
?>

View File

@ -2,6 +2,8 @@
require_once 'includes/status_messages.php'; require_once 'includes/status_messages.php';
require_once 'includes/internetRoute.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'); $arrHostapdConf = parse_ini_file(RASPI_CONFIG.'/hostapd.ini');
$bridgedEnabled = $arrHostapdConf['BridgedEnable']; $bridgedEnabled = $arrHostapdConf['BridgedEnable'];
foreach ($interfaces as $interface) {
exec("ip a show $interface", $$interface);
}
load_client_config();
$clients=getClients();
echo renderTemplate("networking", compact( echo renderTemplate("networking", compact(
"status", "status",
"interfaces", "interfaces",
"routeInfo", "routeInfo",
"bridgedEnabled") "bridgedEnabled",
"clients")
); );
} }
?>

View File

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

View File

@ -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/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:/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:/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

View File

@ -9,12 +9,11 @@
<div class="col"> <div class="col">
<button class="btn btn-light btn-icon-split btn-sm service-status float-right"> <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="icon"><i class="fas fa-circle service-status-<?php echo $ifaceStatus ?>"></i></span>
<span class="text service-status"><?php echo strtolower($apInterface) .' '. _($ifaceStatus) ?></span> <span class="text service-status"><?php echo $type_name .' '. _($ifaceStatus) ?></span>
</button> </button>
</div> </div>
</div><!-- /.row --> </div><!-- /.row -->
</div><!-- /.card-header --> </div><!-- /.card-header -->
<div class="card-body"> <div class="card-body">
<div class="row"> <div class="row">
@ -33,24 +32,53 @@
<div class="col-sm-6 align-items-stretch"> <div class="col-sm-6 align-items-stretch">
<div class="card h-100"> <div class="card h-100">
<div class="card-body wireless"> <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="row justify-content-md-center">
<div class="col-md"> <div class="col-md">
<div class="info-item"><?php echo _("Connected To"); ?></div><div><?php echo htmlspecialchars($connectedSSID, ENT_QUOTES); ?></div> <?php if ($clientinfo["type"] == "wlan") : // WIRELESS ?>
<div class="info-item"><?php echo _("Interface"); ?></div><div><?php echo htmlspecialchars($clientInterface); ?></div> <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($connectedBSSID, 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($bitrate, 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($signalLevel, 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 _("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 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>
<div class="col-md mt-2 d-flex justify-content-center"> <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> <script>var linkQ = <?php echo json_encode($strLinkQuality); ?>;</script>
<div class="chart-container"> <div class="chart-container">
<canvas id="divChartLinkQ"></canvas> <canvas id="divChartLinkQ"></canvas>
</div> </div>
</div><!--row-->
</div> </div>
</div><!--row-->
</div><!-- /.card-body --> </div><!-- /.card-body -->
</div><!-- /.card --> </div><!-- /.card -->
</div><!-- /.col-md-6 --> </div><!-- /.col-md-6 -->
@ -103,23 +131,21 @@
</div><!-- /.card --> </div><!-- /.card -->
</div><!-- /.col-md-6 --> </div><!-- /.col-md-6 -->
</div><!-- /.row --> </div><!-- /.row -->
<div class="col-lg-12 mt-3"> <div class="col-lg-12 mt-3">
<div class="row"> <div class="row">
<form action="wlan0_info" method="POST"> <form action="wlan0_info" method="POST">
<?php echo CSRFTokenFieldTag() ?> <?php echo CSRFTokenFieldTag() ?>
<?php if (!RASPI_MONITOR_ENABLED) : ?> <?php if (!RASPI_MONITOR_ENABLED) : ?>
<?php if (!$wlan0up) : ?> <?php if ($ifaceStatus == "down") : ?>
<input type="submit" class="btn btn-success" value="<?php echo _("Start").' '.$clientInterface ?>" name="ifup_wlan0" /> <input type="submit" class="btn btn-success" value="<?php echo _("Start").' '.$type_name ?>" name="ifup_wlan0" />
<?php else : ?> <?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 ?>
<?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> <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> </form>
</div> </div>
</div> </div>
</div><!-- /.card-body --> </div><!-- /.card-body -->
<div class="card-footer"><?php echo _("Information provided by ip and iw and from system"); ?></div> <div class="card-footer"><?php echo _("Information provided by ip and iw and from system"); ?></div>
</div><!-- /.card --> </div><!-- /.card -->

View File

@ -12,12 +12,16 @@
<div id="msgNetworking"></div> <div id="msgNetworking"></div>
<ul class="nav nav-tabs"> <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> <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> </ul>
<div class="tab-content"> <div class="tab-content">
<div role="tabpanel" class="tab-pane active" id="summary"> <div role="tabpanel" class="tab-pane active" id="summary">
<h4 class="mt-3"><?php echo _("Internet connection"); ?></h4> <h4 class="mt-3"><?php echo _("Internet connection"); ?></h4>
<div class="row"> <div class="row">
<div class="col-sm-12""> <div class="col-sm-12">
<div class="card "> <div class="card ">
<div class="card-body"> <div class="card-body">
<div class="table-responsive"> <div class="table-responsive">
@ -77,6 +81,119 @@
</div> </div>
</div> </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>';
echo "</td>\n";
echo "</tr>\n";
}
}
} else echo "<tr><td colspan=4>No network devices found</td></tr>";
?>
</tbody>
</table>
</div>
</form>
</div>
</div>
</div>
</div>
</div><!-- /.tab-panel -->
</div> </div>
</div><!-- /.card-body --> </div><!-- /.card-body -->
<div class="card-footer"><?php echo _("Information provided by /sys/class/net"); ?></div> <div class="card-footer"><?php echo _("Information provided by /sys/class/net"); ?></div>