]> andersk Git - libfaim.git/blame - aim_tlv.c
- Mon Jul 17 01:56:31 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 {
13ebc4c4 31 /*
32 * Okay, so now AOL has decided that any TLV of
33 * type 0x0013 can only be two bytes, despite
34 * what the actual given length is. So here
35 * we dump any invalid TLVs of that sort. Hopefully
36 * theres no special cases to this special case.
37 * - mid (30jun2000)
38 */
39 if ((type == 0x0013) && (length != 0x0002)) {
40 printf("faim: skipping TLV t(0013) with invalid length (0x%04x)\n", length);
41 length = 0x0002;
42 } else {
43 cur = (struct aim_tlvlist_t *)malloc(sizeof(struct aim_tlvlist_t));
44 memset(cur, 0x00, sizeof(struct aim_tlvlist_t));
49c8a2fa 45
13ebc4c4 46 cur->tlv = aim_createtlv();
47 cur->tlv->type = type;
48 cur->tlv->length = length;
49 cur->tlv->value = (u_char *)malloc(length*sizeof(u_char));
50 memcpy(cur->tlv->value, buf+pos, length);
49c8a2fa 51
13ebc4c4 52 cur->next = list;
53 list = cur;
54 }
49c8a2fa 55 pos += length;
56 }
57 }
58 }
59
60 return list;
61}
62
63void aim_freetlvchain(struct aim_tlvlist_t **list)
64{
65 struct aim_tlvlist_t *cur, *cur2;
66
67 if (!list || !(*list))
68 return;
69
70 cur = *list;
71 while (cur)
72 {
73 aim_freetlv(&cur->tlv);
74 cur2 = cur->next;
75 free(cur);
76 cur = cur2;
77 }
78 list = NULL;
79 return;
80}
81
e6b05d80 82int aim_counttlvchain(struct aim_tlvlist_t **list)
83{
84 struct aim_tlvlist_t *cur;
85 int count = 0;
86
87 if (!list || !(*list))
88 return 0;
89
90 for (cur = *list; cur; cur = cur->next)
91 count++;
92
93 return count;
94}
95
96int aim_addtlvtochain_str(struct aim_tlvlist_t **list, unsigned short type, char *str, int len)
0e2be272 97{
98 struct aim_tlvlist_t *new;
99 struct aim_tlvlist_t *cur;
100
101 if (!list)
102 return 0;
103
104 new = (struct aim_tlvlist_t *)malloc(sizeof(struct aim_tlvlist_t));
105 memset(new, 0x00, sizeof(struct aim_tlvlist_t));
106
107 new->tlv = aim_createtlv();
108 new->tlv->type = type;
e6b05d80 109 new->tlv->length = len;
0e2be272 110 new->tlv->value = (u_char *)malloc(new->tlv->length*sizeof(u_char));
111 memcpy(new->tlv->value, str, new->tlv->length);
112
113 new->next = NULL;
114
115 if (*list == NULL) {
116 *list = new;
117 } else if ((*list)->next == NULL) {
118 (*list)->next = new;
119 } else {
120 for(cur = *list; cur->next; cur = cur->next)
121 ;
122 cur->next = new;
123 }
124 return new->tlv->length;
125}
126
127int aim_addtlvtochain16(struct aim_tlvlist_t **list, unsigned short type, unsigned short val)
128{
129 struct aim_tlvlist_t *new;
130 struct aim_tlvlist_t *cur;
131
132 if (!list)
133 return 0;
134
135 new = (struct aim_tlvlist_t *)malloc(sizeof(struct aim_tlvlist_t));
136 memset(new, 0x00, sizeof(struct aim_tlvlist_t));
137
138 new->tlv = aim_createtlv();
139 new->tlv->type = type;
140 new->tlv->length = 2;
141 new->tlv->value = (u_char *)malloc(new->tlv->length*sizeof(u_char));
142 aimutil_put16(new->tlv->value, val);
143
144 new->next = NULL;
145
146 if (*list == NULL) {
147 *list = new;
148 } else if ((*list)->next == NULL) {
149 (*list)->next = new;
150 } else {
151 for(cur = *list; cur->next; cur = cur->next)
152 ;
153 cur->next = new;
154 }
155 return 2;
156}
157
158int aim_addtlvtochain32(struct aim_tlvlist_t **list, unsigned short type, unsigned long val)
159{
160 struct aim_tlvlist_t *new;
161 struct aim_tlvlist_t *cur;
162
163 if (!list)
164 return 0;
165
166 new = (struct aim_tlvlist_t *)malloc(sizeof(struct aim_tlvlist_t));
167 memset(new, 0x00, sizeof(struct aim_tlvlist_t));
168
169 new->tlv = aim_createtlv();
170 new->tlv->type = type;
171 new->tlv->length = 4;
172 new->tlv->value = (u_char *)malloc(new->tlv->length*sizeof(u_char));
173 aimutil_put32(new->tlv->value, val);
174
175 new->next = NULL;
176
177 if (*list == NULL) {
178 *list = new;
179 } else if ((*list)->next == NULL) {
180 (*list)->next = new;
181 } else {
182 for(cur = *list; cur->next; cur = cur->next)
183 ;
184 cur->next = new;
185 }
186 return 4;
187}
188
189int aim_writetlvchain(u_char *buf, int buflen, struct aim_tlvlist_t **list)
190{
191 int goodbuflen = 0;
192 int i = 0;
193 struct aim_tlvlist_t *cur;
194
195 if (!list || !buf || !buflen)
196 return 0;
197
198 /* do an initial run to test total length */
199 for (cur = *list; cur; cur = cur->next) {
200 goodbuflen += 2 + 2; /* type + len */
201 goodbuflen += cur->tlv->length;
202 }
203
204 if (goodbuflen > buflen)
205 return 0; /* not enough buffer */
206
207 /* do the real write-out */
208 for (cur = *list; cur; cur = cur->next) {
209 i += aimutil_put16(buf+i, cur->tlv->type);
210 i += aimutil_put16(buf+i, cur->tlv->length);
211 memcpy(buf+i, cur->tlv->value, cur->tlv->length);
212 i += cur->tlv->length;
213 }
214
215 return i;
216}
217
218
49c8a2fa 219/*
220 * Grab the Nth TLV of type type in the TLV list list.
221 */
222struct aim_tlv_t *aim_gettlv(struct aim_tlvlist_t *list, u_short type, int nth)
223{
224 int i;
225 struct aim_tlvlist_t *cur;
226
227 i = 0;
228 for (cur = list; cur != NULL; cur = cur->next)
229 {
230 if (cur && cur->tlv)
231 {
232 if (cur->tlv->type == type)
233 i++;
234 if (i >= nth)
235 return cur->tlv;
236 }
237 }
238 return NULL;
239}
240
241char *aim_gettlv_str(struct aim_tlvlist_t *list, u_short type, int nth)
242{
243 struct aim_tlv_t *tlv;
244 char *newstr;
245
246 if (!(tlv = aim_gettlv(list, type, nth)))
247 return NULL;
248
249 newstr = (char *) malloc(tlv->length + 1);
250 memcpy(newstr, tlv->value, tlv->length);
251 *(newstr + tlv->length) = '\0';
252
253 return newstr;
254}
255
9de3ca7e 256struct aim_tlv_t *aim_grabtlv(u_char *src)
257{
258 struct aim_tlv_t *dest = NULL;
259
260 dest = aim_createtlv();
261
262 dest->type = src[0] << 8;
263 dest->type += src[1];
264
265 dest->length = src[2] << 8;
266 dest->length += src[3];
267
268 dest->value = (u_char *) malloc(dest->length*sizeof(u_char));
269 memset(dest->value, 0, dest->length*sizeof(u_char));
270
271 memcpy(dest->value, &(src[4]), dest->length*sizeof(u_char));
272
273 return dest;
274}
275
276struct aim_tlv_t *aim_grabtlvstr(u_char *src)
277{
278 struct aim_tlv_t *dest = NULL;
279
280 dest = aim_createtlv();
281
282 dest->type = src[0] << 8;
283 dest->type += src[1];
284
285 dest->length = src[2] << 8;
286 dest->length += src[3];
287
288 dest->value = (u_char *) malloc((dest->length+1)*sizeof(u_char));
289 memset(dest->value, 0, (dest->length+1)*sizeof(u_char));
290
291 memcpy(dest->value, &(src[4]), dest->length*sizeof(u_char));
292 dest->value[dest->length] = '\0';
293
294 return dest;
295}
296
297int aim_puttlv (u_char *dest, struct aim_tlv_t *newtlv)
298{
299 int i=0;
300
301 dest[i++] = newtlv->type >> 8;
302 dest[i++] = newtlv->type & 0x00FF;
303 dest[i++] = newtlv->length >> 8;
304 dest[i++] = newtlv->length & 0x00FF;
305 memcpy(&(dest[i]), newtlv->value, newtlv->length);
306 i+=newtlv->length;
307 return i;
308}
309
310struct aim_tlv_t *aim_createtlv(void)
311{
312 struct aim_tlv_t *newtlv = NULL;
313 newtlv = (struct aim_tlv_t *)malloc(sizeof(struct aim_tlv_t));
314 memset(newtlv, 0, sizeof(struct aim_tlv_t));
315 return newtlv;
316}
317
318int aim_freetlv(struct aim_tlv_t **oldtlv)
319{
320 if (!oldtlv)
321 return -1;
322 if (!*oldtlv)
323 return -1;
324 if ((*oldtlv)->value)
325 free((*oldtlv)->value);
326 free(*(oldtlv));
327 (*oldtlv) = NULL;
328
329 return 0;
330}
331
332int aim_puttlv_16(u_char *buf, u_short t, u_short v)
333{
334 int curbyte=0;
335 curbyte += aimutil_put16(buf+curbyte, (u_short)(t&0xffff));
336 curbyte += aimutil_put16(buf+curbyte, (u_short)0x0002);
337 curbyte += aimutil_put16(buf+curbyte, (u_short)(v&0xffff));
338 return curbyte;
339}
01b59e1e 340
341int aim_puttlv_32(u_char *buf, u_short t, u_long v)
342{
343 int curbyte=0;
344 curbyte += aimutil_put16(buf+curbyte, (u_short)(t&0xffff));
345 curbyte += aimutil_put16(buf+curbyte, (u_short)0x0004);
346 curbyte += aimutil_put32(buf+curbyte, (u_long)(v&0xffffffff));
347 return curbyte;
348}
349
350int aim_puttlv_str(u_char *buf, u_short t, u_short l, u_char *v)
351{
352 int curbyte;
01b59e1e 353
354 curbyte = 0;
355 curbyte += aimutil_put16(buf+curbyte, (u_short)(t&0xffff));
356 curbyte += aimutil_put16(buf+curbyte, (u_short)(l&0xffff));
0c20631f 357 if (v)
358 memcpy(buf+curbyte, v, l);
01b59e1e 359 curbyte += l;
360 return curbyte;
361}
This page took 1.801587 seconds and 5 git commands to generate.