]> andersk Git - libfaim.git/blame - aim_rxhandlers.c
Implemented chat and some chatnav. Nearly a 2000line diff.
[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 {
314 switch(workingPtr->conn->type)
315 {
316 case AIM_CONN_TYPE_AUTH:
a25832e6 317 {
318 u_long head;
319
320 head = aimutil_get32(workingPtr->data);
321 if (head == 0x00000001)
322 {
9de3ca7e 323#if debug > 0
a25832e6 324 printf("got connection ack on auth line\n");
9de3ca7e 325#endif
a25832e6 326 workingPtr->handled = 1;
327 }
328 else
329 {
01b59e1e 330 u_short family,subtype;
331
332 family = aimutil_get16(workingPtr->data);
333 subtype = aimutil_get16(workingPtr->data+2);
334
335 switch (family)
336 {
337 /* New login protocol */
338#ifdef SNACLOGIN
339 case 0x0017:
340 if (subtype == 0x0001)
341 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0017, 0x0001, workingPtr);
342 else if (subtype == 0x0003)
343 workingPtr->handled = aim_authparse(sess, workingPtr);
344 else if (subtype == 0x0007)
345 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0017, 0x0007, workingPtr);
346 else
347 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0017, 0xffff, workingPtr);
348 break;
349#else
350 /* XXX: this isnt foolproof */
351 case 0x0001:
352 if (subtype == 0x0003)
353 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_GEN, AIM_CB_GEN_SERVERREADY, workingPtr);
354 else
355 workingPtr->handled = aim_authparse(sess, workingPtr);
356 break;
357 case 0x0007:
358 if (subtype == 0x0005)
359 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_ADM, AIM_CB_ADM_INFOCHANGE_REPLY, workingPtr);
360 break;
361 default:
362 /* Old login protocol */
363 /* any user callbacks will be called from here */
364 workingPtr->handled = aim_authparse(sess, workingPtr);
365#endif
366 }
a25832e6 367 }
368 }
9de3ca7e 369 break;
370 case AIM_CONN_TYPE_BOS:
371 {
372 u_short family;
373 u_short subtype;
a25832e6 374
375 family = aimutil_get16(workingPtr->data);
376 subtype = aimutil_get16(workingPtr->data+2);
377
9de3ca7e 378 switch (family)
379 {
380 case 0x0000: /* not really a family, but it works */
381 if (subtype == 0x0001)
a25832e6 382 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0000, 0x0001, workingPtr);
9de3ca7e 383 else
a25832e6 384 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_UNKNOWN, workingPtr);
9de3ca7e 385 break;
386 case 0x0001: /* Family: General */
387 switch (subtype)
388 {
389 case 0x0001:
a25832e6 390 workingPtr->handled = aim_parse_generalerrs(sess, workingPtr);
9de3ca7e 391 break;
392 case 0x0003:
a25832e6 393 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0001, 0x0003, workingPtr);
9de3ca7e 394 break;
395 case 0x0005:
a25832e6 396 workingPtr->handled = aim_handleredirect_middle(sess, workingPtr);
9de3ca7e 397 break;
398 case 0x0007:
a25832e6 399 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0001, 0x0007, workingPtr);
9de3ca7e 400 break;
401 case 0x000a:
a25832e6 402 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0001, 0x000a, workingPtr);
9de3ca7e 403 break;
404 case 0x000f:
a25832e6 405 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0001, 0x000f, workingPtr);
9de3ca7e 406 break;
407 case 0x0013:
01b59e1e 408 workingPtr->handled = aim_parsemotd_middle(sess, workingPtr);
9de3ca7e 409 break;
410 default:
a25832e6 411 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_GEN, AIM_CB_GEN_DEFAULT, workingPtr);
9de3ca7e 412 }
413 break;
414 case 0x0002: /* Family: Location */
415 switch (subtype)
416 {
417 case 0x0001:
a25832e6 418 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0002, 0x0001, workingPtr);
9de3ca7e 419 break;
420 case 0x0003:
a25832e6 421 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0002, 0x0003, workingPtr);
9de3ca7e 422 break;
423 case 0x0006:
a25832e6 424 workingPtr->handled = aim_parse_userinfo_middle(sess, workingPtr);
9de3ca7e 425 break;
426 default:
a25832e6 427 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_LOC, AIM_CB_LOC_DEFAULT, workingPtr);
9de3ca7e 428 }
429 break;
430 case 0x0003: /* Family: Buddy List */
431 switch (subtype)
432 {
433 case 0x0001:
a25832e6 434 workingPtr->handled = aim_parse_generalerrs(sess, workingPtr);
9de3ca7e 435 break;
436 case 0x0003:
a25832e6 437 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0003, 0x0003, workingPtr);
9de3ca7e 438 break;
439 case 0x000b: /* oncoming buddy */
a25832e6 440 workingPtr->handled = aim_parse_oncoming_middle(sess, workingPtr);
9de3ca7e 441 break;
442 case 0x000c: /* offgoing buddy */
a25832e6 443 workingPtr->handled = aim_parse_offgoing_middle(sess, workingPtr);
9de3ca7e 444 break;
445 default:
a25832e6 446 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_BUD, AIM_CB_BUD_DEFAULT, workingPtr);
9de3ca7e 447 }
448 break;
449 case 0x0004: /* Family: Messeging */
450 switch (subtype)
451 {
452 case 0x0001:
a25832e6 453 workingPtr->handled = aim_parse_msgerror_middle(sess, workingPtr);
9de3ca7e 454 break;
455 case 0x0005:
a25832e6 456 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0004, 0x0005, workingPtr);
9de3ca7e 457 break;
458 case 0x0007:
a25832e6 459 workingPtr->handled = aim_parse_incoming_im_middle(sess, workingPtr);
9de3ca7e 460 break;
461 case 0x000a:
a25832e6 462 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0004, 0x000a, workingPtr);
9de3ca7e 463 break;
464 default:
a25832e6 465 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_MSG, AIM_CB_MSG_DEFAULT, workingPtr);
9de3ca7e 466 }
467 break;
468 case 0x0009:
469 if (subtype == 0x0001)
a25832e6 470 workingPtr->handled = aim_parse_generalerrs(sess, workingPtr);
9de3ca7e 471 else if (subtype == 0x0003)
a25832e6 472 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0009, 0x0003, workingPtr);
9de3ca7e 473 else
a25832e6 474 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_BOS, AIM_CB_BOS_DEFAULT, workingPtr);
9de3ca7e 475 break;
476 case 0x000a: /* Family: User lookup */
477 switch (subtype)
478 {
479 case 0x0001:
a25832e6 480 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x000a, 0x0001, workingPtr);
9de3ca7e 481 break;
482 case 0x0003:
a25832e6 483 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x000a, 0x0003, workingPtr);
9de3ca7e 484 break;
485 default:
a25832e6 486 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_LOK, AIM_CB_LOK_DEFAULT, workingPtr);
9de3ca7e 487 }
488 break;
489 case 0x000b:
490 if (subtype == 0x0001)
a25832e6 491 workingPtr->handled = aim_parse_generalerrs(sess, workingPtr);
9de3ca7e 492 else if (subtype == 0x0002)
a25832e6 493 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x000b, 0x0002, workingPtr);
9de3ca7e 494 else
a25832e6 495 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_STS, AIM_CB_STS_DEFAULT, workingPtr);
9de3ca7e 496 break;
497 default:
a25832e6 498 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_UNKNOWN, workingPtr);
9de3ca7e 499 break;
500 }
501 }
502 break;
503 case AIM_CONN_TYPE_CHATNAV:
504 {
505 u_short family;
506 u_short subtype;
a25832e6 507 family = aimutil_get16(workingPtr->data);
508 subtype= aimutil_get16(workingPtr->data+2);
509
510 if ((family == 0x0002) && (subtype == 0x0006))
9de3ca7e 511 {
512 workingPtr->handled = 1;
513 aim_conn_setstatus(workingPtr->conn, AIM_CONN_STATUS_READY);
514 }
0c20631f 515 else if ((family == 0x000d) && (subtype == 0x0009))
516 workingPtr->handled = aim_chatnav_parse_info(sess, workingPtr);
9de3ca7e 517 else
518 {
a25832e6 519 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, family, subtype, workingPtr);
9de3ca7e 520 }
521 }
522 break;
523 case AIM_CONN_TYPE_CHAT:
0c20631f 524 {
525 u_short family, subtype;
526
527 family = aimutil_get16(workingPtr->data);
528 subtype= aimutil_get16(workingPtr->data+2);
529
530 if ((family == 0x0000) && (subtype == 0x00001))
531 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0000, 0x0001, workingPtr);
532 else if (family == 0x0001)
533 {
534 if (subtype == 0x0001)
535 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0001, 0x0001, workingPtr);
536 else if (subtype == 0x0003)
537 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0001, 0x0003, workingPtr);
538 else if (subtype == 0x0007)
539 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0001, 0x0007, workingPtr);
540 else
541 printf("Chat: unknown snac %04x/%04x\n", family, subtype);
542 }
543 else if (family == 0x000e)
544 {
545 if (subtype == 0x0002)
546 workingPtr->handled = aim_chat_parse_infoupdate(sess, workingPtr);
547 else if (subtype == 0x0003)
548 workingPtr->handled = aim_chat_parse_joined(sess, workingPtr);
549 else if (subtype == 0x0004)
550 workingPtr->handled = aim_chat_parse_leave(sess, workingPtr);
551 else if (subtype == 0x0006)
552 workingPtr->handled = aim_chat_parse_incoming(sess, workingPtr);
553 else
554 printf("Chat: unknown snac %04x/%04x\n", family, subtype);
555 }
556 else
557 {
558 printf("Chat: unknown snac %04x/%04x\n", family, subtype);
559 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_CHT, AIM_CB_CHT_DEFAULT, workingPtr);
560 }
561 }
9de3ca7e 562 break;
563 default:
24286d93 564 printf("\nAHHHHH! UNKNOWN CONNECTION TYPE! (0x%02x)\n\n", workingPtr->conn->type);
a25832e6 565 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_UNKNOWN, workingPtr);
9de3ca7e 566 break;
567 }
a25832e6 568 /* move to next command */
9de3ca7e 569 workingPtr = workingPtr->next;
570 }
571 }
572
a25832e6 573 sess->queue_incoming = aim_purge_rxqueue(sess->queue_incoming);
9de3ca7e 574
575 return 0;
576}
577
01b59e1e 578int aim_parsemotd_middle(struct aim_session_t *sess,
579 struct command_rx_struct *command, ...)
9de3ca7e 580{
581 rxcallback_t userfunc = NULL;
01b59e1e 582 char *msg;
583 int ret=1;
584 struct aim_tlvlist_t *tlvlist;
585 u_short id;
586
587 /*
588 * Dunno.
589 */
590 id = aimutil_get16(command->data+10);
591
592 /*
593 * TLVs follow
594 */
595 tlvlist = aim_readtlvchain(command->data+12, command->commandlen-12);
a25832e6 596
01b59e1e 597 msg = aim_gettlv_str(tlvlist, 0x000b, 1);
598
599 userfunc = aim_callhandler(command->conn, 0x0001, 0x0013);
600 if (userfunc)
601 ret = userfunc(sess, command, id, msg);
9de3ca7e 602
01b59e1e 603 aim_freetlvchain(&tlvlist);
9de3ca7e 604
01b59e1e 605 return ret;
606
9de3ca7e 607}
608
a25832e6 609int aim_handleredirect_middle(struct aim_session_t *sess,
610 struct command_rx_struct *command, ...)
9de3ca7e 611{
01b59e1e 612 struct aim_tlv_t *tmptlv = NULL;
9de3ca7e 613 int serviceid = 0x00;
01b59e1e 614 char cookie[AIM_COOKIELEN];
9de3ca7e 615 char *ip = NULL;
616 rxcallback_t userfunc = NULL;
01b59e1e 617 struct aim_tlvlist_t *tlvlist;
618 int ret = 1;
619
620 tlvlist = aim_readtlvchain(command->data+10, command->commandlen-10);
621
622 tmptlv = aim_gettlv(tlvlist, 0x000d, 1);
623 serviceid = aimutil_get16(tmptlv->value);
624
625 ip = aim_gettlv_str(tlvlist, 0x0005, 1);
626
627 tmptlv = aim_gettlv(tlvlist, 0x0006, 1);
628 memcpy(cookie, tmptlv->value, AIM_COOKIELEN);
9de3ca7e 629
0c20631f 630 if (serviceid == AIM_CONN_TYPE_CHAT)
631 {
632 /*
633 * Chat hack.
634 *
635 */
636 userfunc = aim_callhandler(command->conn, 0x0001, 0x0005);
637 if (userfunc)
638 ret = userfunc(sess, command, serviceid, ip, cookie, sess->pendingjoin);
639 free(sess->pendingjoin);
640 sess->pendingjoin = NULL;
641 }
642 else
643 {
644 userfunc = aim_callhandler(command->conn, 0x0001, 0x0005);
645 if (userfunc)
646 ret = userfunc(sess, command, serviceid, ip, cookie);
647 }
01b59e1e 648 aim_freetlvchain(&tlvlist);
649
650 return ret;
9de3ca7e 651}
652
a25832e6 653int aim_parse_unknown(struct aim_session_t *sess,
654 struct command_rx_struct *command, ...)
9de3ca7e 655{
656 u_int i = 0;
657
658 printf("\nRecieved unknown packet:");
659
660 for (i = 0; i < command->commandlen; i++)
661 {
662 if ((i % 8) == 0)
663 printf("\n\t");
664
665 printf("0x%2x ", command->data[i]);
666 }
667
668 printf("\n\n");
669
670 return 1;
671}
672
673
674/*
675 * aim_parse_generalerrs()
676 *
677 * Middle handler for 0x0001 snac of each family.
678 *
679 */
a25832e6 680int aim_parse_generalerrs(struct aim_session_t *sess,
681 struct command_rx_struct *command, ...)
9de3ca7e 682{
683 u_short family;
684 u_short subtype;
a25832e6 685
686 family = aimutil_get16(command->data+0);
687 subtype= aimutil_get16(command->data+2);
9de3ca7e 688
689 switch(family)
690 {
691 default:
692 /* Unknown family */
a25832e6 693 return aim_callhandler_noparam(sess, command->conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_UNKNOWN, command);
9de3ca7e 694 }
695
696 return 1;
697}
698
699
700
This page took 0.313697 seconds and 5 git commands to generate.