Unlang operations with IP addresses
Hello, I am trying to figure out how to compute IP address from a range and netmask in freeradius v3. Actually something similar like this expression in v4: %{eval:%{DHCP-Your-IP-Address} & %{DHCP-Subnet-Mask} + 1} Thank you. Ludo
On Dec 10, 2024, at 12:13 PM, Ľudovít Mikula <ludovit.mikula@mikori.sk> wrote:
I am trying to figure out how to compute IP address from a range and netmask in freeradius v3.
I'm not sure what that means. There's no "range" in the server, just IP addresses such as 192.168.0.1, and IPs with prefixes, such as 192.168/16
Actually something similar like this expression in v4: %{eval:%{DHCP-Your-IP-Address} & %{DHCP-Subnet-Mask} + 1}
That's not the v4 syntax, as v4 is much, much, simpler than that. But whatever... Do you want to convert an IP + mask into an IP address prefix? In v3, you should be able to this by simply treating the IP/prefix as a string: something prefix = "%{DHCP-Your-IP-Address}/%{DHCP-Subnet-Mask}" The parser won't care that there are "too many" things in the IP address. It will take care of clearing the lower bits automatically. Alan DeKok.
Ok, I've got the question wrong. What I want to do: based on assigned IP address and subnet mask, compute first IP address from the range from which the IP address was assigned. Example: given: DHCP-Your-IP-Address: 192.168.10.20 DHCP-Subnet-Mask: 255.255.255.0 would produce: DHCP-Router-Address: 192.168.10.1 Ludo On 10. 12. 2024 18:21, Alan DeKok wrote:
On Dec 10, 2024, at 12:13 PM, Ľudovít Mikula <ludovit.mikula@mikori.sk> wrote:
I am trying to figure out how to compute IP address from a range and netmask in freeradius v3.
I'm not sure what that means. There's no "range" in the server, just IP addresses such as 192.168.0.1, and IPs with prefixes, such as 192.168/16
Actually something similar like this expression in v4: %{eval:%{DHCP-Your-IP-Address} & %{DHCP-Subnet-Mask} + 1}
That's not the v4 syntax, as v4 is much, much, simpler than that. But whatever...
Do you want to convert an IP + mask into an IP address prefix?
In v3, you should be able to this by simply treating the IP/prefix as a string:
something prefix = "%{DHCP-Your-IP-Address}/%{DHCP-Subnet-Mask}"
The parser won't care that there are "too many" things in the IP address. It will take care of clearing the lower bits automatically.
Alan DeKok.
- List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
On Dec 10, 2024, at 1:44 PM, Ľudovít Mikula <ludovit.mikula@mikori.sk> wrote:
Ok, I've got the question wrong.
What I want to do: based on assigned IP address and subnet mask, compute first IP address from the range from which the IP address was assigned.
Example:
given: DHCP-Your-IP-Address: 192.168.10.20 DHCP-Subnet-Mask: 255.255.255.0
would produce: DHCP-Router-Address: 192.168.10.1
Hmm... I'm not sure that's easy to do in v3. In v4 it's easy: ip-address thing = (DHCP-Your-IP-Address & ((uint32) DHCP-Subnet-Mask)) + 1 In v3, I think this is about the only situation where you'd have to use something other than unlang. :( Alan DeKok.
Thank you, was trying to wrap my head around it in unlang. Ended up using sql since I already use it and the overhead is probably quite small. Just for reference this is what I used: &DHCP-Router-Address = "%{sql: SELECT INET_NTOA((INET_ATON('%{DHCP-Your-IP-Address}') & INET_ATON('%{%{DHCP-Subnet-Mask}:-255.255.255.0}')) +1) AS ip;}" Ludo On 10. 12. 2024 21:51, Alan DeKok wrote:
On Dec 10, 2024, at 1:44 PM, Ľudovít Mikula <ludovit.mikula@mikori.sk> wrote:
Ok, I've got the question wrong.
What I want to do: based on assigned IP address and subnet mask, compute first IP address from the range from which the IP address was assigned.
Example:
given: DHCP-Your-IP-Address: 192.168.10.20 DHCP-Subnet-Mask: 255.255.255.0
would produce: DHCP-Router-Address: 192.168.10.1
Hmm... I'm not sure that's easy to do in v3. In v4 it's easy:
ip-address thing = (DHCP-Your-IP-Address & ((uint32) DHCP-Subnet-Mask)) + 1
In v3, I think this is about the only situation where you'd have to use something other than unlang. :(
Alan DeKok. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
On 10/12/2024 21:29, Ľudovít Mikula wrote:
Ended up using sql since I already use it and the overhead is probably quite small.
Just for reference this is what I used: &DHCP-Router-Address = "%{sql: SELECT INET_NTOA((INET_ATON('%{DHCP-Your-IP-Address}') & INET_ATON('%{%{DHCP-Subnet-Mask}:-255.255.255.0}')) +1) AS ip;}"
I had to work out something similar recently - and you can do it in unlang by casting IP addresses to integers, doing the maths and then casting back to IP. For what you're doing the following would work: update { &Tmp-Integer-0 := &DHCP-Your-IP-Address &Tmp-Integer-1 := &DHCP-Subnet-Mask &Tmp-Integer-2 := "%{expr: (&Tmp-Integer-0 & &Tmp-Integer-1) + 1}" &DHCP-Router-Address := &Tmp-Integer-2 } It's not pretty, but it works - and avoids any external calls. Nick -- Nick Porter Porter Computing Ltd Registered in England No 12659380
Thank you Nick, that's perfect! I was trying to do exactly the same, but couldn't find a way to cast the IPs ... turns out I was overcomplicating it :) Ludo On 11. 12. 2024 8:54, Nick Porter wrote:
On 10/12/2024 21:29, Ľudovít Mikula wrote:
Ended up using sql since I already use it and the overhead is probably quite small.
Just for reference this is what I used: &DHCP-Router-Address = "%{sql: SELECT INET_NTOA((INET_ATON('%{DHCP-Your-IP-Address}') & INET_ATON('%{%{DHCP-Subnet-Mask}:-255.255.255.0}')) +1) AS ip;}"
I had to work out something similar recently - and you can do it in unlang by casting IP addresses to integers, doing the maths and then casting back to IP.
For what you're doing the following would work:
update { &Tmp-Integer-0 := &DHCP-Your-IP-Address &Tmp-Integer-1 := &DHCP-Subnet-Mask &Tmp-Integer-2 := "%{expr: (&Tmp-Integer-0 & &Tmp- Integer-1) + 1}" &DHCP-Router-Address := &Tmp-Integer-2 }
It's not pretty, but it works - and avoids any external calls.
Nick
- List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
"given: DHCP-Your-IP-Address: 192.168.10.20 DHCP-Subnet-Mask: 255.255.255.0 would produce: DHCP-Router-Address: 192.168.10.1" Hi Ludo, If you use mysql in your freeradius configuration, it is possible to create a function that returns what you need: CREATE FUNCTION get_gw (`ip` VARCHAR(15), `mask` VARCHAR(15)) RETURNS VARCHAR(15) RETURN INET_NTOA(( INET_ATON(ip) & CONV(CONCAT(REPEAT(1, BIT_ COUNT(INET_ATON(mask))), REPEAT(0, 32 - BIT_COUNT(INET_ATON(mask)))), 2, 10)) +1); select get_gw("192.168.10.20","255.255.255.0")\G *************************** 1. row *************************** get_gw("192.168.10.20","255.255.255.0"): 192.168.10.1 Petr
participants (4)
-
Alan DeKok -
Nick Porter -
petr.linke@seznam.cz -
Ľudovít Mikula