#!/usr/bin/perl
use strict;
use warnings;
require 'sys/ioctl.ph';
use Socket;

my %interfaces;
my $max_addrs = 30;
socket(my $socket, AF_INET, SOCK_DGRAM, 0) or die "socket: $!";

{
    my $ifreqpack = 'a16a16';
    my $buf = pack($ifreqpack, '', '') x $max_addrs;
    my $ifconf = pack('iP', length($buf), $buf);

    # This does the actual work
    ioctl($socket, SIOCGIFCONF(), $ifconf) or die "ioctl: $!";

    my $len = unpack('iP', $ifconf);
    substr($buf, $len) = '';

    %interfaces = unpack("($ifreqpack)*", $buf);

    unless (keys(%interfaces) < $max_addrs) {
        # Buffer was too small
        $max_addrs += 10;
        redo;
    }
}

for my $addr (values %interfaces) {
    $addr = inet_ntoa((sockaddr_in($addr))[1]);
}

use Data::Dumper;
print Dumper \%interfaces;
