#!/usr/bin/perl =head1 NAME reboot-zyxel - reboot a Zyxel P-660RU DSL modem/router =head1 SYNOPSIS [edit script to set $ROUTER_IP and $ADMIN_PASSWORD] reboot-zyxel =head1 DESCRIPTION Reboots a Zyxel P-660RU ADSL2+ "ethernet/USB router" -- ie. one of these: http://www.zyxel.com/web/product_family_detail.php?PC1indexflag=20040812093058&CategoryGroupNo=F9619EE6-1FB3-48FB-B68E-7773E95FF97F It's cheap and nasty, and it's what ESAT/BT deliver to customers as their ADSL router. It offers an *interesting* javascript-based web UI, and this script contains enough reverse-engineered smarts to reboot the router using that. It'll cause the router to reboot, then wait for the connection to return up to a maximum of 3 minutes. If the reboot and reconnection is successful, it'll exit with a status of 0; otherwise, exit status will be non-0. =cut my $ROUTER_IP = '10.18.72.1'; # your router's IP address on the LAN, here my $ADMIN_PASSWORD = 'password'; # your router's password here # --------------------------------------------------------------------------- use Digest::MD5 qw(md5_hex); my $pwdmd5 = md5_hex($ADMIN_PASSWORD); my $url_login = "http://$ROUTER_IP/Forms/rpAuth_1?". "hiddenPassword=$pwdmd5&LoginPassword=ZyXEL+ZyWALL+Series"; my $url_reset = "http://$ROUTER_IP/Forms/DiagGeneral_2?IsReset=1"; print "Logging in...\n"; system ("curl -s '$url_login'") and die "curl $url_login failed"; print "Rebooting...\n"; # hit the reset URL. this will immediately trigger a reset without closing the # connection (duh!), so kill the local "curl" process once we do it my $resetpid = fork(); if ($resetpid == 0) { exec("curl -s '$url_reset'"); die; } sleep 5; kill 15, $resetpid; kill 9, $resetpid; # wait for reboot to complete and line to reenable print "Waiting for reconnection...\n"; my $start = time; for ($retry = 0; $retry < 180; $retry++) { my $gotit; open (IN, "ping -c 1 4.2.2.1 |"); while () { if (/bytes from 4.2.2.1: /) { $gotit = 1; } } close IN; if ($gotit) { my $secs = time - $start; print "Rebooted and reconnected after $secs seconds\n"; exit; } sleep 1; } die "timed out before we got a ping reply!\n";