3 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;
49 cur->tlv->value = (u_char *)malloc(length*sizeof(u_char));
50 memcpy(cur->tlv->value, buf+pos, length);
63 void aim_freetlvchain(struct aim_tlvlist_t **list)
65 struct aim_tlvlist_t *cur, *cur2;
67 if (!list || !(*list))
73 aim_freetlv(&cur->tlv);
82 int aim_counttlvchain(struct aim_tlvlist_t **list)
84 struct aim_tlvlist_t *cur;
87 if (!list || !(*list))
90 for (cur = *list; cur; cur = cur->next)
96 int aim_addtlvtochain_str(struct aim_tlvlist_t **list, unsigned short type, char *str, int len)
98 struct aim_tlvlist_t *new;
99 struct aim_tlvlist_t *cur;
104 new = (struct aim_tlvlist_t *)malloc(sizeof(struct aim_tlvlist_t));
105 memset(new, 0x00, sizeof(struct aim_tlvlist_t));
107 new->tlv = aim_createtlv();
108 new->tlv->type = type;
109 new->tlv->length = len;
110 new->tlv->value = (u_char *)malloc(new->tlv->length*sizeof(u_char));
111 memcpy(new->tlv->value, str, new->tlv->length);
117 } else if ((*list)->next == NULL) {
120 for(cur = *list; cur->next; cur = cur->next)
124 return new->tlv->length;
127 int aim_addtlvtochain16(struct aim_tlvlist_t **list, unsigned short type, unsigned short val)
129 struct aim_tlvlist_t *new;
130 struct aim_tlvlist_t *cur;
135 new = (struct aim_tlvlist_t *)malloc(sizeof(struct aim_tlvlist_t));
136 memset(new, 0x00, sizeof(struct aim_tlvlist_t));
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);
148 } else if ((*list)->next == NULL) {
151 for(cur = *list; cur->next; cur = cur->next)
158 int aim_addtlvtochain32(struct aim_tlvlist_t **list, unsigned short type, unsigned long val)
160 struct aim_tlvlist_t *new;
161 struct aim_tlvlist_t *cur;
166 new = (struct aim_tlvlist_t *)malloc(sizeof(struct aim_tlvlist_t));
167 memset(new, 0x00, sizeof(struct aim_tlvlist_t));
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);
179 } else if ((*list)->next == NULL) {
182 for(cur = *list; cur->next; cur = cur->next)
189 int aim_writetlvchain(u_char *buf, int buflen, struct aim_tlvlist_t **list)
193 struct aim_tlvlist_t *cur;
195 if (!list || !buf || !buflen)
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;
204 if (goodbuflen > buflen)
205 return 0; /* not enough buffer */
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;
220 * Grab the Nth TLV of type type in the TLV list list.
222 struct aim_tlv_t *aim_gettlv(struct aim_tlvlist_t *list, u_short type, int nth)
225 struct aim_tlvlist_t *cur;
228 for (cur = list; cur != NULL; cur = cur->next)
232 if (cur->tlv->type == type)
241 char *aim_gettlv_str(struct aim_tlvlist_t *list, u_short type, int nth)
243 struct aim_tlv_t *tlv;
246 if (!(tlv = aim_gettlv(list, type, nth)))
249 newstr = (char *) malloc(tlv->length + 1);
250 memcpy(newstr, tlv->value, tlv->length);
251 *(newstr + tlv->length) = '\0';
256 struct aim_tlv_t *aim_grabtlv(u_char *src)
258 struct aim_tlv_t *dest = NULL;
260 dest = aim_createtlv();
262 dest->type = src[0] << 8;
263 dest->type += src[1];
265 dest->length = src[2] << 8;
266 dest->length += src[3];
268 dest->value = (u_char *) malloc(dest->length*sizeof(u_char));
269 memset(dest->value, 0, dest->length*sizeof(u_char));
271 memcpy(dest->value, &(src[4]), dest->length*sizeof(u_char));
276 struct aim_tlv_t *aim_grabtlvstr(u_char *src)
278 struct aim_tlv_t *dest = NULL;
280 dest = aim_createtlv();
282 dest->type = src[0] << 8;
283 dest->type += src[1];
285 dest->length = src[2] << 8;
286 dest->length += src[3];
288 dest->value = (u_char *) malloc((dest->length+1)*sizeof(u_char));
289 memset(dest->value, 0, (dest->length+1)*sizeof(u_char));
291 memcpy(dest->value, &(src[4]), dest->length*sizeof(u_char));
292 dest->value[dest->length] = '\0';
297 int aim_puttlv (u_char *dest, struct aim_tlv_t *newtlv)
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);
310 struct aim_tlv_t *aim_createtlv(void)
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));
318 int aim_freetlv(struct aim_tlv_t **oldtlv)
324 if ((*oldtlv)->value)
325 free((*oldtlv)->value);
332 int aim_puttlv_16(u_char *buf, u_short t, u_short v)
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));
341 int aim_puttlv_32(u_char *buf, u_short t, u_long v)
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));
350 int aim_puttlv_str(u_char *buf, u_short t, u_short l, u_char *v)
355 curbyte += aimutil_put16(buf+curbyte, (u_short)(t&0xffff));
356 curbyte += aimutil_put16(buf+curbyte, (u_short)(l&0xffff));
358 memcpy(buf+curbyte, v, l);