2 * Routines for AIM Instant Messenger (OSCAR) dissection
3 * Copyright 2000, Ralf Hoelzer <ralf@well.com>
5 * $Id: packet-aim.c,v 1.31 2003/12/21 11:40:45 jmayer Exp $
7 * Ethereal - Network traffic analyzer
8 * By Gerald Combs <gerald@ethereal.com>
9 * Copyright 1998 Gerald Combs
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
37 #include <epan/packet.h>
38 #include <epan/strutil.h>
40 #include "packet-tcp.h"
43 #define TCP_PORT_AIM 5190
44 #define MAX_BUDDYNAME_LENGTH 30
48 typedef struct _aim_tlv {
55 #define CHANNEL_NEW_CONN 0x01
56 #define CHANNEL_SNAC_DATA 0x02
57 #define CHANNEL_FLAP_ERR 0x03
58 #define CHANNEL_CLOSE_CONN 0x04
61 #define FAMILY_GENERIC 0x0001
62 #define FAMILY_LOCATION 0x0002
63 #define FAMILY_BUDDYLIST 0x0003
64 #define FAMILY_MESSAGING 0x0004
65 #define FAMILY_ADVERTS 0x0005
66 #define FAMILY_INVITATION 0x0006
67 #define FAMILY_ADMIN 0x0007
68 #define FAMILY_POPUP 0x0008
69 #define FAMILY_BOS 0x0009
70 #define FAMILY_USERLOOKUP 0x000A
71 #define FAMILY_STATS 0x000B
72 #define FAMILY_TRANSLATE 0x000C
73 #define FAMILY_CHAT_NAV 0x000D
74 #define FAMILY_CHAT 0x000E
75 #define FAMILY_SSI 0x0013
76 #define FAMILY_ICQ 0x0015
77 #define FAMILY_SIGNON 0x0017
78 #define FAMILY_OFT 0xfffe
81 #define FAMILY_SIGNON_LOGON 0x0002
82 #define FAMILY_SIGNON_LOGON_REPLY 0x0003
83 #define FAMILY_SIGNON_SIGNON 0x0006
84 #define FAMILY_SIGNON_SIGNON_REPLY 0x0007
87 #define FAMILY_GENERIC_ERROR 0x0001
88 #define FAMILY_GENERIC_CLIENTREADY 0x0002
89 #define FAMILY_GENERIC_SERVERREADY 0x0003
90 #define FAMILY_GENERIC_SERVICEREQ 0x0004
91 #define FAMILY_GENERIC_REDIRECT 0x0005
92 #define FAMILY_GENERIC_RATEINFOREQ 0x0006
93 #define FAMILY_GENERIC_RATEINFO 0x0007
94 #define FAMILY_GENERIC_RATEINFOACK 0x0008
95 #define FAMILY_GENERIC_UNKNOWNx09 0x0009
96 #define FAMILY_GENERIC_RATECHANGE 0x000a
97 #define FAMILY_GENERIC_SERVERPAUSE 0x000b
98 #define FAMILY_GENERIC_SERVERRESUME 0x000d
99 #define FAMILY_GENERIC_REQSELFINFO 0x000e
100 #define FAMILY_GENERIC_SELFINFO 0x000f
101 #define FAMILY_GENERIC_EVIL 0x0010
102 #define FAMILY_GENERIC_SETIDLE 0x0011
103 #define FAMILY_GENERIC_MIGRATIONREQ 0x0012
104 #define FAMILY_GENERIC_MOTD 0x0013
105 #define FAMILY_GENERIC_SETPRIVFLAGS 0x0014
106 #define FAMILY_GENERIC_WELLKNOWNURL 0x0015
107 #define FAMILY_GENERIC_NOP 0x0016
108 #define FAMILY_GENERIC_DEFAULT 0xffff
110 /* Family Location Services */
111 #define FAMILY_LOCATION_ERROR 0x0001
112 #define FAMILY_LOCATION_REQRIGHTS 0x0002
113 #define FAMILY_LOCATION_RIGHTSINFO 0x0003
114 #define FAMILY_LOCATION_SETUSERINFO 0x0004
115 #define FAMILY_LOCATION_REQUSERINFO 0x0005
116 #define FAMILY_LOCATION_USERINFO 0x0006
117 #define FAMILY_LOCATION_WATCHERSUBREQ 0x0007
118 #define FAMILY_LOCATION_WATCHERNOT 0x0008
119 #define FAMILY_LOCATION_DEFAULT 0xffff
121 /* Family Buddy List */
122 #define FAMILY_BUDDYLIST_ERROR 0x0001
123 #define FAMILY_BUDDYLIST_REQRIGHTS 0x0002
124 #define FAMILY_BUDDYLIST_RIGHTSINFO 0x0003
125 #define FAMILY_BUDDYLIST_ADDBUDDY 0x0004
126 #define FAMILY_BUDDYLIST_REMBUDDY 0x0005
127 #define FAMILY_BUDDYLIST_REJECT 0x000a
128 #define FAMILY_BUDDYLIST_ONCOMING 0x000b
129 #define FAMILY_BUDDYLIST_OFFGOING 0x000c
130 #define FAMILY_BUDDYLIST_DEFAULT 0xffff
132 /* Family Messaging Service */
133 #define FAMILY_MESSAGING_ERROR 0x0001
134 #define FAMILY_MESSAGING_PARAMINFO 0x0005
135 #define FAMILY_MESSAGING_OUTGOING 0x0006
136 #define FAMILY_MESSAGING_INCOMING 0x0007
137 #define FAMILY_MESSAGING_EVIL 0x0009
138 #define FAMILY_MESSAGING_MISSEDCALL 0x000a
139 #define FAMILY_MESSAGING_CLIENTAUTORESP 0x000b
140 #define FAMILY_MESSAGING_ACK 0x000c
141 #define FAMILY_MESSAGING_DEFAULT 0xffff
143 /* Family Advertising */
144 #define FAMILY_ADVERTS_ERROR 0x0001
145 #define FAMILY_ADVERTS_REQUEST 0x0002
146 #define FAMILY_ADVERTS_DATA 0x0003
147 #define FAMILY_ADVERTS_DEFAULT 0xffff
149 /* Family Invitation */
150 #define FAMILY_INVITATION_ERROR 0x0001
151 #define FAMILY_INVITATION_DEFAULT 0xffff
154 #define FAMILY_ADMIN_ERROR 0x0001
155 #define FAMILY_ADMIN_INFOCHANGEREPLY 0x0005
156 #define FAMILY_ADMIN_DEFAULT 0xffff
159 #define FAMILY_POPUP_ERROR 0x0001
160 #define FAMILY_POPUP_DEFAULT 0xffff
162 /* Family BOS (Misc) */
163 #define FAMILY_BOS_ERROR 0x0001
164 #define FAMILY_BOS_RIGHTSQUERY 0x0002
165 #define FAMILY_BOS_RIGHTS 0x0003
166 #define FAMILY_BOS_DEFAULT 0xffff
168 /* Family User Lookup */
169 #define FAMILY_USERLOOKUP_ERROR 0x0001
170 #define FAMILY_USERLOOKUP_SEARCHEMAIL 0x0002
171 #define FAMILY_USERLOOKUP_SEARCHRESULT 0x0003
172 #define FAMILY_USERLOOKUP_DEFAULT 0xffff
174 /* Family User Stats */
175 #define FAMILY_STATS_ERROR 0x0001
176 #define FAMILY_STATS_SETREPORTINTERVAL 0x0002
177 #define FAMILY_STATS_REPORTACK 0x0004
178 #define FAMILY_STATS_DEFAULT 0xffff
180 /* Family Translation */
181 #define FAMILY_TRANSLATE_ERROR 0x0001
182 #define FAMILY_TRANSLATE_DEFAULT 0xffff
184 /* Family Chat Navigation */
185 #define FAMILY_CHATNAV_ERROR 0x0001
186 #define FAMILY_CHATNAV_CREATE 0x0008
187 #define FAMILY_CHATNAV_INFO 0x0009
188 #define FAMILY_CHATNAV_DEFAULT 0xffff
191 #define FAMILY_CHAT_ERROR 0x0001
192 #define FAMILY_CHAT_ROOMINFOUPDATE 0x0002
193 #define FAMILY_CHAT_USERJOIN 0x0003
194 #define FAMILY_CHAT_USERLEAVE 0x0004
195 #define FAMILY_CHAT_OUTGOINGMSG 0x0005
196 #define FAMILY_CHAT_INCOMINGMSG 0x0006
197 #define FAMILY_CHAT_DEFAULT 0xffff
199 /* Family Server-Stored Buddy Lists */
200 #define FAMILY_SSI_ERROR 0x0001
201 #define FAMILY_SSI_REQRIGHTS 0x0002
202 #define FAMILY_SSI_RIGHTSINFO 0x0003
203 #define FAMILY_SSI_REQLIST 0x0005
204 #define FAMILY_SSI_LIST 0x0006
205 #define FAMILY_SSI_ACTIVATE 0x0007
206 #define FAMILY_SSI_ADD 0x0008
207 #define FAMILY_SSI_MOD 0x0009
208 #define FAMILY_SSI_DEL 0x000a
209 #define FAMILY_SSI_SRVACK 0x000e
210 #define FAMILY_SSI_NOLIST 0x000f
211 #define FAMILY_SSI_EDITSTART 0x0011
212 #define FAMILY_SSI_EDITSTOP 0x0012
215 #define FAMILY_ICQ_ERROR 0x0001
216 #define FAMILY_ICQ_LOGINREQUEST 0x0002
217 #define FAMILY_ICQ_LOGINRESPONSE 0x0003
218 #define FAMILY_ICQ_AUTHREQUEST 0x0006
219 #define FAMILY_ICQ_AUTHRESPONSE 0x0007
221 static const value_string aim_fnac_family_ids[] = {
222 { FAMILY_GENERIC, "Generic" },
223 { FAMILY_LOCATION, "Location" },
224 { FAMILY_BUDDYLIST, "Buddy List" },
225 { FAMILY_MESSAGING, "Messaging" },
226 { FAMILY_ADVERTS, "Advertisement" },
227 { FAMILY_INVITATION, "Invitation" },
228 { FAMILY_ADMIN, "Admin" },
229 { FAMILY_POPUP, "Popup" },
230 { FAMILY_BOS, "Bos" },
231 { FAMILY_USERLOOKUP, "User Lookup" },
232 { FAMILY_STATS, "Stats" },
233 { FAMILY_TRANSLATE, "Translate" },
234 { FAMILY_CHAT_NAV, "Chat Nav" },
235 { FAMILY_CHAT, "Chat" },
236 { FAMILY_SSI, "Server Stored Info" },
237 { FAMILY_ICQ, "ICQ" },
238 { FAMILY_SIGNON, "Sign-on" },
239 { FAMILY_OFT, "OFT/Rvous" },
243 static const value_string aim_fnac_family_signon[] = {
244 { FAMILY_SIGNON_LOGON, "Logon" },
245 { FAMILY_SIGNON_LOGON_REPLY, "Logon Reply" },
246 { FAMILY_SIGNON_SIGNON, "Sign-on" },
247 { FAMILY_SIGNON_SIGNON_REPLY, "Sign-on Reply" },
251 static const value_string aim_fnac_family_generic[] = {
252 { FAMILY_GENERIC_ERROR, "Error" },
253 { FAMILY_GENERIC_CLIENTREADY , "Client Ready" },
254 { FAMILY_GENERIC_SERVERREADY, "Server Ready" },
255 { FAMILY_GENERIC_SERVICEREQ, "Service Req" },
256 { FAMILY_GENERIC_REDIRECT, "Redirect" },
257 { FAMILY_GENERIC_RATEINFOREQ, "Rate Info Req" },
258 { FAMILY_GENERIC_RATEINFO, "Rate Info" },
259 { FAMILY_GENERIC_RATEINFOACK, "Rate Info Ack" },
260 { FAMILY_GENERIC_UNKNOWNx09, "Unknown" },
261 { FAMILY_GENERIC_RATECHANGE, "Rate Change" },
262 { FAMILY_GENERIC_SERVERPAUSE, "Server Pause" },
263 { FAMILY_GENERIC_SERVERRESUME, "Server Resume" },
264 { FAMILY_GENERIC_REQSELFINFO, "Self Info Req" },
265 { FAMILY_GENERIC_SELFINFO, "Self Info" },
266 { FAMILY_GENERIC_EVIL, "Evil" },
267 { FAMILY_GENERIC_SETIDLE, "Set Idle" },
268 { FAMILY_GENERIC_MIGRATIONREQ, "Migration Req" },
269 { FAMILY_GENERIC_MOTD, "MOTD" },
270 { FAMILY_GENERIC_SETPRIVFLAGS, "Set Privilege Flags" },
271 { FAMILY_GENERIC_WELLKNOWNURL, "Well Known URL" },
272 { FAMILY_GENERIC_NOP, "noop" },
273 { FAMILY_GENERIC_DEFAULT, "Generic Default" },
277 static const value_string aim_fnac_family_location[] = {
278 { FAMILY_LOCATION_ERROR, "Error" },
279 { FAMILY_LOCATION_REQRIGHTS, "Request Rights" },
280 { FAMILY_LOCATION_RIGHTSINFO, "Rights Info" },
281 { FAMILY_LOCATION_SETUSERINFO, "Set User Info" },
282 { FAMILY_LOCATION_REQUSERINFO, "Request User Info" },
283 { FAMILY_LOCATION_USERINFO, "User Info" },
284 { FAMILY_LOCATION_WATCHERSUBREQ, "Watcher Subrequest" },
285 { FAMILY_LOCATION_WATCHERNOT, "Watcher Notification" },
286 { FAMILY_LOCATION_DEFAULT, "Location Default" },
290 static const value_string aim_fnac_family_buddylist[] = {
291 { FAMILY_BUDDYLIST_ERROR, "Error" },
292 { FAMILY_BUDDYLIST_REQRIGHTS, "Request Rights" },
293 { FAMILY_BUDDYLIST_RIGHTSINFO, "Rights Info" },
294 { FAMILY_BUDDYLIST_ADDBUDDY, "Add Buddy" },
295 { FAMILY_BUDDYLIST_REMBUDDY, "Remove Buddy" },
296 { FAMILY_BUDDYLIST_REJECT, "Reject Buddy" },
297 { FAMILY_BUDDYLIST_ONCOMING, "Oncoming Buddy" },
298 { FAMILY_BUDDYLIST_OFFGOING, "Offgoing Buddy" },
299 { FAMILY_BUDDYLIST_DEFAULT, "Buddy Default" },
303 static const value_string aim_fnac_family_messaging[] = {
304 { FAMILY_MESSAGING_ERROR, "Error" },
305 { FAMILY_MESSAGING_PARAMINFO, "Parameter Info" },
306 { FAMILY_MESSAGING_INCOMING, "Incoming" },
307 { FAMILY_MESSAGING_EVIL, "Evil" },
308 { FAMILY_MESSAGING_MISSEDCALL, "Missed Call" },
309 { FAMILY_MESSAGING_CLIENTAUTORESP, "Client Auto Response" },
310 { FAMILY_MESSAGING_ACK, "Acknowledge" },
311 { FAMILY_MESSAGING_DEFAULT, "Messaging Default" },
315 static const value_string aim_fnac_family_adverts[] = {
316 { FAMILY_ADVERTS_ERROR, "Error" },
317 { FAMILY_ADVERTS_REQUEST, "Request" },
318 { FAMILY_ADVERTS_DATA, "Data (GIF)" },
319 { FAMILY_ADVERTS_DEFAULT, "Adverts Default" },
323 static const value_string aim_fnac_family_invitation[] = {
324 { FAMILY_INVITATION_ERROR, "Error" },
325 { FAMILY_INVITATION_DEFAULT, "Invitation Default" },
329 static const value_string aim_fnac_family_admin[] = {
330 { FAMILY_ADMIN_ERROR, "Error" },
331 { FAMILY_ADMIN_INFOCHANGEREPLY, "Infochange reply" },
332 { FAMILY_ADMIN_DEFAULT, "Adminstrative Default" },
336 static const value_string aim_fnac_family_popup[] = {
337 { FAMILY_POPUP_ERROR, "Error" },
338 { FAMILY_POPUP_DEFAULT, "Popup Default" },
342 static const value_string aim_fnac_family_bos[] = {
343 { FAMILY_BOS_ERROR, "Error" },
344 { FAMILY_BOS_RIGHTSQUERY, "Rights Query" },
345 { FAMILY_BOS_RIGHTS, "Rights" },
346 { FAMILY_BOS_DEFAULT, "BOS Default" },
350 static const value_string aim_fnac_family_userlookup[] = {
351 { FAMILY_USERLOOKUP_ERROR, "Error" },
352 { FAMILY_USERLOOKUP_DEFAULT, "Userlookup Default" },
356 static const value_string aim_fnac_family_stats[] = {
357 { FAMILY_STATS_ERROR, "Error" },
358 { FAMILY_STATS_SETREPORTINTERVAL, "Set Report Interval" },
359 { FAMILY_STATS_REPORTACK, "Report Ack" },
360 { FAMILY_STATS_DEFAULT, "Stats Default" },
364 static const value_string aim_fnac_family_translate[] = {
365 { FAMILY_TRANSLATE_ERROR, "Error" },
366 { FAMILY_TRANSLATE_DEFAULT, "Translate Default" },
370 static const value_string aim_fnac_family_chatnav[] = {
371 { FAMILY_CHATNAV_ERROR, "Error" },
372 { FAMILY_CHATNAV_CREATE, "Create" },
373 { FAMILY_CHATNAV_INFO, "Info" },
374 { FAMILY_CHATNAV_DEFAULT, "ChatNav Default" },
378 static const value_string aim_fnac_family_chat[] = {
379 { FAMILY_CHAT_ERROR, "Error" },
380 { FAMILY_CHAT_USERJOIN, "User Join" },
381 { FAMILY_CHAT_USERLEAVE, "User Leave" },
382 { FAMILY_CHAT_OUTGOINGMSG, "Outgoing Message" },
383 { FAMILY_CHAT_INCOMINGMSG, "Incoming Message" },
384 { FAMILY_CHAT_DEFAULT, "Chat Default" },
388 static const value_string aim_fnac_family_ssi[] = {
389 { FAMILY_SSI_ERROR, "Error" },
390 { FAMILY_SSI_REQRIGHTS, "Request Rights" },
391 { FAMILY_SSI_RIGHTSINFO, "Rights Info" },
392 { FAMILY_SSI_REQLIST, "Request List" },
393 { FAMILY_SSI_LIST, "List" },
394 { FAMILY_SSI_ACTIVATE, "Activate" },
395 { FAMILY_SSI_ADD, "Add Buddy" },
396 { FAMILY_SSI_MOD, "Modify Buddy" },
397 { FAMILY_SSI_DEL, "Delete Buddy" },
398 { FAMILY_SSI_SRVACK, "Server Ack" },
399 { FAMILY_SSI_NOLIST, "No List" },
400 { FAMILY_SSI_EDITSTART, "Edit Start" },
401 { FAMILY_SSI_EDITSTOP, "Edit Stop" },
405 #define FAMILY_SSI_TYPE_BUDDY 0x0000
406 #define FAMILY_SSI_TYPE_GROUP 0x0001
407 #define FAMILY_SSI_TYPE_PERMIT 0x0002
408 #define FAMILY_SSI_TYPE_DENY 0x0003
409 #define FAMILY_SSI_TYPE_PDINFO 0x0004
410 #define FAMILY_SSI_TYPE_PRESENCEPREFS 0x0005
411 #define FAMILY_SSI_TYPE_ICONINFO 0x0014
413 static const value_string aim_fnac_family_ssi_types[] = {
414 { FAMILY_SSI_TYPE_BUDDY, "Buddy" },
415 { FAMILY_SSI_TYPE_GROUP, "Group" },
416 { FAMILY_SSI_TYPE_PERMIT, "Permit" },
417 { FAMILY_SSI_TYPE_DENY, "Deny" },
418 { FAMILY_SSI_TYPE_PDINFO, "PDINFO" },
419 { FAMILY_SSI_TYPE_PRESENCEPREFS, "Presence Preferences" },
420 { FAMILY_SSI_TYPE_ICONINFO, "Icon Info" },
424 static const value_string aim_fnac_family_icq[] = {
425 { FAMILY_ICQ_ERROR, "Error" },
426 { FAMILY_ICQ_LOGINREQUEST, "Login Request" },
427 { FAMILY_ICQ_LOGINRESPONSE, "Login Response" },
428 { FAMILY_ICQ_AUTHREQUEST, "Auth Request" },
429 { FAMILY_ICQ_AUTHRESPONSE, "Auth Response" },
433 #define SIGNON_SCREENNAME 0x0001
434 #define SIGNON_PASSWORD 0x0025
435 #define SIGNON_CLIENTSTRING 0x0003
436 #define SIGNON_CLIENTMAJOR 0x0017
437 #define SIGNON_CLIENTMINOR 0x0018
438 #define SIGNON_CLIENTPOINT 0x0019
439 #define SIGNON_CLIENTBUILD 0x001a
440 #define SIGNON_CLIENTCOUNTRY 0x000e
441 #define SIGNON_CLIENTLANGUAGE 0x000f
442 #define SIGNON_CLIENTUSESSI 0x004a
444 static const aim_tlv aim_signon_signon_tlv[] = {
445 { SIGNON_SCREENNAME, "Screen Name", FT_STRING },
446 { SIGNON_PASSWORD, "Signon Challenge Response", FT_BYTES },
447 { SIGNON_CLIENTSTRING, "Login Request", FT_STRING },
448 { SIGNON_CLIENTMAJOR, "Client Major Version", FT_UINT16 },
449 { SIGNON_CLIENTMINOR, "Client Minor Version", FT_UINT16 },
450 { SIGNON_CLIENTPOINT, "Client Point", FT_UINT16 },
451 { SIGNON_CLIENTBUILD, "Client Build", FT_UINT16 },
452 { SIGNON_CLIENTCOUNTRY, "Client Country", FT_STRING },
453 { SIGNON_CLIENTLANGUAGE, "Client Language", FT_STRING },
454 { SIGNON_CLIENTUSESSI, "Use SSI", FT_UINT8 },
458 #define SIGNON_LOGON_REPLY_SCREENNAME 0x0001
459 #define SIGNON_LOGON_REPLY_ERRORURL 0x0004
460 #define SIGNON_LOGON_REPLY_BOSADDR 0x0005
461 #define SIGNON_LOGON_REPLY_AUTHCOOKIE 0x0006
462 #define SIGNON_LOGON_REPLY_ERRORCODE 0x0008
463 #define SIGNON_LOGON_REPLY_EMAILADDR 0x0011
464 #define SIGNON_LOGON_REPLY_REGSTATUS 0x0013
465 #define SIGNON_LOGON_REPLY_LATESTBETABUILD 0x0040
466 #define SIGNON_LOGON_REPLY_LATESTBETAURL 0x0041
467 #define SIGNON_LOGON_REPLY_LATESTBETAINFO 0x0042
468 #define SIGNON_LOGON_REPLY_LATESTBETANAME 0x0043
469 #define SIGNON_LOGON_REPLY_LATESTRELEASEBUILD 0x0044
470 #define SIGNON_LOGON_REPLY_LATESTRELEASEURL 0x0045
471 #define SIGNON_LOGON_REPLY_LATESTRELEASEINFO 0x0046
472 #define SIGNON_LOGON_REPLY_LATESTRELEASENAME 0x0047
474 static const aim_tlv aim_signon_logon_reply_tlv[] = {
475 { SIGNON_LOGON_REPLY_SCREENNAME, "Screen Name", FT_STRING },
476 { SIGNON_LOGON_REPLY_ERRORURL, "Error URL", FT_STRING },
477 { SIGNON_LOGON_REPLY_BOSADDR, "BOS Server Address", FT_STRING },
478 { SIGNON_LOGON_REPLY_AUTHCOOKIE, "Authorization Cookie", FT_BYTES },
479 { SIGNON_LOGON_REPLY_ERRORCODE, "Error Code", FT_UINT16 },
480 { SIGNON_LOGON_REPLY_EMAILADDR, "Account Email Address", FT_STRING },
481 { SIGNON_LOGON_REPLY_REGSTATUS, "Registration Status", FT_UINT16 },
482 { SIGNON_LOGON_REPLY_LATESTBETABUILD, "Latest Beta Build", FT_UINT32 },
483 { SIGNON_LOGON_REPLY_LATESTBETAURL, "Latest Beta URL", FT_STRING },
484 { SIGNON_LOGON_REPLY_LATESTBETAINFO, "Latest Beta Info", FT_STRING },
485 { SIGNON_LOGON_REPLY_LATESTBETANAME, "Latest Beta Name", FT_STRING },
486 { SIGNON_LOGON_REPLY_LATESTRELEASEBUILD, "Latest Release Build", FT_UINT32 },
487 { SIGNON_LOGON_REPLY_LATESTRELEASEURL, "Latest Release URL", FT_STRING },
488 { SIGNON_LOGON_REPLY_LATESTRELEASEINFO, "Latest Release Info", FT_STRING },
489 { SIGNON_LOGON_REPLY_LATESTRELEASENAME, "Latest Release Name", FT_STRING },
493 #define FAMILY_BUDDYLIST_USERFLAGS 0x0001
494 #define FAMILY_BUDDYLIST_MEMBERSINCE 0x0002
495 #define FAMILY_BUDDYLIST_ONSINCE 0x0003
496 #define FAMILY_BUDDYLIST_IDLETIME 0x0004
497 #define FAMILY_BUDDYLIST_ICQSTATUS 0x0006
498 #define FAMILY_BUDDYLIST_ICQIPADDR 0x000a
499 #define FAMILY_BUDDYLIST_ICQSTUFF 0x000c
500 #define FAMILY_BUDDYLIST_CAPINFO 0x000d
501 #define FAMILY_BUDDYLIST_UNKNOWN 0x000e
502 #define FAMILY_BUDDYLIST_SESSIONLEN 0x000f
503 #define FAMILY_BUDDYLIST_ICQSESSIONLEN 0x0010
505 static const aim_tlv aim_fnac_family_buddylist_oncoming_tlv[] = {
506 { FAMILY_BUDDYLIST_USERFLAGS, "User flags", FT_UINT16 },
507 { FAMILY_BUDDYLIST_MEMBERSINCE, "Member since date", FT_UINT32 },
508 { FAMILY_BUDDYLIST_ONSINCE, "Online since", FT_UINT32 },
509 { FAMILY_BUDDYLIST_IDLETIME, "Idle time (sec)", FT_UINT16 },
510 { FAMILY_BUDDYLIST_ICQSTATUS, "ICQ Online status", FT_UINT16 },
511 { FAMILY_BUDDYLIST_ICQIPADDR, "ICQ User IP Address", FT_UINT16 },
512 { FAMILY_BUDDYLIST_ICQSTUFF, "ICQ Info", FT_BYTES },
513 { FAMILY_BUDDYLIST_CAPINFO, "Capability Info", FT_BYTES },
514 { FAMILY_BUDDYLIST_UNKNOWN, "Unknown", FT_UINT16 },
515 { FAMILY_BUDDYLIST_SESSIONLEN, "Session Length (sec)", FT_UINT32 },
516 { FAMILY_BUDDYLIST_SESSIONLEN, "ICQ Session Length (sec)", FT_UINT32 },
521 #define FAMILY_LOCATION_USERINFO_INFOENCODING 0x0001
522 #define FAMILY_LOCATION_USERINFO_INFOMSG 0x0002
523 #define FAMILY_LOCATION_USERINFO_AWAYENCODING 0x0003
524 #define FAMILY_LOCATION_USERINFO_AWAYMSG 0x0004
525 #define FAMILY_LOCATION_USERINFO_CAPS 0x0005
527 static const aim_tlv aim_fnac_family_location_userinfo_tlv[] = {
528 { FAMILY_LOCATION_USERINFO_INFOENCODING, "Info Msg Encoding", FT_STRING },
529 { FAMILY_LOCATION_USERINFO_INFOMSG, "Info Message", FT_STRING },
530 { FAMILY_LOCATION_USERINFO_AWAYENCODING, "Away Msg Encoding", FT_STRING },
531 { FAMILY_LOCATION_USERINFO_AWAYMSG, "Away Message", FT_STRING },
532 { FAMILY_LOCATION_USERINFO_CAPS, "Capabilities", FT_BYTES },
536 #define FAMILY_LOCATION_USERINFO_INFOTYPE_GENERALINFO 0x0001
537 #define FAMILY_LOCATION_USERINFO_INFOTYPE_AWAYMSG 0x0003
538 #define FAMILY_LOCATION_USERINFO_INFOTYPE_CAPS 0x0005
540 static const value_string aim_snac_location_request_user_info_infotypes[] = {
541 { FAMILY_LOCATION_USERINFO_INFOTYPE_GENERALINFO, "Request General Info" },
542 { FAMILY_LOCATION_USERINFO_INFOTYPE_AWAYMSG, "Request Away Message" },
543 { FAMILY_LOCATION_USERINFO_INFOTYPE_CAPS, "Request Capabilities" },
547 static int dissect_aim(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
548 static guint get_aim_pdu_len(tvbuff_t *tvb, int offset);
549 static void dissect_aim_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
551 static void get_message( guchar *msg, tvbuff_t *tvb, int msg_offset, int msg_length);
552 static int get_buddyname( char *name, tvbuff_t *tvb, int len_offset, int name_offset);
553 static void dissect_aim_newconn(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *tree);
554 static void dissect_aim_snac(tvbuff_t *tvb, packet_info *pinfo,
555 int offset, proto_tree *tree);
556 static void dissect_aim_snac_fnac_subtype(tvbuff_t *tvb, int offset,
557 proto_tree *tree, guint16 family);
558 static void dissect_aim_snac_signon(tvbuff_t *tvb, packet_info *pinfo,
559 int offset, proto_tree *tree,
561 static void dissect_aim_snac_signon_logon(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *tree);
562 static void dissect_aim_snac_signon_logon_reply(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *tree);
563 static void dissect_aim_snac_signon_signon(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *tree);
564 static void dissect_aim_snac_signon_signon_reply(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *tree);
565 static void dissect_aim_snac_generic(tvbuff_t *tvb, packet_info *pinfo,
566 int offset, proto_tree *tree,
568 static void dissect_aim_snac_buddylist(tvbuff_t *tvb, packet_info *pinfo,
569 int offset, proto_tree *tree,
571 static void dissect_aim_snac_location(tvbuff_t *tvb, packet_info *pinfo,
572 int offset, proto_tree *tree,
574 static void dissect_aim_snac_location_request_user_information(tvbuff_t *tvb, int offset, proto_tree *tree);
575 static void dissect_aim_snac_location_user_information(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *tree);
576 static void dissect_aim_snac_adverts(tvbuff_t *tvb, packet_info *pinfo,
577 int offset, proto_tree *tree,
579 static void dissect_aim_snac_userlookup(tvbuff_t *tvb, packet_info *pinfo,
580 int offset, proto_tree *tree,
582 static void dissect_aim_snac_chat(tvbuff_t *tvb, packet_info *pinfo,
583 int offset, proto_tree *tree,
585 static void dissect_aim_snac_messaging(tvbuff_t *tvb, packet_info *pinfo,
586 int offset, proto_tree *tree,
588 static void dissect_aim_snac_ssi(tvbuff_t *tvb, packet_info *pinfo,
589 int offset, proto_tree *tree,
591 static void dissect_aim_snac_ssi_list(tvbuff_t *tvb, packet_info *pinfo _U_,
592 int offset, proto_tree *tree,
593 guint16 subtype _U_);
594 static void dissect_aim_flap_err(tvbuff_t *tvb, packet_info *pinfo,
595 int offset, proto_tree *tree);
596 static void dissect_aim_close_conn(tvbuff_t *tvb, packet_info *pinfo,
597 int offset, proto_tree *tree);
598 static void dissect_aim_unknown_channel(tvbuff_t *tvb, packet_info *pinfo,
599 int offset, proto_tree *tree);
600 static int dissect_aim_tlv(tvbuff_t *tvb, packet_info *pinfo,
601 int offset, proto_tree *tree, const aim_tlv *tlv);
603 /* Initialize the protocol and registered fields */
604 static int proto_aim = -1;
605 static int hf_aim_cmd_start = -1;
606 static int hf_aim_channel = -1;
607 static int hf_aim_seqno = -1;
608 static int hf_aim_data = -1;
609 static int hf_aim_data_len = -1;
610 static int hf_aim_signon_challenge_len = -1;
611 static int hf_aim_signon_challenge = -1;
612 static int hf_aim_fnac_family = -1;
613 static int hf_aim_fnac_subtype = -1;
614 static int hf_aim_fnac_subtype_signon = -1;
615 static int hf_aim_fnac_subtype_generic = -1;
616 static int hf_aim_fnac_subtype_location = -1;
617 static int hf_aim_fnac_subtype_buddylist = -1;
618 static int hf_aim_fnac_subtype_messaging = -1;
619 static int hf_aim_fnac_subtype_adverts = -1;
620 static int hf_aim_fnac_subtype_invitation = -1;
621 static int hf_aim_fnac_subtype_admin = -1;
622 static int hf_aim_fnac_subtype_popup = -1;
623 static int hf_aim_fnac_subtype_bos = -1;
624 static int hf_aim_fnac_subtype_userlookup = -1;
625 static int hf_aim_fnac_subtype_stats = -1;
626 static int hf_aim_fnac_subtype_translate = -1;
627 static int hf_aim_fnac_subtype_chatnav = -1;
628 static int hf_aim_fnac_subtype_chat = -1;
629 static int hf_aim_fnac_subtype_ssi = -1;
630 static int hf_aim_fnac_subtype_ssi_version = -1;
631 static int hf_aim_fnac_subtype_ssi_numitems = -1;
632 static int hf_aim_fnac_subtype_ssi_buddyname_len = -1;
633 static int hf_aim_fnac_subtype_ssi_buddyname = -1;
634 static int hf_aim_fnac_subtype_ssi_gid = -1;
635 static int hf_aim_fnac_subtype_ssi_bid = -1;
636 static int hf_aim_fnac_subtype_ssi_type = -1;
637 static int hf_aim_fnac_subtype_ssi_tlvlen = -1;
638 static int hf_aim_fnac_subtype_ssi_data = -1;
639 static int hf_aim_fnac_subtype_icq = -1;
640 static int hf_aim_fnac_flags = -1;
641 static int hf_aim_fnac_id = -1;
642 static int hf_aim_infotype = -1;
643 static int hf_aim_snac_location_request_user_info_infotype = -1;
644 static int hf_aim_buddyname_len = -1;
645 static int hf_aim_buddyname = -1;
646 static int hf_aim_userinfo_warninglevel = -1;
647 static int hf_aim_userinfo_tlvcount = -1;
649 /* Initialize the subtree pointers */
650 static gint ett_aim = -1;
651 static gint ett_aim_fnac = -1;
652 static gint ett_aim_tlv = -1;
653 static gint ett_aim_ssi = -1;
655 /* desegmentation of AIM over TCP */
656 static gboolean aim_desegment = TRUE;
658 /* Code to actually dissect the packets */
659 static int dissect_aim(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
661 /* check, if this is really an AIM packet, they start with 0x2a */
662 /* XXX - I've seen some stuff starting with 0x5a followed by 0x2a */
664 if(tvb_bytes_exist(tvb, 0, 1) && tvb_get_guint8(tvb, 0) != 0x2a) {
665 /* Not an instant messenger packet, just happened to use the same port */
666 /* XXX - if desegmentation disabled, this might be a continuation
667 packet, not a non-AIM packet */
671 tcp_dissect_pdus(tvb, pinfo, tree, aim_desegment, 6, get_aim_pdu_len,
673 return tvb_length(tvb);
676 static guint get_aim_pdu_len(tvbuff_t *tvb, int offset)
681 * Get the length of the AIM packet.
683 plen = tvb_get_ntohs(tvb, offset + 4);
686 * That length doesn't include the length of the header itself; add that in.
691 static void dissect_aim_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
694 unsigned char hdr_channel; /* channel ID */
695 unsigned short hdr_sequence_no; /* Internal frame sequence number, not needed */
696 unsigned short hdr_data_field_length; /* length of data within frame */
700 /* Set up structures we will need to add the protocol subtree and manage it */
702 proto_tree *aim_tree = NULL;
704 /* Make entries in Protocol column and Info column on summary display */
705 if (check_col(pinfo->cinfo, COL_PROTOCOL))
706 col_set_str(pinfo->cinfo, COL_PROTOCOL, "AIM");
708 if (check_col(pinfo->cinfo, COL_INFO))
709 col_add_str(pinfo->cinfo, COL_INFO, "AOL Instant Messenger");
711 /* get relevant header information */
712 offset += 1; /* XXX - put the identifier into the tree? */
713 hdr_channel = tvb_get_guint8(tvb, offset);
715 hdr_sequence_no = tvb_get_ntohs(tvb, offset);
717 hdr_data_field_length = tvb_get_ntohs(tvb, offset);
720 /* In the interest of speed, if "tree" is NULL, don't do any work not
721 necessary to generate protocol tree items. */
724 ti = proto_tree_add_item(tree, proto_aim, tvb, 0, -1, FALSE);
725 aim_tree = proto_item_add_subtree(ti, ett_aim);
726 proto_tree_add_uint(aim_tree, hf_aim_cmd_start, tvb, 0, 1, '*');
727 proto_tree_add_uint(aim_tree, hf_aim_channel, tvb, 1, 1, hdr_channel);
728 proto_tree_add_uint(aim_tree, hf_aim_seqno, tvb, 2, 2, hdr_sequence_no);
729 proto_tree_add_uint(aim_tree, hf_aim_data_len, tvb, 4, 2, hdr_data_field_length);
735 /* New connection request */
736 case CHANNEL_NEW_CONN:
737 dissect_aim_newconn(tvb, pinfo, offset, aim_tree);
739 case CHANNEL_SNAC_DATA:
740 dissect_aim_snac(tvb, pinfo, offset, aim_tree);
742 case CHANNEL_FLAP_ERR:
743 dissect_aim_flap_err(tvb, pinfo, offset, aim_tree);
745 case CHANNEL_CLOSE_CONN:
746 dissect_aim_close_conn(tvb, pinfo, offset, aim_tree);
749 dissect_aim_unknown_channel(tvb, pinfo, offset, aim_tree);
756 static int get_buddyname( char *name, tvbuff_t *tvb, int len_offset, int name_offset)
758 guint8 buddyname_length;
760 buddyname_length = tvb_get_guint8(tvb, len_offset);
762 if(buddyname_length > MAX_BUDDYNAME_LENGTH ) buddyname_length = MAX_BUDDYNAME_LENGTH;
763 tvb_get_nstringz0(tvb, name_offset, buddyname_length + 1, name);
765 return buddyname_length;
769 static void get_message( guchar *msg, tvbuff_t *tvb, int msg_offset, int msg_length)
773 int max, tagchars = 0;
774 int new_offset = msg_offset;
775 int new_length = msg_length;
779 /* make sure nothing bigger than 1000 bytes is printed */
780 if( msg_length > 999 ) return;
782 memset( msg, '\0', 1000);
786 /* loop until HTML tag is reached - quick&dirty way to find start of message
787 * (it is nearly impossible to find the correct start offset for all client versions) */
788 while( (tagchars < 6) && (new_length > 5) )
790 j = tvb_get_guint8(tvb, new_offset);
791 if( ( (j == '<') && (tagchars == 0) ) ||
792 ( (j == 'h') && (tagchars == 1) ) ||
793 ( (j == 'H') && (tagchars == 1) ) ||
794 ( (j == 't') && (tagchars == 2) ) ||
795 ( (j == 'T') && (tagchars == 2) ) ||
796 ( (j == 'm') && (tagchars == 3) ) ||
797 ( (j == 'M') && (tagchars == 3) ) ||
798 ( (j == 'l') && (tagchars == 4) ) ||
799 ( (j == 'L') && (tagchars == 4) ) ||
800 ( (j == '>') && (tagchars == 5) ) ) tagchars++;
805 /* set offset and length of message to after the first HTML tag */
806 msg_offset = new_offset;
807 msg_length = new_length;
808 max = msg_length - 1;
811 /* find the rest of the message until either a </html> is reached or the end of the frame.
812 * All other HTML tags are stripped to display only the raw message (printable characters) */
813 while( (c < max) && (tagchars < 7) )
815 j = tvb_get_guint8(tvb, msg_offset+c);
818 /* make sure this is an HTML tag by checking the order of the chars */
819 if( ( (j == '<') && (tagchars == 0) ) ||
820 ( (j == '/') && (tagchars == 1) ) ||
821 ( (j == 'h') && (tagchars == 2) ) ||
822 ( (j == 'H') && (tagchars == 2) ) ||
823 ( (j == 't') && (tagchars == 3) ) ||
824 ( (j == 'T') && (tagchars == 3) ) ||
825 ( (j == 'm') && (tagchars == 4) ) ||
826 ( (j == 'M') && (tagchars == 4) ) ||
827 ( (j == 'l') && (tagchars == 5) ) ||
828 ( (j == 'L') && (tagchars == 5) ) ||
829 ( (j == '>') && (tagchars == 6) ) ) tagchars++;
832 if( j == '<' ) bracket = TRUE;
833 if( j == '>' ) bracket = FALSE;
834 if( (isprint(j) ) && (bracket == FALSE) && (j != '>'))
846 static void dissect_aim_newconn(tvbuff_t *tvb, packet_info *pinfo,
847 int offset, proto_tree *tree)
849 if (check_col(pinfo->cinfo, COL_INFO))
850 col_add_fstr(pinfo->cinfo, COL_INFO, "New Connection");
851 if (tvb_length_remaining(tvb, offset) > 0)
852 proto_tree_add_item(tree, hf_aim_data, tvb, offset, -1, FALSE);
855 static void dissect_aim_snac(tvbuff_t *tvb, packet_info *pinfo,
856 int offset, proto_tree *aim_tree)
863 proto_tree *aim_tree_fnac = NULL;
866 orig_offset = offset;
867 family = tvb_get_ntohs(tvb, offset);
869 subtype = tvb_get_ntohs(tvb, offset);
871 flags = tvb_get_ntohs(tvb, offset);
873 id = tvb_get_ntohl(tvb, offset);
876 if (check_col(pinfo->cinfo, COL_INFO)) {
877 col_add_fstr(pinfo->cinfo, COL_INFO, "SNAC data");
881 offset = orig_offset;
882 ti1 = proto_tree_add_text(aim_tree, tvb, 6, 10, "FNAC");
883 aim_tree_fnac = proto_item_add_subtree(ti1, ett_aim_fnac);
885 proto_tree_add_item (aim_tree_fnac, hf_aim_fnac_family,
886 tvb, offset, 2, FALSE);
889 /* Dissect the subtype based on the family */
890 dissect_aim_snac_fnac_subtype(tvb, offset, aim_tree_fnac, family);
893 proto_tree_add_uint(aim_tree_fnac, hf_aim_fnac_flags, tvb, offset,
896 proto_tree_add_uint(aim_tree_fnac, hf_aim_fnac_id, tvb, offset,
901 if (check_col(pinfo->cinfo, COL_INFO))
902 col_append_fstr(pinfo->cinfo, COL_INFO, ", Family: %s",
903 val_to_str(family, aim_fnac_family_ids,
904 "Unknown Family ID=0x%04x"));
909 dissect_aim_snac_signon(tvb, pinfo, offset, aim_tree, subtype);
912 dissect_aim_snac_generic(tvb, pinfo, offset, aim_tree, subtype);
914 case FAMILY_BUDDYLIST:
915 dissect_aim_snac_buddylist(tvb, pinfo, offset, aim_tree, subtype);
917 case FAMILY_LOCATION:
918 dissect_aim_snac_location(tvb, pinfo, offset, aim_tree, subtype);
921 dissect_aim_snac_adverts(tvb, pinfo, offset, aim_tree, subtype);
923 case FAMILY_USERLOOKUP:
924 dissect_aim_snac_userlookup(tvb, pinfo, offset, aim_tree, subtype);
927 dissect_aim_snac_chat(tvb, pinfo, offset, aim_tree, subtype);
929 case FAMILY_MESSAGING:
930 dissect_aim_snac_messaging(tvb, pinfo, offset, aim_tree, subtype);
933 dissect_aim_snac_ssi(tvb, pinfo, offset, aim_tree, subtype);
938 static void dissect_aim_snac_signon(tvbuff_t *tvb, packet_info *pinfo,
939 int offset, proto_tree *tree,
944 case FAMILY_SIGNON_LOGON:
945 dissect_aim_snac_signon_logon(tvb, pinfo, offset, tree);
947 case FAMILY_SIGNON_LOGON_REPLY:
948 dissect_aim_snac_signon_logon_reply(tvb, pinfo, offset, tree);
950 case FAMILY_SIGNON_SIGNON:
951 dissect_aim_snac_signon_signon(tvb, pinfo, offset, tree);
953 case FAMILY_SIGNON_SIGNON_REPLY:
954 dissect_aim_snac_signon_signon_reply(tvb, pinfo, offset, tree);
959 static void dissect_aim_snac_signon_logon(tvbuff_t *tvb, packet_info *pinfo,
960 int offset, proto_tree *tree)
962 while (tvb_length_remaining(tvb, offset) > 0) {
963 offset = dissect_aim_tlv(tvb, pinfo, offset, tree, aim_signon_signon_tlv);
967 static void dissect_aim_snac_signon_logon_reply(tvbuff_t *tvb,
969 int offset, proto_tree *tree)
971 if (check_col(pinfo->cinfo, COL_INFO))
972 col_append_fstr(pinfo->cinfo, COL_INFO, ", Login information reply");
974 while (tvb_length_remaining(tvb, offset) > 0) {
975 offset = dissect_aim_tlv(tvb, pinfo, offset, tree,
976 aim_signon_logon_reply_tlv);
980 static void dissect_aim_snac_signon_signon(tvbuff_t *tvb, packet_info *pinfo,
981 int offset, proto_tree *tree)
983 guint8 buddyname_length = 0;
984 char buddyname[MAX_BUDDYNAME_LENGTH + 1];
987 proto_tree_add_item(tree, hf_aim_infotype, tvb, offset, 2, FALSE);
994 buddyname_length = get_buddyname( buddyname, tvb, offset, offset + 1 );
996 if (check_col(pinfo->cinfo, COL_INFO)) {
997 col_append_fstr(pinfo->cinfo, COL_INFO, " Username: %s", buddyname);
1001 proto_tree_add_text(tree, tvb, offset + 1, buddyname_length,
1002 "Screen Name: %s", buddyname);
1005 offset += buddyname_length + 1;
1008 static void dissect_aim_snac_signon_signon_reply(tvbuff_t *tvb,
1010 int offset, proto_tree *tree)
1012 guint16 challenge_length = 0;
1014 if (check_col(pinfo->cinfo, COL_INFO))
1015 col_append_fstr(pinfo->cinfo, COL_INFO, ", Sign-on reply");
1017 /* Logon Challenge Length */
1018 challenge_length = tvb_get_ntohs(tvb, offset);
1019 proto_tree_add_item(tree, hf_aim_signon_challenge_len, tvb, offset, 2, FALSE);
1023 proto_tree_add_item(tree, hf_aim_signon_challenge, tvb, offset, challenge_length, FALSE);
1024 offset += challenge_length;
1027 static void dissect_aim_snac_generic(tvbuff_t *tvb, packet_info *pinfo,
1028 int offset, proto_tree *tree,
1033 case FAMILY_GENERIC_ERROR:
1034 if (check_col(pinfo->cinfo, COL_INFO))
1035 col_add_fstr(pinfo->cinfo, COL_INFO, "Generic Error");
1037 case FAMILY_GENERIC_CLIENTREADY:
1038 if (check_col(pinfo->cinfo, COL_INFO))
1039 col_add_fstr(pinfo->cinfo, COL_INFO,
1040 "Client is now online and ready for normal function");
1042 case FAMILY_GENERIC_SERVERREADY:
1043 if (check_col(pinfo->cinfo, COL_INFO))
1044 col_add_fstr(pinfo->cinfo, COL_INFO,
1045 "Server is now ready for normal functions");
1047 case FAMILY_GENERIC_SERVICEREQ:
1048 if (check_col(pinfo->cinfo, COL_INFO))
1049 col_add_fstr(pinfo->cinfo, COL_INFO,
1050 "Request for new service (server will redirect client)");
1052 case FAMILY_GENERIC_REDIRECT:
1053 if (check_col(pinfo->cinfo, COL_INFO))
1054 col_add_fstr(pinfo->cinfo, COL_INFO, "Redirect response");
1056 case FAMILY_GENERIC_RATEINFOREQ:
1057 if (check_col(pinfo->cinfo, COL_INFO))
1058 col_add_fstr(pinfo->cinfo, COL_INFO, "Request Rate Information");
1060 case FAMILY_GENERIC_RATEINFO:
1061 if (check_col(pinfo->cinfo, COL_INFO))
1062 col_add_fstr(pinfo->cinfo, COL_INFO, "Rate information response");
1064 case FAMILY_GENERIC_RATEINFOACK:
1065 if (check_col(pinfo->cinfo, COL_INFO))
1066 col_add_fstr(pinfo->cinfo, COL_INFO, "Rate Information Response Ack");
1068 case FAMILY_GENERIC_RATECHANGE:
1069 if (check_col(pinfo->cinfo, COL_INFO))
1070 col_add_fstr(pinfo->cinfo, COL_INFO, "Rate Change");
1072 case FAMILY_GENERIC_SERVERPAUSE:
1073 if (check_col(pinfo->cinfo, COL_INFO))
1074 col_add_fstr(pinfo->cinfo, COL_INFO, "Server Pause");
1076 case FAMILY_GENERIC_SERVERRESUME:
1077 if (check_col(pinfo->cinfo, COL_INFO))
1078 col_add_fstr(pinfo->cinfo, COL_INFO, "Server Resume");
1080 case FAMILY_GENERIC_REQSELFINFO:
1081 if (check_col(pinfo->cinfo, COL_INFO))
1082 col_add_fstr(pinfo->cinfo, COL_INFO, "Request Self Info");
1084 case FAMILY_GENERIC_SELFINFO:
1085 if (check_col(pinfo->cinfo, COL_INFO))
1086 col_add_fstr(pinfo->cinfo, COL_INFO, "Self Info");
1088 case FAMILY_GENERIC_EVIL:
1089 if (check_col(pinfo->cinfo, COL_INFO))
1090 col_add_fstr(pinfo->cinfo, COL_INFO, "Evil");
1092 case FAMILY_GENERIC_SETIDLE:
1093 if (check_col(pinfo->cinfo, COL_INFO))
1094 col_add_fstr(pinfo->cinfo, COL_INFO, "Set Idle");
1096 case FAMILY_GENERIC_MIGRATIONREQ:
1097 if (check_col(pinfo->cinfo, COL_INFO))
1098 col_add_fstr(pinfo->cinfo, COL_INFO, "Request Migration");
1100 case FAMILY_GENERIC_MOTD:
1101 if (check_col(pinfo->cinfo, COL_INFO))
1102 col_add_fstr(pinfo->cinfo, COL_INFO, "MOTD");
1104 case FAMILY_GENERIC_SETPRIVFLAGS:
1105 if (check_col(pinfo->cinfo, COL_INFO))
1106 col_add_fstr(pinfo->cinfo, COL_INFO, "Set Privilege Flags");
1108 case FAMILY_GENERIC_WELLKNOWNURL:
1109 if (check_col(pinfo->cinfo, COL_INFO))
1110 col_add_fstr(pinfo->cinfo, COL_INFO, "Well Known URL");
1112 case FAMILY_GENERIC_NOP:
1113 if (check_col(pinfo->cinfo, COL_INFO))
1114 col_add_fstr(pinfo->cinfo, COL_INFO, "No-op");
1116 case FAMILY_GENERIC_DEFAULT:
1117 if (check_col(pinfo->cinfo, COL_INFO))
1118 col_add_fstr(pinfo->cinfo, COL_INFO, "Generic Default");
1122 /* Show the undissected payload */
1123 if (tvb_length_remaining(tvb, offset) > 0)
1124 proto_tree_add_item(tree, hf_aim_data, tvb, offset, -1, FALSE);
1127 static void dissect_aim_snac_buddylist(tvbuff_t *tvb, packet_info *pinfo,
1128 int offset, proto_tree *tree,
1131 guint8 buddyname_length = 0;
1132 char buddyname[MAX_BUDDYNAME_LENGTH + 1];
1133 guint16 tlv_count = 0;
1137 case FAMILY_BUDDYLIST_ERROR:
1138 if (check_col(pinfo->cinfo, COL_INFO))
1139 col_add_fstr(pinfo->cinfo, COL_INFO, "Buddylist - Error");
1142 case FAMILY_BUDDYLIST_REQRIGHTS:
1143 if (check_col(pinfo->cinfo, COL_INFO))
1144 col_add_fstr(pinfo->cinfo, COL_INFO, "Request Rights information");
1147 case FAMILY_BUDDYLIST_RIGHTSINFO:
1148 if (check_col(pinfo->cinfo, COL_INFO))
1149 col_add_fstr(pinfo->cinfo, COL_INFO, "Rights information");
1152 case FAMILY_BUDDYLIST_ADDBUDDY:
1153 if (check_col(pinfo->cinfo, COL_INFO))
1154 col_add_fstr(pinfo->cinfo, COL_INFO, "Add to Buddylist");
1157 case FAMILY_BUDDYLIST_REMBUDDY:
1158 if (check_col(pinfo->cinfo, COL_INFO))
1159 col_add_fstr(pinfo->cinfo, COL_INFO, "Remove from Buddylist");
1162 case FAMILY_BUDDYLIST_ONCOMING:
1163 buddyname_length = get_buddyname( buddyname, tvb, offset, offset + 1 );
1165 if (check_col(pinfo->cinfo, COL_INFO)) {
1166 col_add_fstr(pinfo->cinfo, COL_INFO, "Oncoming Buddy");
1167 col_append_fstr(pinfo->cinfo, COL_INFO, ": %s", buddyname);
1171 proto_tree_add_text(tree, tvb, offset + 1, buddyname_length,
1172 "Screen Name: %s", buddyname);
1174 offset += buddyname_length + 1;
1177 proto_tree_add_item(tree, hf_aim_userinfo_warninglevel, tvb, offset,
1182 tlv_count = tvb_get_ntohs(tvb, offset);
1183 proto_tree_add_item(tree, hf_aim_userinfo_tlvcount, tvb, offset,
1187 while (tvb_length_remaining(tvb, offset) > 0) {
1188 offset = dissect_aim_tlv(tvb, pinfo, offset, tree,
1189 aim_fnac_family_buddylist_oncoming_tlv);
1194 case FAMILY_BUDDYLIST_OFFGOING:
1195 buddyname_length = get_buddyname( buddyname, tvb, offset, offset + 1 );
1197 if (check_col(pinfo->cinfo, COL_INFO)) {
1198 col_add_fstr(pinfo->cinfo, COL_INFO, "Offgoing Buddy");
1199 col_append_fstr(pinfo->cinfo, COL_INFO, ": %s", buddyname);
1203 proto_tree_add_text(tree, tvb, offset + 1, buddyname_length,
1204 "Screen Name: %s", buddyname);
1206 offset += buddyname_length + 1;
1209 proto_tree_add_item(tree, hf_aim_userinfo_warninglevel, tvb, offset,
1214 tlv_count = tvb_get_ntohs(tvb, offset);
1215 proto_tree_add_item(tree, hf_aim_userinfo_tlvcount, tvb, offset,
1222 /* Show the undissected payload */
1223 if (tvb_length_remaining(tvb, offset) > 0)
1224 proto_tree_add_item(tree, hf_aim_data, tvb, offset, -1, FALSE);
1227 static void dissect_aim_snac_location(tvbuff_t *tvb, packet_info *pinfo,
1228 int offset, proto_tree *tree,
1233 case FAMILY_LOCATION_ERROR:
1234 if (check_col(pinfo->cinfo, COL_INFO))
1235 col_add_fstr(pinfo->cinfo, COL_INFO, "Location - Error");
1237 case FAMILY_LOCATION_REQRIGHTS:
1238 if (check_col(pinfo->cinfo, COL_INFO))
1239 col_add_fstr(pinfo->cinfo, COL_INFO, "Request Rights Information");
1241 case FAMILY_LOCATION_RIGHTSINFO:
1242 if (check_col(pinfo->cinfo, COL_INFO))
1243 col_add_fstr(pinfo->cinfo, COL_INFO, "Rights Information");
1245 case FAMILY_LOCATION_SETUSERINFO:
1246 if (check_col(pinfo->cinfo, COL_INFO))
1247 col_add_fstr(pinfo->cinfo, COL_INFO, "Set User Information");
1249 case FAMILY_LOCATION_REQUSERINFO:
1250 if (check_col(pinfo->cinfo, COL_INFO))
1251 col_add_fstr(pinfo->cinfo, COL_INFO, "Request User Information");
1252 dissect_aim_snac_location_request_user_information(tvb, offset, tree);
1254 case FAMILY_LOCATION_USERINFO:
1255 if (check_col(pinfo->cinfo, COL_INFO))
1256 col_add_fstr(pinfo->cinfo, COL_INFO, "User Information");
1257 dissect_aim_snac_location_user_information(tvb, pinfo, offset, tree);
1259 case FAMILY_LOCATION_WATCHERSUBREQ:
1260 if (check_col(pinfo->cinfo, COL_INFO))
1261 col_add_fstr(pinfo->cinfo, COL_INFO, "Watcher Subrequest");
1263 case FAMILY_LOCATION_WATCHERNOT:
1264 if (check_col(pinfo->cinfo, COL_INFO))
1265 col_add_fstr(pinfo->cinfo, COL_INFO, "Watcher Notification");
1267 case FAMILY_LOCATION_DEFAULT:
1268 if (check_col(pinfo->cinfo, COL_INFO))
1269 col_add_fstr(pinfo->cinfo, COL_INFO, "Location Default");
1274 static void dissect_aim_snac_location_request_user_information(tvbuff_t *tvb,
1278 guint8 buddyname_length = 0;
1281 proto_tree_add_item(tree, hf_aim_snac_location_request_user_info_infotype,
1282 tvb, offset, 2, FALSE);
1285 /* Buddy Name length */
1286 buddyname_length = tvb_get_guint8(tvb, offset);
1287 proto_tree_add_item(tree, hf_aim_buddyname_len, tvb, offset, 1, FALSE);
1291 proto_tree_add_item(tree, hf_aim_buddyname, tvb, offset, buddyname_length, FALSE);
1292 offset += buddyname_length;
1294 /* Show the undissected payload */
1295 if (tvb_length_remaining(tvb, offset) > 0)
1296 proto_tree_add_item(tree, hf_aim_data, tvb, offset, -1, FALSE);
1299 static void dissect_aim_snac_location_user_information(tvbuff_t *tvb,
1300 packet_info *pinfo _U_,
1301 int offset, proto_tree *tree)
1303 guint8 buddyname_length = 0;
1304 guint16 tlv_count = 0;
1307 /* Buddy Name length */
1308 buddyname_length = tvb_get_guint8(tvb, offset);
1309 proto_tree_add_item(tree, hf_aim_buddyname_len, tvb, offset, 1, FALSE);
1313 proto_tree_add_item(tree, hf_aim_buddyname, tvb, offset, buddyname_length, FALSE);
1314 offset += buddyname_length;
1317 proto_tree_add_item(tree, hf_aim_userinfo_warninglevel, tvb, offset, 2, FALSE);
1321 tlv_count = tvb_get_ntohs(tvb, offset);
1322 proto_tree_add_item(tree, hf_aim_userinfo_tlvcount, tvb, offset, 2, FALSE);
1325 /* Dissect the TLV array containing general user status */
1326 while (i++ < tlv_count) {
1327 offset = dissect_aim_tlv(tvb, pinfo, offset, tree,
1328 aim_fnac_family_buddylist_oncoming_tlv);
1331 /* Dissect the TLV array containing the away message (or whatever info was
1332 specifically requested) */
1333 while (tvb_length_remaining(tvb, offset) > 0) {
1334 offset = dissect_aim_tlv(tvb, pinfo, offset, tree,
1335 aim_fnac_family_location_userinfo_tlv);
1339 static void dissect_aim_snac_adverts(tvbuff_t *tvb _U_,
1340 packet_info *pinfo _U_,
1341 int offset _U_, proto_tree *tree _U_,
1346 case FAMILY_ADVERTS_ERROR:
1347 if (check_col(pinfo->cinfo, COL_INFO))
1348 col_add_fstr(pinfo->cinfo, COL_INFO, "Advertisements - Error");
1350 case FAMILY_ADVERTS_REQUEST:
1351 if (check_col(pinfo->cinfo, COL_INFO))
1352 col_add_fstr(pinfo->cinfo, COL_INFO, "Advertisement Request");
1354 case FAMILY_ADVERTS_DATA:
1355 if (check_col(pinfo->cinfo, COL_INFO))
1356 col_add_fstr(pinfo->cinfo, COL_INFO, "Advertisement data (GIF)");
1360 /* Show the undissected payload */
1361 if (tvb_length_remaining(tvb, offset) > 0)
1362 proto_tree_add_item(tree, hf_aim_data, tvb, offset, -1, FALSE);
1365 static void dissect_aim_snac_userlookup(tvbuff_t *tvb _U_, packet_info *pinfo,
1366 int offset _U_, proto_tree *tree _U_,
1371 case FAMILY_USERLOOKUP_ERROR:
1372 if (check_col(pinfo->cinfo, COL_INFO))
1373 col_add_fstr(pinfo->cinfo, COL_INFO,
1374 "Search - Error (could be: not found)");
1376 case FAMILY_USERLOOKUP_SEARCHEMAIL:
1377 if (check_col(pinfo->cinfo, COL_INFO))
1378 col_add_fstr(pinfo->cinfo, COL_INFO,
1379 "Search for Screen Name by e-mail");
1381 case FAMILY_USERLOOKUP_SEARCHRESULT:
1382 if (check_col(pinfo->cinfo, COL_INFO))
1383 col_add_fstr(pinfo->cinfo, COL_INFO, "Screen Name Search Result");
1387 /* Show the undissected payload */
1388 if (tvb_length_remaining(tvb, offset) > 0)
1389 proto_tree_add_item(tree, hf_aim_data, tvb, offset, -1, FALSE);
1392 static void dissect_aim_snac_chat(tvbuff_t *tvb, packet_info *pinfo,
1393 int offset _U_, proto_tree *tree,
1396 guint8 buddyname_length = 0;
1397 char buddyname[MAX_BUDDYNAME_LENGTH + 1];
1402 case FAMILY_CHAT_OUTGOINGMSG:
1403 /* channel message from client */
1404 get_message( msg, tvb, 40 + buddyname_length, tvb_length(tvb)
1405 - 40 - buddyname_length );
1407 if (check_col(pinfo->cinfo, COL_INFO)) {
1408 col_add_fstr(pinfo->cinfo, COL_INFO, "Chat Message ");
1409 col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s", msg);
1413 case FAMILY_CHAT_INCOMINGMSG:
1414 /* channel message to client */
1415 buddyname_length = get_buddyname( buddyname, tvb, 30, 31 );
1416 get_message( msg, tvb, 36 + buddyname_length, tvb_length(tvb)
1417 - 36 - buddyname_length );
1419 if (check_col(pinfo->cinfo, COL_INFO)) {
1420 col_add_fstr(pinfo->cinfo, COL_INFO, "Chat Message ");
1421 col_append_fstr(pinfo->cinfo, COL_INFO, "from: %s", buddyname);
1422 col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s", msg);
1426 proto_tree_add_text(tree, tvb, 31, buddyname_length,
1427 "Screen Name: %s", buddyname);
1433 static void dissect_aim_snac_messaging(tvbuff_t *tvb, packet_info *pinfo,
1434 int offset, proto_tree *tree,
1437 guint8 buddyname_length = 0;
1438 char buddyname[MAX_BUDDYNAME_LENGTH + 1];
1443 case FAMILY_MESSAGING_OUTGOING:
1448 buddyname_length = get_buddyname( buddyname, tvb, offset, offset + 1 );
1450 /* djh - My test suggest that this is broken. Need to give this a
1451 closer look @@@@@@@@@ */
1452 get_message( msg, tvb, 36 + buddyname_length, tvb_length(tvb) - 36
1453 - buddyname_length );
1455 if (check_col(pinfo->cinfo, COL_INFO)) {
1456 col_add_fstr(pinfo->cinfo, COL_INFO, "Message ");
1457 col_append_fstr(pinfo->cinfo, COL_INFO, "to: %s", buddyname);
1458 col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s", msg);
1462 proto_tree_add_text(tree, tvb, 27, buddyname_length,
1463 "Screen Name: %s", buddyname);
1468 case FAMILY_MESSAGING_INCOMING:
1473 buddyname_length = get_buddyname( buddyname, tvb, offset, offset + 1 );
1475 /* djh - My test suggest that this is broken. Need to give this a
1476 closer look @@@@@@@@@ */
1477 get_message( msg, tvb, 36 + buddyname_length, tvb_length(tvb) - 36
1478 - buddyname_length);
1480 if (check_col(pinfo->cinfo, COL_INFO)) {
1481 col_add_fstr(pinfo->cinfo, COL_INFO, "Message");
1482 col_append_fstr(pinfo->cinfo, COL_INFO, " from: %s", buddyname);
1484 col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s", msg);
1488 proto_tree_add_text(tree, tvb, 27, buddyname_length,
1489 "Screen Name: %s", buddyname);
1495 static void dissect_aim_snac_ssi(tvbuff_t *tvb, packet_info *pinfo _U_,
1496 int offset, proto_tree *tree,
1497 guint16 subtype _U_)
1501 case FAMILY_SSI_LIST:
1502 dissect_aim_snac_ssi_list(tvb, pinfo, offset, tree, subtype);
1505 /* Show the undissected payload */
1506 if (tvb_length_remaining(tvb, offset) > 0)
1507 proto_tree_add_item(tree, hf_aim_data, tvb, offset, -1, FALSE);
1511 static void dissect_aim_snac_ssi_list(tvbuff_t *tvb, packet_info *pinfo _U_,
1512 int offset, proto_tree *tree,
1513 guint16 subtype _U_)
1515 guint16 buddyname_length = 0;
1516 guint16 tlv_len = 0;
1518 proto_tree *ssi_entry = NULL;
1521 proto_tree_add_item(tree, hf_aim_fnac_subtype_ssi_version, tvb, offset, 1,
1525 /* Number of items */
1526 proto_tree_add_item(tree, hf_aim_fnac_subtype_ssi_numitems, tvb, offset, 2,
1530 while (tvb_length_remaining(tvb, offset) > 4) {
1531 ti = proto_tree_add_text(tree, tvb, offset, 0, "SSI Entry");
1532 ssi_entry = proto_item_add_subtree(ti, ett_aim_ssi);
1534 /* Buddy Name Length */
1535 buddyname_length = tvb_get_ntohs(tvb, offset);
1536 proto_tree_add_item(ssi_entry, hf_aim_fnac_subtype_ssi_buddyname_len,
1537 tvb, offset, 2, FALSE);
1541 if (buddyname_length > 0) {
1542 proto_tree_add_item(ssi_entry, hf_aim_fnac_subtype_ssi_buddyname, tvb,
1543 offset, buddyname_length, FALSE);
1544 offset += buddyname_length;
1547 /* Buddy group ID */
1548 proto_tree_add_item(ssi_entry, hf_aim_fnac_subtype_ssi_gid, tvb, offset,
1553 proto_tree_add_item(ssi_entry, hf_aim_fnac_subtype_ssi_bid, tvb, offset,
1558 proto_tree_add_item(ssi_entry, hf_aim_fnac_subtype_ssi_type, tvb, offset,
1562 /* Size of the following TLV in bytes (as opposed to the number of
1563 TLV objects in the chain) */
1564 tlv_len = tvb_get_ntohs(tvb, offset);
1565 proto_tree_add_item(ssi_entry, hf_aim_fnac_subtype_ssi_tlvlen, tvb,
1569 /* For now, we just dump the TLV contents as-is, since there is not a
1570 TLV dissection utility that works based on total chain length */
1572 proto_tree_add_item(ssi_entry, hf_aim_data, tvb, offset, tlv_len,
1579 static void dissect_aim_snac_fnac_subtype(tvbuff_t *tvb, int offset,
1580 proto_tree *tree, guint16 family)
1582 /* Since the subtypes differ by family, we need to display the correct
1583 subtype based on the family. If we don't know the family, or we do
1584 not have the subtypes enumerated for a known family, we just dump the
1589 case FAMILY_GENERIC:
1590 proto_tree_add_item (tree, hf_aim_fnac_subtype_generic,
1591 tvb, offset, 2, FALSE);
1593 case FAMILY_LOCATION:
1594 proto_tree_add_item (tree, hf_aim_fnac_subtype_location,
1595 tvb, offset, 2, FALSE);
1597 case FAMILY_BUDDYLIST:
1598 proto_tree_add_item (tree, hf_aim_fnac_subtype_buddylist,
1599 tvb, offset, 2, FALSE);
1601 case FAMILY_MESSAGING:
1602 proto_tree_add_item (tree, hf_aim_fnac_subtype_messaging,
1603 tvb, offset, 2, FALSE);
1605 case FAMILY_ADVERTS:
1606 proto_tree_add_item (tree, hf_aim_fnac_subtype_adverts,
1607 tvb, offset, 2, FALSE);
1609 case FAMILY_INVITATION:
1610 proto_tree_add_item (tree, hf_aim_fnac_subtype_invitation,
1611 tvb, offset, 2, FALSE);
1614 proto_tree_add_item (tree, hf_aim_fnac_subtype_admin,
1615 tvb, offset, 2, FALSE);
1618 proto_tree_add_item (tree, hf_aim_fnac_subtype_popup,
1619 tvb, offset, 2, FALSE);
1622 proto_tree_add_item (tree, hf_aim_fnac_subtype_bos,
1623 tvb, offset, 2, FALSE);
1625 case FAMILY_USERLOOKUP:
1626 proto_tree_add_item (tree, hf_aim_fnac_subtype_userlookup,
1627 tvb, offset, 2, FALSE);
1630 proto_tree_add_item (tree, hf_aim_fnac_subtype_stats,
1631 tvb, offset, 2, FALSE);
1633 case FAMILY_TRANSLATE:
1634 proto_tree_add_item (tree, hf_aim_fnac_subtype_translate,
1635 tvb, offset, 2, FALSE);
1637 case FAMILY_CHAT_NAV:
1638 proto_tree_add_item (tree, hf_aim_fnac_subtype_chatnav,
1639 tvb, offset, 2, FALSE);
1642 proto_tree_add_item (tree, hf_aim_fnac_subtype_chat,
1643 tvb, offset, 2, FALSE);
1646 proto_tree_add_item (tree, hf_aim_fnac_subtype_ssi,
1647 tvb, offset, 2, FALSE);
1650 proto_tree_add_item (tree, hf_aim_fnac_subtype_icq,
1651 tvb, offset, 2, FALSE);
1654 proto_tree_add_item (tree, hf_aim_fnac_subtype_signon,
1655 tvb, offset, 2, FALSE);
1659 proto_tree_add_item(tree, hf_aim_fnac_subtype, tvb, offset, 2, FALSE);
1665 static void dissect_aim_flap_err(tvbuff_t *tvb, packet_info *pinfo,
1666 int offset, proto_tree *tree)
1668 if (check_col(pinfo->cinfo, COL_INFO)) {
1669 col_add_fstr(pinfo->cinfo, COL_INFO, "FLAP error");
1672 /* Show the undissected payload */
1673 if (tvb_length_remaining(tvb, offset) > 0)
1674 proto_tree_add_item(tree, hf_aim_data, tvb, offset, -1, FALSE);
1677 static void dissect_aim_close_conn(tvbuff_t *tvb, packet_info *pinfo,
1678 int offset, proto_tree *tree)
1680 if (check_col(pinfo->cinfo, COL_INFO)) {
1681 col_add_fstr(pinfo->cinfo, COL_INFO, "Close Connection");
1684 /* Show the undissected payload */
1685 if (tvb_length_remaining(tvb, offset) > 0)
1686 proto_tree_add_item(tree, hf_aim_data, tvb, offset, -1, FALSE);
1689 static void dissect_aim_unknown_channel(tvbuff_t *tvb, packet_info *pinfo,
1690 int offset, proto_tree *tree)
1692 if (check_col(pinfo->cinfo, COL_INFO)) {
1693 col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown Channel");
1696 /* Show the undissected payload */
1697 if (tvb_length_remaining(tvb, offset) > 0)
1698 proto_tree_add_item(tree, hf_aim_data, tvb, offset, -1, FALSE);
1701 /* Dissect a TLV value */
1702 static int dissect_aim_tlv(tvbuff_t *tvb, packet_info *pinfo _U_,
1703 int offset, proto_tree *tree, const aim_tlv *tlv)
1710 proto_tree *tlv_tree;
1715 /* Record the starting offset so we can reuse it at the second pass */
1716 orig_offset = offset;
1718 /* Get the value ID */
1719 valueid = tvb_get_ntohs(tvb, offset);
1722 /* Figure out which entry applies from the tlv list */
1724 while (tmp[i].valueid) {
1725 if (tmp[i].valueid == valueid) {
1726 /* We found a match */
1732 /* At this point, we are either pointing at the correct record, or
1733 we didn't find the record, and are pointing at the last item in the
1736 length = tvb_get_ntohs(tvb, offset);
1741 offset = orig_offset;
1743 /* Show the info in the top of the tree if it's one of the standard
1745 if (tmp[i].datatype == FT_STRING && length > 0) {
1747 buf = tvb_get_string(tvb, offset + 4, length);
1748 ti1 = proto_tree_add_text(tree, tvb, offset, length + 4,
1749 "%s: %s", tmp[i].desc, buf);
1752 else if (tmp[i].datatype == FT_UINT16) {
1753 value16 = tvb_get_ntohs(tvb, offset + 4);
1754 ti1 = proto_tree_add_text(tree, tvb, offset, length + 4,
1755 "%s: %d", tmp[i].desc, value16);
1757 else if (tmp[i].datatype == FT_UINT32) {
1758 value32 = tvb_get_ntohl(tvb, offset + 4);
1759 ti1 = proto_tree_add_text(tree, tvb, offset, length + 4,
1760 "%s: %d", tmp[i].desc, value32);
1763 ti1 = proto_tree_add_text(tree, tvb, offset, length + 4,
1767 tlv_tree = proto_item_add_subtree(ti1, ett_aim_tlv);
1769 proto_tree_add_text(tlv_tree, tvb, offset, 2,
1770 "Value ID: %s (0x%04x)", tmp[i].desc, valueid);
1773 proto_tree_add_text(tlv_tree, tvb, offset, 2,
1774 "Length: %d", length);
1777 ti1 = proto_tree_add_text(tlv_tree, tvb, offset, length,
1782 /* Return the new length */
1787 /* Register the protocol with Ethereal */
1789 proto_register_aim(void)
1792 /* Setup list of header fields */
1793 static hf_register_info hf[] = {
1794 { &hf_aim_cmd_start,
1795 { "Command Start", "aim.cmd_start", FT_UINT8, BASE_HEX, NULL, 0x0, "", HFILL }
1798 { "Channel ID", "aim.channel", FT_UINT8, BASE_HEX, NULL, 0x0, "", HFILL }
1801 { "Sequence Number", "aim.seqno", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
1804 { "Data Field Length", "aim.datalen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
1807 { "Data", "aim.data", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }
1809 { &hf_aim_signon_challenge_len,
1810 { "Signon challenge length", "aim.signon.challengelen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
1812 { &hf_aim_signon_challenge,
1813 { "Signon challenge", "aim.signon.challenge", FT_STRING, BASE_HEX, NULL, 0x0, "", HFILL }
1815 { &hf_aim_fnac_family,
1816 { "FNAC Family ID", "aim.fnac.family", FT_UINT16, BASE_HEX, VALS(aim_fnac_family_ids), 0x0, "", HFILL }
1818 { &hf_aim_fnac_subtype,
1819 { "FNAC Subtype ID", "aim.fnac.subtype", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }
1821 { &hf_aim_fnac_subtype_signon,
1822 { "FNAC Subtype ID", "aim.fnac.subtype", FT_UINT16, BASE_HEX, VALS(aim_fnac_family_signon), 0x0, "", HFILL }
1824 { &hf_aim_fnac_subtype_generic,
1825 { "FNAC Subtype ID", "aim.fnac.subtype", FT_UINT16, BASE_HEX, VALS(aim_fnac_family_generic), 0x0, "", HFILL }
1827 { &hf_aim_fnac_subtype_location,
1828 { "FNAC Subtype ID", "aim.fnac.subtype", FT_UINT16, BASE_HEX, VALS(aim_fnac_family_location), 0x0, "", HFILL }
1830 { &hf_aim_fnac_subtype_buddylist,
1831 { "FNAC Subtype ID", "aim.fnac.subtype", FT_UINT16, BASE_HEX, VALS(aim_fnac_family_buddylist), 0x0, "", HFILL }
1833 { &hf_aim_fnac_subtype_messaging,
1834 { "FNAC Subtype ID", "aim.fnac.subtype", FT_UINT16, BASE_HEX, VALS(aim_fnac_family_messaging), 0x0, "", HFILL }
1836 { &hf_aim_fnac_subtype_adverts,
1837 { "FNAC Subtype ID", "aim.fnac.subtype", FT_UINT16, BASE_HEX, VALS(aim_fnac_family_adverts), 0x0, "", HFILL }
1839 { &hf_aim_fnac_subtype_invitation,
1840 { "FNAC Subtype ID", "aim.fnac.subtype", FT_UINT16, BASE_HEX, VALS(aim_fnac_family_invitation), 0x0, "", HFILL }
1842 { &hf_aim_fnac_subtype_admin,
1843 { "FNAC Subtype ID", "aim.fnac.subtype", FT_UINT16, BASE_HEX, VALS(aim_fnac_family_admin), 0x0, "", HFILL }
1845 { &hf_aim_fnac_subtype_popup,
1846 { "FNAC Subtype ID", "aim.fnac.subtype", FT_UINT16, BASE_HEX, VALS(aim_fnac_family_popup), 0x0, "", HFILL }
1848 { &hf_aim_fnac_subtype_bos,
1849 { "FNAC Subtype ID", "aim.fnac.subtype", FT_UINT16, BASE_HEX, VALS(aim_fnac_family_bos), 0x0, "", HFILL }
1851 { &hf_aim_fnac_subtype_userlookup,
1852 { "FNAC Subtype ID", "aim.fnac.subtype", FT_UINT16, BASE_HEX, VALS(aim_fnac_family_userlookup), 0x0, "", HFILL }
1854 { &hf_aim_fnac_subtype_stats,
1855 { "FNAC Subtype ID", "aim.fnac.subtype", FT_UINT16, BASE_HEX, VALS(aim_fnac_family_stats), 0x0, "", HFILL }
1857 { &hf_aim_fnac_subtype_translate,
1858 { "FNAC Subtype ID", "aim.fnac.subtype", FT_UINT16, BASE_HEX, VALS(aim_fnac_family_translate), 0x0, "", HFILL }
1860 { &hf_aim_fnac_subtype_chatnav,
1861 { "FNAC Subtype ID", "aim.fnac.subtype", FT_UINT16, BASE_HEX, VALS(aim_fnac_family_chatnav), 0x0, "", HFILL }
1863 { &hf_aim_fnac_subtype_chat,
1864 { "FNAC Subtype ID", "aim.fnac.subtype", FT_UINT16, BASE_HEX, VALS(aim_fnac_family_chat), 0x0, "", HFILL }
1866 { &hf_aim_fnac_subtype_ssi,
1867 { "FNAC Subtype ID", "aim.fnac.subtype", FT_UINT16, BASE_HEX, VALS(aim_fnac_family_ssi), 0x0, "", HFILL }
1869 { &hf_aim_fnac_subtype_ssi_version,
1870 { "SSI Version", "aim.fnac.ssi.version", FT_UINT8, BASE_HEX, NULL, 0x0, "", HFILL }
1872 { &hf_aim_fnac_subtype_ssi_numitems,
1873 { "SSI Object count", "aim.fnac.ssi.numitems", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }
1875 { &hf_aim_fnac_subtype_ssi_buddyname_len,
1876 { "SSI Buddy Name length", "aim.fnac.ssi.buddyname_len", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }
1878 { &hf_aim_fnac_subtype_ssi_buddyname,
1879 { "Buddy Name", "aim.fnac.ssi.buddyname", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }
1881 { &hf_aim_fnac_subtype_ssi_gid,
1882 { "SSI Buddy Group ID", "aim.fnac.ssi.gid", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }
1884 { &hf_aim_fnac_subtype_ssi_bid,
1885 { "SSI Buddy ID", "aim.fnac.ssi.bid", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }
1887 { &hf_aim_fnac_subtype_ssi_type,
1888 { "SSI Buddy type", "aim.fnac.ssi.type", FT_UINT16, BASE_HEX, VALS(aim_fnac_family_ssi_types), 0x0, "", HFILL }
1890 { &hf_aim_fnac_subtype_ssi_tlvlen,
1891 { "SSI TLV Len", "aim.fnac.ssi.tlvlen", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }
1893 { &hf_aim_fnac_subtype_ssi_data,
1894 { "SSI Buddy Data", "aim.fnac.ssi.data", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }
1896 { &hf_aim_fnac_subtype_icq,
1897 { "FNAC Subtype ID", "aim.fnac.subtype", FT_UINT16, BASE_HEX, VALS(aim_fnac_family_icq), 0x0, "", HFILL }
1899 { &hf_aim_fnac_flags,
1900 { "FNAC Flags", "aim.fnac.flags", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }
1903 { "FNAC ID", "aim.fnac.id", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }
1906 { "Infotype", "aim.infotype", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }
1908 { &hf_aim_snac_location_request_user_info_infotype,
1909 { "Infotype", "aim.snac.location.request_user_info.infotype", FT_UINT16,
1910 BASE_HEX, VALS(aim_snac_location_request_user_info_infotypes), 0x0,
1913 { &hf_aim_buddyname_len,
1914 { "Buddyname len", "aim.buddynamelen", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }
1916 { &hf_aim_buddyname,
1917 { "Buddy Name", "aim.buddyname", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }
1919 { &hf_aim_userinfo_warninglevel,
1920 { "Warning Level", "aim.userinfo.warninglevel", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL },
1922 { &hf_aim_userinfo_tlvcount,
1923 { "TLV Count", "aim.userinfo.tlvcount", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL },
1927 /* Setup protocol subtree array */
1928 static gint *ett[] = {
1934 module_t *aim_module;
1936 /* Register the protocol name and description */
1937 proto_aim = proto_register_protocol("AOL Instant Messenger", "AIM", "aim");
1939 /* Required function calls to register the header fields and subtrees used */
1940 proto_register_field_array(proto_aim, hf, array_length(hf));
1941 proto_register_subtree_array(ett, array_length(ett));
1943 aim_module = prefs_register_protocol(proto_aim, NULL);
1944 prefs_register_bool_preference(aim_module, "desegment",
1945 "Desegment all AIM messages spanning multiple TCP segments",
1946 "Whether the AIM dissector should desegment all messages spanning multiple TCP segments",
1951 proto_reg_handoff_aim(void)
1953 dissector_handle_t aim_handle;
1955 aim_handle = new_create_dissector_handle(dissect_aim, proto_aim);
1956 dissector_add("tcp.port", TCP_PORT_AIM, aim_handle);