#!/bin/sh # Netmon Nodewatcher (C) 2010-2012 Freifunk Oldenburg # License; GPL v3 SCRIPT_VERSION="33" test -f /tmp/started || exit #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` CLIENT_INTERFACES=`uci get nodewatcher.@network[0].client_interfaces` IFACEBLACKLIST=`uci get nodewatcher.@network[0].iface_blacklist` IPWHITELIST=`uci get nodewatcher.@network[0].ip_whitelist` else . `dirname $0`/nodewatcher_config fi if [ $SCRIPT_ERROR_LEVEL -gt "1" ]; then err() { echo $1 >> $SCRIPT_LOGFILE } else err() { : } fi #this method checks id the logfile has bekome too big and deletes the first X lines delete_log() { if [ -f $SCRIPT_LOGFILE ]; then if [ `ls -la $SCRIPT_LOGFILE | awk '{ print $5 }'` -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 } #this method generates the crawl data xml file that is beeing 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)" uptime=$(awk '{ printf ""$1""$2"" }' /proc/uptime) memory=$(awk ' /^MemTotal/ { printf ""$2"" } /^Cached:/ { printf ""$2"" } /^Buffers/ { printf ""$2"" } /^MemFree/ { printf ""$2"" } ' /proc/meminfo) cpu=$(awk -F': ' ' /model/ { printf ""$2"" } /system type/ { printf ""$2"" } ' /proc/cpuinfo) model="$(cat /var/sysinfo/model)" local_time="`date +%s`" load=$(awk '{ printf ""$3""$4"" }' /proc/loadavg) err "`date`: Collecting version information" batman_adv_version=$(cat /sys/module/batman_adv/version) kernel_version=$(uname -r) fastd_version=$(fastd -v | awk '{ print $2 }') nodewatcher_version=$SCRIPT_VERSION # 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="online$hostname$distname$distversion$cpu$model$memory$load$uptime$local_time$batman_adv_version$kernel_version$fastd_version$nodewatcher_version$FIRMWARE_VERSION$BUILD_DATE$OPENWRT_CORE_REVISION$OPENWRT_FEEDS_PACKAGES_REVISION" err "`date`: Collecting information from network interfaces" #Get interfaces #IFACES=`cat /proc/net/dev | awk -F: '!/\|/ { gsub(/[[:space:]]*/, "", $1); split($2, a, " "); printf("%s=%s=%s ", $1, a[1], a[9]) }'` 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 awkscript=' /ether/ { printf ""$2"" } /mtu/ { printf ""$5"" }' if inArray "$IPWHITELIST" "$iface"; then awkscript=$awkscript' /inet / { split($2, a, "/"); printf ""a[1]"" } /inet6/ && /scope global/ { printf ""$2"" } /inet6/ && /scope link/ { printf ""$2""}' 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>$iface$mac_addr$ipv4_addr$ipv6_addr$ipv6_link_local_addr$traffic_rx$traffic_tx$mtu" interface_data=$interface_data"<$iface>$iface$addrs$traffic_rx$traffic_tx" interface_data=$interface_data$(iwconfig ${iface} 2>/dev/null | awk -F':' ' /Mode/{ split($2, m, " "); printf ""m[1]"" } /Cell/{ split($0, c, " "); printf ""c[5]"" } /ESSID/ { split($0, e, "\""); printf ""e[2]"" } /Freq/{ split($3, f, " "); printf ""f[1]f[2]"" } /Tx-Power/{ split($0, p, "="); sub(/[[:space:]]*$/, "", p[2]); printf ""p[2]"" } ')"" #if [ "`iwconfig ${iface} 2>/dev/null | grep IEEE`" != "" ]; then # wlan_mode="`iwconfig $iface | awk -F':' '/Mode/{ split($2, m, " "); print m[1] }'`" # # if [ $wlan_mode = "Master" ]; then # wlan_bssid="`iw $iface info | awk '/addr/{ print $2 }'`" # elif [ $wlan_mode = "Ad-Hoc" ]; then # wlan_bssid="`iwconfig $iface | awk '/Cell/{ print $5 }'`" # fi # # wlan_essid="`iwconfig ${iface} | awk -F'"' '/ESSID/ { print $2 }'`" # wlan_frequency="`iwconfig $iface | awk -F':' '/Freq/{ split($3, f, " "); print f[1] }'`" # wlan_tx_power="`iwconfig $iface | awk -F'=' '/Tx-Power/{ print $2 }'`" # # interface_data=$interface_data"$wlan_mode$wlan_frequency$wlan_essid$wlan_bssid$wlan_tx_power" #fi #interface_data=$interface_data"" done err "`date`: Collecting information from batman advanced and it´s interfaces" #B.A.T.M.A.N. advanced if [ -f /sys/module/batman_adv/version ]; then for iface in $(grep active /sys/class/net/*/batman_adv/iface_status); do status=${iface#*:} iface=${iface%/batman_adv/iface_status:active} iface=${iface#/sys/class/net/} BATMAN_ADV_INTERFACES=$BATMAN_ADV_INTERFACES"<$iface>$iface$status" done # Build a list of direct neighbors batman_adv_originators=$(awk \ 'BEGIN { FS=" "; i=0 } # set the delimiter to " " /O/ { next } # ignore lines with O (will remove second line) /B/ { next } # ignore line with B (will remove first line) { sub("\\(", "", $0) # remove parentheses 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 ""$1""$3""$4""$2""$5"" i++ } }' /sys/kernel/debug/batman_adv/bat0/originators) batman_adv_gateway_mode=$(batctl gw) batman_adv_gateway_list=$(awk \ 'BEGIN { FS=" "; i=0 } /Gateway/ { next } /No gateways/ { next } { sub("=>", "true", $0) sub(" ", "false", $0) sub("\\(", "", $0) sub("\\)", "", $0) sub("\\[", "", $0) sub("\\]:", "", $0) sub(" ", " ", $0) printf ""$1""$2""$3""$4""$5""$6" "$7" "$8"" i++ }' /sys/kernel/debug/batman_adv/bat0/gateways) fi err "`date`: Collecting information about conected clients" #CLIENTS SEDDEV=$(brctl showstp $MESH_INTERFACE | awk '/\([0-9]\)/ { sub("\\(", "", $0) sub("\\)", "", $0) print "s/^ "$2"/"$1"/;" }') client_count=$(brctl showmacs $MESH_INTERFACE | sed -e "$SEDDEV" | egrep -c "(${CLIENT_INTERFACES// /|}).*no") err "`date`: Putting all information into a XML-File and save it at "$SCRIPT_DATA_FILE DATA="$SYSTEM_DATA$interface_data$BATMAN_ADV_INTERFACES$batman_adv_originators$batman_adv_gateway_mode$batman_adv_gateway_list$client_count" #write data to hxml file that provides the data on httpd 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" delete_log #Erzeugt die statusdaten err "`date`: Generate actual status data" crawl exit 0