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 @ 1671e356

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

1
#!/usr/bin/env ruby
2
#
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
  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
  agent = Mechanize.new
43
  x = agent.get(router_path)
44
  salt = x.body.match(/salt = "(.*)"/)[1]
45

    
46
  # pad the password to length 16
47
  pad_size = (16 - password.length)
48
  padded_password = password + "\x01" * pad_size
49

    
50
  # pad it the rest of the way, length 64 for user
51
  salted_password = salt + padded_password + ("\x01" * (63 - salt.length - padded_password.length)) + 'U'
52
  login_hash = salt + Digest::MD5.hexdigest(salted_password)
53

    
54
  # 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
    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
    begin
68
      nics[name]['tx_collisions'] = children.search('tx_collisions')[0].text
69
    rescue Exception
70
      nics[name]['tx_collisions'] = '0'
71
    end
72
    nics[name]['rx_dropped'] = children.search('rx_dropped')[0].text
73
    nics[name]['rx_errors'] = children.search('rx_errors')[0].text
74
  end
75

    
76
  # get wifi associations and print out info for munin graph
77
  puts 'multigraph clients'
78
  clients_xml = agent.get("#{router_path}/wifi_assoc.xml").body
79
  j = 0
80
  doc = Nokogiri::XML(clients_xml.to_s)
81
  doc.xpath('//assoc').each do |_assoc|
82
    j += 1
83
  end
84
  puts 'wifi_assoc.value ' + j.to_s
85

    
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
  doc.xpath('//client').each do |_client|
91
    j += 1
92
  end
93
  puts 'dhcp_clients.value ' + j.to_s
94

    
95
  puts 'multigraph uptime'
96
  # 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
  puts 'uptime.value ' + format('%.2f', (Float(uptime) / 86_400))
101

    
102
  # graph overall interface packets transferred per interval
103
  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
  end
108

    
109
  # graph overall interface dropped packets per interval
110
  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
  end
115

    
116
  # graph overall interface collisions & errors per interval
117
  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
  end
122

    
123
  # graph stats for each interface
124
  %w[LAN WAN WLAN].each do |i|
125
    puts "multigraph if_packets.#{i}"
126
    puts 'send.value ' + nics[i]['packets_sent']
127
    puts 'recv.value ' + nics[i]['packets_received']
128
    puts "multigraph if_drop.#{i}"
129
    puts 'send.value ' + nics[i]['tx_dropped']
130
    puts 'recv.value ' + nics[i]['rx_dropped']
131
    puts "multigraph if_collerr.#{i}"
132
    puts 'coll.value ' + nics[i]['tx_collisions']
133
    puts 'err.value ' + nics[i]['rx_errors']
134
  end
135
end
136

    
137
def config
138
  # build the configuration for graphs
139
  puts 'multigraph if_packets'
140
  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
  %w[LAN WAN WLAN].each do |i|
145
    puts "#{i}_recv.type DERIVE"
146
    puts "#{i}_recv.graph no"
147
    puts "#{i}_recv.min 0"
148
    puts "#{i}_send.label #{i}"
149
    puts "#{i}_send.type DERIVE"
150
    puts "#{i}_send.negative #{i}_recv"
151
    puts "#{i}_send.min 0"
152
  end
153

    
154
  puts 'multigraph if_drop'
155
  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
  %w[LAN WAN WLAN].each do |i|
160
    puts "#{i}_recv.type DERIVE"
161
    puts "#{i}_recv.graph no"
162
    puts "#{i}_recv.min 0"
163
    puts "#{i}_send.label #{i}"
164
    puts "#{i}_send.type DERIVE"
165
    puts "#{i}_send.negative #{i}_recv"
166
    puts "#{i}_send.min 0"
167
  end
168

    
169
  puts 'multigraph if_collerr'
170
  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
  %w[LAN WAN WLAN].each do |i|
175
    puts "#{i}_coll.label #{i} collisions"
176
    puts "#{i}_coll.type DERIVE"
177
    puts "#{i}_coll.min 0"
178
    puts "#{i}_err.label #{i} errors"
179
    puts "#{i}_err.type DERIVE"
180
    puts "#{i}_err.min 0"
181
  end
182

    
183
  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
  puts 'graph_vlabel uptime in days'
198
  puts 'graph_category system'
199
  puts 'uptime.label uptime'
200
  puts 'uptime.draw AREA'
201

    
202
  %w[LAN WAN WLAN].each do |i|
203
    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
    puts 'recv.type DERIVE'
210
    puts 'recv.graph no'
211
    puts 'recv.min 0'
212
    puts 'send.label packets/sec'
213
    puts 'send.type DERIVE'
214
    puts 'send.negative recv'
215
    puts 'send.min 0'
216

    
217
    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
    puts 'recv.type DERIVE'
224
    puts 'recv.graph no'
225
    puts 'recv.min 0'
226
    puts 'send.label TX packets dropped'
227
    puts 'send.type DERIVE'
228
    puts 'send.negative recv'
229
    puts 'send.min 0'
230

    
231
    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
    puts 'coll.type DERIVE'
238
    puts 'coll.min 0'
239
    puts 'err.label errors'
240
    puts 'err.type DERIVE'
241
    puts 'err.min 0'
242
  end
243
end
244

    
245
# main
246
if (ARGV.length == 1) && (ARGV[0] == 'config')
247
  config
248
else
249
  output
250
end