:resolve problems

Hi!

I`m having a problem using this script http://wiki.mikrotik.com/wiki/Use_host_names_in_firewall_rules:

running it from cli results:
/system script> run resolvehostnames
failure: dns name does not exist

And the problem is here, at the end of the script from above:
: if ($newip != $oldip) do={:set newip [:resolve $comment]
/ip firewall address-list set $i address=$newip}
}

Tried running this script both on ROS 5.14 and 5.22. The setup is exactly as in the wiki it must be 100% good. Any ideea?

Check your IP > Firewall > Address Lists. At least one of the hostnames (Comment) can’t be found by your dns server. For example, I changed the comment of the second entry to a hostname that does not exist. The script ran fine on the first entry. The second entry gave the failure: dns name does not exist error, and the script stopped execution.
s.gif

THX… I was giving the script an invlaid hostname in the comment was typing mistake.

Ok now the question is how can I skip an invalid hostname so that the script can continue after the error parsing the whole list ?

One way is to create a second script that contains the :resolve command, and call the second script from the first using the :execute command. Some examples can be found here: http://forum.mikrotik.com/t/dns-update-stop-exection-script/61541/1

One thing to keep in mind is that the :execute command will not wait for the :resolve of the second script to finish before it continues, so you’ll need to add a delay in the first script.

Also, any variables that will be used between the two scripts (probably $comment and $newip) will need to be global and (I think) declared in both. If I have time, I’ll see about posting an example.

Try these 2 scripts. Set the delay below to how long you want to wait before a hostname times out. The name of the first script doesn’t matter, but the name of the second is called from the first, so it must match.

Main script, named whatever:

Delay for X seconds to allow hostname to resolve

:local delay 5

define variables

:global comment
:global newip
:local list
:local oldip

start logging

/log info “[RESOLVE] - START”

Loop through each entry in the address list

:foreach i in=[/ip firewall address-list find] do={

clear newip variable each time

:set newip ""

Get the first five characters of the list name

:set list [:pick [/ip firewall address-list get $i list] 0 5]

If they’re ‘host_’, then we’ve got a match - process it

:if ($list = "host_") do={

Get the comment for this address list item (this is the host name to use)

	:set comment [/ip firewall address-list get $i comment]
	/log info "[RESOLVE] - checking $comment"
	:set oldip [/ip firewall address-list get $i address]
	/log info "[RESOLVE] - old ip: $oldip"
	/log info "[RESOLVE] - calling sub-script"
	:execute script=resolvehostnames-sub

This script does not wait for sub-script to resolve host names, so we need to delay for a time

	:local counter 1
	while ($counter <= $delay) do={
		/log info "[RESOLVE] - waiting for hostname to resolve - attempt $counter"
		:delay 1s

if length of new ip is greater than zero, break out of loop

		:if ([:len $newip] > 0) do={
			:set counter $delay
		}

increment counter

		:set counter ($counter + 1)
	}

if new ip length is greater than zero, an ip was resolved

	:if ([:len $newip] > 0) do={
		/log info "[RESOLVE] - new ip: $newip"

if newip does not equal oldip

		:if ($newip != $oldip) do={
			/log info "[RESOLVE] - ip has changed, updating address list"

Set the address list entry accordingly

			/ip firewall address-list set $i address=$newip
		} else={
			/log info "[RESOLVE] - new ip matches old ip, no change"
		}
	} else={
		/log info "[RESOLVE] - did not get new ip, timed out"
	}
}

}
/log info "[RESOLVE] - END"Sub script, named resolvehostnames-sub# make sure the name of this script matches the one called from the main script (resolvehostnames-sub)
:global comment
:global newip
/log info “[RESOLVE] - trying to resolve $comment from sub-script”
:set newip [:resolve $comment]

Hello skot

Thanks a lot for your script, it had been working great, while I was at v5.25, but a few days back I updated to v6.3 and it stopped updating the addresses, it still is running every 3 minutes, but now it does not update them =(

Guys, any ideas what could change between v5.25 and v6.3? or any way to fix it and make it work again?

Thanks Skot for this excellent script!

The script is working fine for me on v6.3, not sure why it stopped working for you.

First thing I would check is the logs. Look for the [RESOLVE] entries to see if you can find out where the failure is happening. What is the last [RESOLVE] entry that shows up?

For additional testing, you can enclose the entire main script in brackets {}, and then paste it into a terminal window. This may help you to catch any script errors.

This is my version of a resolve script it does ip to host name or host name to ip:


wcsnet, copyright © 2010. all rights reserved

script version : 1.0

:do {

:local content
:local newhost
:local oldhost

:log info “******************** starting - ip resolve ip*******************”
:log info “-”

:foreach i in=[/ip firewall address-list find list=“resolve ip” and disabled=no] do={

:set content [/ip firewall address-list get $i address]
:set oldhost [/ip firewall address-list get $i comment]

:do {
:set newhost [:resolve $content]
} on-error={
:log error “dns resolve failure [ ip - resolve ip ]”
}

: if ($newhost != $oldhost) do={
/ip firewall address-list set $i comment=$newhost
:log warning “$[/system identity get name] $comment dns host name changed: $oldhost → $newhost”
}
}

:log info “******************** ending - ip resolve ip********************”

:exec “o - after script run”

} on-error={
:log error “script failure [ ip - resolve ip ]”
}


:do {

:local content
:local newip
:local oldip

:log info “******************** starting - ip resolve host*******************”
:log info “-”

:foreach i in=[/ip firewall address-list find list=“resolve host” and disabled=no] do={

:set content [/ip firewall address-list get $i comment]
:set oldip [/ip firewall address-list get $i address]

:do {
:set newip [:resolve $content]
} on-error={
:log error “dns resolve failure [ ip - resolve host ]”
}

: if ($newip != $oldip) do={
/ip firewall address-list set $i address=$newip
:log warning “$[/system identity get name] $comment ip address changed: $oldip → $newip”
}
}

:log info “******************** ending - ip resolve host********************”

:exec “o - after script run”

} on-error={
:log error “script failure [ ip - resolve host ]”
}

Hi,

if you used the first code do a little modification and everything will be ok with new Ver of Fw

:execute script=resolvehostnames-sub
to
:execute script=“resolvehostnames-sub”

the original script will be ok with ver 6.31

I hope could be useful for you,
Maxspeed


from this code:
ros code

Delay for X seconds to allow hostname to resolve

:local delay 5

define variables

:global comment
:global newip
:local list
:local oldip

start logging

/log info “[RESOLVE] - START”

Loop through each entry in the address list

:foreach i in=[/ip firewall address-list find] do={

clear newip variable each time

:set newip “”

Get the first five characters of the list name

:set list [:pick [/ip firewall address-list get $i list] 0 5]

If they’re ‘host_’, then we’ve got a match - process it

:if ($list = “host_”) do={

Get the comment for this address list item (this is the host name to use)

:set comment [/ip firewall address-list get $i comment]
/log info “[RESOLVE] - checking $comment”
:set oldip [/ip firewall address-list get $i address]
/log info “[RESOLVE] - old ip: $oldip”
/log info “[RESOLVE] - calling sub-script”
:execute script=resolvehostnames-sub

This script does not wait for sub-script to resolve host names, so we need to delay for a time

:local counter 1
while ($counter <= $delay) do={
/log info “[RESOLVE] - waiting for hostname to resolve - attempt $counter”
:delay 1s

if length of new ip is greater than zero, break out of loop

:if ([:len $newip] > 0) do={
:set counter $delay
}

increment counter

:set counter ($counter + 1)
}

if new ip length is greater than zero, an ip was resolved

:if ([:len $newip] > 0) do={
/log info “[RESOLVE] - new ip: $newip”

if newip does not equal oldip

:if ($newip != $oldip) do={
/log info “[RESOLVE] - ip has changed, updating address list”

Set the address list entry accordingly

/ip firewall address-list set $i address=$newip
} else={
/log info “[RESOLVE] - new ip matches old ip, no change”
}
} else={
/log info “[RESOLVE] - did not get new ip, timed out”
}
}
}
/log info “[RESOLVE] - END”



Sub script, named resolvehostnames-sub
ros code

make sure the name of this script matches the one called from the main script (resolvehostnames-sub)

:global comment
:global newip
/log info “[RESOLVE] - trying to resolve $comment from sub-script”
:set newip [:resolve $comment]