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 @ 17f78427

Historique | Voir | Annoter | Télécharger (8,82 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

    
35
def output
36
  nics = Hash.new
37
  nics["LAN"] = Hash.new
38
  nics["WAN"] = Hash.new
39
  nics["WLAN"] = Hash.new
40
  password = ENV['router_password'] || ""
41
  router_path = ENV['router_ip_address'] || "10.0.0.1"
42
  router_path = "http://" + router_path
43
  agent = Mechanize.new
44
  x = agent.get(router_path)
45
  salt = x.body.match(/salt = "(.*)"/)[1]
46

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

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

    
55
  # authenticate against the router using the hash that we just built
56
  login_path = "#{router_path}/post_login.xml?hash=#{login_hash}"
57
  x = agent.get(login_path)
58

    
59
  # grab the statistics for all interfaces and parse it into a usable form
60
  clients_xml = agent.get("#{router_path}/interface_stats.xml").body
61
  doc = Nokogiri::XML(clients_xml.to_s)
62
  doc.xpath('//interface').each do |interface|
63
    children = interface.children
64
    name = children.search('name')[0].text
65
    nics[name]["packets_sent"] = children.search('packets_sent')[0].text
66
    nics[name]["packets_received"] = children.search('packets_received')[0].text
67
    nics[name]["tx_dropped"] = children.search('tx_dropped')[0].text
68
    begin
69
      nics[name]["tx_collisions"] = children.search('tx_collisions')[0].text
70
    rescue Exception
71
      nics[name]["tx_collisions"] = "0"
72
    end
73
    nics[name]["rx_dropped"] = children.search('rx_dropped')[0].text
74
    nics[name]["rx_errors"] = children.search('rx_errors')[0].text
75
  end
76

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

    
87
  # get dhcp clients and print out info for munin graph
88
  clients_xml = agent.get("#{router_path}/dhcp_clients.xml").body
89
  j = 0
90
  doc = Nokogiri::XML(clients_xml.to_s)
91
  doc.xpath('//client').each do |client|
92
    j+=1
93
  end
94
  puts "dhcp_clients.value " + j.to_s
95

    
96
  puts "multigraph uptime"
97
  # get uptime of connection
98
  clients_xml = agent.get("#{router_path}/wan_connection_status.xml").body
99
  doc = Nokogiri::XML(clients_xml.to_s)
100
  uptime = doc.children.search('wan_interface_up_time_0')[0].text
101
  puts "uptime.value " + sprintf( "%.2f", (Float(uptime)/86400) )
102

    
103
  # graph overall interface packets transferred per interval
104
  puts "multigraph if_packets"
105
  for i in [ "LAN", "WAN", "WLAN" ] do
106
    puts "#{i}_recv.value " + nics[i]["packets_received"]
107
    puts "#{i}_send.value " + nics[i]["packets_sent"]
108
  end
109

    
110
  # graph overall interface dropped packets per interval
111
  puts "multigraph if_drop"
112
  for i in [ "LAN", "WAN", "WLAN" ] do
113
    puts "#{i}_recv.value " + nics[i]["rx_dropped"]
114
    puts "#{i}_send.value " + nics[i]["tx_dropped"]
115
  end
116

    
117
  # graph overall interface collisions & errors per interval
118
  puts "multigraph if_collerr"
119
  for i in [ "LAN", "WAN", "WLAN" ] do
120
    puts "#{i}_coll.value " + nics[i]["tx_collisions"]
121
    puts "#{i}_err.value " + nics[i]["rx_errors"]
122
  end
123

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

    
138

    
139
def config
140
  # build the configuration for graphs
141
  puts "multigraph if_packets"
142
  puts 'graph_title D-Link DIR-655 interface traffic'
143
  puts 'graph_category network'
144
  puts 'graph_order LAN_recv LAN_send WAN_recv WAN_send WLAN_recv WLAN_send'
145
  puts 'graph_vlabel packets in (-) / out (+) per ${graph_period}'
146
  for i in [ "LAN", "WAN", "WLAN" ] do
147
    puts "#{i}_recv.type DERIVE"
148
    puts "#{i}_recv.graph no"
149
    puts "#{i}_recv.min 0"
150
    puts "#{i}_send.label #{i}"
151
    puts "#{i}_send.type DERIVE"
152
    puts "#{i}_send.negative #{i}_recv"
153
    puts "#{i}_send.min 0"
154
  end
155

    
156
  puts "multigraph if_drop"
157
  puts 'graph_title D-Link DIR-655 interface drops'
158
  puts 'graph_category network'
159
  puts 'graph_order LAN_recv LAN_send WAN_recv WAN_send WLAN_recv WLAN_send'
160
  puts 'graph_vlabel packets / ${graph_period}'
161
  for i in [ "LAN", "WAN", "WLAN" ] do
162
    puts "#{i}_recv.type DERIVE"
163
    puts "#{i}_recv.graph no"
164
    puts "#{i}_recv.min 0"
165
    puts "#{i}_send.label #{i}"
166
    puts "#{i}_send.type DERIVE"
167
    puts "#{i}_send.negative #{i}_recv"
168
    puts "#{i}_send.min 0"
169
  end
170

    
171
  puts "multigraph if_collerr"
172
  puts 'graph_title D-Link DIR-655 interface collisions & errors'
173
  puts 'graph_category network'
174
  puts 'graph_order LAN_coll LAN_err WAN_coll WAN_err WLAN_coll WLAN_coll'
175
  puts 'graph_vlabel packets / ${graph_period}'
176
  for i in [ "LAN", "WAN", "WLAN" ] do
177
    puts "#{i}_coll.label #{i} collisions"
178
    puts "#{i}_coll.type DERIVE"
179
    puts "#{i}_coll.min 0"
180
    puts "#{i}_err.label #{i} errors"
181
    puts "#{i}_err.type DERIVE"
182
    puts "#{i}_err.min 0"
183
  end
184

    
185
  puts "multigraph clients"
186
  puts "graph_title D-Link DIR-655 client information"
187
  puts "graph_category system"
188
  puts "graph_order dhcp_clients wifi_assoc"
189
  puts "graph_vlabel number of clients"
190
  puts "dhcp_clients.label DHCP clients"
191
  puts "dhcp_clients.type GAUGE"
192
  puts "dhcp_clients.min 0"
193
  puts "wifi_assoc.label wifi clients"
194
  puts "wifi_assoc.type GAUGE"
195
  puts "wifi_assoc.min 0"
196

    
197
  puts "multigraph uptime"
198
  puts "graph_title Uptime"
199
  puts 'graph_vlabel uptime in days'
200
  puts 'graph_category system'
201
  puts 'uptime.label uptime'
202
  puts 'uptime.draw AREA'
203

    
204
  for i in [ "LAN", "WAN", "WLAN" ] do
205
    puts "multigraph if_packets.#{i}"
206
    puts "graph_title D-Link DIR-655 #{i} traffic"
207
    puts 'graph_category network'
208
    puts 'graph_order recv send'
209
    puts 'graph_vlabel packets in (-) / out (+) per ${graph_period}'
210
    puts 'recv.label received'
211
    puts 'recv.type DERIVE'
212
    puts 'recv.graph no'
213
    puts 'recv.min 0'
214
    puts 'send.label packets/sec'
215
    puts 'send.type DERIVE'
216
    puts 'send.negative recv'
217
    puts 'send.min 0'
218

    
219
    puts "multigraph if_drop.#{i}"
220
    puts "graph_title D-Link DIR-655 #{i} drops"
221
    puts 'graph_category network'
222
    puts 'graph_order recv send'
223
    puts 'graph_vlabel packets / ${graph_period}'
224
    puts 'recv.label RX packets dropped'
225
    puts 'recv.type DERIVE'
226
    puts 'recv.graph no'
227
    puts 'recv.min 0'
228
    puts 'send.label TX packets dropped'
229
    puts 'send.type DERIVE'
230
    puts 'send.negative recv'
231
    puts 'send.min 0'
232

    
233
    puts "multigraph if_collerr.#{i}"
234
    puts "graph_title D-Link DIR-655 #{i} collisions & errors"
235
    puts 'graph_category network'
236
    puts 'graph_order coll err'
237
    puts 'graph_vlabel packets / ${graph_period}'
238
    puts 'coll.label collisions'
239
    puts 'coll.type DERIVE'
240
    puts 'coll.min 0'
241
    puts 'err.label errors'
242
    puts 'err.type DERIVE'
243
    puts 'err.min 0'
244
  end
245
end
246

    
247

    
248
# main
249
if ARGV.length == 1 and ARGV[0] == 'config'
250
  config()
251
else
252
  output()
253
end