Projet

Général

Profil

Paste
Télécharger au format
Statistiques
| Branche: | Révision:

root / plugins / router / d-link-dir-655-router-statistics-plugin @ 38649d31

Historique | Voir | Annoter | Télécharger (8,74 ko)

1 7a37bfb1 Lars Kruse
#!/usr/bin/env ruby
2 e9c3bcc2 David Reitz
#
3
# Munin plugin for the D-link DIR-655 router
4
#
5
# 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.
6
#
7
# Author:  David Reitz
8
#
9
# 1.  Copy script to a Linux server on your network.
10
# 2.  Create symlink. (ln -s /path/to/dlink_dir655 /etc/munin/plugins/dlink_dir655)
11
# 3.  Edit plugin configuration for this script (vi /etc/munin/plugin-conf.d/munin-node) and add:
12
#     [dlink_dir655]
13
#     host_name dir655
14
#     env.router_password password
15
#     env.router_ip_address 10.0.0.1
16
# 4.  Edit munin configuration to point to itself to gather the data from your router (vi /etc/munin/munin-conf.d/munin) and add:
17
#     [dir655]
18
#     address 127.0.0.1
19
#     use_node_name no
20
# 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).
21
#
22
# 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.  :)
23
#
24
# 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.
25
#
26
# 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!
27
#
28
# Original Implementation:  13 Jan 2011
29
gem 'mechanize'
30
require 'mechanize'
31
require 'digest/md5'
32
require 'nokogiri'
33
34
def output
35 809639ab Lars Kruse
  nics = {}
36
  nics['LAN'] = {}
37
  nics['WAN'] = {}
38
  nics['WLAN'] = {}
39
  password = ENV['router_password'] || ''
40
  router_path = ENV['router_ip_address'] || '10.0.0.1'
41
  router_path = 'http://' + router_path
42 e9c3bcc2 David Reitz
  agent = Mechanize.new
43
  x = agent.get(router_path)
44
  salt = x.body.match(/salt = "(.*)"/)[1]
45 17f78427 Lars Kruse
46 8713eb37 Lars Kruse
  # pad the password to length 16
47 e9c3bcc2 David Reitz
  pad_size = (16 - password.length)
48
  padded_password = password + "\x01" * pad_size
49 17f78427 Lars Kruse
50 e9c3bcc2 David Reitz
  # pad it the rest of the way, length 64 for user
51 809639ab Lars Kruse
  salted_password = salt + padded_password + ("\x01" * (63 - salt.length - padded_password.length)) + 'U'
52 e9c3bcc2 David Reitz
  login_hash = salt + Digest::MD5.hexdigest(salted_password)
53 17f78427 Lars Kruse
54 e9c3bcc2 David Reitz
  # authenticate against the router using the hash that we just built
55
  login_path = "#{router_path}/post_login.xml?hash=#{login_hash}"
56
  x = agent.get(login_path)
57
58
  # grab the statistics for all interfaces and parse it into a usable form
59
  clients_xml = agent.get("#{router_path}/interface_stats.xml").body
60
  doc = Nokogiri::XML(clients_xml.to_s)
61
  doc.xpath('//interface').each do |interface|
62
    children = interface.children
63
    name = children.search('name')[0].text
64 809639ab Lars Kruse
    nics[name]['packets_sent'] = children.search('packets_sent')[0].text
65
    nics[name]['packets_received'] = children.search('packets_received')[0].text
66
    nics[name]['tx_dropped'] = children.search('tx_dropped')[0].text
67 e9c3bcc2 David Reitz
    begin
68 809639ab Lars Kruse
      nics[name]['tx_collisions'] = children.search('tx_collisions')[0].text
69 e9c3bcc2 David Reitz
    rescue Exception
70 809639ab Lars Kruse
      nics[name]['tx_collisions'] = '0'
71 e9c3bcc2 David Reitz
    end
72 809639ab Lars Kruse
    nics[name]['rx_dropped'] = children.search('rx_dropped')[0].text
73
    nics[name]['rx_errors'] = children.search('rx_errors')[0].text
74 e9c3bcc2 David Reitz
  end
75
76
  # get wifi associations and print out info for munin graph
77 809639ab Lars Kruse
  puts 'multigraph clients'
78 e9c3bcc2 David Reitz
  clients_xml = agent.get("#{router_path}/wifi_assoc.xml").body
79
  j = 0
80
  doc = Nokogiri::XML(clients_xml.to_s)
81 809639ab Lars Kruse
  doc.xpath('//assoc').each do |_assoc|
82 b0b39b01 Lars Kruse
    j += 1
83 e9c3bcc2 David Reitz
  end
84 809639ab Lars Kruse
  puts 'wifi_assoc.value ' + j.to_s
85 e9c3bcc2 David Reitz
86
  # get dhcp clients and print out info for munin graph
87
  clients_xml = agent.get("#{router_path}/dhcp_clients.xml").body
