mirror of
https://github.com/munin-monitoring/contrib.git
synced 2018-11-08 00:59:34 +01:00
254 lines
8.8 KiB
Ruby
Executable File
254 lines
8.8 KiB
Ruby
Executable File
#!/usr/bin/ruby
|
|
#
|
|
# Munin plugin for the D-link DIR-655 router
|
|
#
|
|
# This plugin can graph # of wifi clients, # of DHCP clients, collisions & errors for all network interfaces, dropped packets for all interfaces, and both transmit and receive rates for all interfaces of the router.
|
|
#
|
|
# Author: David Reitz
|
|
#
|
|
# 1. Copy script to a Linux server on your network.
|
|
# 2. Create symlink. (ln -s /path/to/dlink_dir655 /etc/munin/plugins/dlink_dir655)
|
|
# 3. Edit plugin configuration for this script (vi /etc/munin/plugin-conf.d/munin-node) and add:
|
|
# [dlink_dir655]
|
|
# host_name dir655
|
|
# env.router_password password
|
|
# env.router_ip_address 10.0.0.1
|
|
# 4. Edit munin configuration to point to itself to gather the data from your router (vi /etc/munin/munin-conf.d/munin) and add:
|
|
# [dir655]
|
|
# address 127.0.0.1
|
|
# use_node_name no
|
|
# 5. Modify the 'password' and 'router_path' variables below to reflect the correct password for the 'User' user on your D-link DIR-655 router and to reflect the correct IP address of your router (this *MUST* be on your local subnet/LAN).
|
|
#
|
|
# NOTICE 1: This is the first Ruby script I've written (as well as being my first Munin plugin), so I consider this a bit of a hack. Just letting you know ahead of time. :)
|
|
#
|
|
# NOTICE 2: I provide this script *as-is*. Use at your own risk! I thought other people may find this script useful/interesting but have no plans to support it for anyone else.
|
|
#
|
|
# Many thanks go to Clarke Brunsdon for his code listed at http://clarkebrunsdon.com/2010/12/the-dlink-dir-655-hash-changes/!!! This really helped me out!
|
|
#
|
|
# Original Implementation: 13 Jan 2011
|
|
gem 'mechanize'
|
|
require 'mechanize'
|
|
require 'digest/md5'
|
|
require 'nokogiri'
|
|
|
|
|
|
def output
|
|
nics = Hash.new
|
|
nics["LAN"] = Hash.new
|
|
nics["WAN"] = Hash.new
|
|
nics["WLAN"] = Hash.new
|
|
password = ENV['router_password'] || ""
|
|
router_path = ENV['router_ip_address'] || "10.0.0.1"
|
|
router_path = "http://" + router_path
|
|
agent = Mechanize.new
|
|
x = agent.get(router_path)
|
|
salt = x.body.match(/salt = "(.*)"/)[1]
|
|
|
|
# pad the pasword to length 16
|
|
pad_size = (16 - password.length)
|
|
padded_password = password + "\x01" * pad_size
|
|
|
|
# pad it the rest of the way, length 64 for user
|
|
salted_password = salt + padded_password + ("\x01" * (63 - salt.length - padded_password.length)) + "U"
|
|
login_hash = salt + Digest::MD5.hexdigest(salted_password)
|
|
|
|
# authenticate against the router using the hash that we just built
|
|
login_path = "#{router_path}/post_login.xml?hash=#{login_hash}"
|
|
x = agent.get(login_path)
|
|
|
|
# grab the statistics for all interfaces and parse it into a usable form
|
|
clients_xml = agent.get("#{router_path}/interface_stats.xml").body
|
|
doc = Nokogiri::XML(clients_xml.to_s)
|
|
doc.xpath('//interface').each do |interface|
|
|
children = interface.children
|
|
name = children.search('name')[0].text
|
|
nics[name]["packets_sent"] = children.search('packets_sent')[0].text
|
|
nics[name]["packets_received"] = children.search('packets_received')[0].text
|
|
nics[name]["tx_dropped"] = children.search('tx_dropped')[0].text
|
|
begin
|
|
nics[name]["tx_collisions"] = children.search('tx_collisions')[0].text
|
|
rescue Exception
|
|
nics[name]["tx_collisions"] = "0"
|
|
end
|
|
nics[name]["rx_dropped"] = children.search('rx_dropped')[0].text
|
|
nics[name]["rx_errors"] = children.search('rx_errors')[0].text
|
|
end
|
|
|
|
# get wifi associations and print out info for munin graph
|
|
puts "multigraph clients"
|
|
clients_xml = agent.get("#{router_path}/wifi_assoc.xml").body
|
|
j = 0
|
|
doc = Nokogiri::XML(clients_xml.to_s)
|
|
doc.xpath('//assoc').each do |assoc|
|
|
j+=1
|
|
end
|
|
puts "wifi_assoc.value " + j.to_s
|
|
|
|
# get dhcp clients and print out info for munin graph
|
|
clients_xml = agent.get("#{router_path}/dhcp_clients.xml").body
|
|
j = 0
|
|
doc = Nokogiri::XML(clients_xml.to_s)
|
|
doc.xpath('//client').each do |client|
|
|
j+=1
|
|
end
|
|
puts "dhcp_clients.value " + j.to_s
|
|
|
|
puts "multigraph uptime"
|
|
# get uptime of connection
|
|
clients_xml = agent.get("#{router_path}/wan_connection_status.xml").body
|
|
doc = Nokogiri::XML(clients_xml.to_s)
|
|
uptime = doc.children.search('wan_interface_up_time_0')[0].text
|
|
puts "uptime.value " + sprintf( "%.2f", (Float(uptime)/86400) )
|
|
|
|
# graph overall interface packets transferred per interval
|
|
puts "multigraph if_packets"
|
|
for i in [ "LAN", "WAN", "WLAN" ] do
|
|
puts "#{i}_recv.value " + nics[i]["packets_received"]
|
|
puts "#{i}_send.value " + nics[i]["packets_sent"]
|
|
end
|
|
|
|
# graph overall interface dropped packets per interval
|
|
puts "multigraph if_drop"
|
|
for i in [ "LAN", "WAN", "WLAN" ] do
|
|
puts "#{i}_recv.value " + nics[i]["rx_dropped"]
|
|
puts "#{i}_send.value " + nics[i]["tx_dropped"]
|
|
end
|
|
|
|
# graph overall interface collisions & errors per interval
|
|
puts "multigraph if_collerr"
|
|
for i in [ "LAN", "WAN", "WLAN" ] do
|
|
puts "#{i}_coll.value " + nics[i]["tx_collisions"]
|
|
puts "#{i}_err.value " + nics[i]["rx_errors"]
|
|
end
|
|
|
|
# graph stats for each interface
|
|
for i in [ "LAN", "WAN", "WLAN" ] do
|
|
puts "multigraph if_packets.#{i}"
|
|
puts "send.value " + nics[i]["packets_sent"]
|
|
puts "recv.value " + nics[i]["packets_received"]
|
|
puts "multigraph if_drop.#{i}"
|
|
puts "send.value " + nics[i]["tx_dropped"]
|
|
puts "recv.value " + nics[i]["rx_dropped"]
|
|
puts "multigraph if_collerr.#{i}"
|
|
puts "coll.value " + nics[i]["tx_collisions"]
|
|
puts "err.value " + nics[i]["rx_errors"]
|
|
end
|
|
end
|
|
|
|
|
|
def config
|
|
# build the configuration for graphs
|
|
puts "multigraph if_packets"
|
|
puts 'graph_title D-Link DIR-655 interface traffic'
|
|
puts 'graph_category network'
|
|
puts 'graph_order LAN_recv LAN_send WAN_recv WAN_send WLAN_recv WLAN_send'
|
|
puts 'graph_vlabel packets in (-) / out (+) per ${graph_period}'
|
|
for i in [ "LAN", "WAN", "WLAN" ] do
|
|
puts "#{i}_recv.type DERIVE"
|
|
puts "#{i}_recv.graph no"
|
|
puts "#{i}_recv.min 0"
|
|
puts "#{i}_send.label #{i}"
|
|
puts "#{i}_send.type DERIVE"
|
|
puts "#{i}_send.negative #{i}_recv"
|
|
puts "#{i}_send.min 0"
|
|
end
|
|
|
|
puts "multigraph if_drop"
|
|
puts 'graph_title D-Link DIR-655 interface drops'
|
|
puts 'graph_category network'
|
|
puts 'graph_order LAN_recv LAN_send WAN_recv WAN_send WLAN_recv WLAN_send'
|
|
puts 'graph_vlabel packets / ${graph_period}'
|
|
for i in [ "LAN", "WAN", "WLAN" ] do
|
|
puts "#{i}_recv.type DERIVE"
|
|
puts "#{i}_recv.graph no"
|
|
puts "#{i}_recv.min 0"
|
|
puts "#{i}_send.label #{i}"
|
|
puts "#{i}_send.type DERIVE"
|
|
puts "#{i}_send.negative #{i}_recv"
|
|
puts "#{i}_send.min 0"
|
|
end
|
|
|
|
puts "multigraph if_collerr"
|
|
puts 'graph_title D-Link DIR-655 interface collisions & errors'
|
|
puts 'graph_category network'
|
|
puts 'graph_order LAN_coll LAN_err WAN_coll WAN_err WLAN_coll WLAN_coll'
|
|
puts 'graph_vlabel packets / ${graph_period}'
|
|
for i in [ "LAN", "WAN", "WLAN" ] do
|
|
puts "#{i}_coll.label #{i} collisions"
|
|
puts "#{i}_coll.type DERIVE"
|
|
puts "#{i}_coll.min 0"
|
|
puts "#{i}_err.label #{i} errors"
|
|
puts "#{i}_err.type DERIVE"
|
|
puts "#{i}_err.min 0"
|
|
end
|
|
|
|
puts "multigraph clients"
|
|
puts "graph_title D-Link DIR-655 client information"
|
|
puts "graph_category system"
|
|
puts "graph_order dhcp_clients wifi_assoc"
|
|
puts "graph_vlabel number of clients"
|
|
puts "dhcp_clients.label DHCP clients"
|
|
puts "dhcp_clients.type GAUGE"
|
|
puts "dhcp_clients.min 0"
|
|
puts "wifi_assoc.label wifi clients"
|
|
puts "wifi_assoc.type GAUGE"
|
|
puts "wifi_assoc.min 0"
|
|
|
|
puts "multigraph uptime"
|
|
puts "graph_title Uptime"
|
|
puts 'graph_vlabel uptime in days'
|
|
puts 'graph_category system'
|
|
puts 'uptime.label uptime'
|
|
puts 'uptime.draw AREA'
|
|
|
|
for i in [ "LAN", "WAN", "WLAN" ] do
|
|
puts "multigraph if_packets.#{i}"
|
|
puts "graph_title D-Link DIR-655 #{i} traffic"
|
|
puts 'graph_category network'
|
|
puts 'graph_order recv send'
|
|
puts 'graph_vlabel packets in (-) / out (+) per ${graph_period}'
|
|
puts 'recv.label received'
|
|
puts 'recv.type DERIVE'
|
|
puts 'recv.graph no'
|
|
puts 'recv.min 0'
|
|
puts 'send.label packets/sec'
|
|
puts 'send.type DERIVE'
|
|
puts 'send.negative recv'
|
|
puts 'send.min 0'
|
|
|
|
puts "multigraph if_drop.#{i}"
|
|
puts "graph_title D-Link DIR-655 #{i} drops"
|
|
puts 'graph_category network'
|
|
puts 'graph_order recv send'
|
|
puts 'graph_vlabel packets / ${graph_period}'
|
|
puts 'recv.label RX packets dropped'
|
|
puts 'recv.type DERIVE'
|
|
puts 'recv.graph no'
|
|
puts 'recv.min 0'
|
|
puts 'send.label TX packets dropped'
|
|
puts 'send.type DERIVE'
|
|
puts 'send.negative recv'
|
|
puts 'send.min 0'
|
|
|
|
puts "multigraph if_collerr.#{i}"
|
|
puts "graph_title D-Link DIR-655 #{i} collisions & errors"
|
|
puts 'graph_category network'
|
|
puts 'graph_order coll err'
|
|
puts 'graph_vlabel packets / ${graph_period}'
|
|
puts 'coll.label collisions'
|
|
puts 'coll.type DERIVE'
|
|
puts 'coll.min 0'
|
|
puts 'err.label errors'
|
|
puts 'err.type DERIVE'
|
|
puts 'err.min 0'
|
|
end
|
|
end
|
|
|
|
|
|
# main
|
|
if ARGV.length == 1 and ARGV[0] == 'config'
|
|
config()
|
|
else
|
|
output()
|
|
end
|