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_internal int aim_addtlvtochain_str(struct aim_tlvlist_t **list, unsigned short type, char *str, int len)
100 struct aim_tlvlist_t *new;
101 struct aim_tlvlist_t *cur;
106 new = (struct aim_tlvlist_t *)malloc(sizeof(struct aim_tlvlist_t));
107 memset(new, 0x00, sizeof(struct aim_tlvlist_t));
109 new->tlv = aim_createtlv();
110 new->tlv->type = type;
111 new->tlv->length = len;
112 new->tlv->value = (u_char *)malloc(new->tlv->length*sizeof(u_char));
113 memcpy(new->tlv->value, str, new->tlv->length);
119 } else if ((*list)->next == NULL) {
122 for(cur = *list; cur->next; cur = cur->next)
126 return new->tlv->length;
129 faim_internal int aim_addtlvtochain16(struct aim_tlvlist_t **list, unsigned short type, unsigned short val)
131 struct aim_tlvlist_t *new;
132 struct aim_tlvlist_t *cur;
137 new = (struct aim_tlvlist_t *)malloc(sizeof(struct aim_tlvlist_t));
138 memset(new, 0x00, sizeof(struct aim_tlvlist_t));
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);
150 } else if ((*list)->next == NULL) {
153 for(cur = *list; cur->next; cur = cur->next)
160 faim_internal int aim_addtlvtochain32(struct aim_tlvlist_t **list, unsigned short type, unsigned long val)
162 struct aim_tlvlist_t *new;
163 struct aim_tlvlist_t *cur;
168 new = (struct aim_tlvlist_t *)malloc(sizeof(struct aim_tlvlist_t));
169 memset(new, 0x00, sizeof(struct aim_tlvlist_t));
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);
181 } else if ((*list)->next == NULL) {
184 for(cur = *list; cur->next; cur = cur->next)
191 faim_internal int aim_writetlvchain(u_char *buf, int buflen, struct aim_tlvlist_t **list)
195 struct aim_tlvlist_t *cur;
197 if (!list || !buf || !buflen)
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;
206 if (goodbuflen > buflen)
207 return 0; /* not enough buffer */
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;
222 * Grab the Nth TLV of type type in the TLV list list.
224 faim_internal struct aim_tlv_t *aim_gettlv(struct aim_tlvlist_t *list, u_short type, int nth)
227 struct aim_tlvlist_t *cur;
230 for (cur = list; cur != NULL; cur = cur->next)
234 if (cur->tlv->type == type)
243 faim_internal char *aim_gettlv_str(struct aim_tlvlist_t *list, u_short type, int nth)
245 struct aim_tlv_t *tlv;
248 if (!(tlv = aim_gettlv(list, type, nth)))
251 newstr = (char *) malloc(tlv->length + 1);
252 memcpy(newstr, tlv->value, tlv->length);
253 *(newstr + tlv->length) = '\0';
258 faim_internal struct aim_tlv_t *aim_grabtlv(u_char *src)
260 struct aim_tlv_t *dest = NULL;
262 dest = aim_createtlv();
264 dest->type = src[0] << 8;
265 dest->type += src[1];
267 dest->length = src[2] << 8;
268 dest->length += src[3];
270 dest->value = (u_char *) malloc(dest->length*sizeof(u_char));
271 memset(dest->value, 0, dest->length*sizeof(u_char));
273 memcpy(dest->value, &(src[4]), dest->length*sizeof(u_char));
278 faim_internal struct aim_tlv_t *aim_grabtlvstr(u_char *src)
280 struct aim_tlv_t *dest = NULL;
282 dest = aim_createtlv();
284 dest->type = src[0] << 8;
285 dest->type += src[1];
287 dest->length = src[2] << 8;
288 dest->length += src[3];
290 dest->value = (u_char *) malloc((dest->length+1)*sizeof(u_char));
291 memset(dest->value, 0, (dest->length+1)*sizeof(u_char));
293 memcpy(dest->value, &(src[4]), dest->length*sizeof(u_char));
294 dest->value[dest->length] = '\0';
299 faim_internal int aim_puttlv(u_char *dest, struct aim_tlv_t *newtlv)
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);
312 faim_internal struct aim_tlv_t *aim_createtlv(void)
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));
320 faim_internal int aim_freetlv(struct aim_tlv_t **oldtlv)
326 if ((*oldtlv)->value)
327 free((*oldtlv)->value);
334 faim_internal int aim_puttlv_16(u_char *buf, u_short t, u_short v)
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));
343 faim_internal int aim_puttlv_32(u_char *buf, u_short t, u_long v)
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));
352 faim_internal int aim_puttlv_str(u_char *buf, u_short t, int l, char *v)
357 curbyte += aimutil_put16(buf+curbyte, (u_short)(t&0xffff));
358 curbyte += aimutil_put16(buf+curbyte, (u_short)(l&0xffff));
360 memcpy(buf+curbyte, (unsigned char *)v, l);