source: trunk/klask @ 23

Last change on this file since 23 was 23, checked in by g7moreau, 16 years ago
  • Update list debian package need by klask
  • Property svn:executable set to *
File size: 41.3 KB
Line 
1#!/usr/bin/perl -w
2
3use strict;
4use warnings;
5
6use Net::SNMP;
7use YAML qw(:all);
8use Net::Netmask;
9use Net::CIDR::Lite;
10use NetAddr::IP;
11use Getopt::Long;
12
13# apt-get install snmp fping libnet-cidr-lite-perl libnet-netmask-perl libnet-snmp-perl libnetaddr-ip-perl libyaml-perl
14# libcrypt-des-perl libcrypt-hcesha-perl libdigest-hmac-perl
15# arping fping bind9-host arpwatch
16
17my $KLASK_DB_FILE  = '/var/cache/klask/klaskdb';
18my $KLASK_SW_FILE  = '/var/cache/klask/switchdb';
19my $KLASK_CFG_FILE = '/etc/klask.conf';
20
21my $KLASK_CFG = YAML::LoadFile("$KLASK_CFG_FILE");
22
23my %DEFAULT = %{$KLASK_CFG->{default}};
24my @SWITCH  = @{$KLASK_CFG->{switch}};
25
26my %switch_level = ();
27LEVEL_OF_EACH_SWITCH:
28for my $sw (@SWITCH){
29   $switch_level{$sw->{hostname}} = $sw->{level} || $DEFAULT{switch_level}  || 2;
30   }
31@SWITCH = sort { $switch_level{$b->{hostname}} <=> $switch_level{$a->{hostname}} } @{$KLASK_CFG->{switch}}; 
32
33my %SWITCH_PORT_COUNT = ();
34
35my %CMD_DB = (
36   help       => \&cmd_help,
37   exportdb   => \&cmd_exportdb,
38   updatedb   => \&cmd_updatedb,
39   searchdb   => \&cmd_searchdb,
40   removedb   => \&cmd_removedb,
41   search     => \&cmd_search,
42   enable     => \&cmd_enable,
43   disable    => \&cmd_disable,
44   status     => \&cmd_status,
45   updatesw   => \&cmd_updatesw,
46   exportsw   => \&cmd_exportsw,
47   dotsw      => \&cmd_exportsw_dot,
48   iplocation => \&cmd_iplocation,
49   );
50
51my %INTERNAL_PORT_MAP = (
52   0 => 'A',
53   1 => 'B',
54   2 => 'C',
55   3 => 'D',
56   4 => 'E',
57   5 => 'F',
58   6 => 'G',
59   7 => 'H',
60   );
61my %INTERNAL_PORT_MAP_REV = reverse %INTERNAL_PORT_MAP;
62
63my %SWITCH_KIND = (
64   J3299A => { model => 'HP224M',     match => 'HP J3299A ProCurve Switch 224M'  },
65   J4120A => { model => 'HP1600M',    match => 'HP J4120A ProCurve Switch 1600M' },
66   J4093A => { model => 'HP2424M',    match => 'HP J4093A ProCurve Switch 2424M' },
67   J4813A => { model => 'HP2524',     match => 'HP J4813A ProCurve Switch 2524'  },
68   J4900A => { model => 'HP2626A',    match => 'HP J4900A ProCurve Switch 2626'  },
69   J4900B => { model => 'HP2626B',    match => 'HP J4900B ProCurve Switch 2626'  },
70   J9021A => { model => 'HP2810-24G', match => 'ProCurve J9021A Switch 2810-24G' },
71   J4903A => { model => 'HP2824',     match => 'J4903A.+?Switch 2824,'           },
72   J4110A => { model => 'HP8000M',    match => 'HP J4110A ProCurve Switch 8000M' },
73   BS350T => { model => 'BS350T',     match => 'BayStack 350T HW'                },
74   );
75 
76my %OID_NUMBER = (
77   sysDescr    => '1.3.6.1.2.1.1.1.0',
78   sysName     => '1.3.6.1.2.1.1.5.0',
79   sysContact  => '1.3.6.1.2.1.1.4.0',
80   sysLocation => '1.3.6.1.2.1.1.6.0',
81   );
82
83################
84# principal
85################
86
87my $cmd = shift @ARGV || 'help';
88if (defined $CMD_DB{$cmd}) {
89   $CMD_DB{$cmd}->(@ARGV);
90   }
91else {
92   print STDERR "klask: command $cmd not found\n\n";
93   $CMD_DB{help}->();
94   exit 1;
95   }
96
97exit;
98
99###
100# fast ping dont l'objectif est de remplir la table arp de la machine
101sub fastping {
102   system "fping -c 1 @_ >/dev/null 2>&1";
103   }
104
105###
106# donne l'@ ip, dns, arp en fonction du dns OU de l'ip
107sub resolve_ip_arp_host {
108   my $param_ip_or_host = shift;
109   my $interface = shift || '*';
110   my $type      = shift || 'fast';
111
112   my %ret = (
113      hostname_fq  => 'unknow',
114      ipv4_address => '0.0.0.0',
115      mac_address  => 'unknow',
116      );
117
118#   my $cmdarping  = `arping -c 1 -w 1 -rR $param 2>/dev/null`;
119
120   # controler que arpwatch tourne !
121   # resultat de la commande arpwatch
122   # /var/lib/arpwatch/arp.dat
123   # 0:13:d3:e1:92:d0        192.168.24.109  1163681980      theo8sv109
124   #my $cmd = "grep  -e '".'\b'."$param_ip_or_host".'\b'."' /var/lib/arpwatch/arp.dat | sort +2rn | head -1";
125#   my $cmd = "grep  -he '".'\b'."$param_ip_or_host".'\b'."' /var/lib/arpwatch/*.dat | sort +2rn | head -1";
126   my $cmd = "grep  -he '".'\b'."$param_ip_or_host".'\b'."' /var/lib/arpwatch/$interface.dat | sort +2rn | head -1";
127   my $cmd_arpwatch = `$cmd`;
128   chomp $cmd_arpwatch;
129   my ($arp, $ip, $timestamp, $host) = split /\s+/, $cmd_arpwatch;
130#print "OOO $cmd\n";
131#print "TTT arp $arp -> $ip pour host $host\n";
132   $ret{ipv4_address} = $ip        if $ip;
133   $ret{mac_address}  = $arp       if $arp;
134   $ret{timestamp}    = $timestamp if $timestamp;
135
136   my $nowtimestamp = time();
137
138   if ( $type eq 'fast' and ( not defined $timestamp or $timestamp < ( $nowtimestamp - 3 * 3600 ) ) ) {
139      $ret{mac_address} = 'unknow';
140      return %ret;
141      }
142
143  # resultat de la commande arp
144   # tech7meylan.hmg.inpg.fr (194.254.66.240) at 00:14:22:45:28:A9 [ether] on eth0
145   my $cmd_arp  = `arp -a $param_ip_or_host 2>/dev/null`;
146   chomp $cmd_arp;
147   $cmd_arp =~ /(\S*)\s\(([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})\)\sat\s([0-9,A-Z]{2}:[0-9,A-Z]{2}:[0-9,A-Z]{2}:[0-9,A-Z]{2}:[0-9,A-Z]{2}:[0-9,A-Z]{2})/;
148   $ret{hostname_fq}  = $1 if(defined($1));
149   $ret{ipv4_address} = $2 if(defined($2));
150   $ret{mac_address}  = $3 if(defined($3));
151
152#   if ($ret{ipv4_address} eq '0.0.0.0' and $ret{mac_address} eq 'unknow'and $ret{hostname_fq} eq 'unknow') {
153      # resultat de la commande host si le parametre est ip
154      # 250.66.254.194.in-addr.arpa domain name pointer legihp2100.hmg.inpg.fr.
155      my $cmd_host = `host $param_ip_or_host 2>/dev/null`;
156      chomp $cmd_host;
157      $cmd_host =~ m/domain\sname\spointer\s(\S+)\.$/;
158      $ret{hostname_fq} = $1 if defined $1;
159
160      # resultat de la commande host si parametre est hostname
161      # tech7meylan.hmg.inpg.fr has address 194.254.66.240
162      $cmd_host =~ m/\shas\saddress\s([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})$/;
163      $ret{ipv4_address} = $1 if defined $1;
164
165      $cmd_host =~ m/\b([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.in-addr\.arpa\s/;
166      $ret{ipv4_address} = "$4.$3.$2.$1"     if defined $1 and  defined $2 and  defined $3 and  defined $4;
167      $ret{hostname_fq}  = $param_ip_or_host if not defined $1 and $ret{hostname_fq} eq 'unknow';
168#      }
169
170   unless ($ret{mac_address} eq 'unknow') {
171      my @paquets = ();
172      foreach ( split(/:/, $ret{mac_address}) ) {
173         my @chars = split //, uc("00$_");
174         push @paquets, "$chars[-2]$chars[-1]";
175         }
176      $ret{mac_address} = join ':', @paquets;
177      }
178
179   return %ret;
180   }
181
182# Find Surname of a switch
183sub get_switch_model {
184   my $sw_snmp_description = shift || 'unknow';
185   
186   for my $sw_kind (keys %SWITCH_KIND) {
187      next if not $sw_snmp_description =~ m/$SWITCH_KIND{$sw_kind}->{match}/;
188     
189      return $SWITCH_KIND{$sw_kind}->{model};
190      }
191     
192   return $sw_snmp_description;
193   }
194
195###
196# va rechercher le nom des switchs pour savoir qui est qui
197sub init_switch_names {
198   my $verbose = shift;
199   
200   printf "%-25s                %-25s %s\n",'Switch','Description','Type';
201#   print "Switch description\n" if $verbose;
202   print "-------------------------------------------------------------------------\n" if $verbose;
203
204   INIT_EACH_SWITCH:
205   for my $sw (@SWITCH) {
206      my %session = ( -hostname   => $sw->{hostname} );
207         $session{-version} = $sw->{version}   || 1;
208         $session{-port}    = $sw->{snmpport}  || $DEFAULT{snmpport}  || 161;
209         if (exists $sw->{version} and $sw->{version} eq 3) {
210            $session{-username} = $sw->{username} || 'snmpadmin';
211            }
212         else {
213            $session{-community} = $sw->{community} || $DEFAULT{community} || 'public';
214            }
215
216      $sw->{local_session} = \%session;
217
218      my ($session, $error) = Net::SNMP->session( %{$sw->{local_session}} );
219      print "$error \n" if $error;
220
221      my $result = $session->get_request(
222         -varbindlist => [
223            $OID_NUMBER{sysDescr},
224            $OID_NUMBER{sysName},
225            $OID_NUMBER{sysContact},
226            $OID_NUMBER{sysLocation},
227            ]
228         );
229      $sw->{description} = $result->{$OID_NUMBER{sysName}} || $sw->{hostname};
230      $sw->{model} = get_switch_model( $result->{$OID_NUMBER{sysDescr}});
231      #$sw->{location} = $result->{"1.3.6.1.2.1.1.6.0"} || $sw->{hostname};
232      #$sw->{contact} = $result->{"1.3.6.1.2.1.1.4.0"} || $sw->{hostname};
233      $session->close;
234
235      # Ligne à virer car on récupère maintenant le modèle du switch
236      my ($desc, $type) = split ':', $sw->{description}, 2;
237#      printf "%-25s 0--------->>>> %-25s %s\n", $sw->{hostname}, $desc, uc($type)."**" if $verbose;
238      printf "%-25s 0--------->>>> %-25s %s\n", $sw->{hostname}, $desc, $sw->{model} if $verbose;
239      }
240
241   print "\n" if $verbose;
242   }
243
244###
245# convertit l'hexa (uniquement 2 chiffres) en decimal
246sub hex_to_dec {
247   #00:0F:1F:43:E4:2B
248   my $car = '00' . uc(shift);
249
250   return '00' if $car eq '00UNKNOW';
251   my %table = (
252      "0"=>"0",  "1"=>"1",  "2"=>"2",  "3"=>"3",  "4"=>"4",  "5"=>"5", "6"=>"6", "7"=>"7", "8"=>"8", "9"=>"9",
253      "A"=>"10", "B"=>"11", "C"=>"12", "D"=>"13", "E"=>"14", "F"=>"15"
254      );
255   my @chars = split(//, $car);
256   return $table{$chars[-2]}*16 + $table{$chars[-1]};
257   }
258
259###
260# convertit l'@ arp en decimal
261sub arp_hex_to_dec {
262   #00:0F:1F:43:E4:2B
263   my $arp = shift;
264
265   my @paquets = split /:/, $arp;
266   my $return = '';
267   foreach(@paquets) {
268      $return .= ".".hex_to_dec($_);
269      }
270   return $return;
271   }
272
273###
274# va rechercher le port et le switch sur lequel est la machine
275sub find_switch_port {
276   my $arp = shift;
277   my $switch_proposal = shift || '';
278   
279   my %ret;
280   $ret{switch_description} = "unknow";
281   $ret{switch_port} = "0";
282
283   return %ret if $arp eq 'unknow';;
284
285   my @switch_search = @SWITCH;
286   if ($switch_proposal ne '') {
287      for my $sw (@SWITCH) {
288         next if $sw->{hostname} ne $switch_proposal;
289         unshift @switch_search, $sw;
290         last;
291         }
292      }
293
294   my $research = "1.3.6.1.2.1.17.4.3.1.2".arp_hex_to_dec($arp);
295   
296   LOOP_ON_SWITCH:
297   for my $sw (@switch_search) {
298      my ($session, $error) = Net::SNMP->session( %{$sw->{local_session}} );
299      print "$error \n" if $error;
300
301      my $result = $session->get_request(
302         -varbindlist => [$research]
303         );
304      if (not defined($result) or $result->{$research} eq 'noSuchInstance') {
305         $session->close;
306         next LOOP_ON_SWITCH;
307         }
308
309         my $swport = $result->{$research};
310         $session->close;
311
312         # IMPORTANT !!
313         # ceci empeche la detection sur certains port ...
314         # en effet les switch sont relies entre eux par un cable reseau et du coup
315         # tous les arp de toutes les machines sont presentes sur ces ports (ceux choisis ici sont les miens)
316         # cette partie est a ameliore, voir a configurer dans l'entete
317         # 21->24 45->48
318#         my $flag = 0;
319         SWITCH_PORT_IGNORE:
320         foreach my $p (@{$sw->{portignore}}) {
321            next SWITCH_PORT_IGNORE if $swport ne get_numerical_port($sw->{model},$p);
322#            $flag = 1;
323            next LOOP_ON_SWITCH;
324            }
325#         if ($flag == 0) {
326            $ret{switch_hostname}    = $sw->{hostname};
327            $ret{switch_description} = $sw->{description};
328            $ret{switch_port}        = get_human_readable_port($sw->{model}, $swport); # $swport;
329           
330            last LOOP_ON_SWITCH;
331#            }
332#         }
333#      $session->close;
334      }
335   return %ret;
336   }
337
338###
339# va rechercher les port et les switch sur lequel est la machine
340sub find_all_switch_port {
341   my $arp = shift;
342
343   my $ret = {};
344
345   return $ret if $arp eq 'unknow';
346
347   for my $sw (@SWITCH) {
348      $SWITCH_PORT_COUNT{$sw->{hostname}} = {} if not exists $SWITCH_PORT_COUNT{$sw->{hostname}};
349      }
350
351   my $research = "1.3.6.1.2.1.17.4.3.1.2".arp_hex_to_dec($arp);
352   LOOP_ON_ALL_SWITCH:
353   for my $sw (@SWITCH) {
354      my ($session, $error) = Net::SNMP->session( %{$sw->{local_session}} );
355      print "$error \n" if $error;
356
357      my $result = $session->get_request(
358         -varbindlist => [$research]
359         );
360
361      if(defined($result) and $result->{$research} ne 'noSuchInstance'){
362         my $swport = $result->{$research};
363
364         $ret->{$sw->{hostname}} = {};
365         $ret->{$sw->{hostname}}{hostname}    = $sw->{hostname};
366         $ret->{$sw->{hostname}}{description} = $sw->{description};
367         $ret->{$sw->{hostname}}{port}        = get_human_readable_port($sw->{model}, $swport);
368
369         $SWITCH_PORT_COUNT{$sw->{hostname}}->{$swport}++;
370         }
371
372      $session->close;
373      }
374   return $ret;
375   }
376
377sub get_list_network {
378
379   return keys %{$KLASK_CFG->{network}};
380   }
381
382sub get_current_interface {
383   my $network = shift;
384
385   return $KLASK_CFG->{network}{$network}{interface};
386   }
387 
388###
389# liste l'ensemble des adresses ip d'un réseau
390sub get_list_ip {
391   my @network = @_;
392
393   my $cidrlist = Net::CIDR::Lite->new;
394
395   for my $net (@network) {
396      my @line  = @{$KLASK_CFG->{network}{$net}{'ip-subnet'}};
397      for my $cmd (@line) {
398         for my $method (keys %$cmd){
399            $cidrlist->add_any($cmd->{$method}) if $method eq 'add';
400            }
401         }
402      }
403
404   my @res = ();
405
406   for my $cidr ($cidrlist->list()) {
407      my $net = new NetAddr::IP $cidr;
408      for my $ip (@$net) {
409         $ip =~ s#/32##;
410         push @res,  $ip;
411         }
412      }
413
414   return @res;
415   }
416
417# liste l'ensemble des routeurs du réseau
418sub get_list_main_router {
419   my @network = @_;
420
421   my @res = ();
422
423   for my $net (@network) {
424      push @res, $KLASK_CFG->{network}{$net}{'main-router'};
425      }
426
427   return @res;
428   }
429
430sub get_human_readable_port {
431   my $sw_model = shift;
432   my $sw_port  = shift;
433   
434   return $sw_port if not $sw_model eq 'HP8000M';
435   
436   my $reste = (($sw_port - 1) % 8) + 1;
437   my $major = int( ($sw_port - 1) / 8 );
438
439   return "$INTERNAL_PORT_MAP{$major}$reste";
440   }
441
442sub get_numerical_port {
443   my $sw_model = shift;
444   my $sw_port  = shift;
445   
446   return $sw_port if not $sw_model eq 'HP8000';
447
448   my $letter = substr($sw_port, 0, 1);
449   
450#   return $port if $letter =~ m/\d/;
451   
452   my $reste =  substr($sw_port, 1);
453   
454   return $INTERNAL_PORT_MAP_REV{$letter} * 8 + $reste;
455   }
456
457################
458# Les commandes
459################
460
461sub cmd_help {
462
463print <<END;
464klask - ports manager and finder for switch
465
466 klask updatedb
467 klask exportdf
468
469 klask searchdb computer
470 klask search   computer
471
472 klask enable  switch port
473 klask disable switch port
474 klask status  switch port
475END
476   }
477
478sub cmd_search {
479   my @computer = @_;
480   
481   init_switch_names();    #nomme les switchs
482   fastping(@computer);
483   for my $clientname (@computer) {
484      my %resol_arp = resolve_ip_arp_host($clientname);          #resolution arp
485      my %where     = find_switch_port($resol_arp{mac_address}); #retrouve l'emplacement
486      printf "%-22s %2i %-30s %-15s %18s", $where{switch_description}, $where{switch_port}, $resol_arp{hostname_fq}, $resol_arp{ipv4_address}, $resol_arp{mac_address}."\n"
487         unless $where{switch_description} eq 'unknow' and $resol_arp{hostname_fq} eq 'unknow' and $resol_arp{mac_address} eq 'unknow';
488      }
489   }
490
491sub cmd_searchdb {
492   my @computer = @_;
493
494   fastping(@computer);
495   my $computerdb = YAML::LoadFile("$KLASK_DB_FILE");
496   
497   LOOP_ON_COMPUTER:
498   for my $clientname (@computer) {
499      my %resol_arp = resolve_ip_arp_host($clientname);      #resolution arp
500      my $ip = $resol_arp{ipv4_address};
501     
502      next LOOP_ON_COMPUTER unless exists $computerdb->{$ip};
503     
504      my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($computerdb->{$ip}{timestamp});
505      $year += 1900;
506      $mon++;
507      my $date = sprintf "%04i-%02i-%02i %02i:%02i", $year,$mon,$mday,$hour,$min;
508
509      printf "%-22s %2s %-30s %-15s %-18s %s\n",
510         $computerdb->{$ip}{switch_name},
511         $computerdb->{$ip}{switch_port},
512         $computerdb->{$ip}{hostname_fq},
513         $ip,
514         $computerdb->{$ip}{mac_address},
515         $date;
516      }
517   }
518
519sub cmd_updatedb {
520   my @network = @_;
521      @network = get_list_network() if not @network;
522
523   my $computerdb = YAML::LoadFile("$KLASK_DB_FILE");
524   my $timestamp = time;
525
526   my %computer_not_detected = ();
527   my $timestamp_last_week = $timestamp - (3600 * 24 * 7);
528
529   my $number_of_computer = get_list_ip(@network); # + 1;
530   my $size_of_database   = keys %$computerdb;
531   my $i = 0;
532   my $detected_computer = 0;
533
534   init_switch_names('yes');    #nomme les switchs
535
536   { # Remplis le champs portignore des ports d'inter-connection pour chaque switch
537   my $switch_connection = YAML::LoadFile("$KLASK_SW_FILE");
538   my %db_switch_output_port       = %{$switch_connection->{output_port}};
539   my %db_switch_connected_on_port = %{$switch_connection->{connected_on_port}};
540   my %db_switch_chained_port = ();
541   for my $swport (keys %db_switch_connected_on_port) {       
542      my ($sw_connect,$port_connect) = split ':', $swport;
543      $db_switch_chained_port{$sw_connect} .= "$port_connect:";
544      }
545   for my $sw (@SWITCH){
546      push @{$sw->{portignore}}, $db_switch_output_port{$sw->{hostname}}  if exists $db_switch_output_port{$sw->{hostname}};
547      if ( exists $db_switch_chained_port{$sw->{hostname}} ) {
548         chop $db_switch_chained_port{$sw->{hostname}};
549         push @{$sw->{portignore}}, split(':',$db_switch_chained_port{$sw->{hostname}});
550         }
551#      print "$sw->{hostname} ++ @{$sw->{portignore}}\n";
552      }
553   }
554
555   my %router_mac_ip = ();
556   DETECT_ALL_ROUTER:
557#   for my $one_router ('194.254.66.254') {
558   for my $one_router ( get_list_main_router(@network) ) {
559      my %resol_arp = resolve_ip_arp_host($one_router);
560      $router_mac_ip{ $resol_arp{mac_address} } = $resol_arp{ipv4_address};
561      }
562
563   ALL_NETWORK:
564   for my $net (@network) {
565
566      my @computer = get_list_ip($net);
567      my $current_interface = get_current_interface($net);
568
569      fastping(@computer);
570
571      LOOP_ON_COMPUTER:
572      for my $one_computer (@computer) {
573         $i++;
574         
575         my $total_percent = int(($i*100)/$number_of_computer);
576
577         my $localtime = time - $timestamp;
578         my ($sec,$min) = localtime($localtime);
579
580         my $time_elapse = 0;
581            $time_elapse = $localtime * ( 100 - $total_percent) / $total_percent if $total_percent != 0;
582         my ($sec_elapse,$min_elapse) = localtime($time_elapse);
583
584         printf "\rComputer scanned: %4i/%i (%2i%%)",  $i,                 $number_of_computer, $total_percent;
585#         printf ", Computer detected: %4i/%i (%2i%%)", $detected_computer, $size_of_database,   int(($detected_computer*100)/$size_of_database);
586         printf ", detected: %4i/%i (%2i%%)", $detected_computer, $size_of_database,   int(($detected_computer*100)/$size_of_database);
587         printf " [Time: %02i:%02i / %02i:%02i]", int($localtime/60), $localtime % 60, int($time_elapse/60), $time_elapse % 60;
588#         printf "  [%02i:%02i/%02i:%02i]", int($localtime/60), $localtime % 60, int($time_elapse/60), $time_elapse % 60;
589         printf " %-14s", $one_computer;
590
591         my %resol_arp = resolve_ip_arp_host($one_computer,$current_interface);
592         
593         # do not search on router connection (why ?)
594         if ( exists $router_mac_ip{$resol_arp{mac_address}}) {
595            $computer_not_detected{$one_computer} = $current_interface;
596            next LOOP_ON_COMPUTER;
597            }
598
599         # do not search on switch inter-connection
600         if (exists $switch_level{$resol_arp{hostname_fq}}) {
601            $computer_not_detected{$one_computer} = $current_interface;
602            next LOOP_ON_COMPUTER;
603            }
604
605         my $switch_proposal = '';
606         if (exists $computerdb->{$resol_arp{ipv4_address}} and exists $computerdb->{$resol_arp{ipv4_address}}{switch_hostname}) {
607            $switch_proposal = $computerdb->{$resol_arp{ipv4_address}}{switch_hostname};
608            }
609
610         # do not have a mac address
611         if ($resol_arp{mac_address} eq 'unknow' or (exists $resol_arp{timestamps} and $resol_arp{timestamps} < ($timestamp - 3 * 3600))) {
612            $computer_not_detected{$one_computer} = $current_interface;
613            next LOOP_ON_COMPUTER;
614            }
615
616         my %where = find_switch_port($resol_arp{mac_address},$switch_proposal);
617
618         #192.168.24.156:
619         #  arp: 00:0B:DB:D5:F6:65
620         #  hostname: pcroyon.hmg.priv
621         #  port: 5
622         #  switch: sw-batH-legi:hp2524
623         #  timestamp: 1164355525
624
625         # do not have a mac address
626#         if ($resol_arp{mac_address} eq 'unknow') {
627#            $computer_not_detected{$one_computer} = $current_interface;
628#            next LOOP_ON_COMPUTER;
629#            }
630
631         # detected on a switch
632         if ($where{switch_description} ne 'unknow') {
633            $detected_computer++;
634            $computerdb->{$resol_arp{ipv4_address}} = {
635               hostname_fq        => $resol_arp{hostname_fq},
636               mac_address        => $resol_arp{mac_address},
637               switch_hostname    => $where{switch_hostname},
638               switch_description => $where{switch_description},
639               switch_port        => $where{switch_port},
640               timestamp          => $timestamp,
641               };
642            next LOOP_ON_COMPUTER;
643            }
644
645         # new in the database but where it is ?
646         if (not exists $computerdb->{$resol_arp{ipv4_address}}) {
647            $detected_computer++;
648            $computerdb->{$resol_arp{ipv4_address}} = {
649               hostname_fq        => $resol_arp{hostname_fq},
650               mac_address        => $resol_arp{mac_address},
651               switch_hostname    => $where{switch_hostname},
652               switch_description => $where{switch_description},
653               switch_port        => $where{switch_port},
654               timestamp          => $resol_arp{timestamp},
655               };
656            }
657
658         # mise a jour du nom de la machine si modification dans le dns
659         $computerdb->{$resol_arp{ipv4_address}}{hostname_fq} = $resol_arp{hostname_fq};
660       
661         # mise à jour de la date de détection si détection plus récente par arpwatch
662         $computerdb->{$resol_arp{ipv4_address}}{timestamp}   = $resol_arp{timestamp} if exists $resol_arp{timestamp} and $computerdb->{$resol_arp{ipv4_address}}{timestamp} < $resol_arp{timestamp};
663
664         # provisoire car changement de nom des attributs
665#         $computerdb->{$resol_arp{ipv4_address}}{mac_address}        = $computerdb->{$resol_arp{ipv4_address}}{arp};
666#         $computerdb->{$resol_arp{ipv4_address}}{switch_description} = $computerdb->{$resol_arp{ipv4_address}}{switch};
667#         $computerdb->{$resol_arp{ipv4_address}}{switch_port}        = $computerdb->{$resol_arp{ipv4_address}}{port};
668       
669         # relance un arping sur la machine si celle-ci n'a pas été détectée depuis plus d'une semaine
670#         push @computer_not_detected, $resol_arp{ipv4_address} if $computerdb->{$resol_arp{ipv4_address}}{timestamp} < $timestamp_last_week;
671         $computer_not_detected{$resol_arp{ipv4_address}} = $current_interface if $computerdb->{$resol_arp{ipv4_address}}{timestamp} < $timestamp_last_week;
672       
673         }
674      }
675
676   # final end of line at the end of the loop
677   printf "\n";
678
679   my $dirdb = $KLASK_DB_FILE;
680      $dirdb =~ s#/[^/]*$##;
681   mkdir "$dirdb", 0755 unless -d "$dirdb";
682   YAML::DumpFile("$KLASK_DB_FILE", $computerdb);
683
684   for my $one_computer (keys %computer_not_detected) {
685      my $interface = $computer_not_detected{$one_computer};
686      system "arping -c 1 -w 1 -rR -i $interface $one_computer &>/dev/null";
687#      print  "arping -c 1 -w 1 -rR -i $interface $one_computer 2>/dev/null\n";
688      }
689   }
690
691sub cmd_removedb {
692   my @computer = @_;
693   
694   my $computerdb = YAML::LoadFile("$KLASK_DB_FILE");
695
696   LOOP_ON_COMPUTER:
697   for my $one_computer (@computer) {
698
699      my %resol_arp = resolve_ip_arp_host($one_computer);
700
701      delete $computerdb->{$resol_arp{ipv4_address}} if exists $computerdb->{$resol_arp{ipv4_address}};
702      }
703
704   my $dirdb = $KLASK_DB_FILE;
705      $dirdb =~ s#/[^/]*$##;
706   mkdir "$dirdb", 0755 unless -d "$dirdb";
707   YAML::DumpFile("$KLASK_DB_FILE", $computerdb);
708   }
709
710sub cmd_exportdb {
711   my $computerdb = YAML::LoadFile("$KLASK_DB_FILE");
712
713   printf "%-24s %-4s            %-30s %-15s %-18s %-s\n", qw(Switch Port Hostname IPv4-Address MAC-Address Date);
714   print "---------------------------------------------------------------------------------------------------------------------------\n";
715
716   LOOP_ON_IP_ADDRESS:
717   foreach my $ip (Net::Netmask::sort_by_ip_address(keys %$computerdb)) {
718   
719#      next LOOP_ON_IP_ADDRESS if $computerdb->{$ip}{hostname_fq} eq 'unknow';
720
721      # to be improve in the future
722      next LOOP_ON_IP_ADDRESS if $computerdb->{$ip}{hostname_fq} eq ($computerdb->{$ip}{switch_hostname} || $computerdb->{$ip}{switch_description}); # switch on himself !
723
724# dans le futur
725#      next if $computerdb->{$ip}{hostname_fq} eq 'unknow';
726     
727      my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($computerdb->{$ip}{timestamp});
728      $year += 1900;
729      $mon++;
730      my $date = sprintf "%04i-%02i-%02i %02i:%02i", $year,$mon,$mday,$hour,$min;
731
732      printf "%-25s  %2s  <-------  %-30s %-15s %-18s %s\n",
733         $computerdb->{$ip}{switch_hostname} || $computerdb->{$ip}{switch_description},
734         $computerdb->{$ip}{switch_port},
735         $computerdb->{$ip}{hostname_fq},
736         $ip,
737         $computerdb->{$ip}{mac_address},
738         $date;
739      }
740   }
741
742sub cmd_iplocation {
743   my $computerdb = YAML::LoadFile("$KLASK_DB_FILE");
744
745   LOOP_ON_IP_ADDRESS:
746   foreach my $ip (Net::Netmask::sort_by_ip_address(keys %$computerdb)) {
747
748      next LOOP_ON_IP_ADDRESS if $computerdb->{$ip}{hostname_fq} eq ($computerdb->{$ip}{switch_hostname} || $computerdb->{$ip}{switch_description}); # switch on himself !
749
750      my $sw_hostname = $computerdb->{$ip}{switch_hostname} || '';
751      next if $sw_hostname eq 'unknow';
752 
753      my $sw_location = '';
754      for my $sw (@SWITCH) {
755         next if $sw_hostname ne $sw->{hostname};
756         $sw_location = $sw->{location};
757         last;
758         }
759
760      printf "%s: \"%s\"\n", $ip, $sw_location if not $sw_location eq '';
761      }
762   }
763
764sub cmd_enable {
765   my $switch = shift;
766   my $port   = shift;
767   
768   #snmpset -v 1 -c community X.X.X.X 1.3.6.1.2.1.2.2.1.7.NoPort = 1 (up)
769   #snmpset -v 1 -c community X.X.X.X 1.3.6.1.2.1.2.2.1.7.NoPort = 2 (down)
770   system "snmpset -v 1 -c public $switch 1.3.6.1.2.1.2.2.1.7.$port = 1";
771   }
772
773sub cmd_disable {
774   my $switch = shift;
775   my $port   = shift;
776   
777   system "snmpset -v 1 -c public $switch 1.3.6.1.2.1.2.2.1.7.$port = 2";
778   }
779
780sub cmd_status {
781   my $switch = shift;
782   my $port   = shift;
783   
784   system "snmpget -v 1 -c public $switch 1.3.6.1.2.1.2.2.1.7.$port";
785   }
786
787
788sub cmd_updatesw {
789
790   init_switch_names('yes');    #nomme les switchs
791   print "\n";
792
793   my %where = ();
794   my %db_switch_output_port = ();
795   my %db_switch_ip_hostname = ();
796
797   DETECT_ALL_ROUTER:
798#   for my $one_computer ('194.254.66.254') {
799   for my $one_router ( get_list_main_router(get_list_network()) ) {
800      my %resol_arp = resolve_ip_arp_host($one_router,'*','low');            # resolution arp
801      next DETECT_ALL_ROUTER if $resol_arp{mac_address} eq 'unknow';
802     
803      $where{$resol_arp{ipv4_address}} = find_all_switch_port($resol_arp{mac_address}); # retrouve les emplacements des routeurs
804      }
805
806   ALL_ROUTER_IP_ADDRESS:
807   for my $ip (Net::Netmask::sort_by_ip_address(keys %where)) { # '194.254.66.254')) {
808   
809      next ALL_ROUTER_IP_ADDRESS if not exists $where{$ip}; # /a priori/ idiot car ne sers à rien...
810
811      ALL_SWITCH_CONNECTED:
812      for my $switch_detected ( keys %{$where{$ip}} ) {
813
814         my $switch = $where{$ip}->{$switch_detected};
815
816         next ALL_SWITCH_CONNECTED if $switch->{port} eq '0';
817         
818         $db_switch_output_port{$switch->{hostname}} = $switch->{port};
819         }
820      }   
821
822#   print "Switch output port\n"; 
823#   print "------------------\n";
824#   for my $sw (sort keys %db_switch_output_port) {
825#      printf "%-25s %2s\n", $sw, $db_switch_output_port{$sw};
826#      }
827#   print "\n";
828
829
830   my %db_switch_link_with = ();
831
832   my @list_switch_ip = ();
833   my @list_switch_ipv4 = ();
834   for my $sw (@SWITCH){
835      push @list_switch_ip, $sw->{hostname};
836      }
837
838   ALL_SWITCH:
839   for my $one_computer (@list_switch_ip) {
840      my %resol_arp = resolve_ip_arp_host($one_computer,'*','low'); # arp resolution
841      next ALL_SWITCH if $resol_arp{mac_address} eq 'unknow';
842     
843      push @list_switch_ipv4,$resol_arp{ipv4_address};
844     
845      $where{$resol_arp{ipv4_address}} = find_all_switch_port($resol_arp{mac_address}); # find port on all switch
846
847      $db_switch_ip_hostname{$resol_arp{ipv4_address}} = $resol_arp{hostname_fq};
848      }
849     
850   ALL_SWITCH_IP_ADDRESS:
851   for my $ip (Net::Netmask::sort_by_ip_address(@list_switch_ipv4)) {
852   
853      next ALL_SWITCH_IP_ADDRESS if not exists $where{$ip};
854
855      DETECTED_SWITCH:
856      for my $switch_detected ( keys %{$where{$ip}} ) {
857
858         next DETECTED_SWITCH if not exists $SWITCH_PORT_COUNT{ $db_switch_ip_hostname{$ip}};
859
860         my $switch = $where{$ip}->{$switch_detected};
861
862         next if $switch->{port}     eq '0';
863         next if $switch->{port}     eq $db_switch_output_port{$switch->{hostname}};
864         next if $switch->{hostname} eq $db_switch_ip_hostname{$ip}; # $computerdb->{$ip}{hostname};
865
866         $db_switch_link_with{ $db_switch_ip_hostname{$ip} } ||= {};
867         $db_switch_link_with{ $db_switch_ip_hostname{$ip} }->{ $switch->{hostname} } = $switch->{port};
868         }
869
870      }
871   
872   my %db_switch_connected_on_port = ();
873   my $maybe_more_than_one_switch_connected = 'yes';
874   
875   while ($maybe_more_than_one_switch_connected eq 'yes') {
876      for my $sw (keys %db_switch_link_with) {
877         for my $connect (keys %{$db_switch_link_with{$sw}}) {
878         
879            my $port = $db_switch_link_with{$sw}->{$connect};
880         
881            $db_switch_connected_on_port{"$connect:$port"} ||= {};
882            $db_switch_connected_on_port{"$connect:$port"}->{$sw}++; # Just to define the key
883            }
884         }
885
886      $maybe_more_than_one_switch_connected  = 'no';
887
888      SWITCH_AND_PORT:
889      for my $swport (keys %db_switch_connected_on_port) {
890         
891         next if keys %{$db_switch_connected_on_port{$swport}} == 1;
892         
893         $maybe_more_than_one_switch_connected = 'yes';
894
895         my ($sw_connect,$port_connect) = split ':', $swport;
896         my @sw_on_same_port = keys %{$db_switch_connected_on_port{$swport}};
897
898         CONNECTED:
899         for my $sw_connected (@sw_on_same_port) {
900           
901            next CONNECTED if not keys %{$db_switch_link_with{$sw_connected}} == 1;
902           
903            $db_switch_connected_on_port{$swport} = {$sw_connected => 1};
904           
905            for my $other_sw (@sw_on_same_port) {
906               next if $other_sw eq $sw_connected;
907               
908               delete $db_switch_link_with{$other_sw}->{$sw_connect};
909               }
910           
911            # We can not do better for this switch for this loop
912            next SWITCH_AND_PORT;
913            }
914         }
915      }
916
917   my %db_switch_parent =();
918
919   for my $sw (keys %db_switch_link_with) {
920      for my $connect (keys %{$db_switch_link_with{$sw}}) {
921     
922         my $port = $db_switch_link_with{$sw}->{$connect};
923     
924         $db_switch_connected_on_port{"$connect:$port"} ||= {};
925         $db_switch_connected_on_port{"$connect:$port"}->{$sw} = $port;
926       
927         $db_switch_parent{$sw} = {switch => $connect, port => $port};
928         }
929      }
930
931   print "Switch output port and parent port connection\n"; 
932   print "---------------------------------------------\n";
933   for my $sw (sort keys %db_switch_output_port) {
934      if (exists $db_switch_parent{$sw}) {
935         printf "%-25s  %2s  +-->  %2s  %-25s\n", $sw, $db_switch_output_port{$sw}, $db_switch_parent{$sw}->{port}, $db_switch_parent{$sw}->{switch};
936         }
937      else {
938         printf "%-25s  %2s  +-->  router\n", $sw, $db_switch_output_port{$sw};
939         }
940      }
941   print "\n";
942
943   print "Switch parent and children port inter-connection\n";
944   print "------------------------------------------------\n";
945   for my $swport (sort keys %db_switch_connected_on_port) {       
946      my ($sw_connect,$port_connect) = split ':', $swport;
947      for my $sw (keys %{$db_switch_connected_on_port{$swport}}) {
948         if (exists $db_switch_output_port{$sw}) {
949            printf "%-25s  %2s  <--+  %2s  %-25s\n", $sw_connect, $port_connect, $db_switch_output_port{$sw}, $sw;
950            }
951         else {
952            printf "%-25s  %2s  <--+      %-25s\n", $sw_connect, $port_connect, $sw;
953            }
954         }
955      }
956
957   my $switch_connection = {
958      output_port       => \%db_switch_output_port,
959      parent            => \%db_switch_parent,
960      connected_on_port => \%db_switch_connected_on_port,
961      link_with         => \%db_switch_link_with,
962      };
963     
964   YAML::DumpFile("$KLASK_SW_FILE", $switch_connection);
965   }
966
967sub cmd_exportsw {
968   my @ARGV   = @_;
969
970   my $format = 'txt';
971
972   my $ret = GetOptions(
973      'format|f=s'  => \$format,
974      );
975
976   my %possible_format = (
977      txt => \&cmd_exportsw_txt,
978      dot => \&cmd_exportsw_dot,
979      );
980
981   $format = 'txt' if not defined $possible_format{$format};
982   
983   $possible_format{$format}->(@ARGV);
984   }
985
986sub cmd_exportsw_txt {
987
988   my $switch_connection = YAML::LoadFile("$KLASK_SW_FILE");
989
990   my %db_switch_output_port       = %{$switch_connection->{output_port}};
991   my %db_switch_parent            = %{$switch_connection->{parent}};
992   my %db_switch_connected_on_port = %{$switch_connection->{connected_on_port}};
993
994   print "Switch output port and parent port connection\n"; 
995   print "---------------------------------------------\n";
996   for my $sw (sort keys %db_switch_output_port) {
997      if (exists $db_switch_parent{$sw}) {
998         printf "%-25s  %2s  +-->  %2s  %-25s\n", $sw, $db_switch_output_port{$sw}, $db_switch_parent{$sw}->{port}, $db_switch_parent{$sw}->{switch};
999         }
1000      else {
1001         printf "%-25s  %2s  +-->  router\n", $sw, $db_switch_output_port{$sw};
1002         }
1003      }
1004   print "\n";
1005
1006   print "Switch parent and children port inter-connection\n";
1007   print "------------------------------------------------\n";
1008   for my $swport (sort keys %db_switch_connected_on_port) {       
1009      my ($sw_connect,$port_connect) = split ':', $swport;
1010      for my $sw (keys %{$db_switch_connected_on_port{$swport}}) {
1011         if (exists $db_switch_output_port{$sw}) {
1012            printf "%-25s  %2s  <--+  %2s  %-25s\n", $sw_connect, $port_connect, $db_switch_output_port{$sw}, $sw;
1013            }
1014         else {
1015            printf "%-25s  %2s  <--+      %-25s\n", $sw_connect, $port_connect, $sw;
1016            }
1017         }
1018      }
1019   }
1020
1021sub cmd_exportsw_dot {
1022
1023   my $switch_connection = YAML::LoadFile("$KLASK_SW_FILE");
1024   
1025   my %db_switch_output_port       = %{$switch_connection->{output_port}};
1026   my %db_switch_parent            = %{$switch_connection->{parent}};
1027   my %db_switch_connected_on_port = %{$switch_connection->{connected_on_port}};
1028   my %db_switch_link_with         = %{$switch_connection->{link_with}};
1029     
1030   my %db_building= ();
1031   for my $sw (@SWITCH) {
1032      my ($building, $location) = split /\//, $sw->{location}, 2;
1033      $db_building{$building} ||= {};
1034      $db_building{$building}->{$location} ||= {};
1035      $db_building{$building}->{$location}{ $sw->{hostname} } = 'y';
1036      }
1037 
1038 
1039   print "digraph G {\n";
1040
1041   print "site [label = \"site\", color = black, fillcolor = gold, shape = invhouse, style = filled];\n";
1042   print "internet [label = \"internet\", color = black, fillcolor = cyan, shape = house, style = filled];\n";
1043
1044   my $b=0;
1045   for my $building (keys %db_building) {
1046      $b++;
1047     
1048      print "\"building$b\" [label = \"$building\", color = black, fillcolor = gold, style = filled];\n";
1049      print "site -> \"building$b\" [len = 2, color = firebrick];\n";
1050
1051      my $l = 0;
1052      for my $loc (keys %{$db_building{$building}}) {
1053         $l++;
1054 
1055         print "\"location$b-$l\" [label = \"$building / $loc\", color = black, fillcolor = orange, style = filled];\n";
1056         print "\"building$b\" -> \"location$b-$l\" [len = 2, color = firebrick]\n";
1057
1058         for my $sw (keys %{$db_building{$building}->{$loc}}) {
1059
1060            print "\"$sw:$db_switch_output_port{$sw}\" [label = $db_switch_output_port{$sw}, color = black, fillcolor = lightblue,  peripheries = 2, style = filled];\n";
1061
1062            print "\"$sw\" [label = \"$sw\", color = black, fillcolor = palegreen, shape = rect, style = filled];\n";
1063            print "\"location$b-$l\" -> \"$sw\" [len = 2, color = firebrick, arrowtail = dot]\n";
1064            print "\"$sw\" -> \"$sw:$db_switch_output_port{$sw}\" [len=2, style=bold, arrowhead = normal, arrowtail = invdot]\n";
1065
1066
1067            for my $swport (keys %db_switch_connected_on_port) {
1068               my ($sw_connect,$port_connect) = split ':', $swport;
1069               next if not $sw_connect eq $sw;
1070               next if $port_connect eq $db_switch_output_port{$sw};
1071               print "\"$sw:$port_connect\" [label = $port_connect, color = black, fillcolor = plum,  peripheries = 1, style = filled];\n";
1072               print "\"$sw:$port_connect\" -> \"$sw\" [len=2, style=bold, arrowhead= normal, arrowtail = inv]\n";
1073              }
1074            }
1075         }
1076      }
1077
1078#   print "Switch output port and parent port connection\n"; 
1079#   print "---------------------------------------------\n";
1080   for my $sw (sort keys %db_switch_output_port) {
1081      if (exists $db_switch_parent{$sw}) {
1082#         printf "   \"%s:%s\" -> \"%s:%s\"\n", $sw, $db_switch_output_port{$sw}, $db_switch_parent{$sw}->{switch}, $db_switch_parent{$sw}->{port};
1083         }
1084      else {
1085         printf "   \"%s:%s\" -> internet\n", $sw, $db_switch_output_port{$sw};
1086         }
1087      }
1088   print "\n";
1089
1090#   print "Switch parent and children port inter-connection\n";
1091#   print "------------------------------------------------\n";
1092   for my $swport (sort keys %db_switch_connected_on_port) {       
1093      my ($sw_connect,$port_connect) = split ':', $swport;
1094      for my $sw (keys %{$db_switch_connected_on_port{$swport}}) {
1095         if (exists $db_switch_output_port{$sw}) {
1096            printf "   \"%s:%s\" -> \"%s:%s\" [color = navyblue]\n", $sw, $db_switch_output_port{$sw}, $sw_connect, $port_connect;
1097            }
1098         else {
1099            printf "   \"%s\"   -> \"%s%s\"\n", $sw, $sw_connect, $port_connect;
1100            }
1101         }
1102      }
1103
1104print "}\n";
1105   }
1106
1107
1108__END__
1109
1110
1111=head1 NAME
1112
1113klask - ports manager and finder for switch
1114
1115
1116=head1 SYNOPSIS
1117
1118 klask updatedb
1119 klask exportdb
1120
1121 klask updatesw
1122 klask exportsw --format [txt|dot]
1123
1124 klask searchdb computer
1125 klask search   computer
1126
1127 klask enable  switch port
1128 klask disable swith port
1129 klask status  swith port
1130
1131
1132=head1 DESCRIPTION
1133
1134klask is a small tool to find where is a host in a big network. klask mean search in brittany.
1135
1136Klask has now a web site dedicated for it !
1137
1138 http://servforge.legi.inpg.fr/projects/klask
1139
1140
1141=head1 COMMANDS
1142
1143
1144=head2 search
1145
1146This command takes one or more computer in argument. It search a computer on the network and give the port and the switch on which the computer is connected.
1147
1148
1149=head2 enable
1150
1151This command activate a port on a switch by snmp. So you need to give the switch and the port number on the command line.
1152
1153
1154=head2 disable
1155
1156This command deactivate a port on a switch by snmp. So you need to give the switch and the port number on the command line.
1157
1158
1159=head2 status
1160
1161This command return the status of a port number on a switch by snmp. So you need to give the switch name and the port number on the command line.
1162
1163
1164=head2 updatedb
1165
1166This command will scan networks and update a database. To know which are the cmputer scan, you have to configure the file /etc/klask.conf This file is easy to read and write because klask use YAML format and not XML.
1167
1168
1169=head2 exportdb
1170
1171This command print the content of the database. There is actually only one format. It's very easy to have more format, it's just need times...
1172
1173
1174=head2 updatesw
1175
1176This command build a map of your manageable switch on your network. The list of the switch must be given in the file /etc/klask.conf.
1177
1178
1179=head2 exportsw --format [txt|dot]
1180
1181This command print the content of the switch database. There is actually two format. One is just txt for terminal and the other is the dot format from the graphviz environnement.
1182
1183 klask exportsw --format dot > /tmp/map.dot
1184 dot -Tpng /tmp/map.dot > /tmp/map.png
1185
1186
1187
1188=head1 CONFIGURATION
1189
1190Because klask need many parameters, it's not possible actually to use command line parameters. The configuration is done in a /etc/klask.conf YAML file. This format have many advantage over XML, it's easier to read and to write !
1191
1192Here an example, be aware with indent, it's important in YAML, do not use tabulation !
1193
1194 default:
1195   community: public
1196   snmpport: 161
1197
1198 network:
1199   labnet:
1200     ip-subnet:
1201       - add: 192.168.1.0/24
1202       - add: 192.168.2.0/24
1203     interface: eth0
1204     main-router: gw1.labnet.local
1205
1206   schoolnet:
1207     ip-subnet:
1208       - add: 192.168.6.0/24
1209       - add: 192.168.7.0/24
1210     interface: eth0.38
1211     main-router: gw2.schoolnet.local
1212
1213 switch:
1214   - hostname: sw1.klask.local
1215     portignore:
1216       - 1
1217       - 2
1218
1219   - hostname: sw2.klask.local
1220     location: BatK / 2 / K203
1221     type: HP2424
1222     portignore:
1223       - 1
1224       - 2
1225
1226I think it's pretty easy to understand. The default section can be overide in any section, if parameter mean something in theses sections. Network to be scan are define in the network section. You must put a add by network. Maybe i will make a delete line to suppress specific computers. The switch section define your switch. You have to write the port number to ignore, this is important if your switchs are cascade. Juste put the ports numbers between switch.
1227
1228
1229=head1 FILES
1230
1231 /etc/klask.conf
1232 /var/cache/klask/klaskdb
1233 /var/cache/klask/switchdb
1234
1235=head1 SEE ALSO
1236
1237Net::SNMP, Net::Netmask, Net::CIDR::Lite, NetAddr::IP, YAML
1238
1239
1240=head1 VERSION
1241
12420.4
1243
1244
1245=head1 AUTHOR
1246
1247Written by Gabriel Moreau, Grenoble - France
1248
1249
1250=head1 COPYRIGHT
1251       
1252Copyright (C) 2005-2008 Gabriel Moreau.
1253
1254
1255=head1 LICENCE
1256
1257GPL version 2 or later and Perl equivalent
Note: See TracBrowser for help on using the repository browser.