From d9ae6534eed05639403584b7b2733ec36c08f1a4 Mon Sep 17 00:00:00 2001
From: Luke Howard <lukeh@padl.com>
Date: Mon, 14 Nov 2011 18:54:44 +1100
Subject: add rs_attr_display_name/rs_attr_parse_name

---
 lib/avp.c                           | 74 +++++++++++++++++++++++++++++++++++++
 lib/include/radsec/radsec.h         | 57 ++++++++++++++++++++++++++--
 lib/radius/Makefile.am              |  1 +
 lib/radius/share/dictionary.juniper | 23 ++++++++++++
 lib/radsec.sym                      |  2 +
 5 files changed, 153 insertions(+), 4 deletions(-)
 create mode 100644 lib/radius/share/dictionary.juniper

diff --git a/lib/avp.c b/lib/avp.c
index 0de72b1..5af6129 100644
--- a/lib/avp.c
+++ b/lib/avp.c
@@ -447,6 +447,79 @@ rs_attr_find (const char *name,
   return RSE_OK;
 }
 
+int
+rs_attr_display_name (unsigned int attr,
+                      unsigned int vendor,
+                      char *buffer,
+                      size_t bufsize,
+                      int canonical)
+{
+  const DICT_ATTR *da = NULL;
+  DICT_ATTR da2;
+  int err;
+
+  if (!canonical) {
+    da = nr_dict_attr_byvalue (attr, vendor);
+  }
+  if (da == NULL) {
+    err = nr_dict_attr_2struct(&da2, attr, vendor,
+                               buffer, bufsize);
+    if (err < 0)
+      return -err;
+  } else {
+    snprintf(buffer, bufsize, "%s", da->name);
+  }
+
+  return RSE_OK;
+}
+
+int
+rs_attr_parse_name (const char *name,
+		    unsigned int *attr,
+		    unsigned int *vendor)
+{
+  const DICT_ATTR *da;
+
+  if (strncmp(name, "Attr-", 5) == 0) {
+    char *s = (char *)&name[5];
+    unsigned int tmp;
+
+    tmp = strtoul(s, &s, 10);
+    if (*s == '.') {
+      s++;
+
+      switch (tmp) {
+      case PW_VENDOR_SPECIFIC:
+	*vendor = strtoul(s, &s, 10);
+	if (*s != '.')
+	  return RSE_ATTR_BAD_NAME;
+
+	s++;
+
+	*attr = strtoul(s, &s, 10);
+	if (*s != '\0')
+	  return RSE_ATTR_BAD_NAME;
+
+	break;
+      default:
+	return RSE_ATTR_BAD_NAME;
+      }
+    } else {
+      *attr = tmp;
+      *vendor = 0;
+    }
+  } else {
+    da = nr_dict_attr_byname (name);
+    if (da == NULL)
+      return RSE_ATTR_UNKNOWN;
+
+    *attr = da->attr;
+    *vendor = da->vendor;
+  }
+
+  return RSE_OK;
+}
+
 size_t
 rs_avp_display_value (rs_const_avp *vp,
                       char *buffer,
@@ -454,3 +527,4 @@ rs_avp_display_value (rs_const_avp *vp,
 {
   return nr_vp_snprintf_value (buffer, buflen, vp);
 }
+
diff --git a/lib/include/radsec/radsec.h b/lib/include/radsec/radsec.h
index 33d7990..6e967af 100644
--- a/lib/include/radsec/radsec.h
+++ b/lib/include/radsec/radsec.h
@@ -407,121 +407,170 @@ int rs_err_code(struct rs_error *err, int dofree_flag);
  */
 #define RS_MAX_STRING_LEN         254
 
+/** Free the AVP list \a vps */
 void
 rs_avp_free(rs_avp **vps);
 
+/** Return the length of AVP \a vp in bytes */
 size_t
 rs_avp_length(rs_const_avp *vp);
 
+/** Return the type of \a vp */
 rs_attr_type_t
 rs_avp_typeof(rs_const_avp *vp);
 
+/** Retrieve the attribute and vendor ID of \a vp */
 void
 rs_avp_attrid(rs_const_avp *vp, unsigned int *attr, unsigned int *vendor);
 
-
+/** Add \a vp to the list pointed to by \a head */
 void
-rs_avp_append(rs_avp **head, rs_avp *tail);
+rs_avp_append(rs_avp **head, rs_avp *vp);
 
+/** Find an AVP in \a vp that matches \a attr and \a vendor */
 rs_avp *
 rs_avp_find(rs_avp *vp, unsigned int attr, unsigned int vendor);
 
+/** Find an AVP in \a vp that matches \a attr and \a vendor */
 rs_const_avp *
 rs_avp_find_const(rs_const_avp *vp, unsigned int attr, unsigned int vendor);
 
+/** Alloc a new AVP for \a attr and \a vendor */
 rs_avp *
 rs_avp_alloc(unsigned int attr, unsigned int vendor);
 
+/** Duplicate existing AVP \a vp */
 rs_avp *
 rs_avp_dup(rs_const_avp *vp);
 
+/** Remove matching AVP from list \a vps */
 int
-rs_avp_delete(rs_avp **first, unsigned int attr, unsigned int vendor);
+rs_avp_delete(rs_avp **vps, unsigned int attr, unsigned int vendor);
 
+/** Return next AVP in list */
 rs_avp *
-rs_avp_next(rs_avp *avp);
+rs_avp_next(rs_avp *vp);
 
+/** Return next AVP in list */
 rs_const_avp *
 rs_avp_next_const(rs_const_avp *avp);
 
+/** Return string value of \a vp */
 const char *
 rs_avp_string_value(rs_const_avp *vp);
 
+/** Set AVP \a vp to string \a str */
 int
 rs_avp_string_set(rs_avp *vp, const char *str);
 
+/** Return integer value of \a vp */
 uint32_t
 rs_avp_integer_value(rs_const_avp *vp);
 
+/** Set AVP \a vp to integer \a val */
 int
 rs_avp_integer_set(rs_avp *vp, uint32_t val);
 
+/** Return IPv4 value of \a vp */
 uint32_t
 rs_avp_ipaddr_value(rs_const_avp *vp);
 
+/** Set AVP \a vp to IPv4 address \a in */
 int
 rs_avp_ipaddr_set(rs_avp *vp, struct in_addr in);
 
+/** Return POSIX time value of \a vp */
 time_t
 rs_avp_date_value(rs_const_avp *vp);
 
+/** Set AVP \a vp to POSIX time \a date */
 int
 rs_avp_date_set(rs_avp *vp, time_t date);
 
+/** Return constant pointer to octets in \a vp */
 const unsigned char *
 rs_avp_octets_value_const_ptr(rs_const_avp *vp);
 
+/** Return pointer to octets in \a vp */
 unsigned char *
 rs_avp_octets_value_ptr(rs_avp *vp);
 
+/** Retrieve octet pointer \a p and length \a len from \a vp */
 int
 rs_avp_octets_value_byref(rs_avp *vp,
 			  unsigned char **p,
 			  size_t *len);
 
+/** Copy octets from \a vp into \a buf and \a len */
 int
 rs_avp_octets_value(rs_const_avp *vp,
 		    unsigned char *buf,
 		    size_t *len);
 
+/**
+ * Copy octets possibly fragmented across multiple VPs
+ * into \a buf and \a len
+ */
 int
 rs_avp_fragmented_value(rs_const_avp *vps,
 		        unsigned char *buf,
 		        size_t *len);
 
+/** Copy \a len octets in \a buf to AVP \a vp */
 int
 rs_avp_octets_set(rs_avp *vp,
 		  const unsigned char *buf,
 		  size_t len);
 
+/** Return IFID value of \a vp */
 int
 rs_avp_ifid_value(rs_const_avp *vp, uint8_t val[8]);
 
 int
 rs_avp_ifid_set(rs_avp *vp, const uint8_t val[8]);
 
+/** Return byte value of \a vp */
 uint8_t
 rs_avp_byte_value(rs_const_avp *vp);
 
+/** Set AVP \a vp to byte \a val */
 int
 rs_avp_byte_set(rs_avp *vp, uint8_t val);
 
+/** Return short value of \a vp */
 uint16_t
 rs_avp_short_value(rs_const_avp *vp);
 
+/** Set AVP \a vp to short integer \a val */
 int
 rs_avp_short_set(rs_avp *vp, uint16_t val);
 
+/** Display possibly \a canonical attribute name into \a buffer */
+int
+rs_attr_display_name (unsigned int attr,
+                      unsigned int vendor,
+                      char *buffer,
+                      size_t bufsize,
+                      int canonical);
+
+/** Display AVP \a vp into \a buffer */
 size_t
 rs_avp_display_value(rs_const_avp *vp,
                      char *buffer,
                      size_t buflen);
 
 int
+rs_attr_parse_name (const char *name,
+		    unsigned int *attr,
+		    unsigned int *vendor);
+
+/** Lookup attribute \a name */
+int
 rs_attr_find(const char *name,
              unsigned int *attr,
              unsigned int *vendor);
 
+/** Return dictionary name for AVP \a vp */
 const char *
 rs_avp_name(rs_const_avp *vp);
 
diff --git a/lib/radius/Makefile.am b/lib/radius/Makefile.am
index b57ef16..92a12cf 100644
--- a/lib/radius/Makefile.am
+++ b/lib/radius/Makefile.am
@@ -22,6 +22,7 @@ libradsec_radius_la_CFLAGS = $(AM_CFLAGS) -DHAVE_CONFIG_H
 
 DICTIONARIES = \
 	share/dictionary.txt \
+	share/dictionary.juniper \
 	share/dictionary.microsoft \
 	share/dictionary.ukerna
 
diff --git a/lib/radius/share/dictionary.juniper b/lib/radius/share/dictionary.juniper
new file mode 100644
index 0000000..9aa5df4
--- /dev/null
+++ b/lib/radius/share/dictionary.juniper
@@ -0,0 +1,23 @@
+# -*- text -*-
+#
+#  dictionary.juniper
+#
+#	As posted to the list by Eric Kilfoil <ekilfoil@uslec.net>
+#
+# Version:	$Id$
+#
+
+VENDOR		Juniper				2636
+
+BEGIN-VENDOR	Juniper
+
+ATTRIBUTE	Juniper-Local-User-Name			1	string
+ATTRIBUTE	Juniper-Allow-Commands			2	string
+ATTRIBUTE	Juniper-Deny-Commands			3	string
+ATTRIBUTE	Juniper-Allow-Configuration		4	string
+ATTRIBUTE	Juniper-Deny-Configuration		5	string
+ATTRIBUTE	Juniper-Interactive-Command		8	string
+ATTRIBUTE	Juniper-Configuration-Change		9	string
+ATTRIBUTE	Juniper-User-Permissions		10	string
+
+END-VENDOR	Juniper
diff --git a/lib/radsec.sym b/lib/radsec.sym
index 5382409..f234082 100644
--- a/lib/radsec.sym
+++ b/lib/radsec.sym
@@ -1,4 +1,6 @@
+rs_attr_display_name
 rs_attr_find
+rs_attr_parse_name
 rs_avp_alloc
 rs_avp_append
 rs_avp_attrid
-- 
cgit v1.1