]> andersk Git - libfaim.git/blame - aim_tlv.c
- Sun Mar 19 06:07:52 UTC 2000
[libfaim.git] / aim_tlv.c
CommitLineData
a25832e6 1#include <faim/aim.h>
9de3ca7e 2
49c8a2fa 3struct aim_tlvlist_t *aim_readtlvchain(u_char *buf, int maxlen)
4{
5 int pos;
6 struct aim_tlvlist_t *list;
7 struct aim_tlvlist_t *cur;
8
9 u_short type;
10 u_short length;
11
12 if (!buf)
13 return NULL;
14
15 list = NULL;
16
17 pos = 0;
18
19 while (pos < maxlen)
20 {
21 type = aimutil_get16(buf+pos);
22 pos += 2;
23
24 if (pos < maxlen)
25 {
26 length = aimutil_get16(buf+pos);
27 pos += 2;
28
29 if ((pos+length) <= maxlen)
30 {
31 cur = (struct aim_tlvlist_t *)malloc(sizeof(struct aim_tlvlist_t));
32 memset(cur, 0x00, sizeof(struct aim_tlvlist_t));
33
0c20631f 34 cur->tlv = aim_createtlv();
49c8a2fa 35 cur->tlv->type = type;
36 cur->tlv->length = length;
37 cur->tlv->value = (u_char *)malloc(length*sizeof(u_char));
38 memcpy(cur->tlv->value, buf+pos, length);
39
40 cur->next = list;
41 list = cur;
42
43 pos += length;
44 }
45 }
46 }
47
48 return list;
49}
50
51void aim_freetlvchain(struct aim_tlvlist_t **list)
52{
53 struct aim_tlvlist_t *cur, *cur2;
54
55 if (!list || !(*list))
56 return;
57
58 cur = *list;
59 while (cur)
60 {
61 aim_freetlv(&cur->tlv);
62 cur2 = cur->next;
63 free(cur);
64 cur = cur2;
65 }
66 list = NULL;
67 return;
68}
69
0e2be272 70int aim_addtlvtochain_str(struct aim_tlvlist_t **list, unsigned short type, char *str)
71{
72 struct aim_tlvlist_t *new;
73 struct aim_tlvlist_t *cur;
74
75 if (!list)
76 return 0;
77
78 new = (struct aim_tlvlist_t *)malloc(sizeof(struct aim_tlvlist_t));
79 memset(new, 0x00, sizeof(struct aim_tlvlist_t));
80
81 new->tlv = aim_createtlv();
82 new->tlv->type = type;
83 new->tlv->length = strlen(str);
84 new->tlv->value = (u_char *)malloc(new->tlv->length*sizeof(u_char));
85 memcpy(new->tlv->value, str, new->tlv->length);
86
87 new->next = NULL;
88
89 if (*list == NULL) {
90 *list = new;
91 } else if ((*list)->next == NULL) {
92 (*list)->next = new;
93 } else {
94 for(cur = *list; cur->next; cur = cur->next)
95 ;
96 cur->next = new;
97 }
98 return new->tlv->length;
99}
100
101int aim_addtlvtochain16(struct aim_tlvlist_t **list, unsigned short type, unsigned short val)
102{
103 struct aim_tlvlist_t *new;
104 struct aim_tlvlist_t *cur;
105
106 if (!list)
107 return 0;
108
109 new = (struct aim_tlvlist_t *)malloc(sizeof(struct aim_tlvlist_t));
110 memset(new, 0x00, sizeof(struct aim_tlvlist_t));
111
112 new->tlv = aim_createtlv();
113 new->tlv->type = type;
114 new->tlv->length = 2;
115 new->tlv->value = (u_char *)malloc(new->tlv->length*sizeof(u_char));
116 aimutil_put16(new->tlv->value, val);
117
118 new->next = NULL;
119
120 if (*list == NULL) {
121 *list = new;
122 } else if ((*list)->next == NULL) {
123 (*list)->next = new;
124 } else {
125 for(cur = *list; cur->next; cur = cur->next)
126 ;
127 cur->next = new;
128 }
129 return 2;
130}
131
132int aim_addtlvtochain32(struct aim_tlvlist_t **list, unsigned short type, unsigned long val)
133{
134 struct aim_tlvlist_t *new;
135 struct aim_tlvlist_t *cur;
136
137 if (!list)
138 return 0;
139
140 new = (struct aim_tlvlist_t *)malloc(sizeof(struct aim_tlvlist_t));
141 memset(new, 0x00, sizeof(struct aim_tlvlist_t));
142
143 new->tlv = aim_createtlv();
144 new->tlv->type = type;
145 new->tlv->length = 4;
146 new->tlv->value = (u_char *)malloc(new->tlv->length*sizeof(u_char));
147 aimutil_put32(new->tlv->value, val);
148
149 new->next = NULL;
150
151 if (*list == NULL) {
152 *list = new;
153 } else if ((*list)->next == NULL) {
154 (*list)->next = new;
155 } else {
156 for(cur = *list; cur->next; cur = cur->next)
157 ;
158 cur->next = new;
159 }
160 return 4;
161}
162
163int aim_writetlvchain(u_char *buf, int buflen, struct aim_tlvlist_t **list)
164{
165 int goodbuflen = 0;
166 int i = 0;
167 struct aim_tlvlist_t *cur;
168
169 if (!list || !buf || !buflen)
170 return 0;
171
172 /* do an initial run to test total length */
173 for (cur = *list; cur; cur = cur->next) {
174 goodbuflen += 2 + 2; /* type + len */
175 goodbuflen += cur->tlv->length;
176 }
177
178 if (goodbuflen > buflen)
179 return 0; /* not enough buffer */
180
181 /* do the real write-out */
182 for (cur = *list; cur; cur = cur->next) {
183 i += aimutil_put16(buf+i, cur->tlv->type);
184 i += aimutil_put16(buf+i, cur->tlv->length);
185 memcpy(buf+i, cur->tlv->value, cur->tlv->length);
186 i += cur->tlv->length;
187 }
188
189 return i;
190}
191
192
49c8a2fa 193/*
194 * Grab the Nth TLV of type type in the TLV list list.
195 */
196struct aim_tlv_t *aim_gettlv(struct aim_tlvlist_t *list, u_short type, int nth)
197{
198 int i;
199 struct aim_tlvlist_t *cur;
200
201 i = 0;
202 for (cur = list; cur != NULL; cur = cur->next)
203 {
204 if (cur && cur->tlv)
205 {
206 if (cur->tlv->type == type)
207 i++;
208 if (i >= nth)
209 return cur->tlv;
210 }
211 }
212 return NULL;
213}
214
215char *aim_gettlv_str(struct aim_tlvlist_t *list, u_short type, int nth)
216{
217 struct aim_tlv_t *tlv;
218 char *newstr;
219
220 if (!(tlv = aim_gettlv(list, type, nth)))
221 return NULL;
222
223 newstr = (char *) malloc(tlv->length + 1);
224 memcpy(newstr, tlv->value, tlv->length);
225 *(newstr + tlv->length) = '\0';
226
227 return newstr;
228}
229
9de3ca7e 230struct aim_tlv_t *aim_grabtlv(u_char *src)
231{
232 struct aim_tlv_t *dest = NULL;
233
234 dest = aim_createtlv();
235
236 dest->type = src[0] << 8;
237 dest->type += src[1];
238
239 dest->length = src[2] << 8;
240 dest->length += src[3];
241
242 dest->value = (u_char *) malloc(dest->length*sizeof(u_char));
243 memset(dest->value, 0, dest->length*sizeof(u_char));
244
245 memcpy(dest->value, &(src[4]), dest->length*sizeof(u_char));
246
247 return dest;
248}
249
250struct aim_tlv_t *aim_grabtlvstr(u_char *src)
251{
252 struct aim_tlv_t *dest = NULL;
253
254 dest = aim_createtlv();
255
256 dest->type = src[0] << 8;
257 dest->type += src[1];
258
259 dest->length = src[2] << 8;
260 dest->length += src[3];
261
262 dest->value = (u_char *) malloc((dest->length+1)*sizeof(u_char));
263 memset(dest->value, 0, (dest->length+1)*sizeof(u_char));
264
265 memcpy(dest->value, &(src[4]), dest->length*sizeof(u_char));
266 dest->value[dest->length] = '\0';
267
268 return dest;
269}
270
271int aim_puttlv (u_char *dest, struct aim_tlv_t *newtlv)
272{
273 int i=0;
274
275 dest[i++] = newtlv->type >> 8;
276 dest[i++] = newtlv->type & 0x00FF;
277 dest[i++] = newtlv->length >> 8;
278 dest[i++] = newtlv->length & 0x00FF;
279 memcpy(&(dest[i]), newtlv->value, newtlv->length);
280 i+=newtlv->length;
281 return i;
282}
283
284struct aim_tlv_t *aim_createtlv(void)
285{
286 struct aim_tlv_t *newtlv = NULL;
287 newtlv = (struct aim_tlv_t *)malloc(sizeof(struct aim_tlv_t));
288 memset(newtlv, 0, sizeof(struct aim_tlv_t));
289 return newtlv;
290}
291
292int aim_freetlv(struct aim_tlv_t **oldtlv)
293{
294 if (!oldtlv)
295 return -1;
296 if (!*oldtlv)
297 return -1;
298 if ((*oldtlv)->value)
299 free((*oldtlv)->value);
300 free(*(oldtlv));
301 (*oldtlv) = NULL;
302
303 return 0;
304}
305
306int aim_puttlv_16(u_char *buf, u_short t, u_short v)
307{
308 int curbyte=0;
309 curbyte += aimutil_put16(buf+curbyte, (u_short)(t&0xffff));
310 curbyte += aimutil_put16(buf+curbyte, (u_short)0x0002);
311 curbyte += aimutil_put16(buf+curbyte, (u_short)(v&0xffff));
312 return curbyte;
313}
01b59e1e 314
315int aim_puttlv_32(u_char *buf, u_short t, u_long v)
316{
317 int curbyte=0;
318 curbyte += aimutil_put16(buf+curbyte, (u_short)(t&0xffff));
319 curbyte += aimutil_put16(buf+curbyte, (u_short)0x0004);
320 curbyte += aimutil_put32(buf+curbyte, (u_long)(v&0xffffffff));
321 return curbyte;
322}
323
324int aim_puttlv_str(u_char *buf, u_short t, u_short l, u_char *v)
325{
326 int curbyte;
01b59e1e 327
328 curbyte = 0;
329 curbyte += aimutil_put16(buf+curbyte, (u_short)(t&0xffff));
330 curbyte += aimutil_put16(buf+curbyte, (u_short)(l&0xffff));
0c20631f 331 if (v)
332 memcpy(buf+curbyte, v, l);
01b59e1e 333 curbyte += l;
334 return curbyte;
335}
This page took 4.460305 seconds and 5 git commands to generate.