I need some ideas to convert a static route from RouterOS to hex.
Example: A route to the network 192.168.2.0/24 using gateway 192.168.1.1
The string to convert: [Network Bitmask][Network Address][IP Address]
Final hex string: 0x18c0a802c0a80101
I need some ideas to convert a static route from RouterOS to hex.
Example: A route to the network 192.168.2.0/24 using gateway 192.168.1.1
The string to convert: [Network Bitmask][Network Address][IP Address]
Final hex string: 0x18c0a802c0a80101
My first suggestion - it should be 0x18c0a802**00**c0a80101. What if the mask if more specific than /24? ![]()
#
# Script converting network and gateway from routing table to hexadecimal string
# dst-address=192.168.2.0/24 gateway=192.168.1.1 => result=0x18c0a80200c0a80101
#
# (c) Daniel Starnowski 2011
#
:foreach route in=[/ip route find] do={
:local dst [/ip route get $route dst-address];
:local gateway [/ip route get $route gateway];
:if ($gateway=[:toip $gateway]) do={
:local total ($dst . "." . $gateway);
:local result "0x";
:local hextable [:toarray "0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f"];
:local total2 "";
:local decimal;
:local division;
:local i;
:local j;
:for i from=1 to=[:len $total] step=1 do={
:set j [:pick $total ($i-1) $i];
:if (($j=".") or ($j="/")) do={:set j ","};
:set total2 ($total2 . $j);
};
:set total2 [:toarray $total2];
:for i from=0 to=8 step=1 do={
:set j $i;
:if ($j<5) do={if ($j=0) do={:set j 4;} else={:set j ($j-1);};};
:set decimal [:pick $total2 $j ($j+1)]
:set division ($decimal / 16);
:set result ($result . [:pick $hextable $division]);
:set result ($result . [:pick $hextable ($decimal - (16 * $division))]);
};
:put $result;
} else={:put ("Gateway is not a single IP address for ".$dst);}
}
This will generate an error on the dhcp client (the data is invalid).
If I set the network bits to “/25”, then the CIDR bit usage changes.
The string would be:
24 bits = 18c0a802c0a80101
25 bits = 19c0a80200c0a80101


Then how should it look like for:
192.168.0.0/16
10.0.0.0/8
10.0.0.0/16
10.0.0.0/20
10.0.0.0/24
10.0.0.0/28
? ![]()
Thank you!
I’m trying to learn to write scripts in RouterOS, I must say that it’s quite easier to write scripts in a Unix machine.
You like chocolate, I’ll remeber that if I attend to the next MUM in Warsaw.
If the gateway address is the same (192.168.1.1).
192.168.0.0/16 = 0x10c0a8c0a80101
10.0.0.0/8 = 0x080ac0a80101
10.0.0.0/16 = 0x100a00c0a80101
10.0.0.0/20 = 0x140a0000c0a80101
10.0.0.0/24 = 0x180a0000c0a80101
10.0.0.0/28 = 0x1c0a000000c0a80101
If you have a computer with perl or ruby, try these scripts.
http://forum.mikrotik.com/t/calculate-dhcp-option-121-classless-static-route-option/43789/1
In your script above, did you forget to add a closing bracket to the end of it?
Ok, this modification was quick
.
And the perl script you gave me as example - gives invalid result for /0 mask. In that RFC (see the examples in the RFC) - should be no octets, but the perl script gives one
.
#
# Second script converting network and gateway from routing table to hexadecimal string
# according to RFC 3442
# result=0x<prefix><network><gateway>
# example: dst-address=192.168.2.0/24 gateway=192.168.1.1 => result=0x18c0a802c0a80101
#
# Width of subnet mask Number of significant octets
# 0 0
# 1- 8 1
# 9-16 2
# 17-24 3
# 25-32 4
#
# (c) Daniel Starnowski 2011
#
:foreach route in=[/ip route find] do={
:local dst [/ip route get $route dst-address];
:local gateway [/ip route get $route gateway];
:if ($gateway=[:toip $gateway]) do={
:local total ($dst . "." . $gateway);
:local result "0x";
:local hextable [:toarray "0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f"];
:local total2 "";
:local decimal;
:local division;
:local i;
:local j;
:for i from=1 to=[:len $total] step=1 do={
:set j [:pick $total ($i-1) $i];
:if (($j=".") or ($j="/")) do={:set j ","};
:set total2 ($total2 . $j);
};
:set total2 [:toarray $total2];
:set decimal [:pick $total2 4]
:set division ($decimal / 16);
:set result ($result . [:pick $hextable $division]);
:set result ($result . [:pick $hextable ($decimal - (16 * $division))]);
:local omit ((32-[:pick $total2 4]) / 8);
:for i from=($omit+1) to=8 step=1 do={
:set j $i;
:if ($j<5) do={:set j ($j-1-$omit);};
:set decimal [:pick $total2 $j]
:set division ($decimal / 16);
:set result ($result . [:pick $hextable $division]);
:set result ($result . [:pick $hextable ($decimal - (16 * $division))]);
};
:put ($result . " for " . $dst);
} else={:put ("Gateway is not a single IP address for ".$dst);}
}
Can you give me an example, thanks.
dasiu@admin:~/Dokumenty/Mikrotik/Skrypty$ ./dhcp.perl 16.32.64.128 0.0.0.0/0
DHCP option 121 (249) hex string: 000010204080
From the RFC 3442 - see the first example:
Width of subnet mask Number of significant octets
0 0
1- 8 1
9-16 2
17-24 3
25-32 4
The following table contains some examples of how various subnet
number/mask combinations can be encoded:
Subnet number Subnet mask Destination descriptor
0 0 0
10.0.0.0 255.0.0.0 8.10
10.0.0.0 255.255.255.0 24.10.0.0
10.17.0.0 255.255.0.0 16.10.17
10.27.129.0 255.255.255.0 24.10.27.129
10.229.0.128 255.255.255.128 25.10.229.0.128
10.198.122.47 255.255.255.255 32.10.198.122.47
So then - line 16 of the perl script given by you:
$string .= sprintf(‘%02x’, $b0);
should be:
$string .= sprintf(‘%02x’, $b0) if($mask > 0);
You are right, I must have forgotten to add “if($mask > 0)” to the perl script (it’s corrected now).
Another karma granted for this one. ![]()