On Fri, 15 Apr 2011 13:12:00 -0500 Ted Zlatanov <t...@lifelogs.com> wrote: 

TZ> On Tue, 12 Apr 2011 08:13:29 -0500 Ted Zlatanov <t...@lifelogs.com> wrote: 
TZ> Actually it would be really nice if cfengine produced the list of
TZ> interfaces in addition to the current net_iface_* classes.  It's already
TZ> traversing the list of interfaces and providing sys.ipv4 so collecting
TZ> their names in a sys.interfaces slist would be useful.

TZ> I think it would be useful information to know the network driver, maybe
TZ> as the mapped value if the key is the interface name.

Here's sample output and a Perl function to print out information about
the interfaces, using just /sbin/ifconfig output and /sys if it's
available.  This is pretty useful for us--and it all works for
non-Ethernet drivers like Infiniband.

The list of flags was built from several sources.  It may be incomplete.

You can get the list of interfaces from @interfaces as you can see.

Let me know if you have trouble making it work and if you find it
useful.  The Perl code doesn't require any modules and should work on
Perl 5.6 and later (definitely 5.8 and later).

Ted

+jcf_interface_eth0_flag_broadcast
+jcf_interface_eth0_flag_multicast
+jcf_interface_eth0_flag_running
+jcf_interface_eth0_flag_up
=jcf_interface_eth0_hwaddr=00:32:ea:29:b2:76
=jcf_interface_eth0_bcast=10.1.14.255
=jcf_interface_eth0_mask=255.255.255.0
=jcf_interface_eth0_scope=Link
=jcf_interface_eth0_mtu=1500
=jcf_interface_eth0_metric=1
=jcf_interface_eth0_inet_addr=10.1.14.81
=jcf_interface_eth0_inet6_addr=fe80::223:aeff:fe92:2b76/64
=jcf_interface_eth0_module=tg3
=jcf_interface_eth0_module_srcversion=B99342A64564556B56C3BDB
=jcf_interface_eth0_module_version=2.216
=jcf_interface_eth0_module_initstate=live
+jcf_interface_lo_flag_loopback
+jcf_interface_lo_flag_running
+jcf_interface_lo_flag_up
=jcf_interface_lo_mask=255.0.0.0
=jcf_interface_lo_scope=Host
=jcf_interface_lo_mtu=16436
=jcf_interface_lo_metric=1
=jcf_interface_lo_inet_addr=127.0.0.1
=jcf_interface_lo_inet6_addr=::1/128
@jcf_interfaces= { "eth0", "lo" }

sub print_cfengine_interface_config
{
    my $i = '/sbin/ifconfig';
    open my $ifconfig, "$i -a|" or die "Couldn't open $i: $!";
    my $config = join '', <$ifconfig>;
    my @interfaces;

    foreach my $c (split "\n\n", $config)
    {
        next unless $c =~ m/^(\S+)\s+(.+)/s;
        my $if = $1;
        my $data = $2;

        push @interfaces, $if;

        # most of these flags are from the ifconfig man pages and from practice
        foreach my $flag (qw/IPV6 ADDRCONF ANYCAST BROADCAST CoS DEPRECATED 
DHCP DUPLICATE FAILED FIXEDMTU INACTIVE LOOPBACK MIP MULTI_BCAST MULTICAST 
NOARP NOFAILOVER NOLOCAL NONUD NORTEXCH NOXMIT OFFLINE POINTOPOINT PREFERRED 
PRIVATE PROMISC ROUTER RUNNING STANDBY TEMPORARY UNNUMBERED UP VIRTUAL XRESOLV/)
        {
            next unless $data =~ m/$flag/i;
            print "+jcf_interface_${if}_flag_", lc($flag), "\n";
        }

        # many of these, but not all, are available in /proc/net/dev
        # but /proc is not available on many systems...

        # Link encap:Ethernet HWaddr 00:32:ea:29:b2:76
        # inet addr:10.1.14.81  Bcast:10.1.14.255  Mask:255.255.255.0
        # inet6 addr: fe80::223:aeff:fe92:2b76/64 Scope:Link
        # MTU:1500  Metric:1
        foreach my $kw1 ('HWaddr',
                         (map { "$_:" } qw/Bcast Mask Scope MTU Metric/),
                         'inet addr:', 'inet6 addr:')
        {
            my $kw = quotemeta($kw1);
            next unless $data =~ m/$kw\s*(\S+)/;
            my $v = $1;
            my $k = lc $kw1;
            $k =~ s/:$//;
            $k =~ s/\s+/_/g;
            $k =~ s/\W+/_/g;
            print "=jcf_interface_${if}_$k=$v\n";
        }

        # the following was only tested on Linux, it uses /sys
        my $syspath =  "/sys/class/net/$if/device";
        if (-f "$syspath/uevent")
        {
            open my $uevent, '<', "$syspath/uevent"
             or die "Couldn't open $syspath/uevent: $!";
            while (<$uevent>)
            {
                if (m/^DRIVER=(.+)/)
                {
                    print "=jcf_interface_${if}_module=$1\n";
                    last;
                }
            }
        }

        foreach my $k (qw/srcversion version initstate/)
        {
            my $f = "$syspath/driver/module/$k";
            next unless -f $f;
            open my $fh, '<', $f or die "Couldn't open $f: $!";
            my $v = <$fh>;
            chomp $v;
            print "=jcf_interface_${if}_module_$k=$v\n";

        }

    }

    printf "\@jcf_interfaces= { %s }\n",
     join(", ", map { "\"$_\"" } @interfaces);
}

_______________________________________________
Help-cfengine mailing list
Help-cfengine@cfengine.org
https://cfengine.org/mailman/listinfo/help-cfengine

Reply via email to