ATTRIBUTE Tmp-Date-7 1847 date
ATTRIBUTE Tmp-Date-8 1848 date
ATTRIBUTE Tmp-Date-9 1849 date
+
+ATTRIBUTE Tmp-Integer64-0 1871 integer64
+ATTRIBUTE Tmp-Integer64-1 1872 integer64
+ATTRIBUTE Tmp-Integer64-2 1873 integer64
+ATTRIBUTE Tmp-Integer64-3 1874 integer64
+ATTRIBUTE Tmp-Integer64-4 1875 integer64
+ATTRIBUTE Tmp-Integer64-5 1876 integer64
+ATTRIBUTE Tmp-Integer64-6 1877 integer64
+ATTRIBUTE Tmp-Integer64-7 1878 integer64
+ATTRIBUTE Tmp-Integer64-8 1879 integer64
+ATTRIBUTE Tmp-Integer64-9 1880 integer64
#
# These attributes shouldn't be used anywhere. They are defined here
# only for casting of values in conditional expressions.
/*
* Convert things which are obviously integers to IP addresses
+ *
+ * We assume the number is the bigendian representation of the
+ * IP address.
*/
if (fr_integer_check(value)) {
vp->vp_ipaddr = htonl(atol(value));
{
char const *c1, *c2;
+ /*
+ * Convert things which are obviously integers to Ethernet addresses
+ *
+ * We assume the number is the bigendian representation of the
+ * ethernet address.
+ */
+ if (fr_integer_check(value)) {
+ uint64_t integer = htonll(atoll(value));
+
+ memcpy(&vp->vp_ether, &integer, sizeof(vp->vp_ether));
+ break;
+ }
+
length = 0;
cp = value;
while (*cp) {
{
VALUE_PAIR *vp;
- uint64_t integer;
+ uint64_t int64 = 0; /* Needs to be initialised to zero */
+ uint32_t int32 = 0; /* Needs to be initialised to zero */
while (isspace((int) *fmt)) fmt++;
if (vp->length > 8) {
break;
}
- memcpy(&integer, &(vp->vp_octets), vp->length);
- return snprintf(out, outlen, "%" PRIu64, ntohll(integer));
+
+ if (vp->length > 4) {
+ memcpy(&int64, vp->vp_octets, vp->length);
+ return snprintf(out, outlen, "%" PRIu64, htonll(int64));
+ }
+
+ memcpy(&int32, vp->vp_octets, vp->length);
+ return snprintf(out, outlen, "%i", htonl(int32));
case PW_TYPE_INTEGER64:
return snprintf(out, outlen, "%" PRIu64, vp->vp_integer64);
- case PW_TYPE_INTEGER:
+ /*
+ * IP addresses are treated specially, as parsing functions assume the value
+ * is bigendian and will convert it for us.
+ */
case PW_TYPE_IPADDR:
+ return snprintf(out, outlen, "%u", htonl(vp->vp_ipaddr));
+
+ case PW_TYPE_INTEGER:
case PW_TYPE_DATE:
case PW_TYPE_BYTE:
case PW_TYPE_SHORT:
return snprintf(out, outlen, "%u", vp->vp_integer);
+ /*
+ * Ethernet is weird... It's network related, so we assume to it should be
+ * bigendian.
+ */
case PW_TYPE_ETHERNET:
- memcpy(&integer, &(vp->vp_ether), vp->length);
- return snprintf(out, outlen, "%" PRIu64, ntohll(integer));
+ memcpy(&int64, &vp->vp_ether, vp->length);
+ return snprintf(out, outlen, "%" PRIu64, htonll(int64));
case PW_TYPE_SIGNED:
return snprintf(out, outlen, "%i", vp->vp_signed);
break;
}
- REDEBUG("Type \"%s\" cannot be converted to integer",
- fr_int2str(dict_attr_types, vp->da->type, PW_TYPE_INVALID));
+ REDEBUG("Type '%s' of length %zu cannot be converted to integer",
+ fr_int2str(dict_attr_types, vp->da->type, PW_TYPE_INVALID), vp->length);
*out = '\0';
return -1;
}
ret = rad_vp2data(&p, vp);
+ if (ret < 0) {
+ return ret;
+ }
len = (size_t) ret;
/*
static ssize_t xlat_string(UNUSED void *instance, REQUEST *request,
char const *fmt, char *out, size_t outlen)
{
- int len;
+ size_t len;
+ ssize_t ret;
VALUE_PAIR *vp;
+ uint8_t const *p;
while (isspace((int) *fmt)) fmt++;
if (*fmt == '&') fmt++;
if ((radius_get_vp(&vp, request, fmt) < 0) || !vp) goto nothing;
- if (vp->da->type != PW_TYPE_OCTETS) goto nothing;
+ ret = rad_vp2data(&p, vp);
+ if (ret < 0) {
+ return ret;
+ }
+
+ switch (vp->da->type) {
+ case PW_TYPE_OCTETS:
+ len = fr_print_string((char const *) p, vp->length, out, outlen);
+ break;
- len = fr_print_string(vp->vp_strvalue, vp->length, out, outlen);
- out[len] = '\0';
+ case PW_TYPE_STRING:
+ len = strlcpy(out, vp->vp_strvalue, outlen);
+ break;
+
+ default:
+ len = fr_print_string((char const *) p, ret, out, outlen);
+ break;
+ }
return len;
}
--- /dev/null
+#
+# PRE: update
+#
+update reply {
+ Filter-Id := "filter"
+}
+
+update request {
+ Tmp-String-0 := '9870'
+ Tmp-String-1 := '98709870'
+ Tmp-String-2 := '987098709870'
+ Tmp-Octets-0 := 0x39383731
+ Tmp-Octets-1 := 0x3938373139383731
+ Tmp-Octets-2 := 0x393837313938373139383731
+ Tmp-IP-Address-0 := 57.56.55.50
+ Tmp-Date-0 := 959985459
+ Tmp-Integer-0 := 959985460
+ Tmp-Cast-Abinary := 'ip out forward srcip 57.56.55.53/32 udp dstport = 1812'
+ Tmp-Cast-IfId := '0000:0000:3938:3737'
+ Tmp-Cast-IPv6Addr := '::3938:3738'
+ Tmp-Cast-IPv6Prefix := '::3938:3739/128'
+ Tmp-Cast-Byte := 58
+ Tmp-Cast-Short := 14139
+ Tmp-Cast-Ethernet := 00:00:39:38:37:3c
+ Tmp-Cast-Integer64 := 1152921505566832445
+ Tmp-Cast-IPv4Prefix := 57.56.55.62/32
+}
+
+update request {
+ Tmp-String-2 := "%{integer:Tmp-IP-Address-0}"
+ Tmp-String-3 := "%{integer:Tmp-Date-0}"
+ Tmp-String-4 := "%{integer:Tmp-Integer-0}"
+ Tmp-String-5 := "%{integer:Tmp-Cast-Abinary}"
+ Tmp-String-6 := "%{integer:Tmp-Cast-Ifid}"
+ Tmp-String-7 := "%{integer:Tmp-Cast-IPv6Addr}"
+ Tmp-String-8 := "%{integer:Tmp-Cast-IPv6Prefix}"
+}
+
+# String - network order representation of a 4 char string
+update request {
+ Tmp-Integer-0 := "%{integer:Tmp-String-0}"
+}
+if ((Tmp-String-0 != "%{string:Tmp-Integer-0}") || (Tmp-Integer-0 != 959985456)) {
+ update reply {
+ Filter-Id += 'fail'
+ }
+}
+
+# String - network order representation of a 8 char string
+update request {
+ Tmp-Integer64-0 := "%{integer:Tmp-String-1}"
+}
+if ((Tmp-String-1 != "%{string:Tmp-Integer64-0}") || (Tmp-Integer64-0 != 4123106139115632432)) {
+ update reply {
+ Filter-Id += 'fail'
+ }
+}
+
+# String - Can't convert 12 byte string to integer (our biggest native size is a 64bit unsigned int)
+if ("%{integer:Tmp-String-2}" != '') {
+ update reply {
+ Filter-Id += 'fail'
+ }
+}
+
+# Octets - network order representation of a 4 byte octet string
+update request {
+ Tmp-Integer-0 := "%{integer:Tmp-Octets-0}"
+}
+if ((Tmp-Octets-0 != "0x%{hex:Tmp-Integer-0}") || (Tmp-Integer-0 != 959985457)) {
+ update reply {
+ Filter-Id += 'fail'
+ }
+}
+
+# Octets - network order representation of a 8 byte octet string
+update request {
+ Tmp-Integer64-0 := "%{integer:Tmp-Octets-1}"
+}
+if ((Tmp-Octets-1 != "0x%{hex:Tmp-Integer64-0}") || (Tmp-Integer64-0 != 4123106143410599729)) {
+ update reply {
+ Filter-Id += 'fail'
+ }
+}
+
+# String - Can't convert 12 byte octet string to integer (our biggest native size is a 64bit unsigned int)
+if ("%{integer:Tmp-Octets-2}" != '') {
+ update reply {
+ Filter-Id += 'fail'
+ }
+}
+
+# IP Address
+if (Tmp-String-2 != '959985458') {
+ update reply {
+ Filter-Id += 'fail'
+ }
+}
+
+if (<ipaddr>Tmp-String-2 != &Tmp-IP-Address-0) {
+ update reply {
+ Filter-Id += 'fail'
+ }
+}
+
+# Date
+if (Tmp-String-3 != '959985459') {
+ update reply {
+ Filter-Id += 'fail'
+ }
+}
+
+# Integer
+if (Tmp-String-4 != '959985460') {
+ update reply {
+ Filter-Id += 'fail'
+ }
+}
+
+# Abinary - Can't convert ascend binary to an integer
+if (Tmp-String-5 != '') {
+ update reply {
+ Filter-Id += 'fail'
+ }
+}
+
+# ifid - Can't convert interface ID to an integer
+if (Tmp-String-6 != '') {
+ update reply {
+ Filter-Id += 'fail'
+ }
+}
+
+# ipv6addr - Can't convert IPv6 to integer
+if (Tmp-String-7 != '') {
+ update reply {
+ Filter-ID += 'fail'
+ }
+}
+
+# ipv6addrprefix
+if (Tmp-String-8 != '') {
+ update reply {
+ Filter-ID += 'fail'
+ }
+}
+update request {
+ Tmp-String-0 := "%{integer:Tmp-Cast-Byte}"
+ Tmp-String-1 := "%{integer:Tmp-Cast-Short}"
+ Tmp-String-2 := "%{integer:Tmp-Cast-Ethernet}"
+ Tmp-String-3 := "%{integer:Tmp-Cast-Integer64}"
+ Tmp-String-4 := "%{integer:Tmp-Cast-IPv4Prefix}"
+}
+
+# byte
+if (Tmp-String-0 != '58') {
+ update reply {
+ Filter-ID += 'fail'
+ }
+}
+
+# short
+if (Tmp-String-1 != '14139') {
+ update reply {
+ Filter-ID += 'fail'
+ }
+}
+
+# ethernet
+if (Tmp-String-2 != '62913607630848') {
+ update reply {
+ Filter-Id += 'fail'
+ }
+}
+if (<ether>Tmp-String-2 != &Tmp-Cast-Ethernet) {
+ update reply {
+ Filter-Id += 'fail'
+ }
+}
+
+# integer64
+if (Tmp-String-3 != '1152921505566832445') {
+ update reply {
+ Filter-Id += 'fail'
+ }
+}
+
+# ipv4prefix
+if (Tmp-String-4 != '') {
+ update reply {
+ Filter-Id += 'fail'
+ }
+}
+
+
+
+