updateip.pl

From Stewart1, 6 Months ago, written in Perl, viewed 3 times.
URL https://pastebin.freepbx.org/view/e000c644 Embed
Download Paste or View Raw
  1. #!/usr/bin/perl -w
  2.  
  3. use IO::Select;
  4. use IO::Socket;
  5.  
  6. $pollinterval = 10;             # interval in seconds to check for public IP change
  7.  
  8. $dgs = new IO::Socket::INET(Proto => 'udp') or die "Socket: $!\n";
  9. $sel = new IO::Select($dgs);
  10.  
  11. sub get_public_ip {             # get current public IP from STUN server
  12.     my $tid = 0;
  13.     while (1) {
  14.         $index = 0 if ++$index > $#hosts;
  15.         my $destpaddr = sockaddr_in($ports[$index], $hosts[$index]);
  16.         my $obuf = pack("n n N N N N", 1, 0, 0, 0, 0xdeadbeef, ++$tid);
  17.         $dgs->send($obuf, 0, $destpaddr); # send STUN binding request
  18.         my $pubip = '';
  19.         while ($sel->can_read(1)) {     # wait for reply
  20.             if ($dgs->recv($ibuf, 100, 0)) {
  21.                 next unless $ibuf && length($ibuf) >= 32;
  22.                 my ($type, $tid1, $tid2, $attr, $packed) = unpack("n x10 N N n x6 a4", $ibuf);
  23.                 next unless $type == 0x0101 && $tid1 == 0xdeadbeef && $tid2 == $tid && $attr == 0x0001;
  24.                 $pubip = inet_ntoa($packed);
  25.                 last;
  26.             }
  27.         }
  28.         return $pubip if $pubip;
  29.     }
  30. }
  31.  
  32. sub logit {
  33.     (my $msg) = @_;
  34.     print LOG scalar(localtime), " $msg\n";
  35. }
  36.  
  37. sub get_asterisk_ip {           # get IP address being used by Asterisk chan_sip
  38.     open(PIPE, "asterisk -x 'sip show settings' |") or return '';
  39.     my $asterisk_ip = '';
  40.     while(<PIPE>) {
  41.         $asterisk_ip = $1 if /Externaddr: +([\d\.]+)/;
  42.     }
  43.     close(PIPE);
  44.     return $asterisk_ip;
  45. }
  46.  
  47. open(LOG, ">>updateip.log") or die;
  48. select(LOG); $| = 1; select(STDOUT);
  49.  
  50. open(IN, "stunlist.txt") or die;
  51. while (<IN>) {
  52.     chomp;
  53.     my ($host, $port) = split /:/, $_;
  54.     push(@hosts, inet_aton($host));
  55.     push(@ports, $port);
  56. }
  57.  
  58. $index = -1;
  59.  
  60. $current_ip = get_asterisk_ip();
  61. logit("updateip started current Asterisk external IP is $current_ip");
  62. while (1) {
  63.     sleep($pollinterval);                           # wait a while between tests
  64.     next if ($new_ip = get_public_ip()) eq $current_ip; # if IP has not changed
  65.     if (($newer_ip = get_public_ip()) ne $new_ip) { # if a second opinion doesn't match
  66.         logit("new ip mismatch $current_ip $new_ip $newer_ip $index");
  67.         next;
  68.     }
  69.     logit("ip change from $current_ip to $new_ip detected");
  70.     system("sed -i 's/.*public-ip/$new_ip public-ip/' /etc/hosts"); # update public IP in hosts file
  71.     sleep(30);
  72.     if (($asterisk_ip = get_asterisk_ip()) ne $new_ip) { # asterisk didn't see update
  73.         logit("update failed; Asterisk external IP is $asterisk_ip");
  74.     }
  75.     else {
  76.         logit("Asterisk external IP is now $asterisk_ip"); # update successful
  77.     }
  78.     $current_ip = $new_ip;
  79. }
  80.  

Replies to updateip.pl rss

Title Name Language When
updateip.pl Stewart1 perl 6 Months ago.

Reply to "updateip.pl"

Here you can reply to the paste above