Help testing if a variable contains an IPv4

Alan DeKok aland at
Sat Jun 12 15:05:40 CEST 2021

On Jun 12, 2021, at 8:55 AM, David Herselman via Freeradius-Users <freeradius-users at> wrote:
> I'm trying to allow non MFA logins from configuration revisioning systems where the target device doesn't support SSH key based authentication. I started constructing an unlang check using '<ipv4prefix>' and hit some quirks.
> Most of our devices include the calling station's source IP in their request, whilst a few send the reverse DNS lookup strings. How do I test if a variable matches the structure of an IPv4 IP?

  It depends.

 In RADIUS, attributes have a data type.  Some are type "string", and others are type "ipaddr".  The first one can contain an ASCII string which represents the *printed* form on an IP address.  But it's not an IP address.

  In contrast, the "ipaddr" data type is a 32-bit IPv4 address.

> My problem appears to be that '<ipv4prefix>&String  <' returns true, for example:

  Because an ASCII string isn't a 32-bit IPv4 address.

> (0)   Calling-Station-Id = ""
> (0)       if (&Client-Shortname == "core_routers") && !(&User-Name == "revisioncfg" && &Calling-Station-Id && <ipv4prefix>&Calling-Station-Id < {

  That won't work.  What you're asking is for it to do a DNS lookup (generally a bad idea, too), and then compare the resulting IP address to the prefix.

  What's actually happening is that it's casting the first 32-bits of the string to an IP address, and then checking that.

  The solution is to copy the Calling-Station-ID to an attribute of type "ipaddr" first.  e.g. Tmp-IP-Address-0.  Then, compare that address to the prefix:

	update request {
		Tmp-IP-Address-0 := &Calling-Station-Id

	if (<ipv4prefix>&Tmp-IP-Address-0 < {

  Alan DeKok.

More information about the Freeradius-Users mailing list