summaryrefslogtreecommitdiff
path: root/tlv11.c
diff options
context:
space:
mode:
authorvenaas <venaas>2008-09-11 10:38:51 +0000
committervenaas <venaas@e88ac4ed-0b26-0410-9574-a7f39faa03bf>2008-09-11 10:38:51 +0000
commitfaf8717dcbc9c2e3ed1892402133b6c9663a5e7d (patch)
tree3085f5bd29b9c68d8ae94892b91d78586cd89a95 /tlv11.c
parenta98c9b737c943e062efa1a4fc7b31d539e1a2f11 (diff)
lots of changes to radsrv/reply and use of new radmsg stuff
git-svn-id: https://svn.testnett.uninett.no/radsecproxy/trunk@373 e88ac4ed-0b26-0410-9574-a7f39faa03bf
Diffstat (limited to 'tlv11.c')
-rw-r--r--tlv11.c118
1 files changed, 118 insertions, 0 deletions
diff --git a/tlv11.c b/tlv11.c
new file mode 100644
index 0000000..2593c15
--- /dev/null
+++ b/tlv11.c
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2008 Stig Venaas <venaas@uninett.no>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ */
+
+#include <stdint.h>
+#include "list.h"
+#include "tlv11.h"
+#include <stdlib.h>
+#include <string.h>
+#include <arpa/inet.h>
+
+struct tlv *maketlv(uint8_t t, uint8_t l, void *v) {
+ struct tlv *tlv;
+
+ tlv = malloc(sizeof(struct tlv));
+ if (!tlv)
+ return NULL;
+ tlv->t = t;
+ tlv->l = l;
+ if (l && v) {
+ tlv->v = malloc(l);
+ if (!tlv->v) {
+ free(tlv);
+ return NULL;
+ }
+ memcpy(tlv->v, v, l);
+ } else
+ tlv->v = NULL;
+ return tlv;
+}
+
+struct tlv *copytlv(struct tlv *in) {
+ return in ? maketlv(in->t, in->l, in->v) : NULL;
+}
+
+void freetlv(struct tlv *tlv) {
+ if (tlv) {
+ free(tlv->v);
+ free(tlv);
+ }
+}
+
+int eqtlv(struct tlv *t1, struct tlv *t2) {
+ if (!t1 || !t2)
+ return t1 == t2;
+ if (t1->t != t2->t || t1->l != t2->l)
+ return 0;
+ return memcmp(t1->v, t2->v, t1->l) == 0;
+}
+
+struct list *copytlvlist(struct list *tlvs) {
+ struct list *out;
+ struct list_node *node;
+
+ if (!tlvs)
+ return NULL;
+ out = list_create();
+ if (!out)
+ return NULL;
+ for (node = list_first(tlvs); node; node = list_next(node)) {
+ if (!list_push(out, copytlv((struct tlv *)node->data))) {
+ freetlvlist(out);
+ return NULL;
+ }
+ }
+ return out;
+}
+
+void freetlvlist(struct list *tlvs) {
+ struct tlv *tlv;
+ while ((tlv = (struct tlv *)list_shift(tlvs)))
+ freetlv(tlv);
+ list_destroy(tlvs);
+}
+
+void rmtlv(struct list *tlvs, uint8_t t) {
+ struct list_node *n, *p;
+ struct tlv *tlv;
+
+ p = NULL;
+ n = list_first(tlvs);
+ while (n) {
+ tlv = (struct tlv *)n->data;
+ if (tlv->t == t) {
+ list_removedata(tlvs, tlv);
+ freetlv(tlv);
+ n = p ? list_next(p) : list_first(tlvs);
+ } else {
+ p = n;
+ n = list_next(n);
+ }
+ }
+}
+
+uint8_t *tlv2str(struct tlv *tlv) {
+ uint8_t *s = malloc(tlv->l + 1);
+ if (s) {
+ memcpy(s, tlv->v, tlv->l);
+ s[tlv->l] = '\0';
+ }
+ return s;
+}
+
+uint8_t *tlv2buf(uint8_t *p, struct tlv *tlv) {
+ *p++ = tlv->t;
+ *p++ = tlv->l;
+ if (tlv->l) {
+ if (tlv->v)
+ memcpy(p, tlv->v, tlv->l);
+ else
+ memset(p, 0, tlv->l);
+ }
+ return p;
+}