|
UPnP steht für 'Universal Plug and Play', welches von plug-and-play (englisch) abgeleitet ist. Es ist eine Sammlung von Protokollen, welche vom UPnP Forum (englisch) definiert wurden.
Ein Teil dieser Ziele ist es nützliche Informationen über das Gerät im Netzwerk zu verbreiten, damit andere Geräte diese Informationen nutzen können um das neue Gerät zu integrieren.
Die Spezifaktionen über UPnP können hier (englisch) gefunden werden.
Es gibt viele Wege um Informationen von UPnP Geräten zu erhalten. Es gibt sogar einige Werkzeuge, welche es ermöglichen über graphische Oberflächen mit UPnP zu experimentieren - wie zum Beipiel GUPnP (englisch).
Ich habe den Weg über Perl (englisch) und das Net::UPnP-Module (english) gewählt.
Das folgende Skript benutzt dieses Perl-Modul um UPnP Geräte im Netzwerk zu erkennen und Informationen über die verfügbaren Dienste abzufragen.
#!/usr/bin/perl
# Geschrieben im August 2009 von Axel Arnold - http://www.axel-arnold.de
# Dieser Code wird unter der CPL 1.0 (http://www.opensource.org/licenses/cpl1.0.php) zur Verfügung gestellt
use strict;
# Subroutine um die Servicebeschreibung ueber http zu holen und alle verfuegbaren Actions aus dieser zu extrahieren
sub getServiceActions {
my ($url) = @_;
my @result = ();
my $ua = LWP::UserAgent->new;
$ua->timeout(10);
$ua->env_proxy;
my $response = $ua->get( $url );
if ( $response->is_success ) {
my $parser = XML::LibXML->new();
my $doc = $parser->parse_string( $response->decoded_content );
my $root = $doc->firstChild();
my $xpc = XML::LibXML::XPathContext->new( $root );
$xpc->registerNs('x', 'urn:schemas-upnp-org:service-1-0');
my @actions = $xpc->findnodes('//x:actionList/x:action/x:name' );
foreach my $action (@actions) {
@result=(@result, $action->textContent());
}
}
}
if ((@ARGV) == 0) {
die "get_upnp_info <Muster des Geraetenamens>\n\nBeispiel: get_upnp_info FRITZ\n get_upnp_info .\n";
}
my $devicePattern = "$ARGV[0]";
# Basisgeraete finden
my $obj = Net::UPnP::ControlPoint->new();
my @dev_list = $obj->search( st =>'upnp:rootdevice', mx => 3 );
# Iteriere ueber alle gefundenen Geraete
foreach my $dev (@dev_list) {
# Pruefe ob das Geraet dem angegebenen Muster entspricht
$_ = $dev->getfriendlyname();
if ( not /$devicePattern/ ) {
next;
}
print "Device = " . $dev-> getfriendlyname() . "\n";
my $url = URI->new( $dev->getlocation() );
# hole alle Dienste
my @service_list = $dev->getservicelist();
foreach my $service (@service_list) {
my $serviceID = $service->getserviceid();
my $scpdurl = $service->getdevicedescription( name=>'SCPDURL' );
# hole alle Actions des Dienstes
$url->path( $scpdurl );
my @actions = getServiceActions( $url );
foreach my $action ( @actions ) {
$_ = $action;
# 'post' alle 'Get' Actions
if ( /^Get/ ) {
my %action_in_arg = ();
my $action_res = $service->postaction( $action, \%action_in_arg);
if ($action_res->getstatuscode() == 200) {
my $arg_ref = $action_res->getargumentlist();
my %args = %$arg_ref;
foreach my $k ( keys %args ) {
print "" . $serviceID . "::" . $action . ":" . $k . " = " . $args{$k} . "\n";
}
}
}
}
}
}
Ich benutze dieses Perl-Skript um den Status meiner FRITZ!Box in Nagios (englisch), einer Software zur Überwachung von Hard- und Software, zu verfolgen.
Dies ist das Nagios-Skript (es erwartet die Warnungs-Upstream-, die Fehler-Upstream-, die Warnungs-Downstream- und die Fehler-Downstream-Bitrate als Kommandozeilenparameter):
#!/bin/ksh
# Erstellt im August 2009 von Axel Arnold - http://www.axel-arnold.de
# Dieser Code wird unter der CPL 1.0 (http://www.opensource.org/licenses/cpl1.0.php) zur Verfügung gestellt.
dir=`dirname $0`
minup=$1
maxup=$2
mindown=$3
maxdown=$4
integer minup
integer maxup
integer mindown
integer maxdown
upnp=`/usr/local/bin/get_upnp_info FRITZ!Box`
# ERROR - no physical link
physical_link_status=`echo "$upnp" | grep 'GetCommonLinkProperties:NewPhysicalLinkStatus'`
echo "$physical_link_status" | grep -E 'Up$' > /dev/null
if [ $? -ne 0 ]; then
/usr/bin/echo "FRITZ!Box Physical Link is not Up!"
exit 2
fi
# ERROR - no DSL link
link_status=`echo "$upnp" | grep 'GetDSLLinkInfo:NewLinkStatus'`
echo "$link_status" | grep -E 'Up$' > /dev/null
if [ $? -ne 0 ]; then
/usr/bin/echo "FRITZ!Box DSL Link is not Up!"
exit 2
fi
upstream=`echo "$upnp" | grep 'GetCommonLinkProperties:NewLayer1UpstreamMaxBitRate' | awk -F'=' '{print $2}'`
downstream=`echo "$upnp" | grep 'GetCommonLinkProperties:NewLayer1DownstreamMaxBitRate' | awk -F'=' '{print $2}'`
# ERROR - upstream too low
if [ $upstream -lt $minup ]; then
/usr/bin/echo "FRITZ!Box max. Upstream Bitrate too low! | $upstream $downstream"
/usr/bin/echo "$upstream $downstream | "
exit 2
# WARNING - upstream too low
elif [ $upstream -lt $maxup ]; then
/usr/bin/echo "FRITZ!Box max. Upstream Bitrate too low! | $upstream $downstream"
/usr/bin/echo "$upstream $downstream | "
exit 1
fi
# ERROR - downstream too low
if [ $downstream -lt $mindown ]; then
/usr/bin/echo "FRITZ!Box max. Downstream Bitrate too low! | $upstream $downstream"
/usr/bin/echo "$upstream $downstream | "
exit 2
# WARNING - downstream too low
elif [ $downstream -lt $maxdown ]; then
/usr/bin/echo "FRITZ!Box max. Downstream Bitrate too low! | $upstream $downstream"
/usr/bin/echo "$upstream $downstream | "
exit 1
fi
uptime=`echo "$upnp" | grep 'GetStatusInfo:NewUptime' | awk -F'=' '{print $2}'`
upseconds=uptime
integer uptime;
integer days
integer hours
integer minutes
integer seconds
days=$uptime/60/60/24
uptime=$uptime-($days*60*60*24)
hours=$uptime/60/60
uptime=$uptime-($hours*60*60)
minutes=$uptime/60
uptime=$uptime-($minutes*60)
seconds=$uptime
/usr/bin/echo "Uptime ${days}d ${hours}h ${minutes}min ${seconds}sec | $upstream $downstream"
/usr/bin/echo "$upstream $downstream | "
exit 0
Zuletzt geändert: 12.12.2009
|
/etc/nagios/resource.cfg:
#hinzugefuegt
$USER2$=/etc/nagios/localcommands
/etc/nagios/objects/commands.cfg:
# hinzugefuegt:
define command {
command_name check_fritzbox
command_line $USER2$/check_fritzbox.ksh $ARG1$ $ARG2$ $ARG3$ $ARG4$
}
/etc/nagios/objects/local-net.cfg:
# hinzugefuegt
define service {
use remote-service
host_name router
service_description FRITZ Box
check_command check_fritzbox!1100000!1140000!14000000!14300000
}
ich hatte vor einiger Zeit schon einmal Deine Fritz!Box-Überwachung am Laufen, aber dann ist irgendwann die Festplattte mit dem system darauf gestorben. Jetzt wollte ich die Sache noch einmal angehen und habe das ganze neu installiert, aber ich bekomme keine Info (get_upnp_info) zurück. Ich weiß einfach nicht mehr weiter. Vielleicht hast Du zeit für eine kleine Offline-Diskussion.
Vielen Dank im Voraus
Ullrich
Kommentar hinzufügen