#!/bin/sh -u # -*- sh -*- : << =cut =head1 NAME upnpc_ - Plugin to monitor routers via UPnP This plugin uses the upnpc utility (package miniupnpc in Debian), to monitor an router using UPnP. It can monitor the following aspects, and plot them as separate graphs, or a single multigraph (if linked at upnpc or upnpc_multi: * uptime: how long the link has been up; * bitrate: the up and downlink bitrate (e.g., sync speed for DSL); * traffic: the actual up and downstream traffic rate; * pkts: the number of packets coming in and out. =head1 APPLICABLE SYSTEMS Linux systems with upnpc installed (miniupnpc package). =head1 CONFIGURATION If you do not want to show the link maximum bitrates, add the following plugin-configuration: [upnpc*] env.traffic_remove_max true =head1 AUTHOR Olivier Mehani Copyright (C) 2016,2019 Olivier Mehani =head1 LICENSE SPDX-License-Identifier: GPL-3.0-or-later =head1 MAGIC MARKERS #%# family=auto #%# capabilities=autoconf suggest =cut if [ "${MUNIN_DEBUG:-0}" = 1 ]; then set -x fi if ! command -v upnpc >/dev/null; then echo "upnpc not found (miniupnpc package)" >&2 exit 1 fi PLUGIN_NAME="$(basename "${0}")" MODE="$(echo "${PLUGIN_NAME}" | sed 's/.*_//')" DATA="$(upnpc -s)" SUPPORTED_MODES=$( echo "${DATA}" | sed -n " \ s/.*Bytes.*/traffic/p; \ s/.*Packets.*/pkts/p; \ s/.*uptime=.*/uptime/p; \ ") HOST=$(echo "${DATA}" | sed -n "s#.*desc: http://\([^/:]\+\).*#\1#p") autoconf() { test -n "${DATA}" && echo yes || echo "no (No UPnP router detected)" } suggest () { for mode in ${SUPPORTED_MODES}; do echo "${mode}" done echo "multi" } config () { case ${1} in "uptime") cat << EOF graph_title Uplink connection uptime (${HOST}) graph_args -l 0 graph_category network graph_scale no graph_vlabel uptime in hours uptime.label uptime uptime.draw AREA uptime.cdef uptime,3600,/ EOF ;; "bitrate") cat << EOF graph_title [DEPRECATED] Uplink bitrate (${HOST}) graph_args --base 1000 -l 0 graph_category network graph_vlabel bitrate down (-) / up (+) down.label bps up.label bps down.graph no up.negative down EOF ;; "traffic") cat << EOF graph_title Uplink traffic (${HOST}) graph_args --base 1000 -l 0 graph_category network EOF if [ "${traffic_remove_max:-false}" != 'true' ]; then cat << EOF maxdown.label bps (max) maxup.label bps (max) maxdown.graph no maxup.negative maxdown EOF fi cat << EOF down.label bps down.type DERIVE down.min 0 down.cdef down,8,* up.label bps up.type DERIVE up.min 0 up.cdef up,8,* down.graph no up.negative down EOF ;; "pkts") # ${graph_period} is not a shell variable cat << EOF graph_title Uplink packets (${HOST}) graph_args --base 1000 -l 0 graph_category network EOF # ${graph_period} is not a shell variable # shellcheck disable=SC2016 echo 'graph_vlabel packets in (-) / out (+) per ${graph_period}' cat << EOF down.label pps down.type DERIVE down.min 0 up.label pps up.type DERIVE up.min 0 down.graph no up.negative down EOF ;; "multi"|"upnpc") echo "multigraph ${PLUGIN_NAME}" config "traffic" for mode in ${SUPPORTED_MODES}; do echo "multigraph ${PLUGIN_NAME}.${mode}" config "${mode}" done ;; *) echo "unknown mode '${1}'" >&2 exit 1 ;; esac } fetch () { case "${1}" in "uptime") echo "${DATA}" | sed -n "s/.*uptime=\([0-9]\+\)s.*/uptime.value \1/p" ;; "bitrate") echo "${DATA}" | sed -n "s/^MaxBitRateDown : \([0-9]\+\) bps.*MaxBitRateUp \([0-9]\+\) bps.*/down.value \1\nup.value \2/p" ;; "traffic") echo "${DATA}" | sed -n " s/^Bytes:\s*Sent:\s*\([0-9]\+\).*Recv:\s*\([0-9]\+\).*/up.value \1\ndown.value \2/p" if [ "${traffic_remove_max:-false}" != 'true' ]; then echo "${DATA}" | sed -n " s/^MaxBitRateDown : \([0-9]\+\) bps.*MaxBitRateUp \([0-9]\+\) bps.*/maxdown.value \1\nmaxup.value \2/p" fi ;; "pkts") echo "${DATA}" | sed -n "s/^Packets:\s*Sent:\s*\([0-9]\+\).*Recv:\s*\([0-9]\+\).*/up.value \1\ndown.value \2/p" ;; "multi"|"upnpc") echo "multigraph ${PLUGIN_NAME}" fetch "traffic" for mode in ${SUPPORTED_MODES}; do echo "multigraph ${PLUGIN_NAME}.${mode}" fetch "${mode}" done ;; *) echo "unknown mode '${1}'" >&2 exit 1 ;; esac } case ${1:-} in "autoconf") autoconf ;; "suggest") suggest ;; "config") config "${MODE}" if [ "${MUNIN_CAP_DIRTYCONFIG:-0}" = "1" ]; then fetch "${MODE}" fi ;; *) fetch "${MODE}" ;; esac