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