1 /* Copyright (c) 2008-2009, UNINETT AS
2 * Copyright (c) 2010, NORDUnet A/S */
3 /* See LICENSE for licensing information. */
4
5 #ifdef SYS_SOLARIS9
6 #include <sys/inttypes.h>
7 #else
8 #include <stdint.h>
9 #endif
10 #include "list.h"
11 #include "tlv11.h"
12 #include <stdlib.h>
13 #include <string.h>
14 #include <arpa/inet.h>
15
maketlv(uint8_t t,uint8_t l,void * v)16 struct tlv *maketlv(uint8_t t, uint8_t l, void *v) {
17 struct tlv *tlv;
18
19 tlv = malloc(sizeof(struct tlv));
20 if (!tlv)
21 return NULL;
22 tlv->t = t;
23 tlv->l = l;
24 if (l && v) {
25 tlv->v = malloc(l);
26 if (!tlv->v) {
27 free(tlv);
28 return NULL;
29 }
30 memcpy(tlv->v, v, l);
31 } else
32 tlv->v = NULL;
33 return tlv;
34 }
35
copytlv(struct tlv * in)36 struct tlv *copytlv(struct tlv *in) {
37 return in ? maketlv(in->t, in->l, in->v) : NULL;
38 }
39
freetlv(struct tlv * tlv)40 void freetlv(struct tlv *tlv) {
41 if (tlv) {
42 free(tlv->v);
43 free(tlv);
44 }
45 }
46
eqtlv(struct tlv * t1,struct tlv * t2)47 int eqtlv(struct tlv *t1, struct tlv *t2) {
48 if (!t1 || !t2)
49 return t1 == t2;
50 if (t1->t != t2->t || t1->l != t2->l)
51 return 0;
52 return memcmp(t1->v, t2->v, t1->l) == 0;
53 }
54
copytlvlist(struct list * tlvs)55 struct list *copytlvlist(struct list *tlvs) {
56 struct list *out;
57 struct list_node *node;
58
59 if (!tlvs)
60 return NULL;
61 out = list_create();
62 if (!out)
63 return NULL;
64 for (node = list_first(tlvs); node; node = list_next(node)) {
65 if (!list_push(out, copytlv((struct tlv *)node->data))) {
66 freetlvlist(out);
67 return NULL;
68 }
69 }
70 return out;
71 }
72
freetlvlist(struct list * tlvs)73 void freetlvlist(struct list *tlvs) {
74 struct tlv *tlv;
75 while ((tlv = (struct tlv *)list_shift(tlvs)))
76 freetlv(tlv);
77 list_destroy(tlvs);
78 }
79
rmtlv(struct list * tlvs,uint8_t t)80 void rmtlv(struct list *tlvs, uint8_t t) {
81 struct list_node *n, *p;
82 struct tlv *tlv;
83
84 p = NULL;
85 n = list_first(tlvs);
86 while (n) {
87 tlv = (struct tlv *)n->data;
88 if (tlv->t == t) {
89 list_removedata(tlvs, tlv);
90 freetlv(tlv);
91 n = p ? list_next(p) : list_first(tlvs);
92 } else {
93 p = n;
94 n = list_next(n);
95 }
96 }
97 }
98
tlv2str(struct tlv * tlv)99 uint8_t *tlv2str(struct tlv *tlv) {
100 uint8_t *s = malloc(tlv->l + 1);
101 if (s) {
102 memcpy(s, tlv->v, tlv->l);
103 s[tlv->l] = '\0';
104 }
105 return s;
106 }
107
resizetlv(struct tlv * tlv,uint8_t newlen)108 struct tlv *resizetlv(struct tlv *tlv, uint8_t newlen) {
109 uint8_t *newv;
110 if (newlen != tlv->l) {
111 newv = realloc(tlv->v, newlen);
112 if (newlen && !newv)
113 return NULL;
114 tlv->v = newv;
115 tlv->l = newlen;
116 }
117 return tlv;
118 }
119
120 /* Local Variables: */
121 /* c-file-style: "stroustrup" */
122 /* End: */
123