* Note that we don't care about the length of the input string,
* because '\0' is an invalid UTF-8 character.
*/
-static int utf8_char(uint8_t *str)
+int fr_utf8_char(const uint8_t *str)
{
if (*str < 0x20) return 0;
* has to be larger than the input string by at least 5 bytes.
* If not, the output is silently truncated...
*/
-void librad_safeprint(char *in, int inlen, char *out, int outlen)
+void fr_print_string(const char *in, size_t inlen, char *out, size_t outlen)
{
- unsigned char *str = (unsigned char *)in;
+ const uint8_t *str = (const uint8_t *) in;
int sp = 0;
int utf8 = 0;
- if (inlen < 0) inlen = strlen(in);
+ if (inlen == 0) inlen = strlen(in);
/*
*
* Some clients send strings with an off-by-one
* length (confused with strings in C).
*/
- if ((inlen == 0) && (*str == 0)) break;
+ if ((inlen == 1) && (*str == 0)) break;
switch (*str) {
case '\\':
continue;
}
- utf8 = utf8_char((uint8_t *)str);
+ utf8 = fr_utf8_char(str);
if (!utf8) {
snprintf(out, outlen, "\\%03o", *str);
out += 4;
* Print one value into a string.
* delimitst will define if strings and dates will be delimited by '"'
*/
-int vp_prints_value(char * out, int outlen, VALUE_PAIR *vp, int delimitst)
+int vp_prints_value(char * out, size_t outlen, VALUE_PAIR *vp, int delimitst)
{
DICT_VALUE *v;
char buf[1024];
if ((delimitst == 1) && vp->flags.has_tag) {
/* Tagged attribute: print delimter and ignore tag */
buf[0] = '"';
- librad_safeprint((char *)(vp->vp_strvalue),
+ fr_print_string(vp->vp_strvalue,
vp->length, buf + 1, sizeof(buf) - 2);
strcat(buf, "\"");
} else if (delimitst == 1) {
/* Non-tagged attribute: print delimter */
buf[0] = '"';
- librad_safeprint((char *)vp->vp_strvalue,
+ fr_print_string(vp->vp_strvalue,
vp->length, buf + 1, sizeof(buf) - 2);
strcat(buf, "\"");
} else {
/* Non-tagged attribute: no delimiter */
- librad_safeprint((char *)vp->vp_strvalue,
+ fr_print_string(vp->vp_strvalue,
vp->length, buf, sizeof(buf));
}
a = buf;
case PW_TYPE_INTEGER:
if ( vp->flags.has_tag ) {
/* Attribute value has a tag, need to ignore it */
- if ((v = dict_valbyattr(vp->attribute, (vp->vp_integer & 0xffffff)))
+ if ((v = dict_valbyattr(vp->attribute, vp->vendor, (vp->vp_integer & 0xffffff)))
!= NULL)
a = v->name;
else {
case PW_TYPE_BYTE:
case PW_TYPE_SHORT:
/* Normal, non-tagged attribute */
- if ((v = dict_valbyattr(vp->attribute, vp->vp_integer))
+ if ((v = dict_valbyattr(vp->attribute, vp->vendor, vp->vp_integer))
!= NULL)
a = v->name;
else {
break;
case PW_TYPE_DATE:
t = vp->vp_date;
- if (delimitst) {
+ if (delimitst == 1) {
len = strftime(buf, sizeof(buf), "\"%b %e %Y %H:%M:%S %Z\"",
localtime_r(&t, &s_tm));
} else {
}
if (len > 0) a = buf;
break;
+ case PW_TYPE_SIGNED: /* Damned code for 1 WiMAX attribute */
+ snprintf(buf, sizeof(buf), "%d", vp->vp_signed);
+ a = buf;
+ break;
case PW_TYPE_IPADDR:
a = inet_ntop(AF_INET, &(vp->vp_ipaddr),
buf, sizeof(buf));
strcpy(buf, "0x");
- lrad_bin2hex(vp->vp_octets, buf + 2, vp->length);
+ fr_bin2hex(vp->vp_octets, buf + 2, vp->length);
a = buf;
break;
a = inet_ntop(AF_INET6, &addr, buf, sizeof(buf));
if (a) {
char *p = buf + strlen(buf);
- sprintf(p, "/%u", (unsigned int) vp->vp_strvalue[1]);
+ snprintf(p, buf + sizeof(buf) - p - 1, "/%u",
+ (unsigned int) vp->vp_octets[1]);
}
}
break;
a = buf;
break;
+ case PW_TYPE_TLV:
+ if (outlen <= (2 * (vp->length + 1))) return 0;
+
+ strcpy(buf, "0x");
+
+ fr_bin2hex(vp->vp_tlv, buf + 2, vp->length);
+ a = buf;
+ break;
+
default:
a = "UNKNOWN-TYPE";
break;
"<`STRING`>"
};
+const char *vp_print_name(char *buffer, size_t bufsize, int attr, int vendor)
+{
+ size_t len = 0;
+
+ if (!buffer) return NULL;
+
+ if (vendor) {
+ DICT_VENDOR *v;
+
+ v = dict_vendorbyvalue(vendor);
+ if (v) {
+ snprintf(buffer, bufsize, "%s-", v->name);
+ } else {
+ snprintf(buffer, bufsize, "Vendor-%u-", vendor);
+ }
+
+ len = strlen(buffer);
+ if (len == bufsize) {
+ return NULL;
+ }
+ }
+
+ snprintf(buffer + len, bufsize - len, "Attr-%u", attr & 0xffff);
+ len += strlen(buffer + len);
+ if (len == bufsize) {
+ return NULL;
+ }
+
+ return buffer;
+}
+
/*
* Print one attribute and value into a string.
*/
-int vp_prints(char *out, int outlen, VALUE_PAIR *vp)
+int vp_prints(char *out, size_t outlen, VALUE_PAIR *vp)
{
- int len;
+ size_t len;
const char *token = NULL;
const char *name;
+ char namebuf[128];
out[0] = 0;
if (!vp) return 0;
- name = vp->name;
-
- if (!*name) {
- DICT_ATTR *da = dict_attrbyvalue(vp->attribute);
- if (!da) return 0;
- name = da->name;
- }
+ name = vp->name;
- if (strlen(name) + 3 > (size_t)outlen) {
- return 0;
+ if (!name || !*name) {
+ if (!vp_print_name(namebuf, sizeof(namebuf), vp->attribute, vp->attribute)) {
+ return 0;
+ }
+ name = namebuf;
}
if ((vp->operator > T_OP_INVALID) &&
}
if( vp->flags.has_tag ) {
-
- snprintf(out, outlen, "%s:%d %s ", name, vp->flags.tag,
- token);
+ snprintf(out, outlen, "%s:%d %s ",
+ name, vp->flags.tag, token);
len = strlen(out);
vp_prints_value(out + len, outlen - len, vp, 1);
} else {
-
snprintf(out, outlen, "%s %s ", name, token);
len = strlen(out);
vp_prints_value(out + len, outlen - len, vp, 1);
}
- return strlen(out);
+ return len + strlen(out + len);
}