Schrift
[thread]11939[/thread]

LinuxMagazin Script Fehler (Seite 2)

Leser: 22


<< |< 1 2 >| >> 14 Einträge, 2 Seiten
Gast Gast
 2008-06-11 18:29
#110976 #110976
Dubu+2008-06-10 22:56:59--
Freut mich, dass es geholfen hat.

Hat es, nochmals Danke!

Peter
roli
 2009-05-13 17:06
#121577 #121577
User since
2004-12-31
424 Artikel
BenutzerIn
[default_avatar]
Hi,

ich bin auch gerade dabei mich mit "Licht ins Dunkel" zu beschäftigen. Dabei ist mir aufgefallen, das der Eintrag "ip_change" in namedev nirgends genutzt wird. Bei dem split wird er noch berücksichtigt, aber an device_add wird er nicht übergeben. Also habe ich hier mal folgende Anpassung gemacht:
Code (perl): (dl )
1
2
3
4
5
6
7
my($mac, $ip, $ip_change) = split ' ', $nextline;
if($ip_change) {
  $db->device_add($name, $mac);
}
else {
  $db->device_add($name, $mac, $ip);
}

Dann ist mir aufgefallen, das sich das Problem nach "WatchLan" durchzieht. In device_add wird er auch nicht berücksichtigt. Da in das Feld ip_static_id der Tabelle devices aber die id der IP-Adresse eingetragen wird, setzt's bei mir aus. Wie kann ich mittels ROSE die id abfragen? In guter alter SQL würde ich schreiben:
Code: (dl )
SELECT id FROM ip_addresses WHERE string = $ip_adr

Wie würde ich das in ROSE realisieren? Was ich mir so ausgedacht habe fuktioniert leider nicht:
Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
sub device_add {
###########################################

  my ( $self, $name, $mac_address, $ip_adr ) = @_;

  my $ip_id;
  if($ip_change) {
    $ip_id = WatchLAN::ip_addresses( $ip_change );
  }   
  my $device = WatchLAN::Device->new( mac_address => $mac_address );
  $device->load( speculative => 1 );
  $device->name($name);
  $device->ip_static_id($ip_id);
  $device->save();
}
Roland
--
"Steh vorn, während du fragst;
sitzen soll, wer antwortet."
Aus "Die Edda des Snorri Sturluson" "Gylfis Täuschung" Strophe 2
roli
 2009-05-15 11:51
#121611 #121611
User since
2004-12-31
424 Artikel
BenutzerIn
[default_avatar]
Hi,

für den Fall das es doch jemanden interessiert, ich habe jetzt eine Lösung bei der auch berücksichtigt wird, ob es sich um dynamische, oder statische IP-Adressen handelt.
namedev
Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#!/usr/bin/perl
# angepasst 2009, by roli

use strict;
use warnings;
use WatchLAN;

my $db = WatchLAN->new();

while(<DATA>) {
    if(/^#\s*(.*)/) {
        my $name = $1;
        my $nextline = <DATA>;
        chomp $nextline;
        my($mac, $ip, $ip_change) = split ' ', $nextline;
        if($ip_change) {
            $db->device_add($name, $mac);
        }
        else {
            $db->device_add($name, $mac, $ip);
        }
    }
}

__DATA__
#MyLaptop
00:26:25:d2:9a:12 10.0.0.150 ip_change

#MyFileSRV
00:e0:a1:19:57:c5 10.1.0.1


WatchLAN.pm
Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
###########################################
# Mike Schilli, 2006 (m@perlmeister.com)
# angepasst 2009, by roli
###########################################
package WatchLAN;
###########################################
use strict;
use Apache::DBI;   # share a single DB conn
use Rose::DB::Object::Loader;
use Log::Log4perl qw(:easy);
use DateTime;

use Data::Dumper;

my $loader = Rose::DB::Object::Loader->new(
    db_dsn => 'dbi:mysql:dbname=watchlan',
    db_username  => 'root',
    db_password  => 'watchlan',
    db_options   => { AutoCommit => 1, RaiseError => 1 },
    class_prefix => 'WatchLAN'
);

my @classes = $loader->make_classes();

#print Dumper @classes;
#foreach my $class (@classes)
#    {
#      if($class->isa('Rose::DB::Object'))
#      {
#        print $class->meta->perl_class_definition(braces => 'bsd',
#                                                  indent => 2), "\n";
#      }
#      else # Rose::DB::Object::Manager subclasses
#      {
#        print $class->perl_class_definition, "\n";
#      }
#    }

###########################################
sub new {
###########################################
    my ($class) = @_;

    my $self = {
        cache          => {},
        flush_interval => 60,
        next_update    => undef,
    };

    bless $self, $class;
    $self->cache_flush();

    return $self;
}

###########################################
sub event_add {
###########################################
    my($self, $mac, $ip)= @_;

    $self->{cache}->{"$mac,$ip"}++;
    $self->cache_flush() if time() > $self->{next_update};
}

