Script to auto update router with changed Gateway IP

Description
Script that tests the Gateway address and tries to renew it if it can't detect it. Can be executed through the Scheduler, set it for example to run with 20 seconds apart.

The script has 4 global variables that can be printed to see the current state of the script:

  1. IPFailure. The number of complete contact failures (not just one ping failure). That is
    that result in a renew command.
  2. IPSuccess. Number of successful connections. If there is no failure this is the same as
    the number of times the scheduler has executed the script.
  3. IPPingFailure. Total number of times a ping of the Gateway has failed. This is just to
    inform that there has bin a failure in one or several of the test pings.
  4. PublicIPCount. A script lock variable. This variable protects the core part of the
    script from other events to access it, that is if there is an ongoing event that runs
    the script already (since I am unfamiliar with how the RouterOS manages multiple threads
    or not I added this just in case. I don't want another process to start messing around
    until the current process is done).

After the script has done it's first execution, these variabales can be through the Terminal located at /system/script/environment and the command print. They will be updated each time the Scheduler runs the script.

General function.
The first thing that is done is to check if another process is running the script. If it is it will skip the core part of the script and instead decrement the PublicIPCount variable. This is done to prevent a deadlock if the first process will fail without resetting the PublicIPCount variable to zero. If no other process is running it will set the PublicIPCount variable to 4 which means that if the Scheduler is set to run every 20 second the current process will have 80 seconds to execute the script before a new event also starts to run the script.

Next part will initialize local variables and fetch the current gateway address.

Next part will loop 5 times or until a successful ping with a delay of 4 seconds between each ping.

Next part will check the outcome of the ping loop and then determine which flag to increment, IPFailure or IPSuccess.

Next part will write the result to the console (here I don't know how :put command reacts then it is executed through the Scheduler. If it is logged? Or if it is just ignored then the script is not executed through the Terminal).

Next part will check the outcome of the ping loop like above and on failure run the renew command (here I am not sure if I should involve the release command or not? Perhaps in a later version use it if the renew command fails).

Final part will reset the PublicIPCount variable so that the next event can access the core part of the script again.

*** SCRIPT PublicIP ***********************************
:global IPFailure;
:global IPSuccess;
:global IPPingFailure;
:global PublicIPCount;

:if ($PublicIPCount <= 0) do={

Lock access for other scheduled events until ongoing process is done.

:set PublicIPCount 4;

:local currentGateway [/ip rout get [find dst-address="0.0.0.0/0"] gateway];
:local i 0;
:local pingState 0;

:do {
:set i ($i + 1);
:set pingState [/ping $currentGateway count=1];
:if ($i < 5 && $pingState = 0) do={ :set IPPingFailure ($IPPingFailure + 1); :delay 4; }
} while= ($i < 5 && $pingState = 0);

:if ($pingState = 0) do={ :set IPFailure ($IPFailure + 1); } else={:set IPSuccess ($IPSuccess + 1); }

:put "Current State: Tries $i State $pingState Total success $IPSuccess Total failure $IPFailure";

If ping failed try to renew the Public IP.

:if ($pingState = 0) do={ [/ip dhcp-client renew 0]; }

Release lock and let other scheduled events run the code

:set PublicIPCount 0;
} else={

In case of execute failure above this countdown prevents deadlock

:set PublicIPCount ($PublicIPCount - 1); }


Please enjoy!