Check utilisation of RouterOS IP Pools

I was looking for a way to do a quick summary of the utilisation of my DHCP/PPP pools and stumbled across a helpful little script.

This was originally found on the MikroTik forums and posted back in 2010 written by dssmiktik, and surprisingly enough it works perfectly on even v6.0 with no changes required.

# List stats for IP -> Pool
#
# criticalthreshold = output pool display in red if pool used is above this %
# warnthreshold = output pool display in gold if pool used is above this %

:local criticalthreshold 85
:local warnthreshold 70

# Internal processing below...
# ----------------------------------
/ip pool {
   :local poolname
   :local pooladdresses
   :local poolused
   :local poolpercent
   :local minaddress
   :local maxaddress
   :local findindex
   :local tmpint
   :local maxindex
   :local line

   :put ("IP Pool Statistics")
   :put ("------------------")

# Iterate through IP Pools
   :foreach p in=[find] do={

      :set poolname [get $p name]
      :set pooladdresses 0
      :set poolused 0
      :set line ""

      :set line ("     " . $poolname)

#   Iterate through current pool's IP ranges
      :foreach r in=[:toarray [get $p range]] do={

#      Get min and max addresses
         :set findindex [:find [:tostr $r] "-"]
         :if ([:len $findindex] > 0) do={
            :set minaddress [:pick [:tostr $r] 0 $findindex]
            :set maxaddress [:pick [:tostr $r] ($findindex + 1) [:len [:tostr $r]]]
         } else={
            :set minaddress [:tostr $r]
            :set maxaddress [:tostr $r]
         }

#       Convert to array of octets (replace '.' with ',')
         :for x from=0 to=([:len [:tostr $minaddress]] - 1) do={
            :if ([:pick [:tostr $minaddress] $x ($x + 1)] = ".") do={
               :set minaddress ([:pick [:tostr $minaddress] 0 $x] . "," . \
                                       [:pick [:tostr $minaddress] ($x + 1) [:len [:tostr $minaddress]]]) }
         }
         :for x from=0 to=([:len [:tostr $maxaddress]] - 1) do={
            :if ([:pick [:tostr $maxaddress] $x ($x + 1)] = ".") do={
               :set maxaddress ([:pick [:tostr $maxaddress] 0 $x] . "," . \
                                       [:pick [:tostr $maxaddress] ($x + 1) [:len [:tostr $maxaddress]]]) }
         }

#      Calculate available addresses for current range
         :if ([:len [:toarray $minaddress]] = [:len [:toarray $maxaddress]]) do={
            :set maxindex ([:len [:toarray $minaddress]] - 1)
            :for x from=$maxindex to=0 step=-1 do={
#             Calculate 256^($maxindex - $x)
               :set tmpint 1
               :if (($maxindex - $x) > 0) do={
                  :for y from=1 to=($maxindex - $x) do={ :set tmpint (256 * $tmpint) }
               }
               :set tmpint ($tmpint * ([:tonum [:pick [:toarray $maxaddress] $x]] - \
                                                    [:tonum [:pick [:toarray $minaddress] $x]]) )
               :set pooladdresses ($pooladdresses + $tmpint)
#         for x
            }

#      if len array $minaddress = $maxaddress
         }

#      Add current range to total pool's available addresses
         :set pooladdresses ($pooladdresses + 1)

#   foreach r
      }

#   Now, we have the available address for all ranges in this pool
#   Get the number of used addresses for this pool
      :set poolused [:len [used find pool=[:tostr $poolname]]]
      :set poolpercent (($poolused * 100) / $pooladdresses)

#   Output information
      :set line ([:tostr $line] . "  [" . $poolused . "/" . $pooladdresses . "]")
      :set line ([:tostr $line] . "  " . $poolpercent . " % used")

#   Set colored display for used thresholds
      :if ( [:tonum $poolpercent] > $criticalthreshold ) do={
         :log error ("IP Pool " . $poolname . " is " . $poolpercent . "% full")
         :put ([:terminal style varname] . $line)
      } else={
         :if ( [:tonum $poolpercent] > $warnthreshold ) do={
            :log warning ("IP Pool " . $poolname . " is " . $poolpercent . "% full")
            :put ([:terminal style syntax-meta] . $line)
         } else={
            :put ([:terminal style none] . $line)
         }
      }

# foreach p
   }
# /ip pool
}

The output generated looks something like this:

[read@Test] > system script run check-pool
IP Pool Statistics
------------------
New [169/1013] 16 % used
Col [425/1013] 41 % used
CC [0/245] 0 % used
Wireless Controller [396/1013] 39 % used
ppp-default [0/1] 0 % used
ppp-restricted [0/1] 0 % used
J-NEW [153/501] 30 % used
NS Primary [300/1013] 29 % used
NS Backup [0/244] 0 % used

For those of you who might use the Cool Console script I posted a few months ago, this could make an excellent addition to the stats displayed.

Advertisement

5 thoughts on “Check utilisation of RouterOS IP Pools

  1. This have a bug on RouterOS 6.12

    IP Pool Statistics
    ——————
    pool1 [1050/254] 413 % used
    pool99 [0/254] 0 % used
    pool2 [0/254] 0 % used
    pool3 [0/254] 0 % used
    pool4 [0/254] 0 % used
    pool5 [0/126] 0 % used

  2. Cool script. Thanks! I cant believe this information cant be found in the web GUI. This is certainly better than counting the IP’s in use.

  3. This does not work right for DHCP pools with next pool set.
    Advance_Extention uses Advance_Extension_2 as it next pool.

    IP Pool Statistics
    ——————
    Advance_AP1 [26/61] 42 % used
    Advance_AP2 [37/61] 60 % used
    Advance_AP3 [28/61] 45 % used
    Advance_AP4 [13/61] 21 % used
    Jamestown_AP1 [24/29] 82 % used
    Advance_Extention [69/61] 113 % used
    Advance_Extension_2 [0/29] 0 % used

    How would I go about fixing this script for this usage.

  4. Hi Andrew,

    First of all, Apologies – I’m a long time MT user but never really got into the scripting side of things so my question is most likely completely ‘noobish’.

    I was wondering if there would be a way to change this script so that it would email an alert if a pool was almost exhausted or exhausted already so that we can be proactive on this rather than reacting when a customer rings up in a puff saying something along the lines of ‘My wifi isn’t working’.

    Regards,

    Charlie.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.