nodewatcher: split into nodewatcher.d scripts for individual task

This splits up the data extraction/assembly of the nodewatcher
script into several parts and distributes them across packages, so
that each nodewatcher.d subscript is located in the package providing
the relevant functionality. This allows to extend the nodewatcher data
by enabling/disabling packages.
This scheme is not perfectly fulfilled for fff-network vs. fff-wireless,
as data cannot uniquely assigned there and the XML syntax does not allow
separation anyway.

In general, this moves code without applying code improvements, yielding
at an easy comparison of moved fragments. However, the following changes
were done to improve experience:

- The function writing debug output has been renamed from "err" to "debug"
- Since we catch the stdout of the nodewatcher.d functions anyway,
  those scripts were adjusted to echo output directly instead of first
  writing it into a variable and then outputting it at the end.
- The uci config has been kept, but initialization for the network part
  has been moved to the fff-network package.
- Space indent has been changed to tab, which is more common in the
  firmware and requires less space.
- Remove support for nodewatcher run without uci config. Script-based
  nodewatcher on other platforms will have altered code anyway, and
  splitting it up will prevent effective use as a blueprint for those
  cases. After this change, nodewatcher in firmware is supposed to be
  used only for this firmware.

Note that since the nodewatcher.d scripts are evaluated by using their
echo output, having a function created uncaught output to stdout there
will corrupt the XML.

Signed-off-by: Tim Niemeyer <tim@tn-x.org>
[rebase and adjustments for current master, use simpler mechanism to
call nodewatcher.d scripts, use tab indent, remove debug() definition
where not needed, do not remove uci config, add commit message, use
echo -n]
Signed-off-by: Adrian Schmutzler <freifunk@adrianschmutzler.de>
Reviewed-by: Fabian Bläse <fabian@blaese.de>
[remove 'local' modifier for variable not inside a function, fix typo]
Signed-off-by: Fabian Bläse <fabian@blaese.de>
This commit is contained in:
Tim Niemeyer 2020-01-07 14:40:20 +01:00 committed by Fabian Bläse
parent 9957cd4318
commit b6c7acd704
14 changed files with 361 additions and 302 deletions

View File

@ -1,7 +1,7 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=fff-babeld
PKG_RELEASE:=1
PKG_RELEASE:=2
PKG_BUILD_DIR:=$(BUILD_DIR)/fff-babeld

View File

@ -0,0 +1,16 @@
#!/bin/sh
if pgrep babeld >/dev/null; then
neighbours="$(echo dump | nc ::1 33123 | grep '^add neighbour' |
awk '{
for (i=2; i < NF; i += 2) {
vars[$i] = $(i+1)
}
}
{
printf "<neighbour><ip>%s</ip><outgoing_interface>%s</outgoing_interface><link_cost>%s</link_cost></neighbour>", vars["address"], vars["if"], vars["cost"]
}')"
echo -n "<babel_neighbours>$neighbours</babel_neighbours>"
fi
exit 0

View File

@ -1,7 +1,7 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=fff-batman-adv
PKG_RELEASE:=3
PKG_RELEASE:=4
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)

View File

