Internet Connectivity Monitor Script requierd [SOLVED]

Currently I am using Internet monitoring script (actually NETWATCH) which check Google Dns IP 8.8.8.8 and if receive no ping reply , it switches to my backup link by changing route distance. working fine.

But the issue is that sometime Google DNS ping timeout dueto my ISP issue and rest of internet works fine , but the netwatch consider it down (dueto single host checkup)

So how can I add at least 2 to 3 multiple hosts and if the script dont receive reply from all of them , then it should take action (like route change or whatever i want)

HELP please :frowning:

use 3 global variables on 3 netwatch different address, and when all 3 variables are set, change the route…

I think I will not be able to understand the script coding :smiley: as i m really dumb in this section.
I will be really thankful to you if you post an example code , Plzzz

HELP Please :frowning:

Hi cicserver, instead of the inbuilt watchdog I am using a simple script which ping an IP address 5 times not just once and just after all 5 failed attempts it performs an action ( this can be adjusted to less than 5 ) . Hope this might help :

       :local i 0;
       :local F 0;
       :local date;
       :local time;
       
       :global InternetStatus;
       :global InternetLastChange;
       
       :for i from=1 to=5 do={
       \tif ([/ping 8.8.8.8 count=1]=0) do={:set F ($F + 1)}
       \t:delay 1;
       };
       \t\t\t\t
       :if (($F=5)) do={
       \t:if (($InternetStatus="UP")) do={
       \t\t:log info "WARNING : The INTERNET service's gone DOWN";
       \t\t:set InternetStatus "DOWN";
       
       ##do some action if needed    
 
       \t\t:set date [/system clock get date];
       \t\t:set time [/system clock get time];
       \t\t:set InternetLastChange ($time . " " . $date);
       \t\t\t\t
       \t} else={:set InternetStatus "DOWN";}
       } else={
       \t:if (($InternetStatus="DOWN")) do={\t
       \t\t:log info "WARNING : The INTERNET service's gone UP"; 
       \t\t:set InternetStatus "UP";
       
       ##do some action if needed
           
       \t\t:set date [/system clock get date];
       \t\t:set time [/system clock get time];
       \t\t:set InternetLastChange ($time . " " . $date);
       \t\t\t\t
       \t} else={:set InternetStatus "UP";}

The syntax

:set variablename valueofthevariable

ARE WRONG,

must be

:set $variablename value=valueofthevariable;


:set not define new variable, like :local or :global, it use already defined variable, and $ must be put before variable name.

Actually it’s working for compatibility, but in future version the support for wrong syntax can be removed.

Thanks for the correction. Unfortunately there are not many resources about mikrotik scripting language.

Right…

While both syntaxes work indeed, I must say that it seems the syntax you call "right" is actually violating normal mode of expression interpolating... making me hope the "right" syntax would be removed in favor of the "wrong" syntax.

Instead, one would expect that the "right" syntax would eventually be used for variable variables, so that for example:
:local varname oldValue
:local newvar varname

EXPECTED:

Because the value of $newvar is "varname",

set the variable called "varname" to the value "newValue".

:set $newvar newValue

ACTUAL:

Sets the variable "newvar" to the value "newValue",

and keeps "varname" unmodified.

:put $varname
:put $newvarwould output

newValue
varname

as opposed to the current

oldValue
newValue

It’s perfect logical what you obtain from:

:local varname > value=> oldValue> ;
→ create new variable called varname and set it’s value to string “oldValue”

:local newvar > value=> varname> ;
→ create new variable called newvar and set it’s value to string “varname”

:set $newvar > value=> newValue> ;
→ now set newvar variable content to string “newValue”

:put $varname
→ varname containing “oldValue” and correctly display “oldValue”

:put $newvar
→ newvar containing “newValue” and correctly display “newValue”

if you use correct syntax you obtain the same:

:local varname > value=> oldValue> ;
→ create new variable called varname and set it’s value to string “oldValue”

:local newvar > value=> $> varname> ;
→ create new variable called newvar and set it’s value equal to variable varname

:set $newvar > value=> newValue> ;
→ now set newvar variable content to string “newValue”

:put $varname
→ varname containing “oldValue” and correctly display “oldValue”

:put $newvar
→ newvar containing “newValue” and correctly display “newValue”

How you think to obtain
newValue
varname
as output of the two “:put”?

That variable are two distinct variables, if you need only one, use one.
The “pointer” type of variable do not exist on that scripting language.

And about share same value because one variable is previous set as another variable, I think is the worst way of programming code, without explicit use of pointer.

Yes, I got that. They indeed obtain the same in current versions.

I’m just saying that I don’t think the so called “right” syntax makes sense.

:set $newvar > value=> newValue> ;
→ now set newvar variable content to string “newValue”

But see… THAT doesn’t make sense… With all other commands, the normal process of interpretation is for
[command] ([unnamed parameter VALUE])* ([named parameter]=[value of named parameter])*
to become
[command] [unnamed parameter]=[value of unnamed parameter] [named parameter]=[value of named parameter]

So for example, in the code

:local interface LAN
/interface monitor-traffic $interface

the later command is interpolated to

/interface monitor-traffic interface="LAN"

and this is true even for the “local” and “global” commands, i.e.

:local varB $interface

is interpolated to

/local name="varB" value="LAN"

But with “set”… no… that normal flow is broken, and instead of

:set $varB $interface

being interpolated to

/set name="LAN" value="LAN"

it’s suddenly

/set name="varB" value="LAN"

completely flying in the face of how any other command would deal with variables.

The “pointer” type of variable do not exist on that scripting language.

Neither does it exist in PHP… “variable variables” and “pointers” are two distinct features of a language, and in fact, PHP has the former - see here… In the case of PHP, there’s a different syntax required, which can make code confusing, but in RouterOS’ scripting language, it’s the lack of a different syntax that seems to make things more confusing.

And about share same value because one variable is previous set as another variable, I think is the worst way of programming code, without explicit use of pointer.

I’ll agree that “variable variables” aren’t in general a good programming practice, and I for one avoid them in PHP, and would probably avoid them in RouterOS scripting too. But just like any programming tool, they should be available for use if needed, which would arguably be more often in RouterOS scripting that in PHP.

Now I catch your point…

Like

:set $varB $interface → :set [u]eval/u $interface

eval is a function to “evaluate” code :wink:

But if you try to use “/set name=” you get one error:
[admin@MATRIX] > /set value=k name=x
syntax error (line 1 column 19)
[admin@MATRIX] > /set value=k name=$x
[admin@MATRIX] >because also “/set name=” want as argument one variable, defined or not.

(The code are from RouterOS 6.14)

But I hope you agree with me:

MikroTik must extend read/write support from/to file to more than 4096 Bytes.
Missing float numbers.
toarray function: must be passed as parameter what I want to split to array, not only “,”
make possible to save function output, like “ping”

Surely I forget others…

Have to agree with boen_robot

Lolz everyone have forgotten the real question asked by me in this thread, and started there conversation :stuck_out_tongue:

Can any one please post a script which can check at least two or three wan hosts, and if found all of three dead, then its should change the route distance (or whatever action I would like it to take) and then if any single WAN host replies back , then it should change the distance back to normal.

Man, try to read the reply after your previous post !

Dear mainTAP,

I am really grateful to you for the script. It’s working fine, But the issue is that it checks only single / one HOST. I want to check at least 2 hosts for cross verification. Is it possible to add? how?

One question more, How many times does Mikrotik’s NETWATCH pings the host before considering it UP or DOWN? one time or ??

Thank you for user friendly script post. :smiley:

You are welcome, to add more hosts would be easy, how many would you like to check for how many repeats? Do you want to consider the link down only if all the attempts fail?

As for the netwach functionality, i believe it pings just once and makes its decision upon the outcome.

Ping at least 2 Hosts, and 5 times ping count. If it donot receive all ping replies from both hosts, then its should consider the link DOWN. but if any single host is reachable, then the link should be considered UP.

Thank you for being kind :smiley: :slight_smile:

I’ll post the script in couple of hours when I get to a PC :wink: