This is my near the first Mikrotik script, so don't hesitate to comment.
Code: Select all
:global ipcalc do={
#
# GL(c), 2016
#
:local pOpt $1
:local pIpaddr $2
:local pNetmask $3
:if ([:len $pOpt] = 0) do={
:error "ipcalc usage:\n\r \$ipcalc [-m|-p|-n|-b] ipaddr[/prefix] [netmask]"
:return
}
:local lIpaddr
:local lPrefix
:local pos [:find $pIpaddr "/"]
:if ($pos >= 0) do={
:set lIpaddr [:toip [:pick $pIpaddr 0 $pos]]
:set lPrefix [:tonum [:pick $pIpaddr ($pos + 1) [:len $pIpaddr]]]
} else={
:set lIpaddr [:toip $pIpaddr]
}
:if ((([:len $lPrefix] > 0) && ("$lIpaddr/$lPrefix" != $pIpaddr)) || \
(([:len $lPrefix] = 0) && ("$lIpaddr" != $pIpaddr)) || \
([:len $lIpaddr] = 0)) do={
:error "ipcalc failed: invalid ip address: $pIpaddr"
}
:local lNetmask [:toip $pNetmask]
:if (([:len $pNetmask] != 0) && ($lNetmask != $pNetmask)) do={
:error "ipcalc failed: invalid netmask: $pNetmask"
}
# specified netmask always has precedence over prefix
:if ([:len $lNetmask] > 0) do={
:set lPrefix 0
:while (($lPrefix < 32) && (($lNetmask<<$lPrefix) != 0.0.0.0)) do={
:set lPrefix ($lPrefix + 1)
}
} else={
:if ([:len $lPrefix] = 0) do={
:local bits [:tonum [:pick $lIpaddr 0 [:find $lIpaddr "."]]]
:if (($bits & 128) = 0) do={
:set lPrefix 8
}
:if (($bits & 192) = 128) do={
:set lPrefix 16
}
:if (($bits & 192) = 192) do={
:set lPrefix 24
}
}
:set lNetmask (255.255.255.255<<(32-$lPrefix))
}
:if ($pOpt = "-m") do={ :return $lNetmask }
:if ($pOpt = "-p") do={ :return $lPrefix }
:if ($pOpt = "-n") do={ :return ($lIpaddr & $lNetmask) }
:if ($pOpt = "-b") do={ :return (($lIpaddr & $lNetmask) | (~$lNetmask)) }
:error "ipcalc failed: unknown option: $pOpt"
}