radsecproxy-1.6.5.
[libradsec.git] / tlv11.c
1 /*
2  * Copyright (C) 2008 Stig Venaas <venaas@uninett.no>
3  * Copyright (C) 2010 NORDUnet A/S
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  */
9
10 #ifdef SYS_SOLARIS9
11 #include <sys/inttypes.h>
12 #else
13 #include <stdint.h>
14 #endif
15 #include "list.h"
16 #include "tlv11.h"
17 #include <stdlib.h>
18 #include <string.h>
19 #include <arpa/inet.h>
20
21 struct tlv *maketlv(uint8_t t, uint8_t l, void *v) {
22     struct tlv *tlv;
23
24     tlv = malloc(sizeof(struct tlv));
25     if (!tlv)
26         return NULL;
27     tlv->t = t;
28     tlv->l = l;
29     if (l && v) {
30         tlv->v = malloc(l);
31         if (!tlv->v) {
32             free(tlv);
33             return NULL;
34         }
35         memcpy(tlv->v, v, l);
36     } else
37         tlv->v = NULL;
38     return tlv;
39 }
40
41 struct tlv *copytlv(struct tlv *in) {
42     return in ? maketlv(in->t, in->l, in->v) : NULL;
43 }
44
45 void freetlv(struct tlv *tlv) {
46     if (tlv) {
47         free(tlv->v);
48         free(tlv);
49     }
50 }
51
52 int eqtlv(struct tlv *t1, struct tlv *t2) {
53     if (!t1 || !t2)
54         return t1 == t2;
55     if (t1->t != t2->t || t1->l != t2->l)
56         return 0;
57     return memcmp(t1->v, t2->v, t1->l) == 0;
58 }
59
60 struct list *copytlvlist(struct list *tlvs) {
61     struct list *out;
62     struct list_node *node;
63
64     if (!tlvs)
65         return NULL;
66     out = list_create();
67     if (!out)
68         return NULL;
69     for (node = list_first(tlvs); node; node = list_next(node)) {
70         if (!list_push(out, copytlv((struct tlv *)node->data))) {
71             freetlvlist(out);
72             return NULL;
73         }
74     }
75     return out;
76 }
77
78 void freetlvlist(struct list *tlvs) {
79     struct tlv *tlv;
80     while ((tlv = (struct tlv *)list_shift(tlvs)))
81         freetlv(tlv);
82     list_destroy(tlvs);
83 }
84
85 void rmtlv(struct list *tlvs, uint8_t t) {
86     struct list_node *n, *p;
87     struct tlv *tlv;
88
89     p = NULL;
90     n = list_first(tlvs);
91     while (n) {
92         tlv = (struct tlv *)n->data;
93         if (tlv->t == t) {
94             list_removedata(tlvs, tlv);
95             freetlv(tlv);
96             n = p ? list_next(p) : list_first(tlvs);
97         } else {
98             p = n;
99             n = list_next(n);
100         }
101     }
102 }
103
104 uint8_t *tlv2str(struct tlv *tlv) {
105     uint8_t *s = malloc(tlv->l + 1);
106     if (s) {
107         memcpy(s, tlv->v, tlv->l);
108         s[tlv->l] = '\0';
109     }
110     return s;
111 }
112
113 uint8_t *tlv2buf(uint8_t *p, const struct tlv *tlv) {
114     *p++ = tlv->t;
115     *p++ = tlv->l;
116     if (tlv->l) {
117         if (tlv->v)
118             memcpy(p, tlv->v, tlv->l);
119         else
120             memset(p, 0, tlv->l);
121     }
122     return p;
123 }
124
125 /* Local Variables: */
126 /* c-file-style: "stroustrup" */
127 /* End: */