Community discussions

MikroTik App
 
steve1
just joined
Topic Author
Posts: 5
Joined: Sat Jan 28, 2023 2:58 pm

DNS script not normalizing characters of a particular host

Thu Jan 25, 2024 12:37 pm

Hi,

I found a DHCP > DNS script that looks for hostnames or lease comments and replaces characters outside of a-z, A-Z and 0-9 with a hyphen when creating a static dns entry.

I have 28 hosts, and some do not have a hostname. I can add a DHCP lease comment for those missing a hostname, and this script will read and normalise the comment to make a static DNS entry.

If a hostname exists, the script will only read that, and the comment is ignored.

My Meross smart plug is using ASCIII characters for spaces for its hostname, and the script does not seem to pick them up. Or is the script only normalising the DHCP lease comments, not hostnames? I do not believe I have DHCP entries with hostnames that need normalising, so I can only confirm that the script is normalising lease comments.

The Meross smart plug appears as "192.168.1.8: Meross\032Smart\032Plug.home.arpa" to my Pi-hole server, and the Mikrotik Static DNS entry appears as "Meross Smart Plug.home.arpa"

Everything else is normalised perfectly, with Hyphens for any characters not being "a-z, A-Z and 0-9".

How can I change the script to recognise the ASCIII spaces as disallowed?

Thanks
:local DHCPtag
:set DHCPtag "DHCP2DNS"

:if ( [ :len $leaseActIP ] <= 0 ) do={ :error "empty lease address" }

:if ( $leaseBound = 1 ) do=\
{
  :local ttl
  :local domain
  :local hostname
  :local fqdn
  :local leaseId
  :local comment

# Normalize hostname (e.g. "-= My Phone =-" -> "My-Phone")
# - truncate length to 63 chars
# - substitute disallowed chars with a hyphen
# param: name
:local normalizeHostname do={
  :local result;
  :local isInvalidChar true;
  :for i from=0 to=([:len $name]-1) do={
    :local char [:pick $name $i];
    :if ($i < 63) do={
      :if ($char~"[a-zA-Z0-9]") do={
        :set result ($result . $char);
        :set isInvalidChar false;
      } else={
        :if (!$isInvalidChar) do={
          :set result ($result . "-");
          :set isInvalidChar true;
        };
      };
    };
  };

  # delete trailing hyphen
  :if ($isInvalidChar) do={
    :set result [:pick $result 0 ([:len $result]-1)];
  }
  :return $result;
};

  /ip dhcp-server
  :set ttl [ get [ find name=$leaseServerName ] lease-time ]
  network 
  :set domain [ get [ find $leaseActIP in address ] domain ]
  
  .. lease
  :set leaseId [ find address=$leaseActIP ]

# Check for multiple active leases for the same IP address. It's weird and it shouldn't be, but just in case.

  :if ( [ :len $leaseId ] != 1) do=\
  {
   :log info "DHCP2DNS: not registering domain name for address $leaseActIP because of multiple active leases for $leaseActIP"
   :error "multiple active leases for $leaseActIP"
  }  

  :set hostname [ get $leaseId host-name ]
  :set comment [ get $leaseId comment ]
  /

  :if ( [ :len $hostname ] <= 0 ) do={ :set hostname [$normalizeHostname name=$comment] }

  :if ( [ :len $hostname ] <= 0 ) do=\
  {
    :log error "DHCP2DNS: not registering domain name for address $leaseActIP because of empty lease host-name or comment"
    :error "empty lease host-name or comment"
  }
  :if ( [ :len $domain ] <= 0 ) do=\
  {
    :log error "DHCP2DNS: not registering domain name for address $leaseActIP because of empty network domain name"
    :error "empty network domain name"
  }

  :set fqdn "$hostname.$domain"
  
  /ip dns static
  :if ( [ :len [ find name=$fqdn and address=$leaseActIP and disabled=no ] ] = 0 ) do=\
  {
    :log info "DHCP2DNS: registering static domain name $fqdn for address $leaseActIP with ttl $ttl"
    add address=$leaseActIP name=$fqdn ttl=$ttl comment=$DHCPtag disabled=no
  } else=\
  {
    :log error "DHCP2DNS: not registering domain name $fqdn for address $leaseActIP because of existing active static DNS entry with this name or address" 
  }
  /
} \
else=\
{
  /ip dns static
  :local dnsDhcpId 
  :set dnsDhcpId [ find address=$leaseActIP and comment=$DHCPtag ]

  :if ( [ :len $dnsDhcpId ] > 0 ) do=\
  {
    :log info "DHCP2DNS: removing static domain name(s) for address $leaseActIP"
    remove $dnsDhcpId
  }
  /
}
Last edited by steve1 on Fri Jan 26, 2024 4:26 am, edited 1 time in total.
 