88
  j = 0
89
  doc = Nokogiri::XML(clients_xml.to_s)
90 809639ab Lars Kruse
  doc.xpath('//client').each do |_client|
91 b0b39b01 Lars Kruse
    j += 1
92 e9c3bcc2 David Reitz
  end
93 809639ab Lars Kruse
  puts 'dhcp_clients.value ' + j.to_s
94 e9c3bcc2 David Reitz
95 809639ab Lars Kruse
  puts 'multigraph uptime'
96 bd45f70d David Reitz
  # get uptime of connection
97
  clients_xml = agent.get("#{router_path}/wan_connection_status.xml").body
98
  doc = Nokogiri::XML(clients_xml.to_s)
99
  uptime = doc.children.search('wan_interface_up_time_0')[0].text
100 809639ab Lars Kruse
  puts 'uptime.value ' + format('%.2f', (Float(uptime) / 86_400))
101 bd45f70d David Reitz
102 e9c3bcc2 David Reitz
  # graph overall interface packets transferred per interval
103 809639ab Lars Kruse
  puts 'multigraph if_packets'
104
  %w[LAN WAN WLAN].each do |i|
105
    puts "#{i}_recv.value " + nics[i]['packets_received']
106
    puts "#{i}_send.value " + nics[i]['packets_sent']
107 e9c3bcc2 David Reitz
  end
108
109
  # graph overall interface dropped packets per interval
110 809639ab Lars Kruse
  puts 'multigraph if_drop'
111
  %w[LAN WAN WLAN].each do |i|
112
    puts "#{i}_recv.value " + nics[i]['rx_dropped']
113
    puts "#{i}_send.value " + nics[i]['tx_dropped']
114 e9c3bcc2 David Reitz
  end
115
116
  # graph overall interface collisions & errors per interval
117 809639ab Lars Kruse
  puts 'multigraph if_collerr'
118
  %w[LAN WAN WLAN].each do |i|
119
    puts "#{i}_coll.value " + nics[i]['tx_collisions']
120
    puts "#{i}_err.value " + nics[i]['rx_errors']
121 e9c3bcc2 David Reitz
  end
122 17f78427 Lars Kruse
123 e9c3bcc2 David Reitz
  # graph stats for each interface
124 809639ab Lars Kruse
  %w[LAN WAN WLAN].each do |i|
125 e9c3bcc2 David Reitz
    puts "multigraph if_packets.#{i}"
126 809639ab Lars Kruse
    puts 'send.value ' + nics[i]['packets_sent']
127
    puts 'recv.value ' + nics[i]['packets_received']
128 e9c3bcc2 David Reitz
    puts "multigraph if_drop.#{i}"
129 809639ab Lars Kruse
    puts 'send.value ' + nics[i]['tx_dropped']
130
    puts 'recv.value ' + nics[i]['rx_dropped']
131 e9c3bcc2 David Reitz
    puts "multigraph if_collerr.#{i}"
132 809639ab Lars Kruse
    puts 'coll.value ' + nics[i]['tx_collisions']
133
    puts 'err.value ' + nics[i]['rx_errors']
134 e9c3bcc2 David Reitz
  end
135
end
136
137
def config
138
  # build the configuration for graphs
139 809639ab Lars Kruse
  puts 'multigraph if_packets'
140 e9c3bcc2 David Reitz
  puts 'graph_title D-Link DIR-655 interface traffic'
141
  puts 'graph_category network'
142
  puts 'graph_order LAN_recv LAN_send WAN_recv WAN_send WLAN_recv WLAN_send'
143
  puts 'graph_vlabel packets in (-) / out (+) per ${graph_period}'
144 809639ab Lars Kruse
  %w[LAN WAN WLAN].each do |i|
145 bd45f70d David Reitz
    puts "#{i}_recv.type DERIVE"
146 e9c3bcc2 David Reitz
    puts "#{i}_recv.graph no"
147
    puts "#{i}_recv.min 0"
148
    puts "#{i}_send.label #{i}"
149 bd45f70d David Reitz
    puts "#{i}_send.type DERIVE"
150 e9c3bcc2 David Reitz
    puts "#{i}_send.negative #{i}_recv"
151
    puts "#{i}_send.min 0"
152
  end
153
154 809639ab Lars Kruse
  puts 'multigraph if_drop'
155 e9c3bcc2 David Reitz
  puts 'graph_title D-Link DIR-655 interface drops'
156
  puts 'graph_category network'
157
  puts 'graph_order LAN_recv LAN_send WAN_recv WAN_send WLAN_recv WLAN_send'
158
  puts 'graph_vlabel packets / ${graph_period}'
159 809639ab Lars Kruse
  %w[LAN WAN WLAN].each do |i|
160 bd45f70d David Reitz
    puts "#{i}_recv.type DERIVE"
161 e9c3bcc2 David Reitz
    puts "#{i}_recv.graph no"
162
    puts "#{i}_recv.min 0"
