8 die "$us: no arguments permitted\n" if @ARGV;
10 our ($monh,$monchild);
13 # no entry: not reported, does not exist
14 # /ry+/: reported, entry exists
15 # during processing only:
16 # /r/: reported, may not still exist
17 # /y+/: not reported, entry exists
20 return unless $monchild;
22 or warn "$us: cannot kill monitor child [$monchild]: $!\n";
27 END { killmonitor(); }
37 $monchild = open $monh, "-|", qw(ip -o monitor addr)
38 or die "spawn monitor: $!\n";
39 sleep(1) if $restart++;
42 my $got = sysread $monh, $discard, 4096;
43 die "read monitor: $!\n" unless defined $got;
44 die "monitor failed\n" unless $got;
46 $_='r' foreach values %reported;
47 foreach my $ip (qw(4 6)) {
48 my $addrh = new IO::File;
49 open $addrh, "-|", qw(ip -o), "-$ip", qw(addr show)
50 or die "spawn addr $ip show: $!\n";
51 my $afstr = $ip==4 ? 'inet' : $ip==6 ? 'inet6' : die;
53 if (m{^\d+\:\s*(\S+)\s+$afstr\s+([0-9a-z.:]+)(?:/\d+)?\s}) {
54 my $outline = "$ip $1 $2";
55 $reported{$outline} .= "y";
58 warn "unexpected output from addr $ip show: $_\n";
62 die "addr $ip show failed $!\n" unless $r;
65 foreach my $k (keys %reported) {
66 local $_ = $reported{$k};
76 print STDERR "$us: $@";
81 STDOUT->flush or die $!;