###########################################
sub cache_flush {
###########################################
    my ($self) = @_;

    for my $key ( keys %{ $self->{cache} } ){
        my ($mac, $ip) = split /,/, $key;
        my $counter = $self->{cache}->{$key};

        my $minute = DateTime->from_epoch(
            epoch => $self->{next_update} - $self->{flush_interval},
            time_zone => "local",
        );

        my $activity = WatchLAN::Activity->new(minute => $minute);

        $activity->device( { mac_address => $mac } );
        $activity->ip_address( { string => $ip } );
        $activity->counter($counter);
        $activity->save();
    }

    $self->{cache} = {};
    $self->{next_update} = time() - ( time() % $self->{flush_interval} ) +
        $self->{flush_interval};
}

###########################################
sub device_add {
###########################################
    my ( $self, $name, $mac_address, $ip_change ) = @_;

    my $device = WatchLAN::Device->new( mac_address => $mac_address );
    $device->load( speculative => 1 );
    $device->name($name);

    if($ip_change) {
        my $ip_id;
        my $dummy = WatchLAN::IpAddress->new(string => $ip_change); # unique key
        $dummy->load;
        $ip_id = $dummy->id;
        #print "IP-ID= $ip_id <\n";
        $device->ip_static_id($ip_id);
    }

    $device->save();
}

1;


Darüber hinaus habe ich das "lastaccess" Script dahingehend angepasst, das bei unbekannten Geräten sowohl die MAC als auch die IP-Adresse mit ausgegeben werden.
access
Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#!/usr/bin/perl -w
###########################################
# Mike Schilli, 2006 (m@perlmeister.com)
# angepasst 2009, by roli
###########################################
use strict;
use WatchLAN;
#use Data::Dumper;

my $reachback = DateTime->now( time_zone => "local" )
    ->subtract( minutes => 60 * 24 );

my $events = WatchLAN::Activity::Manager->get_activity(
    with_objects => [ 'device', 'ip_address' ],
    query   => [ minute => { gt => $reachback }, ],
    sort_by => ['minute'],
);

#print Dumper @$events;

my %latest = ();

for my $event (@$events) {
    $latest{$event->device_id()} = $event;
}

for my $id (keys %latest) {
    my $event = $latest{$id};
    my $name  = $event->device()->name();
    $name ||= "unknown (id=$id)";
    if($name =~ m/unknown \(id=/){
        my $mac   = $event->device()->mac_address();
        my $ip    = $event->ip_address()->string();
        printf "%23s: %s ago \t MAC=$mac IP=$ip\n", $name, time_diff($event->minute());
    }
    else{
        printf "%23s: %s ago\n", $name, time_diff($event->minute());
    }
}

###########################################
sub time_diff {
###########################################
    my ($dt) = @_;

    my $duration = DateTime->now(time_zone => "local") - $dt;

    for (qw(hours minutes seconds)) {
        if(my $n = $duration->in_units($_)) {
            my $unit = $_;
            $unit =~ s/s$// if $n == 1;
            return "$n $unit";
        }
    }
}

Last edited: 2009-05-15 11:57:20 +0200 (CEST)
Roland
--
"Steh vorn, während du fragst;
sitzen soll, wer antwortet."
Aus "Die Edda des Snorri Sturluson" "Gylfis Täuschung" Strophe 2
roli
 2009-05-19 16:01
#121708 #121708
User since
2004-12-31
424 Artikel
BenutzerIn
[default_avatar]
Hi,

wie hörte ich mal einen Professor sagen: "Ein guter Dialog ist ein vor Zeugen abgewickelter Monolg".
Wie auch immer, ich habe Mike Schilli mal angeschrieben, er gab mir noch den Tip in WatchLan.pm folgende Änderung einzubauen
Code (perl): (dl )
1
2
3
4
5
6
7
8
if($ip_change) {
        my $ip_id;
        my $dummy = WatchLAN::IpAddress->new(string => $ip_change); # unique key
        $dummy->load(speculative =>1);
        $ip_id = $dummy->id;
        #print "IP-ID= $ip_id <\n";
        $device->ip_static_id($ip_id);
    }
, also das "(speculative =>1)". Dann gibt's keine Fehler wenn die IP-Adr noch nicht in der DB drinnen ist.

Nachdem nun auch statische IP's als solche in der DB stehen, ist die nächste Aufgabe zu prüfen ob sich nicht mal die MAC zu dieser IP ändert. Dazu habe ich mir mal folgende SQL ausgedacht
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
CREATE TEMPORARY TABLE tt1
SELECT DISTINCT t1.string AS IP_Adr, t2.mac_address AS MAC
FROM ip_addresses t1, devices t2, activity t3
WHERE t3.device_id = t2.id
AND t3.ip_address_id = t1.id
AND t2.ip_static_id IS NOT NULL
ORDER BY t1.string;

CREATE TEMPORARY TABLE tt2
SELECT *, COUNT(IP_Adr) AS anz FROM tt1
GROUP BY IP_Adr;

SELECT a.IP_Adr, a.MAC FROM tt1 a, tt2 bA
WHERE a.IP_Adr = b.IP_Adr
AND b.anz >1

nicht schön, aber funktionierend. So wie's aussieht sollte ich mich mal wieder mit JOIN's beschäftigen ;-}

Hat jemand eine Idee wie ich das in ROSE mache?
Roland
--
"Steh vorn, während du fragst;
sitzen soll, wer antwortet."
Aus "Die Edda des Snorri Sturluson" "Gylfis Täuschung" Strophe 2
<< |< 1 2 >| >> 14 Einträge, 2 Seiten



View all threads created 2008-05-30 16:22.