3 faim_internal struct aim_tlvlist_t *aim_readtlvchain(u_char *buf, int maxlen)
6 struct aim_tlvlist_t *list;
7 struct aim_tlvlist_t *cur;
21 type = aimutil_get16(buf+pos);
26 length = aimutil_get16(buf+pos);
29 if ((pos+length) <= maxlen)
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.
39 if ((type == 0x0013) && (length != 0x0002)) {
40 printf("faim: skipping TLV t(0013) with invalid length (0x%04x)\n", length);
43 cur = (struct aim_tlvlist_t *)malloc(sizeof(struct aim_tlvlist_t));
44 memset(cur, 0x00, sizeof(struct aim_tlvlist_t));
46 cur->tlv = aim_createtlv();
47 cur->tlv->type = type;
48 cur->tlv->length = length;
50 cur->tlv->value = (unsigned char *)malloc(length);
51 memcpy(cur->tlv->value, buf+pos, length);
65 faim_internal void aim_freetlvchain(struct aim_tlvlist_t **list)
67 struct aim_tlvlist_t *cur, *cur2;
69 if (!list || !(*list))
75 aim_freetlv(&cur->tlv);
84 faim_internal int aim_counttlvchain(struct aim_tlvlist_t **list)
86 struct aim_tlvlist_t *cur;
89 if (!list || !(*list))
92 for (cur = *list; cur; cur = cur->next)
98 faim_export int aim_sizetlvchain(struct aim_tlvlist_t **list)
100 struct aim_tlvlist_t *cur;
103 if (!list || !(*list))
106 for (cur = *list; cur; cur = cur->next)
107 size += (4 + cur->tlv->length);
113 faim_internal int aim_addtlvtochain_str(struct aim_tlvlist_t **list, unsigned short type, char *str, int len)
115 struct aim_tlvlist_t *newtlv;
116 struct aim_tlvlist_t *cur;
121 newtlv = (struct aim_tlvlist_t *)malloc(sizeof(struct aim_tlvlist_t));
122 memset(newtlv, 0x00, sizeof(struct aim_tlvlist_t));
124 newtlv->tlv = aim_createtlv();
125 newtlv->tlv->type = type;
126 newtlv->tlv->length = len;
127 newtlv->tlv->value = (unsigned char *)malloc(newtlv->tlv->length*sizeof(unsigned char));
128 memcpy(newtlv->tlv->value, str, newtlv->tlv->length);
134 } else if ((*list)->next == NULL) {
135 (*list)->next = newtlv;
137 for(cur = *list; cur->next; cur = cur->next)
141 return newtlv->tlv->length;
144 faim_internal int aim_addtlvtochain16(struct aim_tlvlist_t **list, unsigned short type, unsigned short val)
146 struct aim_tlvlist_t *newtl;
147 struct aim_tlvlist_t *cur;
152 newtl = (struct aim_tlvlist_t *)malloc(sizeof(struct aim_tlvlist_t));
153 memset(newtl, 0x00, sizeof(struct aim_tlvlist_t));
155 newtl->tlv = aim_createtlv();
156 newtl->tlv->type = type;
157 newtl->tlv->length = 2;
158 newtl->tlv->value = (unsigned char *)malloc(newtl->tlv->length*sizeof(unsigned char));
159 aimutil_put16(newtl->tlv->value, val);
165 } else if ((*list)->next == NULL) {
166 (*list)->next = newtl;
168 for(cur = *list; cur->next; cur = cur->next)
175 faim_internal int aim_addtlvtochain32(struct aim_tlvlist_t **list, unsigned short type, unsigned long val)
177 struct aim_tlvlist_t *newtl;
178 struct aim_tlvlist_t *cur;
183 newtl = (struct aim_tlvlist_t *)malloc(sizeof(struct aim_tlvlist_t));
184 memset(newtl, 0x00, sizeof(struct aim_tlvlist_t));
186 newtl->tlv = aim_createtlv();
187 newtl->tlv->type = type;
188 newtl->tlv->length = 4;
189 newtl->tlv->value = (unsigned char *)malloc(newtl->tlv->length*sizeof(unsigned char));
190 aimutil_put32(newtl->tlv->value, val);
196 } else if ((*list)->next == NULL) {
197 (*list)->next = newtl;
199 for(cur = *list; cur->next; cur = cur->next)
206 faim_internal int aim_addtlvtochain_caps(struct aim_tlvlist_t **list, unsigned short type, unsigned short caps)
208 unsigned char buf[128]; /* icky fixed length buffer */
209 struct aim_tlvlist_t *newtl;
210 struct aim_tlvlist_t *cur;
215 newtl = (struct aim_tlvlist_t *)malloc(sizeof(struct aim_tlvlist_t));
216 memset(newtl, 0x00, sizeof(struct aim_tlvlist_t));
218 newtl->tlv = aim_createtlv();
219 newtl->tlv->type = type;
221 newtl->tlv->length = aim_putcap(buf, sizeof(buf), caps);
222 newtl->tlv->value = (unsigned char *)calloc(1, newtl->tlv->length);
223 memcpy(newtl->tlv->value, buf, newtl->tlv->length);
229 } else if ((*list)->next == NULL) {
230 (*list)->next = newtl;
232 for(cur = *list; cur->next; cur = cur->next)
236 return newtl->tlv->length;
239 faim_internal int aim_writetlvchain(u_char *buf, int buflen, struct aim_tlvlist_t **list)
243 struct aim_tlvlist_t *cur;
245 if (!list || !buf || !buflen)
248 /* do an initial run to test total length */
249 for (cur = *list; cur; cur = cur->next) {
250 goodbuflen += 2 + 2; /* type + len */
251 goodbuflen += cur->tlv->length;
254 if (goodbuflen > buflen)
255 return 0; /* not enough buffer */
257 /* do the real write-out */
258 for (cur = *list; cur; cur = cur->next) {
259 i += aimutil_put16(buf+i, cur->tlv->type);
260 i += aimutil_put16(buf+i, cur->tlv->length);
261 memcpy(buf+i, cur->tlv->value, cur->tlv->length);
262 i += cur->tlv->length;
270 * Grab the Nth TLV of type type in the TLV list list.
272 faim_internal struct aim_tlv_t *aim_gettlv(struct aim_tlvlist_t *list, u_short type, int nth)
275 struct aim_tlvlist_t *cur;
278 for (cur = list; cur != NULL; cur = cur->next)
282 if (cur->tlv->type == type)
291 faim_internal char *aim_gettlv_str(struct aim_tlvlist_t *list, u_short type, int nth)
293 struct aim_tlv_t *tlv;
296 if (!(tlv = aim_gettlv(list, type, nth)))
299 newstr = (char *) malloc(tlv->length + 1);
300 memcpy(newstr, tlv->value, tlv->length);
301 *(newstr + tlv->length) = '\0';
306 faim_internal struct aim_tlv_t *aim_grabtlv(u_char *src)
308 struct aim_tlv_t *dest = NULL;
310 dest = aim_createtlv();
312 dest->type = src[0] << 8;
313 dest->type += src[1];
315 dest->length = src[2] << 8;
316 dest->length += src[3];
318 dest->value = (u_char *) malloc(dest->length*sizeof(u_char));
319 memset(dest->value, 0, dest->length*sizeof(u_char));
321 memcpy(dest->value, &(src[4]), dest->length*sizeof(u_char));
326 faim_internal struct aim_tlv_t *aim_grabtlvstr(u_char *src)
328 struct aim_tlv_t *dest = NULL;
330 dest = aim_createtlv();
332 dest->type = src[0] << 8;
333 dest->type += src[1];
335 dest->length = src[2] << 8;
336 dest->length += src[3];
338 dest->value = (u_char *) malloc((dest->length+1)*sizeof(u_char));
339 memset(dest->value, 0, (dest->length+1)*sizeof(u_char));
341 memcpy(dest->value, &(src[4]), dest->length*sizeof(u_char));
342 dest->value[dest->length] = '\0';
347 faim_internal int aim_puttlv(u_char *dest, struct aim_tlv_t *newtlv)
351 dest[i++] = newtlv->type >> 8;
352 dest[i++] = newtlv->type & 0x00FF;
353 dest[i++] = newtlv->length >> 8;
354 dest[i++] = newtlv->length & 0x00FF;
355 memcpy(&(dest[i]), newtlv->value, newtlv->length);
360 faim_internal struct aim_tlv_t *aim_createtlv(void)
362 struct aim_tlv_t *newtlv = NULL;
363 newtlv = (struct aim_tlv_t *)malloc(sizeof(struct aim_tlv_t));
364 memset(newtlv, 0, sizeof(struct aim_tlv_t));
368 faim_internal int aim_freetlv(struct aim_tlv_t **oldtlv)
374 if ((*oldtlv)->value)
375 free((*oldtlv)->value);
382 faim_internal int aim_puttlv_16(u_char *buf, u_short t, u_short v)
385 curbyte += aimutil_put16(buf+curbyte, (u_short)(t&0xffff));
386 curbyte += aimutil_put16(buf+curbyte, (u_short)0x0002);
387 curbyte += aimutil_put16(buf+curbyte, (u_short)(v&0xffff));
391 faim_internal int aim_puttlv_32(u_char *buf, u_short t, u_long v)
394 curbyte += aimutil_put16(buf+curbyte, (u_short)(t&0xffff));
395 curbyte += aimutil_put16(buf+curbyte, (u_short)0x0004);
396 curbyte += aimutil_put32(buf+curbyte, (u_long)(v&0xffffffff));
400 faim_internal int aim_puttlv_str(u_char *buf, u_short t, int l, char *v)
405 curbyte += aimutil_put16(buf+curbyte, (u_short)(t&0xffff));
406 curbyte += aimutil_put16(buf+curbyte, (u_short)(l&0xffff));
408 memcpy(buf+curbyte, (unsigned char *)v, l);