%PDF- %PDF-
Direktori : /usr/share/perl5/vendor_perl/Munin/Node/Configure/ |
Current File : //usr/share/perl5/vendor_perl/Munin/Node/Configure/HostEnumeration.pm |
package Munin::Node::Configure::HostEnumeration; # $Id$ use strict; use warnings; use Socket; use Munin::Node::Configure::Debug; use Exporter (); our @ISA = qw/Exporter/; our @EXPORT = qw/expand_hosts/; ### Network address manipulation ############################################### # converts a hostname or IP and an optional netmask into a list of the # hostnames and/or IPs in that network. # # If you haven't guessed, this is IPv4 only. sub _hosts_in_net { my ($host, $mask) = @_; my @ret; # avoid losing the hostname that was provided. makes for more appropriate # links in the servicedir. # # FIXME: this is very limited. make it work in the case when a netmask is # provided (substitute the hostname for the corresponding IP in the list # that is returned. unless (defined $mask) { return $host; } my $addr = _resolve($host); die "Invalid netmask: $mask\n" unless ($mask =~ /^\d+$/ and $mask <= 32); my $net = unpack('N', $addr); # ntohl() # Evil maths courtesy of nmap's TargetGroup.cc my $low = $net & (0 - (1 << (32 - $mask))); my $high = $net | ((1 << (32 - $mask)) - 1); # Note that the .. operator uses signed integers. Hence the loop. for (my $ip = $low; $ip <= $high; $ip++) { push @ret, inet_ntoa(pack 'N', $ip); } return @ret; } # Resolves a hostname or IP, and returns the address as a bitstring in # network byte order. sub _resolve { my ($host) = @_; my ($name, $aliases, $addrtype, $length, @addrs) = gethostbyname($host); die "Unable to resolve $host\n" unless $name; if (scalar @addrs > 1) { warn sprintf "# Hostname %s resolves to %u IPs. Using %s\n", $host, scalar(@addrs), inet_ntoa($addrs[0]); } DEBUG(sprintf "# Resolved %s to %s", $host, inet_ntoa($addrs[0])); return $addrs[0]; } sub expand_hosts { my (@unexpanded) = @_; my @hosts; foreach my $item (@unexpanded) { DEBUG("Processing $item"); my ($host, $mask) = split '/', $item, 2; push @hosts, _hosts_in_net($host, $mask); } return @hosts; } 1; __END__ =head1 NAME Munin::Node::Configure::HostEnumeration - Takes a list of hosts, and returns the corresponding IPs in dotted-quad form. =head1 SYNOPSIS @hosts = ('switch1', 'host1/24', '10.0.0.60/30'); foreach my $host (expand_hosts(@hosts)) { # ... } =head1 SUBROUTINES =over =item B<expand_hosts> @expanded = expand_hosts(@list); Takes a list of hosts, and returns the corresponding IPs in dotted-quad form. Items can be specified as a hostname or dotted-quad IP, either with or without a netmask. Currently only IPv4 addresses are supported. =back =cut # vim: ts=4 : sw=4 : expandtab