163
    puts "#{i}_send.label #{i}"
164 bd45f70d David Reitz
    puts "#{i}_send.type DERIVE"
165 e9c3bcc2 David Reitz
    puts "#{i}_send.negative #{i}_recv"
166
    puts "#{i}_send.min 0"
167
  end
168
169 809639ab Lars Kruse
  puts 'multigraph if_collerr'
170 e9c3bcc2 David Reitz
  puts 'graph_title D-Link DIR-655 interface collisions & errors'
171
  puts 'graph_category network'
172
  puts 'graph_order LAN_coll LAN_err WAN_coll WAN_err WLAN_coll WLAN_coll'
173
  puts 'graph_vlabel packets / ${graph_period}'
174 809639ab Lars Kruse
  %w[LAN WAN WLAN].each do |i|
175 e9c3bcc2 David Reitz
    puts "#{i}_coll.label #{i} collisions"
176 bd45f70d David Reitz
    puts "#{i}_coll.type DERIVE"
177 e9c3bcc2 David Reitz
    puts "#{i}_coll.min 0"
178
    puts "#{i}_err.label #{i} errors"
179 bd45f70d David Reitz
    puts "#{i}_err.type DERIVE"
180 e9c3bcc2 David Reitz
    puts "#{i}_err.min 0"
181
  end
182
183 809639ab Lars Kruse
  puts 'multigraph clients'
184
  puts 'graph_title D-Link DIR-655 client information'
185
  puts 'graph_category system'
186
  puts 'graph_order dhcp_clients wifi_assoc'
187
  puts 'graph_vlabel number of clients'
188
  puts 'dhcp_clients.label DHCP clients'
189
  puts 'dhcp_clients.type GAUGE'
190
  puts 'dhcp_clients.min 0'
191
  puts 'wifi_assoc.label wifi clients'
192
  puts 'wifi_assoc.type GAUGE'
193
  puts 'wifi_assoc.min 0'
194
195
  puts 'multigraph uptime'
196
  puts 'graph_title Uptime'
197 bd45f70d David Reitz
  puts 'graph_vlabel uptime in days'
198
  puts 'graph_category system'
199
  puts 'uptime.label uptime'
200
  puts 'uptime.draw AREA'
201
202 809639ab Lars Kruse
  %w[LAN WAN WLAN].each do |i|
203 e9c3bcc2 David Reitz
    puts "multigraph if_packets.#{i}"
204
    puts "graph_title D-Link DIR-655 #{i} traffic"
205
    puts 'graph_category network'
206
    puts 'graph_order recv send'
207
    puts 'graph_vlabel packets in (-) / out (+) per ${graph_period}'
208
    puts 'recv.label received'
209 bd45f70d David Reitz
    puts 'recv.type DERIVE'
210 e9c3bcc2 David Reitz
    puts 'recv.graph no'
211
    puts 'recv.min 0'
212
    puts 'send.label packets/sec'
213 bd45f70d David Reitz
    puts 'send.type DERIVE'
214 e9c3bcc2 David Reitz
    puts 'send.negative recv'
215
    puts 'send.min 0'
216 17f78427 Lars Kruse
217 e9c3bcc2 David Reitz
    puts "multigraph if_drop.#{i}"
218
    puts "graph_title D-Link DIR-655 #{i} drops"
219
    puts 'graph_category network'
220
    puts 'graph_order recv send'
221
    puts 'graph_vlabel packets / ${graph_period}'
222
    puts 'recv.label RX packets dropped'
223 bd45f70d David Reitz
    puts 'recv.type DERIVE'
224 e9c3bcc2 David Reitz
    puts 'recv.graph no'
225
    puts 'recv.min 0'
226
    puts 'send.label TX packets dropped'
227 bd45f70d David Reitz
    puts 'send.type DERIVE'
228 e9c3bcc2 David Reitz
    puts 'send.negative recv'
229
    puts 'send.min 0'
230 17f78427 Lars Kruse
231 e9c3bcc2 David Reitz
    puts "multigraph if_collerr.#{i}"
232
    puts "graph_title D-Link DIR-655 #{i} collisions & errors"
233
    puts 'graph_category network'
234
    puts 'graph_order coll err'
235
    puts 'graph_vlabel packets / ${graph_period}'
236
    puts 'coll.label collisions'
237 bd45f70d David Reitz
    puts 'coll.type DERIVE'
238 e9c3bcc2 David Reitz
    puts 'coll.min 0'
239
    puts 'err.label errors'
240 bd45f70d David Reitz
    puts 'err.type DERIVE'
241 e9c3bcc2 David Reitz
    puts 'err.min 0'
242
  end
243
end
244
245
# main
246 809639ab Lars Kruse
if (ARGV.length == 1) && (ARGV[0] == 'config')
247
  config
248 e9c3bcc2 David Reitz
else
249 809639ab Lars Kruse
  output
250 e9c3bcc2 David Reitz
end