steve1
just joined
Topic Author
Posts: 5
Joined: Sat Jan 28, 2023 2:58 pm

Re: DNS script not normalizing characters of a particular host

Fri Jan 26, 2024 4:07 am

Yay, I figured it out.

The script was only normalizing DHCP comments, and all of my other hosts had hostnames that did not need normalizing.

So, the solution was to add a single line:
  :set hostname [$normalizeHostname name=$hostname]
Added below:
  :set hostname [ get $leaseId host-name ]
  :set comment [ get $leaseId comment ]
  /
This meant that the hostname was normalized before being set:
  :set fqdn "$hostname.$domain"
Thus resulting in a normalised hostname used to add a static dns entry:
  /ip dns static
  
  :if ( [ :len [ find name=$fqdn and address=$leaseActIP and disabled=no ] ] = 0 ) do=\
  {
    :log info "DHCP2DNS: registering static domain name $fqdn for address $leaseActIP with ttl $ttl"
    add address=$leaseActIP name=$fqdn ttl=$ttl comment=$DHCPtag disabled=no
Here's the entire script:
:local DHCPtag
:set DHCPtag "DHCP2DNS"

:if ( [ :len $leaseActIP ] <= 0 ) do={ :error "empty lease address" }

:if ( $leaseBound = 1 ) do=\
{
  :local ttl
  :local domain
  :local hostname
  :local fqdn
  :local leaseId
  :local comment

# Normalize hostname (e.g. "-= My Phone =-" -> "My-Phone")
# - truncate length to 63 chars
# - substitute disallowed chars with a hyphen
# param: name
:local normalizeHostname do={
  :local result;
  :local isInvalidChar true;
  :for i from=0 to=([:len $name]-1) do={
    :local char [:pick $name $i];
    :if ($i < 63) do={
      :if ($char~"[a-zA-Z0-9]") do={
        :set result ($result . $char);
        :set isInvalidChar false;
      } else={
        :if (!$isInvalidChar) do={
          :set result ($result . "-");
          :set isInvalidChar true;
        };
      };
    };
  };

  # delete trailing hyphen
  :if ($isInvalidChar) do={
    :set result [:pick $result 0 ([:len $result]-1)];
  }
  :return $result;
};

  /ip dhcp-server
  :set ttl [ get [ find name=$leaseServerName ] lease-time ]
  network 
  :set domain [ get [ find $leaseActIP in address ] domain ]
  
  .. lease
  :set leaseId [ find address=$leaseActIP ]

# Check for multiple active leases for the same IP address. It's weird and it shouldn't be, but just in case.

  :if ( [ :len $leaseId ] != 1) do=\
  {
   :log info "DHCP2DNS: not registering domain name for address $leaseActIP because of multiple active leases for $leaseActIP"
   :error "multiple active leases for $leaseActIP"
  }  

  :set hostname [ get $leaseId host-name ]
  :set comment [ get $leaseId comment ]
  /

  :set hostname [$normalizeHostname name=$hostname]

  :if ( [ :len $hostname ] <= 0 ) do={ :set hostname [$normalizeHostname name=$comment] }

  :if ( [ :len $hostname ] <= 0 ) do=\
  {
    :log error "DHCP2DNS: not registering domain name for address $leaseActIP because of empty lease host-name or comment"
    :error "empty lease host-name or comment"
  }
  :if ( [ :len $domain ] <= 0 ) do=\
  {
    :log error "DHCP2DNS: not registering domain name for address $leaseActIP because of empty network domain name"
    :error "empty network domain name"
  }

  :set fqdn "$hostname.$domain"
  
  /ip dns static
  
  :if ( [ :len [ find name=$fqdn and address=$leaseActIP and disabled=no ] ] = 0 ) do=\
  {
    :log info "DHCP2DNS: registering static domain name $fqdn for address $leaseActIP with ttl $ttl"
    add address=$leaseActIP name=$fqdn ttl=$ttl comment=$DHCPtag disabled=no
  } else=\
  {
    :log error "DHCP2DNS: not registering domain name $fqdn for address $leaseActIP because of existing active static DNS entry with this name or address" 
  }
  /
} \

else=\
{
  /ip dns static
  :local dnsDhcpId 
  :set dnsDhcpId [ find address=$leaseActIP and comment=$DHCPtag ]

  :if ( [ :len $dnsDhcpId ] > 0 ) do=\
  {
    :log info "DHCP2DNS: removing static domain name(s) for address $leaseActIP"
    remove $dnsDhcpId
  }
  /
}

Who is online

Users browsing this forum: Maximus888 and 7 guests