colinardo
Goto Top

Mikrotik Scripting: Resolve Domain to IPv6 Address

Hello Mikrotik users.

Unfortunately Mikrotik does not provide an explicit function for resolving DNS names to IPv6 addresses. The :resolve function only returns a single IPv4 address when both v4 and v6 addresses exist for this domain, which you can see with this terminal command
:put [:resolve dns.google.com]
But if you need to get the IPv6 counterpart you can do this with a trick by using a temporary IPv6 firewall address list.
You could have used web services and external APIs and make an http call using /tool fetch on the device, but I wanted solve this without using external services.

As a result, I wrote an easy to use global function for the problem:


back-to-topFunction "$resolveipv6"

# define global function to resolve IPv6 DNS Names to IPs
:global resolveipv6 do={
    :local result [:toarray ""]      
    :local maxwait 5
    :local cnt 0
    :local listname "tmp-resolve$cnt"  
    /ipv6 firewall address-list {
        :do {
            :while ([:len [find list=$listname]] > 0) do={
                :set cnt ($cnt + 1)
                :set listname "tmp-resolve$cnt"  
            }
            :set cnt 0
            add list=$listname address=$1
            :while ([find list=$listname && dynamic] = "" && $cnt < $maxwait) do={:delay 1;:set cnt ($cnt +1)}  
            :foreach i in=[find list=$listname && dynamic] do={
                 :local rawip [get $i address]
                 :set result ($result, [:pick $rawip 0 [:find $rawip "/"]])  
            }
            remove [find list=$listname && !dynamic]
        }
     }
    :return $result
}

The function, once called in a script, can be used like this in scripts or on the console:

back-to-topOutput of addresses on the console (returns an array if there are multiple addresses)

:put [$resolveipv6 "dns.google.com"]  
Results in an array of two addresses
2001:4860:4860::8844;2001:4860:4860::8888

back-to-topStore result in a variable and retrieve individual addresses via index

:local myvar [$resolveipv6 "dns.google.com"]  
# get first address of result
:put [:pick $myvar 0]
# get second address of result
:put [:pick $myvar 1]

Important note: If you put the function in a startup script it will be available in all scripts and the console as soon as you declare it once by this call:
:global resolveipv6
Maybe this is helpful for someone until Mikrotik itself provides an IPv6 capable resolve variant.

Greetings and all the best for the new year.
@colinardo

Content-ID: 5151910821

Url: https://administrator.de/contentid/5151910821

Printed on: October 11, 2024 at 02:10 o'clock

colinardo
colinardo Mar 04, 2024 updated at 11:25:27 (UTC)
Goto Top

back-to-topUpdate 04.03.2024:


The current RouterOS Version 7.15beta4 (2024-Mar-04 08:04) started introducing the type parameter to specify which address type (IPv4|IPv6|any) should be resolved.

*) console - added "type" parameter to ":resolve" command;

Example:
:put [:resolve type=ipv6 dns.google.com]