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