]> andersk Git - libfaim.git/blame - aim_rxhandlers.c
- Fixed a robustness problem in aim_handleredirect_middle()
[libfaim.git] / aim_rxhandlers.c
CommitLineData
9de3ca7e 1/*
24286d93 2 * aim_rxhandlers.c
3 *
4 * This file contains most all of the incoming packet handlers, along
5 * with aim_rxdispatch(), the Rx dispatcher. Queue/list management is
6 * actually done in aim_rxqueue.c.
7 *
9de3ca7e 8 */
9
a25832e6 10#include <faim/aim.h>
9de3ca7e 11
24286d93 12/*
13 * Bleck functions get called when there's no non-bleck functions
14 * around to cleanup the mess...
15 */
a25832e6 16int bleck(struct aim_session_t *sess,struct command_rx_struct *workingPtr, ...)
9de3ca7e 17{
18 u_short family;
19 u_short subtype;
01b59e1e 20
21 u_short maxf;
22 u_short maxs;
23
24 /* XXX: this is ugly. and big just for debugging. */
25 char *literals[14][25] = {
26 {"Invalid",
27 NULL
28 },
29 {"General",
30 "Invalid",
31 "Error",
32 "Client Ready",
33 "Server Ready",
34 "Service Request",
35 "Redirect",
36 "Rate Information Request",
37 "Rate Information",
38 "Rate Information Ack",
39 NULL,
40 "Rate Information Change",
41 "Server Pause",
42 NULL,
43 "Server Resume",
44 "Request Personal User Information",
45 "Personal User Information",
46 "Evil Notification",
47 NULL,
48 "Migration notice",
49 "Message of the Day",
50 "Set Privacy Flags",
51 "Well Known URL",
52 "NOP"
53 },
54 {"Location",
55 "Invalid",
56 "Error",
57 "Request Rights",
58 "Rights Information",
59 "Set user information",
60 "Request User Information",
61 "User Information",
62 "Watcher Sub Request",
63 "Watcher Notification"
64 },
65 {"Buddy List Management",
66 "Invalid",
67 "Error",
68 "Request Rights",
69 "Rights Information",
70 "Add Buddy",
71 "Remove Buddy",
72 "Watcher List Query",
73 "Watcher List Response",
74 "Watcher SubRequest",
75 "Watcher Notification",
76 "Reject Notification",
77 "Oncoming Buddy",
78 "Offgoing Buddy"
79 },
80 {"Messeging",
81 "Invalid",
82 "Error",
83 "Add ICBM Parameter",
84 "Remove ICBM Parameter",
85 "Request Parameter Information",
86 "Parameter Information",
87 "Outgoing Message",
88 "Incoming Message",
89 "Evil Request",
90 "Evil Reply",
91 "Missed Calls",
92 "Message Error",
93 "Host Ack"
94 },
95 {"Advertisements",
96 "Invalid",
97 "Error",
98 "Request Ad",
99 "Ad Data (GIFs)"
100 },
101 {"Invitation / Client-to-Client",
102 "Invalid",
103 "Error",
104 "Invite a Friend",
105 "Invitation Ack"
106 },
107 {"Administrative",
108 "Invalid",
109 "Error",
110 "Information Request",
111 "Information Reply",
112 "Information Change Request",
113 "Information Chat Reply",
114 "Account Confirm Request",
115 "Account Confirm Reply",
116 "Account Delete Request",
117 "Account Delete Reply"
118 },
119 {"Popups",
120 "Invalid",
121 "Error",
122 "Display Popup"
123 },
124 {"BOS",
125 "Invalid",
126 "Error",
127 "Request Rights",
128 "Rights Response",
129 "Set group permission mask",
130 "Add permission list entries",
131 "Delete permission list entries",
132 "Add deny list entries",
133 "Delete deny list entries",
134 "Server Error"
135 },
136 {"User Lookup",
137 "Invalid",
138 "Error",
139 "Search Request",
140 "Search Response"
141 },
142 {"Stats",
143 "Invalid",
144 "Error",
145 "Set minimum report interval",
146 "Report Events"
147 },
148 {"Translate",
149 "Invalid",
150 "Error",
151 "Translate Request",
152 "Translate Reply",
153 },
154 {"Chat Navigation",
155 "Invalid",
156 "Error",
157 "Request rights",
158 "Request Exchange Information",
159 "Request Room Information",
160 "Request Occupant List",
161 "Search for Room",
162 "Outgoing Message",
163 "Incoming Message",
164 "Evil Request",
165 "Evil Reply",
166 "Chat Error",
167 }
168 };
169
170 maxf = sizeof(literals) / sizeof(literals[0]);
171 maxs = sizeof(literals[0]) / sizeof(literals[0][0]);
172
173 family = aimutil_get16(workingPtr->data+0);
174 subtype= aimutil_get16(workingPtr->data+2);
175
176 if((family < maxf) && (subtype+1 < maxs) && (literals[family][subtype] != NULL))
177 printf("bleck: null handler for %04x/%04x (%s)\n", family, subtype, literals[family][subtype+1]);
178 else
179 printf("bleck: null handler for %04x/%04x (no literal)\n",family,subtype);
180
9de3ca7e 181 return 1;
182}
183
a25832e6 184int aim_conn_addhandler(struct aim_session_t *sess,
185 struct aim_conn_t *conn,
9de3ca7e 186 u_short family,
187 u_short type,
188 rxcallback_t newhandler,
189 u_short flags)
190{
191 struct aim_rxcblist_t *new,*cur;
192
193 if (!conn)
194 return -1;
195
196#if debug > 0
197 printf("aim_conn_addhandler: adding for %04x/%04x\n", family, type);
198#endif
199
200 new = (struct aim_rxcblist_t *)calloc(1, sizeof(struct aim_rxcblist_t));
201 new->family = family;
202 new->type = type;
203 new->flags = flags;
204 if (!newhandler)
205 new->handler = &bleck;
206 else
207 new->handler = newhandler;
208 new->next = NULL;
209
210 cur = conn->handlerlist;
211 if (!cur)
212 conn->handlerlist = new;
213 else
214 {
215 while (cur->next)
216 cur = cur->next;
217 cur->next = new;
218 }
219
220 return 0;
221}
222
223int aim_clearhandlers(struct aim_conn_t *conn)
224{
225 struct aim_rxcblist_t *cur,*tmp;
226 if (!conn)
227 return -1;
228
229 cur = conn->handlerlist;
230 while(cur)
231 {
232 tmp = cur->next;
233 free(cur);
234 cur = tmp;
235 }
236 return 0;
237}
238
239rxcallback_t aim_callhandler(struct aim_conn_t *conn,
240 u_short family,
241 u_short type)
242{
243 struct aim_rxcblist_t *cur;
244
245 if (!conn)
246 return NULL;
247
248#if debug > 0
249 printf("aim_callhandler: calling for %04x/%04x\n", family, type);
250#endif
251
252 cur = conn->handlerlist;
253 while(cur)
254 {
255 if ( (cur->family == family) && (cur->type == type) )
256 return cur->handler;
257 cur = cur->next;
258 }
259
260 if (type==0xffff)
261 return NULL;
262 return aim_callhandler(conn, family, 0xffff);
263}
264
a25832e6 265int aim_callhandler_noparam(struct aim_session_t *sess,
266 struct aim_conn_t *conn,
9de3ca7e 267 u_short family,
268 u_short type,
269 struct command_rx_struct *ptr)
270{
271 rxcallback_t userfunc = NULL;
272 userfunc = aim_callhandler(conn, family, type);
273 if (userfunc)
a25832e6 274 return userfunc(sess, ptr);
9de3ca7e 275 return 0;
276}
277
278/*
279 aim_rxdispatch()
280
281 Basically, heres what this should do:
282 1) Determine correct packet handler for this packet
283 2) Mark the packet handled (so it can be dequeued in purge_queue())
284 3) Send the packet to the packet handler
285 4) Go to next packet in the queue and start over
286 5) When done, run purge_queue() to purge handled commands
287
288 Note that any unhandlable packets should probably be left in the
289 queue. This is the best way to prevent data loss. This means
290 that a single packet may get looked at by this function multiple
291 times. This is more good than bad! This behavior may change.
292
293 Aren't queue's fun?
294
295 TODO: Get rid of all the ugly if's.
296 TODO: Clean up.
297 TODO: More support for mid-level handlers.
298 TODO: Allow for NULL handlers.
299
300 */
a25832e6 301int aim_rxdispatch(struct aim_session_t *sess)
9de3ca7e 302{
303 int i = 0;
304 struct command_rx_struct *workingPtr = NULL;
305
a25832e6 306 if (sess->queue_incoming == NULL)
9de3ca7e 307 /* this shouldn't really happen, unless the main loop's select is broke */
308 printf("parse_generic: incoming packet queue empty.\n");
309 else
310 {
a25832e6 311 workingPtr = sess->queue_incoming;
9de3ca7e 312 for (i = 0; workingPtr != NULL; i++)
313 {
7bed1692 314 /*
315 * XXX: This is still fairly ugly.
316 */
9de3ca7e 317 switch(workingPtr->conn->type)
318 {
7bed1692 319 case -1:
320 /*
321 * This can happen if we have a queued command
322 * that was recieved after a connection has
323 * been terminated. In which case, the handler
324 * list has been cleared, and there's nothing we
325 * can do for it. We can only cancel it.
326 */
327 workingPtr->handled = 1;
328 break;
9de3ca7e 329 case AIM_CONN_TYPE_AUTH:
a25832e6 330 {
331 u_long head;
332
333 head = aimutil_get32(workingPtr->data);
334 if (head == 0x00000001)
335 {
9de3ca7e 336#if debug > 0
a25832e6 337 printf("got connection ack on auth line\n");
9de3ca7e 338#endif
a25832e6 339 workingPtr->handled = 1;
340 }
341 else
342 {
01b59e1e 343 u_short family,subtype;
344
345 family = aimutil_get16(workingPtr->data);
346 subtype = aimutil_get16(workingPtr->data+2);
347
348 switch (family)
349 {
350 /* New login protocol */
351#ifdef SNACLOGIN
352 case 0x0017:
353 if (subtype == 0x0001)
354 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0017, 0x0001, workingPtr);
355 else if (subtype == 0x0003)
356 workingPtr->handled = aim_authparse(sess, workingPtr);
357 else if (subtype == 0x0007)
358 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0017, 0x0007, workingPtr);
359 else
360 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0017, 0xffff, workingPtr);
361 break;
362#else
363 /* XXX: this isnt foolproof */
364 case 0x0001:
365 if (subtype == 0x0003)
366 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_GEN, AIM_CB_GEN_SERVERREADY, workingPtr);
367 else
368 workingPtr->handled = aim_authparse(sess, workingPtr);
369 break;
370 case 0x0007:
371 if (subtype == 0x0005)
372 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_ADM, AIM_CB_ADM_INFOCHANGE_REPLY, workingPtr);
373 break;
374 default:
375 /* Old login protocol */
376 /* any user callbacks will be called from here */
377 workingPtr->handled = aim_authparse(sess, workingPtr);
378#endif
379 }
a25832e6 380 }
381 }
9de3ca7e 382 break;
383 case AIM_CONN_TYPE_BOS:
384 {
385 u_short family;
386 u_short subtype;
a25832e6 387
388 family = aimutil_get16(workingPtr->data);
389 subtype = aimutil_get16(workingPtr->data+2);
390
9de3ca7e 391 switch (family)
392 {
393 case 0x0000: /* not really a family, but it works */
394 if (subtype == 0x0001)
a25832e6 395 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0000, 0x0001, workingPtr);
9de3ca7e 396 else
a25832e6 397 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_UNKNOWN, workingPtr);
9de3ca7e 398 break;
399 case 0x0001: /* Family: General */
400 switch (subtype)
401 {
402 case 0x0001:
a25832e6 403 workingPtr->handled = aim_parse_generalerrs(sess, workingPtr);
9de3ca7e 404 break;
405 case 0x0003:
a25832e6 406 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0001, 0x0003, workingPtr);
9de3ca7e 407 break;
408 case 0x0005:
a25832e6 409 workingPtr->handled = aim_handleredirect_middle(sess, workingPtr);
9de3ca7e 410 break;
411 case 0x0007:
a25832e6 412 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0001, 0x0007, workingPtr);
9de3ca7e 413 break;
414 case 0x000a:
a25832e6 415 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0001, 0x000a, workingPtr);
9de3ca7e 416 break;
417 case 0x000f:
a25832e6 418 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0001, 0x000f, workingPtr);
9de3ca7e 419 break;
420 case 0x0013:
01b59e1e 421 workingPtr->handled = aim_parsemotd_middle(sess, workingPtr);
9de3ca7e 422 break;
423 default:
a25832e6 424 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_GEN, AIM_CB_GEN_DEFAULT, workingPtr);
9de3ca7e 425 }
426 break;
427 case 0x0002: /* Family: Location */
428 switch (subtype)
429 {
430 case 0x0001:
a25832e6 431 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0002, 0x0001, workingPtr);
9de3ca7e 432 break;
433 case 0x0003:
a25832e6 434 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0002, 0x0003, workingPtr);
9de3ca7e 435 break;
436 case 0x0006:
a25832e6 437 workingPtr->handled = aim_parse_userinfo_middle(sess, workingPtr);
9de3ca7e 438 break;
439 default:
a25832e6 440 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_LOC, AIM_CB_LOC_DEFAULT, workingPtr);
9de3ca7e 441 }
442 break;
443 case 0x0003: /* Family: Buddy List */
444 switch (subtype)
445 {
446 case 0x0001:
a25832e6 447 workingPtr->handled = aim_parse_generalerrs(sess, workingPtr);
9de3ca7e 448 break;
449 case 0x0003:
a25832e6 450 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0003, 0x0003, workingPtr);
9de3ca7e 451 break;
452 case 0x000b: /* oncoming buddy */
a25832e6 453 workingPtr->handled = aim_parse_oncoming_middle(sess, workingPtr);
9de3ca7e 454 break;
455 case 0x000c: /* offgoing buddy */
a25832e6 456 workingPtr->handled = aim_parse_offgoing_middle(sess, workingPtr);
9de3ca7e 457 break;
458 default:
a25832e6 459 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_BUD, AIM_CB_BUD_DEFAULT, workingPtr);
9de3ca7e 460 }
461 break;
462 case 0x0004: /* Family: Messeging */
463 switch (subtype)
464 {
465 case 0x0001:
a25832e6 466 workingPtr->handled = aim_parse_msgerror_middle(sess, workingPtr);
9de3ca7e 467 break;
468 case 0x0005:
a25832e6 469 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0004, 0x0005, workingPtr);
9de3ca7e 470 break;
471 case 0x0007:
a25832e6 472 workingPtr->handled = aim_parse_incoming_im_middle(sess, workingPtr);
9de3ca7e 473 break;
474 case 0x000a:
a25832e6 475 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0004, 0x000a, workingPtr);
9de3ca7e 476 break;
477 default:
a25832e6 478 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_MSG, AIM_CB_MSG_DEFAULT, workingPtr);
9de3ca7e 479 }
480 break;
481 case 0x0009:
482 if (subtype == 0x0001)
a25832e6 483 workingPtr->handled = aim_parse_generalerrs(sess, workingPtr);
9de3ca7e 484 else if (subtype == 0x0003)
a25832e6 485 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0009, 0x0003, workingPtr);
9de3ca7e 486 else
a25832e6 487 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_BOS, AIM_CB_BOS_DEFAULT, workingPtr);
9de3ca7e 488 break;
489 case 0x000a: /* Family: User lookup */
490 switch (subtype)
491 {
492 case 0x0001:
a25832e6 493 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x000a, 0x0001, workingPtr);
9de3ca7e 494 break;
495 case 0x0003:
a25832e6 496 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x000a, 0x0003, workingPtr);
9de3ca7e 497 break;
498 default:
a25832e6 499 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_LOK, AIM_CB_LOK_DEFAULT, workingPtr);
9de3ca7e 500 }
501 break;
502 case 0x000b:
503 if (subtype == 0x0001)
a25832e6 504 workingPtr->handled = aim_parse_generalerrs(sess, workingPtr);
9de3ca7e 505 else if (subtype == 0x0002)
a25832e6 506 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x000b, 0x0002, workingPtr);
9de3ca7e 507 else
a25832e6 508 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_STS, AIM_CB_STS_DEFAULT, workingPtr);
9de3ca7e 509 break;
510 default:
a25832e6 511 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_UNKNOWN, workingPtr);
9de3ca7e 512 break;
513 }
514 }
515 break;
516 case AIM_CONN_TYPE_CHATNAV:
517 {
518 u_short family;
519 u_short subtype;
a25832e6 520 family = aimutil_get16(workingPtr->data);
521 subtype= aimutil_get16(workingPtr->data+2);
522
523 if ((family == 0x0002) && (subtype == 0x0006))
9de3ca7e 524 {
525 workingPtr->handled = 1;
526 aim_conn_setstatus(workingPtr->conn, AIM_CONN_STATUS_READY);
527 }
0c20631f 528 else if ((family == 0x000d) && (subtype == 0x0009))
529 workingPtr->handled = aim_chatnav_parse_info(sess, workingPtr);
9de3ca7e 530 else
531 {
a25832e6 532 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, family, subtype, workingPtr);
9de3ca7e 533 }
534 }
535 break;
536 case AIM_CONN_TYPE_CHAT:
0c20631f 537 {
538 u_short family, subtype;
539
540 family = aimutil_get16(workingPtr->data);
541 subtype= aimutil_get16(workingPtr->data+2);
542
543 if ((family == 0x0000) && (subtype == 0x00001))
544 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0000, 0x0001, workingPtr);
545 else if (family == 0x0001)
546 {
547 if (subtype == 0x0001)
548 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0001, 0x0001, workingPtr);
549 else if (subtype == 0x0003)
550 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0001, 0x0003, workingPtr);
551 else if (subtype == 0x0007)
552 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0001, 0x0007, workingPtr);
553 else
554 printf("Chat: unknown snac %04x/%04x\n", family, subtype);
555 }
556 else if (family == 0x000e)
557 {
558 if (subtype == 0x0002)
559 workingPtr->handled = aim_chat_parse_infoupdate(sess, workingPtr);
560 else if (subtype == 0x0003)
561 workingPtr->handled = aim_chat_parse_joined(sess, workingPtr);
562 else if (subtype == 0x0004)
563 workingPtr->handled = aim_chat_parse_leave(sess, workingPtr);
564 else if (subtype == 0x0006)
565 workingPtr->handled = aim_chat_parse_incoming(sess, workingPtr);
566 else
567 printf("Chat: unknown snac %04x/%04x\n", family, subtype);
568 }
569 else
570 {
571 printf("Chat: unknown snac %04x/%04x\n", family, subtype);
572 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_CHT, AIM_CB_CHT_DEFAULT, workingPtr);
573 }
574 }
9de3ca7e 575 break;
576 default:
7bed1692 577 printf("\nAHHHHH! UNKNOWN CONNECTION TYPE! (type = %d, fd = %d, channel = %02x, commandlen = %02x)\n\n", workingPtr->conn->type, workingPtr->conn->fd, workingPtr->type, workingPtr->commandlen);
a25832e6 578 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_UNKNOWN, workingPtr);
9de3ca7e 579 break;
580 }
a25832e6 581 /* move to next command */
9de3ca7e 582 workingPtr = workingPtr->next;
583 }
584 }
585
a25832e6 586 sess->queue_incoming = aim_purge_rxqueue(sess->queue_incoming);
9de3ca7e 587
588 return 0;
589}
590
01b59e1e 591int aim_parsemotd_middle(struct aim_session_t *sess,
592 struct command_rx_struct *command, ...)
9de3ca7e 593{
594 rxcallback_t userfunc = NULL;
01b59e1e 595 char *msg;
596 int ret=1;
597 struct aim_tlvlist_t *tlvlist;
598 u_short id;
599
600 /*
601 * Dunno.
602 */
603 id = aimutil_get16(command->data+10);
604
605 /*
606 * TLVs follow
607 */
608 tlvlist = aim_readtlvchain(command->data+12, command->commandlen-12);
a25832e6 609
01b59e1e 610 msg = aim_gettlv_str(tlvlist, 0x000b, 1);
611
612 userfunc = aim_callhandler(command->conn, 0x0001, 0x0013);
613 if (userfunc)
614 ret = userfunc(sess, command, id, msg);
9de3ca7e 615
01b59e1e 616 aim_freetlvchain(&tlvlist);
9de3ca7e 617
01b59e1e 618 return ret;
619
9de3ca7e 620}
621
a25832e6 622int aim_handleredirect_middle(struct aim_session_t *sess,
623 struct command_rx_struct *command, ...)
9de3ca7e 624{
01b59e1e 625 struct aim_tlv_t *tmptlv = NULL;
9de3ca7e 626 int serviceid = 0x00;
01b59e1e 627 char cookie[AIM_COOKIELEN];
9de3ca7e 628 char *ip = NULL;
629 rxcallback_t userfunc = NULL;
01b59e1e 630 struct aim_tlvlist_t *tlvlist;
631 int ret = 1;
632
0e2be272 633 if (!(tlvlist = aim_readtlvchain(command->data+10, command->commandlen-10)))
634 {
635 printf("libfaim: major bug: unable to read tlvchain from redirect\n");
636 return ret;
637 }
01b59e1e 638
0e2be272 639 if (!(tmptlv = aim_gettlv(tlvlist, 0x000d, 1)))
640 {
641 printf("libfaim: major bug: no service ID in tlvchain from redirect\n");
642 aim_freetlvchain(&tlvlist);
643 return ret;
644 }
01b59e1e 645 serviceid = aimutil_get16(tmptlv->value);
646
0e2be272 647 if (!(ip = aim_gettlv_str(tlvlist, 0x0005, 1)))
648 {
649 printf("libfaim: major bug: no IP in tlvchain from redirect (service 0x%02x)\n", serviceid);
650 aim_freetlvchain(&tlvlist);
651 return ret;
652 }
01b59e1e 653
0e2be272 654 if (!(tmptlv = aim_gettlv(tlvlist, 0x0006, 1)))
655 {
656 printf("libfaim: major bug: no cookie in tlvchain from redirect (service 0x%02x)\n", serviceid);
657 aim_freetlvchain(&tlvlist);
658 return ret;
659 }
01b59e1e 660 memcpy(cookie, tmptlv->value, AIM_COOKIELEN);
9de3ca7e 661
0c20631f 662 if (serviceid == AIM_CONN_TYPE_CHAT)
663 {
664 /*
665 * Chat hack.
666 *
667 */
668 userfunc = aim_callhandler(command->conn, 0x0001, 0x0005);
669 if (userfunc)
670 ret = userfunc(sess, command, serviceid, ip, cookie, sess->pendingjoin);
671 free(sess->pendingjoin);
672 sess->pendingjoin = NULL;
673 }
674 else
675 {
676 userfunc = aim_callhandler(command->conn, 0x0001, 0x0005);
677 if (userfunc)
678 ret = userfunc(sess, command, serviceid, ip, cookie);
679 }
0e2be272 680
681 /*
682 * XXX: Is there a leak here? Where does IP get freed?
683 */
01b59e1e 684 aim_freetlvchain(&tlvlist);
685
686 return ret;
9de3ca7e 687}
688
a25832e6 689int aim_parse_unknown(struct aim_session_t *sess,
690 struct command_rx_struct *command, ...)
9de3ca7e 691{
692 u_int i = 0;
693
694 printf("\nRecieved unknown packet:");
695
696 for (i = 0; i < command->commandlen; i++)
697 {
698 if ((i % 8) == 0)
699 printf("\n\t");
700
701 printf("0x%2x ", command->data[i]);
702 }
703
704 printf("\n\n");
705
706 return 1;
707}
708
709
710/*
711 * aim_parse_generalerrs()
712 *
713 * Middle handler for 0x0001 snac of each family.
714 *
715 */
a25832e6 716int aim_parse_generalerrs(struct aim_session_t *sess,
717 struct command_rx_struct *command, ...)
9de3ca7e 718{
719 u_short family;
720 u_short subtype;
a25832e6 721
722 family = aimutil_get16(command->data+0);
723 subtype= aimutil_get16(command->data+2);
9de3ca7e 724
725 switch(family)
726 {
727 default:
728 /* Unknown family */
a25832e6 729 return aim_callhandler_noparam(sess, command->conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_UNKNOWN, command);
9de3ca7e 730 }
731
732 return 1;
733}
734
735
736
This page took 0.159477 seconds and 5 git commands to generate.