This file is indexed.

/usr/share/perl5/Munin/Node/Configure/HostEnumeration.pm is in munin-node 2.0.33-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
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