Completely remove perl from the build DUMP_PERL (#291)

* And finally ... remove perl from the images

* Remove two more than came from the Admin merge

* Remove perl from perm packages
This commit is contained in:
Tim Wilkinson 2022-03-15 19:23:39 -07:00 committed by GitHub
parent 6707867dfd
commit 09985d3c57
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 6 additions and 10890 deletions

View File

@ -59,7 +59,7 @@ CONFIG_PACKAGE_kmod-pppoe=n
CONFIG_PACKAGE_kmod-pppox=n
CONFIG_PACKAGE_uhttpd=y
CONFIG_PACKAGE_olsrd=y
CONFIG_PACKAGE_perl=y
CONFIG_PACKAGE_perl=m
CONFIG_PACKAGE_olsrd-mod-arprefresh=y
CONFIG_PACKAGE_olsrd-mod-dyn-gw=y
CONFIG_PACKAGE_olsrd-mod-nameservice=y
@ -68,10 +68,10 @@ CONFIG_PACKAGE_olsrd-mod-jsoninfo=y
CONFIG_PACKAGE_olsrd-mod-dot-draw=y
CONFIG_PACKAGE_olsrd-mod-watchdog=y
CONFIG_PACKAGE_olsrd-mod-secure=m
CONFIG_PACKAGE_perlbase-essential=y
CONFIG_PACKAGE_perlbase-xsloader=y
CONFIG_PACKAGE_perlbase-file=y
CONFIG_PACKAGE_perlbase-perlio=y
CONFIG_PACKAGE_perlbase-essential=m
CONFIG_PACKAGE_perlbase-xsloader=m
CONFIG_PACKAGE_perlbase-file=m
CONFIG_PACKAGE_perlbase-perlio=m
CONFIG_PACKAGE_libpcap=m
CONFIG_PACKAGE_tcpdump-mini=m
CONFIG_PACKAGE_ntpclient=y

View File

@ -65,11 +65,6 @@ olsrd-mod-secure
olsrd-mod-txtinfo
olsrd-mod-watchdog
opkg
perl
perlbase-essential
perlbase-file
perlbase-perlio
perlbase-xsloader
ssidident
swconfig
tcpdump-mini

View File

@ -69,7 +69,7 @@ function html.alert_banner()
local local_message = read_all("/tmp/local_message")
html.print("<div class=\"TopBanner\">")
html.print("<div class=\"LogoDiv\"><a href=\"http://localnode.local.mesh:8080\" title=\"Go to localnode\"><img src=\"/AREDN.png\" class=\"AREDNLogo\"></img></a><div style=\"float: right;font-size: 8px;color: grey;\">Lua version</div></div>")
html.print("<div class=\"LogoDiv\"><a href=\"http://localnode.local.mesh:8080\" title=\"Go to localnode\"><img src=\"/AREDN.png\" class=\"AREDNLogo\"></img></a></div>")
local supported = aredn.hardware.supported()
if supported == 0 then

View File

@ -1,86 +0,0 @@
#!/usr/bin/perl -w -I/www/cgi-bin
use perlfunc;
$needsrun=nvram_get("nodeupgraded");
if ( ! $needsrun ){
print "Node not upgraded, exiting\n";
exit 0;
}
$config=nvram_get('config');
if ($config ne "mesh")
{
print "This node was previously configured in non-mesh mode and is no longer implemented. Returning to \"firstboot\".\n";
system ("firstboot -y && reboot");
exit 1;
}
#Prep some variables
$node = nvram_get("node");
$mac2 = mac2ip(get_mac(get_interface("wifi")), 0);
$dtdmac = mac2ip(get_mac(get_interface("lan")), 0);
$cfg = ();
$defaultcfg = ();
open(TMPCONFFILE, ">/tmp/.mesh_setup") or die;
foreach $line (`cat /etc/config.mesh/_setup`)
{
next if $line =~ /^\s*#/;
next if $line =~ /^\s*$/;
$line =~ /^(\w+)\s*=\s*(.*)$/;
$cfg{$1} = $2;
}
foreach $line (`cat /etc/config.mesh/_setup.default`)
{
next if $line =~ /^\s*#/;
next if $line =~ /^\s*$/;
$line =~ s/<NODE>/$node/;
$line =~ s/<MAC2>/$mac2/;
$line =~ s/<DTDMAC>/$dtdmac/;
$line =~ /^(\w+)\s*=\s*(.*)$/;
$defaultcfg{$1} = $2;
}
# Set variables in special conditions
if ( ($cfg{dmz_mode} eq '0') || ( $cfg{wan_proto} eq "disabled") ) {
$cfg{olsrd_gw} = 0;
}
#End special condition overides
foreach $variable( sort keys %defaultcfg )
{
if ( defined $cfg{$variable} )
{
print TMPCONFFILE "$variable = $cfg{$variable}\n";
}
else
{
print TMPCONFFILE "$variable = $defaultcfg{$variable}\n";
}
}
# Specific settings for variables that are not in the default config but are added by the system
foreach $variable( 'dmz_dhcp_end', 'dmz_dhcp_limit', 'dmz_dhcp_start', 'dmz_lan_ip', 'dmz_lan_mask', 'wifi_rxant', 'wifi_txant', 'wan_gw', 'wan_ip', 'wan_mask' )
{
if ( defined $cfg{$variable} )
{
print TMPCONFFILE "$variable = $cfg{$variable}\n";
}
}
close (TMPCONFFILE);
system ("mv /tmp/.mesh_setup /etc/config.mesh/_setup");
print "Updated mode: mesh\n";
#Commit the new combined config
system ("/usr/local/bin/node-setup.pl -a mesh");
nvram_set("nodeupgraded","0");
print "Rebooting node";
system ("reboot");

View File

@ -1,544 +0,0 @@
#!/usr/bin/perl -w -I/www/cgi-bin
=for comment
Part of AREDN -- Used for creating Amateur Radio Emergency Data Networks
Copyright (C) 2015 Conrad Lara
See Contributors file for additional contributors
Copyright (c) 2013 David Rivenburg et al. BroadBand-HamNet
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation version 3 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional Terms:
Additional use restrictions exist on the AREDN(TM) trademark and logo.
See AREDNLicense.txt for more info.
Attributions to the AREDN Project must be retained in the source code.
If importing this code into a new or existing project attribution
to the AREDN project must be added to the source code.
You must not misrepresent the origin of the material contained within.
Modified versions must be modified to attribute to the original source
and be marked in reasonable ways as differentiate it from the original
version.
=cut
use perlfunc;
$| = 1;
$auto = 0;
$do_basic = 1;
sub usage
{
die "
usage: node-setup [-a] [-p] <configname>
-a: automatic mode - don't ask any questions
-p: only process port forwarding and dhcp settings\n\n"
}
##########################
# main program starts here
# validate args
while(defined $ARGV[0] and $ARGV[0] =~ /^-/)
{
$arg = shift;
if ($arg eq "-a") { $auto = 1 }
elsif($arg eq "-p") { $do_basic = 0 }
else { usage() }
}
$config = shift;
usage() unless defined $config;
die "'$config' is not a valid configuration\n" unless ($config eq "mesh" and -f "/etc/config.mesh/_setup");
chomp ($lanintf=`jsonfilter -e '@.network.lan.ifname' < /etc/board.json | cut -f1`);
$node = nvram_get("node");
$tactical = nvram_get("tactical");
$mac2 = mac2ip(get_mac(get_interface("wifi")), 0);
$dtdmac = mac2ip(get_mac($lanintf), 0);
unless($auto)
{
print "\ncurrent node name is '$node'\n";
print "type a new name or just <enter> to keep the current name\n\n";
do
{
print "enter node name: ";
$node2 = <STDIN>;
die "node-setup aborted\n" if not defined $node2;
chomp $node2;
}
while($node2 =~ /[^\w\-]/ or $node2 =~ /_/);
print "\ncurrent tactical name is ";
if($tactical) { print "'$tactical'\n" }
else { print "not set\n" }
print "type a new name, <enter> to keep the current name,\n";
print "or @ to remove the tactical name\n\n";
do
{
print "enter tactical name: ";
$tac2 = <STDIN>;
die "node-setup aborted\n" if not defined $tac2;
chomp $tac2;
}
while($tac2 ne "@" and ($tac2 =~ /[^\w\-]/ or $tac2 =~ /_/));
$node = $node2 if $node2;
$tactical = $tac2 if $tac2;
$tactical = "" if $tac2 eq "@";
}
#
# load and verify the selected configuration
#
foreach $line (`cat /etc/config.mesh/_setup`)
{
next if $line =~ /^\s*#/;
next if $line =~ /^\s*$/;
$line =~ s/<NODE>/$node/;
$line =~ s/<MAC2>/$mac2/;
$line =~ s/<DTDMAC>/$dtdmac/;
$line =~ /^(\w+)\s*=\s*(.*)$/;
$cfg{$1} = $2;
}
chomp ($lanintf=`jsonfilter -e '@.network.lan.ifname' < /etc/board.json`);
$cfg{lan_intf} = "$lanintf";
$cfg{wan_intf} = "dummy";
# wan_intf is set by wifi-setup directly to network config file
$cfg{dtdlink_intf} = get_bridge_interfaces("dtdlink");
if ( $cfg{wifi_enable} == 1 )
{
$cfg{wifi_intf} = `jsonfilter -e '@.network.wifi.ifname' < /etc/board.json | cut -f1`;
$cfg{wifi_intf} =~ /wlan(\d+)/;
chomp $cfg{wifi_intf};
}
else
{
$wifi_sudo_intf = "$lanintf";
$wifi_sudo_intf =~ s/^([^\. \t]+).*$/$1/;
$cfg{wifi_intf} = $wifi_sudo_intf . ".3975";
}
die "configuration load failed\n" unless keys %cfg;
# delete some config lines if necessary
if($cfg{wan_proto} eq "dhcp")
{
$deleteme{wan_ip} = 1;
$deleteme{wan_gw} = 1;
$deleteme{wan_mask} = 1;
}
$deleteme{lan_gw} = 1 if $cfg{dmz_mode} or $cfg{wan_proto} ne "disabled";
# lan_dhcp sense is inverted in the dhcp config file
# and it is a checkbox so it may not be defined - this fixes that
if($cfg{lan_dhcp}) { $cfg{lan_dhcp} = 0 }
else { $cfg{lan_dhcp} = 1 }
# verify that we have all the variables we need
chdir "/etc/config.mesh" or die;
foreach(`grep "^[^#].*<" *`)
{
($file, $parm) = /^(\S+):.*<(\w+)>/;
if($parm eq uc $parm) # nvram variable
{
$lcparm = lc $parm;
die "parameter '$parm' in file '$file' does not exist\n" unless nvram_get($lcparm) ne "";
}
elsif(not $deleteme{$parm})
{
die "parameter '$parm' in file '$file' does not exist\n" unless exists $cfg{$parm};
}
}
# switch to dmz values if needed
if($cfg{dmz_mode})
{
foreach(qw(lan_ip lan_mask dhcp_start dhcp_end dhcp_limit))
{
$cfg{$_} = $cfg{"dmz_$_"};
}
}
# select ports and dhcp files based on mode
$portfile = "/etc/config.mesh/_setup.ports";
$dhcpfile = "/etc/config.mesh/_setup.dhcp";
$portfile .= ($cfg{dmz_mode} ? ".dmz" : ".nat");
$dhcpfile .= ($cfg{dmz_mode} ? ".dmz" : ".nat");
$aliasfile = "/etc/config.mesh/aliases";
$aliasfile .= ($cfg{dmz_mode} ? ".dmz" : ".nat");
#check for old aliases file, copy it to .dmz and create symlink
#just in case anyone is already using the file for some script or something
unless(-l "/etc/config.mesh/aliases") {
if(-f "/etc/config.mesh/aliases") {
system "cat /etc/config.mesh/aliases > /etc/config.mesh/aliases.dmz";
system "rm /etc/config.mesh/aliases";
system "cd /etc/config.mesh ; ln -s aliases.dmz aliases";
} else { system "cd /etc/config.mesh ; touch aliases.dmz ; ln -s aliases.dmz aliases"; }
}
# basic configuration
if($do_basic)
{
# setup the staging area
system "rm -rf /tmp/new_config; mkdir /tmp/new_config";
# copy and process the new configuration
chdir "/etc/config.mesh" or die;
foreach $file (glob "*")
{
chomp $file;
next if $file =~ /^_setup/;
next if $file =~ /^firewall.user/;
next if $file =~ /^olsrd/;
open(IN, $file) or die;
open(OUT, "> /tmp/new_config/$file") or die;
while(defined ($line = <IN>))
{
if($line =~ /^include\s+(\S+)/)
{
${incs} = $1;
foreach $inc (`cat ${incs}`)
{
print OUT $inc;
}
next;
}
$line =~ s/<NODE>/$node/;
$line =~ s/<MAC2>/$mac2/;
$line =~ s/<DTDMAC>/$dtdmac/;
$delparm = 0;
while(($parm) = $line =~ /^[^\#].*<(\S+)>/)
{
if($deleteme{$parm})
{
$delparm = 1;
last;
}
$line =~ s/<$parm>/$cfg{$parm}/;
}
print OUT $line unless $delparm;
}
close(OUT);
close(IN);
}
# make it official
system "rm -f /etc/config/*";
system "mv /tmp/new_config/* /etc/config";
unlink "/tmp/new_config";
system "cp -f /etc/config.mesh/firewall.user /etc/";
nvram_set("config", "mesh");
nvram_set("node", $node);
nvram_set("tactical", $tactical);
}
#
# generate the system files
#
open(HOSTS, ">/etc/hosts") or die;
print HOSTS "# automatically generated file - do not edit\n";
print HOSTS "# use /etc/hosts.user for custom entries\n";
print HOSTS "127.0.0.1\tlocalhost\n";
print HOSTS "$cfg{lan_ip}\tlocalnode ";
print HOSTS "\n$cfg{wifi_ip}\t" if $cfg{wifi_ip};
print HOSTS "$node $tactical\n";
print HOSTS "$cfg{dtdlink_ip}\tdtdlink.$node.local.mesh dtdlink.$node\n" if $cfg{dtdlink_ip};
print HOSTS add_ip_address($cfg{lan_ip}, 1), "\tlocalap\n" unless $cfg{dmz_mode};
open(ETHER, ">/etc/ethers") or die;
print ETHER "# automatically generated file - do not edit\n";
print ETHER "# use /etc/ethers.user for custom entries\n";
$netaddr = ip2decimal($cfg{lan_ip}) & ip2decimal($cfg{lan_mask});
foreach(`cat $dhcpfile`)
{
next if /^\s*#/;
next if /^\s*$/;
($mac, $ip, $host, $noprop) = split /\s+/, $_;
$ip = decimal2ip($netaddr + $ip);
# filter out addresses that are illegal for the lan subnet
next unless validate_same_subnet($ip, $cfg{lan_ip}, $cfg{lan_mask});
next unless validate_ip_netmask($ip, $cfg{lan_mask});
printf ETHER "$mac\t$ip $noprop\n";
printf HOSTS "$ip\t$host $noprop\n";
}
#aliases need to be added to /etc/hosts or they will not show up on the localnode
#nor will the services they might offer
#also add a comment to the hosts file so we can display the aliases differently if needed
if(-e $aliasfile) {
foreach(`cat $aliasfile`) {
next if /^\s*#/;
next if /^\s*$/;
($ip, $host) = split /\s+/, $_;
printf HOSTS "$ip\t$host #ALIAS\n";
}
}
print HOSTS "\n";
close(HOSTS);
close(ETHER);
system "cat /etc/hosts.user >> /etc/hosts" if -e "/etc/hosts.user";
system "cat /etc/ethers.user >> /etc/ethers" if -e "/etc/ethers.user";
unless($do_basic)
{
system "cp -f /etc/config.mesh/firewall /etc/config";
system "cp -f /etc/config.mesh/firewall.user /etc/";
}
open(FILE, ">>/etc/config/firewall") or die;
if($cfg{dmz_mode}) {
print FILE "\nconfig forwarding\n";
print FILE " option src wifi\n";
print FILE " option dest lan\n";
print FILE "\n";
print FILE "\nconfig forwarding\n";
print FILE " option src dtdlink\n";
print FILE " option dest lan\n";
system "uci set firewall.\@zone\[2\].masq=0";
} else {
print FILE "\n";
print FILE "config 'include'\n";
print FILE " option 'path' '/etc/firewall.natmode'\n";
print FILE " option 'reload' '1'\n";
}
if ($cfg{olsrd_gw}) {
print FILE "\nconfig forwarding\n";
print FILE " option src wifi\n";
print FILE " option dest wan\n";
print FILE "\n";
print FILE "\nconfig forwarding\n";
print FILE " option src dtdlink\n";
print FILE " option dest wan\n";
}
foreach(`cat $portfile`)
{
next if /^\s*#/;
next if /^\s*$/;
chomp;
# set dmz server
if(/dmz_ip = (\S+)/ and not $cfg{dmz_mode})
{
print FILE "\nconfig redirect\n\toption src wifi\n\toption proto tcp\n\toption src_dip $cfg{wifi_ip}\n\toption dest_ip $1\n\n";
print FILE "config redirect\n\toption src wifi\n\toption proto udp\n\toption src_dip $cfg{wifi_ip}\n\toption dest_ip $1\n\n";
next;
}
# set port forwarding rule
($intf, $type, $oport, $host, $iport, $enable) = split /[:]/, $_;
next unless $enable;
if($cfg{dmz_mode})
{
next if $intf eq "wifi";
$intf = "wan" if $intf eq "both";
}
$match = "option src_dport $oport\n";
if ($type eq "tcp") { $match .= "option proto tcp\n" }
elsif($type eq "udp") { $match .= "option proto udp\n" }
# uci the host and than
# set the inside port unless the rule uses an outside port range
$host = "option dest_ip $host\n";
$host .="\toption dest_port $iport\n" unless $oport =~ /-/;
if($intf eq "both")
{
print FILE "\nconfig redirect\n\toption src wifi\n\t$match\toption src_dip $cfg{wifi_ip}\n\t$host\n";
print FILE "\nconfig redirect\n\toption src dtdlink\n\t$match\toption src_dip $cfg{wifi_ip}\n\t$host\n";
print FILE "config redirect\n\toption src wan\n\t$match\t$host\n";
}
elsif($intf eq "wifi")
{
print FILE "\nconfig redirect\n\toption src dtdlink\n\t$match\toption src_dip $cfg{wifi_ip}\n\t$host\n";
print FILE "config redirect\n\toption src wifi\n\t$match\toption src_dip $cfg{wifi_ip}\n\t$host\n";
}
elsif($intf eq "wan")
{
print FILE "\nconfig redirect\n\toption src dtdlink\n\t$match\toption src_dip $cfg{wifi_ip}\n\t$host\n";
print FILE "config redirect\n\toption src wan\n\t$match\t$host\n";
}
else
{
print STDERR "ERROR: unknown interface '$intf'\n";
close(FILE);
exit 1;
}
}
close(FILE);
# generate the services file
$servfile = "/etc/config.mesh/_setup.services." . ($cfg{dmz_mode} ? "dmz" : "nat");
open(SERV, ">/etc/config/services") or die;
foreach(`cat $servfile 2>/dev/null`)
{
next if /^\s*#/;
next if /^\s*$/;
chomp;
($name, $link, $proto, $host, $port, $suffix) = split /\|/, $_;
$proto = "http" unless $proto;
$port = 0 unless $link;
$suffix = "" unless $suffix;
next unless defined $name and $name ne "" and defined $host and $host ne "";
printf SERV "%s://%s:%s/%s|%s|%s\n", $proto, $host, $port, $suffix, "tcp", $name;
}
close(SERV);
# generate the local config script
open(FILE, ">/etc/local/services") or die;
print FILE "#!/bin/sh\n";
unless($cfg{wifi_proto} eq "disabled")
{
$cfg{wifi_txpower} = wifi_maxpower($cfg{wifi_channel}) if not defined $cfg{wifi_txpower} or $cfg{wifi_txpower} > wifi_maxpower($cfg{wifi_channel});
$cfg{wifi_txpower} = 1 if $cfg{wifi_txpower} < 1;
if ( $cfg{wifi_enable} == 1 )
{
print FILE "/usr/sbin/iw dev $cfg{wifi_intf} set txpower fixed $cfg{wifi_txpower}00\n";
}
if(defined $cfg{aprs_lat} and defined $cfg{aprs_lon})
{
printf FILE "echo %s,%s > /tmp/latlon.txt\n", $cfg{aprs_lat}, $cfg{aprs_lon};
}
}
close(FILE);
system "chmod +x /etc/local/services";
# generate olsrd.conf
if(-f "/etc/config.mesh/olsrd")
{
open(IN, "/etc/config.mesh/olsrd") or die;
open(OUT, ">/etc/config/olsrd") or die;
while(defined ($line = <IN>))
{
if($line =~ /<olsrd_bridge>/)
{
if($cfg{olsrd_bridge}) { $line =~ s/<olsrd_bridge>/"wifi" "lan"/ }
else { $line =~ s/<olsrd_bridge>/"lan"/ }
}
elsif(($parm) = $line =~ /^[^\#].*<(\S+)>/)
{
$line =~ s/<$parm>/$cfg{$parm}/;
}
print OUT $line;
}
if($cfg{dmz_mode})
{
print OUT "\n";
print OUT "config Hna4\n";
@parts = split /[.]/, $cfg{dmz_lan_ip};
--$parts[3]; # assume network = lan_ip - 1
print OUT "\toption netaddr ", join(".", @parts),"\n";
print OUT "\toption netmask 255.255.255.", ((0xff << $cfg{dmz_mode}) & 0xff), "\n";
print OUT "\n\n";
}
if($cfg{olsrd_gw})
{
print OUT "config LoadPlugin\n";
print OUT " option library 'olsrd_dyn_gw.so.0.5'\n";
print OUT " option Interval '60'\n";
print OUT " list Ping '8.8.8.8'\n"; # google dns\n";
print OUT " list Ping '8.8.4.4'\n"; # google dns\n";
print OUT "\n\n";
}
close(OUT);
close(IN);
}
# indicate whether lan is running in dmz mode
$cmd .= "uci -q set aredn.\@dmz[0].mode=$cfg{dmz_mode};";
# Setup node lan dhcp
if ( $cfg{lan_dhcp_noroute} ) {
$cmd .= "uci add_list dhcp.\@dhcp[0].dhcp_option='121,10.0.0.0/8,$cfg{lan_ip},172.16.0.0/12,$cfg{lan_ip}' >/dev/null 2>&1;";
$cmd .= "uci add_list dhcp.\@dhcp[0].dhcp_option='249,10.0.0.0/8,$cfg{lan_ip},172.16.0.0/12,$cfg{lan_ip}' >/dev/null 2>&1;";
$cmd .= "uci add_list dhcp.\@dhcp[0].dhcp_option=3 >/dev/null 2>&1;";
} else {
$cmd .= "uci add_list dhcp.\@dhcp[0].dhcp_option='121,10.0.0.0/8,$cfg{lan_ip},172.16.0.0/12,$cfg{lan_ip},0.0.0.0/0,$cfg{lan_ip}' >/dev/null 2>&1;";
$cmd .= "uci add_list dhcp.\@dhcp[0].dhcp_option='249,10.0.0.0/8,$cfg{lan_ip},172.16.0.0/12,$cfg{lan_ip},0.0.0.0/0,$cfg{lan_ip}' >/dev/null 2>&1;";
}
# finish up
$cmd .= "uci -q commit;";
system $cmd;
#
# generate the wireless config file
#
system('/usr/local/bin/wifi-setup');
unless($auto)
{
print "configuration complete.\n";
print "you should now reboot the router.\n";
}
exit 0;

View File

@ -1,141 +0,0 @@
#!/usr/bin/perl -w
=for comment
Part of AREDN -- Used for creating Amateur Radio Emergency Data Networks
Copyright (C) 2015 Conrad Lara
See Contributors file for additional contributors
Copyright (c) 2013 David Rivenburg et al. BroadBand-HamNet
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation version 3 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional Terms:
Additional use restrictions exist on the AREDN(TM) trademark and logo.
See AREDNLicense.txt for more info.
Attributions to the AREDN Project must be retained in the source code.
If importing this code into a new or existing project attribution
to the AREDN project must be added to the source code.
You must not misrepresent the origin of the material contained within.
Modified versions must be modified to attribute to the original source
and be marked in reasonable ways as differentiate it from the original
version.
=cut
# do the initial setup of the essential nvram variables
# node - node name
# mac2 - last 3 bytes of wifi mac address in the form ddd.ddd.ddd
# wifi_mac - full mac address of wireless card in the form hh:hh:hh:hh:hh:hh
#
# intended to run every boot but it should only actually do anything
# on the first boot
sub fail
{
open(ERR, ">>/tmp/nvram_errors");
print ERR "@_\n";
close(ERR);
die "@_\n";
}
sub get_wlan2phy
{
my ($wlan) = $1;
my ($phy) = "";
return "phy0" unless $wlan;
foreach(`iwinfo $wlan info`)
{
next unless /^.*PHY name:\s*([a-z0-4]+)/;
$phy = $1;
}
return $phy;
}
$commit = 0;
$wifiif = `uci -q get network.wifi.ifname`;
$phy = get_wlan2phy("$wifiif");
# Added new wifimac parm, the radio* wont startup without it, use the path location in wifi config
# Actually it just needs some path to get to the radio.
chomp ($wifi_mac = `uci -c /etc/local/uci/ -q get hsmmmesh.settings.wifimac`);
if($wifi_mac eq "")
{
open(FILE, "/sys/class/ieee80211/${phy}/macaddress") or fail("ERROR: wireless mac not available");
while(<FILE>)
{
next unless /(\w\w:\w\w:\w\w:\w\w:\w\w:\w\w)/;
$wifi_mac = $1;
last;
}
close(FILE);
fail("ERROR: wireless mac not found") if $wifi_mac eq "";
system "uci -c /etc/local/uci/ set hsmmmesh.settings.wifimac=$wifi_mac";
$commit = 1;
}
chomp ($mac2 = `uci -c /etc/local/uci/ -q get hsmmmesh.settings.mac2`);
if($mac2 eq "")
{
open(FILE, "/sys/class/ieee80211/${phy}/macaddress") or fail("ERROR: wireless mac not available");
while(<FILE>)
{
next unless /\w\w:\w\w:\w\w:(\w\w):(\w\w):(\w\w)/;
$mac2 = join ".", hex $1, hex $2, hex $3;
last;
}
close(FILE);
fail("ERROR: wireless mac not found") if $mac2 eq "";
system "uci -c /etc/local/uci/ set hsmmmesh.settings.mac2=$mac2";
$commit = 1;
}
chomp ($node = `uci -c /etc/local/uci/ -q get hsmmmesh.settings.node`);
if($node eq "")
{
$mac2 =~ s/\./-/g;
$node = "NOCALL-$mac2";
system "uci -c /etc/local/uci/ set hsmmmesh.settings.node=NOCALL-$mac2";
$commit = 1;
}
chomp ($dtdmac = `uci -c /etc/local/uci/ -q get hsmmmesh.settings.dtdmac`);
if($dtdmac eq "")
{
# We should always have an eth0 interface on all nodes.
# Not porting get_interface into this file at this time
# as on a firstboot where nvram-setup runs the interfaces
# should not be changed yet.
open(FILE, "/sbin/ifconfig eth0 |") or fail("ERROR: eth0 mac not available");
while(<FILE>)
{
next unless /\w\w:\w\w:\w\w:(\w\w):(\w\w):(\w\w)/;
$dtdmac = join ".", hex $1, hex $2, hex $3;
last;
}
close(FILE);
system "uci -c /etc/local/uci/ set hsmmmesh.settings.dtdmac=$dtdmac";
$commit = 1;
}
system "uci -c /etc/local/uci/ commit" if $commit;

View File

@ -1,163 +0,0 @@
#!/usr/bin/perl -w -I/www/cgi-bin
=for comment
Part of AREDN -- Used for creating Amateur Radio Emergency Data Networks
Copyright (C) 2015 Conrad Lara
See Contributors file for additional contributors
Copyright (c) 2013 David Rivenburg et al. BroadBand-HamNet
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation version 3 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional Terms:
Additional use restrictions exist on the AREDN(TM) trademark and logo.
See AREDNLicense.txt for more info.
Attributions to the AREDN Project must be retained in the source code.
If importing this code into a new or existing project attribution
to the AREDN project must be added to the source code.
You must not misrepresent the origin of the material contained within.
Modified versions must be modified to attribute to the original source
and be marked in reasonable ways as differentiate it from the original
version.
=cut
# this script generates the olsrd config file
# static part comes from /etc/config/olsrd.conf
# dynamic part depends on the node configuration
use perlfunc;
use ucifunc;
use tunfunc;
#Check what config file we are building for
if ( !$ARGV[0] ) {
$UCI_CONF_FILE="olsrd";
} else {
$UCI_CONF_FILE=$ARGV[0];
}
if ( $UCI_CONF_FILE eq "olsrd6" ) {
# We only generate entries for IPv4 at moment"
exit 0;
}
@names = @hosts = @services = @tunnels = ();
# canonical names for this node
# (they show up in reverse order, make the "official" name last)
push @names, $name if ($name = nvram_get("tactical"));
push @names, $name if ($name = nvram_get("node"));
# load the dhcp reservations when in dmz mode
chomp(my $dmz_mode = `/sbin/uci -q get aredn.\@dmz[0].mode`);
if($dmz_mode ne "0")
{
# add DNS aliases first
# (see above comment about "tactical" names)
foreach(`cat /etc/config.mesh/aliases.dmz`) {
next unless ($ip, $host) = split ' ', $_;
push @hosts, qq("$ip" "$host");
}
#($lanip, $lanmask, $lanbcast, $lannet) = get_ip4_network("eth0.0");
foreach(`cat /etc/ethers`)
{
#stop certain IP's from getting propagated over the mesh
($junk, $junk, $noprop) = split ' ', $_;
next if $noprop eq "#NOPROP";
next unless ($ip) = /[0-9a-f:]+\s+([\d\.]+)/i;
next unless $host = ip2hostname($ip);
push @hosts, qq("$ip" "$host");
}
}
# Add a name for the dtdlink interface.
if ($name = nvram_get("node"))
{
my ($dtdip,$dtdmask,$dtdbcast,$dtdnet);
($dtdip, $dtdmask, $dtdbcast, $dtdnet) = get_ip4_network(get_interface("dtdlink"));
push @hosts, qq("$dtdip" "dtdlink.$name.local.mesh");
}
# load the services
foreach(`cat /etc/config/services 2>/dev/null`)
{
next unless /^\w+:\/\/[\w\-\.]+:\d+(\/[^\|]*)?\|(tcp|udp)\|\w/;
chomp;
push @services, $_;
}
# load the tunnels
my @tunnelnames = @section = ();
if (-e "/etc/local/mesh-firewall/02-vtund")
{
$tunnum=50;
push(@tunnelnames, &uci_get_names_by_sectiontype("vtun","client"));
foreach (@tunnelnames)
{
$section=&uci_get_named_section("vtun",$_);
if ($section->{enabled} eq 1)
{
push(@tunnels,"tun${tunnum}");
$tunnum++;
}
}
$tunnum=50 + &get_tunnel_maxclients();
@tunnelnames=&uci_get_names_by_sectiontype("vtun","server");
foreach (@tunnelnames)
{
$section=&uci_get_named_section("vtun",$_);
if ($section->{enabled} eq 1)
{
push(@tunnels,"tun${tunnum}");
$tunnum++;
}
}
}
# add the nameservice plugin
push @file, qq(\nLoadPlugin "olsrd_nameservice.so.0.4"\n);
push @file, qq({\n);
push @file, qq( PlParam "sighup-pid-file" "/var/run/dnsmasq/dnsmasq.pid"\n);
push @file, qq( PlParam "interval" "30"\n);
push @file, qq( PlParam "timeout" "300"\n);
push @file, qq( PlParam "name-change-script" "touch /tmp/namechange"\n);
#push @file, qq( PlParam "lat" "1"\n);
#push @file, qq( PlParam "lon" "2"\n);
#push @file, qq( PlParam "laton-file" "/var/run/latlon.js"\n);
#push @file, qq( PlParam "laton-infile" "/tmp/latlon.txt"\n);
foreach(@names) { push @file, qq( PlParam "name" "$_"\n) }
foreach(@hosts) { push @file, qq( PlParam $_\n) }
foreach(@services) { push @file, qq( PlParam "service" "$_"\n) }
push @file, qq(}\n);
# add the ACTIVE tunnel interfaces
if ( @tunnels )
{
push @file, qq(\nInterface );
foreach(@tunnels) { push @file, qq("$_" ) }
push @file, qq(\n{\n);
push @file, qq( Ip4Broadcast 255.255.255.255\n);
push @file, qq( Mode \"ether\"\n);
push @file, qq(}\n);
}
# write the file
print @file;

View File

@ -1,50 +0,0 @@
#!/usr/bin/perl -w
=for comment
Part of AREDN -- Used for creating Amateur Radio Emergency Data Networks
Copyright (C) 2015 Conrad Lara
See Contributors file for additional contributors
Copyright (c) 2013 David Rivenburg et al. BroadBand-HamNet
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation version 3 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional Terms:
Additional use restrictions exist on the AREDN(TM) trademark and logo.
See AREDNLicense.txt for more info.
Attributions to the AREDN Project must be retained in the source code.
If importing this code into a new or existing project attribution
to the AREDN project must be added to the source code.
You must not misrepresent the origin of the material contained within.
Modified versions must be modified to attribute to the original source
and be marked in reasonable ways as differentiate it from the original
version.
=cut
unless(defined ($pw = shift))
{
print STDERR "\nusage: setpasswd <password>\n";
print STDERR "this sets both the system and website paswords\n\n";
exit 1;
}
$pw2 = $pw;
$pw2 =~ s/'/'\\''/g;
system "{ echo '$pw2'; sleep 1; echo '$pw2'; } | passwd > /dev/null\n";
print STDERR "passwords changed.\n";

View File

@ -1,335 +0,0 @@
#!/usr/bin/perl -w
=for comment
Part of AREDN -- Used for creating Amateur Radio Emergency Data Networks
Copyright (C) 2015 Conrad Lara
See Contributors file for additional contributors
Copyright (c) 2013 David Rivenburg et al. BroadBand-HamNet
2015-04-01 AE6XE update to display neighbor nodes, replace vendor with mode
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation version 3 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional Terms:
Additional use restrictions exist on the AREDN(TM) trademark and logo.
See AREDNLicense.txt for more info.
Attributions to the AREDN Project must be retained in the source code.
If importing this code into a new or existing project attribution
to the AREDN project must be added to the source code.
You must not misrepresent the origin of the material contained within.
Modified versions must be modified to attribute to the original source
and be marked in reasonable ways as differentiate it from the original
version.
=cut
sub usage
{
print "usage: wscan [-1abnor] [-i iface]\n";
print " -1 run once and quit\n";
print " -a average mode\n";
print " -b batch mode\n";
print " -n <num> number of times to scan\n";
print " -o show only open access points\n";
print " -r raw mode\n";
print " -w produce html output\n";
exit;
}
sub freq_to_chan
{
my ($freq) = @_;
if ($freq < 256 )
{
return $freq;
}
elsif ($freq == 2484)
{
return "14";
}
elsif ($freq == 2407)
{
return 0;
}
elsif ($freq < 2484)
{
return ($freq-2407)/5;
}
elsif ($freq < 5000)
{
return $freq ; # stay in freq, no ch #s
}
elsif ($freq < 5380) # these are 5Ghz channels 75 and below
{
return ($freq-5000)/5 ;
}
elsif ($freq < 5500) # ch 76 to 99 can only be 3Ghz freq, no part 15 here
{
return ($freq-2000); # return 3ghz freq (5ghz boards with -2Ghz transverter)
}
elsif ($freq < 6000)
{
return ($freq-5000)/5;
}
else
{
return $freq;
}
}
sub pushAP
{
my($signal, $freq, $key, $ssid, $host, $mac, $mode) = @_;
return if $mac eq "";
return if $openap and ($key ne "");
$chan=freq_to_chan($freq);
if($ssid eq "") { $ssid = "(hidden)" }
if($chan eq "") { $chan = "?" }
if($key eq "") { $key = " " }
else { $key = "*" }
if($avg)
{
$avgs{"$mac total"} += $signal;
$avgs{"$mac num"} += 1;
$aphash{$mac} = sprintf "% 3d %s %-32s\t%s\t%s\t%s\n",
$chan, $key, $ssid, $host, $mac, $mode;
}
elsif($web)
{
push @list, sprintf "% 3d|%d|%s|%s|%s|%s|%s",
$signal, $chan, $key, sprintf("&#x%*vX", '&#x',$ssid), $host, $mac, $mode;
}
else
{
push @list, sprintf "% 3d %2d %s %-32s\t%s\t%s\t%s\n",
$signal, $chan, $key, $ssid, $host, $mac, $mode;
}
}
###################################################
$avg = 0; # average mode
$batch = 0; # batch mode
$loops = 0; # number of times to run 0=inf
$raw = 0; # raw mode
$openap = 0; # show open ap's
$iface = `uci -q get 'network.wifi.ifname'`; # wireless interface
chomp $iface;
$iters = 0; # number of iterations
%avgs = (); # average statistics
%aphash = (); # list of ap's for avg mode
$mychan = `iwinfo $iface info | grep -i channel`;
$mychan =~ /Channel:\s+(-*\d+)/;
$mychan = ( ! defined $1 || ! int($1) || ! ($1 >= -4 && $1 <= 185) ) ? 0 : $1;
# ch 76 - 99 are 3ghz since no part 15 usage (5ghz board with -2ghz transverter)
if ($mychan >= 76 and $mychan <= 99)
{
$mychan = ($mychan*5+3000);
}
while(defined ($arg = shift))
{
if ($arg eq "-h") { usage() }
elsif($arg eq "-1") { $loops = 1 }
elsif($arg eq "-a") { $avg = 1 }
elsif($arg eq "-b") { $batch = 1 }
elsif($arg eq "-o") { $openap = 1 }
elsif($arg eq "-r") { $raw = 1 }
elsif($arg eq "-i") { $iface = shift }
elsif($arg eq "-n") { $loops = shift }
elsif($arg eq "-w") { $web = 1 }
else { die "bad arg $arg\n" }
}
die "bad interface" if not defined $iface;
if($raw)
{
system("iw dev $iface scan passive");
system("iw dev $iface station dump");
exit;
}
while(1)
{
$line = `egrep "['\\"].*-(5|10|20)-v[3456]" /etc/config/wireless | head -1`;
$line =~ /['"](.*-(5|10|20)-v[3456])/;
$myssid = $1;
open(FILE, "iw dev $iface scan passive 2>&1 |") or die "iw scan failed";
$mac = "";
$host = "N/A";
$lastseen = 0;
@list = ();
while($line = <FILE>)
{
if($line =~ /BSS\s+(([[:xdigit:]]{2}:){5}[[:xdigit:]]{2})/)
{
if ( $lastseen < 10000 ) { pushAP($signal, $chan, $key, $ssid, $host, $mac, $mode) }
$mac = uc $1;
$mode = "AP";
$ssid = "";
$signal = 0;
$chan = "";
$key = "";
$lastseen = 0;
}
if($line =~ /BSS(\s+)([[:xdigit:]]{2}:){5}[[:xdigit:]]{2}.*joined/)
{
$mode = "My Ad-Hoc Network";
$chan = $mychan;
}
if($line =~ /\bSSID: (.*)/) { $ssid = $1 }
if($line =~ /\bSSID: unknown/) { $ssid = "unknown" }
if($line =~ /\bcapability: (IBSS)/ and $mode eq "AP")
{ $mode = "Foreign Ad-Hoc Network" }
if($line =~ /\bfreq: (\d+)/) { $chan = $1 }
if($line =~ /\bsignal: ([\d-]+)/) { $signal = $1 }
if($line =~ /\bGroup cipher:(.+)/) { $key = $1 }
if($line =~ /\blast seen: (\d+)/) { $lastseen = $1 }
}
close(FILE);
if ( $lastseen < 10000 ) { pushAP($signal, $chan, $key, $ssid, $host, $mac, $mode) }
sleep 1 if not scalar @list and $loops != 1;
$mac = "";
$mode = "Connected Ad-Hoc Station";
$signal = 0;
$key = "";
$lastseen = 0;
++$iters;
open(FILE, "iw dev $iface station dump 2>&1 |") or die "iw failed";
while($line = <FILE>)
{
if($line =~ /Station (\S+) \(on $iface\)/)
{
if ( $lastseen < 10000 ) { pushAP($signal, $mychan, $key, $myssid, $host, $mac, $mode) }
$lastseen = 0;
$mac = $1;
$ip = `grep $mac /proc/net/arp | egrep "^10.*\$" | tail -1`;
$mac = uc $mac;
if ( $ip ne "" )
{
$ip =~ s/[ \t].*$// ;
chomp($ip);
$host = $ip;
if( $ip ne "")
{
$reverse_ip=join ".",reverse(split /\./,$ip);
foreach(`nslookup $ip`)
{
last if ($host) = /^$reverse_ip\.in-addr\.arpa[ \t]+name[ \t]+=[ \t]+(\S+)\.local\.mesh/;
}
if ( $host eq "" ) { $host = $ip }
}
}
else { $host = "????" }
}
if($line =~ /signal avg:[ \t]+([-\d]+)/) { $signal = $1 }
if($line =~ /inactive time:\t(\d+) ms/) { $lastseen = $1 }
}
close(FILE);
if ( $lastseen < 10000 ) { pushAP($signal, $mychan, $key, $myssid, $host, $mac, $mode) }
sleep 1 if not scalar @list and $loops != 1;
if(not $batch)
{
if($avg)
{
system "clear";
printf "Sig Rel Ch E SSID Hostname MAC/BSSID 802.11 Mode %6d\n", $iters;
print "--- --- -- - -------------------------------- ----------------- ------------- -----------\n";
}
elsif($web)
{
print "<table class=sortable border=1 cellpadding=5>\n";
print "<tr><th>Sig</th><th>Chan</th><th>Enc</th><th>SSID</th><th>Hostname</th><th>MAC/BSSID</th><th>802.11 Mode</th></tr>\n";
}
else
{
#system "clear";
printf "Sig Ch E SSID Hostname MAC/BSSID 802.11 Mode %6d\n", $iters;
print "--- -- - -------------------------------- --------------------- ------------- ------------\n";
}
}
if($avg)
{
open(FILE, "| sort -nr");
foreach $mac (keys %aphash)
{
printf FILE "%3d %3d %s",
($avgs{"$mac total"} - $avgs{"$mac num"} + 1)/$avgs{"$mac num"},
100*$avgs{"$mac num"}/$iters,
$aphash{$mac};
}
close(FILE);
print "\n";
}
elsif($web)
{
foreach $line (sort { $b <=> $a } @list)
{
# Match "AREDN"
if ( $line =~ /&#x41&#x52&#x45&#x44&#x4E/) { print "<tr class=\"wscan-row-node\">"}
else { print "<tr>"}
my $i = 0;
foreach $val (split /\|/, $line)
{
$val = "&nbsp;" unless $val =~ /\S/;
if($i++ == 3) { print "<td>$val</td>" }
else { print "<td align=center>$val</td>" }
}
print "<td>&nbsp;</td>" if $i < 7;
print "</tr>\n";
}
print "</table>\n";
exit;
}
else
{
open(FILE, "| sort -nr");
print FILE @list;
close(FILE);
print "\n";
}
last if --$loops == 0;
}

View File

@ -1,756 +0,0 @@
#!/usr/bin/perl
=for comment
Part of AREDN -- Used for creating Amateur Radio Emergency Data Networks
Copyright (C) 2015 Conrad Lara
See Contributors file for additional contributors
Copyright (c) 2013 David Rivenburg et al. BroadBand-HamNet
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation version 3 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional Terms:
Additional use restrictions exist on the AREDN(TM) trademark and logo.
See AREDNLicense.txt for more info.
Attributions to the AREDN Project must be retained in the source code.
If importing this code into a new or existing project attribution
to the AREDN project must be added to the source code.
You must not misrepresent the origin of the material contained within.
Modified versions must be modified to attribute to the original source
and be marked in reasonable ways as differentiate it from the original
version.
=cut
BEGIN {push @INC, '/www/cgi-bin'};
use perlfunc;
sub firmware_list_gen
{
@fw_images = ();
chomp($fw_version = `cat /etc/mesh-release`);
foreach(`cat /tmp/web/firmware.list 2>/dev/null`)
{
my($md5, $fw, $tag) = /^(\S+) (\S+) (.*)/;
next unless $tag;
next if $tag eq "none";
next unless ($tag eq "all") or ($tag eq "dev" and $parms{dev}) or ($fw_version =~ /$tag/);
push @fw_images, $fw;
$fw_md5{$fw} = $md5;
}
}
$debug = 0;
$| = 1;
$tunnel_active= 0;
if ( -e "/usr/sbin/vtund" && open(my $tuncfgfd, '/etc/config/vtun')) {
while ( my $line = <$tuncfgfd> ) {
if ( $line =~ /option enabled '1'/i ) {
$tunnel_active = 1;
last;
}
}
}
if ( $tunnel_active ) {
read_postdata({acceptfile => false});
} else {
read_postdata({acceptfile => true});
}
reboot_page("/cgi-bin/status") if $parms{button_reboot};
read_query_string();
$node = nvram_get("node");
$tmpdir = "/tmp/web/admin";
system "mkdir -p $tmpdir";
# make developer mode stick
system "touch /tmp/developer_mode" if $parms{dev};
$parms{dev} = 1 if -e "/tmp/developer_mode";
# set the wget command options
$wget = "wget -U 'node: $node'";
#
# handle firmware updates
#
$fw_install = 0;
$patch_install = 0;
@fw_output = ();
@fw_images = ();
%fw_md5 = ();
@serverpaths = ();
$uciserverpath=`uci get aredn.\@downloads[0].firmwarepath`;
chomp($uciserverpath);
push @serverpaths, $uciserverpath;
${hardwaretype} = `/usr/local/bin/get_hardwaretype`;
chomp(${hardwaretype});
${targettype} = `ubus call system board | jsonfilter -e '@["release"].target'`;
chomp(${targettype});
# handle TPLink and Mikrotik exception conditions
$mfg=`/usr/local/bin/get_hardware_mfg`;
chomp($mfg);
$mfgprefix="";
if($mfg=~ /Ubiquiti/i)
{
$mfgprefix="ubnt";
} elsif($mfg=~ /Mikrotik/i) {
$mfgprefix="mikrotik";
} elsif($mfg=~ /TP-Link/i) {
$mfgprefix="cpe";
}
# refresh fw
if($parms{button_refresh_fw})
{
if((get_default_gw() ne "none") || ($uciserverpath =~ ".local.mesh"))
{
push @fw_output, "Downloading firmware list from $uciserverpath...\n";
unlink "/tmp/web/firmware.list";
$ok = 0;
foreach $serverpath (@serverpaths)
{
system "$wget -O /tmp/web/firmware.list $serverpath/firmware.${hardwaretype}.list >/dev/null 2>>$tmpdir/wget.err";
unless($?) { $ok = 1; last }
}
if($ok) { push @fw_output, "Done.\n" }
else { push @fw_output, `cat $tmpdir/wget.err` }
unlink "$tmpdir/wget.err";
}
else
{
push @fw_output, "Error: no route to Host\n";
unlink "/tmp/web/firmware.list";
}
}
# generate data structures
# and set $fw_version
firmware_list_gen();
# upload fw
if($parms{button_ul_fw} and -f "/tmp/web/upload/file")
{
system "mv -f /tmp/web/upload/file $tmpdir/firmware";
if($parms{firmfile} =~ /sysupgrade\.bin$/) # full firmware
{
$fw_install = 1;
# drop the page cache to take pressure of tmps when checking the firmware
`echo 3 > /proc/sys/vm/drop_caches`;
# check firmware header
if(system "/usr/local/bin/firmwarecheck.sh $tmpdir/firmware")
{
push @fw_output, "Firmware CANNOT be updated\n";
push @fw_output, "firmware file is not valid\n";
$fw_install = 0;
unlink("$tmpdir/firmware");
system("/usr/local/bin/uploadctlservices","restore") and push @fw_output, "Failed to restart all services, please reboot this node.\n";
}
}
elsif($parms{firmfile} =~ /^patch\S+\.tgz$/) # firmware patch
{
$patch_install = 1;
}
else
{
push @fw_output, "Firmware CANNOT be updated\n";
push @fw_output, "the uploaded file is not recognized\n";
unlink("$tmpdir/firmware");
system("/usr/local/bin/uploadctlservices","restore") and push @fw_output, "Failed to restart all services, please reboot this node.\n";
}
}
# download fw
if($parms{button_dl_fw} and $parms{dl_fw} ne "default")
{
if((get_default_gw() ne "none") || ($uciserverpath =~ ".local.mesh"))
{
unlink "$tmpdir/firmware";
system("/usr/local/bin/uploadctlservices","upgrade");
$ok = 0;
foreach $serverpath (@serverpaths)
{
system "$wget -O $tmpdir/firmware $serverpath/$parms{dl_fw} >/dev/null 2>>$tmpdir/wget.err";
unless($?) { $ok = 1; last }
}
if($parms{dl_fw} =~ /sysupgrade\.bin$/) # full firmware
{
$fw_install = 1;
unless($ok)
{
push @fw_output, "Downloading firmware image...\n";
push @fw_output, `cat $tmpdir/wget.err`;
}
unlink "$tmpdir/wget.err";
# check md5sum
$fw = $parms{dl_fw};
chdir $tmpdir;
if(system "echo '$fw_md5{$fw} firmware' | md5sum -cs")
{
push @fw_output, "Firmware CANNOT be updated\n";
push @fw_output, "firmware file is not valid\n";
$fw_install = 0;
unlink("$tmpdir/firmware");
system("/usr/local/bin/uploadctlservices","restore") and push @fw_output, "Failed to restart all services, please reboot this node.\n";
}
}
elsif($parms{dl_fw} =~ /^patch\S+\.tgz$/) # firmware patch
{
$patch_install = 1;
unless($ok)
{
push @fw_output, "Downloading patch file...\n";
push @fw_output, `cat $tmpdir/wget.err`;
}
unlink "$tmpdir/wget.err";
# check md5sum
$fw = $parms{dl_fw};
chdir $tmpdir;
if(system "echo '$fw_md5{$fw} firmware' | md5sum -cs")
{
push @fw_output, "Firmware CANNOT be updated\n";
push @fw_output, "patch file is not valid\n";
$patch_install = 0;
unlink("$tmpdir/firmware");
system("/usr/local/bin/uploadctlservices","restore") and push @fw_output, "Failed to restart all services, please reboot this node.\n";
}
}
else
{
push @fw_output, "Firmware CANNOT be updated\n";
push @fw_output, "the downloaded file is not recognized\n";
unlink("$tmpdir/firmware");
system("/usr/local/bin/uploadctlservices","restore") and push @fw_output, "Failed to restart all services, please reboot this node.\n";
}
}
else
{
push @fw_output, "Error: no route to Host\n";
unlink "/tmp/web/firmware.list";
}
}
# install fw
if($fw_install and -f "$tmpdir/firmware")
{
my $junk;
http_header();
html_header("FIRMWARE UPDATE IN PROGRESS", 0);
print "<meta http-equiv='refresh' content='180;URL=http://$node.local.mesh:8080'>";
print "</head>\n";
print "<body><center>\n";
print "<h2>The firmware is being updated.</h2>\n";
print "<h1>DO NOT REMOVE POWER UNTIL UPDATE IS FINISHED</h1>\n";
print "</center><br>\n";
unless($debug)
{
# drop the page cache to take pressure of tmps for the upgrade process
`echo 3 > /proc/sys/vm/drop_caches`;
`/usr/local/bin/upgrade_kill_prep`;
if ( $parms{checkbox_keep_settings} )
{
print "
<center><h2>Firmware will be written in the background.</h2>
<h3>If your computer is connected to the LAN of this node you may need to acquire<br>
a new IP address and reset any name service caches you may be using.</h3>
<h3>The node will reboot twice while the configuration is applied<br>
When the node has finished booting you should ensure your computer has<br>
received a new IP address and reconnect with<br>
<a href='http://$node.local.mesh:8080/'>http://$node.local.mesh:8080/</a><br>
(This page will automatically reload in 3 minutes)</h3>
</center></body></html>
";
open (my $SYSUPGRADECONF, "/etc/arednsysupgrade.conf") or die "Failed to open arednsysupgrade.conf";
open (my $TMPSYSUPGRADECONF, '>', "/tmp/sysupgradefilelist") or die "Failed to open TMPSYSUPGRADECONF";
while (<$SYSUPGRADECONF>){
chomp;
next if /^\#/ ;
if ( -e "$_" ) {
print $TMPSYSUPGRADECONF "$_\n";
}
}
close $SYSUPGRADECONF;
close $TMPSYSUPGRADECONF;
nvram_set("nodeupgraded","1");
system("tar -czf /tmp/arednsysupgradebackup.tgz -T /tmp/sysupgradefilelist");
if ($? != 0) {
print "
<center><h2>ERROR: Could not backup filesystem.</h2>
<h3>An error occured trying to backup the file system. Node will now reboot.
</center>
";
page_footer();
print "</body></html>";
nvram_set("nodeupgraded","0");
system "/sbin/reboot";
exit 1;
}
system("rm -f /tmp/sysupgradefilelist");
`/usr/local/bin/spawn_sysupgrade $tmpdir/firmware 2>&1 &`;
}
else
{
print "
<center><h2>Firmware will be written in the background.</h2>
<h3>If your computer is connected to the LAN of this node you may need to acquire<br>
a new IP address and reset any name service caches you may be using.</h3>
<h3>The node will reboot after the firmware has been written to flash memory<br>
When the node has finished booting you should ensure your computer has<br>
received a new IP address and reconnect with<br>
<a href='http://localnode.local.mesh:8080/'>http://192.168.1.1:8080/</a><br>
and continue setup of the node in firstboot state.<br>
(This page will automatically reload in 3 minutes)</h3>
</center></body></html>
";
`/sbin/sysupgrade -n $tmpdir/firmware 2>&1 &`;
}
`killall uhttpd &`;
exit;
}
}
# install patch
if($patch_install and -f "$tmpdir/firmware")
{
@fw_output = ();
for($fail = 1; ; )
{
# check available space
chomp ($size = `gunzip -c $tmpdir/firmware | wc -c`);
$size = int(($size + 1023) / 1024);
if(get_free_space("/tmp") - $size < 100)
{
push @fw_output, "Firmware CANNOT be patched\n";
push @fw_output, "insufficient /tmp space\n";
push @fw_output, "try again after a reboot\n";
last;
}
elsif(get_free_space("/overlay") - $size < 100)
{
push @fw_output, "Firmware CANNOT be patched\n";
push @fw_output, "insufficient flash space\n";
push @fw_output, "a full firmware install is required\n";
last;
}
# make it so
unlink "$tmpdir/patch.err";
unlink "$tmpdir/patch.out";
last if system "mkdir -p $tmpdir/patch 2>>$tmpdir/patch.err";
last if not chdir "$tmpdir/patch";
last if system "tar xzf $tmpdir/firmware 2>>$tmpdir/patch.err";
unless(-f "files.tar")
{
push @fw_output, "Firmware CANNOT be updated\n";
push @fw_output, "patch file is not valid\n";
last;
}
last if -x "pre-install" and system "./pre-install >>$tmpdir/patch.out 2>>$tmpdir/patch.err";
last if system "tar xvf files.tar -C / >>$tmpdir/patch.out 2>>$tmpdir/patch.err";
last if -x "post-install" and system "./post-install >>$tmpdir/patch.out 2>>$tmpdir/patch.err";
reboot_page("/cgi-bin/status") if -f "reboot";
firmware_list_gen(); # mesh-release has changed so regenerate the firmware list
$fail = 0;
last;
}
if($fail)
{
unless(@fw_output)
{
push @fw_output, "Firmware patch failed. This is very bad.\n";
push @fw_output, "You should probably reinstall the full firmware.\n";
push @fw_output, `cat $tmpdir/patch.err 2>/dev/null`;
}
}
else
{
push @fw_output, "Installing patch...\n";
push(@fw_output, `cat $tmpdir/patch.out`) if $parms{dev};
push @fw_output, "Done.\n";
}
unlink("$tmpdir/firmware");
system("/usr/local/bin/uploadctlservices","restore") and push @fw_output, "Failed to restart all services, please reboot this node.\n";
}
#
# handle package actions
#
@pkg_output = ();
# load permanent package list
foreach(`cat /etc/permpkg 2>/dev/null`)
{
next if /^#/;
chomp;
$permpkg{$_} = 1;
}
# upload package
if($parms{button_ul_pkg} and -f "/tmp/web/upload/file")
{
system "mv -f /tmp/web/upload/file /tmp/web/upload/newpkg.ipk";
push @pkg_output, `opkg -force-overwrite install /tmp/web/upload/newpkg.ipk 2>&1`;
system "rm -rf /tmp/opkg-*";
unlink("/tmp/web/upload/newpkg.ipk");
system("/usr/local/bin/uploadctlservices","restore") and push @pkg_output, "Failed to restart all services, please reboot this node.\n";
}
# download package
$meshpkgs = system('grep -q ".local.mesh" /etc/opkg/distfeeds.conf');
if($parms{button_dl_pkg} and $parms{dl_pkg} ne "default")
{
if((get_default_gw() ne "none") || (!$meshpkgs))
{
system("/usr/local/bin/uploadctlservices","opkginstall");
push @pkg_output, `opkg -force-overwrite install $parms{dl_pkg} 2>&1`;
system("/usr/local/bin/uploadctlservices","restore") and push @pkg_output, "Failed to restart all services, please reboot this node.\n";
}
else
{
push @pkg_output, "Error: no route to Host\n";
}
}
# refresh package list
if($parms{button_refresh_pkg})
{
if((get_default_gw() ne "none") || (!$meshpkgs))
{
@pkg_output = `opkg update 2>&1`;
system "opkg list | grep -v '^ ' | cut -f1,3 -d' ' | gzip -c > /etc/opkg.list.gz";
}
else
{
push @pkg_output, "Error: no route to Host\n";
}
}
# remove package
if($parms{button_rm_pkg} and $parms{rm_pkg} ne "default" and not $permpkg{$parms{rm_pkg}})
{
@pkg_output = `opkg remove $parms{rm_pkg} 2>&1`;
if (! $?) {
push @pkg_output, "Package removed succssfully";
}
}
# generate data structures
@pkgs = ();
%pkgver = ();
foreach(`opkg list_installed | cut -f1,3 -d' '`)
{
($pkg, $ver) = split /\s/, $_;
next unless $ver;
push @pkgs, $pkg;
$pkgver{$pkg} = $ver;
}
@dl_pkgs = ();
%dlpkgver = ();
foreach(`zcat /etc/opkg.list.gz 2>/dev/null`)
{
($pkg, $ver) = split /\s/, $_;
next unless $ver;
next if $pkgver{$pkg} and $pkgver{$pkg} eq $ver;
push @dl_pkgs, $pkg;
$dlpkgver{$pkg} = $ver;
}
#
# handle ssh key actions
#
@key_output = ();
$keyfile = "/etc/dropbear/authorized_keys";
# upload key
if($parms{button_ul_key} and -f "/tmp/web/upload/file")
{
$count = `wc -l $keyfile 2>/dev/null`;
system "grep ^ssh- /tmp/web/upload/file >> $keyfile";
if($count eq `wc -l $keyfile`)
{
push @key_output, "Error: file does not appear to be an ssh key file\n";
push @key_output, "Authorized keys not changed.\n";
}
else
{
push @key_output, "Key installed.\n";
}
unlink("/tmp/web/upload/file");
system("/usr/local/bin/uploadctlservices","restore") and push @key_output, "Failed to restart all services, please reboot this node.\n";
}
# remove key
if($parms{button_rm_key} and $parms{rm_key} ne "default" and -f $keyfile)
{
$count = `wc -l $keyfile`;
system "grep -v '$parms{rm_key}' $keyfile > $tmpdir/keys";
system "mv -f $tmpdir/keys $keyfile";
if($count eq `wc -l $keyfile`)
{
push @key_output, "Error: authorized keys were not changed.\n";
}
else
{
push @key_output, "Key $parms{rm_key} removed.\n";
}
}
# generate data structures
@keys = ();
open(FILE, ">$tmpdir/newkeys");
foreach(`cat $keyfile 2>/dev/null`)
{
($type, $key, $who, $extra) = split /\s+/, $_;
next if $extra;
next unless $who =~ /.\@./;
next unless $type =~ /^ssh-/;
push @keys, $who;
print FILE "$type $key $who\n";
}
close(FILE);
# sanitize the key file
if(-f $keyfile and system "diff $keyfile $tmpdir/newkeys >/dev/null 2>&1")
{
system "mv -f $tmpdir/newkeys $keyfile";
push @key_output, "Info: key file sanitized.\n";
}
# clean up
system "rm -rf /tmp/web/upload $tmpdir" unless $debug;
#
# generate the page
#
http_header();
html_header("$node administration", 1);
print "<body><center>\n";
alert_banner();
print "<form method=post action=admin.pl enctype='multipart/form-data'>\n";
print "<table width=790>\n";
print "<tr><td>\n";
navbar("admin");
print "</td></tr>\n";
print "<tr><td align=center><a href='/help.html#admin' target='_blank'>Help</a>&nbsp;&nbsp;";
print "<input type=submit name=button_reboot value=Reboot style='font-weight:bold' title='Immediately reboot this node'>";
print "</td></tr>\n";
print "<tr><td align=center>\n";
print "<table cellspacing=10>\n";
#
# firmware
#
print "<tr><td align=center>\n";
print "<table cellspacing=10>\n";
print "<tr><th colspan=3>Firmware Update</th></tr>\n";
if(@fw_output)
{
print "<tr><td colspan=3 align=center><table><tr><td><b><pre>\n";
print word_wrap(80, @fw_output);
print "</pre></b></td></tr></table></td></tr>\n";
}
print "<tr><td align=center colspan=3>current version: $fw_version</td></tr>\n";
print "<tr><td align=center colspan=3>hardware type: (${targettype}) $mfgprefix (${hardwaretype})</td></tr>\n";
print "<tr>\n";
print "<td>Upload Firmware</td>\n";
print "<td><input type=file name=firmfile title='choose the firmware file to install from your hard drive' accept='.bin'></td>\n";
print "<td align=center><input type=submit name=button_ul_fw value=Upload title='install the firmware'";
if($tunnel_active) {
print " disabled><br><small>Disabled: Tunnels enabled</small>";
} else {
print ">";
}
print "</td>\n";
print "</tr>\n";
print "<tr>\n";
print "<td>Download Firmware</td>\n";
print "<td><select name=dl_fw style='font-family:monospace'>\n";
selopt("- Select Firmware -", "default", "default");
foreach(@fw_images)
{
selopt($_, $_, "default");
}
print "</select>\n";
print "<input type=submit name=button_refresh_fw value=Refresh title='download the list of available firmware versions'>\n";
print "<td align=center><input type=submit name=button_dl_fw value=Download title='install the firmware'></td>\n";
print "<td align=right><input type=checkbox name=checkbox_keep_settings checked>Keep Settings</td>\n";
print "</tr>\n";
print "</table></td></tr>\n";
print "<tr><td colspan=3><hr></td></tr>\n";
#
# packages
#
print "<tr><td align=center>\n";
print "<table cellspacing=10>\n";
print "<tr><th colspan=3>Package Management</th></tr>\n";
if(@pkg_output)
{
# opkg can produce duplicate first lines, remove them here
while(defined $pkg_output[1] and $pkg_output[0] eq $pkg_output[1])
{
shift @pkg_output;
}
print "<tr><td colspan=3 align=center><table><tr><td><b><pre>\n";
print word_wrap(80, @pkg_output);
print "</pre></b></td></tr></table></td></tr>\n";
}
print "<tr>\n";
print "<td>Upload Package</td>\n";
print "<td><input type=file name=ul_pkg title='choose the .ipk file to install from your hard drive'> </td>\n";
print "<td align=center><input type=submit name=button_ul_pkg value=Upload title='install the package'";
if($tunnel_active) {
print " disabled><br><small>Disabled: Tunnels enabled</small>";
} else {
print ">";
}
print "</td>\n";
print "</tr>\n";
print "<tr>\n";
print "<td>Download Package</td>\n";
print "<td><select name=dl_pkg style='font-family:monospace'>\n";
selopt("- Select Package -", "default", "default");
foreach $pkg (@dl_pkgs)
{
selopt("$pkg $dlpkgver{$pkg}", $pkg, "default");
}
print "</select>\n";
print "<input type=submit name=button_refresh_pkg value=Refresh title='download the list of available packages (warning: this takes a lot of space)'>\n";
print "<td align=center><input type=submit name=button_dl_pkg value=Download title='install the package'></td>\n";
print "</tr>\n";
print "<tr>\n";
print "<td>Remove Package</td>\n";
print "<td><select name=rm_pkg style='font-family:monospace'>\n";
selopt("- Select Package -", "default", "default");
foreach $pkg (@pkgs)
{
$opt = $permpkg{$pkg} ? "disabled" : "";
selopt("$pkg $pkgver{$pkg}", $pkg, "default", $opt);
}
print "</select></td>\n";
print "<td align=center><input type=submit name=button_rm_pkg value=Remove title='remove the selected package'></td>\n";
print "</tr>\n";
print "</table></td></tr>\n";
print "<tr><td colspan=3><hr></td></tr>\n";
#
# ssh keys
#
print "<tr><td align=center>\n";
print "<table cellspacing=10>\n";
print "<tr><th colspan=3>Authorized SSH Keys</th></tr>\n";
if(@key_output)
{
print "<tr><td colspan=3 align=center><table><tr><td><b><pre>\n";
print word_wrap(80, @key_output);
print "</pre></b></td></tr></table></td></tr>\n";
}
print "<tr>\n";
print "<td>Upload Key</td>\n";
print "<td><input type=file name=sshkey title='choose the id_rsa.pub file to install from your hard drive'></td>\n";
print "<td align=center><input type=submit name=button_ul_key value=Upload title='install the key'";
print "></td>\n";
print "</tr>\n";
print "<tr>\n";
print "<td>Remove Key</td>\n";
print "<td><select name=rm_key style='font-family:monospace'>\n";
selopt("- Select Key -", "default", "default");
foreach(@keys)
{
selopt($_, $_, "default");
}
print "</select>\n";
print "<td align=center><input type=submit name=button_rm_key value=Remove title='remove the selected key'></td>\n";
print "</tr>\n";
print "</table></td></tr>\n";
print "<tr><td colspan=3><hr></td></tr>\n";
print "<tr><th colspan=3>Support Data</th></tr>\n";
print "<tr><td colspan=3 align=center><a href=/cgi-bin/supporttool>Download Support Data</a></td></tr>\n";
print "<tr><td colspan=3><hr></td></tr>\n";
print "</table>\n";
print "</td></tr>\n";
print "</table>\n";
print "<input type=hidden name=dev value=1>\n" if $parms{dev};
print "</form>\n";
print "</center>\n";
show_debug_info();
show_parse_errors();
page_footer();
print "</body>\n";
print "</html>\n";

View File

@ -1,561 +0,0 @@
#!/usr/bin/perl
=for comment
Part of AREDN -- Used for creating Amateur Radio Emergency Data Networks
Copyright (C) 2020 - Darryl Quinn
See Contributors file for additional contributors
Copyright (c) 2013 David Rivenburg et al. BroadBand-HamNet
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation version 3 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional Terms:
Additional use restrictions exist on the AREDN(TM) trademark and logo.
See AREDNLicense.txt for more info.
Attributions to the AREDN Project must be retained in the source code.
If importing this code into a new or existing project attribution
to the AREDN project must be added to the source code.
You must not misrepresent the origin of the material contained within.
Modified versions must be modified to attribute to the original source
and be marked in reasonable ways as differentiate it from the original
version.
=cut
BEGIN {push @INC, '/www/cgi-bin'};
use perlfunc;
use ucifunc;
use tunfunc;
$debug = 0;
$| = 1;
# ---------------------------------------- ADVANCED CONFIG ALLOWED UCI VALUES ------------------
@setting = ();
push @setting, {
key => "aredn.\@map[0].maptiles",
type => "string",
desc => "Specifies the URL of the location to access map tiles",
default => "http://stamen-tiles-{s}.a.ssl.fastly.net/terrain/{z}/{x}/{y}.jpg"
};
push @setting, {
key => "aredn.\@map[0].leafletcss",
type => "string",
desc => "Specifies the URL of the leaflet.css file",
default => "http://cdn.leafletjs.com/leaflet/v0.7.7/leaflet.css"
};
push @setting, {
key => "aredn.\@map[0].leafletjs",
type => "string",
desc => "Specifies the URL of the leaflet.js file",
default => "http://cdn.leafletjs.com/leaflet/v0.7.7/leaflet.js"
};
push @setting, {
key => "aredn.\@downloads[0].firmwarepath",
type => "string",
desc => "Specifies the URL of the location from which firmware files will be downloaded.",
default => "http://downloads.arednmesh.org/firmware"
};
push @setting, {
key => "aredn.\@downloads[0].pkgs_core",
type => "string",
desc => "Specifies the URL for the 'core' packages: kernel modules and the like",
default => defaultPackageRepos('aredn_core'),
postcallback => "writePackageRepo('core')"
};
push @setting, {
key => "aredn.\@downloads[0].pkgs_base",
type => "string",
desc => "Specifies the URL for the 'base' packages: libraries, shells, etc.",
default => defaultPackageRepos('base'),
postcallback => "writePackageRepo('base')"
};
push @setting, {
key => "aredn.\@downloads[0].pkgs_arednpackages",
type => "string",
desc => "Specifies the URL for the 'arednpackages' packages: vtun, etc.",
default => defaultPackageRepos('arednpackages'),
postcallback => "writePackageRepo('arednpackages')"
};
push @setting, {
key => "aredn.\@downloads[0].pkgs_luci",
type => "string",
desc => "Specifies the URL for the 'luci' packages: luci and things needed for luci.",
default => defaultPackageRepos('luci'),
postcallback => "writePackageRepo('luci')"
};
push @setting, {
key => "aredn.\@downloads[0].pkgs_packages",
type => "string",
desc => "Specifies the URL for the 'packages' packages: everything not included in the other dirs.",
default => defaultPackageRepos('packages'),
postcallback => "writePackageRepo('packages')"
};
push @setting, {
key => "aredn.\@downloads[0].pkgs_routing",
type => "string",
desc => "Specifies the URL for the 'routing' packages: olsr, etc.",
default => defaultPackageRepos('routing'),
postcallback => "writePackageRepo('routing')"
};
push @setting, {
key => "aredn.\@downloads[0].pkgs_telephony",
type => "string",
desc => "Specifies the URL for the 'telephony' packages.",
default => defaultPackageRepos('telephony'),
postcallback => "writePackageRepo('telephony')"
};
push @setting, {
key => "aredn.\@downloads[0].pkgs_freifunk",
type => "string",
desc => "Specifies the URL for the 'freifunk' packages.",
default => defaultPackageRepos('freifunk'),
postcallback => "writePackageRepo('freifunk')"
};
push @setting, {
key => "aredn.\@poe[0].passthrough",
type => "boolean",
desc => "Specifies whether a PoE passthrough port should be on or off. (Not all devices have PoE passthrough ports.",
default => "0",
condition => "hasPOE()",
postcallback => "setPOEOutput()"
};
push @setting, {
key => "aredn.\@usb[0].passthrough",
type => "boolean",
desc => "Specifies whether the USB port should be on or off. (Not all devices have USB powered ports.",
default => "1",
postcallback => "setUSBOutput()",
condition => "hasUSB()"
};
my $tunnelLimitsUpperBound = 100; # maxclients/maxservers cannot exceed this value
push @setting, {
key => "aredn.\@tunnel[0].maxclients",
type => "string",
desc => "Specifies the maximum number of tunnel clients this node can serve; must be an integer in the range [0,$tunnelLimitsUpperBound]. (Only applies if tunnel software is installed)",
default => "10",
condition => "hasTunnelSoftware()",
precallback => "restrictTunnelLimitToValidRange",
postcallback => "adjustTunnelInterfaceCount()"
};
push @setting, {
key => "aredn.\@tunnel[0].maxservers",
type => "string",
desc => "Specifies the maximum number of tunnel servers to which this node can connect; must be an integer in the range [0,$tunnelLimitsUpperBound]. (Only applies if tunnel software is installed)",
default => "10",
condition => "hasTunnelSoftware()",
precallback => "restrictTunnelLimitToValidRange",
postcallback => "adjustTunnelInterfaceCount()"
};
push @setting, {
key => "aredn.\@meshstatus[0].lowmem",
type => "string",
desc => "Specifies the low memory threshold (in KB) when we will truncate the mesh status page",
default => "10000"
};
push @setting, {
key => "aredn.\@meshstatus[0].lowroutes",
type => "string",
desc => "When low memory is detected, limit the number of routes shown on the mesh status page",
default => "1000"
};
push @setting, {
key => "aredn.olsr.restart",
type => "none",
desc => "Will restart OLSR when saving setting -- wait up to 2 or 3 minutes to receive response.",
default => "0",
postcallback => "olsr_restart()"
};
push @setting, {
key => "aredn.aam.refresh",
type => "none",
desc => "Attempt to pull any AREDN Alert messages.",
default => "0",
postcallback => "aam_refresh()"
};
push @setting, {
key => "aredn.\@alerts[0].localpath",
type => "string",
desc => "Specifies the URL of the location from which local AREDN Alerts can be downloaded.",
default => ""
};
push @setting, {
key => "aredn.aam.purge",
type => "none",
desc => "Immediately purge/delete all AREDN (and local) Alerts from this node.",
default => "",
postcallback => "alert_purge()"
};
# ----------------------------------------
# ----- CONDITIONS ----------
sub hasPOE()
{
$pin=`cat /etc/board.json|jsonfilter -e '@.gpioswitch.poe_passthrough.pin'`;
chomp($pin);
return $pin ? return 1 : return 0;
}
sub hasUSB()
{
$pin=`cat /etc/board.json|jsonfilter -e '@.gpioswitch.usb_power_switch.pin'`;
chomp($pin);
return $pin ? return 1 : return 0;
}
sub hasTunnelSoftware()
{
return (-e "/usr/sbin/vtund") ? 1 : 0;
}
# ----- CONDITIONS ----------
# ----- CALLBACKS ----------
sub setPOEOutput()
{
$newval="0" if(!$newval);
system("/usr/local/bin/poe_passthrough",$newval);
}
sub setUSBOutput()
{
$newval="0" if(!$newval);
system("/usr/local/bin/usb_passthrough",$newval);
}
sub olsr_restart()
{
$rc=`/etc/init.d/olsrd restart`;
return $rc;
}
sub aam_refresh()
{
$rc=`/usr/local/bin/aredn_message.sh`;
return $rc;
}
sub alert_purge()
{
unlink("/tmp/aredn_message");
unlink("/tmp/local_message");
return 0;
}
sub writePackageRepo {
my $repo = @_[0];
my $uciurl = `uci get aredn.\@downloads[0].pkgs_$repo`;
chomp($uciurl);
my $file = '/etc/opkg/distfeeds.conf';
my $disturl = `grep aredn_$repo /etc/opkg/distfeeds.conf | cut -d' ' -f3`;
chomp($disturl);
system("sed -i 's|$disturl|$uciurl|g' $file");
}
sub restrictTunnelLimitToValidRange() {
$newval =~ s/^\s+|\s+$//g;
if ($newval !~ /^\s*-?\d+\s*$/) {
push @msg, "$key must be an integer in the range [0,$tunnelLimitsUpperBound]";
$newval = 0
} elsif ($newval < 0) {
push @msg, "Lower limit of $key is 0";
$newval = 0
} elsif ($newval > $tunnelLimitsUpperBound) {
push @msg, "Upper limit of $key is $tunnelLimitsUpperBound";
$newval = $tunnelLimitsUpperBound
}
}
sub addTunnelInterface() {
my ($configfile, $tunnum) = @_;
&uci_add_named_section($configfile,"tun${tunnum}","interface");
&uci_set_named_option($configfile,"tun${tunnum}","ifname","tun${tunnum}");
&uci_set_named_option($configfile,"tun${tunnum}","proto","none");
}
sub adjustTunnelInterfaceCount() {
my $tunnelIfCount = &get_tunnel_interface_count();
my $neededIfCount = &get_tunnel_maxclients() + &get_tunnel_maxservers();
if ($tunnelIfCount != $neededIfCount) {
for (my $i = $tunnelIfCount; $i < $neededIfCount; $i++) {
my $tunnum = $i + 50;
&addTunnelInterface("network_tun",$tunnum);
&addTunnelInterface("network",$tunnum);
}
for (my $i = $tunnelIfCount - 1; $i >= $neededIfCount; $i--) {
my $tunnum = $i + 50;
&uci_delete_named_section("network_tun","tun${tunnum}");
&uci_delete_named_section("network","tun${tunnum}");
}
&uci_commit("network_tun");
&uci_commit("network");
&uci_clone("network_tun");
# can't clone network because it contains macros; re-edit it instead:
system "sed -i"
. " -e '\$r /etc/config.mesh/network_tun'"
. " -e '/interface.*tun/,\$d'"
. " /etc/config.mesh/network";
}
}
# ----- CALLBACKS ----------
read_postdata({acceptfile => false});
if($parms{button_firstboot})
{
system "firstboot -y";
reboot_page("/cgi-bin/status");
}
reboot_page("/cgi-bin/status") if $parms{button_reboot};
$node = nvram_get("node");
# make developer mode stick
system "touch /tmp/developer_mode" if $parms{dev};
$parms{dev} = 1 if -e "/tmp/developer_mode";
#
# process POSTED data
#
$scount = scalar @setting;
for($i=0;$i<$scount;$i++)
{
if($parms{eval "button_save_" . $i})
{
$newvalfield=eval "newval_" . $i;
$newval=$parms{$newvalfield};
$newval=~ s/^\s+|\s+$//;
if ($setting[$i]->{'type'} eq "boolean")
{
if ($newval)
{
$newval="1";
}
else
{
$newval="0";
}
}
$key=$setting[$i]->{'key'};
@x=split(/\./, $setting[$i]->{'key'});
$cfgfile=$x[0];
# run precallbacks
eval $setting[$i]->{'precallback'} if($setting[$i]->{'precallback'});
# set "live" settings
system("uci set '$key=$newval'");
system("uci commit '$cfgfile'");
# set AREDN config settings (used after a "Save Settings" on the Setup page)
system("uci -S -c /etc/config.mesh set '$key=$newval'");
system("uci -S -c /etc/config.mesh commit '$cfgfile'");
push @msg, "Changed $key";
# run postcallbacks
eval $setting[$i]->{'postcallback'} if($setting[$i]->{'postcallback'});
last;
}
}
#
# generate the page
#
http_header();
html_header("$node Advanced Configuration", 0);
print <<EOF;
<style>
/* The switch - the box around the slider */
.switch {
position: relative;
display: inline-block;
width: 60px;
height: 34px;
}
/* Hide default HTML checkbox */
.switch input {
opacity: 0;
width: 0;
height: 0;
}
/* The slider */
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
-webkit-transition: .4s;
transition: .4s;
}
.slider:before {
position: absolute;
content: "";
height: 26px;
width: 26px;
left: 4px;
bottom: 4px;
background-color: white;
-webkit-transition: .4s;
transition: .4s;
}
input:checked + .slider {
background-color: #2196F3;
}
input:focus + .slider {
box-shadow: 0 0 1px #2196F3;
}
input:checked + .slider:before {
-webkit-transform: translateX(26px);
-ms-transform: translateX(26px);
transform: translateX(26px);
}
/* Rounded sliders */
.slider.round {
border-radius: 34px;
}
.slider.round:before {
border-radius: 50%;
}
</style>
<script>
function toggleDefault(fname, defval) {
if(document.getElementById(fname).checked) {
cval = '1'
} else {
cval = '0'
}
if(cval != defval) {
document.getElementById(fname).click();
}
return true;
}
</script>
</head>
EOF
print "<body><center>\n";
alert_banner();
print "<div style=\"padding:5px;background-color:#FF0000;color:#FFFFFF;width:650px;\"><strong>WARNING:</strong> Changing advanced settings can be harmful to the stability, security, and performance of this node and potentially the entire mesh network.<br><strong>You should only continue if you are sure of what you are doing.</strong></div>\n";
print "<form method=post action=advancedconfig enctype='multipart/form-data'>\n";
print "<table width=790>\n";
print "<tr><td>\n";
navbar("advancedconfig");
print "</td></tr>\n";
print "<tr><td align=center><a href='/help.html#advancedconfig' target='_blank'>Help</a>&nbsp;&nbsp;";
print "<input type=submit name=button_reboot value=Reboot style='font-weight:bold' title='Immediately reboot this node'>";
print "&nbsp;&nbsp;<input type=submit name=button_firstboot value='Reset to Firstboot' onclick=\"return confirm('All config settings and add-on packages will be lost back to first boot state. Continue?')\" title='Reset this node to the initial/firstboot status and reboot.'>";
print "</td></tr>\n";
if(@msg)
{
foreach(@msg)
{
print "<tr><td align='center'><strong>$_</strong></td></tr>\n";
}
}
print "<tr><td align=center>\n";
print "<table border=1>\n";
print <<EOF;
<thead>
<tr>
<th>Help<br><small>(hover)</small></th>
<th>Config Setting</th>
<th>Value</th>
<th>Actions</th>
</tr>
</thead>
EOF
$scount = 0;
foreach(@setting)
{
# check to see if setting is conditional
if($setting[$scount]->{'condition'})
{
if (!eval $setting[$scount]->{'condition'})
{
$scount++;
next;
}
}
$sconfig = $_->{'key'};
$sval = `uci -q get '$sconfig'`;
print <<EOF;
<tr>
<td align="center"><span title="$setting[$scount]->{'desc'}"><img src="/qmark.png" /></span></td>
<td>$sconfig</td>
<td>
EOF
print "<input type='text' id='field_$scount' name='newval_$scount' size='65' value='$sval'>" if($setting[$scount]->{'type'} eq "string");
print "OFF<label class='switch'><input type='checkbox' id='field_$scount' name='newval_$scount' value='1' checked><span class='slider round'></span></label>ON" if($setting[$scount]->{'type'} eq "boolean" and $sval == 1 );
print "OFF<label class='switch'><input type='checkbox' id='field_$scount' name='newval_$scount' value='1'><span class='slider round'></span></label>ON" if($setting[$scount]->{'type'} eq "boolean" and $sval == 0 );
print "Click EXECUTE button to trigger this action<input type='hidden' id='field_$scount' name='newval_$scount' value='$sval'>" if($setting[$scount]->{'type'} eq "none");
print <<EOF;
</td>
EOF
if($setting[$scount]->{'type'} ne "none")
{
print "<td align='center'><input type='submit' name='button_save_$scount' value='Save Setting' /><br><br>";
} else {
print "<td align='center'><input type='submit' name='button_save_$scount' value='Execute' /><br><br>";
}
print "<input value='Set to Default' type='button' onclick=\"document.getElementById('field_$scount').value='$setting[$scount]->{'default'}';\">" if($setting[$scount]->{'type'} eq "string");
print "<input value='Set to Default' type='button' onclick=\"return toggleDefault('field_$scount', '$setting[$scount]->{'default'}' );\">" if($setting[$scount]->{'type'} eq "boolean");
print <<EOF;
</td>
</tr>
EOF
$scount++;
}
print "</table>\n";
print "</td></tr>\n";
print "</table>\n";
print "</form>\n";
print "</center>\n";
show_debug_info();
show_parse_errors();
page_footer();
print "</body>\n";
print "</html>\n";

View File

@ -1,306 +0,0 @@
=for comment
Part of AREDN -- Used for creating Amateur Radio Emergency Data Networks
Copyright (C) 2015 Conrad Lara
See Contributors file for additional contributors
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation version 3 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional Terms:
Additional use restrictions exist on the AREDN(TM) trademark and logo.
See AREDNLicense.txt for more info.
Attributions to the AREDN Project must be retained in the source code.
If importing this code into a new or existing project attribution
to the AREDN project must be added to the source code.
You must not misrepresent the origin of the material contained within.
Modified versions must be modified to attribute to the original source
and be marked in reasonable ways as differentiate it from the original
version.
=cut
use perlfunc;
#############################
#
# @returns all channels, or specific band lis
sub rf_channel_map
{
%channellist = (
'900' => {
4 => "(907)",
5 => "(912)",
6 => "(917)",
7 => "(922)",
},
'2400' => {
-4 => "-4 (2387)",
-3 => "-3 (2392)",
-2 => "-2 (2397)",
-1 => "-1 (2402)",
1 => "1 (2412)",
2 => "2 (2417)",
3 => "3 (2422)",
4 => "4 (2427)",
5 => "5 (2432)",
6 => "6 (2437)",
7 => "7 (2442)",
8 => "8 (2447)",
9 => "9 (2452)",
10 => "10 (2457)",
11 => "11 (2462)",
},
'3400' => {
76 => "(3380)",
77 => "(3385)",
78 => "(3390)",
79 => "(3395)",
80 => "(3400)",
81 => "(3405)",
82 => "(3410)",
83 => "(3415)",
84 => "(3420)",
85 => "(3425)",
86 => "(3430)",
87 => "(3435)",
88 => "(3440)",
89 => "(3445)",
90 => "(3450)",
91 => "(3455)",
92 => "(3460)",
93 => "(3465)",
94 => "(3470)",
95 => "(3475)",
96 => "(3480)",
97 => "(3485)",
98 => "(3490)",
99 => "(3495)",
},
'5500' => {
37 => "36 (5190)",
40 => "40 (5200)",
44 => "44 (5220)",
48 => "48 (5240)",
52 => "52 (5260)",
56 => "56 (5280)",
60 => "60 (5300)",
64 => "64 (5320)",
100 => "100 (5500)",
104 => "104 (5520)",
108 => "108 (5540)",
112 => "112 (5560)",
116 => "116 (5580)",
120 => "120 (5600)",
124 => "124 (5620)",
128 => "128 (5640)",
132 => "132 (5660)",
136 => "136 (5680)",
140 => "140 (5700)",
149 => "149 (5745)",
153 => "153 (5765)",
157 => "157 (5785)",
161 => "161 (5805)",
165 => "165 (5825)",
},
# 5800 UBNT US Band
'5800ubntus' => {
131 => "131 (5655)",
132 => "132 (5660)",
133 => "133 (5665)",
134 => "134 (5670)",
135 => "135 (5675)",
136 => "136 (5680)",
137 => "137 (5685)",
138 => "138 (5690)",
139 => "139 (5695)",
140 => "140 (5700)",
141 => "141 (5705)",
142 => "142 (5710)",
143 => "143 (5715)",
144 => "144 (5720)",
145 => "145 (5725)",
146 => "146 (5730)",
147 => "147 (5735)",
148 => "148 (5740)",
149 => "149 (5745)",
150 => "150 (5750)",
151 => "151 (5755)",
152 => "152 (5760)",
153 => "153 (5765)",
154 => "154 (5770)",
155 => "155 (5775)",
156 => "156 (5780)",
157 => "157 (5785)",
158 => "158 (5790)",
159 => "159 (5795)",
160 => "160 (5800)",
161 => "161 (5805)",
162 => "162 (5810)",
163 => "163 (5815)",
164 => "164 (5820)",
165 => "165 (5825)",
166 => "166 (5830)",
167 => "167 (5835)",
168 => "168 (5840)",
169 => "169 (5845)",
170 => "170 (5850)",
171 => "171 (5855)",
172 => "172 (5860)",
173 => "173 (5865)",
174 => "174 (5870)",
175 => "175 (5875)",
176 => "176 (5880)",
177 => "177 (5885)",
178 => "178 (5890)",
179 => "179 (5895)",
180 => "180 (5900)",
181 => "181 (5905)",
182 => "182 (5910)",
183 => "183 (5915)",
184 => "184 (5920)",
},
);
my($reqband) = @_;
if ( defined($reqband) ){
if ( exists($channellist{$reqband}) ){
return $channellist{$reqband};
}
else
{
return -1;
}
}
else {
return $channellist;
}
}
sub is_channel_valid
{
my ($channel) = @_;
if ( !defined($channel) ) {
return -1;
}
$boardinfo=hardware_info();
#We know about the band so lets use it
if ( exists($boardinfo->{'rfband'}))
{
$validchannels=rf_channel_map($boardinfo->{'rfband'});
if ( exists($validchannels->{$channel}) )
{
return 1;
} else {
return 0;
}
}
# We don't have the device band in the data file so lets fall back to checking manually
else {
my $channelok=0;
my $wifiintf = get_interface("wifi");
foreach (`iwinfo $wifiintf freqlist`)
{
next unless /Channel $channel/;
next if /\[restricted\]/;
$channelok=1;
}
return $channelok;
}
}
sub rf_channels_list
{
$boardinfo=hardware_info();
#We know about the band so lets use it
if ( exists($boardinfo->{'rfband'}))
{
if (rf_channel_map($boardinfo->{'rfband'}) != -1 )
{
return rf_channel_map($boardinfo->{'rfband'});
}
}
else
{
my %channels = ();
my $wifiintf = get_interface("wifi");
foreach (`iwinfo $wifiintf freqlist` )
{
next unless /([0-9]+.[0-9]+) GHz \(Channel ([0-9]+)\)/;
next if /\[restricted\]/;
my $channelnum = $2;
my $channelfreq = $1;
$channelnum =~s/^0+//g;
$channels->{$channelnum} = "$channelfreq GHZ" ;
}
return $channels;
}
}
sub is_wifi_chanbw_valid
{
# chan_bw valid
return 1;
}
sub rf_default_channel
{
my %default_rf = (
'900' => {
chanbw => "5",
channel => "5",
},
'2400' => {
chanbw => "10",
channel => "-2",
},
'3400' => {
chanbw => "10",
channel => "84",
},
'5800ubntus' => {
chanbw => "10",
channel => "149",
},
);
$boardinfo=hardware_info();
#We know about the band so lets use it
if ( exists($boardinfo->{'rfband'}))
{
return $default_rf{$boardinfo->{'rfband'}};
}
else {
# Somewhat "expensive" in that it duplicates calls made above, but rare to be used.
my $channels = rf_channels_list();
foreach $channelnumber (sort {$a <=> $b} keys %{$channels}) {
return { chanbw => "5", channel => $channelnumber };
}
}
}
#weird uhttpd/busybox error requires a 1 at the end of this file
1

View File

@ -1,49 +0,0 @@
#!/usr/bin/perl
=for comment
Part of AREDN -- Used for creating Amateur Radio Emergency Data Networks
Copyright (C) 2015 Conrad Lara
See Contributors file for additional contributors
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation version 3 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional Terms:
Additional use restrictions exist on the AREDN(TM) trademark and logo.
See AREDNLicense.txt for more info.
Attributions to the AREDN Project must be retained in the source code.
If importing this code into a new or existing project attribution
to the AREDN project must be added to the source code.
You must not misrepresent the origin of the material contained within.
Modified versions must be modified to attribute to the original source
and be marked in reasonable ways as differentiate it from the original
version.
=cut
print "Content-type:text\r\n\r\n";
$ispermitencblock = `opkg list-installed blockknownencryption|wc -l`;
chomp($ispermitencblock);
if ($ispermitencblock){
print "Encrypted Traffic: Blocked\n";
} else {
print "Encrypted Traffic: Allowed\n";
}
print "Active firewall rules:\n";
system ("/usr/sbin/iptables -L");

View File

@ -1,680 +0,0 @@
#!/usr/bin/perl
=for comment
Part of AREDN -- Used for creating Amateur Radio Emergency Data Networks
Copyright (C) 2015 Conrad Lara
See Contributors file for additional contributors
Copyright (c) 2013 David Rivenburg et al. BroadBand-HamNet
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation version 3 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional Terms:
Additional use restrictions exist on the AREDN(TM) trademark and logo.
See AREDNLicense.txt for more info.
Attributions to the AREDN Project must be retained in the source code.
If importing this code into a new or existing project attribution
to the AREDN project must be added to the source code.
You must not misrepresent the origin of the material contained within.
Modified versions must be modified to attribute to the original source
and be marked in reasonable ways as differentiate it from the original
version.
=cut
$debug = 0;
BEGIN {push @INC, '/www/cgi-bin'};
use perlfunc;
use ucifunc;
%rateL = (
'1.0M' => '1', # CCP LP
'2.0M' => '2', # CCP LP
'5.5M' => '5.5', # CCP LP
'MCS0' => '6.5', # HT20 LGI
'11.0M'=> '11', # CCP LP
'MCS1' => '13', # HT20 LGI...
'MCS2' => '19.5',
'MCS3' => '26',
'MCS4' => '39',
'MCS5' => '52',
'MCS6' => '58.5',
'MCS7' => '65',
'MCS8' => '13',
'MCS9' => '26',
'MCS10' => '39',
'MCS11' => '52',
'MCS12' => '78',
'MCS13' => '104',
'MCS14' => '117',
'MCS15' => '130',
);
%rateS = (
'MCS0' => '7.2',
'MCS1' => '14.4',
'MCS2' => '21.7',
'MCS3' => '28.9',
'MCS4' => '43.3',
'MCS5' => '57.8',
'MCS6' => '65',
'MCS7' => '72.2',
'MCS8' => '14.4',
'MCS9' => '28.9',
'MCS10' => '43.3',
'MCS11' => '57.8',
'MCS12' => '86.7',
'MCS13' => '115.6',
'MCS14' => '130',
'MCS15' => '144.4',
);
# Limit displayed nodes and services to the most reachable routes if memory on the node is small
%lowMemoryLimits = (
memory => `/sbin/uci -q get aredn.\@meshstatus[0].lowmem` || 10000,
routes => `/sbin/uci -q get aredn.\@meshstatus[0].lowroutes` || 1000,
);
sub get_available_mem
{
foreach(`free`)
{
next unless /^Mem[:]/;
my @tmp = split /\s+/, $_;
return $tmp[6];
}
return "N/A";
}
# collect some variables
$node = nvram_get("node");
$node = "NOCALL" if $node eq "";
$tactical = nvram_get("tactical");
$config = nvram_get("config");
$config = "not set" if $config eq "" || not -d "/etc/config.mesh";
($my_ip) = get_ip4_network(get_interface("wifi"));
${wifiif} = `uci -q get 'network.wifi.ifname'`;
chomp ${wifiif};
$phy = get_wlan2phy("${wifiif}");
chomp ($chanbw = `cat /sys/kernel/debug/ieee80211/${phy}/ath9k/chanbw`);
if ($chanbw eq "0x00000005") {$chanbw = 4;}
elsif ($chanbw eq "0x0000000a") {$chanbw = 2;}
else {$chanbw = 1;}
read_postdata();
system "mkdir -p /tmp/web";
system "touch /tmp/web/automesh" if $parms{auto};
system "rm -f /tmp/web/automesh" if $parms{stop};
#get location info if available
$lat=&uci_get_indexed_option("aredn","location",0,"lat");
$lon=&uci_get_indexed_option("aredn","location",0,"lon");
if($lat ne "" and $lon ne "")
{
$lat_lon = "<center><strong>Location: </strong> $lat $lon</center>";
}
else
{
$lat_lon = "<strong>Location Not Available</strong>";
}
@route30 = `/sbin/ip route list table 30`;
$olsrTotal = scalar @route30;
$olsrNodes = scalar grep /\//, @route30;
$node_desc = `/sbin/uci -q get system.\@system[0].description`; #pull the node description from uci
undef @route30;
# parse the txtinfo output
chomp($tmperr = `mktemp /tmp/web/nc.XXXXXX`);
foreach(`echo /rou | nc 127.0.0.1 2006 2>>$tmperr`)
{
next if /^\D/;
my ($ip, $junk, $junk, $etx) = split /\s+/, $_;
my ($net, $cidr) = split /\//, $ip;
if ( $etx <= 50 ) { $routes{$net}{etx} = $etx; }
}
if ($olsrTotal > $lowMemoryLimits{routes} && get_available_mem() < $lowMemoryLimits{memory})
{
my @oroutes = sort { $routes{$a}{etx} <=> $routes{$b}{etx} } keys %routes;
foreach ( @oroutes[$lowMemoryLimits{routes} .. $#oroutes] )
{
delete $routes{$_};
}
}
@arps = {};
open my $fh, '<', '/proc/net/arp';
foreach (<$fh>) { push @arps, $_ if (/$wifiif/ && !/00:00:00:00:00:00/) }
close $fh;
foreach(`echo /lin | nc 127.0.0.1 2006 2>>$tmperr`)
{
next if /^\D/;
my ($junk, $ip, $junk, $lq, $nlq) = split /\s+/, $_;
$links{$ip} = {
lq => $lq,
nlq => $nlq,
mbps => ""
};
$neighbor{$ip} = 1;
my ($mac) = grep /^$ip/, @arps;
$mac =~ s/^.*(\w\w:\w\w:\w\w:\w\w:\w\w:\w\w).*$/$1/;
chomp $mac;
open my $fh, '<', "/sys/kernel/debug/ieee80211/${phy}/netdev:${wifiif}/stations/$mac/rc_stats_csv";
if ( $mac && $fh )
{
my @csv = <$fh>;
close $fh;
#802.11b/n
my ($mbps) = grep /^([^,]*,){3}A/, @csv;
if ($mbps)
{
my ($gi, $dummy, $rate, $dummy, $ewma) = $mbps =~ /^[^,]*,([^,]*),([^,]*,){2}([^,]*),([^,]*,){4}([^,]*).*$/ ;
$rate =~ s/[ \t]//g;
$mbps = $gi eq "SGI" ? $rateS{$rate}*$ewma/100 : $rateL{$rate}*$ewma/100 ;
}
else
{
#802.11a/b/g
($mbps) = grep /^A/, @csv;
if ($mbps)
{
$mbps =~ /^[^,]*,([^,]*),([^,]*,){4}([^,]*).*$/;
$mbps = $1*$3/100;
}
}
$links{$ip}{mbps} = $mbps ? sprintf "%.1f", $mbps / $chanbw : "0.0";
}
}
undef @arps;
foreach(`echo /hna | nc 127.0.0.1 2006 2>>$tmperr`)
{
next if /^\D/;
my ($iproute, $ip) = split /\s+/, $_;
my ($net, $cidr) = split /\//, $iproute;
if ( $net eq "0.0.0.0" ) { $wangateway{$ip} = 1; }
}
foreach(`echo /mid | nc 127.0.0.1 2006 2>>$tmperr`)
{
next if /^\D/;
my ($ip, $junk) = $_ =~ /^(\S+)\s+(.*)$/;
foreach $aip ( split /\s+/, $junk )
{
$ipalias{$aip} = $ip;
$neighbor{$aip} = 1;
if ( $links{$aip} ) { $neighbor{$ip} = 1 }
}
}
# stat and -s do not work in microperl
@parts = split /\s+/, `ls -l $tmperr`;
$txtinfo_err = $parts[4];
unlink $tmperr;
# load the local hosts file
open my $fh, '<', '/etc/hosts';
foreach (<$fh>)
{
next unless /^10[.]/;
chomp;
my ($ip, $name, $tactical) = split /\s+/, $_;
next if $name =~ /^(localhost|localnode|localap|dtdlink\..*)$/;
if ( $name !~ /\./ ) { $name="${name}.local.mesh"; }
if($ip eq $my_ip)
{
$tactical = "" unless $tactical;
$localhosts{$ip}{tactical} = $tactical;
$localhosts{$ip}{name} = $name;
}
else { push @{$localhosts{$my_ip}{hosts}}, $name; }
if($tactical eq "#NOPROP") { push @{$localhosts{$my_ip}{noprops}}, $name; }
if($tactical eq "#ALIAS") { push @{$localhosts{$my_ip}{aliases}}, $name; }
}
close $fh;
# load the olsr hosts file
open my $fh, '<', '/var/run/hosts_olsr';
foreach (<$fh>)
{
next unless /^\d/;
chomp;
my ($ip, $name, undef, $originator, undef, undef) = split /\s+/, $_;
next unless $originator;
next if $originator eq "myself";
# Filter hosts which are unreachable
next unless $routes{$ip} || $routes{$originator};
my $etx = $routes{$ip}{etx} ? $routes{$ip}{etx} : $routes{$originator}{etx};
if (( $name !~ /\./ ) || ( $name =~ /^mid\.[^\.]*$/ )) { $name="${name}.local.mesh"; }
if ( $ip eq $originator )
{
if ($hosts{$ip}{name})
{
$hosts{$ip}{tactical} = $name;
}
else
{
$hosts{$ip}{name} = $name;
$hosts{$ip}{etx} = $etx;
}
}
elsif ( $name =~ /^dtdlink\..*$/ )
{
$dtd{$originator} = 1;
if ( $links{$ip} ) { $links{$ip}{dtd} = 1 }
}
elsif ( $name =~ /^mid\d+\..*$/ )
{
$midcount{$originator} = $midcount{$originator} ? $midcount{$originator}+1: 1 ;
if ( $links{$ip} ) { $links{$ip}{tun} = 1 }
}
else
{
push @{$hosts{$originator}{hosts}}, $name;
}
}
close $fh;
# Discard
undef %routes;
# load the olsr services file
open my $fh, '<', '/var/run/services_olsr';
foreach (<$fh>)
{
next unless /^\w/;
chomp;
my ($url, $junk, $name) = split /\|/, $_;
next unless defined $name;
my ($protocol, $host, $port, $path) = $url =~ /^(\w+):\/\/([\w\-\.]+):(\d+)\/(.*)/;
next unless defined $path;
my ($name, $originator) = split /\#/, $name;
# Filter services for unreachable hosts
next unless $hosts{$originator}{name} || $originator eq " my own service";
$name =~ s/\s+$//;
if ( $host !~ /\./ ) { $host="${host}.local.mesh"; }
# attempt to work around olsr never forgetting defunct services
# assume that the first entry in the file by this name is the most recent, ignore the rest
next if $services{$host}{$name};
$services{$host}{$name} = $port ? "<a href='${protocol}://${host}:${port}/${path}' target='_blank'>$name</a>" : $name;
}
close $fh;
# load the node history
open my $fh, '<', '/tmp/node.history';
foreach (<$fh>)
{
chomp;
($ip, $age, $host) = split / /, $_;
next unless $age;
$host = "" unless $host;
$host =~ s|/| / |;
$history{$ip}{age} = $age;
$history{$ip}{host} = $host;
}
close $fh;
#delete $hosts{"127.0.0.1"};
# compress the output if we can
if ( $ENV{HTTP_ACCEPT_ENCODING} =~ /gzip/ )
{
print "Content-type: text/html\r\nCache-Control: no-store\r\nContent-Encoding: gzip\r\n\r\n";
open my $zout, "|gzip";
select $zout;
}
else
{
print "Content-type: text/html\r\nCache-Control: no-store\r\n\r\n";
}
# generate the page
html_header("$node mesh status", 0);
print "<meta http-equiv='refresh' content='10;url=/cgi-bin/mesh'>\n" if -f "/tmp/web/automesh";
print "</head>\n";
print "<body><form method=post action=/cgi-bin/mesh enctype='multipart/form-data'>\n";
print "<input type=hidden name=reload value=1>\n";
print "<center>\n";
alert_banner();
# page header
print "<h1>$node mesh status</h1>";
print "$lat_lon"; #display lat lon info
print "<table id='node_description_display'><tr><td>$node_desc</td></tr></table>" if $node_desc; #display node description
print "<hr><nobr>";
# nav buttons
if(-f "/tmp/web/automesh")
{
print "<input type=submit name=stop value=Stop title='Abort continuous status'>\n";
}
else
{
print "<input type=submit name=refresh value=Refresh title='Refresh this page'>\n";
print "&nbsp;&nbsp;&nbsp;\n";
print "<input type=submit name=auto value=Auto title='Automatic page refresh'>\n";
}
print "&nbsp;&nbsp;&nbsp";
print "<button type=button onClick='window.location=\"status\"' title='Return to the status page'>Quit</button>\n";
if($txtinfo_err)
{
print "<br><br><b>Whoops! OLSR is not running, try again later.</b>\n";
print "</center></form>";
page_footer();
print "</body></html>\n";
exit;
}
print "</nobr><br><br>\n";
unless(keys %localhosts || keys %links)
{
print "No other nodes are available.\n";
print "</center></form>";
page_footer();
print "</body></html\n";
exit;
}
print "<table><tr><td valign=top><table>\n";
# show local hosts
print "<tr><th colspan=4 align=left><nobr>Local Hosts</nobr></th><th align=left>Services</th></tr>\n";
print "<tr><td colspan=5><hr></td></tr>\n";
if(keys %localhosts)
{
my %rows = ();
foreach $ip (keys %localhosts)
{
my $host = $localhosts{$ip}{name};
my $localpart = $host =~ s/.local.mesh//r;
my $tactical = $localhosts{$ip}{tactical} ? " / " . $localhosts{$ip}{tactical} : "";
$rows{$host} = sprintf "<tr><td valign=top><nobr>%s</nobr>", $localpart . $tactical;
if ( $wangateway{$ip} ) { $nodeiface = "wan" ; }
if ( $nodeiface ) { $rows{$host} .= " &nbsp; <small>($nodeiface)</small>"; }
$rows{$host} .= "</td><td colspan=3>&nbsp;</td><td>\n" ;
foreach(sort keys %{$services{$host}})
{
$rows{$host} .= "<nobr>" . $services{$host}{$_} . "</nobr><br>\n";
}
$rows{$host} .= "</td></tr>\n";
# add locally advertised dmz hosts
foreach $dmzhost (@{$localhosts{$ip}{hosts}})
{
#find non-propagated and aliased hosts and change color
my $nopropd = 0;
my $aliased = 0;
if(grep { /$dmzhost/ } @{$localhosts{$ip}{noprops}}) { $nopropd = 1; }
if(grep { /$dmzhost/ } @{$localhosts{$ip}{aliases}}) { $aliased = 1; }
$localpart = $dmzhost =~ s/.local.mesh//r;
if(!$nopropd && !$aliased) { $rows{$host} .= "<tr><td valign=top><nobr>&nbsp;<img src='/dot.png'>$localpart</nobr></td>"; }
elsif($aliased) { $rows{$host} .= "<tr><td class=aliased-hosts valign=top title='Aliased Host'><nobr>&nbsp;<img src='/dot.png'>$localpart</nobr></td>"; }
else { $rows{$host} .= "<tr><td class=hidden-hosts valign=top title='Non Propagated Host'><nobr>&nbsp;<img src='/dot.png'>$localpart</nobr></td>"; }
$rows{$host} .= "<td colspan=3></td><td>\n";
foreach(sort keys %{$services{$dmzhost}})
{
$rows{$host} .= "<nobr>" . $services{$dmzhost}{$_} . "</nobr><br>\n";
}
$rows{$host} .= "</td></tr>\n";
}
}
foreach(sort keys %rows) { print $rows{$_} }
}
else
{
print "<tr><td>none</td></tr>\n";
}
# show remote nodes
print "<tr><td>&nbsp;</td></tr>\n";
print "<tr><th align=left><nobr>Remote Nodes</nobr></th><th>&nbsp;&nbsp;</th><th>ETX</th><th>&nbsp;&nbsp;</th><th align=left>Services</th></tr>\n";
print "<tr><td colspan=5><hr></td></tr>\n";
my $row;
foreach $ip (sort { $hosts{$a}{etx} <=> $hosts{$b}{etx} } keys %hosts)
{
next if $neighbor{$ip};
my $host = $hosts{$ip}{name};
next unless $host;
my $localpart = $host =~ s/.local.mesh//r;
my $tactical = $hosts{$ip}{tactical} ? " / " . $hosts{$ip}{tactical} : "";
my $etx = sprintf "%.2f", $hosts{$ip}{etx};
$row = sprintf "<tr><td valign=top><nobr><a href='http://%s:8080/'>%s</a>", $host, $localpart . $tactical;
my $nodeiface;
my $mcount = 0 + $midcount{$ip};
if ( $dtd{$ip} ) { $mcount -= 1; } # extra mid entry matching and with dtdlink in hosts_olsrd
if ( $hosts{$ip}{tactical} ) { $mcount -= 1; } # extra mid entry if tactical name defined
if ( $mcount > 0 ) { $nodeiface = "tun*$mcount" ; }
if ( $wangateway{$ip} ) { $nodeiface = $nodeiface ? $nodeiface . ",wan" : "wan" ; }
if ( $nodeiface ) { $row .= " &nbsp; <small>($nodeiface)</small>"; }
$row .= sprintf "</nobr></td><td></td><td align=right valign=top>%s</td><td></td><td>\n", $etx;
foreach(sort keys %{$services{$host}})
{
$row .= "<nobr>" . $services{$host}{$_} . "</nobr><br>\n";
}
$row .= "</td></tr>\n";
# add advertised dmz hosts
foreach $dmzhost (@{$hosts{$ip}{hosts}})
{
my $localpart = $dmzhost =~ s/.local.mesh//r;
$row .= "<tr><td valign=top><nobr>&nbsp;<img src='/dot.png'>$localpart</nobr></td>";
$row .= "<td colspan=3></td><td>\n";
foreach(sort keys %{$services{$dmzhost}})
{
$row .= "<nobr>" . $services{$dmzhost}{$_} . "</nobr><br>\n";
}
$row .= "</td></tr>\n";
}
print $row;
}
undef %neighbor;
if(!$row)
{
print "<tr><td>none</td></tr>\n";
}
print "</table></td><td width=20>&nbsp;</td><td valign=top><table>\n";
# show current neighbors
print "<tr><th align=left><nobr>Current Neighbors</nobr></th><th>&nbsp;&nbsp;</th><th>LQ</th><th>NLQ</th><th>TxMbps</th><th>&nbsp;&nbsp;</th><th align=left>Services</th></tr>\n";
print "<tr><td colspan=7><hr></td></tr>\n";
if(keys %links)
{
my %rows = ();
foreach $ip (keys %links)
{
my $ipmain = exists $ipalias{$ip} ? $ipalias{$ip} : $ip ;
my $host = $hosts{$ipmain}{name} ? $hosts{$ipmain}{name} : $ipmain;
my $localpart = $host =~ s/.local.mesh//r;
my $tactical = $hosts{$ipmain}{tactical} ? " / " . $hosts{$ipmain}{tactical} : "";
if ( $rows{$host} ) { $host .= " " ; } # avoid collision 2 links to same host {rf, dtd}
my $no_space_host=$host;
$no_space_host =~ s/\s+$//;
my $row = sprintf "<tr><td valign=top><nobr><a href='http://%s:8080/'>%s</a>", $no_space_host, $localpart . $tactical;
my $nodeiface;
if ( $ipmain ne $ip ) # indicate if dtd or tunnel interface to neighbor
{
if ( $links{$ip}{dtd} ){ $nodeiface="dtd" ; }
elsif ( $links{$ip}{tun} ){ $nodeiface="tun" ; }
else { $nodeiface="?" ; }
}
if ( $wangateway{$ip} || $wangateway{$ipmain} ) { $nodeiface = $nodeiface ? $nodeiface . ",wan" : "wan" ; }
if ( $nodeiface ) { $row .= " &nbsp; <small>($nodeiface)</small>"; }
$row .= sprintf ("</nobr></td><td></td><td align=right valign=top>%.0f%%</td><td align=right valign=top>%.0f%%</td><td align=right valign=top>%s</td><td></td><td>\n", 100*$links{$ip}{lq}, 100*$links{$ip}{nlq},$links{$ip}{mbps});
if ( ! exists $neighservices{$host} )
{
foreach(sort keys %{$services{$host}}) { $row .= "<nobr>" . $services{$host}{$_} . "</nobr><br>\n" }
$row .= "</td></tr>\n";
# add advertised dmz hosts
foreach $dmzhost (@{$hosts{$ipmain}{hosts}})
{
my $localpart = $dmzhost =~ s/.local.mesh//r;
$row .= "<tr><td valign=top><nobr>&nbsp;<img src='/dot.png'>$localpart</nobr></td><td colspan=5></td><td>\n";
foreach(sort keys %{$services{$dmzhost}}) { $row .= $services{$dmzhost}{$_} . "<br>\n" }
$row .= "</td></tr>\n";
}
$neighservices{$host}=1;
}
$rows{$host}=$row;
}
foreach(sort keys %rows) { print $rows{$_} }
}
else
{
print "<tr><td>none</td></tr>\n";
}
undef %services;
# show previous neighbors
print "<tr><td>&nbsp;</td></tr>\n";
print "<tr><th colspan=6 align=left><nobr>Previous Neighbors</nobr></th><th align=left>When</th></tr>\n";
print "<tr><td colspan=7><hr></td></tr>\n";
%rows = ();
($uptime) = `cat /proc/uptime` =~ /^(\d+)/;
foreach $ip (keys %history)
{
next if $links{$ip};
next if $links{$ipalias{$ip}};
$age = sprintf "%010d", $uptime - $history{$ip}{age};
$host = $history{$ip}{host} ? $history{$ip}{host} : $ip;
$host =~ s/^mid\d+\.// ;
$host =~ s/^dtdlink\.// ;
$rows{$age} .= sprintf "<tr><td colspan=6><nobr>%s</nobr>", $host;
foreach(@{$hosts{$ip}{hosts}}) { $rows{$age} .= "<br><nobr><img src='/dot.png'>$_</nobr>" }
$rows{$age} .= "</td><td valign=top><nobr>";
if($age < 3600)
{
$val = int($age/60);
$rows{$age} .= $val == 1 ? "1 minute ago" : "$val minutes ago";
}
else
{
$val = sprintf "%.1f", $age/3660;
$rows{$age} .= $val eq "1.0" ? "1 hour ago" : "$val hours ago";
}
$rows{$age} .= "</nobr></td></tr>\n";
}
if(keys %rows)
{
foreach(sort keys %rows) { print $rows{$_} }
}
else
{
print "<tr><td>none</td></tr>\n";
}
print "<tr><td>&nbsp;</td></tr>\n";
print "<tr><th align='left'>OLSR Entries</th></tr>\n";
print "<tr><td colspan=7><hr></td></tr>\n";
print "<tr><td>Total</td><td>&nbsp;</td><td align='right'>$olsrTotal</td></tr>\n";
print "<tr><td>Nodes</td><td>&nbsp;</td><td align='right'>$olsrNodes</td></tr>\n";
print "</table></td></tr></table>\n";
# end
print "</center>\n";
print "</form>\n";
if($debug)
{
print "<pre>\n";
print "localhosts\n";
foreach $ip (sort keys %localhosts)
{
printf "%s %s", $ip, $localhosts{$ip}{name};
printf "/%s", $localhosts{$ip}{tactical} if $localhosts{$ip}{tactical};
foreach(@{$localhosts{$ip}{hosts}}) { print ":$_" }
print "\n";
}
print "\nhosts\n";
foreach $ip (sort keys %hosts)
{
$hosts{$ip}{name} = "" unless $hosts{$ip}{name};
printf "%s %s", $ip, $hosts{$ip}{name};
printf "/%s", $hosts{$ip}{tactical} if $hosts{$ip}{tactical};
foreach(@{$hosts{$ip}{hosts}}) { print ":$_" }
printf(" %d", $hosts{$ip}{mid}) if $hosts{$ip}{mid};
}
print "\nlinks\n";
foreach(sort keys %links)
{
print "$_\n";
}
print "</pre>\n";
}
show_debug_info();
show_parse_errors();
page_footer();
print "</body>\n";
print "</html>\n";

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,98 +0,0 @@
#!/usr/bin/perl
=for comment
Part of AREDN -- Used for creating Amateur Radio Emergency Data Networks
Copyright (C) 2015 Conrad Lara
See Contributors file for additional contributors
Copyright (c) 2013 David Rivenburg et al. BroadBand-HamNet
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation version 3 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional Terms:
Additional use restrictions exist on the AREDN(TM) trademark and logo.
See AREDNLicense.txt for more info.
Attributions to the AREDN Project must be retained in the source code.
If importing this code into a new or existing project attribution
to the AREDN project must be added to the source code.
You must not misrepresent the origin of the material contained within.
Modified versions must be modified to attribute to the original source
and be marked in reasonable ways as differentiate it from the original
version.
=cut
$debug = 0;
BEGIN {push @INC, '/www/cgi-bin'};
use perlfunc;
# collect some variables
$node = nvram_get("node");
$node = "NOCALL" if $node eq "";
read_postdata();
system "mkdir -p /tmp/web";
system "/usr/local/bin/wscan -w > /tmp/web/wscan.next" unless $parms{stop};
system "touch /tmp/web/autoscan" if $parms{auto};
system "rm -f /tmp/web/autoscan" if $parms{stop};
system "mv /tmp/web/wscan.next /tmp/web/wscan" unless $parms{stop};
# generate the page
http_header();
html_header("$node WiFi scan", 0);
print "<meta http-equiv='refresh' content='5;url=/cgi-bin/scan'>\n" if -f "/tmp/web/autoscan";
print "<script src=\"/js/sorttable-min.js\"></script>";
print "<style>
table.sortable thead {
background-color:#eee;
color:#666666;
font-weight: bold;
cursor: default;
}
</style>";
print "</head>\n";
print "<body><form method=post action=/cgi-bin/scan enctype='multipart/form-data'>\n";
print "<center>\n";
alert_banner();
print "<h1>$node WiFi scan</h1><hr>\n";
if(-f "/tmp/web/autoscan")
{
print "<input type=submit name=stop value=Stop title='Abort continuous scan'>\n";
}
else
{
print "<input type=submit name=refresh value=Refresh title='Refresh this page'>\n";
print "&nbsp;&nbsp;&nbsp;\n";
print "<input type=submit name=auto value=Auto title='Begin continuous scan'>\n";
}
print "&nbsp;&nbsp;&nbsp;\n";
print "<button type=button onClick='window.location=\"status\"' title='Return to status page'>Quit</button><br><br>\n";
system "cat /tmp/web/wscan";
print "<br>";
print "</center>\n";
print "</form>\n";
show_debug_info();
show_parse_errors();
page_footer();
print "</body>\n";
print "</html>\n";

File diff suppressed because it is too large Load Diff

View File

@ -1,307 +0,0 @@
#!/usr/bin/perl
=for comment
Part of AREDN -- Used for creating Amateur Radio Emergency Data Networks
Copyright (C) 2015 Darryl Quinn
See Contributors file for additional contributors
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation version 3 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional Terms:
Additional use restrictions exist on the AREDN(TM) trademark and logo.
See AREDNLicense.txt for more info.
Attributions to the AREDN Project must be retained in the source code.
If importing this code into a new or existing project attribution
to the AREDN project must be added to the source code.
You must not misrepresent the origin of the material contained within.
Modified versions must be modified to attribute to the original source
and be marked in reasonable ways as differentiate it from the original
version.
=cut
$debug = 0;
BEGIN {push @INC, '/www/cgi-bin'};
use perlfunc;
chomp ($tzone=`date +%Z`);
read_query_string();
# collect some variables
$node = nvram_get("node");
$node = "NOCALL" unless $node;
if($parms{"realtime"} )
{
$dmode="Realtime";
} else {
$dmode="Archived";
}
http_header();
html_header("$node $dmode signal strength", 0);
$header = <<EOF;
<link href="/loading.css" rel="stylesheet">
<script src="/js/jquery-2.1.4.min.js"></script>
<script src="/js/jquery.canvasjs.min.js"></script>
<script type="text/javascript">
var dps=[[{"label":"Init","y":[-95,-95]}]];
// Read a page's GET URL variables and return them as an associative array.
function getUrlVars()
{
var vars = [], hash;
var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
for(var i = 0; i < hashes.length; i++)
{
hash = hashes[i].split('=');
vars.push(hash[0]);
vars[hash[0]] = hash[1];
}
return vars;
}
function hide_spinner() {
\$('#content-loading-spinner').dequeue();
\$('#content-loading-spinner').hide();
\$('#content-overlay').dequeue();
\$('#content-overlay').hide();
}
\$(document).ajaxComplete(function() {
hide_spinner();
});
\$(document).ready(function () {
var MAXPOINTS=10;
var chart = new CanvasJS.Chart("chartContainer", {
zoomEnabled: true,
zoomType: "xy",
exportEnabled: true,
backgroundColor: "#E7E7E7",
title: {
text: "$dmode Signal to Noise"
},
legend: {
horizontalAlign: "right", // left, center ,right
verticalAlign: "center", // top, center, bottom
},
axisX: {
title: "Time (in $tzone)",
labelFontSize: 12,
labelAngle: -45,
valueFormatString: "MM/DD HH:mm",
},
axisY: {
title: "dBm",
interlacedColor: "#F0F8FF",
},
toolTip: {
contentFormatter: function (e) {
var content = " ";
content += "At " + e.entries[0].dataPoint.timestamp.substring(11, 19) + "<br />";
if (e.entries[0].dataPoint.signal_dbm) {
content += "Signal: " + e.entries[0].dataPoint.signal_dbm + "dBm<br/>";
} else {
content += "Signal: 0<br/>";
}
content += "Noise: " + e.entries[0].dataPoint.noise_dbm + "dBm<br/>";
content += "SNR: " + e.entries[0].dataPoint.snr + "dB<br/>";
content += "TX Rate: " + e.entries[0].dataPoint.tx_rate_mbps + "Mbps<br/>";
content += "TX MCS: " + e.entries[0].dataPoint.tx_rate_mcs_index + "<br/>";
content += "RX Rate: " + e.entries[0].dataPoint.rx_rate_mbps + "Mbps<br/>";
content += "RX MCS: " + e.entries[0].dataPoint.rx_rate_mcs_index + "<br/>";
return content;
}
},
data: [
{
type: "rangeArea",
xValueType: "dateTime",
showInLegend: true,
legendText: "Signal",
dataPoints: dps[0]
}
],
}); // --- chart
var formatDataPoint = function(point) {
point.label = point.timestamp.substring(5, 10) + " " + point.timestamp.substring(11, 19);
point.y = [point.signal_dbm, point.noise_dbm];
point.snr = (point.noise_dbm * -1) - (point.signal_dbm * -1);
point.tx_rate_mcs_index = point.tx_rate_mcs_index ? point.tx_rate_mcs_index : "N/A";
point.rx_rate_mcs_index = point.rx_rate_mcs_index ? point.rx_rate_mcs_index : "N/A";
return point;
};
var updateArchiveChart = function () {
\$.getJSON("/cgi-bin/api?chart=archive&device=$parms{device}", function (result) {
var points = result.pages.chart.archive.map(formatDataPoint);
chart.options.data[0].dataPoints = points;
if(result.pages.chart.archive.constructor === Array) {
chart.render();
};
});
};
var updateRealtimeChart = function () {
\$.getJSON("/cgi-bin/api?chart=realtime&realtime=1&device=$parms{device}", function (result) {
var point = formatDataPoint(result.pages.chart.realtime[0]);
dps[0].push(point);
chart.render();
toneFreq(point.snr);
\$('#snr').html(point.snr);
});
};
var dmode = getUrlVars()["realtime"];
if(dmode) {
updateRealtimeChart();
setInterval(function() {updateRealtimeChart()}, 1000);
} else {
updateArchiveChart();
setInterval(function() {updateArchiveChart()}, 60000);
}
chart.render();
}); // --- document.ready
var audioCtx = new(window.AudioContext || window.webkitAudioContext)();
var oscillator = audioCtx.createOscillator();
var gainNode = audioCtx.createGain();
oscillator.connect(gainNode);
oscillator.type = 'sine';
gainNode.connect(audioCtx.destination);
gainNode.gain.value = 1;
function toneFreq(snr) {
var p = document.getElementById("tonePitch").value;
oscillator.frequency.value = snr * p;
var v = document.getElementById("toneVol").value;
gainNode.gain.value = v;
}
function toneOn() {
oscillator = audioCtx.createOscillator();
gainNode = audioCtx.createGain();
oscillator.connect(gainNode);
oscillator.type = 'sine';
gainNode.connect(audioCtx.destination);
gainNode.gain.value = .5;
oscillator.start();
document.getElementById("toneOff").disabled = false;
document.getElementById("toneOn").disabled = true;
};
function toneOff() {
document.getElementById("toneOff").disabled = true;
document.getElementById("toneOn").disabled = false;
oscillator.stop();
};
</script>
</head>
EOF
$page = <<EOF;
<body>
<div class="overlay" id="content-overlay"></div>
<div id="content-loading-spinner-wrapper">
<div id="content-loading-spinner">
<div class="spinner"></div>
<div class="loading-text">
Loading . . .
</div>
</div>
</div>
<center>
<div class="TopBanner">
<div class="LogoDiv"><img src="/AREDN.png" class="AREDNLogo"></img></div>
</div>
<h1><big>$node</big></h1><hr>
<nobr>
<button onclick="window.location.href='/cgi-bin/signal'">Archive</button>
<button onclick="window.location.href='/cgi-bin/signal?realtime=1'">Realtime</button>
<button onclick="window.location.href='/cgi-bin/status'">Quit</button>
<br />
<div id="deviceSelector">
<form name="deviceSelector" method="GET" action="/cgi-bin/signal">
Selected Device:&nbsp;<select name="device" onChange="this.form.submit();">
EOF
# get a list of files from /tmp/snrlog
my @files = `ls -1A /tmp/snrlog`;
$parms{device}="" if(!/$parms{device}/ ~~ @files);
# default to "Strongest Signal" for Realtime
if(! $parms{device} and $parms{realtime}) {
$page = $page . "<option selected value='strongest'>Average signal for all connected stations</option>";
}
$firstSel=1;
# iterate over each file
foreach $logfile (@files)
{
chomp($logfile);
my ($dmac, $dname) = $logfile =~ /^(.*?)\-(.*)/;
$dname=$dmac if($dname eq '');
if($parms{device} eq $logfile or (!$parms{realtime} and $firstSel)) {
$page = $page . "<option selected value='$logfile'>$dname</option>\n";
$firstSel=0;
} else {
$page = $page . "<option value='$logfile'>$dname</option>\n";
}
}
$page = $page . "</select>\n";
$page = $page . "<input type='hidden' name='realtime' value='1'></input>\n" if($parms{realtime} eq "1");
$page = $page . <<EOF;
</form>
</div>
<div id="snrValues" style="float: left;">
EOF
$page = $page . "<div><h3>SNR: <span id='snr'>0</span>dB</h3></div>" if($parms{"realtime"} eq "1");
if($parms{"realtime"} eq "1") {
$page = $page . "<div style='float: right;'>Sound: <button id='toneOn' onclick='toneOn();'>On</button>&nbsp;";
$page = $page . "<button id='toneOff' disabled onclick='toneOff();'>Off</button><br /><br />";
$page = $page . "Pitch:&nbsp;<input type='range' id='tonePitch' name='tonePitch' min='5' max='100'></input><br /><br />";
$page = $page . "Volume:&nbsp;<input type='range' id='toneVol' name='toneVol' min='0' max='10'></input><br /><br />";
$page = $page . "</div>";
}
$page = $page . <<EOF;
</div>
<div id="chartContainer" style="width: 80%; height: 60%;"></div>
</center>
EOF
print $header;
print $page;
show_debug_info();
print "</body></html>";
sub DEBUGEXIT()
{
my ($text) = @_;
http_header();
html_header("$node setup", 1);
print "DEBUG-";
print $text;
print "</body>";
exit;
}

View File

@ -1,298 +0,0 @@
#!/usr/bin/perl
=for comment
Part of AREDN -- Used for creating Amateur Radio Emergency Data Networks
Copyright (C) 2015 Conrad Lara
See Contributors file for additional contributors
Copyright (c) 2013 David Rivenburg et al. BroadBand-HamNet
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation version 3 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional Terms:
Additional use restrictions exist on the AREDN(TM) trademark and logo.
See AREDNLicense.txt for more info.
Attributions to the AREDN Project must be retained in the source code.
If importing this code into a new or existing project attribution
to the AREDN project must be added to the source code.
You must not misrepresent the origin of the material contained within.
Modified versions must be modified to attribute to the original source
and be marked in reasonable ways as differentiate it from the original
version.
=cut
$debug = 0;
BEGIN {push @INC, '/www/cgi-bin'};
use perlfunc;
use ucifunc;
# collect some variables
$node = nvram_get("node");
$node = "NOCALL" if $node eq "";
$tactical = nvram_get("tactical");
$config = nvram_get("config");
$config = "not set" if $config eq "" or not -d "/etc/config.mesh";
$wifi_iface = get_interface("wifi");
$wifi_iface =~ /wlan(\d+)/;
$radio = ( defined $1 )? "radio$1" : "radio0";
$wifi_disable = ( $wifi_iface =~ /eth.*$/ )? 1 : 0;
if ( ! $wifi_disable )
{
($junk, $wifi_channel) = &uci_get_named_option("wireless", "$radio", "channel");
if ($wifi_channel >= 76 and $wifi_channel <= 99)
{
$wifi_channel = ($wifi_channel*5+3000);
}
($junk, $wifi_chanbw) = &uci_get_named_option("wireless", "$radio", "chanbw");
$wifi_ssid = "N/A";
@wisections = &uci_get_all_indexed_by_sectiontype("wireless", "wifi-iface");
foreach(@wisections) {
if ($_->{network} eq "wifi") {
$wifi_ssid = $_->{ssid};
}
}
}
$node_desc = `/sbin/uci -q get system.\@system[0].description`; #pull the node description from uci
#get location info if available
$lat_lon = "<strong>Location Not Available</strong>";
$lat=&uci_get_indexed_option("aredn","location",0,"lat");
$lon=&uci_get_indexed_option("aredn","location",0,"lon");
if($lat ne "" and $lon ne "") {
$lat_lon = "<center><strong>Location: </strong> $lat $lon</center>";
}
$olsrTotal = `/sbin/ip route list table 30 | wc -l`; #num hosts olsr is keeping track of
$olsrNodes = `/sbin/ip route list table 30 | egrep "/" | wc -l`; #num *nodes* on the network (minus other hosts)
read_postdata();
if($parms{css} and -f "/www/$parms{css}" and $parms{css} =~ /\.css$/i) {
unlink "/tmp/web/style.css";
symlink "/www/$parms{css}","/tmp/web/style.css";
}
# generate the page
http_header();
html_header("$node status", 1);
print "<body><form method='post' action='/cgi-bin/status' enctype='multipart/form-data'>\n";
print "<center>\n";
alert_banner();
# page header
print "<h1><big>$node";
print " / $tactical" if $tactical;
print "</big></h1>";
print "<center>$lat_lon</center>"; #display location info
print "<table id='node_description_display'><tr><td>$node_desc</td></tr></table>" if $node_desc;
print "<hr>\n";
# nav buttons
print "<nobr>\n";
#print qq(<button type=button onClick='window.open("/help.html", "_blank")' title='Open a help window'>Help</button>\n);
print "<a href='/help.html' target='_blank'>Help</a>\n";
print "&nbsp;&nbsp;&nbsp;";
print "<input type=submit name=refresh value=Refresh title='Refresh this page'>\n";
if($config eq "mesh")
{
print "&nbsp;&nbsp;&nbsp;";
print "<button type=button onClick='window.location=\"mesh\"' title='See what is on the mesh'>Mesh Status</button>\n";
if ( ! $wifi_disable )
{
print "&nbsp;&nbsp;&nbsp;";
print "<button type=button onClick='window.location=\"scan\"' title='See what wireless networks are nearby'>WiFi Scan</button>\n";
}
}
print "&nbsp;&nbsp;&nbsp;";
print "<button type=button onClick='window.location=\"setup\"' title='Configure this node'>Setup</button>\n";
print "&nbsp;&nbsp;&nbsp;";
print "<select name=\"css\" size=\"1\" onChange=\"form.submit()\" >";
css_options();
print "</select>";
print "</nobr>";
print "<input type=hidden name=reload value=reload>\n";
if($config eq "not set")
{
print "<b><br><br>This node is not yet configured.<br>";
print "Go to the setup page and set your node name and password.<br>\n";
print "Click Save Changes, <u>even if you didn't make any changes</u>, then the node will reboot.</b>\n";
print "<br><br>\n";
print "<div style=\"max-width: 540px\; text-align: left\">\n";
print "<p>This device can be configured to either permit or prohibit known encrypted traffic on its RF link. It is up to the user to decide which is appropriate based on how it will be used and the license under which it will be operated. These rules vary by country, frequency, and intended use. You are encouraged to read and understand these rules before going further.</p>";
print "<p>This device is pre-configured with no restrictions as to the type of data being passed.</p>\n";
print "<p>Follow these steps if <span style=\"text-decoration: underline\">you wish to prohibit</span> known encrypted traffic on the RF link. These instructions will disappear, so copy them for your reference:</p>";
print "<p><ol>\n";
print "<li>Setup your node name and password as instructed at the top of this page</li>";
print "<li>After you Save Changes allow your node to reboot</li>";
print "<li>Return to the Node Status page and navigate to Setup &gt Administration</li>";
print "<li>Obtain the blockknownencryption package from the AREDN&trade; website OR refresh the Package list (node must be connected to the internet)</li>";
print "<li>Install the blockknownencryption package by uploading it or choosing it from the package drop-down list</li>";
print "<li>Wait until the package installs and then reboot your node</li>";
print "</ol></p>\n";
print "</div>";
}
# status display
@col1 = @col2 = ();
$hide_local = 0;
$browser_ip = "";
# left column - network interface info
# show the Primary/Wifi address
($ip, $mask, $bcast, $net, $cidr) = get_ip4_network($wifi_iface);
$cidr = "/ $cidr" if $cidr;
if (! $wifi_disable )
{
$str = "<th align=right><nobr>Wifi address</nobr></th><td>$ip <small>$cidr</small><br>";
}
else
{
$str = "<th align=right><nobr>Primary address</nobr></th><td>$ip <small>$cidr</small><br>";
}
# $str .= "<small><nobr>" . get_ip6_addr($wifi_iface) . "</nobr></small></td>";
push @col1, $str;
# find out if the browser is on this node's lan
# if not, hide the local network details
($ip, $mask, $bcast, $net, $cidr) = get_ip4_network(get_interface("lan"));
if($ENV{REMOTE_ADDR} =~ /::ffff:([\d\.]+)/)
{
$browser_ip = $1;
$hide_local = 1 unless validate_same_subnet($browser_ip, $ip, $mask);
}
if($ip =~ /^10\./ or not $hide_local)
{
$cidr = "/ $cidr" if $cidr;
$str = "<th align=right><nobr>LAN address</nobr></th><td>$ip <small>$cidr</small><br>";
# $str .= "<small><nobr>" . get_ip6_addr(get_interface("lan")) . "</nobr></small></td>";
push @col1, $str;
}
{
my $wanintf = get_interface("wan");
if(not $hide_local and not system "ifconfig $wanintf >/dev/null 2>&1")
{
($ip, $mask, $bcast, $net, $cidr) = get_ip4_network("$wanintf");
$cidr = "/ $cidr" if $cidr;
$cidr = "" unless $cidr;
$str = "<th align=right><nobr>WAN address</nobr></th><td>$ip <small>$cidr</small><br>";
# $str .= "<small><nobr>" . get_ip6_addr("$wanintf") . "</nobr></small></td>";
push @col1, $str;
}
}
$ip = get_default_gw();
if($ip =~ /^10\./ or not $hide_local)
{
$str = "<th align=right><nobr>default gateway</nobr></th><td>$ip";
$str .= "<br><nobr>" . mesh_ip2hostname($ip) . "</nobr>" if $ip =~ /^10\./;
push @col1, $str . "</td>";
}
if($browser_ip)
{
$str = "<th align=right><nobr>your address</nobr></th><td>$browser_ip";
$str .= "<br><nobr>" . mesh_ip2hostname($browser_ip) . "</nobr>";# if $ip =~ /^10\./;
push @col1, $str . "</td>";
}
if ( ! $wifi_disable )
{
$str = "<th align=right><nobr>SSID</nobr></th><td>$wifi_ssid";
push @col1, $str . "</td>";
$str = "<th align=right><nobr>Channel</nobr></th><td>$wifi_channel";
push @col1, $str . "</td>";
$str = "<th align=right><nobr>Bandwidth</nobr></th><td>$wifi_chanbw MHz";
push @col1, $str . "</td>";
}
# right column - system info
if($config eq "mesh" and ! $wifi_disable )
{
$str = "<th align=right valign=middle><nobr>Signal/Noise/Ratio</nobr></th><td valign=middle><nobr>";
($s, $n) = get_wifi_signal($wifi_iface);
if($s eq "N/A") { $str .= "N/A" }
else { $str .= sprintf "<big><b>%d / %d / %d dB</b></big>", $s, $n, $s - $n }
$str .= "&nbsp;&nbsp;&nbsp;";
$str .= "<button type=button onClick='window.location=\"signal?realtime=1\"' title='Display continuous or archived signal strength on a chart'>Charts</button>\n";
$str .= "</nobr></td>";
push @col2, $str;
}
push @col2, "<th align=right><nobr>firmware version</nobr></th><td>" . `cat /etc/mesh-release`. "</td>";
push @col2, "<th align=right>system time</th><td>" . `date +'%a %b %e %Y<br>%T %Z'` . "</td>";
$uptime = `uptime`;
$uptime =~ s/^ ..:..:.. up //;
($uptime, $load) = $uptime =~ /(.*), load average: (.*)/;
push @col2, "<th align=right>uptime<br>load average</th><td>$uptime<br>$load</td>";
$str = "<th align=right>free space</th><td><nobr>flash = ";
$space = get_free_space("/overlay");
$str .= $space < 100 ? "<blink><b>$space KB</b></blink>" : "$space KB";
$str .= "</nobr><br><nobr>/tmp = ";
$space = get_free_space("/tmp");
$str .= $space < 3000 ? "<blink><b>$space KB</b></blink>" : "$space KB";
$str .= "</nobr><br><nobr>memory = ";
$space = get_free_mem();
$str .= $space < 500 ? "<blink><b>$space KB</b></blink>" : "$space KB";
$str .= "</nobr></td>";
push @col2, $str;
push @col2, "<th align='right'>OLSR Entries</th><td><nobr>Total = $olsrTotal<nobr><br><nobr>Nodes = $olsrNodes<nobr></td>"; #display OLSR numbers
# now print the tables
print "<br><br><table>\n";
print "<tr><td valign=top><table cellpadding=4>\n";
foreach(@col1) { print "<tr>$_</tr>\n" }
print "</table></td><td valign=top><table cellpadding=4>\n";
foreach(@col2) { print "<tr>$_</tr>\n" }
print "</table></td></tr></table>\n";
# end
print "</center>\n";
print "</form>\n";
show_debug_info();
show_parse_errors();
page_footer();
print "</body>\n";
print "</html>\n";

View File

@ -1,206 +0,0 @@
#!/usr/bin/perl
=for comment
Part of AREDN -- Used for creating Amateur Radio Emergency Data Networks
Copyright (C) 2015 Conrad Lara
See Contributors file for additional contributors
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation version 3 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional Terms:
Additional use restrictions exist on the AREDN(TM) trademark and logo.
See AREDNLicense.txt for more info.
Attributions to the AREDN Project must be retained in the source code.
If importing this code into a new or existing project attribution
to the AREDN project must be added to the source code.
You must not misrepresent the origin of the material contained within.
Modified versions must be modified to attribute to the original source
and be marked in reasonable ways as differentiate it from the original
version.
=cut
BEGIN {push @INC, '/www/cgi-bin'};
use perlfunc;
chomp (${wifiif}=`uci -q get 'network.wifi.ifname'`);
$phy=get_wlan2phy("${wifiif}");
@files = ( "/etc/config/",
"/etc/config.mesh/",
"/etc/local/",
"/etc/mesh-release",
"/tmp/etc/",
"/var/run/hosts_olsr",
"/tmp/rssi.dat",
"/tmp/rssi.log",
"/tmp/zombie.log",
"/tmp/olsrd.log",
"/tmp/manager.log",
"/tmp/manager.log.0",
"/tmp/AutoDistReset.log",
"/sys/kernel/debug/ieee80211/phy0/ath9k/ack_to",
"/sys/kernel/debug/ieee80211/phy1/ath9k/ack_to",
"/etc/board.json"
);
@sensitive = ( "/etc/config/vtun",
"/etc/config.mesh/vtun",
"/etc/httpd.conf",
);
@cmds = ( "cat /proc/cpuinfo",
"cat /proc/meminfo",
"df -k",
"dmesg",
"ifconfig",
"iptables -t filter -L -v",
"iptables -t nat -L -v",
"iptables -t mangle -L -v",
"ip route list",
"ip route list table 29",
"ip route list table 30",
"ip route list table 31",
"ip route list table main",
"ip route list table default",
"ip rule list",
"iwinfo",
"iwinfo ${wifiif} assoclist",
"iw phy ${phy} info",
"iw dev ${wifiif} info",
"iw dev ${wifiif} scan",
"iw dev ${wifiif} station dump",
"logread",
"md5sum /www/cgi-bin/*",
"echo /all | nc 127.0.0.1 2006",
"opkg list-installed",
"ps -w",
"/usr/local/bin/get_hardwaretype",
"/usr/local/bin/get_boardid",
"/usr/local/bin/get_model",
"/usr/local/bin/get_hardware_mfg",
);
@cmds_ubnt = (
"cat /dev/mtd0|grep 'U-Boot'|head -n1",
);
$FREE_SPACE_TMP=get_free_space("/tmp");
$mfg = `/usr/local/bin/get_hardware_mfg`;
chomp($mfg);
if ($FREE_SPACE_TMP eq "N/A" || $FREE_SPACE_TMP <= 2*1024) {
exit 1;
}
system ("rm", "-r", "-f", "/tmp/sd");
foreach $path (@files) {
next if (! -e $path and ! -d $path);
if ( $path =~ /^\/(.*\/).*\/$/ ) {
my $rpath = $1;
system("mkdir", "-p", "/tmp/sd/$rpath");
system("cp","-r","-p","$path","/tmp/sd/$rpath");
} else {
$path =~ /^(.*\/).*/;
my $sourcepath = $1;
system("mkdir", "-p", "/tmp/sd/$sourcepath");
system("cp","-r","-p","$path","/tmp/sd/$path");
}
}
#Remove sensitive files
foreach $path (@sensitive) {
if ( $path =~ /^\/(.*)/ ) {
my $sourcepath = $1;
system("rm", "-r", "-f", "/tmp/sd/$sourcepath");
}
}
#Remove passwords from config files
system ("cat /tmp/sd/etc/config/wireless | sed -e 's/ key.*\$/ key \*\*\*\*\*\*/' > /tmp/sd/etc/config/wireless.sav");
unlink "rm /tmp/sd/etc/config/wireless";
rename "/tmp/sd/etc/config/wireless.sav", "/tmp/sd/etc/config/wireless";
system ("cat /tmp/sd/etc/config.mesh/_setup | sed -e 's/_key =.*\$/_key =/' > /tmp/sd/etc/config.mesh/_setup.sav");
unlink "/tmp/sd/etc/config.mesh/_setup";
rename "/tmp/sd/etc/config.mesh/_setup.sav", "/tmp/sd/etc/config.mesh/_setup";
system("touch","/tmp/sd/data.txt");
open (my $CMDS_OUT, '>', '/tmp/sd/data.txt') or die "Could not open dump file";
foreach $cmd (@cmds) {
print $CMDS_OUT "========== $cmd ==========\n";
open(my $CMD_PIPE, "-|", $cmd ) or next;
while (<$CMD_PIPE>) {
print { $CMDS_OUT } $_;
}
}
if ( $mfg eq "Ubiquiti" ) {
foreach $cmd (@cmds_ubnt) {
print $CMDS_OUT "========== $cmd (UBNT only) ==========\n";
open(my $CMD_PIPE, "-|", $cmd ) or next;
while (<$CMD_PIPE>) {
print { $CMDS_OUT } $_;
}
}
}
close ($CMDS_OUT);
system("tar", "-zcf", "/tmp/supportdata.tgz", "-C", "/tmp/sd", "./");
# Cleanup the temp files
system ("rm", "-r", "-f", "/tmp/sd");
$nodename=`uname -n`;
chomp($nodename);
$tstamp=`date +%Y%m%d%H%M`;
chomp($tstamp);
open(my $SDFH, '<', "/tmp/supportdata.tgz") or exit(1);
binmode $SDFH;
if (exists $ENV{GATEWAY_INTERFACE}) {
print "Content-type: application/x-gzip\r\n";
print "Content-Disposition: attachment; filename=supportdata-$nodename-$tstamp.tgz\r\n";
print "\r\n";
print while <$SDFH>;
undef ($SDFH);
unlink("/tmp/supportdata.tgz");
} else {
undef ($SDFH);
unlink ("/tmp/supportdata-$nodename-$tstamp.tgz"); # Shouldn't exist but lets be sure
system ("mv", "/tmp/supportdata.tgz", "/tmp/supportdata-$nodename-$tstamp.tgz");
if ($? != 0) {
print "Failed to rename the support data file.\n It may be present at /tmp/supportdata.tgz\n";
exit(1);
} else {
print "File created: /tmp/supportdata-$nodename-$tstamp.tgz\n";
print "Please copy this file and remove from the node\n";
print "to free up resources.\n"
}
}

View File

@ -1,77 +0,0 @@
#!/usr/bin/perl
=for comment
Part of AREDN -- Used for creating Amateur Radio Emergency Data Networks
Copyright (C) 2015 Conrad Lara
See Contributors file for additional contributors
Copyright (c) 2013 David Rivenburg et al. BroadBand-HamNet
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation version 3 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional Terms:
Additional use restrictions exist on the AREDN(TM) trademark and logo.
See AREDNLicense.txt for more info.
Attributions to the AREDN Project must be retained in the source code.
If importing this code into a new or existing project attribution
to the AREDN project must be added to the source code.
You must not misrepresent the origin of the material contained within.
Modified versions must be modified to attribute to the original source
and be marked in reasonable ways as differentiate it from the original
version.
=cut
BEGIN {push @INC, '/www/cgi-bin'};
use perlfunc;
http_header();
html_header("$node system information", 1);
print "<body><pre>\n";
print " node: ", nvram_get("node"), "\n";
print "model: ", `/usr/local/bin/get_model`, "\n";
if ( is_hardware_supported() !=1 ){
print "<font color=\"red\">!!!! UNSUPPORTED DEVICE !!!!</font>\n";
print "boardid: " , hardware_boardid() , "\n";
if ( is_hardware_supported == 0 ) {
print "<font color=\"red\">Device HAS BEEN TESTED AS UNSUPPORTED</font>\n";
}
else {
print "<font color=\"red\">Device has not been tested. Please file a ticket with your experiences.</font>\n";
}
print "\n";
}
foreach(`ifconfig -a`)
{
next unless /^(\S+) .*HWaddr (\S+)/;
printf "%-6s %s\n", $1, $2;
}
print "\n/proc/cpuinfo\n";
system "cat /proc/cpuinfo";
print "\nnvram\n";
system "uci -c /etc/local/uci show 2>&1";
print "</pre>\n";
page_footer();
print "</body>\n";
print "</html>\n";

View File

@ -1,290 +0,0 @@
=for comment
Part of AREDN -- Used for creating Amateur Radio Emergency Data Networks
Copyright (c) 2015 Darryl Quinn
See Contributors file for additional contributors
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation version 3 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional Terms:
Additional use restrictions exist on the AREDN(TM) trademark and logo.
See AREDNLicense.txt for more info.
Attributions to the AREDN Project must be retained in the source code.
If importing this code into a new or existing project attribution
to the AREDN project must be added to the source code.
You must not misrepresent the origin of the material contained within.
Modified versions must be modified to attribute to the original source
and be marked in reasonable ways as differentiate it from the original
version.
=cut
sub get_server_dns()
{
my @list;
my $uciresult;
my ($rc,$dns)=&uci_get_indexed_option("vtun","network","0","dns");
return $dns;
}
#################################
# get base network from config
#################################
sub get_server_network_address()
{
my @list;
my $uciresult;
my ($rc,$server_net)=&uci_get_indexed_option("vtun","network","0","start");
if($rc eq 0 and $server_net ne "")
{
# to facilitate overrides (ie. moving the server to a new node)
# read the file into $mac
@list = split('\.', $server_net);
}
else
{
# or, calc based on eth0 mac address, then store it.
$mac=get_mac("eth0");
@MACS=split(/:/, $mac);
push @list, "172";
push @list, "31";
push @list, hex $MACS[5];
# strip off the high bits
push @list, ((hex $MACS[4]) << 2) & 255;
$server_net=sprintf("%d.%d.%d.%d",$list[0],$list[1],$list[2],$list[3]);
#($rc,$uciresult)=&uci_add_sectiontype("vtun","network");
($rc,$uciresult)=&uci_set_indexed_option("vtun","network","0","start",$server_net);
$rc=&uci_commit("vtun");
}
return @list;
}
sub get_active_tun()
{
my @active_tun;
foreach(`ps -w|grep vtun|grep ' tun '`)
{
@parts = $_ =~ /.*\:.*-(172-31-.*)\stun\stun.*/g;1;
$parts[0] =~ s/\-/\./g;
push(@active_tun,$parts[0]);
}
return @active_tun;
}
# INPUT arg: Array of active tunnel IP's, IP of the tunnel network you are checking
sub is_tunnel_active()
{
my ($n, @active_tun) = @_;
my $match=0;
foreach(@active_tun){
#print "a=$_, n=$n\n";
if($n eq $_) {
$match = 1;
last;
}
}
return $match; # the return value of the do block
}
sub get_tunnel_option()
{
my ($optionname) = @_;
return &uci_get_indexed_option("aredn", "tunnel", 0, "$optionname");
}
sub get_tunnel_maxclients()
{
my ($rc, $maxclients) = &get_tunnel_option("maxclients");
return $rc ? 10 : $maxclients;
}
sub get_tunnel_maxservers()
{
my ($rc, $maxservers) = &get_tunnel_option("maxservers");
return $rc ? 10 : $maxservers;
}
sub get_tunnel_interface_count()
{
my $count = `uci show network_tun | fgrep =interface | wc -l`;
return $? ? "0" : $count;
}
##########################
# Add OLSRD interfaces - NOT NEEDED
##########################
sub add_olsrd_interfaces() {
my ($sname,$tunstart,$tuncount) = @_;
my $tuns;
&uci_add_named_section("olsrd",$sname,"Interface");
&uci_set_named_option("olsrd",$sname,"Ip4Broadcast","255.255.255.255");
# delete all interfaces first
&uci_delete_named_option("olsrd",$sname,"interfaces");
for my $i (0..$tuncount-1) {
$tuns=$tuns . " " if $i;
$tuns=$tuns . "tun" . $tunstart;
$tunstart++;
}
&uci_add_list_named_option("olsrd",$sname,"interfaces","$tuns");
&uci_commit("olsrd");
}
##########################
# Add network interfaces tun50 thru tun69 - called on install
##########################
sub add_network_interfaces() {
&uci_set_indexed_option("aredn","tunnel",0,"maxclients","10");
&uci_set_indexed_option("aredn","tunnel",0,"maxservers","10");
&uci_commit("aredn");
&uci_clone("aredn");
for (my $tunnum=50; $tunnum<=69; $tunnum++)
{
&uci_add_named_section("network_tun","tun${tunnum}","interface");
&uci_set_named_option("network_tun","tun${tunnum}","ifname","tun${tunnum}");
&uci_set_named_option("network_tun","tun${tunnum}","proto","none");
}
&uci_commit("network_tun");
&uci_clone("network_tun");
# required to support node_setup script
system "cat /etc/config.mesh/network_tun >> /etc/config.mesh/network";
system "cat /etc/config.mesh/network_tun >> /etc/config/network";
}
#################################
# Check Freespace on / filesystem
#################################
sub check_freespace()
{
my $fs = `df / | grep -v '^Filesystem' | awk 'NF=6{print \$4}NF==5{print \$3}{}'`;
chomp $fs;
return $fs;
}
sub vpn_setup_required()
{
my ($navpage) = @_;
http_header();
html_header("$node setup", 1);
print "<body><center><table width=790>";
print "<tr><td>\n";
navbar($navpage);
print "</td></tr>";
#################
# messages
#################
if(@cli_err)
{
print "<tr><td align=center><b>ERROR:<br>";
foreach(@cli_err) { print "$_<br>" }
print "</b></td></tr>\n";
}
print "<tr><td align=center><br><b>";
print "Tunnel software needs to be installed.<br/>";
print "<form method='post' action='/cgi-bin/$navpage' enctype='multipart/form-data'>\n";
print "<input type=submit name=button_install value='Click to install' class='btn_tun_install' />";
print "</form>";
print "</b></td></tr>\n";
print "</table></center></body></html>\n";
exit;
}
#################################
# Install VTUN Components/config
#################################
sub install_vtun
{
# check free disk space - get real values
$freespace=&check_freespace();
if($freespace < 600)
{
push @cli_err, "Insuffient free disk space!";
# redirect back to admin page
} else {
# Update/Install VTUN
system "opkg update >/dev/null 2>&1";
if ($? eq 0)
{
system "opkg install kmod-tun zlib liblzo vtun >/dev/null 2>&1";
if ($? eq 0)
{
# add network interfaces
add_network_interfaces();
# create UCI config file
system("touch /etc/config/vtun");
# create options section
$rc=&uci_add_sectiontype("vtun","options");
$rc=&uci_commit();
http_header();
html_header("TUNNEL INSTALLATION IN PROGRESS", 0);
print "</head>\n";
print "<body><center>\n";
print "<h2>Installing tunnel software...</h2>\n";
print "<h1>DO NOT REMOVE POWER UNTIL THE INSTALLATION IS FINISHED</h1>\n";
print "</center><br>\n";
unless($debug)
{
print "
<center><h2>The node is rebooting</h2>
<h3>When the node has fully rebooted you can reconnect with<br>
<a href='http://$node.local.mesh:8080/'>http://$node.local.mesh:8080/</a><br>
</h3>
</center>
";
page_footer();
print "</body></html>";
system "/sbin/reboot" unless $debug;
exit;
}
} else {
push @cli_err,"Package installation failed!";
}
} else {
push @cli_err,"Package update failed!";
}
}
}
sub generate_ips()
{
my ($netip) = @_;
my $serverip = &addrtoint($netip);
$serverip++;
$serverip++;
$serverip=inttoaddr($serverip);
my $clientip = &addrtoint($netip);
$clientip++;
$clientip=inttoaddr($clientip);
return ($clientip, $serverip);
}
sub addrtoint { return( unpack( "N", pack( "C4", split( /[.]/,$_[0]))))};
sub inttoaddr { return( join( ".", unpack( "C4", pack( "N", $_[0]))))};
#weird uhttpd/busybox error requires a 1 at the end of this file
1

View File

@ -1,306 +0,0 @@
=for comment
Part of AREDN -- Used for creating Amateur Radio Emergency Data Networks
Copyright (c) 2015 Darryl Quinn
See Contributors file for additional contributors
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation version 3 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional Terms:
Additional use restrictions exist on the AREDN(TM) trademark and logo.
See AREDNLicense.txt for more info.
Attributions to the AREDN Project must be retained in the source code.
If importing this code into a new or existing project attribution
to the AREDN project must be added to the source code.
You must not misrepresent the origin of the material contained within.
Modified versions must be modified to attribute to the original source
and be marked in reasonable ways as differentiate it from the original
version.
=cut
### UCI Helpers --GET-- --GET-- --GET-- --GET-- --GET-- --GET-- --GET-- --GET-- --GET-- --GET-- --GET-- ###
sub uci_get_sectiontype_count()
{
my ($config, $stype)=@_;
my $cmd=sprintf('uci show %s|egrep %s\.\@%s.*=%s|wc -l',$config,$config,$stype,$stype);
my $res=`$cmd`;
my $rc=$?;
chomp($res);
return ($rc,$res);
}
sub uci_get_indexed_option()
{
my ($config,$stype,$index,$key)=@_;
my $cmd=sprintf('uci get %s.@%s[%s].%s',$config,$stype,$index,$key);
my $res=`$cmd`;
my $rc=$?;
chomp($res);
return ($rc,$res);
}
sub uci_get_indexed_sectiontype()
{
my ($config,$stype,$index)=@_;
my $cmd=sprintf('uci get %s.@%s[%s]',$config,$stype,$index);
my @res=`$cmd`;
my $rc=$?;
chomp($res);
return ($rc, @res);
}
sub uci_get_named_option()
{
my ($config,$sname,$option)=@_;
my $cmd=sprintf('uci get %s.%s.%s',$config,$sname,$option);
my @res=`$cmd`;
my $rc=$?;
chomp($res);
return ($rc, @res);
}
# Returns an array of section names
sub uci_get_names_by_sectiontype()
{
my ($config,$stype)=@_;
my @names=();
my $cmd=sprintf('uci show %s|egrep vtun\..*=%s',$config,$stype);
my @lines=`$cmd`;
if (scalar @lines) {
foreach $l (0..@lines-1) {
@parts=();
chomp($lines[$l]);
@parts = $lines[$l] =~ /^$config\.(.*)\=$stype/g;1;
if (scalar(@parts) eq 1) {
push(@names,$parts[0]);
}
}
}
return @names;
}
# Returns all lines of config for a named section
sub uci_get_named_section()
{
my ($config,$sname)=@_;
my $cmd=sprintf('uci show %s.%s',$config,$sname);
my @lines=`$cmd`;
my %section;
if (scalar @lines) {
foreach (@lines)
{
$l=$_;
chomp($l);
# @parts=();
@parts = $l =~ /^$config\.$sname\.(.*)\=(.*)/g;1;
if (scalar(@parts) eq 2) {
$parts[1] =~ s/^\'|\'+$//g;
$section->{$parts[0]} = $parts[1];
}
}
}
return $section;
}
# RETURNS an array of hashes
sub uci_get_all_indexed_by_sectiontype()
{
my ($config,$stype)=@_;
my @sections=();
my $cmd=sprintf('uci show %s|grep %s.@%s',$config,$config,$stype);
my @lines=`$cmd`;
if (scalar @lines) {
my $lastindex=0;
my $sect={};
my @parts=();
foreach $l (0..@lines-1) {
@parts=();
chomp($lines[$l]);
@parts = $lines[$l] =~ /^$config\.\@$stype\[(.*)\]\.(.*)\=(.*)/g;1;
if (scalar(@parts) eq 3) {
if ($parts[0] ne $lastindex) {
push @sections, $sect;
$sect={};
$lastindex=$parts[0];
}
$parts[2] =~ s/^\'|\'+$//g;
$sect->{$parts[1]} = $parts[2];
next;
}
}
push (@sections, $sect);
}
return (@sections);
}
### UCI Helpers --ADD-- ###
sub uci_add_sectiontype()
{
my ($config,$stype)=@_;
system `touch /etc/config/$config` if (! -f "/etc/config/$config");
my $cmd=sprintf('uci add %s %s',$config,$stype);
my $res=`$cmd`;
my $rc=$?;
return $rc;
}
sub uci_add_list_named_option()
{
my ($config,$sname,$option,$val)=@_;
my $cmd=sprintf('uci add_list %s.%s.%s=\'%s\'',$config,$sname,$option,$val);
my $res=`$cmd`;
my $rc=$?;
return $rc;
}
sub uci_add_named_section()
{
my ($config,$sname,$stype)=@_;
system `touch /etc/config/$config` if (! -f "/etc/config/$config");
my $cmd=sprintf('uci set %s.%s=%s',$config,$sname,$stype);
#uci set olsrd.tunnelserver=Interface
my $res=`$cmd`;
my $rc=$?;
return $rc;
}
sub uci_rename_named_section()
{
my ($config,$sname,$snewname)=@_;
my $cmd=sprintf('uci rename %s.%s=%s',$config,$sname,$snewname);
#uci rename vtun.server_2=server_1
my $res=`$cmd`;
my $rc=$?;
return $rc;
}
sub uci_delete_named_section()
{
my ($config,$sname,$stype)=@_;
system `touch /etc/config/$config` if (! -f "/etc/config/$config");
my $cmd=sprintf('uci delete "%s.%s"',$config,$sname);
#uci delete vtun.server_9
my $res=`$cmd`;
my $rc=$?;
return $rc;
}
### UCI Helpers --DELETE-- ###
sub uci_delete_option()
{
my ($config,$stype,$index,$option)=@_;
my $cmd=sprintf('uci delete %s.@%s[%s].%s',$config,$stype,$index,$option);
my $res=`$cmd`;
my $rc=$?;
chomp($res);
return ($rc,$res);
}
sub uci_delete_named_option()
{
my ($config,$sname,$option)=@_;
my $cmd=sprintf('uci delete %s.%s.%s',$config,$sname,$option);
my $res=`$cmd`;
my $rc=$?;
return $rc;
}
sub uci_delete_indexed_type()
{
my ($config,$stype,$index)=@_;
my $cmd=sprintf('uci delete %s.@%s[%s]',$config,$stype,$index);
my $res=`$cmd`;
my $rc=$?;
chomp($res);
return ($rc,$res);
}
### UCI Helpers --SET-- ###
sub uci_set_named_option()
{
my ($config,$sname,$option,$val)=@_;
my $cmd=sprintf('uci set %s.%s.%s="%s"',$config,$sname,$option,$val);
#uci set olsrd.tunnelserver.Ip4Broadcast=255.255.255.255
my $res=`$cmd`;
my $rc=$?;
return $rc;
}
## issue with multiple sections added!
sub uci_set_indexed_option()
{
my ($config,$stype,$index,$option,$val)=@_;
system `touch /etc/config/$config` if (! -f "/etc/config/$config");
if (&uci_get_sectiontype_count($config,$stype) eq 0) {
my $rc=&uci_add_sectiontype($config,$stype);
if ($rc) { return $rc};
}
my $cmd=sprintf('uci set %s.@%s[%s].%s="%s"',$config,$stype,$index,$option,$val);
my $res=`$cmd`;
my $rc=$?;
return $rc;
}
### UCI Helpers --OTHER-- ###
sub uci_commit()
{
my ($config)=@_;
my $cmd=sprintf('uci commit %s',$config);
my $res=`$cmd`;
my $rc=$?;
return $rc;
}
sub uci_revert()
{
my ($config)=@_;
my $cmd=sprintf('uci revert %s',$config);
my $res=`$cmd`;
my $rc=$?;
chomp($res);
return ($rc,$res);
}
sub uci_clone()
{
my ($config)=@_;
# TODO: add protection of overwriting specific templated files in /etc/config.mesh
my $cmd=sprintf('cp /etc/config/%s /etc/config.mesh',$config);
my $res=`$cmd`;
my $rc=$?;
return $rc;
}
### UCI Helpers END ###
#weird uhttpd/busybox error requires a 1 at the end of this file
1

View File

@ -1,519 +0,0 @@
#!/usr/bin/perl
=for comment
Part of AREDN -- Used for creating Amateur Radio Emergency Data Networks
Copyright (c) 2015 Darryl Quinn
See Contributors file for additional contributors
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation version 3 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional Terms:
Additional use restrictions exist on the AREDN(TM) trademark and logo.
See AREDNLicense.txt for more info.
Attributions to the AREDN Project must be retained in the source code.
If importing this code into a new or existing project attribution
to the AREDN project must be added to the source code.
You must not misrepresent the origin of the material contained within.
Modified versions must be modified to attribute to the original source
and be marked in reasonable ways as differentiate it from the original
version.
=cut
$debug = 0;
BEGIN {push @INC, '/www/cgi-bin'};
use perlfunc;
use ucifunc;
use tunfunc;
$VPNVER="1.1";
$config = nvram_get("config");
$node = nvram_get("node");
$node = "NOCALL" if $node eq "";
read_postdata();
#################################
# save clients from form to UCI
#################################
sub save_clients()
{
my $enabled_count=0;
for ($i=0; $i < $parms{"client_num"}; $i++) {
my $net = $parms{"client${i}_netip"};
$rc=&uci_add_named_section("vtun","client_$i","client");
# generate the clientip and serverip
my ($clientip, $serverip) = &generate_ips($net);
$rc=&uci_set_named_option("vtun","client_$i","netip",$net);
push(@cli_err,"Problem saving UCI vtun client net IP (#$i): $rc") if $rc;
$rc=&uci_set_named_option("vtun","client_$i","enabled",$parms{"client${i}_enabled"});
push(@cli_err,"Problem saving UCI vtun client enabled (#$i): $rc") if $rc;
$rc=&uci_set_named_option("vtun","client_$i","name",$parms{"client${i}_name"});
push(@cli_err,"Problem saving UCI vtun client name (#$i): $rc") if $rc;
$rc=&uci_set_named_option("vtun","client_$i","contact",$parms{"client${i}_contact"});
push(@cli_err,"Problem saving UCI vtun client contact (#$i): $rc") if $rc;
$rc=&uci_set_named_option("vtun","client_$i","passwd",$parms{"client${i}_passwd"});
push(@cli_err,"Problem saving UCI vtun client password (#$i): $rc") if $rc;
# generate the VTUN NODE name based on the node name and netip
$net=~ s/\./\-/g;
#VTUN NODE name must not be more than 23 chars long to avoid username limits!
my $vtun_node_name=substr($parms{"client${i}_name"},0,23) . "-" . $net;
$rc=&uci_set_named_option("vtun","client_$i","clientip",$clientip);
push(@cli_err,"Problem saving UCI vtun client client IP (#$i): $rc") if $rc;
$rc=&uci_set_named_option("vtun","client_$i","serverip",$serverip);
push(@cli_err,"Problem saving UCI vtun client server IP (#$i): $rc") if $rc;
$rc=&uci_set_named_option("vtun","client_$i","node",$vtun_node_name);
push(@cli_err,"Problem saving UCI vtun client name (#$i): $rc") if $rc;
$enabled_count++ if $parms{"client${i}_enabled"};
}
my $maxclients = &get_tunnel_maxclients();
push(@cli_err,"Number of clients enabled ($enabled_count) exceeds maxclients ($maxclients); only the first $enabled_count will activate.") if $enabled_count > $maxclients;
}
#################################
# save network info to UCI
#################################
sub save_network()
{
push(@cli_err,"The third octet of the network MUST be from 0 to 255") unless (($parms{server_net1}>=0) && ($parms{server_net1}<=255) && ($parms{server_net1} ne ''));
push(@cli_err,"The last octet of the network MUST be from 0 to 255") unless (($parms{server_net2}>=0) && ($parms{server_net2}<=255) && ($parms{server_net2} ne ''));
push(@cli_err,"The last octet of the network MUST be a multiple of 4 (ie. 0,4,8,12,16,...)") if ($parms{server_net2} % 4);
push(@cli_err,"Not a valid DNS name") unless (validate_fqdn($parms{dns}));
if (not @cli_err)
{
my $net=sprintf("%d.%d.%d.%d",172,31,$parms{server_net1},$parms{server_net2});
push @cli_err, "Problem saving the server network values!" if (&uci_set_indexed_option("vtun","network",0,"start",$net));
push @cli_err, "Problem saving the server DNS name!" if (&uci_set_indexed_option("vtun","network",0,"dns",$dns));
}
}
#################
# page checks
#################
if($parms{button_reboot})
{
system "/sbin/reboot";
}
if($parms{button_install})
{
install_vtun();
}
reboot_required() if($config eq "" or -e "/tmp/reboot-required");
&vpn_setup_required("vpn") unless(-e "/usr/sbin/vtund" );
#################
# If RESET, revert the UCI file
#################
if($parms{button_reset})
{
($rc,$res)=&uci_revert("vtun");
($rc,$res)=&uci_delete_option("vtun","network",0,"start");
($rc,$res)=&uci_delete_option("vtun","network",0,"dns");
$rc=&uci_commit("vtun");
}
#################
# get vtun network address
#################
@netw = ();
@netw = get_server_network_address();
$dns = get_server_dns();
#################
# If RESET or FIRST TIME, load clients/servers from file into parms
#################
if($parms{button_reset} or not $parms{reload})
{
# revert to previous state on initial load
($rc,$res)=&uci_revert("vtun");
# load clients from UCI
&get_client_info();
$parms{server_net1}=$netw[2];
$parms{server_net2}=$netw[3];
$parms{dns}=$dns;
# initialize the "add" entries to clear them
foreach $var (qw(client_add_enabled client_add_name client_add_passwd))
{
$parms{$var} = "";
$parms{$var} = "0" if($var eq 'client_add_enabled');
}
}
#################
# load clients from FORM and validate
#################
for($i =0 , @list = (); $i < $parms{client_num}; $i++) { push @list, $i }
push @list, "_add";
$client_num = 0;
foreach $val (@list)
{
foreach $var (qw(enabled name passwd netip contact))
{
$varname = "client${val}_$var";
$parms{$varname} = "0" if($val eq "enabled" and $parms{$varname} eq "");
$parms{$varname} = "" unless $parms{$varname};
$parms{$varname} =~ s/^\s+//;
$parms{$varname} =~ s/\s+$//;
if($val ne "_add")
{
if($parms{$varname} eq "" and ($var eq "enabled"))
{
$parms{$varname} = "0";
}
}
eval sprintf("\$%s = \$parms{%s}", $var, $varname);
}
# Validate ADDed values
if($val eq "_add")
{
# skip any null values on add or save
next unless ($enabled or $name or $passwd or $contact) and ($parms{client_add} or $parms{button_save});
} # no delete capabilities as net renumbering is not allowed
if($val eq "_add" and $parms{button_save})
{
push @cli_err, "$val this client must be added or cleared out before saving changes";
next;
}
# password MUST be alphanumeric (no special chars)
push @cli_err, "The password cannot contain non-alphanumeric characters (#$client_num)" if ($passwd =~ m/[^a-zA-Z0-9@]/);
push @cli_err, "The password must contain at least one alphabetic character (#$client_num)" if ($passwd !~ /\D/);
push @cli_err, "A client name is required" if($name eq "");
push @cli_err, "A client password is required" if($passwd eq "");
next if $val eq "_add" and @cli_err and $cli_err[-1] =~ /^$val /;
$parms{"client${client_num}_enabled"} = $enabled;
$parms{"client${client_num}_name"} = uc $name;
$parms{"client${client_num}_passwd"} = $passwd;
$parms{"client${client_num}_netip"} = $netip;
# Commit the data for this client
$client_num++;
# Clear out the ADD values
if($val eq "_add")
{
foreach $var (qw(net enabled name passwd netip contact))
{
$parms{"client_add_${var}"} = "";
}
}
}
$parms{client_num} = $client_num;
#################
# SAVE the server network numbers and dns into the UCI
#################
$netw[2]=$parms{server_net1};
$netw[3]=$parms{server_net2};
$dns=$parms{dns};
$rc=save_network();
#################
# SAVE the clients
#################
$rc=save_clients();
#################
# save configuration (commit)
#################
if($parms{button_save} and not @cli_err)
{
if (&uci_commit("vtun"))
{
push(@errors,"Problem committing UCI vtun");
}
&uci_clone("vtun");
unless($debug == 3)
{
# Regenerate olsrd files and restart olsrd
push(@errors,"Problem restarting olsrd") if system "/etc/init.d/olsrd restart > /dev/null 2>&1";
push(@errors,"Problem restaring vtundsrv") if system "/etc/init.d/vtundsrv restart > /dev/null 2>&1";
# delay to allow clients to connect and have an accurate "cloud" status
sleep 5;
}
}
@active_tun=&get_active_tun();
######################################################################################
# generate the page
######################################################################################
http_header() unless $debug == 2;
html_header("$node setup", 1);
print "<body><center>\n";
alert_banner();
print "<form id=vpn method=post action=/cgi-bin/vpn.pl enctype='multipart/form-data'>\n" unless $debug == 2;
print "<form method=post action=test>\n" if $debug == 2;
print "<table width=790>\n";
#################
# Navigation bar
#################
print "<tr><td>\n";
navbar("vpn");
print "</td></tr>\n";
#################
# control buttons
#################
print "<tr><td align=center>";
print "<a href='/help.html#vpn' target='_blank'>Help</a>";
print "&nbsp;&nbsp;&nbsp;\n";
print "<input type=submit name=button_save value='Save Changes' title='Save and use these settings now (takes about 20 seconds)'>&nbsp;\n";
print "<input type=submit name=button_reset value='Reset Values' title='Revert to the last saved settings'>&nbsp;\n";
print "<input type=submit name=button_refresh value='Refresh' title='Refresh this page'>&nbsp;\n";
print "<tr><td>&nbsp;</td></tr>\n";
push @hidden, "<input type=hidden name=reload value=1></td></tr>";
#################
# messages
#################
if(@cli_err)
{
print "<tr><td align=center><b>ERROR:<br>";
foreach(@cli_err) { print "$_<br>" }
print "</b></td></tr>\n";
}
if($parms{button_save})
{
if(@cli_err)
{
print "<tr><td align=center><b>Configuration NOT saved!</b></td></tr>\n";
#}
#elsif(@errors)
#{
#print "<tr><td align=center><b>Configuration saved, however:<br>";
foreach(@errors) { print "$_<br>" }
print "</b></td></tr>\n";
}
else
{
print "<tr><td align=center><b>Configuration saved and is now active.</b></td></tr>\n";
}
print "<tr><td>&nbsp;</td></tr>\n";
}
#################
# everything else
#################
if($config eq "mesh")
{
print "<tr><td align=center valign=top>\n";
&print_vpn_clients();
print "</td></tr>\n";
print "<tr><td><hr></td></tr>\n";
}
print "</table>\n";
print "<p style='font-size:8px'>Tunnel v${VPNVER}</p>";
push @hidden, "<input type=hidden name=client_num value=$parms{client_num}>";
#################
# add hidden form fields
#################
foreach(@hidden) { print "$_\n" }
#################
# close the form
#################
print "</form></center>\n";
show_debug_info();
#################
# close the html
#################
page_footer();
print "</body></html>\n";
exit;
##################
# page subsections
##################
######################################################
# List the clients allowed to connect to this server
######################################################
sub print_vpn_clients()
{
print "<table cellpadding=0 cellspacing=0>";
print "<br /><tr class=tun_network_row><td colspan=6 align=center valign=top>Tunnel Server Network: ";
printf("%d.%d.",$netw[0],$netw[1]);
print "<input type='text' name='server_net1' size='3' maxlen='3' value='$netw[2]' onChange='form.submit()' title='from 0-255' >";
print ".";
print "<input type='text' name='server_net2' size='3' maxlen='3' value='$netw[3]' onChange='form.submit()' title='from 0-255 in multiples of 4. (ie. 0,4,8,12,16...252)' >";
print "<br /><hr>Tunnel Server DNS Name: ";
print "<input type='text' name='dns' size='30' value='$dns' onChange='form.submit()' ></td></tr>";
print "</table>";
#print "<hr />";
print "<table cellpadding=0 cellspacing=0>";
print "<tr><th colspan=6 align=center valign=top>&nbsp;</th></tr>\n";
print "<tr class=tun_client_row>";
print "<tr><th colspan=6>Allow the following clients to connect to this server:</th></tr>\n";
print "<tr><th colspan=6><hr></th></tr>\n";
print "<tr><th>Enabled?</th><th>Client</th><th>Pwd</th><th>Net</th><th>Active&nbsp;</td><th>Action</th></tr>\n";
for($i = 0, @list = (); $i < $parms{client_num}; ++$i) { push @list, $i };
push @list, "_add" unless($parms{client_num} >= &get_tunnel_maxclients());
$cnum=0;
foreach $val (@list)
{
foreach $var (qw(enabled name passwd contact))
{
eval sprintf("\$%s = \$parms{client%s_%s}", $var, $val, $var);
}
print "<tr class=tun_client_add_row><td height=10></td></tr>\n" if $val eq "_add" and scalar(@list) > 1;
print "<tr class='tun_client_list2 tun_client_row'>";
print "<td class='tun_client_center_item' rowspan='2'>";
# Required to be first, so, if the checkbox is cleared, a value will still POST
print "<input type='hidden' name='client${val}_enabled' value='0'>" unless($val eq "_add");
print "<input type='checkbox' name='client${val}_enabled' value='1'";
print " onChange='form.submit()'" unless $val eq "_add";
print " checked='checked'" if $enabled;
print " title='enable this client'></td>";
print "<td><input type=text size=40 name=client${val}_name value='$name'";
print " onChange='form.submit()'" unless $val eq "_add";
# print " disabled" unless $val eq "_add";
print " title='client name'></td>";
print "<td><input type=text size=25 name=client${val}_passwd value='$passwd' ";
print " onChange='form.submit()'" unless $val eq "_add";
print " title='client password'";
#print " disabled" unless $val eq "_add";
print "></td>";
# handle rollover of netw[3]
if($netw[3]+($cnum * 4) > 252) {
$netw[2]++;
$netw[3] = 0;
$net=0;
$cnum=0;
} else {
$net=$cnum;
}
if($val eq "_add") { $lastnet=$netw[3]+(($net) * 4); }
else { $lastnet=$netw[3]+($net * 4); }
$fullnet=sprintf("%d.%d.%d.%d",$netw[0],$netw[1],$netw[2],$lastnet);
print "<td rowspan='2' class='tun_client_center_item'>&nbsp;$fullnet";
print "<input type=hidden name=client${val}_netip value='$fullnet'/></td>";
print "<td rowspan='2' class='tun_client_center_item' align=center>&nbsp;";
if (&is_tunnel_active($fullnet,@active_tun) && ($val ne "_add")) {
print "<img class='tun_client_active_img' src='/connected.png' title='Connected' />";
} else {
print "<img class='tun_client_inactive_img' src='/disconnected.png' title='Not connected' />";
}
print "</td>";
print "<td rowspan='2' class='tun_client_center_item'><input type=submit name=client_add value=Add title='Add this client'>" if($val eq "_add");
print "</td>";
print "<td rowspan='2' class='tun_client_center_item tun_client_mailto'><a href='mailto:?subject=AREDN%20Tunnel%20Connection&body=Your%20connection%20details:%0D%0AName:%20$name%0D%0APassword:%20$passwd%0D%0ANetwork:%20$fullnet%0D%0AServer%20address:%20$dns' target='_blank'><img class='tun_client_mailto_img' src='/email.png' title='Email details' /></a></td>" unless($val eq "_add");
#contact info for the tunnel
print "</tr>";
print "<tr class='tun_client_list1 tun_client_row tun_loading_css_comment'><td colspan='2' align='right'>Contact Info/Comment (Optional): <input type=text maxlength='50' size=40 name=client${val}_contact value='$contact'";
print " onChange='form.submit()'" unless ($val eq "_add" || $val eq "");
print " title='client contact info'></td>";
print "</tr>\n";
# display any errors
while(@cli_err and $cli_err[0] =~ /^$val /)
{
$err = shift @cli_err;
$err =~ s/^\S+ //;
print "<tr class=tun_client_error_row><th colspan=4>$err</th></tr>\n";
}
#push @hidden, "<input type='hidden' name='client${val}_enable' value='0'>" unless($val eq "_add");
print "<tr><td colspan=4 height=4></td></tr>\n";
$cnum++;
}
print "</table>\n";
}
#################################
# load client info from UCI
#################################
sub get_client_info()
{
my @clients=&uci_get_names_by_sectiontype("vtun","client");
my $c=0;
foreach (@clients)
{
my $myclient={};
$myclient=&uci_get_named_section("vtun",$_);
foreach $var (qw(enabled name passwd netip contact))
{
$parms{"client${c}_$var"} = $myclient->{$var};
$parms{"client${c}_$var"} = "0" if($parms{"client${c}_$var"} eq "");
$myclient->{$var} = "";
}
$c++;
}
$parms{client_num} = scalar(@clients);
}
sub DEBUGEXIT()
{
my ($text) = @_;
http_header();
html_header("$node setup", 1);
print "DEBUG-";
print $text;
print "</body>";
exit;
}

View File

@ -1,479 +0,0 @@
#!/usr/bin/perl
=for comment
Part of AREDN -- Used for creating Amateur Radio Emergency Data Networks
Copyright (c) 2015 Darryl Quinn
See Contributors file for additional contributors
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation version 3 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional Terms:
Additional use restrictions exist on the AREDN(TM) trademark and logo.
See AREDNLicense.txt for more info.
Attributions to the AREDN Project must be retained in the source code.
If importing this code into a new or existing project attribution
to the AREDN project must be added to the source code.
You must not misrepresent the origin of the material contained within.
Modified versions must be modified to attribute to the original source
and be marked in reasonable ways as differentiate it from the original
version.
=cut
$debug = 0;
BEGIN {push @INC, '/www/cgi-bin'};
use perlfunc;
use ucifunc;
use tunfunc;
$VPNVER="1.0";
$config = nvram_get("config");
$node = nvram_get("node");
$node = "NOCALL" if $node eq "";
#truncate node name down to 23 chars (max) to avoid vtun issues
#this becomes the vtun "username"
$node = substr($node,0,23);
read_postdata();
#################################
# save server connections from form to UCI
#################################
sub save_connections()
{
my $enabled_count=0;
for ($i=0; $i < $parms{"conn_num"}; $i++) {
my $net = $parms{"conn${i}_netip"};
$rc=&uci_add_named_section("vtun","server_$i","server");
# generate the clientip and serverip
my ($clientip, $serverip) = &generate_ips($net);
# generate the VTUN NODE name based on the node name and netip
$net=~ s/\./\-/g;
my $vtun_node_name=uc "$node-$net";
$rc=&uci_set_named_option("vtun","server_$i","clientip",$clientip);
push(@conn_err,"Problem saving UCI vtun connection client IP (#$i)") if $rc;
$rc=&uci_set_named_option("vtun","server_$i","serverip",$serverip);
push(@conn_err,"Problem saving UCI vtun connection server IP (#$i)") if $rc;
$rc=&uci_set_named_option("vtun","server_$i","node",$vtun_node_name);
push(@conn_err,"Problem saving UCI vtun connection name (#$i)") if $rc;
$rc=&uci_set_named_option("vtun","server_$i","contact",$contact);
push(@conn_err,"Problem saving UCI vtun contact info (#$i)") if $rc;
foreach $var (qw(enabled host passwd netip contact))
{
$rc=&uci_set_named_option("vtun","server_$i",$var,$parms{"conn${i}_$var"});
push(@conn_err,"Problem saving UCI vtun connection (#$i)") if $rc;
}
$enabled_count++ if $parms{"conn${i}_enabled"};
}
my $maxservers = &get_tunnel_maxservers();
push(@conn_err,"Number of servers enabled ($enabled_count) exceeds maxservers ($maxservers); only the first $maxservers will activate.") if $enabled_count > $maxservers;
}
#################
# page checks
#################
if($parms{button_reboot})
{
system "/sbin/reboot";
}
if($parms{button_install})
{
install_vtun();
}
reboot_required() if($config eq "" or -e "/tmp/reboot-required");
&vpn_setup_required("vpnc") unless(-e "/usr/sbin/vtund" );
#################
# If RESET, revert the UCI file
#################
if($parms{button_reset})
{
($rc,$res)=&uci_revert("vtun");
$rc=&uci_commit("vtun");
}
#################
# HANDLE connection deletes
#################
for($i = 0; $i < 10; $i++)
{
$varname="conn${i}_del";
if($parms{$varname})
{
&uci_delete_named_section("vtun","server_${i}");
for($x = $i+1; $x < 10; $x++)
{
$y=$x-1;
&uci_rename_named_section("vtun","server_$x","server_${y}");
}
}
}
#################
# If RESET or FIRST TIME, load servers into parms
#################
if($parms{button_reset} or not $parms{reload})
{
# revert to previous state on initial load
($rc,$res)=&uci_revert("vtun");
# load servers from UCI
&get_connection_info();
# initialize the "add" entries to clear them
foreach $var (qw(enabled host passwd netip contact))
{
$varname = "conn${val}_$var";
$parms{$varname} = "";
$parms{$varname} = "" if($var eq 'enabled');
}
}
#################
# load connections from FORM and validate
#################
for($i =0 , @list = (); $i < $parms{conn_num}; $i++) { push @list, $i }
push @list, "_add";
$conn_num = 0;
foreach $val (@list)
{
foreach $var (qw(enabled host passwd netip contact))
{
$varname = "conn${val}_$var";
$parms{$varname} = "0" if($val eq "enabled" and $parms{$varname} eq "");
$parms{$varname} = "" unless $parms{$varname};
$parms{$varname} =~ s/^\s+//;
$parms{$varname} =~ s/\s+$//;
if($val ne "_add")
{
if($parms{$varname} eq "" and ($var eq "enabled"))
{
$parms{$varname} = "0";
}
}
eval sprintf("\$%s = \$parms{%s}", $var, $varname);
}
# Validate ADDed values
if($val eq "_add") { next unless ($enabled or $host or $passwd or $netip or $contact) and ($parms{conn_add} or $parms{button_save}) }
else { next if $parms{"conn${val}_del"} }
# Validate password is vtun compliant
# TODO
if($val eq "_add" and $parms{button_save})
{
push @conn_err, "$val this connection must be added or cleared out before saving changes";
next;
}
# password MUST be alphanumeric (no special chars)
push @conn_err, "The password cannot contain non-alphanumeric characters (#$conn_num)" if ($passwd =~ m/[^a-zA-Z0-9@\-]/);
push @conn_err, "A connection server is required" if($host eq "");
push @conn_err, "A connection password is required" if($passwd eq "");
push @conn_err, "A connection network IP is required" if($netip eq "");
next if $val eq "_add" and @conn_err and $conn_err[-1] =~ /^$val /;
$parms{"conn${conn_num}_enabled"} = $enabled;
$parms{"conn${conn_num}_host"} = $host;
$parms{"conn${conn_num}_passwd"} = $passwd;
$parms{"conn${conn_num}_netip"} = $netip;
$parms{"conn${conn_num}_contact"} = $contact;
# Commit the data for this connection
$conn_num++;
# Clear out the ADD values
if($val eq "_add")
{
foreach $var (qw(enabled host passwd netip contact))
{
$parms{"conn_add_${var}"} = "";
}
}
}
$parms{conn_num} = $conn_num;
#################
# SAVE the connections
#################
$rc=save_connections();
#################
# SAVE the connections the UCI vtun file
#################
if($parms{button_save} and not @conn_err)
{
if (&uci_commit("vtun"))
{
push(@errors,"Problem committing UCI vtun");
}
&uci_clone("vtun");
unless($debug == 3)
{
# Regenerate olsrd files and restart olsrd
push(@errors,"Problem restarting olsrd") if system "/etc/init.d/olsrd restart > /dev/null 2>&1";
push(@errors,"Problem restaring vtund") if system "/etc/init.d/vtund restart > /dev/null 2>&1";
sleep 5;
}
}
@active_tun=&get_active_tun();
######################################################################################
# generate the page
######################################################################################
http_header() unless $debug == 2;
html_header("$node setup", 1);
print "<body><center>\n";
alert_banner();
print "<form method=post action=/cgi-bin/vpnc.pl enctype='multipart/form-data'>\n" unless $debug == 2;
print "<form method=post action=test>\n" if $debug == 2;
print "<table width=790>\n";
#################
# Navigation bar
#################
print "<tr><td>\n";
navbar("vpnc");
print "</td></tr>\n";
#################
# control buttons
#################
print "<tr><td align=center>";
print "<a href='/help.html#vpn' target='_blank'>Help</a>";
print "&nbsp;&nbsp;&nbsp;\n";
print "<input type=submit name=button_save value='Save Changes' title='Save and use these settings now (takes about 20 seconds)'>&nbsp;\n";
print "<input type=submit name=button_reset value='Reset Values' title='Revert to the last saved settings'>&nbsp;\n";
print "<input type=submit name=button_refresh value='Refresh' title='Refresh this page'>&nbsp;\n";
print "<tr><td>&nbsp;</td></tr>\n";
push @hidden, "<input type=hidden name=reload value=1></td></tr>";
#################
# messages
#################
if(@conn_err)
{
print "<tr><td align=center><b>ERROR:<br>";
foreach(@conn_err) { print "$_<br>" }
print "</b></td></tr>\n";
}
if($parms{button_save})
{
if(@conn_err)
{
print "<tr><td align=center><b>Configuration NOT saved!</b></td></tr>\n";
}
elsif(@errors)
{
print "<tr><td align=center><b>Configuration saved, however:<br>";
foreach(@errors) { print "$_<br>" }
print "</b></td></tr>\n";
}
else
{
print "<tr><td align=center><b>Configuration saved and is now active.</b></td></tr>\n";
}
print "<tr><td>&nbsp;</td></tr>\n";
}
#################
# everything else
#################
if($config eq "mesh")
{
print "<tr><td align=center valign=top>\n";
&print_vpn_connections();
print "</td></tr>\n";
print "<tr><td><hr></td></tr>\n";
}
print "</table>\n";
print "<p style='font-size:8px'>VPN v${VPNVER}</p>";
push @hidden, "<input type=hidden name=conn_num value=$parms{conn_num}>";
#################
# add hidden form fields
#################
foreach(@hidden) { print "$_\n" }
#################
# close the form
#################
print "</form></center>\n";
show_debug_info();
#################
# close the html
#################
page_footer();
print "</body></html>\n";
exit;
##################
# page subsections
##################
######################################################
# List the connections to be made from this client
######################################################
sub print_vpn_connections()
{
print "<table id=connection_section cellpadding=0 cellspacing=0>";
print "<tr><th colspan=6>Connect this node to the following servers:</th></tr>";
print "<tr><th colspan=6><hr></th></tr>\n";
print "<tr><th>Enabled?</th><th>Server</th><th>Pwd</th><th>Network</th><th>Active&nbsp;</th><th>Action</th></tr>\n";
for($i = 0, @list = (); $i < $parms{conn_num}; $i++) { push @list, $i };
push @list, "_add" unless($parms{conn_num} >= &get_tunnel_maxservers());
$cnum=0;
foreach $val (@list)
{
foreach $var (qw(enabled host passwd netip contact))
{
eval sprintf("\$%s = \$parms{conn%s_%s}", $var, $val, $var);
}
print "<tr><td height=10></td></tr>\n" if $val eq "_add" and scalar(@list) > 1;
print "<tr class='tun_client_list2 tun_client_row'>";
print "<td class='tun_client_center_item' rowspan='2'>";
# Required to be first, so, if the checkbox is cleared, a value will still POST
print "<input type='hidden' name='conn${val}_enabled' value='0'>" unless($val eq "_add");
print "<input type='checkbox' name='conn${val}_enabled' value='1'";
print " onChange='form.submit()'" unless $val eq "_add";
print " checked='checked'" if $enabled;
#print " disabled" unless $val eq "_add";
print " title='enable this connection'></td>";
print "<td><input type=text size=25 name=conn${val}_host value='$host'";
print " onChange='form.submit()'" unless $val eq "_add";
# print " disabled" unless $val eq "_add";
print " title='connection name'></td>";
print "<td><input type=text size=20 name=conn${val}_passwd value='$passwd' ";
print " onChange='form.submit()'" unless $val eq "_add";
print " title='connection password'";
#print " disabled" unless $val eq "_add";
print "></td>";
print "<td><input type=text size=14 name=conn${val}_netip value='$netip'";
print " onChange='form.submit()'" unless $val eq "_add";
# print " disabled" unless $val eq "_add";
print " title='connection network'></td>";
print "</td>";
print "<td class='tun_client_center_item' rowspan='2'>&nbsp;";
if (&is_tunnel_active($netip,@active_tun) && ($val ne "_add")) {
print "<img class='tun_client_active_img' src='/connected.png' title='Connected' />";
} else {
print "<img class='tun_client_inactive_img' src='/disconnected.png' title='Not connected' />" if ($val ne "_add");
}
print "</td>";
print "<td class='tun_client_center_item' rowspan='2'>&nbsp;";
print "<input type=submit name=";
if($val eq "_add") { print "conn_add value=Add title='Add this connection'" }
else { print "conn${val}_del value=Del title='Delete this connection'" }
print "></td>";
#contact info for this tunnel
print "</tr>\n";
print "<tr class='tun_client_list1 tun_client_row tun_loading_css_comment'><td colspan='3' align='right'>Contact Info/Comment (Optional): <input type=text maxlength='50' size=40 name=conn${val}_contact value='$contact'";
print " onChange='form.submit()'" unless ($val eq "_add" || $val eq "");
print " title='client contact info'></td>";
print "</tr>\n";
# display any errors
while(@conn_err and $conn_err[0] =~ /^$val /)
{
$err = shift @conn_err;
$err =~ s/^\S+ //;
print "<tr><th colspan=4>$err</th></tr>\n";
}
#push @hidden, "<input type='hidden' name='client${val}_enable' value='0'>" unless($val eq "_add");
print "<tr><td colspan=6 height=4></td></tr>\n";
$cnum++;
}
print "</table>\n";
}
#################################
# load server connection info from UCI
#################################
sub get_connection_info()
{
my @connections=&uci_get_names_by_sectiontype("vtun","server");
my $c=0;
foreach (@connections)
{
my $myconn={};
$myconn=&uci_get_named_section("vtun",$_);
foreach $var (qw(enabled host passwd netip contact))
{
$parms{"conn${c}_$var"} = $myconn->{$var};
$parms{"conn${c}_$var"} = "0" if($parms{"conn${c}_$var"} eq "");
$myconn->{$var} = "";
}
$c++;
}
$parms{conn_num} = scalar(@connections);
}
sub DEBUGEXIT()
{
my ($text) = @_;
http_header();
html_header("$node setup", 1);
print "DEBUG[";
print $text;
print "]</body>";
exit;
}