#!/usr/bin/perl -w
use IO::Select;
use IO::Socket;
$pollinterval = 10; # interval in seconds to check for public IP change
$dgs = new IO
::Socket::INET(Proto
=> 'udp') or die "Socket: $!\n";
$sel = new IO::Select($dgs);
sub get_public_ip { # get current public IP from STUN server
my $tid = 0;
while (1) {
$index = 0 if ++$index > $#hosts;
my $destpaddr = sockaddr_in($ports[$index], $hosts[$index]);
my $obuf = pack("n n N N N N", 1, 0, 0, 0, 0xdeadbeef
, ++$tid);
$dgs->send($obuf, 0, $destpaddr); # send STUN binding request
my $pubip = '';
while ($sel->can_read(1)) { # wait for reply
if ($dgs->recv($ibuf, 100, 0)) {
next unless $ibuf && length($ibuf) >= 32;
my ($type, $tid1, $tid2, $attr, $packed) = unpack("n x10 N N n x6 a4", $ibuf);
next unless $type == 0x0101 && $tid1 == 0xdeadbeef && $tid2 == $tid && $attr == 0x0001;
$pubip = inet_ntoa($packed);
last;
}
}
}
}
sub logit {
(my $msg) = @_;
}
sub get_asterisk_ip { # get IP address being used by Asterisk chan_sip
open(PIPE
, "asterisk -x 'sip show settings' |") or return '';
my $asterisk_ip = '';
while(<PIPE>) {
$asterisk_ip = $1 if /Externaddr: +([\d\.]+)/;
}
}
open(LOG
, ">>updateip.log") or die;
while (<IN>) {
my ($host, $port) = split /:/, $_;
push(@hosts, inet_aton
($host));
}
$index = -1;
$current_ip = get_asterisk_ip();
logit("updateip started current Asterisk external IP is $current_ip");
while (1) {
sleep($pollinterval); # wait a while between tests
next if ($new_ip = get_public_ip()) eq $current_ip; # if IP has not changed
if (($newer_ip = get_public_ip()) ne $new_ip) { # if a second opinion doesn't match
logit("new ip mismatch $current_ip $new_ip $newer_ip $index");
next;
}
logit("ip change from $current_ip to $new_ip detected");
system("sed -i 's/.*public-ip/$new_ip public-ip/' /etc/hosts"); # update public IP in hosts file
if (($asterisk_ip = get_asterisk_ip()) ne $new_ip) { # asterisk didn't see update
logit("update failed; Asterisk external IP is $asterisk_ip");
}
else {
logit("Asterisk external IP is now $asterisk_ip"); # update successful
$current_ip = $new_ip;
}
}
{"html5":"htmlmixed","css":"css","javascript":"javascript","php":"php","python":"python","ruby":"ruby","lua":"text\/x-lua","bash":"text\/x-sh","go":"go","c":"text\/x-csrc","cpp":"text\/x-c++src","diff":"diff","latex":"stex","sql":"sql","xml":"xml","apl":"apl","asterisk":"asterisk","c_loadrunner":"text\/x-csrc","c_mac":"text\/x-csrc","coffeescript":"text\/x-coffeescript","csharp":"text\/x-csharp","d":"d","ecmascript":"javascript","erlang":"erlang","groovy":"text\/x-groovy","haskell":"text\/x-haskell","haxe":"text\/x-haxe","html4strict":"htmlmixed","java":"text\/x-java","java5":"text\/x-java","jquery":"javascript","mirc":"mirc","mysql":"sql","ocaml":"text\/x-ocaml","pascal":"text\/x-pascal","perl":"perl","perl6":"perl","plsql":"sql","properties":"text\/x-properties","q":"text\/x-q","scala":"scala","scheme":"text\/x-scheme","tcl":"text\/x-tcl","vb":"text\/x-vb","verilog":"text\/x-verilog","yaml":"text\/x-yaml","z80":"text\/x-z80"}