1netdisco(3) User Contributed Perl Documentation netdisco(3)
2
3
4
6 netdisco.pm - Utility functions used for back and front ends
7
9 This module provides utility functions for use with netdisco in both
10 the front and backend. Front-end specific features are limited to the
11 mason (.html) files, and the back-end specific features are limited to
12 netdisco.
13
15 Max Baker
16
19 %netdisco::DBH
20 Holds Database Handles, key is db name as set in config file.
21
22 %netdisco::DB
23 Index of current Database Handle. Default 'Pg';
24
25 %netdisco::CONFIG
26 Holds config info from "netdisco.conf"
27
28 %netdisco::GRAPH
29 Holds vertex information for "make_graph()"
30
31 $netdisco::SENDMAIL
32 Full path to sendmail executable
33
34 $netdisco::SQLCARP - Carps SQL!
35 This will "carp()" the SQL sent off to the server for Debugging.
36
37 If running under mason, the output of "carp()" goes to the Apache
38 Error Log. From the shell it goes to STDERR.
39
40 Note that if you set this on a MASON page, the value will remain
41 cached across most of the current httpd proccesses. Make sure you
42 set it back to 0 via mason when you're done, unless you like
43 watching Apache's error_log grow.
44
45 %PORT_CONTROL_REASONS
46 Reason why a port would be shutdown. These get fed into
47 "port_control_log"
48
49 $VERSION - Sync'ed with Netdisco releases
50
52 General Functions
53
54 add_arp(mac,ip)
55 Manipulates entries in 'node_ip' table.
56
57 Expires old entries for given IP address.
58
59 Adds new entry or time stamps matching one.
60
61 add_node(mac,ip,port)
62 Manipulates entries in "node" table.
63
64 Expires old entries matching given arguments.
65
66 Adds a new entry or time stamps matching old entry.
67
68 add_nbt(ip,mac,nbname,domain,server,nbuser)
69 Manipulates entries in 'node_nbt' table.
70
71 Expires old entries for given MAC address.
72
73 Adds new entry or time stamps matching one.
74
75 bits_to_mask(bits)
76 Takes a CIDR style network mask in number of bits (/24) and returns
77 the older style bitmask.
78
79 get_community(type,host,ip)
80 Get Community depending on type (ro,rw). If "get_community" is
81 defined, then get the try to get the community from shell-command.
82 If "get_community" is undefined or nothing is returned from the
83 command use "community" or "community_rw".
84
85 The command specified in "get_community" must return in stdout a
86 string like
87
88 community=<list of readonly-communities>
89 setCommunity=<list of write-communities>
90
91 Returns Community-List as Array reference
92
93 Options:
94 type => 'ro'|'rw' for the type of community
95 host => name of the device
96 ip => device ip-address
97
98 config()
99 Reads the config file and fills the %CONFIG hash.
100
101 updateconfig()
102 Checks the modification time of the configuration file and re-reads
103 it if needed. (Note: for now, defaults are not reset - i.e., if
104 there was an item in the config file before, and it is missing when
105 we reread it, it keeps its old value and doesn't get set to the
106 default.)
107
108 Uses eval to run config, so that we can keep running with the old
109 config if there's a problem with the config file.
110
111 has_layer(bit string,layer)
112 Takes ascii encoded string of eight bits, and checks for the
113 specific layer being true. Most significant bit first.
114
115 has_layer(00000100,3) = true
116
117 hostname(ip)
118 Returns the DNS server entry for the given ip or hostname.
119
120 getip(host)
121 Returns the IP Address of a given IP or hostname. If the given
122 argument appears to be in dotted octet notation, it does no DNS
123 hits and just returns it.
124
125 It also just returns an IP address with a subnet mask. Subnet
126 masks are not permitted on host names.
127
128 in_device(device,to_match)
129 First argument can either be:
130
131 1. plain text IP or hostname
132 2. A row from the device table as returned from sql_hash
133
134 Second argument is an array ref as returned from config, eg.
135 "bulkwalk_no".
136
137 in_subnet(subnet,ip)
138 Returns Boolean. Checks to see if IP address is in subnet. Subnet
139 is defined as single IP address, or CIDR block. Partial CIDR
140 format (192.168/16) is NOT supported.
141
142 in_subnet('192.168.0.0/24','192.168.0.3') = 1;
143 in_subnet('192.168.0.3','192.168.0.3') = 1;
144
145 in_subnets(ip,config_directive)
146 Returns Boolean. Checks a given IP address against all the IPs and
147 subnet blocks listed for a config file directive.
148
149 print in_subnets('192.168.0.1','macsuck_no');
150
151 active_subnets()
152 Returns array ref containing all rows from the subnets table that
153 have a node or device in them.
154
155 dump_subnet(cidr style subnet)
156 Serves you all the possible IP addresses in a subnet.
157
158 Returns reference to hash. Keys are IP addresses in dotted decimal
159 that are in the subnet.
160
161 Gateway and Broadcast (.0 .255) addresses are not included.
162
163 $hash_ref = dump_subnet('192.168.0.0/24');
164 scalar keys %$hash_ref == 254;
165
166 Also accepted :
167
168 dump_subnet('14.0/16');
169 dump_subnet('4/24');
170
171 is_mac(mac)
172 Returns Boolean. Checks if argument appears to be a mac address.
173
174 Checks for types :
175
176 08002b:010203
177 08002b-010203
178 0800.2b01.0203
179 08-00-2b-01-02-03
180 08:00:2b:01:02:03
181
182 log(class,text)
183 Inserts an entry in the "log" table.
184
185 log('error',"this is an error");
186
187 mail(to,subject,body)
188 Sends an E-Mail as Netdisco
189
190 is_private(ip)
191 Returns true if a given IP address is in the RFC1918 private
192 address range.
193
194 cidr(ip, mask)
195 Takes an IP address and netmask and returns the CIDR format subnet.
196
197 mask_to_bits(mask)
198 Takes a netmask and returns the CIDR integer number of bits.
199
200 mask_to_bits('255.255.0.0') = 16
201
202 is_secure
203 To be run under mason only.
204
205 Returns true if the server want's to be secure and is, or true if
206 the server doesn't want to be secure.
207
208 Returns false if the server is not secure but wants to be.
209
210 url_secure(url)
211 sort_ip()
212 Used by "sort {}" calls to sort by IP octet.
213
214 If passed two hashes, will sort on the key "ip" or "remote_ip".
215
216 sort_port()
217 Used by "sort()" - Sort port names with the following formatting
218 types :
219
220 A5
221 5
222 FastEthernet0/1
223 FastEthernet0/1-atm
224 5.5
225 Port:3
226
227 Works on hashes if a key named port exists.
228
229 Cheers to Bradley Baetz (bbaetz) for improvements in this sub.
230
231 make_graph()
232 Returns "Graph::Undirected" object that represents the discovered
233 network.
234
235 Graph is made by loading all the "device_port" entries that have a
236 neighbor, using them as edges. Then each device seen in those
237 entries is added as a vertex.
238
239 Nodes without topology information are not included.
240
241 root_device(ip)
242 If the given IP Address matches a device IP, returns it.
243
244 If the given IP Address matches an alias of a device, returns the
245 IP of the device the alias belongs to.
246
247 User Functions
248
249 user_add(user,%args)
250 Adds or changes a user account.
251
252 %args can have key values of { pw, admin, port, ldap, full_name,
253 note }
254
255 Returns error message if problem.
256
257 user_del(user)
258 Deletes a user from netdisco.
259
260 Returns result from "DBI->do()"
261
262 Integer for number of rows deleted, or undef if error.
263
264 user_ldap_verify(user,password)
265 Test a user from netdisco.
266
267 Returns 1 if user and password are OK, or undef if error.
268
269 ldap_search(filter,attrs,user,pass)
270 Perform an LDAP search from the configured ldap_base with the
271 specified filter.
272
273 Uses an anonymous bind if the user is 'anonymous' or undefined.
274
275 Returns reference to an array of Net::LDAP::Entry objects which
276 match the search filter. Each entry will contain the accessible
277 attributes as defined in attrs array reference. If attrs is
278 undefined, then the server will return the attributes that are
279 specified as accessible by default given the bind credentials.
280
281 SQL Functions
282
283 dbh()
284 Creates and returns a database handle. Creates once, then returns
285 the cached copy.
286
287 Select database handle in use by localizing $netdisco::DB
288
289 dbh_quote($text)
290 Runs DBI::dbh->quote() on the text and returns it.
291
292 hash_diff($hashref_orig,$hashref_new)
293 Sees if items to change in second hash are different or new
294 compared to first.
295
296 insert_or_update(table, {matching}, {values} )
297 Checks for Existing entry in table using "\%matching" and either
298 updates or inserts into table with "\%values" accodringly.
299
300 insert_or_update('device', { 'ip'=>'127.0.0.1' },
301 { 'ip' => '127.0.0.1', dns => 'dog' }
302 );
303
304 First time called it will insert the new entry
305
306 Second time called it will modify the entry with the values.
307
308 Supports
309
310 * Auto Quoting of Values
311
312 Returns undef if problem.
313
314 On inserts in PostgreSQL, returns the OID of the row inserted.
315
316 Or returns value from "DBD::St::execute()"
317
318 sql_column(table,[key_col,val_col],{where})
319 Returns reference to hash. Hash has form $hash{key_val}={val_val}
320
321 If multiple matches are found for key_col, only the last one is
322 kept.
323
324 Usage is the same as sql_rows() -- See for Usage.
325
326 $OldDevices = sql_column('device',['ip','layers']);
327
328 Creates the hash %$OldDevices where the key is the IP address and
329 the Value is the Layers
330
331 sql_columns(table,[key_col,val_col,...],{where})
332 Returns reference to hash. Hash has form $hash{key_val}=hash of
333 all columns}
334
335 If multiple matches are found for key_col, only the last one is
336 kept.
337
338 Usage is the same as sql_rows() -- See for Usage.
339
340 $OldDevices = sql_columns('device',['ip','layers','dns']);
341
342 Creates the hash %$OldDevices where the key is the IP address and
343 the Value is a hash with the keys 'ip', 'layers' and 'dns'.
344
345 sql_do(sql)
346 Simple wrapper to "$dbh->do()"
347
348 No quoting.
349
350 sql_begin()
351 Start an SQL transaction.
352
353 Pass an array reference to the list of tables that should be locked
354 in EXCLUSIVE mode for this transaction. Normally, row locking is
355 sufficient, so no tables need be locked. However, netdisco's
356 macsuck and arpnip processes perform statements like
357
358 UPDATE table SET active='f' WHERE (ip|mac)='foo'
359
360 If two such statements are executed concurrently for the same value
361 of 'foo', they can visit the same rows in different order,
362 resulting in a deadlock. It's tempting to say that you can solve
363 this by making the UPDATE only touch one row at a time by adding
364 "AND active" to the WHERE clause; however, it's possible to get
365 multiple rows with active=true and open up the window for deadlock
366 again. Without a significant rewrite, the best option is to lock
367 the appropriate table in exclusive mode (which still allows
368 readers, such as the web front end, but blocks any inserts or
369 updates). Since netdisco performs updates in bulk, the table will
370 not spend a significant amount of time locked.
371
372 sql_commit()
373 Finish an SQL transaction and return to AutoCommit mode
374
375 sql_rollback()
376 If an SQL transaction is in progress, roll it back and return to
377 AutoCommit mode. Suitable to be called in a generic error
378 situation when you don't know what has been done, since it is a
379 noop if there is no transaction occurring.
380
381 sql_disconnect()
382 Disconnect from the SQL database, e.g., before forking.
383
384 sql_hash(table, [columns], {where})
385 Returns reference to hash representing single row.
386
387 Usage is the same as sql_rows() -- See for Usage.
388
389 my $hashref = sql_hash('device',['ip','ports'], {'ip'=>'127.0.0.1'});
390
391 sql_match(text,exact_flag)
392 Parses text to substitue wildcards * and ? for % and _
393
394 Optional exact_flag specifies whether or not to search for that
395 exact text search or to do a *text*.
396
397 Default is non_exact.
398
399 sql_rows(table, [columns] , {where} ,OR, orderbystring)
400 Returns a reference to an array of hash references. Each hash
401 reference is the return of "$dbh->fetchrow_hashref"
402
403 Supports
404
405 * Joins
406 * Pattern Matching
407 * NULL/NOT NULL
408 * Boolean OR or AND criteria
409 * Auto-Quotes all values and Override
410 * IN (list) and NOT IN (list) clauses
411
412 Pass a true value for the OR argument to join constraints in the
413 WHERE clause by OR instead of AND.
414
415 SIMPLE QUERY:
416 Select info for every device:
417
418 $matches = sql_rows('device',['ip','dns','uptime]);
419
420 DISABLE AUTOQUOTING:
421 Pass the where value as a reference:
422
423 sql_rows('device d, device e',['d.ip,d.dns,e.ip,e.dns'],
424 {'d.dns' => \'e.dns'});
425
426 Creates the SQL:
427
428 SELECT d.ip,d.dns,e.ip,e.dns FROM device d, device e WHERE d.dns = e.dns;
429
430 This also leaves a security hole if the where value is coming
431 from the outside world because someone could stuff in
432 'dog';delete from node where true;...> as a value. If you
433 turn off quoting make sure the program is feeding the where
434 value.
435
436 DISABLE AUTOQUOTING AND CONNECTOR
437 Pass the where value as a double scalar reference:
438
439 sql_rows('device',['*'], {'age(creation)' => \\"< interval '1 day'"})
440
441 Creates the sql:
442
443 SELECT * FROM device WHERE age(creation) < interval '1 day';
444
445 NULL VALUES
446 Select all the devices without reverse dns entries:
447
448 $matches = sql_rows('device',['ip','name'],{'dns'=>'IS NULL'});
449
450 JOINS
451 $matches = sql_rows('device d left join device_ip i on d.ip = i.ip',
452 ['distinct(d.ip)','d.dns','i.alias','i.ip'],
453 {'d.ip/i.alias'=>'127.0.0.1', 'd.dns/i.dns' => 'dog%'},
454 1);
455
456 Selects all rows within "device" and "device_ip" where
457 "device_ip.alias" or "device.ip" are "localhost" or
458 "device_ip.dns" or "device.dns" has "dog" in it.
459
460 Where columns with slashes are split into separate search terms
461 combined with "OR":
462
463 { 'd.ip/i.alias' => '127.0.0.1' }
464
465 Creates the SQL
466
467 "WHERE (d.ip = '127.0.0.1' OR i.alias = '127.0.0.1')"
468
469 MULTIPLE CONTSTRAINTS ON SAME COLUMN
470 Pass the where values as an array reference
471
472 $matches = sql_rows('device',['ip'],{'dns' => ['cat%','-g%'] },1 );
473
474 Creates the SQL:
475
476 SELECT ip FROM device WHERE (dns like 'cat%') OR (dns like '-g%');
477
478 IN (list) CLAUSE
479 Pass the value as a double array reference. Values are auto-
480 quoted.
481
482 Single array reference is for creating multiple "WHERE" entries
483 (see above)
484
485 $matches = sql_rows('node',['mac'], {'substr(mac,1,8)' => [['00:00:00','00:00:0c']]})
486
487 Creates the SQL:
488
489 SELECT mac FROM node WHERE (substr(mac,1,8) IN ('00:00:00','00:00:0c'));
490
491 NOT IN (list)
492 Pass the value as a double array reference. Prepend one of the
493 array values with a "!"
494
495 $matches = sql_rows('device',['name'], {'vendor' => [['!cisco','hp']] });
496
497 Will find all devices that are neither cisco or hp.
498
499 ORDER BY CLAUSE
500 $matches = sql_rows('device',['ip','dns'], undef, undef, 'order by dns limit 10');
501
502 sql_query(table, [columns] , {where} ,OR, orderbystring)
503 Returns a DBI state handle on which the SQL query has been
504 prepare()d and execute()d. This function is good for large queries
505 instead of sql_rows(), as the whole result set does not need to be
506 read into memory.
507
508 Code such as
509
510 my $nodes = sql_rows(...);
511 foreach my $row (@$nodes) {
512 ...
513 }
514
515 can be replaced by
516
517 my $sth = sql_query(...);
518 while (my $row = $sth->fetchrow_hashref()) {
519 ...
520 }
521
522 The arguments are exactly the same as sql_rows().
523
524 sql_scalar(table,[column],{where})
525 Returns a scalar of value of first column given.
526
527 Internally calls "sql_hash()" which calls "sql_rows()"
528
529 All arguments are passed directly to "sql_hash()"
530
531 my $count_ip = sql_scalar('device',['COUNT(ip)'],{'name' => 'dog'});
532
533 sql_vacuum(table,%opts)
534 Runs a VACUUM ANALYZE if we are Postgres
535
536 Pass the table name as '' if you want to vacuum all tables.
537
538 Options:
539
540 verbose => 1 (set if DEBUG)
541 full => 1
542
543 homepath(config,[default])
544 Return the full path of the given file as specified in the config
545 file by prepending $CONFIG{home} to it, if it doesn't already start
546 with a slash. If no value is specified in the config file, the
547 default is used.
548
549 tryuse(module,%opts)
550 Try to use the given module.
551
552 Returns two values: success / failure, and the error message if
553 failure. Caches values if it's non fatal.
554
555 Options:
556
557 ver => version of module required
558 die => 1 if you want to die instead of recover yourself
559
560
561
562perl v5.10.0 2009-11-09 netdisco(3)