diff --git a/files/www/cgi-bin/sysinfo.json b/files/www/cgi-bin/sysinfo.json index e5f7272a..42f1188a 100755 --- a/files/www/cgi-bin/sysinfo.json +++ b/files/www/cgi-bin/sysinfo.json @@ -1,227 +1,239 @@ -#!/usr/bin/perl -=for comment +#!/usr/bin/lua +--[[ - Part of AREDN -- Used for creating Amateur Radio Emergency Data Networks - Copyright (C) 2015 Darryl Quinn - See Contributors file for additional contributors + Part of AREDN -- Used for creating Amateur Radio Emergency Data Networks + Copyright (C) 2016 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 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. + 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 . + You should have received a copy of the GNU General Public License + along with this program. If not, see . - Additional Terms: + Additional Terms: - Additional use restrictions exist on the AREDN(TM) trademark and logo. - See AREDNLicense.txt for more info. + 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. + 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 conained within. + 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. + Modified versions must be modified to attribute to the original source + and be marked in reasonable ways as differentiate it from the original + version - API VERSIONS: - 1.0 - initial release - 1.1 - added services -=cut +--]] -BEGIN {push @INC, '/www/cgi-bin'}; -use perlfunc; +require("uci") +require("aredn.uci") +require("aredn.utils") +require("aredn.http") +require("nixio") +local ipc = require("luci.ip") +local json = require ("luci.jsonc") -read_query_string(); -&json_header(); +-- Function extensions +os.capture = capture -my %info; -$info{"api_version"}="1.1"; +-- ==== MAIN ===== +ctx = uci.cursor() +if not ctx then + error("Failed to get uci cursor") +end -# ============ GENERATE INFO HASH ========= -$node=nvram_get("node"); -chomp($node); -$info{"node"}=$node; +info={} -$model=`/usr/local/bin/get_model`; -chomp($model); -$info{"model"}=$model; +-- API version +info['api_version']="1.1" -$info{"board_id"}=&hardware_boardid(); +-- NODE name +css=getUciConfType("system", "system") +info['node']=css[0]['hostname'] -# ------- Firmware Manufacturer -if (-e "/www/AREDN.png") -{ - $fw_mfg="AREDN"; -} else { - $fw_mfg = "Other"; -} -$info{"firmware_mfg"}=$fw_mfg; +-- MODEL +m=os.capture("/usr/local/bin/get_model") +info['model']=m:chomp() -$fwver=`cat /etc/mesh-release`; -chomp($fwver); -$info{"firmware_version"}=$fwver; +-- BOARD ID +info['board_id']=hardware_boardid() -# ------- Tunnel Installed -if (-e "/usr/sbin/vtund") -{ - $tunnel_installed="true"; -} else { - $tunnel_installed="false"; -} -$info{"tunnel_installed"}=$tunnel_installed; +-- Firmware Manufacturer +local fw_mfg="AREDN" +if not file_exists("/www/AREDN.png") then + fw_mfg = "Other" +end +info['firmware_mfg']=fw_mfg -# ------- SSID -$line = `grep ssid /etc/config/wireless | tail -1`; -$line =~ /['"](.*-(5|10|20)-v[3456])/; -$myssid = $1; -$myssid =~ /(.*)-(5|10|20)-v[3456]/; -$info{"ssid"}=$myssid; +-- Firmware version +local relfile=io.open("/etc/mesh-release","r") +local fv="" +if relfile~=nil then + fv=relfile:read() + relfile:close() +end +info['firmware_version']=fv:chomp() -# ------- Wifi Channel Number -$mychan = `uci get wireless.radio0.channel`; -chomp($mychan); -# 3GHZ channel -> Freq conversion -if ($mychan >= 76 and $mychan <= 99) { - $info{"channel"}=($mychan * 5) + 3000; -} else { - $info{"channel"}=$mychan; -} +-- Tunnel Installed +local tunnel_installed=false +if file_exists("/usr/sbin/vtund") then + tunnel_installed="true" +end +info["tunnel_installed"]=tunnel_installed -# ------- Wifi Bandwidth -$line = `uci get wireless.radio0.chanbw`; -chomp($line); -$info{"chanbw"}=$line; +-- SSID +local myssid="" +wif=getUciConfType("wireless", "wifi-iface") +for pos, t in pairs(wif) do + if wif[pos]['network']=="wifi" then + myssid=wif[pos]['ssid'] + end +end +info["ssid"]=myssid -# ------- ACTIVE TUNNELS -$active_tunnel_count=`ifconfig|grep tun|wc -l`; -chomp($active_tunnel_count); -$info{"active_tunnel_count"}=$active_tunnel_count; - -# ------- LAT/LON -$lat=`head -1 /etc/latlon 2>/dev/null`; -chomp($lat); -$info{"lat"}=$lat; - -$lon=`tail -1 /etc/latlon 2>/dev/null`; -chomp($lon); -$info{"lon"}=$lon; - -# ------- GRID SQUARE -$grid=`head -1 /etc/gridsquare 2>/dev/null`; -chomp($grid); -$info{"grid_square"}=$grid; +--Wifi Channel Number +local chan="" +chan = tonumber(ctx:get("wireless", "radio0", "channel")) +-- 3GHZ channel -> Freq conversion +if (chan >= 76 and chan <= 99) then + chan=(chan * 5) + 3000 +end +info["channel"]=tostring(chan) -# ----------- GENERATE THE JSON ------------ -print "{"; -foreach $ik (keys %info) -{ - print "\"$ik\":\"",$info{$ik},"\","; -} +--Wifi Bandwidth +local chanbw="" +chanbw = ctx:get("wireless", "radio0", "chanbw") +info["chanbw"]=chanbw -############## INTERFACES -print "\"interfaces\":["; -$mystr=""; -foreach(`ifconfig -a`) -{ - next unless /^(\S+) .*HWaddr (\S+)/; - $mystr .= sprintf "{\"name\":\"%s\",", $1; - ($ip, $mask, $bcast, $net, $cidr) = &get_my_ip($1); - $mystr .= sprintf "\"ip\":\"%s\",",$ip; - $mystr .= sprintf "\"mac\":\"%s\"}",$2; - $mystr .= sprintf ","; -} -chop($mystr); -print $mystr; -print "]"; -############## INTERFACES +-- ACTIVE TUNNELS +local atc="" +atc=os.capture("ifconfig|grep tun|wc -l") +info["active_tunnel_count"]=atc:chomp() -if($parms{"hosts"} ) -{ - print ",\"hosts\":["; - $mystr=""; - $hostsfile="/var/run/hosts_olsr"; - if ( -e $hostsfile) - { - if (open(FILE, "<$hostsfile")) { - while($line = ) - { - next unless $line =~ /^(\d+\.\d+\.\d+\.\d+)\s*(\S+)/; - if ($line !~ /dtdlink|mid[0-9]+\./ ) { - $mystr .= sprintf "{\"name\":\"%s\",\"ip\":\"%s\"},",$2,$1; - } - } - close FILE; - } else { - $mystr=sprintf "{\"error\":\"Could not open: %s\"",$hostsfile; - } - } - chop($mystr); - print $mystr; - print "]"; - ############## HOSTS -} +-- LAT/LON +local llfname="/etc/latlon" +local lat="" +local lon="" +if file_exists(llfname) then + llfile=io.open(llfname,"r") + if llfile~=nil then + lat=llfile:read() + lon=llfile:read() + llfile:close() + end +end +info["lat"]=lat +info["lon"]=lon -if($parms{"services"} ) -{ - print ",\"services\":["; - $mystr=""; - $servicesfile="/var/run/services_olsr"; - if ( -e $servicesfile ) - { - if (open(FILE, "<$servicesfile")) { - while($line = ) - { - next unless $line =~ /^(.*)\|(.+)\|(.*)\t+\s+.*/; - $mystr .= sprintf "{\"link\":\"%s\",\"protocol\":\"%s\",\"name\":\"%s\"},",$1,$2,$3; - } - close FILE ; - } else { - $mystr=sprintf "{\"error\":\"Could not open: %s\"",$servicesfile; - } - } - chop($mystr); - print $mystr; - print "]"; - ############## SERVICES -} +-- GRID SQUARE +local gsfname="/etc/gridsquare" +local grid="" +if file_exists(gsfname) then + gsfile=io.open(gsfname,"r") + if gsfile~=nil then + grid=gsfile:read() + gsfile:close() + end +end +info["grid_square"]=grid +-- INTERFACES +local tif={} +local ift=get_interfaces() -print "}"; # ROOT +for pos, i in pairs(ift) do + local nim={} + local ipv4="" + if (i.name ~= "lo" and i.name ~= "wlan0-1") then + --table.print(i) + nim['name']=i.name + ipv4=tostring(i.ipaddrs[1]) + nim['ip']=ipFromCIDR(ipv4) + nim['mac']=i.macaddr + table.insert(tif,nim) + end +end +info["interfaces"]=tif -############################## +-- HOSTS +if string.find(nixio.getenv("QUERY_STRING"):lower(),"hosts=1") then + local hosts={} + local lines={} + local pos, val + local hfile=io.open("/var/run/hosts_olsr","r") + if hfile~=nil then + for line in hfile:lines() do + table.insert(lines,line) + end + hfile:close() + for pos,val in pairs(lines) do + local host={} + -- local data,comment = string.match(val,"^([^#;]+)[#;]*(.*)$") + local data,comment = string.match(val,"^([^#;]+)[#;]*(.*)$") + if data then + --local ip, name=string.match(data,"^%s*([%x%.%:]+)%s+(%S.*)\t%s*$") + local ip, name=string.match(data,"^([%x%.%:]+)%s+(%S.*)\t%s*$") + if ip and name then + if not string.match(name,"^(dtdlink[.]).*") then + if not string.match(name,"^(mid[0-9][.]).*") then + host['name']=name + host['ip']=ip + table.insert(hosts,host) + end + end + end + end + end + else + host['error']="Cannot read hosts file" + table.insert(hosts,host) + end + info["hosts"]=hosts +end -sub json_header -{ - # THIS MUST BE ONE LINE! - # otherwise an intermittent busybox bug will incorrectly "fix" the generated output - # print "HTTP/1.0 200 OK\r\n"; # Not needed under Uhttpd - print "Content-type: application/json\r\n"; - print "Cache-Control: no-store\r\n"; - print "\r\n"; -} +-- SERVICES +if string.find(nixio.getenv("QUERY_STRING"):lower(),"services=1") then + local services={} + local lines={} + local pos, val + local hfile=io.open("/var/run/services_olsr","r") + if hfile~=nil then + for line in hfile:lines() do + table.insert(lines,line) + end + hfile:close() + for pos,val in pairs(lines) do + local service={} + local link,protocol,name = string.match(val,"^(.*)|(.+)|(.*)\t+%s+.*") + if link and protocol and name then + service['link']=link + service['protocol']=protocol + service['name']=name + table.insert(services,service) + end + end + else + service['error']="Cannot read services file" + table.insert(services,service) + end + info["services"]=services +end -sub get_my_ip -{ - my($ip); - foreach(`ifconfig $_[0]`) - { - next unless /inet addr:([\d\.]+)/; - $ip = $1; - last; - } - return ("none") unless defined $ip; - return $ip; -} +-- Output the HTTP header for JSON +json_header() + +-- Output the info table as json +print(json.stringify(info,true))