@ -0,0 +1,60 @@
#!/bin/sh
# Netmon Nodewatcher (C) 2010-2012 Freifunk Oldenburg
# License; GPL v3
debug() {
(>&2 echo "$1")
}
debug "$(date): Collecting information from batman advanced and its interfaces"
#B.A.T.M.A.N. advanced
if [ -f /sys/module/batman_adv/version ]; then
for iface in $(batctl if | sed 's/ //'); do
status=${iface##*:}
iface=${iface%%:*}
BATMAN_ADV_INTERFACES=$BATMAN_ADV_INTERFACES"<$iface><name>$iface</name><status>$status</status></$iface>"
done
echo -n "<batman_adv_interfaces>$BATMAN_ADV_INTERFACES</batman_adv_interfaces>"
# Build a list of direct neighbors
batman_adv_originators=$(/usr/sbin/batctl o -H | awk \
'BEGIN { FS=" "; i=0 } # set the delimiter to " "
{ sub("\\(", "", $0) # remove parentheses
sub("\\)", "", $0)
sub("\\[", "", $0)
sub("\\]", "", $0)
sub("\\*", "", $0)
sub(" ", " ", $0)
o=$1".*"$1 # build a regex to find lines that contains the $1 (=originator) twice
if ($0 ~ o) # filter for this regex (will remove entries without direct neighbor)
{
printf "<originator_"i"><originator>"$1"</originator><link_quality>"$3"</link_quality><nexthop>"$4"</nexthop><last_seen>"$2"</last_seen><outgoing_interface>"$5"</outgoing_interface></originator_"i">"
i++
}
}')
echo -n "<batman_adv_originators>$batman_adv_originators</batman_adv_originators>"
echo -n "<batman_adv_gateway_mode>$(/usr/sbin/batctl gw)</batman_adv_gateway_mode>"
batman_adv_gateway_list=$(/usr/sbin/batctl gwl -H | awk \
'BEGIN { FS=" "; i=0 }
/No gateways/ { next }
{ sub("\\(", "", $0)
sub("\\)", "", $0)
sub("\\[ *", "", $0)
sub("\\]:", "", $0)
sub("\\* ", "true ", $0)
sub(" ", "false ", $0)
printf "<gateway_"i"><selected>"$1"</selected><gateway>"$2"</gateway><link_quality>"$3"</link_quality><nexthop>"$4"</nexthop><outgoing_interface>"$5"</outgoing_interface><gw_class>"$6" "$7" "$8"</gw_class></gateway_"i">"
i++
}')
echo -n "<batman_adv_gateway_list>$batman_adv_gateway_list</batman_adv_gateway_list>"
else
debug "$(date): No batman data .."
exit 1
fi
exit 0

View File

@ -1,7 +1,7 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=fff-network
PKG_RELEASE:=18
PKG_RELEASE:=19
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)

View File

@ -0,0 +1,9 @@
uci batch <<EOF
add nodewatcher network
set nodewatcher.@network[-1].mesh_interface='br-mesh'
set nodewatcher.@network[-1].iface_blacklist='lo ifb0'
set nodewatcher.@network[-1].ip_whitelist='br-mesh'
EOF
uci commit nodewatcher
exit 0

View File

@ -0,0 +1,74 @@
#!/bin/sh
# Netmon Nodewatcher (C) 2010-2012 Freifunk Oldenburg
# License; GPL v3
IFACEBLACKLIST=$(uci get nodewatcher.@network[0].iface_blacklist)
IPWHITELIST=$(uci get nodewatcher.@network[0].ip_whitelist)
debug() {
(>&2 echo "$1")
}
inArray() {
local value
for value in $1; do
if [ "$value" = "$2" ]; then
return 0
fi
done
return 1
}
debug "$(date): Collecting information from network interfaces"
#Get interfaces
interface_data=""
#Loop interfaces
#for entry in $IFACES; do
for filename in $(grep 'up\|unknown' /sys/class/net/*/operstate); do
ifpath=${filename%/operstate*}
iface=${ifpath#/sys/class/net/}
if inArray "$IFACEBLACKLIST" "$iface"; then
continue
fi
#Get interface data for whitelisted interfaces
# shellcheck disable=SC2016
awkscript='
/ether/ { printf "<mac_addr>"$2"</mac_addr>" }
/mtu/ { printf "<mtu>"$5"</mtu>" }'
if inArray "$IPWHITELIST" "$iface"; then
# shellcheck disable=SC2016
awkscript=$awkscript'
/inet / { split($2, a, "/"); printf "<ipv4_addr>"a[1]"</ipv4_addr>" }
/inet6/ && /scope global/ { printf "<ipv6_addr>"$2"</ipv6_addr>" }
/inet6/ && /scope link/ { printf "<ipv6_link_local_addr>"$2"</ipv6_link_local_addr>"}'
fi
addrs=$(ip addr show dev "${iface}" | awk "$awkscript")
traffic_rx=$(cat "$ifpath/statistics/rx_bytes")
traffic_tx=$(cat "$ifpath/statistics/tx_bytes")
interface_data=$interface_data"<$iface><name>$iface</name>$addrs<traffic_rx>$traffic_rx</traffic_rx><traffic_tx>$traffic_tx</traffic_tx>"
interface_data=$interface_data$(iwconfig "${iface}" 2>/dev/null | awk -F':' '
/Mode/{ split($2, m, " "); printf "<wlan_mode>"m[1]"</wlan_mode>" }
/Cell/{ split($0, c, " "); printf "<wlan_bssid>"c[5]"</wlan_bssid>" }
/ESSID/ { split($0, e, "\""); printf "<wlan_essid>"e[2]"</wlan_essid>" }
/Freq/{ split($3, f, " "); printf "<wlan_frequency>"f[1]f[2]"</wlan_frequency>" }
/Tx-Power/{ split($0, p, "="); sub(/[[:space:]]*$/, "", p[2]); printf "<wlan_tx_power>"p[2]"</wlan_tx_power>" }
')
interface_data=$interface_data$(iw dev "${iface}" info 2>/dev/null | awk '
/ssid/{ split($0, s, " "); printf "<wlan_ssid>"s[2]"</wlan_ssid>" }
/type/ { split($0, t, " "); printf "<wlan_type>"t[2]"</wlan_type>" }
/channel/{ split($0, c, " "); printf "<wlan_channel>"c[2]"</wlan_channel>" }
/width/{ split($0, w, ": "); sub(/ .*/, "", w[2]); printf "<wlan_width>"w[2]"</wlan_width>" }
')
interface_data=$interface_data"</$iface>"
done
echo -n "<interface_data>$interface_data</interface_data>"
exit 0

View File

@ -0,0 +1,25 @@
#!/bin/sh
# Netmon Nodewatcher (C) 2010-2012 Freifunk Oldenburg
# License; GPL v3
MESH_INTERFACE=$(uci get nodewatcher.@network[0].mesh_interface)
debug() {
(>&2 echo "$1")
}
debug "$(date): Collecting information about connected clients"
client_count=0
dataclient=""
CLIENT_INTERFACES=$(ls "/sys/class/net/$MESH_INTERFACE/brif" | grep -v '^bat')
for clientif in ${CLIENT_INTERFACES}; do
cc=$(bridge fdb show br "$MESH_INTERFACE" brport "$clientif" | grep -v self | grep -v permanent -c)
client_count=$((client_count + cc))
dataclient="$dataclient<$clientif>$cc</$clientif>"
done
echo -n "<client_count>$client_count</client_count>"
echo -n "<clients>$dataclient</clients>"
exit 0

View File

@ -1,7 +1,7 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=fff-nodewatcher
PKG_RELEASE:=55
PKG_RELEASE:=56
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)

