Revisiting ROS-7.20.4: ":toip" command?

Trying to convert string to ip address using :toip command

> :put [:toip "10.0.0.0/24"];
return null

> :put [:toip "10.0.0.0"];
return 10.0.0.0

Is it the expected behavior? we can not convert ip with subnet?

Logically, IP address is not subnet.

Examples to get the picture:

>/ip/address
/ip/address>:put [:typeof [get ([find interface=bridge]->0) address]]
str
/ip/address>:put [:typeof [get ([find interface=bridge]->0) network]]
ip
1 Like

Until recently, to get the IP address from that string, you have to strip the netmask (with :pick and :find), then call :toip on the result.

Starting with 7.21beta7, :toip can be used to convert a value of type ip-prefix to ip, which means this now work:

:put [:toip 10.0.0.0/24]

However, it doesn't work if converting from string. So, both of these don't work:

:put [:toip "10.0.0.0/24"]
:local ipf "10.0.0.0/24"; :put [:toip $ipf]

In case your input is a available as a string in a variable (in this example $ipf), you'll need to do this in 7.21beta7:

:put [[:parse ":toip $ipf"]]

With older versions, like 7.20.4, this is still required:

:put [:toip [:pick $ipf 0 [:find $ipf "/"]]]

1 Like

Great insight. Thank you @CGGXANNX

Finally... i use pick method from old times since toip stop working for prefix from 6.something...
but later I use "easyParse"...

:if (($vtype="ip-prefix") or \
     ($vtype="ip6-prefix")) do={:execute ":global $vname [[:parse \":return $vvalue\"]]"}

@Lokamaya so for v6/v7 versions agnostic syntax use...

:local ipf "10.0.0.0/24" ; :put [[:parse ":return $ipf"]]
# or as on first post
:put [[:parse ":return 10.0.0.0/24"]]

and work for both IPv4 and IPv6


Reference:

And I thought that OP was trying to get subnet as ip type… :slight_smile:

And my methods return ip-prefix or ipv6-prefix...

So...

:put [[:parse ":return 10.0.0.0/24"]]
# return 10.0.0.0/24 ip-prefix type
#
:put [[:parse ":return 10.0.0.10/24"]]
# return 10.0.0.10/24 ip-prefix type

@optio
But the user want 10.0.0.0/24 the subnet, if the input is 10.0.0.10/24 (ignoring if is string or ip, etc.) ???

>:put [:typeof [[:parse ":return \"10.0.0.0/24\""]]]
str

but not ip type as :toip command…

Already fixed, too much copy and paste...


10.0.0.0/24 can't be one IP, for no reason, and there is no logic to call ip type one ip WITH mask...
only
10.0.0.0 can be one IP...

Ok, I misunderstood OP, since ip type cannot be subnet, ok corrected command is ip-prefix type return but I wasn't sure from first post that OP wants that…

yes, that was my first reply

If user want ip/subnet (with or without prefix, just remove /$prefix in the script...)

{
:local source    10.31.42.56/16

:local ip        [:toip [:pick $source 0 [:find $source "/"]]]
:local prefix    [:tonum [:pick $source ([:find $source "/"] + 1) [:len $source]]]
:local submask   (255.255.255.255<<(32 - $prefix))
:local network   ($ip & $submask)
:put [[:parse ":return $network/$prefix"]]
}

# return 10.31.0.0/16 as ip-prefix (or 10.31.0.0 as IP if /$prefix is removed)

Reference:

I still can't believe we're missing some :toip-prefix <string>. Using parse/execute always seem so hackish, for something that's actually pretty common in router configuration...

For example, parameterizing something like /ip/dhcp-server/... is rather tricky since it so type-sensitive. Although at least the 7.20+ change means you can start with an IP prefix variable and "down convert" to a normal ip/ipv6 type, so some progress:

{
    :local baseprefix 10.0.0.0/24
    :local baseip [:toip $baseprefix]
    :put "First IP address is $($baseip + 1)"
}

# First IP address is 10.0.0.1