Function: IP to Decimal

Since calculating with IP are not simple, I made a function that converts IP to decimal value

Cut and past this to cli and it will create the function IPtoDec

[
:global IPtoDec do={
    local count 16777216
	local sum
	:if ([:typeof [:toip $1]] != "ip") do={
		:error message="You did not specify any VALID IP Address."}
	:local workString value=[:tostr [:toip $1]]
	:local endString value=""
	:local thisChar value=""
	:for i from=0 to=[:len $workString] step=1 do={
		:set $thisChar value=[:pick $workString $i ($i+1)]
		:if ($thisChar = ".") do={
			:set $thisChar value=","}
		:set $endString value=($endString.$thisChar)
	}
	:local resultArray value=[:toarray $endString]
	:foreach i in=$resultArray do={
		:set sum ($i * $count + $sum)
		:set count ($count / 256)
	}
	:return value=$sum
}
]

Test script to use the function:

[
:local IP 192.168.88.1
:local test [$IPtoDec $IP]
:put $test
]
3232258049

Function is partly based on this post: http://forum.mikrotik.com/t/return-ip-octet-function/77321/1
So som cred to @royalpublishing

Since RouterOS does not store Global Value (Environmental variables) with a reboot, I did make a fix for that.


Copy and past these two codes to cli. Reboot or run script Restore_Functions manually to get the IPtoDec function back.

Script to restore functions b]Restore_Functions[/b] :

/system script add dont-require-permissions=no name=Restore_Functions owner=admin policy=read,write,policy,test source=":global IPtoDec do={\r\
    \n    local count 16777216\r\
    \n\tlocal sum\r\
    \n\t:if ([:typeof [:toip \$1]] != \"ip\") do={\r\
    \n\t\t:error message=\"You did not specify any VALID IP Address.\"}\r\
    \n\t:local workString value=[:tostr [:toip \$1]]\r\
    \n\t:local endString value=\"\"\r\
    \n\t:local thisChar value=\"\"\r\
    \n\t:for i from=0 to=[:len \$workString] step=1 do={\r\
    \n\t\t:set \$thisChar value=[:pick \$workString \$i (\$i+1)]\r\
    \n\t\t:if (\$thisChar = \".\") do={\r\
    \n\t\t\t:set \$thisChar value=\",\"}\r\
    \n\t\t:set \$endString value=(\$endString.\$thisChar)\r\
    \n\t}\r\
    \n\t:local resultArray value=[:toarray \$endString]\r\
    \n\t:foreach i in=\$resultArray do={\r\
    \n\t\t:set sum (\$i * \$count + \$sum)\r\
    \n\t\t:set count (\$count / 256)\r\
    \n\t}\r\
    \n\t:return value=\$sum\r\
    \n}\r\
    \n"

Scheduler that run the script Restore_Functions at boot.

/system scheduler add name=Boot_script on-event=Restore_Functions policy=read,write,policy,test start-time=startup

Actually calculating with ip addresses is easy:
Manual:Scripting / Bitwise Operators

Do you need anything more?

(Sadly this does not work with ipv6 addresses. :frowning: Mikrotik, please implement!)

Interesting.

Can you show me how to use this to calculate how many IP there are from 192.168.88.45 to 192.168.89.254?

Whit IPtoDec that would be 3232258558-3232258093=465

:put ([$IPtoDec 192.168.89.254] - [$IPtoDec 192.168.88.45])
465

Hmm

For math, you do not need this function. Found out that this works fine.

:put (192.168.89.254 - 192.168.88.45)
465



:put (192.168.89.254 + 10)
192.168.90.8

Anyone know how to do arithmetic with ipv6?

e.g. :put (fe80::0 + 8) = fe80::8

Rich

He is aking for RouterOS script, not Java.

Ps use code tag when you post codes. Select edit and selct your code and click the </> button to get some like this:

My code

Does it help in your use case if you use bitwise operator?

[admin@MikroTik] > :put (fe80::0 | ::8) 
fe80::8

For this I do get:

 :put (fe80::0 | ::8) 
Script Error: cannot compute bitwise "or" of internal number and internal number

For me it works. Do you have IPv6 disabled (or not installed at all)?

:blush: :blush: :blush:

Did forget that on my test router did not have ipv6 :slight_smile:
Works now.