#!/usr/bin/perl ## # Find out what *listening* sockets are unused ## # ./net-free-sockets.pl [] ## # altblue 20070301 ## use strict; use warnings; use IO::Interface::Simple (); use List::Compare (); print join( "\n", free_sockets(@ARGV) ), "\n"; sub free_sockets { my @used = used_sockets(@_); return () if $used[-1] eq '0.0.0.0'; my @all = grep {defined} map { $_->address } IO::Interface::Simple->interfaces; return List::Compare->new('-u', '-a', \@used, \@all )->get_complement; } sub used_sockets { my ( $port, $proto ) = @_; return if !$port; if ( !$proto || $proto !~ /^((?:tcp|udp|raw)6?)$/ ) { $proto = 'tcp'; } my $xport = sprintf q{%04X}, $port; open my $sox, q{<}, "/proc/net/$proto" or die "Cannot get $proto sockets ($!)"; my @sox = <$sox>; close $sox; my @used; for (@sox) { next if !m{ ^ [^:]+: \s+ ([^:]+):$xport \s+\S+\s+ 0A \b }xm; push @used, join q[.], map { hex } reverse unpack q{(A2)*}, $1; last if $used[-1] eq '0.0.0.0'; } return @used; }