remoteme

CLI tool in perl to report internet ip for the current host using STUN servers
git clone git://holbrook.no/remoteme.git
Log | Files | Refs | LICENSE

remoteme.pl (2201B)


      1 #!/usr/bin/env perl
      2 
      3 use Errno qw/ENODATA/;
      4 use Getopt::Long qw/GetOptions/;
      5 use STUN::Client;
      6 use 5.010; # used in example in https://perlmaven.com/how-to-process-command-line-arguments-in-perl
      7 use Data::Dumper;
      8 use File::BaseDir qw/config_files/;
      9 
     10 use constant DEFAULT_SERVER_LIST_PATH => '/usr/share/stun/servers.txt';
     11 
     12 my $_remotestring;
     13 my $nonewline;
     14 my $configfile;
     15 GetOptions(
     16 	'd' => \$debug,
     17 	'n' => \$nonewline,
     18 	'host=s' => \$_remotestring,
     19 	'c=s' => \$configfile,
     20 );
     21 
     22 if ($configfile eq '') {
     23 	$configfile = config_files('remoteme/servers.txt');
     24 }
     25 
     26 if ($configfile eq '') {
     27 	if (! -f DEFAULT_SERVER_LIST_PATH) {
     28 		if ($_remotestring eq '') {
     29 			print STDERR qq{server list missing\n};
     30 			exit 1;
     31 		}	
     32 	}
     33 	$configfile = DEFAULT_SERVER_LIST_PATH;
     34 }
     35 
     36 my @servers;
     37 if ($_remotestring) {
     38 	#$remotestring = $_remotestring;
     39 	push @servers, $_remotestring;
     40 } else {
     41 	if ($debug) {
     42 		print STDERR "using config file " . $configfile . "\n";
     43 	}
     44 	my $f;
     45 	open($f, "<", $configfile);
     46 	foreach my $l (<$f>) {
     47 		push @servers, $l;
     48 	}
     49 	close($f);
     50 	
     51 }
     52 
     53 my $result;
     54 foreach my $remotestring (@servers) {
     55 	my $host = $remotestring;
     56 	my $port = 3478;
     57 	if ($remotestring =~ ':') {
     58 		($host, $port) = split(/:/, $remotestring);
     59 	}
     60 
     61 	if ($debug) {
     62 		print STDERR "using host " . $remotestring;
     63 	}
     64 
     65 	$c = STUN::Client->new;
     66 
     67 	eval {
     68 		$c->stun_server($host);
     69 	} or do {
     70 		exit $!;
     71 	};
     72 	eval {
     73 		($old, $new) = $c->get or die "cannot get $!";
     74 	} and do {
     75 		undef $old;
     76 		$result = $new->{'attributes'}{'XOR-MAPPED-ADDRESS'}{'address'};
     77 		if (!defined $new || $result eq '') {
     78 			exit ENODATA;
     79 		}
     80 		print $result;
     81 		unless ($nonewline) {
     82 			print "\n";
     83 		}
     84 		#print Dumper($new);
     85 		exit 0;
     86 	};
     87 
     88 	undef $old;
     89 }
     90 
     91 __END__
     92 
     93 =head1 NAME
     94 
     95 rmme - Print current public internet address
     96 
     97 =head1 SYNOPSIS
     98 
     99 rmme [-nh]
    100 
    101 =head1 DESCRIPTION
    102 
    103 Queries a STUN server for the local host's public internet address and returns the result.
    104 
    105 If no address is reported ENODATA will be returned.
    106 
    107 =head1 OPTIONS
    108 
    109 =over 2
    110 
    111 =item -n	Omit newline at end of result
    112 
    113 =item -h	Stun server hostname in format <host|ip>[:port]
    114 
    115 =back
    116 
    117 =head1 AUTHOR
    118 
    119 Louis Holbrook <dev@holbrook.no> (https://holbrook.no)
    120 
    121 =head1 COPYRIGHT
    122 
    123 Licenced under GPLv3