Net::Subnet - ein schneller IP-Adressen Subnet Matcher
Veröffentlicht von Thomas Fahle am (Permalink)
Net::Subnet - Fast IP-in-subnet matcher for IPv4 and IPv6, CIDR or mask von Juerd Waalboer ist ein einfaches und schnelles Werkzeug, um fest zu stellen, ob sich eine bestimmte IP-Adresse in einem Subnetz befindet.
Die nachfolgend angeführten Beispiele beziehen sich auf IPv4, Net::Subnet beherrscht auch IPv6.
Net::Subnet validiert übrigens keine Daten - das muss man ggf. selbst machen.
Alle Funktionen werden automatisch exportiert.
Ist eine IP in einem meiner Subnetze - subnet_matcher()
subnet_matcher() liefert eine Referenz auf eine Funktion zurück, die wahr zurückliefert, wenn eine bestimmte IP-Adresse in einer Liste von Subnetzen (also in irgendeinem dieser Netze) enthalten ist.
Beispiel
#!/usr/bin/perl use strict; use warnings; use Net::Subnet; my $is_rfc1918 = subnet_matcher qw' 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 '; my @ips = qw/ 192.168.1.1 172.16.32.1 192.168.178.2 8.8.8.8 /; foreach my $ip (@ips) { if ( $is_rfc1918->($ip) ) { print "$ip ist eine private IP-Adresse\n"; } else { print "$ip ist keine private IP-Adresse\n"; } }
Das Programm erzeugt folgende Ausgabe:
192.168.1.1 ist eine private IP-Adresse 172.16.32.1 ist eine private IP-Adresse 192.168.178.2 ist eine private IP-Adresse 8.8.8.8 ist keine private IP-Adresse
Wer nur wissen möchte, ob eine bestimmte IP-Adresse in einem bestimmtem Subnetz enthalten ist, kürzt die Liste der Subnetze, die an subnet_matcher() übergeben wird, entsprechend.
Beispiel
#!/usr/bin/perl use strict; use warnings; use Net::Subnet; my $is_in_my_network = subnet_matcher qw' 192.168.178.0/24 '; my @ips = qw' 192.168.1.1 172.16.32.1 192.168.178.2 8.8.8.8 '; foreach my $ip (@ips) { if ( $is_in_my_network->($ip) ) { print "$ip ist in meinem Subnet\n"; } else { print "$ip ist nicht in meinem Subnet\n"; } }
Das Programm erzeugt folgende Ausgabe:
192.168.1.1 ist nicht in meinem Subnet 172.16.32.1 ist nicht in meinem Subnet 192.168.178.2 ist in meinem Subnet 8.8.8.8 ist nicht in meinem Subnet
In welchem meiner Subnetze ist eine IP - subnet_classifier()
subnet_classifier() liefert eine Referenz auf eine Funktion zurück, die prüft, ob eine IP-Adresse zu einem Netz einer Subnetzliste gehört. Im Erfolgsfall wird das Subnetz zurückgegeben.
Beispiel
#!/usr/bin/perl use strict; use warnings; use Net::Subnet; my $rfc1918_classifier = subnet_classifier qw' 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 '; my @ips = qw/ 192.168.1.1 172.16.32.1 192.168.178.2 8.8.8.8 /; foreach my $ip (@ips) { my $subnet = $rfc1918_classifier->($ip); if ( $subnet ) { print "$ip befindet sich im Subnetz '$subnet'\n"; } else { print "$ip befindet sich in keinem Subnetz der Liste\n"; } }
Das Programm erzeugt folgende Ausgabe:
192.168.1.1 befindet sich im Subnetz '192.168.0.0/16' 172.16.32.1 befindet sich im Subnetz '172.16.0.0/12' 192.168.178.2 befindet sich im Subnetz '192.168.0.0/16' 8.8.8.8 befindet sich in keinem Subnetz der Liste
Subnets nach Größe sortieren - sort_subnets()
sort_subnets() sortiert eine Liste von Subnetzen der Größe nach. Kleinere, mehr spezifische, Netze werden weiter vorne einsortiert.
Falls sich Subnetze überlappen, muss die Liste der Subnetze sortiert werden, bevor diese an subnet_matcher() oder subnet_classifier() weitergereicht wird.
Beispiel
#!/usr/bin/perl use strict; use warnings; use Net::Subnet; my @subnets = qw~ 172.16.0.0/12 172.16.0.0/16 172.16.0.0/22 172.16.31.0/24 172.16.31.0/22 ~; # Smaller networks will show up first my @sorted_subnets = sort_subnets(@subnets); foreach my $subnet (@sorted_subnets) { print $subnet, "\n"; }
Das Programm erzeugt folgende Ausgabe:
172.16.31.0/24 172.16.31.0/22 172.16.0.0/22 172.16.0.0/16 172.16.0.0/12