View File

@ -8,10 +8,6 @@ uci batch <<EOF
set nodewatcher.@script[0].logfile='/var/log/nodewatcher.log'
set nodewatcher.@script[0].data_file='/tmp/crawldata/node.data'
set nodewatcher.@script[0].status_text_file='/tmp/status.txt'
add nodewatcher network
set nodewatcher.@network[0].mesh_interface='br-mesh'
set nodewatcher.@network[0].iface_blacklist='lo ifb0'
set nodewatcher.@network[0].ip_whitelist='br-mesh'
EOF
uci commit

View File

@ -0,0 +1,123 @@
#!/bin/sh
# Netmon Nodewatcher (C) 2010-2012 Freifunk Oldenburg
# License; GPL v3
SCRIPT_STATUS_FILE=$(uci get nodewatcher.@script[0].status_text_file)
SCRIPT_VERSION="56"
debug() {
(>&2 echo "$1")
}
#Get system data from other locations
debug "$(date): Collecting basic system status data"
hostname="$(cat /proc/sys/kernel/hostname)"
mac=$(awk '{ mac=toupper($1); gsub(":", "", mac); print mac }' /sys/class/net/br-mesh/address 2>/dev/null)
[ "$hostname" = "OpenWrt" ] && hostname="$mac"
[ "$hostname" = "FFF" ] && hostname="$mac"
description="$(uci -q get fff.system.description)"
if [ -n "$description" ]; then
description="<description><![CDATA[$description]]></description>"
fi
latitude="$(uci -q get fff.system.latitude)"
longitude="$(uci -q get fff.system.longitude)"
if [ -n "$longitude" -a -n "$latitude" ]; then
geo="<geo><lat>$latitude</lat><lng>$longitude</lng></geo>";
fi
position_comment="$(uci -q get fff.system.position_comment)"
if [ -n "$position_comment" ]; then
position_comment="<position_comment><![CDATA[$position_comment]]></position_comment>"
fi
contact="$(uci -q get fff.system.contact)"
if [ -n "$contact" ]; then
contact="<contact>$contact</contact>"
fi
uptime=$(awk '{ printf "<uptime>"$1"</uptime><idletime>"$2"</idletime>" }' /proc/uptime)
memory=$(awk '
/^MemTotal/ { printf "<memory_total>"$2"</memory_total>" }
/^Cached:/ { printf "<memory_caching>"$2"</memory_caching>" }
/^Buffers/ { printf "<memory_buffering>"$2"</memory_buffering>" }
/^MemFree/ { printf "<memory_free>"$2"</memory_free>" }
' /proc/meminfo)
cpu=$(awk -F': ' '
/model/ { printf "<cpu>"$2"</cpu>" }
/system type/ { printf "<chipset>"$2"</chipset>" }
/platform/ { printf "<chipset>"$2"</chipset>" }
' /proc/cpuinfo)
model="<model>$(cat /var/sysinfo/model)</model>"
local_time="$(date +%s)"
load=$(awk '{ printf "<loadavg>"$3"</loadavg><processes>"$4"</processes>" }' /proc/loadavg)
debug "$(date): Collecting version information"
batman_adv_version=$(cat /sys/module/batman_adv/version)
kernel_version=$(uname -r)
if [ -x /usr/bin/fastd ]; then
fastd_version="<fastd_version>$(/usr/bin/fastd -v | awk '{ print $2 }')</fastd_version>"
fi
nodewatcher_version=$SCRIPT_VERSION
if [ -x /usr/sbin/babeld ]; then
babel_version="<babel_version>$(/usr/sbin/babeld -V 2>&1)</babel_version>"
fi
if [ -f "$SCRIPT_STATUS_FILE" ]; then
status_text="<status_text>$(cat "$SCRIPT_STATUS_FILE")</status_text>"
fi
# Checks if fastd is running
if pidof fastd >/dev/null ; then
vpn_active="<vpn_active>1</vpn_active>"
else
vpn_active="<vpn_active>0</vpn_active>"
fi
# example for /etc/openwrt_release:
#DISTRIB_ID="OpenWrt"
#DISTRIB_RELEASE="Attitude Adjustment"
#DISTRIB_REVISION="r35298"
#DISTRIB_CODENAME="attitude_adjustment"
#DISTRIB_TARGET="atheros/generic"
#DISTRIB_DESCRIPTION="OpenWrt Attitude Adjustment 12.09-rc1"
. /etc/openwrt_release
distname=$DISTRIB_ID
distversion=$DISTRIB_RELEASE
# example for /etc/firmware_release:
#FIRMWARE_VERSION="95f36685e7b6cbf423f02cf5c7f1e785fd4ccdae-dirty"
#BUILD_DATE="build date: Di 29. Jan 19:33:34 CET 2013"
#OPENWRT_CORE_REVISION="35298"
#OPENWRT_FEEDS_PACKAGES_REVISION="35298"
. /etc/firmware_release
SYSTEM_DATA="<status>online</status>"
SYSTEM_DATA=$SYSTEM_DATA"$status_text"
SYSTEM_DATA=$SYSTEM_DATA"<hostname>$hostname</hostname>"
SYSTEM_DATA=$SYSTEM_DATA"${description}"
SYSTEM_DATA=$SYSTEM_DATA"${geo}"
SYSTEM_DATA=$SYSTEM_DATA"${position_comment}"
SYSTEM_DATA=$SYSTEM_DATA"${contact}"
SYSTEM_DATA=$SYSTEM_DATA"<hood>$(uci -q get "system.@system[0].hood")</hood>"
SYSTEM_DATA=$SYSTEM_DATA"<hoodid>$(uci -q get "system.@system[0].hoodid")</hoodid>"
SYSTEM_DATA=$SYSTEM_DATA"<distname>$distname</distname>"
SYSTEM_DATA=$SYSTEM_DATA"<distversion>$distversion</distversion>"
SYSTEM_DATA=$SYSTEM_DATA"$cpu"
SYSTEM_DATA=$SYSTEM_DATA"$model"
SYSTEM_DATA=$SYSTEM_DATA"$memory"
SYSTEM_DATA=$SYSTEM_DATA"$load"
SYSTEM_DATA=$SYSTEM_DATA"$uptime"
SYSTEM_DATA=$SYSTEM_DATA"<local_time>$local_time</local_time>"
SYSTEM_DATA=$SYSTEM_DATA"<batman_advanced_version>$batman_adv_version</batman_advanced_version>"
SYSTEM_DATA=$SYSTEM_DATA"<kernel_version>$kernel_version</kernel_version>"
SYSTEM_DATA=$SYSTEM_DATA"$fastd_version"
SYSTEM_DATA=$SYSTEM_DATA"<nodewatcher_version>$nodewatcher_version</nodewatcher_version>"
SYSTEM_DATA=$SYSTEM_DATA"$babel_version"
SYSTEM_DATA=$SYSTEM_DATA"<firmware_version>$FIRMWARE_VERSION</firmware_version>"
SYSTEM_DATA=$SYSTEM_DATA"<firmware_revision>$BUILD_DATE</firmware_revision>"
SYSTEM_DATA=$SYSTEM_DATA"<openwrt_core_revision>$OPENWRT_CORE_REVISION</openwrt_core_revision>"
SYSTEM_DATA=$SYSTEM_DATA"<openwrt_feeds_packages_revision>$OPENWRT_FEEDS_PACKAGES_REVISION</openwrt_feeds_packages_revision>"
SYSTEM_DATA=$SYSTEM_DATA"$vpn_active"
echo -n "<system_data>$SYSTEM_DATA</system_data>"
exit 0

View File

@ -7,327 +7,65 @@ test -f /tmp/started || exit
# Allow only one instance
lockfile="/var/lock/${0##*/}.lock"
if ! lock -n "$lockfile"; then
echo "Only one instance of $0 allowed."
exit 1
echo "Only one instance of $0 allowed."
exit 1
fi
trap "lock -u \"$lockfile\"" INT TERM EXIT
SCRIPT_VERSION="55"
[ -s /etc/config/nodewatcher ] || exit 1
#Get the configuration from the uci configuration file
#If it does not exists, then get it from a normal bash file with variables.
if [ -f /etc/config/nodewatcher ];then
SCRIPT_ERROR_LEVEL=$(uci get nodewatcher.@script[0].error_level)
SCRIPT_LOGFILE=$(uci get nodewatcher.@script[0].logfile)
SCRIPT_DATA_FILE=$(uci get nodewatcher.@script[0].data_file)
MESH_INTERFACE=$(uci get nodewatcher.@network[0].mesh_interface)
IFACEBLACKLIST=$(uci get nodewatcher.@network[0].iface_blacklist)
IPWHITELIST=$(uci get nodewatcher.@network[0].ip_whitelist)
SCRIPT_STATUS_FILE=$(uci get nodewatcher.@script[0].status_text_file)
else
. "$(dirname "$0")/nodewatcher_config"
fi
SCRIPT_ERROR_LEVEL=$(uci get nodewatcher.@script[0].error_level)
SCRIPT_LOGFILE=$(uci get nodewatcher.@script[0].logfile)
SCRIPT_DATA_FILE=$(uci get nodewatcher.@script[0].data_file)
if [ "$SCRIPT_ERROR_LEVEL" -gt "1" ]; then
err() {
echo "$1" >> "$SCRIPT_LOGFILE"
}
debug() {
echo "$1" >> "$SCRIPT_LOGFILE"
}
else
err() {
:
}
debug() {
:
}
fi
#This method checks if the log file has become too big and deletes the first X lines
delete_log() {
if [ -f "$SCRIPT_LOGFILE" ]; then
if [ "$(find "$SCRIPT_LOGFILE" -printf "%s")" -gt "6000" ]; then
sed -i '1,60d' "$SCRIPT_LOGFILE"
err "$(date): Logfile has been made smaller"
fi
fi
}
inArray() {
local value
for value in $1; do
if [ "$value" = "$2" ]; then
return 0
fi
done
return 1
if [ -f "$SCRIPT_LOGFILE" ]; then
if [ "$(find "$SCRIPT_LOGFILE" -printf "%s")" -gt "6000" ]; then
sed -i '1,60d' "$SCRIPT_LOGFILE"
debug "$(date): Logfile has been made smaller"
fi
fi
}
#This method generates the crawl data XML file that is being fetched by netmon
#and provided by a small local httpd
crawl() {
#Get system data from other locations
err "$(date): Collecting basic system status data"
hostname="$(cat /proc/sys/kernel/hostname)"
mac=$(awk '{ mac=toupper($1); gsub(":", "", mac); print mac }' /sys/class/net/br-mesh/address 2>/dev/null)
[ "$hostname" = "OpenWrt" ] && hostname="$mac"
[ "$hostname" = "FFF" ] && hostname="$mac"
description="$(uci -q get fff.system.description)"
if [ -n "$description" ]; then
description="<description><![CDATA[$description]]></description>"
fi
latitude="$(uci -q get fff.system.latitude)"
longitude="$(uci -q get fff.system.longitude)"
if [ -n "$longitude" -a -n "$latitude" ]; then
geo="<geo><lat>$latitude</lat><lng>$longitude</lng></geo>";
fi
position_comment="$(uci -q get fff.system.position_comment)"
if [ -n "$position_comment" ]; then
position_comment="<position_comment><![CDATA[$position_comment]]></position_comment>"
fi
contact="$(uci -q get fff.system.contact)"
if [ -n "$contact" ]; then
contact="<contact>$contact</contact>"
fi
uptime=$(awk '{ printf "<uptime>"$1"</uptime><idletime>"$2"</idletime>" }' /proc/uptime)
debug "$(date): Putting all information into a XML-File and save it at $SCRIPT_DATA_FILE"
memory=$(awk '
/^MemTotal/ { printf "<memory_total>"$2"</memory_total>" }
/^Cached:/ { printf "<memory_caching>"$2"</memory_caching>" }
/^Buffers/ { printf "<memory_buffering>"$2"</memory_buffering>" }
/^MemFree/ { printf "<memory_free>"$2"</memory_free>" }
' /proc/meminfo)
cpu=$(awk -F': ' '
/model/ { printf "<cpu>"$2"</cpu>" }
/system type/ { printf "<chipset>"$2"</chipset>" }
/platform/ { printf "<chipset>"$2"</chipset>" }
' /proc/cpuinfo)
model="<model>$(cat /var/sysinfo/model)</model>"
local_time="$(date +%s)"
load=$(awk '{ printf "<loadavg>"$3"</loadavg><processes>"$4"</processes>" }' /proc/loadavg)
DATA="<?xml version='1.0' standalone='yes'?><data>"
err "$(date): Collecting version information"
for f in /usr/lib/nodewatcher.d/*.sh; do
tmp="$($f)"
DATA="$DATA$tmp"
done
batman_adv_version=$(cat /sys/module/batman_adv/version)
kernel_version=$(uname -r)
if [ -x /usr/bin/fastd ]; then
fastd_version="<fastd_version>$(/usr/bin/fastd -v | awk '{ print $2 }')</fastd_version>"
fi
nodewatcher_version=$SCRIPT_VERSION
if [ -x /usr/sbin/babeld ]; then
babel_version="<babel_version>$(/usr/sbin/babeld -V 2>&1)</babel_version>"
fi
DATA="$DATA</data>"
if [ -f "$SCRIPT_STATUS_FILE" ]; then
status_text="<status_text>$(cat "$SCRIPT_STATUS_FILE")</status_text>"
fi
# Checks if fastd is running
if pidof fastd >/dev/null ; then
vpn_active="<vpn_active>1</vpn_active>"
else
vpn_active="<vpn_active>0</vpn_active>"
fi
# example for /etc/openwrt_release:
#DISTRIB_ID="OpenWrt"
#DISTRIB_RELEASE="Attitude Adjustment"
#DISTRIB_REVISION="r35298"
#DISTRIB_CODENAME="attitude_adjustment"
#DISTRIB_TARGET="atheros/generic"
#DISTRIB_DESCRIPTION="OpenWrt Attitude Adjustment 12.09-rc1"
. /etc/openwrt_release
distname=$DISTRIB_ID
distversion=$DISTRIB_RELEASE
# example for /etc/firmware_release:
#FIRMWARE_VERSION="95f36685e7b6cbf423f02cf5c7f1e785fd4ccdae-dirty"
#BUILD_DATE="build date: Di 29. Jan 19:33:34 CET 2013"
#OPENWRT_CORE_REVISION="35298"
#OPENWRT_FEEDS_PACKAGES_REVISION="35298"
. /etc/firmware_release
SYSTEM_DATA="<status>online</status>"
SYSTEM_DATA=$SYSTEM_DATA"$status_text"
SYSTEM_DATA=$SYSTEM_DATA"<hostname>$hostname</hostname>"
SYSTEM_DATA=$SYSTEM_DATA"${description}"
SYSTEM_DATA=$SYSTEM_DATA"${geo}"
SYSTEM_DATA=$SYSTEM_DATA"${position_comment}"
SYSTEM_DATA=$SYSTEM_DATA"${contact}"
SYSTEM_DATA=$SYSTEM_DATA"<hood>$(uci -q get "system.@system[0].hood")</hood>"
SYSTEM_DATA=$SYSTEM_DATA"<hoodid>$(uci -q get "system.@system[0].hoodid")</hoodid>"
SYSTEM_DATA=$SYSTEM_DATA"<distname>$distname</distname>"
SYSTEM_DATA=$SYSTEM_DATA"<distversion>$distversion</distversion>"
SYSTEM_DATA=$SYSTEM_DATA"$cpu"
SYSTEM_DATA=$SYSTEM_DATA"$model"
SYSTEM_DATA=$SYSTEM_DATA"$memory"
SYSTEM_DATA=$SYSTEM_DATA"$load"
SYSTEM_DATA=$SYSTEM_DATA"$uptime"
SYSTEM_DATA=$SYSTEM_DATA"<local_time>$local_time</local_time>"
SYSTEM_DATA=$SYSTEM_DATA"<batman_advanced_version>$batman_adv_version</batman_advanced_version>"
SYSTEM_DATA=$SYSTEM_DATA"<kernel_version>$kernel_version</kernel_version>"
SYSTEM_DATA=$SYSTEM_DATA"$fastd_version"
SYSTEM_DATA=$SYSTEM_DATA"<nodewatcher_version>$nodewatcher_version</nodewatcher_version>"
SYSTEM_DATA=$SYSTEM_DATA"$babel_version"
SYSTEM_DATA=$SYSTEM_DATA"<firmware_version>$FIRMWARE_VERSION</firmware_version>"
SYSTEM_DATA=$SYSTEM_DATA"<firmware_revision>$BUILD_DATE</firmware_revision>"
SYSTEM_DATA=$SYSTEM_DATA"<openwrt_core_revision>$OPENWRT_CORE_REVISION</openwrt_core_revision>"
SYSTEM_DATA=$SYSTEM_DATA"<openwrt_feeds_packages_revision>$OPENWRT_FEEDS_PACKAGES_REVISION</openwrt_feeds_packages_revision>"
SYSTEM_DATA=$SYSTEM_DATA"$vpn_active"
err "$(date): Collecting information from network interfaces"
#Get interfaces
interface_data=""
#Loop interfaces
#for entry in $IFACES; do
for filename in $(grep 'up\|unknown' /sys/class/net/*/operstate); do
ifpath=${filename%/operstate*}
iface=${ifpath#/sys/class/net/}
if inArray "$IFACEBLACKLIST" "$iface"; then
continue
fi
#Get interface data for whitelisted interfaces
# shellcheck disable=SC2016
awkscript='
/ether/ { printf "<mac_addr>"$2"</mac_addr>" }
/mtu/ { printf "<mtu>"$5"</mtu>" }'
if inArray "$IPWHITELIST" "$iface"; then
# shellcheck disable=SC2016
awkscript=$awkscript'
/inet / { split($2, a, "/"); printf "<ipv4_addr>"a[1]"</ipv4_addr>" }
/inet6/ && /scope global/ { printf "<ipv6_addr>"$2"</ipv6_addr>" }
/inet6/ && /scope link/ { printf "<ipv6_link_local_addr>"$2"</ipv6_link_local_addr>"}'
fi
addrs=$(ip addr show dev "${iface}" | awk "$awkscript")
traffic_rx=$(cat "$ifpath/statistics/rx_bytes")
traffic_tx=$(cat "$ifpath/statistics/tx_bytes")
interface_data=$interface_data"<$iface><name>$iface</name>$addrs<traffic_rx>$traffic_rx</traffic_rx><traffic_tx>$traffic_tx</traffic_tx>"
interface_data=$interface_data$(iwconfig "${iface}" 2>/dev/null | awk -F':' '
/Mode/{ split($2, m, " "); printf "<wlan_mode>"m[1]"</wlan_mode>" }
/Cell/{ split($0, c, " "); printf "<wlan_bssid>"c[5]"</wlan_bssid>" }
/ESSID/ { split($0, e, "\""); printf "<wlan_essid>"e[2]"</wlan_essid>" }
/Freq/{ split($3, f, " "); printf "<wlan_frequency>"f[1]f[2]"</wlan_frequency>" }
/Tx-Power/{ split($0, p, "="); sub(/[[:space:]]*$/, "", p[2]); printf "<wlan_tx_power>"p[2]"</wlan_tx_power>" }
')
interface_data=$interface_data$(iw dev "${iface}" info 2>/dev/null | awk '
/ssid/{ split($0, s, " "); printf "<wlan_ssid>"s[2]"</wlan_ssid>" }
/type/ { split($0, t, " "); printf "<wlan_type>"t[2]"</wlan_type>" }
/channel/{ split($0, c, " "); printf "<wlan_channel>"c[2]"</wlan_channel>" }
/width/{ split($0, w, ": "); sub(/ .*/, "", w[2]); printf "<wlan_width>"w[2]"</wlan_width>" }
')
interface_data=$interface_data"</$iface>"
done
err "$(date): Collecting information from batman advanced and its interfaces"
#B.A.T.M.A.N. advanced
if [ -f /sys/module/batman_adv/version ]; then
for iface in $(batctl if | sed 's/ //'); do
status=${iface##*:}
iface=${iface%%:*}
BATMAN_ADV_INTERFACES=$BATMAN_ADV_INTERFACES"<$iface><name>$iface</name><status>$status</status></$iface>"
done
# Build a list of direct neighbors
batman_adv_originators=$(/usr/sbin/batctl o -H | awk \
'BEGIN { FS=" "; i=0 } # set the delimiter to " "
{ sub("\\(", "", $0) # remove parentheses
sub("\\)", "", $0)
sub("\\[", "", $0)
sub("\\]", "", $0)
sub("\\*", "", $0)
sub(" ", " ", $0)
o=$1".*"$1 # build a regex to find lines that contains the $1 (=originator) twice
if ($0 ~ o) # filter for this regex (will remove entries without direct neighbor)
{
printf "<originator_"i"><originator>"$1"</originator><link_quality>"$3"</link_quality><nexthop>"$4"</nexthop><last_seen>"$2"</last_seen><outgoing_interface>"$5"</outgoing_interface></originator_"i">"
i++
}
}')
batman_adv_gateway_mode=$(/usr/sbin/batctl gw)
batman_adv_gateway_list=$(/usr/sbin/batctl gwl -H | awk \
'BEGIN { FS=" "; i=0 }
/No gateways/ { next }
{ sub("\\(", "", $0)
sub("\\)", "", $0)
sub("\\[ *", "", $0)
sub("\\]:", "", $0)
sub("\\* ", "true ", $0)
sub(" ", "false ", $0)
printf "<gateway_"i"><selected>"$1"</selected><gateway>"$2"</gateway><link_quality>"$3"</link_quality><nexthop>"$4"</nexthop><outgoing_interface>"$5"</outgoing_interface><gw_class>"$6" "$7" "$8"</gw_class></gateway_"i">"
i++
}')
fi
err "$(date): Collecting information about conected clients"
#CLIENTS
client_count=0
dataclient=""
CLIENT_INTERFACES=$(ls "/sys/class/net/$MESH_INTERFACE/brif" | grep -v '^bat')
for clientif in ${CLIENT_INTERFACES}; do
local cc=$(bridge fdb show br "$MESH_INTERFACE" brport "$clientif" | grep -v self | grep -v permanent -c)
client_count=$((client_count + cc))
dataclient="$dataclient<$clientif>$cc</$clientif>"
done
dataair=""
w2dump="$(iw dev w2ap survey dump 2> /dev/null | sed '/Survey/,/\[in use\]/d')"
if [ -n "$w2dump" ] ; then
w2_ACT="$(ACTIVE=$(echo "$w2dump" | grep "active time:"); set ${ACTIVE:-0 0 0 0 0}; echo -e "${4}")"
w2_BUS="$(BUSY=$(echo "$w2dump" | grep "busy time:"); set ${BUSY:-0 0 0 0 0}; echo -e "${4}")"
dataair="$dataair<airtime2><active>$w2_ACT</active><busy>$w2_BUS</busy></airtime2>"
fi
w5dump="$(iw dev w5ap survey dump 2> /dev/null | sed '/Survey/,/\[in use\]/d')"
if [ -n "$w5dump" ] ; then
w5_ACT="$(ACTIVE=$(echo "$w5dump" | grep "active time:"); set ${ACTIVE:-0 0 0 0 0}; echo -e "${4}")"
w5_BUS="$(BUSY=$(echo "$w5dump" | grep "busy time:"); set ${BUSY:-0 0 0 0 0}; echo -e "${4}")"
dataair="$dataair<airtime5><active>$w5_ACT</active><busy>$w5_BUS</busy></airtime5>"
fi
if pgrep babeld >/dev/null; then
neighbours="$(echo dump | nc ::1 33123 | grep '^add neighbour' |
awk '{
for (i=2; i < NF; i += 2) {
vars[$i] = $(i+1)
}
}
{
printf "<neighbour><ip>%s</ip><outgoing_interface>%s</outgoing_interface><link_cost>%s</link_cost></neighbour>", vars["address"], vars["if"], vars["cost"]
}')"
BABELS="<babel_neighbours>$neighbours</babel_neighbours>"
fi
err "$(date): Putting all information into a XML-File and save it at $SCRIPT_DATA_FILE"
DATA="<?xml version='1.0' standalone='yes'?><data>"
DATA=$DATA"<system_data>$SYSTEM_DATA</system_data>"
DATA=$DATA"<interface_data>$interface_data</interface_data>"
DATA=$DATA"<batman_adv_interfaces>$BATMAN_ADV_INTERFACES</batman_adv_interfaces>"
DATA=$DATA"<batman_adv_originators>$batman_adv_originators</batman_adv_originators>"
DATA=$DATA"<batman_adv_gateway_mode>$batman_adv_gateway_mode</batman_adv_gateway_mode>"
DATA=$DATA"<batman_adv_gateway_list>$batman_adv_gateway_list</batman_adv_gateway_list>"
DATA=$DATA"$BABELS"
DATA=$DATA"<client_count>$client_count</client_count>"
DATA=$DATA"<clients>$dataclient</clients>"
DATA=$DATA"$dataair"
DATA=$DATA"</data>"
#write data to xml file that provides the data on httpd
SCRIPT_DATA_DIR=$(dirname "$SCRIPT_DATA_FILE")
test -d "$SCRIPT_DATA_DIR" || mkdir -p "$SCRIPT_DATA_DIR"
echo "$DATA" | gzip | tee "$SCRIPT_DATA_FILE" | alfred -s 64
#write data to xml file that provides the data on httpd
SCRIPT_DATA_DIR=$(dirname "$SCRIPT_DATA_FILE")
test -d "$SCRIPT_DATA_DIR" || mkdir -p "$SCRIPT_DATA_DIR"
echo "$DATA" | gzip | tee "$SCRIPT_DATA_FILE" | alfred -s 64
}
LANG=C
#Prüft ob das logfile zu groß geworden ist
err "$(date): Check logfile"
debug "$(date): Check logfile"
delete_log
#Erzeugt die statusdaten
err "$(date): Generate actual status data"
debug "$(date): Generate actual status data"
crawl
exit 0

View File

@ -1,7 +1,7 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=fff-wireless
PKG_RELEASE:=16
PKG_RELEASE:=17
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)

View File

@ -0,0 +1,18 @@
#!/bin/sh
# Netmon Nodewatcher (C) 2010-2012 Freifunk Oldenburg
# License; GPL v3
w2dump="$(iw dev w2ap survey dump 2> /dev/null | sed '/Survey/,/\[in use\]/d')"
if [ -n "$w2dump" ] ; then
w2_ACT="$(ACTIVE=$(echo "$w2dump" | grep "active time:"); set ${ACTIVE:-0 0 0 0 0}; echo -e "${4}")"
w2_BUS="$(BUSY=$(echo "$w2dump" | grep "busy time:"); set ${BUSY:-0 0 0 0 0}; echo -e "${4}")"
echo -n "$dataair<airtime2><active>$w2_ACT</active><busy>$w2_BUS</busy></airtime2>"
fi
w5dump="$(iw dev w5ap survey dump 2> /dev/null | sed '/Survey/,/\[in use\]/d')"
if [ -n "$w5dump" ] ; then
w5_ACT="$(ACTIVE=$(echo "$w5dump" | grep "active time:"); set ${ACTIVE:-0 0 0 0 0}; echo -e "${4}")"
w5_BUS="$(BUSY=$(echo "$w5dump" | grep "busy time:"); set ${BUSY:-0 0 0 0 0}; echo -e "${4}")"
echo -n "$dataair<airtime5><active>$w5_ACT</active><busy>$w5_BUS</busy></airtime5>"
fi
exit 0