1 /* packet-aim.c
2  * Routines for AIM Instant Messenger (OSCAR) dissection
3  * Copyright 2000, Ralf Hoelzer <ralf@well.com>
4  * Copyright 2004, Jelmer Vernooij <jelmer@samba.org>
5  * Copyright 2004, Devin Heitmueller <dheitmueller@netilla.com>
6  *
7  * Wireshark - Network traffic analyzer
8  * By Gerald Combs <gerald@wireshark.org>
9  * Copyright 1998 Gerald Combs
10  *
11  * SPDX-License-Identifier: GPL-2.0-or-later
12  */
13 
14 #include "config.h"
15 
16 
17 #include <epan/packet.h>
18 #include <epan/strutil.h>
19 #include <epan/to_str.h>
20 
21 #include "packet-tcp.h"
22 #include "packet-tls.h"
23 #include <epan/prefs.h>
24 #include <epan/expert.h>
25 
26 void proto_register_aim(void);
27 void proto_reg_handoff_aim(void);
28 
29 #define TCP_PORTS_AIM_DEFAULT "5190"
30 
31 #define STRIP_TAGS 1
32 
33 /* SNAC families */
34 #define FAMILY_GENERIC    0x0001
35 #define FAMILY_LOCATION   0x0002
36 #define FAMILY_BUDDYLIST  0x0003
37 #define FAMILY_MESSAGING  0x0004
38 #define FAMILY_ADVERTS    0x0005
39 #define FAMILY_INVITATION 0x0006
40 #define FAMILY_ADMIN      0x0007
41 #define FAMILY_POPUP      0x0008
42 #define FAMILY_BOS        0x0009
43 #define FAMILY_USERLOOKUP 0x000A
44 #define FAMILY_STATS      0x000B
45 #define FAMILY_TRANSLATE  0x000C
46 #define FAMILY_CHAT_NAV   0x000D
47 #define FAMILY_CHAT       0x000E
48 #define FAMILY_DIRECTORY  0x000F
49 #define FAMILY_SST        0x0010
50 #define FAMILY_SSI        0x0013
51 #define FAMILY_ICQ        0x0015
52 #define FAMILY_SIGNON     0x0017
53 #define FAMILY_EMAIL      0x0018
54 #define FAMILY_OFT        0xfffe
55 
56 /* channels */
57 #define CHANNEL_NEW_CONN    0x01
58 #define CHANNEL_SNAC_DATA   0x02
59 #define CHANNEL_FLAP_ERR    0x03
60 #define CHANNEL_CLOSE_CONN  0x04
61 #define CHANNEL_KEEP_ALIVE  0x05
62 
63 #define FAMILY_ALL_ERROR_INVALID_HEADER                0x0001
64 #define FAMILY_ALL_ERROR_SERVER_RATE_LIMIT_EXCEEDED    0x0002
65 #define FAMILY_ALL_ERROR_CLIENT_RATE_LIMIT_EXCEEDED    0x0003
66 #define FAMILY_ALL_ERROR_RECIPIENT_NOT_LOGGED_IN       0x0004
67 #define FAMILY_ALL_ERROR_REQUESTED_SERVICE_UNAVAILABLE 0x0005
68 #define FAMILY_ALL_ERROR_REQUESTED_SERVICE_NOT_DEFINED 0x0006
69 #define FAMILY_ALL_ERROR_OBSOLETE_SNAC                 0x0007
70 #define FAMILY_ALL_ERROR_NOT_SUPPORTED_BY_SERVER       0x0008
71 #define FAMILY_ALL_ERROR_NOT_SUPPORTED_BY_CLIENT       0x0009
72 #define FAMILY_ALL_ERROR_REFUSED_BY_CLIENT             0x000a
73 #define FAMILY_ALL_ERROR_REPLY_TOO_BIG                 0x000b
74 #define FAMILY_ALL_ERROR_RESPONSES_LOST                0x000c
75 #define FAMILY_ALL_ERROR_REQUEST_DENIED                0x000d
76 #define FAMILY_ALL_ERROR_INCORRECT_SNAC_FORMAT         0x000e
77 #define FAMILY_ALL_ERROR_INSUFFICIENT_RIGHTS           0x000f
78 #define FAMILY_ALL_ERROR_RECIPIENT_BLOCKED             0x0010
79 #define FAMILY_ALL_ERROR_SENDER_TOO_EVIL               0x0011
80 #define FAMILY_ALL_ERROR_RECEIVER_TOO_EVIL             0x0012
81 #define FAMILY_ALL_ERROR_USER_TEMP_UNAVAILABLE         0x0013
82 #define FAMILY_ALL_ERROR_NO_MATCH                      0x0014
83 #define FAMILY_ALL_ERROR_LIST_OVERFLOW                 0x0015
84 #define FAMILY_ALL_ERROR_REQUEST_AMBIGUOUS             0x0016
85 #define FAMILY_ALL_ERROR_SERVER_QUEUE_FULL             0x0017
86 #define FAMILY_ALL_ERROR_NOT_WHILE_ON_AOL              0x0018
87 
88 static const value_string aim_flap_channels[] = {
89 	{ CHANNEL_NEW_CONN,   "New Connection" },
90 	{ CHANNEL_SNAC_DATA,  "SNAC Data" },
91 	{ CHANNEL_FLAP_ERR,   "FLAP-Level Error" },
92 	{ CHANNEL_CLOSE_CONN, "Close Connection" },
93 	{ CHANNEL_KEEP_ALIVE, "Keep Alive" },
94 	{ 0, NULL }
95 };
96 
97 static const value_string aim_snac_errors[] = {
98 	{ FAMILY_ALL_ERROR_INVALID_HEADER,		  "Invalid SNAC Header" },
99 	{ FAMILY_ALL_ERROR_SERVER_RATE_LIMIT_EXCEEDED,	  "Server rate limit exceeded" },
100 	{ FAMILY_ALL_ERROR_CLIENT_RATE_LIMIT_EXCEEDED,	  "Client rate limit exceeded" },
101 	{ FAMILY_ALL_ERROR_RECIPIENT_NOT_LOGGED_IN,	  "Recipient not logged in" },
102 	{ FAMILY_ALL_ERROR_REQUESTED_SERVICE_UNAVAILABLE, "Requested service unavailable" },
103 	{ FAMILY_ALL_ERROR_REQUESTED_SERVICE_NOT_DEFINED, "Requested service not defined" },
104 	{ FAMILY_ALL_ERROR_OBSOLETE_SNAC,		  "Obsolete SNAC issued" },
105 	{ FAMILY_ALL_ERROR_NOT_SUPPORTED_BY_SERVER,	  "Not supported by server" },
106 	{ FAMILY_ALL_ERROR_NOT_SUPPORTED_BY_CLIENT,	  "Not supported by client" },
107 	{ FAMILY_ALL_ERROR_REFUSED_BY_CLIENT,		  "Refused by client" },
108 	{ FAMILY_ALL_ERROR_REPLY_TOO_BIG,		  "Reply too big" },
109 	{ FAMILY_ALL_ERROR_RESPONSES_LOST,		  "Responses lost" },
110 	{ FAMILY_ALL_ERROR_REQUEST_DENIED,		  "Request denied" },
111 	{ FAMILY_ALL_ERROR_INCORRECT_SNAC_FORMAT,	  "Incorrect SNAC format" },
112 	{ FAMILY_ALL_ERROR_INSUFFICIENT_RIGHTS,		  "Insufficient rights" },
113 	{ FAMILY_ALL_ERROR_RECIPIENT_BLOCKED,		  "Recipient blocked" },
114 	{ FAMILY_ALL_ERROR_SENDER_TOO_EVIL,		  "Sender too evil" },
115 	{ FAMILY_ALL_ERROR_RECEIVER_TOO_EVIL,		  "Receiver too evil" },
116 	{ FAMILY_ALL_ERROR_USER_TEMP_UNAVAILABLE,	  "User temporarily unavailable" },
117 	{ FAMILY_ALL_ERROR_NO_MATCH,			  "No match" },
118 	{ FAMILY_ALL_ERROR_LIST_OVERFLOW,		  "List overflow" },
119 	{ FAMILY_ALL_ERROR_REQUEST_AMBIGUOUS,		  "Request ambiguous" },
120 	{ FAMILY_ALL_ERROR_SERVER_QUEUE_FULL,		  "Server queue full" },
121 	{ FAMILY_ALL_ERROR_NOT_WHILE_ON_AOL,		  "Not while on AOL" },
122 	{ 0, NULL }
123 };
124 
125 static int dissect_aim_tlv_value_userstatus(proto_item *ti, guint16 valueid _U_, tvbuff_t *tvb, packet_info *pinfo _U_);
126 static int dissect_aim_tlv_value_dcinfo(proto_item *ti, guint16 valueid _U_, tvbuff_t *tvb, packet_info *pinfo _U_);
127 static int dissect_aim_tlv_value_client_short_capabilities(proto_item *ti, guint16, tvbuff_t *, packet_info *);
128 
129 
130 #define DC_DISABLED		0x0000
131 #define DC_HTTPS		0x0001
132 #define DC_SOCKS		0x0002
133 #define DC_NORMAL		0x0003
134 #define DC_IMPOSSIBLE	0x0004
135 
136 static const value_string dc_types[] = {
137 	{ DC_DISABLED,	 "DC disabled" },
138 	{ DC_HTTPS,	 "DC thru firewall or HTTPS proxy" },
139 	{ DC_SOCKS,	 "DC thru SOCKS proxy" },
140 	{ DC_NORMAL,	 "Regular connection" },
141 	{ DC_IMPOSSIBLE, "DC not possible " },
142 	{ 0, NULL },
143 };
144 
145 #define PROTO_VERSION_ICQ98	0x0004
146 #define PROTO_VERSION_ICQ99	0x0006
147 #define PROTO_VERSION_ICQ2K	0x0007
148 #define PROTO_VERSION_ICQ2K1	0x0008
149 #define PROTO_VERSION_ICQLITE	0x0009
150 #define PROTO_VERSION_ICQ2K3B	0x000A
151 
152 static const value_string protocol_versions[] = {
153 	{ PROTO_VERSION_ICQ98,	 "ICQ '98" },
154 	{ PROTO_VERSION_ICQ99,	 "ICQ '99" },
155 	{ PROTO_VERSION_ICQ2K,	 "ICQ 2000" },
156 	{ PROTO_VERSION_ICQ2K1,	 "ICQ 2001" },
157 	{ PROTO_VERSION_ICQLITE, "ICQ Lite" },
158 	{ PROTO_VERSION_ICQ2K3B, "ICQ 2003B" },
159 	{ 0, NULL },
160 };
161 
162 #define CONFIRM_STATUS_EMAIL_SENT 		 0x00
163 #define CONFIRM_STATUS_ALREADY_CONFIRMED 0x1E
164 #define CONFIRM_STATUS_SERVER_ERROR	     0x23
165 
166 static const value_string confirm_statusses[] = {
167 	{ CONFIRM_STATUS_EMAIL_SENT, "A confirmation email has been sent" },
168 	{ CONFIRM_STATUS_ALREADY_CONFIRMED, "Account was already confirmed" },
169 	{ CONFIRM_STATUS_SERVER_ERROR, "Server couldn't start confirmation process" },
170 	{ 0, NULL }
171 };
172 
173 #define CLASS_UNCONFIRMED            0x00000001
174 #define CLASS_ADMINISTRATOR          0x00000002
175 #define CLASS_AOL                    0x00000004
176 #define CLASS_COMMERCIAL             0x00000008
177 #define CLASS_AIM                    0x00000010
178 #define CLASS_AWAY                   0x00000020
179 #define CLASS_ICQ                    0x00000040
180 #define CLASS_WIRELESS               0x00000080
181 #define CLASS_UNKNOWN100             0x00000100
182 #define CLASS_IMF                    0x00000200
183 #define CLASS_BOT                    0x00000400
184 #define CLASS_UNKNOWN800             0x00000800
185 #define CLASS_ONE_WAY_WIRELESS       0x00001000
186 #define CLASS_UNKNOWN2000            0x00002000
187 #define CLASS_UNKNOWN4000            0x00004000
188 #define CLASS_UNKNOWN8000            0x00008000
189 #define CLASS_UNKNOWN10000           0x00010000
190 #define CLASS_UNKNOWN20000           0x00020000
191 #define CLASS_NO_KNOCK_KNOCK         0x00040000
192 #define CLASS_FORWARD_MOBILE         0x00080000
193 
194 #define FNAC_FLAG_NEXT_IS_RELATED 	 0x0001
195 #define FNAC_FLAG_CONTAINS_VERSION	 0x8000
196 
197 
198 #define SSI_OP_RESULT_SUCCESS             0
199 #define SSI_OP_RESULT_DB_ERROR            1
200 #define SSI_OP_RESULT_NOT_FOUND           2
201 #define SSI_OP_RESULT_ALREADY_EXISTS      3
202 #define SSI_OP_RESULT_UNAVAILABLE         5
203 #define SSI_OP_RESULT_BAD_REQUEST        10
204 #define SSI_OP_RESULT_DB_TIME_OUT        11
205 #define SSI_OP_RESULT_OVER_ROW_LIMIT     12
206 #define SSI_OP_RESULT_NOT_EXECUTED       13
207 #define SSI_OP_RESULT_AUTH_REQUIRED      14
208 #define SSI_OP_RESULT_BAD_LOGINID        16
209 #define SSI_OP_RESULT_OVER_BUDDY_LIMIT   17
210 #define SSI_OP_RESULT_INSERT_SMART_GROUP 20
211 #define SSI_OP_RESULT_TIMEOUT            26
212 
213 static const value_string aim_ssi_result_codes[] = {
214 	{ SSI_OP_RESULT_SUCCESS,	    "Success" },
215 	{ SSI_OP_RESULT_DB_ERROR,	    "Some kind of database error" },
216 	{ SSI_OP_RESULT_NOT_FOUND,	    "Item was not found for an update or delete" },
217 	{ SSI_OP_RESULT_ALREADY_EXISTS,	    "Item already exists for an insert" },
218 	{ SSI_OP_RESULT_UNAVAILABLE,	    "Server or database is not available" },
219 	{ SSI_OP_RESULT_BAD_REQUEST,	    "Request was not formed well" },
220 	{ SSI_OP_RESULT_DB_TIME_OUT,	    "Database timed out" },
221 	{ SSI_OP_RESULT_OVER_ROW_LIMIT,	    "Too many items of this class for an insert" },
222 	{ SSI_OP_RESULT_NOT_EXECUTED,	    "Not executed due to other error in same request" },
223 	{ SSI_OP_RESULT_AUTH_REQUIRED,	    "Buddy List authorization required" },
224 	{ SSI_OP_RESULT_BAD_LOGINID,	    "Bad loginId" },
225 	{ SSI_OP_RESULT_OVER_BUDDY_LIMIT,   "Too many buddies" },
226 	{ SSI_OP_RESULT_INSERT_SMART_GROUP, "Attempt to added a Buddy to a smart group" },
227 	{ SSI_OP_RESULT_TIMEOUT,	    "General timeout" },
228 	{ 0, NULL }
229 };
230 
231 #define FAMILY_SSI_TYPE_BUDDY         0x0000
232 #define FAMILY_SSI_TYPE_GROUP         0x0001
233 #define FAMILY_SSI_TYPE_PERMIT        0x0002
234 #define FAMILY_SSI_TYPE_DENY          0x0003
235 #define FAMILY_SSI_TYPE_PDINFO        0x0004
236 #define FAMILY_SSI_TYPE_PRESENCEPREFS 0x0005
237 #define FAMILY_SSI_TYPE_ICONINFO      0x0014
238 
239 static const value_string aim_fnac_family_ssi_types[] = {
240 	{ FAMILY_SSI_TYPE_BUDDY,	 "Buddy" },
241 	{ FAMILY_SSI_TYPE_GROUP,	 "Group" },
242 	{ FAMILY_SSI_TYPE_PERMIT,	 "Permit" },
243 	{ FAMILY_SSI_TYPE_DENY,		 "Deny" },
244 	{ FAMILY_SSI_TYPE_PDINFO,	 "PDINFO" },
245 	{ FAMILY_SSI_TYPE_PRESENCEPREFS, "Presence Preferences" },
246 	{ FAMILY_SSI_TYPE_ICONINFO,	 "Icon Info" },
247 	{ 0, NULL }
248 };
249 
250 typedef struct _aim_tlv {
251 	guint16 valueid;
252 	const char *desc;
253 	int (*dissector) (proto_item *ti, guint16 value_id, tvbuff_t *tvb, packet_info *);
254 } aim_tlv;
255 
256 typedef struct _aim_subtype {
257 	guint16 id;
258 	const char *name;
259 	int (*dissector) (tvbuff_t *, packet_info *, proto_tree *);
260 } aim_subtype;
261 
262 typedef struct _aim_family {
263 	int ett;
264 	int proto_id;
265 	protocol_t *proto;
266 	guint16 family;
267 	const char *name;
268 	const aim_subtype *subtypes;
269 } aim_family;
270 
271 static int dissect_aim_tlv(tvbuff_t *tvb, packet_info *pinfo _U_, int offset, proto_tree *tree, const aim_tlv *);
272 
273 static int dissect_aim_tlv_value_uint16(proto_item *ti, guint16, tvbuff_t *, packet_info *);
274 
275 
276 static int proto_aim = -1;
277 static int proto_aim_admin = -1;
278 static int proto_aim_adverts = -1;
279 static int proto_aim_bos = -1;
280 static int proto_aim_buddylist = -1;
281 static int proto_aim_chat = -1;
282 static int proto_aim_chatnav = -1;
283 static int proto_aim_directory = -1;
284 static int proto_aim_email = -1;
285 static int proto_aim_generic = -1;
286 static int proto_aim_icq = -1;
287 static int proto_aim_invitation = -1;
288 static int proto_aim_location = -1;
289 static int proto_aim_messaging = -1;
290 static int proto_aim_popup = -1;
291 static int proto_aim_signon = -1;
292 static int proto_aim_ssi = -1;
293 static int proto_aim_sst = -1;
294 static int proto_aim_stats = -1;
295 static int proto_aim_translate = -1;
296 static int proto_aim_userlookup = -1;
297 
298 
299 static int hf_aim_cmd_start = -1;
300 static int hf_aim_channel = -1;
301 static int hf_aim_seqno = -1;
302 static int hf_aim_data = -1;
303 static int hf_aim_data_len = -1;
304 static int hf_aim_tlv_length = -1;
305 static int hf_aim_tlv_value_id = -1;
306 static int hf_aim_fnac_family = -1;
307 static int hf_aim_fnac_subtype = -1;
308 static int hf_aim_fnac_flags = -1;
309 static int hf_aim_fnac_flag_next_is_related = -1;
310 static int hf_aim_fnac_flag_contains_version = -1;
311 static int hf_aim_fnac_id = -1;
312 static int hf_aim_buddyname_len = -1;
313 static int hf_aim_buddyname = -1;
314 static int hf_aim_userinfo_warninglevel = -1;
315 static int hf_aim_snac_error = -1;
316 static int hf_aim_ssi_result_code = -1;
317 static int hf_aim_tlvcount = -1;
318 static int hf_aim_version = -1;
319 static int hf_aim_userclass_unconfirmed = -1;
320 static int hf_aim_userclass_administrator = -1;
321 static int hf_aim_userclass_aol = -1;
322 static int hf_aim_userclass_commercial = -1;
323 static int hf_aim_userclass_aim = -1;
324 static int hf_aim_userclass_away = -1;
325 static int hf_aim_userclass_icq = -1;
326 static int hf_aim_userclass_wireless = -1;
327 static int hf_aim_userclass_unknown100 = -1;
328 static int hf_aim_userclass_imf = -1;
329 static int hf_aim_userclass_bot = -1;
330 static int hf_aim_userclass_unknown800 = -1;
331 static int hf_aim_userclass_one_way_wireless = -1;
332 static int hf_aim_userclass_unknown2000 = -1;
333 static int hf_aim_userclass_unknown4000 = -1;
334 static int hf_aim_userclass_unknown8000 = -1;
335 static int hf_aim_userclass_unknown10000 = -1;
336 static int hf_aim_userclass_unknown20000 = -1;
337 static int hf_aim_userclass_no_knock_knock = -1;
338 static int hf_aim_userclass_forward_mobile = -1;
339 static int hf_aim_nickinfo_caps = -1;
340 static int hf_aim_nickinfo_short_caps = -1;
341 static int hf_aim_messageblock_featuresdes = -1;
342 static int hf_aim_messageblock_featureslen = -1;
343 static int hf_aim_messageblock_features = -1;
344 static int hf_aim_messageblock_info = -1;
345 static int hf_aim_messageblock_len = -1;
346 static int hf_aim_messageblock_charset = -1;
347 static int hf_aim_messageblock_charsubset = -1;
348 static int hf_aim_messageblock_message = -1;
349 
350 static int hf_aim_dcinfo_ip = -1;
351 static int hf_aim_dcinfo_tcpport = -1;
352 static int hf_aim_dcinfo_type = -1;
353 static int hf_aim_dcinfo_proto_version = -1;
354 static int hf_aim_dcinfo_auth_cookie = -1;
355 static int hf_aim_dcinfo_webport = -1;
356 static int hf_aim_dcinfo_client_future = -1;
357 static int hf_aim_dcinfo_last_info_update = -1;
358 static int hf_aim_dcinfo_last_ext_info_update = -1;
359 static int hf_aim_dcinfo_last_ext_status_update = -1;
360 static int hf_aim_dcinfo_unknown = -1;
361 static int hf_aim_string08 = -1;
362 
363 static int hf_admin_acctinfo_code = -1;
364 static int hf_admin_acctinfo_unknown = -1;
365 static int hf_admin_acctinfo_permissions = -1;
366 static int hf_admin_confirm_status = -1;
367 
368 /* static int hf_aim_bos_data = -1; */
369 static int hf_aim_bos_class = -1;
370 
371 static int hf_aim_buddylist_userinfo_warninglevel = -1;
372 
373 static int hf_aim_chat_screen_name = -1;
374 
375 static int hf_generic_motd_motdtype = -1;
376 static int hf_generic_family = -1;
377 static int hf_generic_version = -1;
378 static int hf_generic_dll_version = -1;
379 static int hf_generic_servicereq_service = -1;
380 static int hf_generic_rateinfo_numclasses = -1;
381 static int hf_generic_rateinfo_windowsize = -1;
382 static int hf_generic_rateinfo_clearlevel = -1;
383 static int hf_generic_rateinfo_alertlevel = -1;
384 static int hf_generic_rateinfo_limitlevel = -1;
385 static int hf_generic_rateinfo_disconnectlevel = -1;
386 static int hf_generic_rateinfo_currentlevel = -1;
387 static int hf_generic_rateinfo_maxlevel = -1;
388 static int hf_generic_rateinfo_lasttime = -1;
389 static int hf_generic_rateinfo_curstate = -1;
390 static int hf_generic_rateinfo_classid = -1;
391 static int hf_generic_rateinfo_numpairs = -1;
392 static int hf_generic_rateinfoack_group = -1;
393 static int hf_generic_ratechange_msg    = -1;
394 static int hf_generic_migration_numfams  = -1;
395 static int hf_generic_priv_flags = -1;
396 static int hf_generic_allow_idle_see = -1;
397 static int hf_generic_allow_member_see = -1;
398 static int hf_generic_selfinfo_warninglevel = -1;
399 static int hf_generic_evil_new_warn_level = -1;
400 static int hf_generic_idle_time = -1;
401 static int hf_generic_client_ver_req_offset = -1;
402 static int hf_generic_client_ver_req_length = -1;
403 static int hf_generic_client_ver_req_hash = -1;
404 static int hf_generic_ext_status_type = -1;
405 static int hf_generic_ext_status_length = -1;
406 static int hf_generic_ext_status_flags = -1;
407 static int hf_generic_ext_status_data = -1;
408 
409 static int hf_icq_tlv_data_chunk_size = -1;
410 static int hf_icq_tlv_request_owner_uid = -1;
411 static int hf_icq_tlv_request_type = -1;
412 static int hf_icq_meta_subtype = -1;
413 static int hf_icq_tlv_request_seq_num = -1;
414 static int hf_icq_dropped_msg_flag = -1;
415 
416 static int hf_aim_snac_location_request_user_info_infotype = -1;
417 static int hf_aim_location_userinfo_warninglevel = -1;
418 static int hf_aim_location_buddyname_len = -1;
419 static int hf_aim_location_buddyname = -1;
420 
421 static int hf_aim_icbm_channel = -1;
422 static int hf_aim_icbm_cookie = -1;
423 static int hf_aim_icbm_msg_flags = -1;
424 static int hf_aim_icbm_max_sender_warnlevel = -1;
425 static int hf_aim_icbm_max_receiver_warnlevel = -1;
426 static int hf_aim_icbm_max_snac_size = -1;
427 static int hf_aim_icbm_min_msg_interval = -1;
428 static int hf_aim_icbm_notification_cookie = -1;
429 static int hf_aim_icbm_notification_channel = -1;
430 static int hf_aim_icbm_notification_type = -1;
431 static int hf_aim_icbm_rendezvous_nak = -1;
432 static int hf_aim_icbm_rendezvous_nak_length = -1;
433 static int hf_aim_message_channel_id = -1;
434 static int hf_aim_icbm_evil = -1;
435 static int hf_aim_evil_warn_level = -1;
436 static int hf_aim_evil_new_warn_level = -1;
437 static int hf_aim_rendezvous_msg_type = -1;
438 static int hf_aim_icbm_client_err_reason = -1;
439 static int hf_aim_icbm_client_err_protocol_version = -1;
440 static int hf_aim_icbm_client_err_client_caps_flags = -1;
441 static int hf_aim_rendezvous_extended_data_message_type = -1;
442 static int hf_aim_rendezvous_extended_data_message_flags = -1;
443 static int hf_aim_rendezvous_extended_data_message_flags_normal = -1;
444 static int hf_aim_rendezvous_extended_data_message_flags_auto = -1;
445 static int hf_aim_rendezvous_extended_data_message_flags_multi = -1;
446 static int hf_aim_rendezvous_extended_data_message_status_code = -1;
447 static int hf_aim_rendezvous_extended_data_message_priority_code = -1;
448 static int hf_aim_rendezvous_extended_data_message_text_length = -1;
449 static int hf_aim_rendezvous_extended_data_message_text = -1;
450 
451 static int hf_aim_messaging_plugin = -1;
452 static int hf_aim_icbm_client_err_length = -1;
453 static int hf_aim_messaging_unknown_uint8 = -1;
454 static int hf_aim_messaging_unknown_uint16 = -1;
455 static int hf_aim_icbm_client_err_downcounter = -1;
456 static int hf_aim_messaging_unknown_data = -1;
457 static int hf_aim_messaging_plugin_specific_data = -1;
458 
459 static int hf_aim_infotype = -1;
460 static int hf_aim_signon_challenge_len = -1;
461 static int hf_aim_signon_challenge = -1;
462 
463 static int hf_aim_fnac_subtype_ssi_version = -1;
464 static int hf_aim_fnac_subtype_ssi_numitems = -1;
465 static int hf_aim_fnac_subtype_ssi_last_change_time = -1;
466 static int hf_aim_fnac_subtype_ssi_buddyname_len = -1;
467 static int hf_aim_fnac_subtype_ssi_buddyname_len8 = -1;
468 static int hf_aim_fnac_subtype_ssi_buddyname = -1;
469 static int hf_aim_fnac_subtype_ssi_gid = -1;
470 static int hf_aim_fnac_subtype_ssi_bid = -1;
471 static int hf_aim_fnac_subtype_ssi_type = -1;
472 static int hf_aim_fnac_subtype_ssi_tlvlen = -1;
473 /* static int hf_aim_fnac_subtype_ssi_data = -1; */
474 static int hf_aim_fnac_subtype_ssi_reason_str_len = -1;
475 static int hf_aim_fnac_subtype_ssi_reason_str = -1;
476 static int hf_aim_fnac_subtype_ssi_grant_auth_unkn = -1;
477 static int hf_aim_fnac_subtype_ssi_allow_auth = -1;
478 
479 static int hf_aim_sst_unknown = -1;
480 static int hf_aim_sst_md5_hash = -1;
481 static int hf_aim_sst_md5_hash_size = -1;
482 static int hf_aim_sst_ref_num = -1;
483 static int hf_aim_sst_icon_size = -1;
484 static int hf_aim_sst_icon = -1;
485 
486 static int hf_aim_userlookup_email = -1;
487 
488 /* Initialize the subtree pointers */
489 static gint ett_aim                     = -1;
490 static gint ett_aim_dcinfo              = -1;
491 static gint ett_aim_buddyname           = -1;
492 static gint ett_aim_fnac                = -1;
493 static gint ett_aim_fnac_flags          = -1;
494 static gint ett_aim_tlv                 = -1;
495 static gint ett_aim_tlv_value           = -1;
496 static gint ett_aim_userclass           = -1;
497 static gint ett_aim_messageblock        = -1;
498 static gint ett_aim_nickinfo_caps       = -1;
499 static gint ett_aim_nickinfo_short_caps = -1;
500 static gint ett_aim_string08_array      = -1;
501 
502 static gint ett_aim_admin               = -1;
503 static gint ett_aim_adverts             = -1;
504 static gint ett_aim_bos                 = -1;
505 static gint ett_aim_buddylist           = -1;
506 static gint ett_aim_chat                = -1;
507 static gint ett_aim_chatnav             = -1;
508 static gint ett_aim_directory           = -1;
509 static gint ett_aim_email               = -1;
510 
511 static gint ett_generic_clientready     = -1;
512 static gint ett_generic_migratefamilies = -1;
513 static gint ett_generic_clientready_item= -1;
514 static gint ett_generic_serverready     = -1;
515 static gint ett_generic                 = -1;
516 static gint ett_generic_priv_flags      = -1;
517 static gint ett_generic_rateinfo_class  = -1;
518 static gint ett_generic_rateinfo_classes= -1;
519 static gint ett_generic_rateinfo_groups = -1;
520 static gint ett_generic_rateinfo_group  = -1;
521 
522 static gint ett_aim_invitation          = -1;
523 static gint ett_aim_icq                 = -1;
524 static gint ett_aim_icq_tlv             = -1;
525 static gint ett_aim_location            = -1;
526 static gint ett_aim_messaging           = -1;
527 static gint ett_aim_rendezvous_data     = -1;
528 static gint ett_aim_extended_data       = -1;
529 static gint ett_aim_extended_data_message_flags = -1;
530 static gint ett_aim_popup               = -1;
531 static gint ett_aim_signon              = -1;
532 static gint ett_aim_ssi                 = -1;
533 static gint ett_ssi                     = -1;
534 static gint ett_aim_sst                 = -1;
535 static gint ett_aim_stats               = -1;
536 static gint ett_aim_translate           = -1;
537 static gint ett_aim_userlookup          = -1;
538 
539 static expert_field ei_aim_messageblock_len = EI_INIT;
540 
541 /* desegmentation of AIM over TCP */
542 static gboolean aim_desegment = TRUE;
543 
544 static dissector_handle_t aim_handle;
545 
546 static GList *families = NULL;
547 
548 static const aim_subtype
549 *aim_get_subtype( guint16 famnum, guint16 subtype )
550 {
551 	GList *gl = families;
552 	while(gl) {
553 		aim_family *fam = (aim_family *)gl->data;
554 		if(fam->family == famnum) {
555 			int i;
556 			for(i = 0; fam->subtypes[i].name; i++) {
557 				if(fam->subtypes[i].id == subtype) return &(fam->subtypes[i]);
558 			}
559 		}
560 		gl = gl->next;
561 	}
562 
563 	return NULL;
564 
565 }
566 
567 static const aim_family
568 *aim_get_family( guint16 famnum )
569 {
570 	GList *gl = families;
571 	while(gl) {
572 		aim_family *fam = (aim_family *)gl->data;
573 		if(fam->family == famnum) return fam;
574 		gl = gl->next;
575 	}
576 
577 	return NULL;
578 }
579 
580 static int
581 aim_get_buddyname(wmem_allocator_t *pool, guint8 **name, tvbuff_t *tvb, int offset)
582 {
583 	guint8 buddyname_length;
584 
585 	buddyname_length = tvb_get_guint8(tvb, offset);
586 
587 	*name = tvb_get_string_enc(pool, tvb, offset + 1, buddyname_length, ENC_UTF_8|ENC_NA);
588 
589 	return buddyname_length;
590 }
591 
592 
593 static void
594 aim_get_message( guchar *msg, tvbuff_t *tvb, int msg_offset, int msg_length)
595 {
596 	int i,j,c;
597 	int bracket = FALSE;
598 	int max, tagchars = 0;
599 	int new_offset = msg_offset;
600 	int new_length = msg_length;
601 
602 
603 	/* make sure nothing bigger than 1000 bytes is printed */
604 	if( msg_length > 999 ) return;
605 
606 	memset( msg, '\0', 1000);
607 	i = 0;
608 	c = 0;
609 
610 	/* loop until HTML tag is reached - quick&dirty way to find start of message
611 	 * (it is nearly impossible to find the correct start offset for all client versions) */
612 	while( (tagchars < 6) && (new_length > 5) )
613 	{
614 		j = tvb_get_guint8(tvb, new_offset);
615 		if( ( (j == '<') && (tagchars == 0) ) ||
616 		    ( (j == 'h') && (tagchars == 1) ) ||
617 		    ( (j == 'H') && (tagchars == 1) ) ||
618 		    ( (j == 't') && (tagchars == 2) ) ||
619 		    ( (j == 'T') && (tagchars == 2) ) ||
620 		    ( (j == 'm') && (tagchars == 3) ) ||
621 		    ( (j == 'M') && (tagchars == 3) ) ||
622 		    ( (j == 'l') && (tagchars == 4) ) ||
623 		    ( (j == 'L') && (tagchars == 4) ) ||
624 		    ( (j == '>') && (tagchars == 5) ) ) tagchars++;
625 		new_offset++;
626 		new_length--;
627 	}
628 
629 	/* set offset and length of message to after the first HTML tag */
630 	msg_offset = new_offset;
631 	msg_length = new_length;
632 	max = msg_length - 1;
633 	tagchars = 0;
634 
635 	/* find the rest of the message until either a </html> is reached or the end of the frame.
636 	 * All other HTML tags are stripped to display only the raw message (printable characters) */
637 	while( (c < max) && (tagchars < 7) )
638 	{
639 		j = tvb_get_guint8(tvb, msg_offset+c);
640 
641 
642 		/* make sure this is an HTML tag by checking the order of the chars */
643 		if( ( (j == '<') && (tagchars == 0) ) ||
644 		    ( (j == '/') && (tagchars == 1) ) ||
645 		    ( (j == 'h') && (tagchars == 2) ) ||
646 		    ( (j == 'H') && (tagchars == 2) ) ||
647 		    ( (j == 't') && (tagchars == 3) ) ||
648 		    ( (j == 'T') && (tagchars == 3) ) ||
649 		    ( (j == 'm') && (tagchars == 4) ) ||
650 		    ( (j == 'M') && (tagchars == 4) ) ||
651 		    ( (j == 'l') && (tagchars == 5) ) ||
652 		    ( (j == 'L') && (tagchars == 5) ) ||
653 		    ( (j == '>') && (tagchars == 6) ) ) tagchars++;
654 
655 #ifdef STRIP_TAGS
656 		if( j == '<' ) bracket = TRUE;
657 		if( j == '>' ) bracket = FALSE;
658 		if( (g_ascii_isprint(j) ) && (bracket == FALSE) && (j != '>'))
659 #else
660 			if( g_ascii_isprint(j) )
661 #endif
662 			{
663 				msg[i] = j;
664 				i++;
665 			}
666 		c++;
667 	}
668 }
669 
670 static void
671 aim_init_family(int proto, int ett, guint16 family, const aim_subtype *subtypes)
672 {
673 	aim_family *fam = g_new(aim_family, 1);
674 	fam->proto = find_protocol_by_id(proto);
675 	fam->name = proto_get_protocol_short_name(fam->proto);
676 	fam->family = family;
677 	fam->subtypes = subtypes;
678 	families = g_list_append(families, fam);
679 
680 	fam->proto_id = proto;
681 	fam->ett = ett;
682 }
683 
684 static int
685 dissect_aim_ssi_result(tvbuff_t *tvb, packet_info *pinfo, proto_tree *aim_tree)
686 {
687 	col_add_str(pinfo->cinfo, COL_INFO,
688 	    val_to_str(tvb_get_ntohs(tvb, 0), aim_ssi_result_codes, "Unknown SSI result code 0x%02x"));
689 
690 	proto_tree_add_item (aim_tree, hf_aim_ssi_result_code, tvb, 0, 2, ENC_BIG_ENDIAN);
691 
692 	return 2;
693 }
694 
695 #define FNAC_TLV_FAMILY_VERSION  0x0001
696 
697 static const aim_tlv aim_fnac_tlvs[] = {
698 	{ FNAC_TLV_FAMILY_VERSION, "SNAC Family Version", dissect_aim_tlv_value_uint16 },
699 	{ 0, NULL, NULL }
700 };
701 
702 static void
703 dissect_aim_snac(tvbuff_t *tvb, packet_info *pinfo, int offset,
704 		 proto_tree *aim_tree, proto_tree *root_tree)
705 {
706 	guint16 family_id;
707 	guint16 subtype_id;
708 	guint16 flags;
709 	guint32 id;
710 	proto_tree *aim_tree_fnac = NULL;
711 	tvbuff_t *subtvb;
712 	int orig_offset;
713 	const aim_subtype *subtype;
714 	proto_tree *family_tree = NULL;
715 	const aim_family *family;
716 
717 	orig_offset = offset;
718 	family_id = tvb_get_ntohs(tvb, offset);
719 	family = aim_get_family(family_id);
720 	offset += 2;
721 	subtype_id = tvb_get_ntohs(tvb, offset);
722 	subtype = aim_get_subtype(family_id, subtype_id);
723 	offset += 2;
724 	flags = tvb_get_ntohs(tvb, offset);
725 	offset += 2;
726 	id = tvb_get_ntohl(tvb, offset);
727 	offset += 4;
728 
729 	if( aim_tree && subtype != NULL )
730 	{
731 		static int * const fnac_flags[] = {
732 			&hf_aim_fnac_flag_next_is_related,
733 			&hf_aim_fnac_flag_contains_version,
734 			NULL
735 		};
736 
737 		offset = orig_offset;
738 		aim_tree_fnac = proto_tree_add_subtree_format(aim_tree, tvb, 6, 10, ett_aim_fnac, NULL,
739 					  "FNAC: Family: %s (0x%04x), Subtype: %s (0x%04x)",
740 					  family ? family->name : "Unknown", family_id,
741 					  (subtype && subtype->name) ? subtype->name : "Unknown", subtype_id);
742 
743 		proto_tree_add_uint_format_value (aim_tree_fnac, hf_aim_fnac_family,
744 						  tvb, offset, 2, family_id, "%s (0x%04x)",
745 						  family ? family->name : "Unknown", family_id);
746 		offset += 2;
747 
748 		proto_tree_add_uint_format_value (aim_tree_fnac, hf_aim_fnac_subtype,
749 						  tvb, offset, 2, subtype_id, "%s (0x%04x)",
750 						  (subtype && subtype->name) ? subtype->name : "Unknown", subtype_id);
751 
752 		offset += 2;
753 
754 		proto_tree_add_bitmask(aim_tree_fnac, tvb, offset, hf_aim_fnac_flags,
755 			       ett_aim_fnac_flags, fnac_flags, ENC_BIG_ENDIAN);
756 		offset += 2;
757 
758 		proto_tree_add_uint(aim_tree_fnac, hf_aim_fnac_id, tvb, offset,
759 				    4, id);
760 		offset += 4;
761 	}
762 
763 	if(flags & FNAC_FLAG_CONTAINS_VERSION)
764 	{
765 		guint16 len = tvb_get_ntohs(tvb, offset);
766 		int oldoffset;
767 		offset+=2;
768 		oldoffset = offset;
769 
770 		while(offset < oldoffset + len) {
771 			offset = dissect_aim_tlv(tvb, pinfo, offset, aim_tree, aim_fnac_tlvs);
772 		}
773 	}
774 
775 	subtvb = tvb_new_subset_remaining(tvb, offset);
776 
777 	if (family)
778 		col_set_str(pinfo->cinfo, COL_PROTOCOL, family->name);
779 
780 	if(subtype != NULL && family != NULL)
781 	{
782 		col_set_str(pinfo->cinfo, COL_INFO, family->name);
783 		col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", subtype->name);
784 	} else {
785 		col_set_str(pinfo->cinfo, COL_INFO, "SNAC data");
786 
787 		if(family)
788 			col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", family->name);
789 	 	else
790 			col_append_fstr(pinfo->cinfo, COL_INFO, ", Family: 0x%04x", family_id);
791 
792 	 	col_append_fstr(pinfo->cinfo, COL_INFO, ", Subtype: 0x%04x", subtype_id);
793 	}
794 
795 	if(aim_tree && family != NULL)
796 	{
797 		proto_item *ti = proto_tree_add_item(root_tree, family->proto_id, subtvb, 0, -1, ENC_NA);
798 		family_tree = proto_item_add_subtree(ti, family->ett);
799 		if(subtype)
800 			proto_item_append_text(ti, ", %s", subtype->name);
801 	}
802 
803 	if((tvb_reported_length_remaining(tvb, offset) > 0) && (subtype != NULL) && subtype->dissector)
804 	{
805 		subtype->dissector(subtvb, pinfo, family_tree);
806 	}
807 }
808 
809 static void
810 dissect_aim_flap_err(tvbuff_t *tvb, packet_info *pinfo, int offset,
811 		     proto_tree *tree)
812 {
813 	col_set_str(pinfo->cinfo, COL_INFO, "FLAP error");
814 
815 	/* Show the undissected payload */
816 	if (tvb_reported_length_remaining(tvb, offset) > 0)
817 		proto_tree_add_item(tree, hf_aim_data, tvb, offset, -1, ENC_NA);
818 }
819 
820 static void
821 dissect_aim_keep_alive(tvbuff_t *tvb, packet_info *pinfo, int offset,
822 		       proto_tree *tree)
823 {
824 	col_set_str(pinfo->cinfo, COL_INFO, "Keep Alive");
825 
826 	/* Show the undissected payload */
827 	if (tvb_reported_length_remaining(tvb, offset) > 0)
828 		proto_tree_add_item(tree, hf_aim_data, tvb, offset, -1, ENC_NA);
829 }
830 
831 static void
832 dissect_aim_unknown_channel(tvbuff_t *tvb, packet_info *pinfo, int offset,
833 			    proto_tree *tree)
834 {
835 	col_set_str(pinfo->cinfo, COL_INFO, "Unknown Channel");
836 
837 	/* Show the undissected payload */
838 	if (tvb_reported_length_remaining(tvb, offset) > 0)
839 		proto_tree_add_item(tree, hf_aim_data, tvb, offset, -1, ENC_NA);
840 }
841 
842 static int
843 dissect_aim_buddyname(tvbuff_t *tvb, packet_info *pinfo _U_, int offset,
844 		      proto_tree *tree)
845 {
846 	guint8 buddyname_length = 0;
847 	proto_tree *buddy_tree;
848 
849 	buddyname_length = tvb_get_guint8(tvb, offset);
850 	offset++;
851 
852 	if(tree)
853 	{
854 		buddy_tree = proto_tree_add_subtree_format(tree, tvb, offset-1, 1+buddyname_length,
855 					 ett_aim_buddyname, NULL, "Buddy: %s",
856 					 tvb_format_text(pinfo->pool, tvb, offset, buddyname_length));
857 		proto_tree_add_item(buddy_tree, hf_aim_buddyname_len, tvb, offset-1, 1, ENC_BIG_ENDIAN);
858 		proto_tree_add_item(buddy_tree, hf_aim_buddyname, tvb, offset, buddyname_length, ENC_UTF_8|ENC_NA);
859 	}
860 
861 	return offset+buddyname_length;
862 }
863 
864 typedef struct _aim_client_capability
865 {
866 	const char *name;
867 	e_guid_t clsid;
868 } aim_client_capability;
869 
870 static const aim_client_capability known_client_caps[] = {
871 	{ "Send File",
872 	  {0x09461343, 0x4c7f, 0x11d1,
873 	    { 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}},
874 
875 	{ "Recv File",
876 	    { 0x09461348, 0x4c7f, 0x11d1,
877 		   { 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}},
878 
879 	{ "Short Caps",
880 	 {0x09460000, 0x4c7f, 0x11d1,
881 	   { 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}},
882 
883 	{ "Secure IM",
884 	 {0x09460001, 0x4c7f, 0x11d1,
885 	   { 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}},
886 
887 	{ "XHTML IM",
888 	 {0x09460002, 0x4c7f, 0x11d1,
889 	   { 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}},
890 
891 	{ "Video Chat",
892 	 {0x09460100, 0x4c7f, 0x11d1,
893 	   { 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}},
894 
895 	{ "Live Video",
896 	 {0x09460101, 0x4c7f, 0x11d1,
897 	   { 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}},
898 
899 	{ "Camera",
900 	 {0x09460102, 0x4c7f, 0x11d1,
901 	   { 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}},
902 
903 	{ "Microphone",
904 	 {0x09460103, 0x4c7f, 0x11d1,
905 	   { 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}},
906 
907 	{ "Live Audio",
908 	 {0x09460104, 0x4c7f, 0x11d1,
909 	   { 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}},
910 
911 	{ "iChatAV info",
912 	 {0x09460105, 0x4c7f, 0x11d1,
913 	   { 0x82, 0x22, 0x44, 0x45, 0x45, 0x53, 0x54, 0x00}}},
914 
915 	{ "Host Status Text Aware",
916 	 {0x0946010A, 0x4c7f, 0x11d1,
917 	   { 0x82, 0x22, 0x44, 0x45, 0x45, 0x53, 0x54, 0x00}}},
918 
919 	{ "Realtime IM",
920 	 {0x0946010B, 0x4c7f, 0x11d1,
921 	   { 0x82, 0x22, 0x44, 0x45, 0x45, 0x53, 0x54, 0x00}}},
922 
923 	{ "Smart Caps",
924 	 {0x094601FF, 0x4c7f, 0x11d1,
925 	   { 0x82, 0x22, 0x44, 0x45, 0x45, 0x53, 0x54, 0x00}}},
926 
927 	{ "Hiptop",
928 	 {0x09461323, 0x4c7f, 0x11d1,
929 	   { 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}},
930 
931 	{ "Voice Chat",
932 	 {0x09461341, 0x4c7f, 0x11d1,
933 		 { 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}},
934 
935 	{ "File Transfer",
936 	 {0x09461343, 0x4c7f, 0x11d1,
937 		 {0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}},
938 
939 	{ "Direct ICQ Communication",
940 	 {0x09461344, 0x4c7f, 0x11d1,
941 		 {0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}},
942 
943 	{ "Direct ICBM",
944 	 {0x09461345, 0x4c7f, 0x11d1,
945 		 {0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}},
946 
947 	{ "Buddy Icon",
948 	 {0x09461346, 0x4c7f, 0x11d1,
949 		 {0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}},
950 
951 	{ "Add-Ins",
952 	 {0x09461347, 0x4c7f, 0x11d1,
953 		 {0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}},
954 
955 	{ "File Sharing",
956 	 {0x09461348, 0x4c7f, 0x11d1,
957 		 {0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}},
958 
959 	{ "ICQ Server Relaying",
960 	 {0x09461349, 0x4c7f, 0x11d1,
961 		 {0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}},
962 
963 	{ "Games",
964 	 {0x0946134a, 0x4c7f, 0x11d1,
965 		 {0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}},
966 
967 	{ "Games",
968 	 {0x0946134a, 0x4c7f, 0x11d1,
969 		 {0x22, 0x82, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}},
970 
971 	{ "Send Buddy List",
972 	 {0x0946134b, 0x4c7f, 0x11d1,
973 		 {0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}},
974 
975 	{ "AIM/ICQ Interoperability",
976 	 {0x0946134d, 0x4c7f, 0x11d1,
977 		 {0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}},
978 
979 	{ "ICQ UTF8 Support",
980 	 {0x0946134e, 0x4c7f, 0x11d1,
981 		 {0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}},
982 
983 	{ "Old ICQ UTF8 Support",
984 	 {0x2e7a6475, 0xfadf, 0x4dc8,
985 		 {0x88, 0x6f, 0xea, 0x35, 0x95, 0xfd, 0xb6, 0xdf}}},
986 
987 	{ "Chat",
988 	 {0x748f2420, 0x6287, 0x11d1,
989 		 {0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}},
990 
991 	{ "ICQ Rich Text Format Messages",
992 	 {0x97b12751, 0x243c, 0x4334,
993 		 {0xad, 0x22, 0xd6, 0xab, 0xf7, 0x3f, 0x14, 0x92}}},
994 
995 	{ "AP User",
996 	 {0xaa4a32b5, 0xf884, 0x48c6,
997 		 {0xa3, 0xd7, 0x8c, 0x50, 0x97, 0x19, 0xfd, 0x5b}}},
998 
999 	{ "Trillian Encryption",
1000 	 {0xf2e7c7f4, 0xfead, 0x4dfb,
1001 		 {0xb2, 0x35, 0x36, 0x79, 0x8b, 0xdf, 0x00, 0x00}}},
1002 
1003 	{ NULL, {0x0, 0x0, 0x0, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } } }
1004 };
1005 
1006 static const aim_client_capability *
1007 aim_find_capability (e_guid_t clsid)
1008 {
1009 	int i;
1010 
1011 	for(i = 0; known_client_caps[i].name; i++)
1012 	{
1013 		const aim_client_capability *caps = &(known_client_caps[i]);
1014 
1015 		if(memcmp(&(caps->clsid), &clsid, sizeof(e_guid_t)) == 0)
1016 			return caps;
1017 	}
1018 
1019 	return NULL;
1020 }
1021 
1022 static const aim_client_capability *
1023 aim_find_short_capability(guint16 shortid)
1024 {
1025 	e_guid_t clsid = {0x09460000, 0x4c7f, 0x11d1, {0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}};
1026 	clsid.data1 |= shortid;
1027 
1028 	return aim_find_capability(clsid);
1029 }
1030 
1031 static int
1032 dissect_aim_capability(proto_tree *entry, tvbuff_t *tvb, int offset)
1033 {
1034 	const aim_client_capability *caps;
1035 	e_guid_t clsid;
1036 
1037 	tvb_get_ntohguid(tvb, offset, &clsid);
1038 	caps = aim_find_capability(clsid);
1039 
1040 	proto_tree_add_guid_format(entry, hf_aim_nickinfo_caps, tvb, offset, 16,
1041 		&clsid,
1042 		"%s {%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
1043 		caps?caps->name:"Unknown", clsid.data1, clsid.data2,
1044 		clsid.data3, clsid.data4[0], clsid.data4[1], clsid.data4[2],
1045 		clsid.data4[3], clsid.data4[4],	clsid.data4[5], clsid.data4[6],
1046 		clsid.data4[7]
1047 	);
1048 
1049 	return offset+16;
1050 }
1051 
1052 static int
1053 dissect_aim_short_capability(proto_tree *entry, tvbuff_t *tvb, int offset)
1054 {
1055 	const aim_client_capability *caps;
1056 	guint16 shortid;
1057 
1058 	shortid = tvb_get_ntohs(tvb, offset);
1059 	caps = aim_find_short_capability(shortid);
1060 
1061 	proto_tree_add_uint_format(entry, hf_aim_nickinfo_short_caps, tvb, offset, 2,
1062 		shortid,
1063 		"%s (0x%04x)",
1064 		caps?caps->name:"Unknown", shortid
1065 	);
1066 
1067 	return offset+2;
1068 }
1069 
1070 static int
1071 dissect_aim_tlv_value_client_capabilities(proto_item *ti, guint16 valueid _U_, tvbuff_t *tvb, packet_info *pinfo _U_)
1072 {
1073 	int offset = 0;
1074 	proto_tree *entry;
1075 
1076 	proto_item_set_text(ti, "Client Capabilities List");
1077 
1078 	entry = proto_item_add_subtree(ti, ett_aim_nickinfo_caps);
1079 
1080  	while (tvb_reported_length_remaining(tvb, offset) > 0) {
1081 		offset = dissect_aim_capability(entry, tvb, offset);
1082 	}
1083 
1084 	return tvb_reported_length(tvb);
1085 }
1086 
1087 static int
1088 dissect_aim_tlv_value_client_short_capabilities(proto_item *ti, guint16 valueid _U_, tvbuff_t *tvb, packet_info *pinfo _U_)
1089 {
1090 	int offset = 0;
1091 	proto_tree *entry;
1092 
1093 	proto_item_set_text(ti, "Short Client Capabilities List");
1094 
1095 	entry = proto_item_add_subtree(ti, ett_aim_nickinfo_short_caps);
1096 
1097  	while (tvb_reported_length_remaining(tvb, offset) > 0) {
1098 		offset = dissect_aim_short_capability(entry, tvb, offset);
1099 	}
1100 
1101 	return tvb_reported_length(tvb);
1102 }
1103 
1104 static int
1105 dissect_aim_tlv_value_time(proto_item *ti _U_, guint16 valueid _U_, tvbuff_t *tvb, packet_info *pinfo _U_)
1106 {
1107 	/* FIXME */
1108 	return tvb_reported_length(tvb);
1109 }
1110 
1111 static int
1112 dissect_aim_userclass(tvbuff_t *tvb, int offset, int len, proto_item *ti, guint32 value)
1113 {
1114 	proto_tree *entry;
1115 	static int * const flags[] = {
1116 		&hf_aim_userclass_unconfirmed,
1117 		&hf_aim_userclass_administrator,
1118 		&hf_aim_userclass_aol,
1119 		&hf_aim_userclass_commercial,
1120 		&hf_aim_userclass_aim,
1121 		&hf_aim_userclass_away,
1122 		&hf_aim_userclass_icq,
1123 		&hf_aim_userclass_wireless,
1124 		&hf_aim_userclass_unknown100,
1125 		&hf_aim_userclass_imf,
1126 		&hf_aim_userclass_bot,
1127 		&hf_aim_userclass_unknown800,
1128 		&hf_aim_userclass_one_way_wireless,
1129 		&hf_aim_userclass_unknown2000,
1130 		&hf_aim_userclass_unknown4000,
1131 		&hf_aim_userclass_unknown8000,
1132 		&hf_aim_userclass_unknown10000,
1133 		&hf_aim_userclass_unknown20000,
1134 		&hf_aim_userclass_no_knock_knock,
1135 		&hf_aim_userclass_forward_mobile,
1136 		NULL
1137 	};
1138 
1139 	entry = proto_item_add_subtree(ti, ett_aim_userclass);
1140 	proto_tree_add_bitmask_list_value(entry, tvb, offset, len, flags, value);
1141 
1142 	return offset+len;
1143 }
1144 
1145 static int
1146 dissect_aim_tlv_value_userclass(proto_item *ti, guint16 valueid _U_, tvbuff_t *tvb, packet_info *pinfo _U_)
1147 {
1148 	guint16 value16 = tvb_get_ntohs(tvb, 0);
1149 	proto_item_set_text(ti, "Value: 0x%04x", value16);
1150 	return dissect_aim_userclass(tvb, 0, 2, ti, value16);
1151 }
1152 
1153 static int
1154 dissect_aim_tlv_value_userstatus(proto_item *ti _U_, guint16 valueid _U_, tvbuff_t *tvb, packet_info *pinfo _U_)
1155 {
1156 	/* FIXME */
1157 	return tvb_reported_length(tvb);
1158 }
1159 
1160 static int
1161 dissect_aim_tlv_value_dcinfo(proto_item *ti, guint16 valueid _U_, tvbuff_t *tvb, packet_info *pinfo _U_)
1162 {
1163 	int offset = 0;
1164 
1165 	proto_tree *dctree = proto_item_add_subtree(ti, ett_aim_dcinfo);
1166 
1167  	proto_tree_add_item(dctree, hf_aim_dcinfo_ip , tvb, offset, 4, ENC_BIG_ENDIAN); offset+=4;
1168 	proto_tree_add_item(dctree, hf_aim_dcinfo_tcpport, tvb, offset, 4, ENC_BIG_ENDIAN); offset+=4;
1169 	proto_tree_add_item(dctree, hf_aim_dcinfo_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset+=1;
1170 	proto_tree_add_item(dctree, hf_aim_dcinfo_proto_version, tvb, offset, 2, ENC_BIG_ENDIAN); offset+=2;
1171 	proto_tree_add_item(dctree, hf_aim_dcinfo_auth_cookie, tvb, offset, 4, ENC_NA); offset+=2;
1172 	proto_tree_add_item(dctree, hf_aim_dcinfo_webport, tvb, offset, 4, ENC_BIG_ENDIAN); offset+=4;
1173 	proto_tree_add_item(dctree, hf_aim_dcinfo_client_future, tvb, offset, 4, ENC_BIG_ENDIAN); offset+=4;
1174 	proto_tree_add_item(dctree, hf_aim_dcinfo_last_info_update, tvb, offset, 4, ENC_BIG_ENDIAN); offset+=4;
1175 	proto_tree_add_item(dctree, hf_aim_dcinfo_last_ext_info_update, tvb, offset, 4, ENC_BIG_ENDIAN); offset+=4;
1176 	proto_tree_add_item(dctree, hf_aim_dcinfo_last_ext_status_update, tvb, offset, 4, ENC_BIG_ENDIAN); offset+=4;
1177 	proto_tree_add_item(dctree, hf_aim_dcinfo_unknown, tvb, offset, 2, ENC_BIG_ENDIAN); offset+=2;
1178 
1179 	return offset;
1180 }
1181 
1182 static int
1183 dissect_aim_tlv_value_string (proto_item *ti, guint16 valueid _U_, tvbuff_t *tvb, packet_info *pinfo)
1184 {
1185 	guint8 *buf;
1186 	gint string_len;
1187 
1188 	string_len = tvb_reported_length(tvb);
1189 	buf = tvb_get_string_enc(pinfo->pool, tvb, 0, string_len, ENC_UTF_8|ENC_NA);
1190 	proto_item_set_text(ti, "Value: %s", format_text(pinfo->pool, buf, string_len));
1191 
1192 	return string_len;
1193 }
1194 
1195 static int
1196 dissect_aim_tlv_value_string08_array (proto_item *ti, guint16 valueid _U_, tvbuff_t *tvb, packet_info *pinfo _U_)
1197 {
1198 	proto_tree *entry;
1199 	gint offset=0;
1200 
1201 	entry = proto_item_add_subtree(ti, ett_aim_string08_array);
1202 
1203 	while (tvb_reported_length_remaining(tvb, offset) > 1)
1204 	{
1205 		guint8 string_len = tvb_get_guint8(tvb, offset);
1206 		proto_tree_add_item(entry, hf_aim_string08, tvb, offset, 1, ENC_UTF_8|ENC_NA);
1207 		offset += (string_len+1);
1208 	}
1209 
1210 	return offset;
1211 }
1212 
1213 static int
1214 dissect_aim_tlv_value_bytes (proto_item *ti _U_, guint16 valueid _U_, tvbuff_t *tvb, packet_info *pinfo _U_)
1215 {
1216 	return tvb_reported_length(tvb);
1217 }
1218 
1219 static int
1220 dissect_aim_tlv_value_uint8 (proto_item *ti, guint16 valueid _U_, tvbuff_t *tvb, packet_info *pinfo _U_)
1221 {
1222 	guint8 value8 = tvb_get_guint8(tvb, 0);
1223 	proto_item_set_text(ti, "Value: %d", value8);
1224 	return 1;
1225 }
1226 
1227 static int
1228 dissect_aim_tlv_value_uint16 (proto_item *ti, guint16 valueid _U_, tvbuff_t *tvb, packet_info *pinfo _U_)
1229 {
1230 	guint16 value16 = tvb_get_ntohs(tvb, 0);
1231 	proto_item_set_text(ti, "Value: %d", value16);
1232 	return 2;
1233 }
1234 
1235 static int
1236 dissect_aim_tlv_value_ipv4 (proto_item *ti, guint16 valueid _U_, tvbuff_t *tvb, packet_info *pinfo _U_)
1237 {
1238 	proto_item_set_text(ti, "Value: %s", tvb_ip_to_str(pinfo->pool, tvb, 0));
1239 	return 4;
1240 }
1241 
1242 static int
1243 dissect_aim_tlv_value_uint32 (proto_item *ti, guint16 valueid _U_, tvbuff_t *tvb, packet_info *pinfo _U_)
1244 {
1245 	guint32 value32 = tvb_get_ntohl(tvb, 0);
1246 	proto_item_set_text(ti, "Value: %d", value32);
1247 	return 4;
1248 }
1249 
1250 static int
1251 dissect_aim_tlv_value_messageblock (proto_item *ti, guint16 valueid _U_, tvbuff_t *tvb, packet_info *pinfo)
1252 {
1253 	proto_tree *entry;
1254 	guint8 *buf;
1255 	guint16 featurelen;
1256 	guint32 blocklen;
1257 	proto_item* len_item;
1258 	int offset=0;
1259 
1260 	/* Setup a new subtree */
1261 	entry = proto_item_add_subtree(ti, ett_aim_messageblock);
1262 
1263 	/* Features descriptor */
1264 	proto_tree_add_item(entry, hf_aim_messageblock_featuresdes, tvb, offset,
1265 			    2, ENC_BIG_ENDIAN);
1266 	offset += 2;
1267 
1268 	/* Features Length */
1269 	featurelen = tvb_get_ntohs(tvb, offset);
1270 	proto_tree_add_item(entry, hf_aim_messageblock_featureslen, tvb, offset,
1271 			    2, ENC_BIG_ENDIAN);
1272 	offset += 2;
1273 
1274 	/* Features (should be expanded further @@@@@@@ ) */
1275 	proto_tree_add_item(entry, hf_aim_messageblock_features, tvb, offset,
1276 			    featurelen, ENC_NA);
1277 	offset += featurelen;
1278 
1279 	/* There can be multiple messages in this message block */
1280 	while (tvb_reported_length_remaining(tvb, offset) > 0) {
1281 		/* Info field */
1282 		proto_tree_add_item(entry, hf_aim_messageblock_info, tvb,
1283 				    offset, 2, ENC_BIG_ENDIAN);
1284 		offset += 2;
1285 
1286 		/* Block length (includes charset and charsubset) */
1287 		len_item = proto_tree_add_item_ret_uint(entry, hf_aim_messageblock_len, tvb, offset,
1288 				    2, ENC_BIG_ENDIAN, &blocklen);
1289 		if (blocklen <= 4)
1290 		{
1291 			expert_add_info(pinfo, len_item, &ei_aim_messageblock_len);
1292 			break;
1293 		}
1294 		offset += 2;
1295 
1296 		/* Character set */
1297 		proto_tree_add_item(entry, hf_aim_messageblock_charset, tvb,
1298 				    offset, 2, ENC_BIG_ENDIAN);
1299 		offset += 2;
1300 
1301 		/* Character subset */
1302 		proto_tree_add_item(entry, hf_aim_messageblock_charsubset, tvb,
1303 				    offset, 2, ENC_BIG_ENDIAN);
1304 		offset += 2;
1305 
1306 		/* The actual message */
1307 		buf = tvb_get_string_enc(pinfo->pool, tvb, offset, blocklen - 4, ENC_ASCII|ENC_NA);
1308 		proto_item_append_text(ti, "Message: %s ",
1309 				    format_text(pinfo->pool, buf, blocklen - 4));
1310 		proto_tree_add_item(entry, hf_aim_messageblock_message, tvb,
1311 				    offset, blocklen-4, ENC_ASCII|ENC_NA);
1312 
1313 		offset += blocklen-4;
1314 	}
1315 
1316 	return offset;
1317 }
1318 
1319 /* Dissect a TLV value */
1320 static int
1321 dissect_aim_tlv(tvbuff_t *tvb, packet_info *pinfo, int offset,
1322 		proto_tree *tree, const aim_tlv *tlv)
1323 {
1324 	guint16 valueid;
1325 	guint16 length;
1326 	int i = 0;
1327 	const aim_tlv *tmp;
1328 	const char *desc;
1329 	proto_item *ti1;
1330 	proto_tree *tlv_tree;
1331 
1332 	/* Get the value ID */
1333 	valueid = tvb_get_ntohs(tvb, offset);
1334 
1335 	/* Figure out which entry applies from the tlv list */
1336 	tmp = tlv;
1337 	while (tmp[i].valueid) {
1338 		if (tmp[i].valueid == valueid) {
1339 			/* We found a match */
1340 			break;
1341 		}
1342 		i++;
1343 	}
1344 
1345 	/* At this point, we are either pointing at the correct record, or
1346 	   we didn't find the record, and are pointing at the last item in the
1347 	   list */
1348 
1349 	length = tvb_get_ntohs(tvb, offset+2);
1350 
1351 	if (tmp[i].desc != NULL)
1352 		desc = tmp[i].desc;
1353 	else
1354 		desc = "Unknown";
1355 
1356 	tlv_tree = proto_tree_add_subtree_format(tree, tvb, offset, length + 4,
1357 												ett_aim_tlv, NULL, "TLV: %s", desc);
1358 
1359 	proto_tree_add_uint_format_value(tlv_tree, hf_aim_tlv_value_id, tvb, offset, 2,
1360 				    valueid, "%s (0x%04x)", desc, valueid);
1361 	offset += 2;
1362 
1363 	proto_tree_add_uint(tlv_tree, hf_aim_tlv_length, tvb, offset, 2, length);
1364 	offset += 2;
1365 
1366 	proto_tree_add_subtree(tlv_tree, tvb, offset, length, ett_aim_tlv_value, &ti1, "Value");
1367 
1368 	if (tmp[i].dissector) {
1369 		tmp[i].dissector(ti1, valueid, tvb_new_subset_length(tvb, offset, length), pinfo);
1370 	}
1371 
1372 	offset += length;
1373 
1374 	/* Return the new length */
1375 	return offset;
1376 }
1377 
1378 static int
1379 dissect_aim_tlv_sequence(tvbuff_t *tvb, packet_info *pinfo, int offset,
1380 			 proto_tree *tree, const aim_tlv *tlv_table)
1381 {
1382 	while (tvb_reported_length_remaining(tvb, offset) > 0) {
1383 		offset = dissect_aim_tlv(tvb, pinfo, offset, tree, tlv_table);
1384 	}
1385 
1386 	return offset;
1387 }
1388 
1389 static int
1390 dissect_aim_tlv_list(tvbuff_t *tvb, packet_info *pinfo, int offset,
1391 		     proto_tree *tree, const aim_tlv *tlv_table)
1392 {
1393 	guint16 i, tlv_count = tvb_get_ntohs(tvb, offset);
1394 
1395 	proto_tree_add_item(tree, hf_aim_tlvcount, tvb, offset, 2, ENC_BIG_ENDIAN);
1396 	offset += 2;
1397 
1398 	for(i = 0; i < tlv_count; i++) {
1399 		offset = dissect_aim_tlv(tvb, pinfo, offset, tree, tlv_table);
1400 	}
1401 
1402 	return offset;
1403 }
1404 
1405 #define AIM_CLIENT_TLV_SCREEN_NAME             0x0001
1406 #define AIM_CLIENT_TLV_NEW_ROASTED_PASSWORD    0x0002
1407 #define AIM_CLIENT_TLV_CLIENT_ID_STRING        0x0003
1408 #define AIM_CLIENT_TLV_ERRORURL                0x0004
1409 #define AIM_CLIENT_TLV_BOS_SERVER_STRING       0x0005
1410 #define AIM_CLIENT_TLV_AUTH_COOKIE             0x0006
1411 #define AIM_CLIENT_TLV_ERRORCODE               0x0008
1412 #define AIM_CLIENT_TLV_DISCONNECT_REASON       0x0009
1413 #define AIM_CLIENT_TLV_RECONNECT_HOST          0x000a
1414 #define AIM_CLIENT_TLV_URL                     0x000b
1415 #define AIM_CLIENT_TLV_DEBUG_DATA              0x000c
1416 #define AIM_CLIENT_TLV_FAMILY_ID               0x000d
1417 #define AIM_CLIENT_TLV_CLIENT_COUNTRY          0x000e
1418 #define AIM_CLIENT_TLV_CLIENT_LANGUAGE         0x000f
1419 #define AIM_CLIENT_TLV_EMAILADDR               0x0011
1420 #define AIM_CLIENT_TLV_OLD_ROASTED_PASSWORD    0x0012
1421 #define AIM_CLIENT_TLV_REGSTATUS               0x0013
1422 #define AIM_CLIENT_TLV_CLIENT_DISTRIBUTION_NUM 0x0014
1423 #define AIM_CLIENT_TLV_INVITEMESSAGE           0x0015
1424 #define AIM_CLIENT_TLV_CLIENT_ID               0x0016
1425 #define AIM_CLIENT_TLV_CLIENT_MAJOR_VERSION    0x0017
1426 #define AIM_CLIENT_TLV_CLIENT_MINOR_VERSION    0x0018
1427 #define AIM_CLIENT_TLV_CLIENT_LESSER_VERSION   0x0019
1428 #define AIM_CLIENT_TLV_CLIENT_BUILD_NUMBER     0x001a
1429 #define AIM_CLIENT_TLV_PASSWORD_MD5            0x0025
1430 #define AIM_CLIENT_TLV_LATESTBETABUILD         0x0040
1431 #define AIM_CLIENT_TLV_LATESTBETAURL           0x0041
1432 #define AIM_CLIENT_TLV_LATESTBETAINFO          0x0042
1433 #define AIM_CLIENT_TLV_LATESTBETANAME          0x0043
1434 #define AIM_CLIENT_TLV_LATESTRELEASEBUILD      0x0044
1435 #define AIM_CLIENT_TLV_LATESTRELEASEURL        0x0045
1436 #define AIM_CLIENT_TLV_LATESTRELEASEINFO       0x0046
1437 #define AIM_CLIENT_TLV_LATESTRELEASENAME       0x0047
1438 #define AIM_CLIENT_TLV_BETA_DIGEST_SIG         0x0048
1439 #define AIM_CLIENT_TLV_RELEASE_DIGEST_SIG      0x0049
1440 #define AIM_CLIENT_TLV_CLIENTUSESSI            0x004a
1441 #define AIM_CLIENT_TLV_CHANGE_PASSWORD_URL     0x0054
1442 #define AIM_CLIENT_TLV_AWAITING_AUTH           0x0066
1443 #define AIM_CLIENT_TLV_MEMBERS                 0x00c8
1444 #define AIM_CLIENT_TLV_VISIBILITY_BITS         0x00c9
1445 #define AIM_CLIENT_TLV_PRIVACY                 0x00ca
1446 #define AIM_CLIENT_TLV_VISIBLE_CLASS           0x00cb
1447 #define AIM_CLIENT_TLV_VISIBLE_MISC            0x00cc
1448 #define AIM_CLIENT_TLV_ICQ2K_SHORTCUT          0x00cd
1449 #define AIM_CLIENT_TLV_FIRST_LOADED_TIME       0x00d4
1450 #define AIM_CLIENT_TLV_BUDDY_ICON_MD5SUM       0x00d5
1451 #define AIM_CLIENT_TLV_GIVEN_NAME              0x0131
1452 #define AIM_CLIENT_TLV_LOCAL_EMAIL             0x0137
1453 #define AIM_CLIENT_TLV_LOCAL_SMS               0x013a
1454 #define AIM_CLIENT_TLV_LOCAL_COMMENT           0x013c
1455 #define AIM_CLIENT_TLV_LOCAL_PERSONAL_ALERT    0x013d
1456 #define AIM_CLIENT_TLV_LOCAL_PERSONAL_SOUND    0x013e
1457 #define AIM_CLIENT_TLV_FIRST_MESSAGE_SENT      0x0145
1458 
1459 static const aim_tlv aim_client_tlvs[] = {
1460 	{ AIM_CLIENT_TLV_SCREEN_NAME,		  "Screen name",				       dissect_aim_tlv_value_string },
1461 	{ AIM_CLIENT_TLV_NEW_ROASTED_PASSWORD,	  "Roasted password array",			       dissect_aim_tlv_value_bytes  },
1462 	{ AIM_CLIENT_TLV_OLD_ROASTED_PASSWORD,	  "Old roasted password array",			       dissect_aim_tlv_value_bytes  },
1463 	{ AIM_CLIENT_TLV_CLIENT_ID_STRING,	  "Client id string (name, version)",		       dissect_aim_tlv_value_string },
1464 	{ AIM_CLIENT_TLV_CLIENT_ID,		  "Client id number",				       dissect_aim_tlv_value_uint16 },
1465 	{ AIM_CLIENT_TLV_CLIENT_MAJOR_VERSION,	  "Client major version",			       dissect_aim_tlv_value_uint16 },
1466 	{ AIM_CLIENT_TLV_CLIENT_MINOR_VERSION,	  "Client minor version",			       dissect_aim_tlv_value_uint16 },
1467 	{ AIM_CLIENT_TLV_CLIENT_LESSER_VERSION,	  "Client lesser version",			       dissect_aim_tlv_value_uint16 },
1468 	{ AIM_CLIENT_TLV_CLIENT_BUILD_NUMBER,	  "Client build number",			       dissect_aim_tlv_value_uint16 },
1469 	{ AIM_CLIENT_TLV_PASSWORD_MD5,		  "Password Hash (MD5)",			       dissect_aim_tlv_value_bytes },
1470 	{ AIM_CLIENT_TLV_CLIENT_DISTRIBUTION_NUM, "Client distribution number",			       dissect_aim_tlv_value_uint32 },
1471 	{ AIM_CLIENT_TLV_CLIENT_LANGUAGE,	  "Client language",				       dissect_aim_tlv_value_string },
1472 	{ AIM_CLIENT_TLV_CLIENT_COUNTRY,	  "Client country",				       dissect_aim_tlv_value_string },
1473 	{ AIM_CLIENT_TLV_BOS_SERVER_STRING,	  "BOS server string",				       dissect_aim_tlv_value_string },
1474 	{ AIM_CLIENT_TLV_AUTH_COOKIE,		  "Authorization cookie",			       dissect_aim_tlv_value_bytes },
1475 	{ AIM_CLIENT_TLV_ERRORURL,		  "Error URL",					       dissect_aim_tlv_value_string },
1476 	{ AIM_CLIENT_TLV_ERRORCODE,		  "Error Code",					       dissect_aim_tlv_value_uint16 },
1477 	{ AIM_CLIENT_TLV_DISCONNECT_REASON,	  "Disconnect Reason",				       dissect_aim_tlv_value_uint16 },
1478 	{ AIM_CLIENT_TLV_RECONNECT_HOST,	  "Reconnect Hostname",				       dissect_aim_tlv_value_string },
1479 	{ AIM_CLIENT_TLV_URL,			  "URL",					       dissect_aim_tlv_value_string },
1480 	{ AIM_CLIENT_TLV_DEBUG_DATA,		  "Debug Data",					       dissect_aim_tlv_value_uint16 },
1481 	{ AIM_CLIENT_TLV_EMAILADDR,		  "Account Email address",			       dissect_aim_tlv_value_string },
1482 	{ AIM_CLIENT_TLV_REGSTATUS,		  "Registration Status",			       dissect_aim_tlv_value_uint16 },
1483 	{ AIM_CLIENT_TLV_LATESTBETABUILD,	  "Latest Beta Build",				       dissect_aim_tlv_value_uint32 },
1484 	{ AIM_CLIENT_TLV_LATESTBETAURL,		  "Latest Beta URL",				       dissect_aim_tlv_value_string },
1485 	{ AIM_CLIENT_TLV_LATESTBETAINFO,	  "Latest Beta Info",				       dissect_aim_tlv_value_string },
1486 	{ AIM_CLIENT_TLV_LATESTBETANAME,	  "Latest Beta Name",				       dissect_aim_tlv_value_string },
1487 	{ AIM_CLIENT_TLV_LATESTRELEASEBUILD,	  "Latest Release Build",			       dissect_aim_tlv_value_uint32 },
1488 	{ AIM_CLIENT_TLV_LATESTRELEASEURL,	  "Latest Release URL",				       dissect_aim_tlv_value_string },
1489 	{ AIM_CLIENT_TLV_LATESTRELEASEINFO,	  "Latest Release Info",			       dissect_aim_tlv_value_string  },
1490 	{ AIM_CLIENT_TLV_LATESTRELEASENAME,	  "Latest Release Name",			       dissect_aim_tlv_value_string },
1491 	{ AIM_CLIENT_TLV_BETA_DIGEST_SIG,	  "Beta Digest Signature (MD5)" ,		       dissect_aim_tlv_value_bytes },
1492 	{ AIM_CLIENT_TLV_RELEASE_DIGEST_SIG,	  "Release Digest Signature (MD5)",		       dissect_aim_tlv_value_bytes },
1493 	{ AIM_CLIENT_TLV_CLIENTUSESSI,		  "Use SSI",					       dissect_aim_tlv_value_uint8 },
1494 	{ AIM_CLIENT_TLV_FAMILY_ID,		  "Service (SNAC Family) ID",			       dissect_aim_tlv_value_uint16 },
1495 	{ AIM_CLIENT_TLV_CHANGE_PASSWORD_URL,	  "Change password url",			       dissect_aim_tlv_value_string },
1496 	{ AIM_CLIENT_TLV_AWAITING_AUTH,		  "Awaiting Authorization",			       dissect_aim_tlv_value_bytes },
1497 	{ AIM_CLIENT_TLV_MEMBERS,		  "Members of this Group",			       dissect_aim_tlv_value_bytes },
1498 	{ AIM_CLIENT_TLV_VISIBILITY_BITS,	  "Bitfield",					       dissect_aim_tlv_value_bytes },
1499 	{ AIM_CLIENT_TLV_PRIVACY,		  "Privacy Settings" ,				       dissect_aim_tlv_value_uint8 },
1500 	{ AIM_CLIENT_TLV_VISIBLE_CLASS,		  "Visible To Classes",				       dissect_aim_tlv_value_userclass },
1501 	{ AIM_CLIENT_TLV_VISIBLE_MISC,		  "Allow Others to See Data",			       dissect_aim_tlv_value_bytes },
1502 	{ AIM_CLIENT_TLV_ICQ2K_SHORTCUT,	  "ICQ2K Shortcut List",			       dissect_aim_tlv_value_string },
1503 	{ AIM_CLIENT_TLV_FIRST_LOADED_TIME,	  "First Time Buddy Was Added (Unix Timestamp)" ,      dissect_aim_tlv_value_uint32 },
1504 	{ AIM_CLIENT_TLV_BUDDY_ICON_MD5SUM,	  "MD5SUM of Current Buddy Icon",		       dissect_aim_tlv_value_bytes },
1505 	{ AIM_CLIENT_TLV_GIVEN_NAME,		  "Locally Specified Buddy Name",		       dissect_aim_tlv_value_string },
1506 	{ AIM_CLIENT_TLV_LOCAL_EMAIL,		  "Locally Specified Buddy Email",		       dissect_aim_tlv_value_string },
1507 	{ AIM_CLIENT_TLV_LOCAL_SMS,		  "Locally Specified Buddy SMS",		       dissect_aim_tlv_value_string },
1508 	{ AIM_CLIENT_TLV_LOCAL_COMMENT,		  "Locally Specified Buddy Comment",		       dissect_aim_tlv_value_string },
1509 	{ AIM_CLIENT_TLV_LOCAL_PERSONAL_ALERT,	  "Personal Alert for Buddy",			       dissect_aim_tlv_value_uint16 },
1510 	{ AIM_CLIENT_TLV_LOCAL_PERSONAL_SOUND,	  "Personal Sound for Buddy",			       dissect_aim_tlv_value_string },
1511 	{ AIM_CLIENT_TLV_FIRST_MESSAGE_SENT,	  "First Time Message Sent to Buddy (Unix Timestamp)", dissect_aim_tlv_value_uint32 },
1512 	{ 0, NULL, NULL }
1513 };
1514 
1515 static void
1516 dissect_aim_close_conn(tvbuff_t *tvb, packet_info *pinfo, int offset,
1517 		       proto_tree *tree)
1518 {
1519 	col_set_str(pinfo->cinfo, COL_INFO, "Close Connection");
1520 
1521 	dissect_aim_tlv_sequence(tvb, pinfo, offset, tree, aim_client_tlvs);
1522 }
1523 
1524 static void
1525 dissect_aim_newconn(tvbuff_t *tvb, packet_info *pinfo, int offset,
1526 		    proto_tree *tree)
1527 {
1528 	col_set_str(pinfo->cinfo, COL_INFO, "New Connection");
1529 
1530 	if (tvb_reported_length_remaining(tvb, offset) > 0) {
1531 		proto_tree_add_item(tree, hf_aim_version, tvb, offset, 4, ENC_NA);
1532 		offset+=4;
1533 		offset = dissect_aim_tlv_sequence(tvb, pinfo, offset, tree, aim_client_tlvs);
1534 	}
1535 
1536 	if (tvb_reported_length_remaining(tvb, offset) > 0)
1537 		proto_tree_add_item(tree, hf_aim_data, tvb, offset, -1, ENC_NA);
1538 }
1539 
1540 
1541 static int
1542 dissect_aim_snac_error(tvbuff_t *tvb, packet_info *pinfo, proto_tree *aim_tree)
1543 {
1544 	col_add_str(pinfo->cinfo, COL_INFO,
1545 	    val_to_str(tvb_get_ntohs(tvb, 0), aim_snac_errors, "Unknown SNAC error 0x%02x"));
1546 
1547 	proto_tree_add_item (aim_tree, hf_aim_snac_error, tvb, 0, 2, ENC_BIG_ENDIAN);
1548 
1549 	return dissect_aim_tlv_sequence(tvb, pinfo, 2, aim_tree, aim_client_tlvs);
1550 }
1551 
1552 static guint
1553 get_aim_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_)
1554 {
1555 	guint16 plen;
1556 
1557 	/*
1558 	* Get the length of the AIM packet.
1559 	*/
1560 	plen = tvb_get_ntohs(tvb, offset + 4);
1561 
1562 	/*
1563 	* That length doesn't include the length of the header itself; add that in.
1564 	*/
1565 	return plen + 6;
1566 }
1567 
1568 static int
1569 dissect_aim_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
1570 {
1571 	/* Header fields */
1572 	unsigned char  hdr_channel;           /* channel ID */
1573 	unsigned short hdr_sequence_no;       /* Internal frame sequence number, not needed */
1574 	unsigned short hdr_data_field_length; /* length of data within frame */
1575 
1576 	int offset=0;
1577 
1578 /* Set up structures we will need to add the protocol subtree and manage it */
1579 	proto_item *ti;
1580 	proto_tree *aim_tree = NULL;
1581 
1582 /* Make entries in Protocol column and Info column on summary display */
1583 	col_set_str(pinfo->cinfo, COL_PROTOCOL, "AIM");
1584 
1585 	col_set_str(pinfo->cinfo, COL_INFO, "AOL Instant Messenger");
1586 
1587 	/* get relevant header information */
1588 	offset += 1;          /* XXX - put the identifier into the tree? */
1589 	hdr_channel           = tvb_get_guint8(tvb, offset);
1590 	offset += 1;
1591 	hdr_sequence_no       = tvb_get_ntohs(tvb, offset);
1592 	offset += 2;
1593 	hdr_data_field_length = tvb_get_ntohs(tvb, offset);
1594 	offset += 2;
1595 
1596 /* In the interest of speed, if "tree" is NULL, don't do any work not
1597    necessary to generate protocol tree items. */
1598 	if (tree) {
1599 		ti = proto_tree_add_item(tree, proto_aim, tvb, 0, -1, ENC_NA);
1600 		aim_tree = proto_item_add_subtree(ti, ett_aim);
1601 		proto_tree_add_uint(aim_tree, hf_aim_cmd_start, tvb, 0, 1, '*');
1602 		proto_tree_add_item(aim_tree, hf_aim_channel, tvb, 1, 1, ENC_BIG_ENDIAN);
1603 		proto_tree_add_uint(aim_tree, hf_aim_seqno, tvb, 2, 2, hdr_sequence_no);
1604 		proto_tree_add_uint(aim_tree, hf_aim_data_len, tvb, 4, 2, hdr_data_field_length);
1605 
1606 	}
1607 
1608 	switch(hdr_channel)
1609 	{
1610 	case CHANNEL_NEW_CONN:
1611 		dissect_aim_newconn(tvb, pinfo, offset, aim_tree);
1612 		break;
1613 	case CHANNEL_SNAC_DATA:
1614 		dissect_aim_snac(tvb, pinfo, offset, aim_tree, tree);
1615 		break;
1616 	case CHANNEL_FLAP_ERR:
1617 		dissect_aim_flap_err(tvb, pinfo, offset, aim_tree);
1618 		break;
1619 	case CHANNEL_CLOSE_CONN:
1620 		dissect_aim_close_conn(tvb, pinfo, offset, aim_tree);
1621 		break;
1622 	case CHANNEL_KEEP_ALIVE:
1623 		dissect_aim_keep_alive(tvb, pinfo, offset, aim_tree);
1624 		break;
1625 	default:
1626 		dissect_aim_unknown_channel(tvb, pinfo, offset, aim_tree);
1627 		break;
1628 	}
1629 
1630 	return tvb_reported_length(tvb);
1631 }
1632 
1633 /* Code to actually dissect the packets */
1634 static int
1635 dissect_aim(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
1636 {
1637 	/* check, if this is really an AIM packet, they start with 0x2a */
1638 	/* XXX - I've seen some stuff starting with 0x5a followed by 0x2a */
1639 
1640 	if(tvb_reported_length(tvb) >= 1 && tvb_get_guint8(tvb, 0) != 0x2a)
1641 	{
1642 		/* Not an instant messenger packet, just happened to use the
1643 		 * same port
1644 		 *
1645 		 * XXX - if desegmentation disabled, this might be a continuation
1646 		 * packet, not a non-AIM packet
1647 		 */
1648 		return 0;
1649 	}
1650 
1651 	tcp_dissect_pdus(tvb, pinfo, tree, aim_desegment, 6, get_aim_pdu_len,
1652 			 dissect_aim_pdu, data);
1653 	return tvb_reported_length(tvb);
1654 }
1655 
1656 static int
1657 dissect_aim_ssl_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
1658 {
1659 	dissector_handle_t *app_handle = (dissector_handle_t *) data;
1660 	/* XXX improve heuristics */
1661 	if (tvb_reported_length(tvb) < 1 || tvb_get_guint8(tvb, 0) != 0x2a) {
1662 		return FALSE;
1663 	}
1664 	dissect_aim(tvb, pinfo, tree, NULL);
1665 	*app_handle = aim_handle;
1666 	return TRUE;
1667 }
1668 
1669 /***********************************************************************************************************
1670  * AIM ADMIN
1671  ***********************************************************************************************************/
1672 static int dissect_aim_admin_accnt_info_req(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *admin_tree)
1673 {
1674 	proto_tree_add_item(admin_tree, hf_admin_acctinfo_code, tvb, 0, 2, ENC_BIG_ENDIAN);
1675 	proto_tree_add_item(admin_tree, hf_admin_acctinfo_unknown, tvb, 2, 2, ENC_BIG_ENDIAN);
1676 	return 4;
1677 }
1678 
1679 static int dissect_aim_admin_accnt_info_repl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *admin_tree)
1680 {
1681 	int offset = 0;
1682 	proto_tree_add_item(admin_tree, hf_admin_acctinfo_permissions, tvb, offset, 2, ENC_BIG_ENDIAN);
1683 	offset+=2;
1684 	return dissect_aim_tlv_list(tvb, pinfo, offset, admin_tree, aim_client_tlvs);
1685 }
1686 
1687 static int dissect_aim_admin_info_change_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *admin_tree)
1688 {
1689 	return dissect_aim_tlv_sequence(tvb, pinfo, 0, admin_tree, aim_client_tlvs);
1690 }
1691 
1692 static int dissect_aim_admin_cfrm_repl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *admin_tree)
1693 {
1694 	int offset = 0;
1695 	proto_tree_add_item(admin_tree, hf_admin_confirm_status, tvb, offset, 2, ENC_BIG_ENDIAN);
1696 	offset+=2;
1697 	return dissect_aim_tlv_sequence(tvb, pinfo, offset, admin_tree, aim_client_tlvs);
1698 }
1699 
1700 static const aim_subtype aim_fnac_family_admin[] = {
1701 	{ 0x0001, "Error", dissect_aim_snac_error },
1702 	{ 0x0002, "Request Account Information", dissect_aim_admin_accnt_info_req },
1703 	{ 0x0003, "Requested Account Information", dissect_aim_admin_accnt_info_repl },
1704 	{ 0x0004, "Infochange Request", dissect_aim_admin_info_change_req },
1705 	{ 0x0005, "Infochange Reply", dissect_aim_admin_accnt_info_repl },
1706 	{ 0x0006, "Account Confirm Request", NULL },
1707 	{ 0x0007, "Account Confirm Reply", dissect_aim_admin_cfrm_repl},
1708 	{ 0, NULL, NULL }
1709 };
1710 
1711 /***********************************************************************************************************
1712  * AIM ADVERTS
1713  ***********************************************************************************************************/
1714 static const aim_subtype aim_fnac_family_adverts[] = {
1715 	{ 0x0001, "Error", dissect_aim_snac_error },
1716 	{ 0x0002, "Request", NULL },
1717 	/* FIXME: */
1718 	/* From other sources, I understand this response contains
1719 	 * a GIF file, haven't actually seen one though. And this
1720 	 * family appears to be deprecated, so we might never find out.. */
1721 	{ 0x0003, "Data (GIF)", NULL },
1722 	{ 0, NULL, NULL }
1723 };
1724 
1725 
1726 /***********************************************************************************************************
1727  * AIM BOS
1728  ***********************************************************************************************************/
1729 
1730 /* Family BOS (Misc) */
1731 
1732 #define AIM_PRIVACY_TLV_MAX_VISIB_LIST_SIZE     0x001
1733 #define AIM_PRIVACY_TLV_MAX_INVISIB_LIST_SIZE   0x002
1734 
1735 static const aim_tlv aim_privacy_tlvs[] = {
1736 	{ AIM_PRIVACY_TLV_MAX_VISIB_LIST_SIZE,   "Max visible list size", dissect_aim_tlv_value_uint16 },
1737 	{ AIM_PRIVACY_TLV_MAX_INVISIB_LIST_SIZE, "Max invisible list size", dissect_aim_tlv_value_uint16 },
1738 	{ 0, NULL, NULL },
1739 };
1740 
1741 static int dissect_aim_bos_set_group_perm(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bos_tree)
1742 {
1743 	int offset = 0;
1744 	guint32 userclass = tvb_get_ntohl(tvb, offset);
1745 	proto_item *ti = proto_tree_add_uint(bos_tree, hf_aim_bos_class, tvb, offset, 4, userclass);
1746 	return dissect_aim_userclass(tvb, offset, 4, ti, userclass);
1747 }
1748 
1749 static int dissect_aim_bos_rights(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bos_tree)
1750 {
1751 	return dissect_aim_tlv_sequence(tvb, pinfo, 0, bos_tree, aim_privacy_tlvs);
1752 }
1753 
1754 static int dissect_aim_bos_buddyname(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bos_tree)
1755 {
1756 	int offset = 0;
1757 	while(tvb_reported_length_remaining(tvb, offset) > 0) {
1758 		offset = dissect_aim_buddyname(tvb, pinfo, offset, bos_tree);
1759 	}
1760 	return offset;
1761 }
1762 
1763 static const aim_subtype aim_fnac_family_bos[] = {
1764 	{ 0x0001, "Error", dissect_aim_snac_error },
1765 	{ 0x0002, "Rights Query", NULL },
1766 	{ 0x0003, "Rights" , dissect_aim_bos_rights },
1767 	{ 0x0004, "Set Group Permissions Mask", dissect_aim_bos_set_group_perm },
1768 	{ 0x0005, "Add To Visible List", dissect_aim_bos_buddyname },
1769 	{ 0x0006, "Delete From Visible List", dissect_aim_bos_buddyname },
1770 	{ 0x0007, "Add To Invisible List", dissect_aim_bos_buddyname },
1771 	{ 0x0008, "Delete From Invisible List", dissect_aim_bos_buddyname },
1772 	{ 0, NULL, NULL }
1773 };
1774 
1775 
1776 /***********************************************************************************************************
1777  * AIM BUDDYLIST
1778  ***********************************************************************************************************/
1779 #define AIM_ONLINEBUDDY_USERCLASS      0x0001
1780 #define AIM_ONLINEBUDDY_ONSINCE        0x0003
1781 #define AIM_ONLINEBUDDY_IDLETIME       0x0004
1782 #define AIM_ONLINEBUDDY_MEMBERSINCE    0x0005
1783 #define AIM_ONLINEBUDDY_STATUS         0x0006
1784 #define AIM_ONLINEBUDDY_IPADDR         0x000a
1785 #define AIM_ONLINEBUDDY_DCINFO         0x000c
1786 #define AIM_ONLINEBUDDY_CAPINFO        0x000d
1787 #define AIM_ONLINEBUDDY_SESSIONLEN     0x000f
1788 #define AIM_ONLINEBUDDY_ICQSESSIONLEN  0x0010
1789 #define AIM_ONLINEBUDDY_TIMEUPDATE     0x0011
1790 #define AIM_ONLINEBUDDY_MYINSTANCENUM  0x0014
1791 #define AIM_ONLINEBUDDY_SHORTCAPS      0x0019
1792 #define AIM_ONLINEBUDDY_BARTINFO       0x001d
1793 #define AIM_ONLINEBUDDY_NICKFLAGS2     0x001f
1794 #define AIM_ONLINEBUDDY_BUDDYFEEDTIME  0x0023
1795 #define AIM_ONLINEBUDDY_SIGTIME        0x0026
1796 #define AIM_ONLINEBUDDY_AWAYTIME       0x0027
1797 #define AIM_ONLINEBUDDY_GEOCOUNTRY     0x002a
1798 
1799 static const aim_tlv aim_onlinebuddy_tlvs[] = {
1800 	{ AIM_ONLINEBUDDY_USERCLASS,	 "User class", dissect_aim_tlv_value_userclass },
1801 	{ AIM_ONLINEBUDDY_ONSINCE,	 "Online since", dissect_aim_tlv_value_uint32 },
1802 	{ AIM_ONLINEBUDDY_IDLETIME,	 "Idle time (sec)", dissect_aim_tlv_value_uint16 },
1803 	{ AIM_ONLINEBUDDY_MEMBERSINCE,	 "Member since", dissect_aim_tlv_value_time },
1804 	{ AIM_ONLINEBUDDY_STATUS,	 "Online status", dissect_aim_tlv_value_userstatus },
1805 	{ AIM_ONLINEBUDDY_IPADDR,	 "User IP Address", dissect_aim_tlv_value_ipv4 },
1806 	{ AIM_ONLINEBUDDY_DCINFO,	 "DC Info", dissect_aim_tlv_value_dcinfo},
1807 	{ AIM_ONLINEBUDDY_CAPINFO,	 "Capability Info", dissect_aim_tlv_value_client_capabilities },
1808 	{ AIM_ONLINEBUDDY_TIMEUPDATE,	 "Time update", dissect_aim_tlv_value_bytes },
1809 	{ AIM_ONLINEBUDDY_SESSIONLEN,	 "Session Length (sec)", dissect_aim_tlv_value_uint32 },
1810 	{ AIM_ONLINEBUDDY_ICQSESSIONLEN, "ICQ Session Length (sec)", dissect_aim_tlv_value_uint32 },
1811 	{ AIM_ONLINEBUDDY_MYINSTANCENUM, "Client instance number", dissect_aim_tlv_value_uint8 },
1812 	{ AIM_ONLINEBUDDY_SHORTCAPS,	 "Short Capabilities", dissect_aim_tlv_value_client_short_capabilities },
1813 	{ AIM_ONLINEBUDDY_BARTINFO,	 "BART Info", dissect_aim_tlv_value_bytes },
1814 	{ AIM_ONLINEBUDDY_NICKFLAGS2,	 "Upper bytes of Nick Flags", dissect_aim_tlv_value_bytes },
1815 	{ AIM_ONLINEBUDDY_BUDDYFEEDTIME, "Last Buddy Feed update", dissect_aim_tlv_value_time },
1816 	{ AIM_ONLINEBUDDY_SIGTIME,	 "Profile set time", dissect_aim_tlv_value_time },
1817 	{ AIM_ONLINEBUDDY_AWAYTIME,	 "Away set time", dissect_aim_tlv_value_time },
1818 	{ AIM_ONLINEBUDDY_GEOCOUNTRY,	 "Country code", dissect_aim_tlv_value_string },
1819 	{ 0, NULL, NULL }
1820 };
1821 
1822 #define AIM_BUDDYLIST_TLV_MAX_CONTACT_ENTRIES 		0x0001
1823 #define AIM_BUDDYLIST_TLV_MAX_WATCHER_ENTRIES 		0x0002
1824 #define AIM_BUDDYLIST_TLV_MAX_ONLINE_NOTIFICATIONS 	0x0003
1825 
1826 static const aim_tlv aim_buddylist_tlvs[] = {
1827 	{ AIM_BUDDYLIST_TLV_MAX_CONTACT_ENTRIES, "Max number of contact list entries", dissect_aim_tlv_value_uint16 },
1828 	{ AIM_BUDDYLIST_TLV_MAX_WATCHER_ENTRIES, "Max number of watcher list entries", dissect_aim_tlv_value_uint16 },
1829 	{ AIM_BUDDYLIST_TLV_MAX_ONLINE_NOTIFICATIONS, "Max online notifications", dissect_aim_tlv_value_uint16 },
1830 	{0, NULL, NULL }
1831 };
1832 
1833 static int
1834 dissect_aim_userinfo(tvbuff_t *tvb, packet_info *pinfo,
1835 		     int offset, proto_tree *tree)
1836 {
1837 	offset = dissect_aim_buddyname(tvb, pinfo, offset, tree);
1838 
1839 	proto_tree_add_item(tree, hf_aim_userinfo_warninglevel, tvb, offset, 2, ENC_BIG_ENDIAN);
1840 	offset += 2;
1841 
1842 	return dissect_aim_tlv_list(tvb, pinfo, offset, tree, aim_onlinebuddy_tlvs);
1843 }
1844 
1845 /* Initialize the protocol and registered fields */
1846 
1847 static int dissect_aim_buddylist_buddylist(tvbuff_t *tvb, packet_info *pinfo, proto_tree *buddy_tree)
1848 {
1849 	int offset = 0;
1850 	while (tvb_reported_length_remaining(tvb, offset) > 0) {
1851 		offset = dissect_aim_buddyname( tvb, pinfo, offset, buddy_tree);
1852 	}
1853 	return offset;
1854 }
1855 
1856 static int dissect_aim_buddylist_rights_repl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *buddy_tree)
1857 {
1858 	return dissect_aim_tlv_sequence(tvb, pinfo, 0, buddy_tree, aim_buddylist_tlvs);
1859 }
1860 
1861 static int dissect_aim_buddylist_reject(tvbuff_t *tvb, packet_info *pinfo, proto_tree *buddy_tree)
1862 {
1863 	return dissect_aim_buddyname(tvb, pinfo, 0, buddy_tree);
1864 }
1865 
1866 static int dissect_aim_buddylist_oncoming(tvbuff_t *tvb, packet_info *pinfo, proto_tree *buddy_tree)
1867 {
1868 	guint8 *buddyname;
1869 	int    offset           = 0;
1870 	int    buddyname_length = aim_get_buddyname( pinfo->pool, &buddyname, tvb, offset );
1871 
1872 	col_set_str(pinfo->cinfo, COL_INFO, "Oncoming Buddy");
1873 	col_append_fstr(pinfo->cinfo, COL_INFO, ": %s",
1874 					format_text(pinfo->pool, buddyname, buddyname_length));
1875 
1876 	offset += dissect_aim_buddyname(tvb, pinfo, offset, buddy_tree);
1877 
1878 	/* Warning level */
1879 	proto_tree_add_item(buddy_tree, hf_aim_buddylist_userinfo_warninglevel, tvb, offset,
1880 						2, ENC_BIG_ENDIAN);
1881 	offset += 2;
1882 
1883 	offset = dissect_aim_tlv_list(tvb, pinfo, offset, buddy_tree, aim_onlinebuddy_tlvs);
1884 
1885 	return offset;
1886 }
1887 
1888 static int dissect_aim_buddylist_offgoing(tvbuff_t *tvb, packet_info *pinfo, proto_tree *buddy_tree)
1889 {
1890 
1891 	guint8 *buddyname;
1892 	int    offset           = 0;
1893 	int    buddyname_length = aim_get_buddyname( pinfo->pool, &buddyname, tvb, offset );
1894 
1895 	col_set_str(pinfo->cinfo, COL_INFO, "Offgoing Buddy");
1896 	col_append_fstr(pinfo->cinfo, COL_INFO, ": %s",
1897 					format_text(pinfo->pool, buddyname, buddyname_length));
1898 
1899 	offset += dissect_aim_buddyname(tvb, pinfo, offset, buddy_tree);
1900 
1901 	/* Warning level */
1902 	proto_tree_add_item(buddy_tree, hf_aim_buddylist_userinfo_warninglevel, tvb, offset,
1903 						2, ENC_BIG_ENDIAN);
1904 	offset += 2;
1905 
1906 	return dissect_aim_tlv_list(tvb, pinfo, offset, buddy_tree, aim_onlinebuddy_tlvs);
1907 }
1908 
1909 static const aim_subtype aim_fnac_family_buddylist[] = {
1910 	{ 0x0001, "Error", dissect_aim_snac_error },
1911 	{ 0x0002, "Rights Request", NULL },
1912 	{ 0x0003, "Rights Reply", dissect_aim_buddylist_rights_repl },
1913 	{ 0x0004, "Add Buddy", dissect_aim_buddylist_buddylist },
1914 	{ 0x0005, "Remove Buddy", dissect_aim_buddylist_buddylist },
1915 	{ 0x0006, "Watchers List Request", NULL },
1916 	{ 0x0007, "Watchers List Reply", dissect_aim_buddylist_buddylist },
1917 	{ 0x000a, "Reject Buddy", dissect_aim_buddylist_reject },
1918 	{ 0x000b, "Oncoming Buddy", dissect_aim_buddylist_oncoming },
1919 	{ 0x000c, "Offgoing Buddy", dissect_aim_buddylist_offgoing },
1920 	{ 0, NULL, NULL }
1921 };
1922 
1923 
1924 /***********************************************************************************************************
1925  * AIM CHAT
1926  ***********************************************************************************************************/
1927 
1928 /* SNAC families */
1929 
1930 #define AIM_CHAT_TLV_BROWSABLE_TREE 		0x001
1931 #define AIM_CHAT_TLV_CLASS_EXCLUSIVE		0x002
1932 #define AIM_CHAT_TLV_MAX_CONCURRENT_ROOMS	0x003
1933 #define AIM_CHAT_TLV_MAX_ROOM_NAME_LEN		0x004
1934 #define AIM_CHAT_TLV_ROOT_ROOMS			0x005
1935 #define AIM_CHAT_TLV_SEARCH_TAGS		0x006
1936 #define AIM_CHAT_TLV_CHILD_ROOMS		0x065
1937 #define AIM_CHAT_TLV_CONTAINS_USER_CLASS	0x066
1938 #define AIM_CHAT_TLV_CONTAINS_USER_ARRAY	0x067
1939 
1940 #if 0
1941 static const aim_tlv aim_chat_tlvs[] _U_ = {
1942 	{ AIM_CHAT_TLV_BROWSABLE_TREE,	     "Browsable tree",			dissect_aim_tlv_value_bytes },
1943 	{ AIM_CHAT_TLV_CLASS_EXCLUSIVE,	     "Exclusively for class",		dissect_aim_tlv_value_userclass },
1944 	{ AIM_CHAT_TLV_MAX_CONCURRENT_ROOMS, "Max. number of concurrent rooms", dissect_aim_tlv_value_uint8 },
1945 	{ AIM_CHAT_TLV_MAX_ROOM_NAME_LEN,    "Max. length of room name",	dissect_aim_tlv_value_uint8 },
1946 	{ AIM_CHAT_TLV_ROOT_ROOMS,	     "Root Rooms",			dissect_aim_tlv_value_bytes },
1947 	{ AIM_CHAT_TLV_SEARCH_TAGS,	     "Search Tags",			dissect_aim_tlv_value_bytes },
1948 	{ AIM_CHAT_TLV_CHILD_ROOMS,	     "Child Rooms",			dissect_aim_tlv_value_bytes },
1949 	{ AIM_CHAT_TLV_CONTAINS_USER_CLASS,  "Contains User Class",		dissect_aim_tlv_value_bytes },
1950 	{ AIM_CHAT_TLV_CONTAINS_USER_ARRAY,  "Contains User Array",		dissect_aim_tlv_value_bytes },
1951 	{ 0, NULL, NULL }
1952 };
1953 #endif
1954 
1955 
1956 static int dissect_aim_chat_userinfo_list(tvbuff_t *tvb, packet_info *pinfo, proto_tree *chat_tree)
1957 {
1958 	int offset = 0;
1959 	while(tvb_reported_length_remaining(tvb, offset) > 0) {
1960 		offset = dissect_aim_userinfo(tvb, pinfo, offset, chat_tree);
1961 	}
1962 	return offset;
1963 }
1964 
1965 static int dissect_aim_chat_outgoing_msg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *chat_tree _U_)
1966 {
1967 	guint8 *buddyname;
1968 	guchar *msg;
1969 	int buddyname_length;
1970 
1971 	msg=(guchar *)wmem_alloc(pinfo->pool, 1000);
1972 	buddyname_length = aim_get_buddyname( pinfo->pool, &buddyname, tvb, 30 );
1973 
1974 	/* channel message from client */
1975 	aim_get_message( msg, tvb, 40 + buddyname_length, tvb_reported_length(tvb)
1976 					 - 40 - buddyname_length );
1977 
1978 	col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s", msg);
1979 
1980 	return tvb_reported_length(tvb);
1981 }
1982 
1983 
1984 static int dissect_aim_chat_incoming_msg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *chat_tree)
1985 {
1986 	guint8 *buddyname;
1987 	guchar *msg;
1988 	/* channel message to client */
1989 	int buddyname_length;
1990 
1991 	msg=(guchar *)wmem_alloc(pinfo->pool, 1000);
1992 	buddyname_length = aim_get_buddyname( pinfo->pool, &buddyname, tvb, 30 );
1993 
1994 	aim_get_message( msg, tvb, 36 + buddyname_length, tvb_reported_length(tvb)
1995 					 - 36 - buddyname_length );
1996 
1997 	col_append_fstr(pinfo->cinfo, COL_INFO, "from: %s", buddyname);
1998 	col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s", msg);
1999 
2000 	proto_tree_add_string(chat_tree, hf_aim_chat_screen_name, tvb, 31, buddyname_length, buddyname);
2001 
2002 	return tvb_reported_length(tvb);
2003 }
2004 
2005 static const aim_subtype aim_fnac_family_chat[] = {
2006 	{ 0x0001, "Error",	      dissect_aim_snac_error },
2007 	{ 0x0002, "Room Info Update", NULL },
2008 	{ 0x0003, "User Join",	      dissect_aim_chat_userinfo_list },
2009 	{ 0x0004, "User Leave",	      dissect_aim_chat_userinfo_list },
2010 	{ 0x0005, "Outgoing Message", dissect_aim_chat_outgoing_msg },
2011 	{ 0x0006, "Incoming Message", dissect_aim_chat_incoming_msg },
2012 	{ 0x0007, "Evil Request",     NULL },
2013 	{ 0x0008, "Evil Reply",       NULL },
2014 	{ 0, NULL, NULL }
2015 };
2016 
2017 /***********************************************************************************************************
2018  * AIM CHATNAV
2019  ***********************************************************************************************************/
2020 
2021 static const aim_subtype aim_fnac_family_chatnav[] = {
2022 	{ 0x0001, "Error", dissect_aim_snac_error },
2023 	{ 0x0002, "Request Limits", NULL },
2024 	{ 0x0003, "Request Exchange", NULL },
2025 	{ 0x0004, "Request Room Information", NULL },
2026 	{ 0x0005, "Request Extended Room Information", NULL },
2027 	{ 0x0006, "Request Member List", NULL },
2028 	{ 0x0007, "Search Room", NULL },
2029 	{ 0x0008, "Create", NULL },
2030 	{ 0x0009, "Info", NULL },
2031 	{ 0, NULL, NULL }
2032 };
2033 
2034 
2035 /***********************************************************************************************************
2036  * AIM DIRECTORY
2037  ***********************************************************************************************************/
2038 static int dissect_aim_directory_user_repl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2039 {
2040 	int offset = 0;
2041 	while (tvb_reported_length_remaining(tvb, offset) > 0) {
2042 		offset = dissect_aim_tlv(tvb, pinfo, offset, tree, aim_client_tlvs);
2043 	}
2044 	return offset;
2045 }
2046 
2047 static const aim_subtype aim_fnac_family_directory[] = {
2048 	{ 0x0001, "Error", dissect_aim_snac_error },
2049 	{ 0x0002, "Client search for user request", NULL },
2050 	{ 0x0003, "Server reply for search request (found users)", dissect_aim_directory_user_repl },
2051 	{ 0x0004, "Request interests list from server", NULL },
2052 	{ 0x0005, "Interests list", NULL },
2053 	{ 0, NULL, NULL },
2054 };
2055 
2056 
2057 /***********************************************************************************************************
2058  * AIM EMAIL
2059  ***********************************************************************************************************/
2060 static const aim_subtype aim_fnac_family_email[] = {
2061 	{ 0x0006, "Email Status Request", NULL },
2062 	{ 0x0007, "Email Status Reply", NULL },
2063 	{ 0x0016, "Activate Email", NULL },
2064 	{ 0, NULL, NULL }
2065 };
2066 
2067 /***********************************************************************************************************
2068  * AIM GENERIC
2069  ***********************************************************************************************************/
2070 #define STRIP_TAGS 1
2071 
2072 
2073 
2074 #define FAMILY_GENERIC_MOTD_MOTDTYPE_MDT_UPGRADE       0x0001
2075 #define FAMILY_GENERIC_MOTD_MOTDTYPE_ADV_UPGRADE       0x0002
2076 #define FAMILY_GENERIC_MOTD_MOTDTYPE_SYS_BULLETIN      0x0003
2077 #define FAMILY_GENERIC_MOTD_MOTDTYPE_NORMAL            0x0004
2078 #define FAMILY_GENERIC_MOTD_MOTDTYPE_NEWS              0x0006
2079 
2080 static const value_string aim_snac_generic_motd_motdtypes[] = {
2081 	{ FAMILY_GENERIC_MOTD_MOTDTYPE_MDT_UPGRADE,  "Mandatory Upgrade Needed Notice" },
2082 	{ FAMILY_GENERIC_MOTD_MOTDTYPE_ADV_UPGRADE,  "Advisable Upgrade Notice" },
2083 	{ FAMILY_GENERIC_MOTD_MOTDTYPE_SYS_BULLETIN, "AIM/ICQ Service System Announcements" },
2084 	{ FAMILY_GENERIC_MOTD_MOTDTYPE_NORMAL,       "Standard Notice" },
2085 	{ FAMILY_GENERIC_MOTD_MOTDTYPE_NEWS,         "News from AOL service" },
2086 	{ 0, NULL }
2087 };
2088 
2089 #define RATEINFO_STATE_LIMITED          0x01
2090 #define RATEINFO_STATE_ALERT            0x02
2091 #define RATEINFO_STATE_CLEAR            0x03
2092 
2093 static const value_string rateinfo_states[] = {
2094 	{ RATEINFO_STATE_LIMITED, "Limited" },
2095 	{ RATEINFO_STATE_ALERT,   "Alert" },
2096 	{ RATEINFO_STATE_CLEAR,   "Clear" },
2097 	{ 0, NULL }
2098 };
2099 
2100 #define RATECHANGE_MSG_LIMIT_PARAMS_CHANGED      0x0001
2101 #define RATECHANGE_MSG_LIMIT_WARN                0x0002
2102 #define RATECHANGE_MSG_LIMIT_HIT                 0x0003
2103 #define RATECHANGE_MSG_LIMIT_CLEAR               0x0004
2104 
2105 static const value_string ratechange_msgs[] = {
2106 	{ RATECHANGE_MSG_LIMIT_PARAMS_CHANGED, "Rate limits parameters changed" },
2107 	{ RATECHANGE_MSG_LIMIT_WARN,           "Rate limits warning (current level < alert level)" },
2108 	{ RATECHANGE_MSG_LIMIT_HIT,            "Rate limit hit (current level < limit level)" },
2109 	{ RATECHANGE_MSG_LIMIT_CLEAR,          "Rate limit clear (current level now > clear level)" },
2110 	{ 0, NULL },
2111 };
2112 
2113 #define EXT_STATUS_TYPE_BUDDY_ICON_0 0
2114 #define EXT_STATUS_TYPE_BUDDY_ICON_1 1
2115 #define EXT_STATUS_TYPE_AVAIL_MSG    2
2116 #define EXT_STATUS_TYPE_UNKNOWN      6
2117 
2118 static const value_string ext_status_types[] = {
2119 	{ EXT_STATUS_TYPE_BUDDY_ICON_0, "Request to send buddy icon" },
2120 	{ EXT_STATUS_TYPE_BUDDY_ICON_1, "Request to send buddy icon" },
2121 	{ EXT_STATUS_TYPE_AVAIL_MSG,    "Extended Status Update" },
2122 	{ 0, NULL },
2123 };
2124 
2125 #define EXT_STATUS_FLAG_INITIAL_SEND    0x41
2126 #define EXT_STATUS_FLAG_RESEND      0x81
2127 
2128 static const value_string ext_status_flags[] = {
2129 	{ EXT_STATUS_FLAG_INITIAL_SEND, "First Send Request" },
2130 	{ EXT_STATUS_FLAG_RESEND,       "Request To Re-Send" },
2131 	{ 0, NULL },
2132 };
2133 
2134 static int dissect_rate_class(tvbuff_t *tvb, packet_info *pinfo _U_, int offset, proto_tree *class_tree)
2135 {
2136 	proto_tree_add_item(class_tree, hf_generic_rateinfo_classid, tvb, offset, 2, ENC_BIG_ENDIAN);offset+=2;
2137 	proto_tree_add_item(class_tree, hf_generic_rateinfo_windowsize, tvb, offset, 4, ENC_BIG_ENDIAN);offset+=4;
2138 	proto_tree_add_item(class_tree, hf_generic_rateinfo_clearlevel, tvb, offset, 4, ENC_BIG_ENDIAN);offset+=4;
2139 	proto_tree_add_item(class_tree, hf_generic_rateinfo_alertlevel, tvb, offset, 4, ENC_BIG_ENDIAN);offset+=4;
2140 	proto_tree_add_item(class_tree, hf_generic_rateinfo_limitlevel, tvb, offset, 4, ENC_BIG_ENDIAN);offset+=4;
2141 	proto_tree_add_item(class_tree, hf_generic_rateinfo_disconnectlevel, tvb, offset, 4, ENC_BIG_ENDIAN);offset+=4;
2142 	proto_tree_add_item(class_tree, hf_generic_rateinfo_currentlevel, tvb, offset, 4, ENC_BIG_ENDIAN);offset+=4;
2143 	proto_tree_add_item(class_tree, hf_generic_rateinfo_maxlevel, tvb, offset, 4, ENC_BIG_ENDIAN);offset+=4;
2144 	proto_tree_add_item(class_tree, hf_generic_rateinfo_lasttime, tvb, offset, 4, ENC_BIG_ENDIAN);offset+=4;
2145 	proto_tree_add_item(class_tree, hf_generic_rateinfo_curstate, tvb, offset, 1, ENC_BIG_ENDIAN);offset+=1;
2146 	return offset;
2147 }
2148 
2149 static int dissect_generic_rateinfo(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2150 {
2151 	int offset = 0;
2152 	guint16 i;
2153 	guint16 numclasses = tvb_get_ntohs(tvb, 0);
2154 	proto_tree *classes_tree = NULL, *groups_tree, *group_tree;
2155 	proto_tree_add_uint(tree, hf_generic_rateinfo_numclasses, tvb, 0, 2, numclasses );
2156 	offset+=2;
2157 
2158 	if(tree) {
2159 		/* sizeof(rate_class_struct) = 35 ! */
2160 		classes_tree = proto_tree_add_subtree(tree, tvb, offset, 35 * numclasses,
2161 								ett_generic_rateinfo_classes, NULL, "Available Rate Classes");
2162 	}
2163 
2164 	for(i = 0; i < numclasses; i++) {
2165 		guint16 myid = tvb_get_ntohs(tvb, offset);
2166 		proto_tree *class_tree = proto_tree_add_subtree_format(classes_tree, tvb, offset, 35,
2167 		                ett_generic_rateinfo_class, NULL, "Rate Class 0x%02x", myid);
2168 		offset = dissect_rate_class(tvb, pinfo, offset, class_tree);
2169 	}
2170 
2171 	groups_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_generic_rateinfo_groups, NULL, "Rate Groups");
2172 
2173 	for(i = 0; i < numclasses; i++) {
2174 		guint16 j;
2175 		guint16 myid = tvb_get_ntohs(tvb, offset);
2176 		guint16 numpairs = tvb_get_ntohs(tvb, offset + 2);
2177 		/*
2178 		 * sizeof(rate_group) = sizeof(class_id) + sizeof(numpairs) + numpairs * 2 * sizeof(uint16_t)
2179 		 *                    = 2 + 2 + numpairs * 4
2180 		 */
2181 		group_tree = proto_tree_add_subtree_format(groups_tree, tvb, offset, 4 + 4 * numpairs,
2182 		                            ett_generic_rateinfo_group, NULL, "Rate Group 0x%02x", myid);
2183 		proto_tree_add_uint(group_tree, hf_generic_rateinfo_classid, tvb, offset, 2, myid);offset+=2;
2184 		proto_tree_add_uint(group_tree, hf_generic_rateinfo_numpairs, tvb, offset, 2, numpairs); offset+=2;
2185 		for(j = 0; j < numpairs; j++) {
2186 			guint16 family_id;
2187 			guint16 subtype_id;
2188 			const aim_family *family;
2189 			const aim_subtype *subtype;
2190 			family_id = tvb_get_ntohs(tvb, offset);
2191 			subtype_id = tvb_get_ntohs(tvb, offset+2);
2192 
2193 			family = aim_get_family(family_id);
2194 			subtype = aim_get_subtype(family_id, subtype_id);
2195 
2196 			proto_tree_add_uint_format_value(group_tree, hf_generic_family, tvb, offset, 4, family_id,
2197 			            "%s (0x%04x), Subtype: %s (0x%04x)", family?family->name:"Unknown", family_id, subtype?subtype->name:"Unknown", subtype_id);
2198 			offset+=4;
2199 		}
2200 	}
2201 
2202 	return offset;
2203 }
2204 
2205 static int dissect_aim_generic_clientready(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *gen_tree)
2206 {
2207 	int offset = 0;
2208 	proto_tree *entry = proto_tree_add_subtree(gen_tree, tvb, 0, -1, ett_generic_clientready, NULL, "Supported services");
2209 
2210 	while(tvb_reported_length_remaining(tvb, offset) > 0) {
2211 		proto_item *ti;
2212 		proto_tree *subtree;
2213 
2214 		ti = proto_tree_add_item(entry, hf_generic_family, tvb, offset, 2, ENC_BIG_ENDIAN);
2215 		subtree = proto_item_add_subtree(ti, ett_generic_clientready_item);
2216 		offset+=2;
2217 
2218 		proto_tree_add_item(subtree, hf_generic_version, tvb, offset, 2, ENC_BIG_ENDIAN);
2219 		offset += 2;
2220 		proto_tree_add_item(subtree, hf_generic_dll_version, tvb, offset, 3, ENC_BIG_ENDIAN);
2221 		/* Padding byte? */
2222 		offset += 4;
2223 		proto_item_set_len(ti, 8);
2224 	}
2225 	return offset;
2226 }
2227 
2228 
2229 static int dissect_aim_generic_serverready(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *gen_tree)
2230 {
2231 	int offset = 0;
2232 	proto_tree *entry = proto_tree_add_subtree(gen_tree, tvb, offset, -1, ett_generic_clientready, NULL, "Supported services");
2233 
2234 	while(tvb_reported_length_remaining(tvb, offset) > 0) {
2235 		proto_tree_add_item(entry, hf_generic_family, tvb, offset, 2, ENC_BIG_ENDIAN);
2236 		offset+=2;
2237 	}
2238 	return offset;
2239 }
2240 
2241 
2242 static int dissect_aim_generic_service_req(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *gen_tree)
2243 {
2244 	int offset = 0;
2245 	const aim_family *family = aim_get_family( tvb_get_ntohs(tvb, offset) );
2246 
2247 	proto_tree_add_uint_format(gen_tree, hf_generic_servicereq_service, tvb, offset, 2, tvb_get_ntohs(tvb, offset), "%s (0x%04x)", family?family->name:"Unknown", tvb_get_ntohs(tvb, offset) );
2248 	offset+=2;
2249 	return offset;
2250 }
2251 
2252 static int dissect_aim_generic_redirect(tvbuff_t *tvb, packet_info *pinfo, proto_tree *gen_tree)
2253 {
2254 	return dissect_aim_tlv_sequence(tvb, pinfo, 0, gen_tree, aim_client_tlvs);
2255 }
2256 
2257 static int dissect_aim_generic_capabilities(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *gen_tree)
2258 {
2259 	int offset = 0;
2260 	proto_tree *entry = proto_tree_add_subtree(gen_tree, tvb, offset, -1, ett_generic_clientready, NULL, "Requested services");
2261 
2262 	while(tvb_reported_length_remaining(tvb, offset) > 0) {
2263 		proto_tree_add_item(entry, hf_generic_family, tvb, offset, 2, ENC_BIG_ENDIAN);
2264 		offset+=2;
2265 		proto_tree_add_item(entry, hf_generic_version, tvb, offset, 2, ENC_BIG_ENDIAN);
2266 		offset+=2;
2267 	}
2268 	return offset;
2269 }
2270 
2271 static int dissect_aim_generic_capack(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *gen_tree)
2272 {
2273 	int offset = 0;
2274 	proto_tree *entry = proto_tree_add_subtree(gen_tree, tvb, offset, -1, ett_generic_clientready, NULL, "Accepted requested services");
2275 
2276 	while(tvb_reported_length_remaining(tvb, offset) > 0) {
2277 		proto_tree_add_item(entry, hf_generic_family, tvb, offset, 2, ENC_BIG_ENDIAN);
2278 		offset+=2;
2279 		proto_tree_add_item(entry, hf_generic_version, tvb, offset, 2, ENC_BIG_ENDIAN);
2280 		offset+=2;
2281 	}
2282 	return offset;
2283 }
2284 
2285 #define AIM_MOTD_TLV_MOTD					   0x000B
2286 
2287 static const aim_tlv aim_motd_tlvs[] = {
2288 	{ AIM_MOTD_TLV_MOTD, "Message of the day message", dissect_aim_tlv_value_string },
2289 	{ 0, NULL, NULL }
2290 };
2291 
2292 static int dissect_aim_generic_motd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *gen_tree)
2293 {
2294 	int offset = 0;
2295 	proto_tree_add_item(gen_tree, hf_generic_motd_motdtype, tvb, offset,
2296 	                    2, tvb_get_ntohs(tvb, offset));
2297 	offset+=2;
2298 	return dissect_aim_tlv_sequence(tvb, pinfo, offset, gen_tree, aim_motd_tlvs);
2299 }
2300 
2301 static int dissect_aim_generic_rateinfoack(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *gen_tree)
2302 {
2303 	int offset = 0;
2304 	while(tvb_reported_length_remaining(tvb, offset) > 0) {
2305 		proto_tree_add_item(gen_tree, hf_generic_rateinfoack_group, tvb, offset, 2, ENC_BIG_ENDIAN);
2306 		offset+=2;
2307 	}
2308 	return offset;
2309 }
2310 
2311 static int dissect_aim_generic_ratechange(tvbuff_t *tvb, packet_info *pinfo, proto_tree *gen_tree)
2312 {
2313 	int offset = 0;
2314 	proto_tree_add_item(gen_tree, hf_generic_ratechange_msg, tvb, offset, 2, ENC_BIG_ENDIAN);
2315 	offset+=2;
2316 	offset = dissect_rate_class(tvb, pinfo, offset, gen_tree);
2317 	return offset;
2318 }
2319 
2320 
2321 static int dissect_aim_generic_clientpauseack(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *gen_tree)
2322 {
2323 	int offset = 0;
2324 	while(tvb_reported_length_remaining(tvb, offset) > 0) {
2325 		proto_tree_add_item(gen_tree, hf_generic_family, tvb, offset, 2, ENC_BIG_ENDIAN);
2326 		offset += 2;
2327 	}
2328 	return offset;
2329 }
2330 
2331 static int dissect_aim_generic_migration_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *gen_tree)
2332 {
2333 	int offset = 0;
2334 	guint32 n, i;
2335 	proto_tree *entry;
2336 
2337 	n = tvb_get_ntohs(tvb, offset);offset+=2;
2338 	proto_tree_add_uint(gen_tree, hf_generic_migration_numfams, tvb, offset, 2, n);
2339 	entry = proto_tree_add_subtree(gen_tree, tvb, offset, 2 * n,
2340 	        ett_generic_migratefamilies, NULL, "Families to migrate");
2341 	for(i = 0; i < n; i++) {
2342 		proto_tree_add_item(entry, hf_generic_family, tvb, offset, 2, ENC_BIG_ENDIAN);
2343 		offset += 2;
2344 	}
2345 
2346 	return dissect_aim_tlv_sequence(tvb, pinfo, offset, gen_tree, aim_client_tlvs);
2347 }
2348 
2349 static int dissect_aim_generic_setprivflags(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *gen_tree)
2350 {
2351 	static int * const flags[] = {
2352 		&hf_generic_allow_idle_see,
2353 		&hf_generic_allow_member_see,
2354 		NULL
2355 	};
2356 
2357 	proto_tree_add_bitmask(gen_tree, tvb, 0, hf_generic_priv_flags, ett_generic_priv_flags, flags, ENC_BIG_ENDIAN);
2358 	return 4;
2359 }
2360 
2361 static int dissect_aim_generic_selfinfo_repl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *gen_tree)
2362 {
2363 	int offset = dissect_aim_buddyname(tvb, pinfo, 0, gen_tree);
2364 	proto_tree_add_item(gen_tree, hf_generic_selfinfo_warninglevel, tvb, offset, 2, ENC_BIG_ENDIAN);
2365 	offset += 2;
2366 	return dissect_aim_tlv_list(tvb, pinfo, offset, gen_tree, aim_onlinebuddy_tlvs);
2367 }
2368 
2369 static int dissect_aim_generic_evil(tvbuff_t *tvb, packet_info *pinfo, proto_tree *gen_tree)
2370 {
2371 	int offset = 0;
2372 	proto_tree_add_item(gen_tree, hf_generic_evil_new_warn_level, tvb, offset, 2, ENC_BIG_ENDIAN);
2373 	while(tvb_reported_length_remaining(tvb, offset) > 0) {
2374 		offset = dissect_aim_userinfo(tvb, pinfo, offset, gen_tree);
2375 	}
2376 	return offset;
2377 }
2378 
2379 static int dissect_aim_generic_setidle(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *gen_tree)
2380 {
2381 	proto_tree_add_item(gen_tree, hf_generic_idle_time, tvb, 0, 2, ENC_BIG_ENDIAN);
2382 	return 2;
2383 }
2384 
2385 static int dissect_aim_generic_ext_status_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *gen_tree)
2386 {
2387 	return dissect_aim_tlv_sequence(tvb, pinfo, 0, gen_tree, aim_onlinebuddy_tlvs);
2388 }
2389 
2390 static int dissect_aim_generic_clientver_req(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *gen_tree)
2391 {
2392 	int offset = 0;
2393 	proto_tree_add_item(gen_tree, hf_generic_client_ver_req_offset, tvb, offset, 4, ENC_BIG_ENDIAN);
2394 	offset+=4;
2395 	proto_tree_add_item(gen_tree, hf_generic_client_ver_req_length, tvb, offset, 4, ENC_BIG_ENDIAN);
2396 	return offset+4;
2397 }
2398 
2399 static int dissect_aim_generic_clientver_repl(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *gen_tree)
2400 {
2401 	proto_tree_add_item(gen_tree, hf_generic_client_ver_req_hash, tvb, 0, 16, ENC_NA);
2402 	return 16;
2403 }
2404 
2405 static int dissect_aim_generic_ext_status_repl(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *gen_tree)
2406 {
2407 	guint8 length;
2408 	int offset = 0;
2409 	proto_tree_add_item(gen_tree, hf_generic_ext_status_type, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2;
2410 	proto_tree_add_item(gen_tree, hf_generic_ext_status_flags, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1;
2411 	proto_tree_add_item(gen_tree, hf_generic_ext_status_length, tvb, offset, 1, ENC_BIG_ENDIAN); length = tvb_get_guint8(tvb, offset); offset += 1;
2412 	proto_tree_add_item(gen_tree, hf_generic_ext_status_data, tvb, offset, length, ENC_NA); offset += 1;
2413 	return offset;
2414 }
2415 
2416 static void
2417 aim_generic_family( gchar *result, guint32 famnum )
2418 {
2419 	const aim_family *family = aim_get_family(famnum);
2420 
2421 	g_snprintf( result, ITEM_LABEL_LENGTH, "%s (0x%x)", family?family->name:"Unknown", famnum);
2422 }
2423 
2424 static const aim_subtype aim_fnac_family_generic[] = {
2425 	{ 0x0001, "Error", dissect_aim_snac_error },
2426 	{ 0x0002, "Client Ready", dissect_aim_generic_clientready },
2427 	{ 0x0003, "Server Ready", dissect_aim_generic_serverready  },
2428 	{ 0x0004, "Service Request", dissect_aim_generic_service_req },
2429 	{ 0x0005, "Redirect", dissect_aim_generic_redirect },
2430 	{ 0x0006, "Rate Info Request", NULL},
2431 	{ 0x0007, "Rate Info", dissect_generic_rateinfo },
2432 	{ 0x0008, "Rate Info Ack", dissect_aim_generic_rateinfoack },
2433 	{ 0x000a, "Rate Change", dissect_aim_generic_ratechange },
2434 	{ 0x000b, "Server Pause", NULL },
2435 	{ 0x000c, "Client Pause Ack", dissect_aim_generic_clientpauseack },
2436 	{ 0x000d, "Server Resume", NULL },
2437 	{ 0x000e, "Self Info Request", NULL },
2438 	{ 0x000f, "Self Info Reply", dissect_aim_generic_selfinfo_repl },
2439 	{ 0x0010, "Evil", dissect_aim_generic_evil },
2440 	{ 0x0011, "Set Idle", dissect_aim_generic_setidle },
2441 	{ 0x0012, "Migration Request", dissect_aim_generic_migration_req },
2442 	{ 0x0013, "Message Of The Day", dissect_aim_generic_motd },
2443 	{ 0x0014, "Set Privilege Flags", dissect_aim_generic_setprivflags },
2444 	{ 0x0015, "Well Known URL", NULL }, /* FIXME */
2445 	{ 0x0016, "noop", NULL },
2446 	{ 0x0017, "Capabilities",  dissect_aim_generic_capabilities },
2447 	{ 0x0018, "Capabilities Ack", dissect_aim_generic_capack },
2448 	{ 0x001e, "Set Extended Status Request", dissect_aim_generic_ext_status_req },
2449 	{ 0x001f, "Client Verification Request",  dissect_aim_generic_clientver_req },
2450 	{ 0x0020, "Client Verification Reply", dissect_aim_generic_clientver_repl },
2451 	{ 0x0021, "Set Extended Status Reply", dissect_aim_generic_ext_status_repl },
2452 	{ 0, NULL, NULL }
2453 };
2454 
2455 /***********************************************************************************************************
2456  * AIM ICQ
2457  ***********************************************************************************************************/
2458 #define ICQ_CLI_OFFLINE_MESSAGE_REQ 	0x003c
2459 #define ICQ_CLI_DELETE_OFFLINE_MSGS	0x003e
2460 #define ICQ_SRV_OFFLINE_MSGS		0x0041
2461 #define ICQ_SRV_END_OF_OFFLINE_MSGS	0x0042
2462 #define ICQ_CLI_META_INFO_REQ		0x07d0
2463 #define ICQ_SRV_META_INFO_REPL		0x07da
2464 
2465 static const value_string aim_icq_data_types[] = {
2466 	{ ICQ_CLI_OFFLINE_MESSAGE_REQ, "Offline Message Request" },
2467 	{ ICQ_SRV_OFFLINE_MSGS,        "Offline Messages Reply" },
2468 	{ ICQ_SRV_END_OF_OFFLINE_MSGS, "End Of Offline Messages Reply" },
2469 	{ ICQ_CLI_DELETE_OFFLINE_MSGS, "Delete Offline Messages Request" },
2470 	{ ICQ_CLI_META_INFO_REQ,       "Metainfo Request" },
2471 	{ ICQ_SRV_META_INFO_REPL,      "Metainfo Reply" },
2472 	{ 0, NULL }
2473 };
2474 
2475 
2476 static int dissect_aim_tlv_value_icq(proto_item *ti, guint16 subtype, tvbuff_t *tvb, packet_info *pinfo);
2477 
2478 #define TLV_ICQ_META_DATA 			  0x0001
2479 
2480 static const aim_tlv icq_tlv[] = {
2481 	{ TLV_ICQ_META_DATA, "Encapsulated ICQ Meta Data", dissect_aim_tlv_value_icq },
2482 	{ 0, NULL, NULL },
2483 };
2484 
2485 
2486 static struct
2487 {
2488 	guint16 subtype;
2489 	const char *name;
2490 	int (*dissector) (tvbuff_t *, packet_info *, proto_tree *);
2491 } icq_calls [] = {
2492 	{ 0x0001, "Server Error Reply",			  NULL },
2493 	{ 0x0064, "Set User Home Info Reply",		  NULL },
2494 	{ 0x006e, "Set User Work Info Reply",		  NULL },
2495 	{ 0x0078, "Set User More Info Reply",		  NULL },
2496 	{ 0x0082, "Set User Notes Info Reply",		  NULL },
2497 	{ 0x0087, "Set User Email Info Reply",		  NULL },
2498 	{ 0x008c, "Set User Interests Info Reply",	  NULL },
2499 	{ 0x0096, "Set User Affiliations Info Reply",	  NULL },
2500 	{ 0x00a0, "Set User Permissions Reply",		  NULL },
2501 	{ 0x00aa, "Set User Password Reply",		  NULL },
2502 	{ 0x00b4, "Unregister Account Reply",		  NULL },
2503 	{ 0x00be, "Set User Homepage Category Reply",	  NULL },
2504 	{ 0x00c8, "User Basic Info Reply",		  NULL },
2505 	{ 0x00d2, "User Work Info Reply",		  NULL },
2506 	{ 0x00dc, "User More Info Reply",		  NULL },
2507 	{ 0x00e6, "User Notes Info Reply",		  NULL },
2508 	{ 0x00eb, "User Extended Email Reply",		  NULL },
2509 	{ 0x00f0, "User Interests Info Reply",		  NULL },
2510 	{ 0x00fa, "User Affiliations Info Reply",	  NULL },
2511 	{ 0x0104, "Short User Info Reply",		  NULL },
2512 	{ 0x010e, "User Homepage Category Reply",	  NULL },
2513 	{ 0x01a4, "Search: User found",			  NULL },
2514 	{ 0x0302, "Registration Stats Reply",		  NULL },
2515 	{ 0x0366, "Random Search Server Reply",		  NULL },
2516 	{ 0x03ea, "Set User Home Info Request",		  NULL },
2517 	{ 0x03f3, "Set User Work Info Request",		  NULL },
2518 	{ 0x03fd, "Set User More Info Request",		  NULL },
2519 	{ 0x0406, "Set User Notes Request",		  NULL },
2520 	{ 0x040b, "Set User Extended Email Info Request", NULL },
2521 	{ 0x0410, "Set User Interests Info Request",	  NULL },
2522 	{ 0x041a, "Set User Affiliations Info Request",	  NULL },
2523 	{ 0x0424, "Set User Permissions Info Request",	  NULL },
2524 	{ 0x042e, "Change User Password Request",	  NULL },
2525 	{ 0x0442, "Set User Homepage Category Request",	  NULL },
2526 	{ 0x04b2, "Fullinfo Request",			  NULL },
2527 	{ 0x04ba, "Short User Info Request",		  NULL },
2528 	{ 0x04c4, "Unregister User Request",		  NULL },
2529 	{ 0x0515, "Search By Details Request",		  NULL },
2530 	{ 0x0569, "Search By UIN Request",		  NULL },
2531 	{ 0x055f, "Whitepages Search Request",		  NULL },
2532 	{ 0x0573, "Search By Email Request",		  NULL },
2533 	{ 0x074e, "Random Chat User Search Request",	  NULL },
2534 	{ 0x0898, "Server Variable Request (XML)",	  NULL },
2535 	{ 0x0aa5, "Registration Report Request",	  NULL },
2536 	{ 0x0aaf, "Shortcut Bar Stats Report Request",	  NULL },
2537 	{ 0x0c3a, "Save Info Request",			  NULL },
2538 	{ 0x1482, "Send SMS Request",			  NULL },
2539 	{ 0x2008, "Spam Report Request",		  NULL },
2540 	{ 0x08a2, "Server Variable Reply (XML)",	  NULL },
2541 	{ 0x0c3f, "Set Fullinfo Reply",			  NULL },
2542 	{ 0x2012, "User Spam Report Reply",		  NULL },
2543 	{ 0, NULL, NULL },
2544 };
2545 
2546 
2547 static int dissect_aim_tlv_value_icq(proto_item *ti, guint16 subtype _U_, tvbuff_t *tvb, packet_info *pinfo)
2548 {
2549 	int         offset = 0;
2550 	int         i;
2551 	proto_item *subtype_item;
2552 	guint16     req_type, req_subtype;
2553 	proto_tree *t      = proto_item_add_subtree(ti, ett_aim_icq_tlv);
2554 
2555 	proto_tree_add_item(t, hf_icq_tlv_data_chunk_size, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2556 	offset += 2;
2557 
2558 	proto_tree_add_item(t, hf_icq_tlv_request_owner_uid, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2559 	offset += 4;
2560 
2561 	proto_tree_add_item(t, hf_icq_tlv_request_type, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2562 	req_type = tvb_get_letohs(tvb, offset);
2563 	offset += 2;
2564 
2565 	proto_tree_add_item(t, hf_icq_tlv_request_seq_num, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2566 	offset += 2;
2567 
2568 	switch (req_type) {
2569 	case ICQ_CLI_OFFLINE_MESSAGE_REQ: return offset;
2570 	case ICQ_CLI_DELETE_OFFLINE_MSGS: return offset;
2571 	case ICQ_SRV_OFFLINE_MSGS:
2572 		/* FIXME */
2573 		break;
2574 	case ICQ_SRV_END_OF_OFFLINE_MSGS:
2575 		proto_tree_add_item(t, hf_icq_dropped_msg_flag, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2576 		return offset+1;
2577 	case ICQ_CLI_META_INFO_REQ:
2578 	case ICQ_SRV_META_INFO_REPL:
2579 		req_subtype = tvb_get_letohs(tvb, offset);
2580 		subtype_item = proto_tree_add_item(t, hf_icq_meta_subtype, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset+=2;
2581 
2582 		for (i = 0; icq_calls[i].name; i++) {
2583 			if (icq_calls[i].subtype == req_subtype) break;
2584 		}
2585 
2586 		col_set_str(pinfo->cinfo, COL_INFO, icq_calls[i].name?icq_calls[i].name:"Unknown ICQ Meta Call");
2587 
2588 		proto_item_append_text(subtype_item, " (%s)", icq_calls[i].name?icq_calls[i].name:"Unknown");
2589 
2590 		if (icq_calls[i].dissector)
2591 			return icq_calls[i].dissector(tvb_new_subset_remaining(tvb, offset), pinfo, t);
2592 
2593 	default:
2594 		break;
2595 	}
2596 
2597 	return offset;
2598 }
2599 
2600 static int dissect_aim_icq_tlv(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2601 {
2602 	return dissect_aim_tlv(tvb, pinfo, 0, tree, icq_tlv);
2603 }
2604 
2605 static const aim_subtype aim_fnac_family_icq[] = {
2606 	{ 0x0001, "Error",         dissect_aim_snac_error },
2607 	{ 0x0002, "ICQ Request",   dissect_aim_icq_tlv },
2608 	{ 0x0003, "ICQ Response",  dissect_aim_icq_tlv },
2609 	{ 0x0006, "Auth Request",  NULL },
2610 	{ 0x0007, "Auth Response", NULL },
2611 	{ 0, NULL, NULL }
2612 };
2613 
2614 /***********************************************************************************************************
2615  * AIM INVITATION
2616  ***********************************************************************************************************/
2617 static int dissect_aim_invitation_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *invite_tree)
2618 {
2619 	return dissect_aim_tlv_sequence(tvb, pinfo, 0, invite_tree, aim_onlinebuddy_tlvs);
2620 }
2621 
2622 static const aim_subtype aim_fnac_family_invitation[] = {
2623 	{ 0x0001, "Error", dissect_aim_snac_error },
2624 	{ 0x0002, "Invite a friend to join AIM", dissect_aim_invitation_req },
2625 	{ 0x0003, "Invitation Ack", NULL },
2626 	{ 0, NULL, NULL }
2627 };
2628 
2629 
2630 /***********************************************************************************************************
2631  * AIM LOCATION
2632  ***********************************************************************************************************/
2633 #define AIM_LOCATION_RIGHTS_TLV_MAX_PROFILE_LENGTH 	0x0001
2634 #define AIM_LOCATION_RIGHTS_TLV_MAX_CAPABILITIES 	0x0002
2635 
2636 static const aim_tlv aim_location_rights_tlvs[] = {
2637 	{ AIM_LOCATION_RIGHTS_TLV_MAX_PROFILE_LENGTH, "Max Profile Length", dissect_aim_tlv_value_uint16 },
2638 	{ AIM_LOCATION_RIGHTS_TLV_MAX_CAPABILITIES, "Max capabilities", dissect_aim_tlv_value_uint16 },
2639 	{ 0, NULL, NULL }
2640 };
2641 
2642 #define AIM_LOCATE_TAG_TLV_SIG_TYPE			0x0001
2643 #define AIM_LOCATE_TAG_TLV_SIG_DATA			0x0002
2644 #define AIM_LOCATE_TAG_TLV_UNAVAILABLE_TYPE		0x0003
2645 #define AIM_LOCATE_TAG_TLV_UNAVAILABLE_DATA		0x0004
2646 #define AIM_LOCATE_TAG_TLV_CAPABILITIES			0x0005
2647 #define AIM_LOCATE_TAG_TLV_SIG_TIME			0x000A
2648 #define AIM_LOCATE_TAG_TLV_UNAVAILABLE_TIME		0x000B
2649 #define AIM_LOCATE_TAG_TLV_SUPPORT_HOST_SIG		0x000C
2650 #define AIM_LOCATE_TAG_TLV_HTML_INFO_TYPE		0x000D
2651 #define AIM_LOCATE_TAG_TLV_HTML_INFO_DATA		0x000E
2652 
2653 static const aim_tlv aim_locate_tags_tlvs[] = {
2654 	{ AIM_LOCATE_TAG_TLV_SIG_TYPE,	       "Signature MIME Type"	      , dissect_aim_tlv_value_string },
2655 	{ AIM_LOCATE_TAG_TLV_SIG_DATA,	       "Signature Data"		      , dissect_aim_tlv_value_string },
2656 	{ AIM_LOCATE_TAG_TLV_UNAVAILABLE_TYPE, "Away Message MIME Type"	      , dissect_aim_tlv_value_string },
2657 	{ AIM_LOCATE_TAG_TLV_UNAVAILABLE_DATA, "Away Message Data"	      , dissect_aim_tlv_value_string },
2658 	{ AIM_LOCATE_TAG_TLV_CAPABILITIES,     "Client Capabilities"	      , dissect_aim_tlv_value_client_capabilities },
2659 	{ AIM_LOCATE_TAG_TLV_SIG_TIME,	       "Signature Time"		      , dissect_aim_tlv_value_time },
2660 	{ AIM_LOCATE_TAG_TLV_UNAVAILABLE_TIME, "Away Message Time"	      , dissect_aim_tlv_value_time },
2661 	{ AIM_LOCATE_TAG_TLV_SUPPORT_HOST_SIG, "Enable Server Based Profiles" , dissect_aim_tlv_value_uint8 },
2662 	{ AIM_LOCATE_TAG_TLV_HTML_INFO_TYPE,   "Host Based Buddy MIME Type"   , dissect_aim_tlv_value_string },
2663 	{ AIM_LOCATE_TAG_TLV_HTML_INFO_DATA,   "Host Bases Buddy Data"	      , dissect_aim_tlv_value_string },
2664 	{ 0, NULL, NULL }
2665 };
2666 
2667 #define FAMILY_LOCATION_USERINFO_INFOTYPE_GENERALINFO  0x0001
2668 #define FAMILY_LOCATION_USERINFO_INFOTYPE_AWAYMSG      0x0003
2669 #define FAMILY_LOCATION_USERINFO_INFOTYPE_CAPS         0x0005
2670 
2671 static const value_string aim_snac_location_request_user_info_infotypes[] = {
2672 	{ FAMILY_LOCATION_USERINFO_INFOTYPE_GENERALINFO, "Request General Info" },
2673 	{ FAMILY_LOCATION_USERINFO_INFOTYPE_AWAYMSG,	 "Request Away Message" },
2674 	{ FAMILY_LOCATION_USERINFO_INFOTYPE_CAPS,	 "Request Capabilities" },
2675 	{ 0, NULL }
2676 };
2677 
2678 static int dissect_aim_location_rightsinfo(tvbuff_t *tvb, packet_info *pinfo, proto_tree *loc_tree)
2679 {
2680 	return dissect_aim_tlv_sequence(tvb, pinfo, 0, loc_tree, aim_location_rights_tlvs);
2681 }
2682 
2683 static int dissect_aim_location_setuserinfo(tvbuff_t *tvb, packet_info *pinfo, proto_tree *loc_tree)
2684 {
2685 	return dissect_aim_tlv_sequence(tvb, pinfo, 0, loc_tree, aim_locate_tags_tlvs);
2686 }
2687 
2688 static int dissect_aim_location_watcher_notification(tvbuff_t *tvb, packet_info *pinfo, proto_tree *loc_tree)
2689 {
2690 	int offset = 0;
2691 	while (tvb_reported_length_remaining(tvb, offset) > 0) {
2692 		offset = dissect_aim_buddyname(tvb, pinfo, offset, loc_tree);
2693 	}
2694 	return offset;
2695 }
2696 
2697 static int dissect_aim_location_user_info_query(tvbuff_t *tvb, packet_info *pinfo, proto_tree *loc_tree)
2698 {
2699 	return dissect_aim_buddyname(tvb, pinfo, 4, loc_tree);
2700 }
2701 
2702 static int dissect_aim_snac_location_request_user_information(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
2703 {
2704 	int    offset		= 0;
2705 	guint8 buddyname_length = 0;
2706 
2707 	/* Info Type */
2708 	proto_tree_add_item(tree, hf_aim_snac_location_request_user_info_infotype,
2709 						tvb, offset, 2, ENC_BIG_ENDIAN);
2710 	offset += 2;
2711 
2712 	/* Buddy Name length */
2713 	buddyname_length = tvb_get_guint8(tvb, offset);
2714 	proto_tree_add_item(tree, hf_aim_location_buddyname_len, tvb, offset, 1, ENC_BIG_ENDIAN);
2715 	offset += 1;
2716 
2717 	/* Buddy name */
2718 	proto_tree_add_item(tree, hf_aim_location_buddyname, tvb, offset, buddyname_length, ENC_UTF_8|ENC_NA);
2719 	offset += buddyname_length;
2720 
2721 	return offset;
2722 }
2723 
2724 static int dissect_aim_snac_location_user_information(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2725 {
2726 	int    offset		= 0;
2727 	guint8 buddyname_length = 0;
2728 
2729 	/* Buddy Name length */
2730 	buddyname_length = tvb_get_guint8(tvb, offset);
2731 	proto_tree_add_item(tree, hf_aim_location_buddyname_len, tvb, offset, 1, ENC_BIG_ENDIAN);
2732 	offset += 1;
2733 
2734 	/* Buddy name */
2735 	proto_tree_add_item(tree, hf_aim_location_buddyname, tvb, offset, buddyname_length, ENC_UTF_8|ENC_NA);
2736 	offset += buddyname_length;
2737 
2738 	/* Warning level */
2739 	proto_tree_add_item(tree, hf_aim_location_userinfo_warninglevel, tvb, offset, 2, ENC_BIG_ENDIAN);
2740 	offset += 2;
2741 
2742 	offset = dissect_aim_tlv_list(tvb, pinfo, offset, tree, aim_onlinebuddy_tlvs);
2743 
2744 	return dissect_aim_tlv_sequence(tvb, pinfo, offset, tree, aim_locate_tags_tlvs);
2745 }
2746 
2747 static const aim_subtype aim_fnac_family_location[] = {
2748 	{ 0x0001, "Error"		 , dissect_aim_snac_error },
2749 	{ 0x0002, "Request Rights"       , NULL },
2750 	{ 0x0003, "Rights Info"		 , dissect_aim_location_rightsinfo },
2751 	{ 0x0004, "Set User Info"	 , dissect_aim_location_setuserinfo },
2752 	{ 0x0005, "Request User Info"	 , dissect_aim_snac_location_request_user_information },
2753 	{ 0x0006, "User Info"		 , dissect_aim_snac_location_user_information },
2754 	{ 0x0007, "Watcher Subrequest"   , NULL },
2755 	{ 0x0008, "Watcher Notification" , dissect_aim_location_watcher_notification },
2756 	{ 0x0015, "User Info Query"	 , dissect_aim_location_user_info_query },
2757 	{ 0, NULL, NULL }
2758 };
2759 
2760 
2761 /***********************************************************************************************************
2762  * AIM MESSAGING
2763  ***********************************************************************************************************/
2764 
2765 
2766 #define INCOMING_CH1_MESSAGE_BLOCK     0x0002
2767 #define INCOMING_CH1_SERVER_ACK_REQ    0x0003
2768 #define INCOMING_CH1_MESSAGE_AUTH_RESP 0x0004
2769 #define INCOMING_CH1_MESSAGE_OFFLINE   0x0006
2770 #define INCOMING_CH1_ICON_PRESENT      0x0008
2771 #define INCOMING_CH1_BUDDY_REQ         0x0009
2772 #define INCOMING_CH1_TYPING            0x000b
2773 
2774 static const aim_tlv aim_messaging_incoming_ch1_tlvs[] = {
2775 	{ INCOMING_CH1_MESSAGE_BLOCK,	  "Message Block", dissect_aim_tlv_value_messageblock },
2776 	{ INCOMING_CH1_SERVER_ACK_REQ,	  "Server Ack Requested", dissect_aim_tlv_value_bytes },
2777 	{ INCOMING_CH1_MESSAGE_AUTH_RESP, "Message is Auto Response", dissect_aim_tlv_value_bytes },
2778 	{ INCOMING_CH1_MESSAGE_OFFLINE,	  "Message was received offline", dissect_aim_tlv_value_bytes },
2779 	{ INCOMING_CH1_ICON_PRESENT,	  "Icon present", dissect_aim_tlv_value_bytes },
2780 	{ INCOMING_CH1_BUDDY_REQ,	  "Buddy Req", dissect_aim_tlv_value_bytes },
2781 	{ INCOMING_CH1_TYPING,		  "Non-direct connect typing notification", dissect_aim_tlv_value_bytes },
2782 	{ 0, NULL, NULL },
2783 };
2784 
2785 static int dissect_aim_tlv_value_rendezvous(proto_item *ti, guint16 valueid _U_, tvbuff_t *tvb, packet_info *pinfo);
2786 
2787 #define ICBM_CHANNEL_IM		0x0001
2788 #define ICBM_CHANNEL_RENDEZVOUS	0x0002
2789 
2790 static const value_string icbm_channel_types[] = {
2791 	{ ICBM_CHANNEL_IM,	   "IM" },
2792 	{ ICBM_CHANNEL_RENDEZVOUS, "Rendezvous" },
2793 	{ 0, NULL },
2794 };
2795 
2796 #define INCOMING_CH2_SERVER_ACK_REQ    	   0x0003
2797 #define INCOMING_CH2_RENDEZVOUS_DATA       0x0005
2798 
2799 static const aim_tlv aim_messaging_incoming_ch2_tlvs[] = {
2800 	{ INCOMING_CH2_SERVER_ACK_REQ, "Server Ack Requested", dissect_aim_tlv_value_bytes },
2801 	{ INCOMING_CH2_RENDEZVOUS_DATA, "Rendez Vous Data", dissect_aim_tlv_value_rendezvous },
2802 	{ 0, NULL, NULL },
2803 };
2804 
2805 #define RENDEZVOUS_TLV_CHANNEL				0x0001
2806 #define RENDEZVOUS_TLV_IP_ADDR				0x0002
2807 #define RENDEZVOUS_TLV_INT_IP				0x0003
2808 #define RENDEZVOUS_TLV_EXT_IP				0x0004
2809 #define RENDEZVOUS_TLV_EXT_PORT				0x0005
2810 #define RENDEZVOUS_TLV_DOWNLOAD_URL			0x0006
2811 #define RENDEZVOUS_TLV_VERIFIED_DOWNLOAD_URL		0x0008
2812 #define RENDEZVOUS_TLV_SEQ_NUM				0x000A
2813 #define RENDEZVOUS_TLV_CANCEL_REASON			0x000B
2814 #define RENDEZVOUS_TLV_INVITATION			0x000C
2815 #define RENDEZVOUS_TLV_INVITE_MIME_CHARSET		0x000D
2816 #define RENDEZVOUS_TLV_INVITE_MIME_LANG			0x000E
2817 #define RENDEZVOUS_TLV_REQ_HOST_CHECK			0x000F
2818 #define RENDEZVOUS_TLV_REQ_USE_ARS			0x0010
2819 #define RENDEZVOUS_TLV_REQ_SECURE			0x0011
2820 #define RENDEZVOUS_TLV_MAX_PROTOCOL_VER			0x0012
2821 #define RENDEZVOUS_TLV_MIN_PROTOCOL_VER			0x0013
2822 #define RENDEZVOUS_TLV_COUNTER_REASON			0x0014
2823 #define RENDEZVOUS_TLV_INVITE_MIME_TYPE			0x0015
2824 #define RENDEZVOUS_TLV_IP_ADDR_XOR			0x0016
2825 #define RENDEZVOUS_TLV_PORT_XOR				0x0017
2826 #define RENDEZVOUS_TLV_ADDR_LIST			0x0018
2827 #define RENDEZVOUS_TLV_SESSION_ID			0x0019
2828 #define RENDEZVOUS_TLV_ROLLOVER_ID			0x001A
2829 #define RENDEZVOUS_TLV_EXTENDED_DATA			0x2711
2830 #define RENDEZVOUS_TLV_ICHAT_INVITEES_DATA		0x277E
2831 
2832 static const aim_tlv aim_rendezvous_tlvs[] = {
2833 	{ RENDEZVOUS_TLV_CHANNEL,		"Rendezvous ICBM Channel", dissect_aim_tlv_value_uint16 },
2834 	{ RENDEZVOUS_TLV_IP_ADDR,		"Rendezvous IP", dissect_aim_tlv_value_ipv4 },
2835 	{ RENDEZVOUS_TLV_INT_IP,		"Internal IP", dissect_aim_tlv_value_ipv4 },
2836 	{ RENDEZVOUS_TLV_EXT_IP,		"External IP", dissect_aim_tlv_value_ipv4 },
2837 	{ RENDEZVOUS_TLV_EXT_PORT,		"External Port", dissect_aim_tlv_value_uint16 },
2838 	{ RENDEZVOUS_TLV_DOWNLOAD_URL,		"Service Support Download URL", dissect_aim_tlv_value_string },
2839 	{ RENDEZVOUS_TLV_VERIFIED_DOWNLOAD_URL, "Verified Service Support Download URL", dissect_aim_tlv_value_string },
2840 	{ RENDEZVOUS_TLV_SEQ_NUM,		"Sequence Number", dissect_aim_tlv_value_uint16 },
2841 	{ RENDEZVOUS_TLV_CANCEL_REASON,		"Cancel Reason", dissect_aim_tlv_value_uint16 },
2842 	{ RENDEZVOUS_TLV_INVITATION,		"Invitation Text", dissect_aim_tlv_value_string },
2843 	{ RENDEZVOUS_TLV_INVITE_MIME_CHARSET,	"Data MIME Type", dissect_aim_tlv_value_string },
2844 	{ RENDEZVOUS_TLV_INVITE_MIME_LANG,	"Data Language", dissect_aim_tlv_value_string },
2845 	{ RENDEZVOUS_TLV_REQ_HOST_CHECK,	"Request Host Check", NULL },
2846 	{ RENDEZVOUS_TLV_REQ_USE_ARS,		"Request Data via Rendezvous Server", NULL },
2847 	{ RENDEZVOUS_TLV_REQ_SECURE,		"Request SSL Connection", NULL },
2848 	{ RENDEZVOUS_TLV_MAX_PROTOCOL_VER,	"Maximum Protocol Version", dissect_aim_tlv_value_uint16 },
2849 	{ RENDEZVOUS_TLV_MIN_PROTOCOL_VER,	"Minimum Protocol Version", dissect_aim_tlv_value_uint16 },
2850 	{ RENDEZVOUS_TLV_COUNTER_REASON,	"Counter Proposal Reason", dissect_aim_tlv_value_uint16 },
2851 	{ RENDEZVOUS_TLV_INVITE_MIME_TYPE,	"Data MIME Type", dissect_aim_tlv_value_string },
2852 	{ RENDEZVOUS_TLV_IP_ADDR_XOR,		"XORed Rendezvous IP", dissect_aim_tlv_value_ipv4 },
2853 	{ RENDEZVOUS_TLV_PORT_XOR,		"XORed Port", dissect_aim_tlv_value_uint16 },
2854 	{ RENDEZVOUS_TLV_ADDR_LIST,		"Address/Port List", dissect_aim_tlv_value_string08_array },
2855 	{ RENDEZVOUS_TLV_SESSION_ID,		"Session ID", dissect_aim_tlv_value_string },
2856 	{ RENDEZVOUS_TLV_ROLLOVER_ID,		"Rollover ID", dissect_aim_tlv_value_string },
2857 /*
2858 	The dissect_aim_tlv_value_extended_data function does not work for iChat generated rendezvous data
2859 	{ RENDEZVOUS_TLV_EXTENDED_DATA,		"Extended Data", dissect_aim_tlv_value_extended_data },
2860 */
2861 	{ RENDEZVOUS_TLV_EXTENDED_DATA,		"Extended Data", NULL },
2862 	{ RENDEZVOUS_TLV_ICHAT_INVITEES_DATA,	"iChat Invitees Data", NULL },
2863 	{ 0, NULL, NULL },
2864 };
2865 
2866 #define MINITYPING_FINISHED_SIGN			0x0000
2867 #define MINITYPING_TEXT_TYPED_SIGN			0x0001
2868 #define MINITYPING_BEGUN_SIGN				0x0002
2869 
2870 static const value_string minityping_type[] _U_ = {
2871 	{MINITYPING_FINISHED_SIGN,   "Typing finished sign" },
2872 	{MINITYPING_TEXT_TYPED_SIGN, "Text typed sign" },
2873 	{MINITYPING_BEGUN_SIGN,	     "Typing begun sign" },
2874 	{0, NULL }
2875 };
2876 
2877 #define RENDEZVOUS_MSG_REQUEST 		0
2878 #define RENDEZVOUS_MSG_CANCEL		1
2879 #define RENDEZVOUS_MSG_ACCEPT 		2
2880 
2881 static const value_string rendezvous_msg_types[] = {
2882 	{ RENDEZVOUS_MSG_REQUEST, "Request" },
2883 	{ RENDEZVOUS_MSG_CANCEL,  "Cancel" },
2884 	{ RENDEZVOUS_MSG_ACCEPT,  "Accept" },
2885 	{ 0, NULL },
2886 };
2887 
2888 #define CLIENT_ERR__REASON_UNSUPPORTED_CHANNEL	1
2889 #define CLIENT_ERR__REASON_BUSTED_PAYLOAD	2
2890 #define CLIENT_ERR__REASON_CHANNEL_SPECIFIC	3
2891 
2892 static const value_string client_err_reason_types[] = {
2893 	{ CLIENT_ERR__REASON_UNSUPPORTED_CHANNEL, "Unsupported Channel" },
2894 	{ CLIENT_ERR__REASON_BUSTED_PAYLOAD,	  "Busted Payload" },
2895 	{ CLIENT_ERR__REASON_CHANNEL_SPECIFIC,	  "Channel Specific Error" },
2896 	{ 0, NULL },
2897 };
2898 
2899 #define RENDEZVOUS_NAK_PROPOSAL_UNSUPPORTED 0
2900 #define RENDEZVOUS_NAK_PROPOSAL_DENIED 1
2901 #define RENDEZVOUS_NAK_PROPOSAL_IGNORED 2
2902 #define RENDEZVOUS_NAK_BUSTED_PARAMETERS 3
2903 #define RENDEZVOUS_NAK_PROPOSAL_TIMED_OUT 4
2904 #define RENDEZVOUS_NAK_ONLINE_BUT_NOT_AVAILABLE 5
2905 #define RENDEZVOUS_NAK_INSUFFICIENT_RESOURCES 6
2906 #define RENDEZVOUS_NAK_RATE_LIMITED 7
2907 #define RENDEZVOUS_NAK_NO_DATA 8
2908 #define RENDEZVOUS_NAK_VERSION_MISMATCH 9
2909 #define RENDEZVOUS_NAK_SECURITY_MISMATCH 10
2910 #define RENDEZVOUS_NAK_SERVICE_SPECIFIC_REASON 15
2911 
2912 static const value_string rendezvous_nak_reason_types[] = {
2913 	{ RENDEZVOUS_NAK_PROPOSAL_UNSUPPORTED,	   "Proposal UUID not supported" },
2914 	{ RENDEZVOUS_NAK_PROPOSAL_DENIED,	   "Not authorized, or user declined" },
2915 	{ RENDEZVOUS_NAK_PROPOSAL_IGNORED,	   "Proposal ignored" },
2916 	{ RENDEZVOUS_NAK_BUSTED_PARAMETERS,	   "Proposal malformed" },
2917 	{ RENDEZVOUS_NAK_PROPOSAL_TIMED_OUT,	   "Attempt to act on proposal (e.g. connect) timed out" },
2918 	{ RENDEZVOUS_NAK_ONLINE_BUT_NOT_AVAILABLE, "Recipient away or busy" },
2919 	{ RENDEZVOUS_NAK_INSUFFICIENT_RESOURCES,   "Recipient had internal error" },
2920 	{ RENDEZVOUS_NAK_RATE_LIMITED,		   "Recipient was ratelimited" },
2921 	{ RENDEZVOUS_NAK_NO_DATA,		   "Recipient had nothing to send" },
2922 	{ RENDEZVOUS_NAK_VERSION_MISMATCH,	   "Incompatible versions" },
2923 	{ RENDEZVOUS_NAK_SECURITY_MISMATCH,	   "Incompatible security settings" },
2924 	{ RENDEZVOUS_NAK_SERVICE_SPECIFIC_REASON,  "Service-specific reject defined by client" },
2925 	{ 0, NULL },
2926 };
2927 
2928 #define EXTENDED_DATA_MTYPE_PLAIN 0x01
2929 #define EXTENDED_DATA_MTYPE_CHAT 0x02
2930 #define EXTENDED_DATA_MTYPE_FILEREQ 0x03
2931 #define EXTENDED_DATA_MTYPE_URL 0x04
2932 #define EXTENDED_DATA_MTYPE_AUTHREQ 0x06
2933 #define EXTENDED_DATA_MTYPE_AUTHDENY 0x07
2934 #define EXTENDED_DATA_MTYPE_AUTHOK 0x08
2935 #define EXTENDED_DATA_MTYPE_SERVER 0x09
2936 #define EXTENDED_DATA_MTYPE_ADDED 0x0C
2937 #define EXTENDED_DATA_MTYPE_WWP 0x0D
2938 #define EXTENDED_DATA_MTYPE_EEXPRESS 0x0E
2939 #define EXTENDED_DATA_MTYPE_CONTACTS 0x13
2940 #define EXTENDED_DATA_MTYPE_PLUGIN 0x1A
2941 #define EXTENDED_DATA_MTYPE_AUTOAWAY 0xE8
2942 #define EXTENDED_DATA_MTYPE_AUTOBUSY 0xE9
2943 #define EXTENDED_DATA_MTYPE_AUTONA 0xEA
2944 #define EXTENDED_DATA_MTYPE_AUTODND 0xEB
2945 #define EXTENDED_DATA_MTYPE_AUTOFFC 0xEC
2946 
2947 static const value_string extended_data_message_types[] = {
2948 	{EXTENDED_DATA_MTYPE_PLAIN,    "Plain text (simple) message"},
2949 	{EXTENDED_DATA_MTYPE_CHAT,     "Chat request message"},
2950 	{EXTENDED_DATA_MTYPE_FILEREQ,  "File request / file ok message"},
2951 	{EXTENDED_DATA_MTYPE_URL,      "URL message (0xFE formatted)"},
2952 	{EXTENDED_DATA_MTYPE_AUTHREQ,  "Authorization request message (0xFE formatted)"},
2953 	{EXTENDED_DATA_MTYPE_AUTHDENY, "Authorization denied message (0xFE formatted)"},
2954 	{EXTENDED_DATA_MTYPE_AUTHOK,   "Authorization given message (empty)"},
2955 	{EXTENDED_DATA_MTYPE_SERVER,   "Message from OSCAR server (0xFE formatted)"},
2956 	{EXTENDED_DATA_MTYPE_ADDED,    "\"You-were-added\" message (0xFE formatted)"},
2957 	{EXTENDED_DATA_MTYPE_WWP,      "Web pager message (0xFE formatted)"},
2958 	{EXTENDED_DATA_MTYPE_EEXPRESS, "Email express message (0xFE formatted)"},
2959 	{EXTENDED_DATA_MTYPE_CONTACTS, "Contact list message"},
2960 	{EXTENDED_DATA_MTYPE_PLUGIN,   "Plugin message described by text string"},
2961 	{EXTENDED_DATA_MTYPE_AUTOAWAY, "Auto away message"},
2962 	{EXTENDED_DATA_MTYPE_AUTOBUSY, "Auto occupied message"},
2963 	{EXTENDED_DATA_MTYPE_AUTONA,   "Auto not available message"},
2964 	{EXTENDED_DATA_MTYPE_AUTODND,  "Auto do not disturb message"},
2965 	{EXTENDED_DATA_MTYPE_AUTOFFC,  "Auto free for chat message"},
2966 	{ 0, NULL },
2967 };
2968 
2969 #define EXTENDED_DATA_MFLAG_NORMAL 0x01
2970 #define EXTENDED_DATA_MFLAG_AUTO 0x03
2971 #define EXTENDED_DATA_MFLAG_MULTI 0x80
2972 
2973 #define EVIL_ORIGIN_ANONYMOUS		1
2974 #define EVIL_ORIGIN_NONANONYMOUS 	2
2975 
2976 static const value_string evil_origins[] = {
2977 	{EVIL_ORIGIN_ANONYMOUS,	   "Anonymous"},
2978 	{EVIL_ORIGIN_NONANONYMOUS, "Non-Anonymous"},
2979 	{0, NULL },
2980 };
2981 
2982 /* Initialize the protocol and registered fields */
2983 
2984 static int
2985 dissect_aim_tlv_value_rendezvous(proto_item *ti, guint16 valueid _U_, tvbuff_t *tvb, packet_info *pinfo)
2986 {
2987 	int offset = 0;
2988 	proto_tree *entry = proto_item_add_subtree(ti, ett_aim_rendezvous_data);
2989 	proto_tree_add_item(entry, hf_aim_rendezvous_msg_type, tvb, offset, 2, ENC_BIG_ENDIAN);
2990 	offset += 2;
2991 
2992 	proto_tree_add_item(entry, hf_aim_icbm_cookie, tvb, offset, 8, ENC_NA);
2993 	offset += 8;
2994 
2995 	offset = dissect_aim_capability(entry, tvb, offset);
2996 
2997 	return dissect_aim_tlv_sequence(tvb, pinfo, offset, entry,
2998 					aim_rendezvous_tlvs);
2999 }
3000 
3001 static int
3002 dissect_aim_msg_outgoing(tvbuff_t *tvb, packet_info *pinfo, proto_tree *msg_tree)
3003 {
3004 	int offset = 0;
3005 	const aim_tlv *aim_ch_tlvs = NULL;
3006 	guint16 channel_id;
3007 	guint8 *buddyname;
3008 	int buddyname_length;
3009 
3010 	/* ICBM Cookie */
3011 	proto_tree_add_item(msg_tree, hf_aim_icbm_cookie, tvb, offset, 8, ENC_NA);
3012 	offset += 8;
3013 
3014 	/* Message Channel ID */
3015 	channel_id = tvb_get_ntohs(tvb, offset);
3016 	proto_tree_add_item(msg_tree, hf_aim_message_channel_id, tvb, offset, 2,
3017 			    ENC_BIG_ENDIAN);
3018 	offset += 2;
3019 
3020 	/* Add the outgoing username to the info column */
3021 	buddyname_length = aim_get_buddyname(pinfo->pool, &buddyname, tvb, offset);
3022 	col_append_fstr(pinfo->cinfo, COL_INFO, " to: %s",
3023 			format_text(pinfo->pool, buddyname, buddyname_length));
3024 
3025 	offset = dissect_aim_buddyname(tvb, pinfo, offset, msg_tree);
3026 
3027 	switch(channel_id) {
3028 	case ICBM_CHANNEL_IM: aim_ch_tlvs = aim_messaging_incoming_ch1_tlvs; break;
3029 	case ICBM_CHANNEL_RENDEZVOUS: aim_ch_tlvs = aim_messaging_incoming_ch2_tlvs; break;
3030 	default: return offset;
3031 	}
3032 
3033 	return dissect_aim_tlv_sequence(tvb, pinfo, offset, msg_tree, aim_ch_tlvs);
3034 }
3035 
3036 
3037 static int
3038 dissect_aim_msg_incoming(tvbuff_t *tvb, packet_info *pinfo, proto_tree *msg_tree)
3039 {
3040 	int offset = 0;
3041 	const aim_tlv *aim_ch_tlvs;
3042 	guint16 channel_id;
3043 
3044 	/* ICBM Cookie */
3045 	proto_tree_add_item(msg_tree, hf_aim_icbm_cookie, tvb, offset, 8, ENC_NA);
3046 	offset += 8;
3047 
3048 	/* Message Channel ID */
3049 	proto_tree_add_item(msg_tree, hf_aim_message_channel_id, tvb, offset, 2,
3050 			    ENC_BIG_ENDIAN);
3051 	channel_id = tvb_get_ntohs(tvb, offset);
3052 	offset += 2;
3053 
3054 	offset = dissect_aim_userinfo(tvb, pinfo, offset, msg_tree);
3055 
3056 	switch(channel_id) {
3057 	case ICBM_CHANNEL_IM: aim_ch_tlvs = aim_messaging_incoming_ch1_tlvs; break;
3058 	case ICBM_CHANNEL_RENDEZVOUS: aim_ch_tlvs = aim_messaging_incoming_ch2_tlvs; break;
3059 	default: return offset;
3060 	}
3061 
3062 	return dissect_aim_tlv_sequence(tvb, pinfo, offset, msg_tree, aim_ch_tlvs);
3063 }
3064 
3065 static int
3066 dissect_aim_msg_params(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *msg_tree)
3067 {
3068 	int offset = 0;
3069 	proto_tree_add_item(msg_tree, hf_aim_icbm_channel, tvb, offset, 2, ENC_BIG_ENDIAN); offset+=2;
3070 	proto_tree_add_item(msg_tree, hf_aim_icbm_msg_flags, tvb, offset, 4, ENC_BIG_ENDIAN); offset+=4;
3071 	proto_tree_add_item(msg_tree, hf_aim_icbm_max_snac_size, tvb, offset, 2, ENC_BIG_ENDIAN); offset+=2;
3072 	proto_tree_add_item(msg_tree, hf_aim_icbm_max_sender_warnlevel, tvb, offset, 2, ENC_BIG_ENDIAN); offset+=2;
3073 	proto_tree_add_item(msg_tree, hf_aim_icbm_max_receiver_warnlevel, tvb, offset, 2, ENC_BIG_ENDIAN); offset+=2;
3074 	proto_tree_add_item(msg_tree, hf_aim_icbm_min_msg_interval, tvb, offset, 4, ENC_BIG_ENDIAN); offset+=4;
3075 	return offset;
3076 }
3077 
3078 static int
3079 dissect_aim_msg_evil_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *msg_tree)
3080 {
3081 	int offset = 0;
3082 	proto_tree_add_item(msg_tree, hf_aim_icbm_evil, tvb, offset, 2, ENC_BIG_ENDIAN); offset+=2;
3083 	return dissect_aim_buddyname(tvb, pinfo, offset, msg_tree);
3084 }
3085 
3086 
3087 static int
3088 dissect_aim_msg_evil_repl(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *msg_tree)
3089 {
3090 	int offset = 0;
3091 	proto_tree_add_item(msg_tree, hf_aim_evil_warn_level, tvb, offset, 2, ENC_BIG_ENDIAN); offset+=2;
3092 	proto_tree_add_item(msg_tree, hf_aim_evil_new_warn_level, tvb, offset, 2, ENC_BIG_ENDIAN); offset+=2;
3093 	return offset;
3094 }
3095 
3096 static int
3097 dissect_aim_msg_minityping(tvbuff_t *tvb, packet_info *pinfo, proto_tree *msg_tree)
3098 {
3099 	int offset = 0;
3100 	proto_tree_add_item(msg_tree,hf_aim_icbm_notification_cookie, tvb, offset, 8, ENC_NA); offset+=8;
3101 	proto_tree_add_item(msg_tree,hf_aim_icbm_notification_channel, tvb, offset, 2, ENC_BIG_ENDIAN); offset+=2;
3102 	offset = dissect_aim_buddyname(tvb, pinfo, offset, msg_tree);
3103 	proto_tree_add_item(msg_tree,hf_aim_icbm_notification_type, tvb, offset, 2, ENC_BIG_ENDIAN); offset+=2;
3104 	return offset;
3105 }
3106 
3107 typedef struct _aim_client_plugin
3108 {
3109 	const char *name;
3110 	e_guid_t uuid;
3111 } aim_client_plugin;
3112 
3113 static const aim_client_plugin known_client_plugins[] = {
3114 	{ "None",
3115 	 {0x0, 0x0, 0x0,
3116 	 {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}},
3117 
3118 	{ "Status Manager",
3119 	 {0xD140CF10, 0xE94F, 0x11D3,
3120 	 {0xBC, 0xD2, 0x00, 0x04, 0xAC, 0x96, 0xDD, 0x96}}},
3121 
3122 	{ NULL, {0x0, 0x0, 0x0, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } } }
3123 };
3124 
3125 static const
3126 aim_client_plugin *aim_find_plugin ( e_guid_t uuid)
3127 {
3128 	int i;
3129 
3130 	for(i = 0; known_client_plugins[i].name; i++)
3131 	{
3132 		const aim_client_plugin *plugin = &(known_client_plugins[i]);
3133 
3134 		if(memcmp(&(plugin->uuid), &uuid, sizeof(e_guid_t)) == 0)
3135 			return plugin;
3136 	}
3137 
3138 	return NULL;
3139 }
3140 
3141 static int
3142 dissect_aim_plugin(proto_tree *entry, tvbuff_t *tvb, int offset, e_guid_t* out_plugin_uuid)
3143 {
3144 	const aim_client_plugin *plugin = NULL;
3145 	e_guid_t uuid;
3146 	proto_item* ti;
3147 
3148 	uuid.data1 = tvb_get_ntohl(tvb, offset);
3149 	uuid.data2 = tvb_get_ntohs(tvb, offset+4);
3150 	uuid.data3 = tvb_get_ntohs(tvb, offset+6);
3151 	tvb_memcpy(tvb, uuid.data4, offset+8, 8);
3152 	if (out_plugin_uuid)
3153 		*out_plugin_uuid = uuid;
3154 
3155 	plugin = aim_find_plugin(uuid);
3156 
3157 	ti = proto_tree_add_item(entry, hf_aim_messaging_plugin, tvb, offset, 16, ENC_NA);
3158 	proto_item_append_text(ti, " (%s)", plugin ? plugin->name:"Unknown");
3159 
3160 	return offset+16;
3161 }
3162 
3163 static int
3164 dissect_aim_rendezvous_extended_message(tvbuff_t *tvb, proto_tree *msg_tree)
3165 {
3166 	int offset = 0;
3167 	guint32 text_length;
3168 	static int * const flags[] = {
3169 		&hf_aim_rendezvous_extended_data_message_flags_normal,
3170 		&hf_aim_rendezvous_extended_data_message_flags_auto,
3171 		&hf_aim_rendezvous_extended_data_message_flags_multi,
3172 		NULL
3173 	};
3174 
3175 	proto_tree_add_item(msg_tree, hf_aim_rendezvous_extended_data_message_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset+=1;
3176 	proto_tree_add_bitmask(msg_tree, tvb, offset, hf_aim_rendezvous_extended_data_message_flags,
3177 			       ett_aim_extended_data_message_flags, flags, ENC_NA);
3178 	offset+=1;
3179 	proto_tree_add_item(msg_tree, hf_aim_rendezvous_extended_data_message_status_code, tvb, offset, 2, ENC_BIG_ENDIAN); offset+=2;
3180 	proto_tree_add_item(msg_tree, hf_aim_rendezvous_extended_data_message_priority_code, tvb, offset, 2, ENC_BIG_ENDIAN); offset+=2;
3181 	text_length = tvb_get_letohs(tvb, offset);
3182 	proto_tree_add_item_ret_uint(msg_tree, hf_aim_rendezvous_extended_data_message_text_length, tvb, offset, 2, ENC_BIG_ENDIAN, &text_length); offset+=2;
3183 	proto_tree_add_item(msg_tree, hf_aim_rendezvous_extended_data_message_text, tvb, offset, text_length, ENC_ASCII|ENC_NA); /* offset+=text_length; */
3184 
3185 	offset = tvb_reported_length(tvb);
3186 
3187 	return offset;
3188 }
3189 
3190 static int
3191 is_uuid_null(e_guid_t uuid)
3192 {
3193 	return (uuid.data1 == 0) &&
3194 	       (uuid.data2 == 0) &&
3195 	       (uuid.data3 == 0) &&
3196 	       (uuid.data4[0] == 0) &&
3197 	       (uuid.data4[1] == 0) &&
3198 	       (uuid.data4[2] == 0) &&
3199 	       (uuid.data4[3] == 0) &&
3200 	       (uuid.data4[4] == 0) &&
3201 	       (uuid.data4[5] == 0) &&
3202 	       (uuid.data4[6] == 0) &&
3203 	       (uuid.data4[7] == 0);
3204 }
3205 
3206 static int
3207 dissect_aim_tlv_value_extended_data(proto_tree *entry, guint16 valueid _U_, tvbuff_t *tvb, packet_info *pinfo _U_)
3208 {
3209 	int offset = 0;
3210 	guint16 length/*, protocol_version*/;
3211 	int start_offset;
3212 	e_guid_t plugin_uuid;
3213 
3214 	length = tvb_get_letohs(tvb, offset);
3215 	proto_tree_add_item(entry, hf_aim_icbm_client_err_length, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset+=2;
3216 	start_offset = offset;
3217 
3218 	proto_tree_add_item(entry, hf_aim_icbm_client_err_protocol_version, tvb, offset, 2, ENC_BIG_ENDIAN); offset+=2;
3219 
3220 	offset = dissect_aim_plugin(entry, tvb, offset, &plugin_uuid);
3221 	proto_tree_add_item(entry, hf_aim_messaging_unknown_uint16, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2;
3222 	proto_tree_add_item(entry, hf_aim_icbm_client_err_client_caps_flags, tvb, offset, 4, ENC_BIG_ENDIAN); offset+=4;
3223 	proto_tree_add_item(entry, hf_aim_messaging_unknown_uint8, tvb, offset, 1, ENC_NA);	offset += 1;
3224 	proto_tree_add_item(entry, hf_aim_icbm_client_err_downcounter, tvb, offset, 2, ENC_LITTLE_ENDIAN); /* offset += 2;*/
3225 
3226 	offset = start_offset + length;
3227 
3228 	length = tvb_get_letohs(tvb, offset);
3229 	proto_tree_add_item(entry, hf_aim_icbm_client_err_length, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset+=2;
3230 	start_offset = offset;
3231 	proto_tree_add_item(entry, hf_aim_icbm_client_err_downcounter, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2;
3232 	proto_tree_add_item(entry, hf_aim_messaging_unknown_data, tvb, offset, length-2, ENC_NA);
3233 	offset = start_offset + length;
3234 
3235 	if (is_uuid_null(plugin_uuid))
3236 	{
3237 		/* a message follows */
3238 		tvbuff_t *subtvb = tvb_new_subset_remaining(tvb, offset);
3239 		/* offset += */ dissect_aim_rendezvous_extended_message(subtvb, entry);
3240 	}
3241 	else
3242 	{
3243 		/* plugin-specific data follows */
3244 		proto_tree_add_item(entry, hf_aim_messaging_plugin_specific_data, tvb, offset, -1, ENC_NA);
3245 	}
3246 	offset = tvb_reported_length(tvb);
3247 
3248 	return offset;
3249 }
3250 
3251 static int
3252 dissect_aim_msg_ack(tvbuff_t *tvb, packet_info *pinfo, proto_tree *msg_tree)
3253 {
3254 	int offset = 0;
3255 
3256 	proto_tree_add_item(msg_tree,hf_aim_icbm_cookie, tvb, offset, 8, ENC_NA); offset+=8;
3257 
3258 	proto_tree_add_item(msg_tree, hf_aim_message_channel_id, tvb, offset, 2,
3259 			    ENC_BIG_ENDIAN); offset += 2;
3260 
3261 	offset = dissect_aim_buddyname(tvb, pinfo, offset, msg_tree);
3262 
3263 	return offset;
3264 }
3265 
3266 static int
3267 dissect_aim_msg_client_err(tvbuff_t *tvb, packet_info *pinfo, proto_tree *msg_tree)
3268 {
3269 	int offset = 0;
3270 	guint16 channel, reason;
3271 
3272 	proto_tree_add_item(msg_tree,hf_aim_icbm_cookie, tvb, offset, 8, ENC_NA); offset+=8;
3273 	channel = tvb_get_ntohs(tvb, offset);
3274 	proto_tree_add_item(msg_tree,hf_aim_icbm_channel, tvb, offset, 2, ENC_BIG_ENDIAN); offset+=2;
3275 	offset = dissect_aim_buddyname(tvb, pinfo, offset, msg_tree);
3276 	reason = tvb_get_ntohs(tvb, offset);
3277 	proto_tree_add_item(msg_tree, hf_aim_icbm_client_err_reason, tvb, offset, 2, ENC_BIG_ENDIAN); offset+=2;
3278 
3279 	if (reason == CLIENT_ERR__REASON_CHANNEL_SPECIFIC && tvb_reported_length_remaining(tvb, offset) > 0)
3280 	{
3281 		switch (channel)
3282 		{
3283 		case ICBM_CHANNEL_RENDEZVOUS:
3284 			proto_tree_add_item(msg_tree, hf_aim_icbm_rendezvous_nak_length, tvb, offset, 2, ENC_BIG_ENDIAN); offset+=2;
3285 			proto_tree_add_item(msg_tree, hf_aim_icbm_rendezvous_nak, tvb, offset, 2, ENC_BIG_ENDIAN); offset+=2;
3286 			break;
3287 
3288 		default:
3289 		    {
3290 			tvbuff_t *subtvb = tvb_new_subset_remaining(tvb, offset);
3291 			proto_tree *extended_tree = proto_tree_add_subtree(msg_tree, tvb, offset, -1, ett_aim_extended_data, NULL, "Extended Data");
3292 			dissect_aim_tlv_value_extended_data(extended_tree, 0, subtvb, pinfo);
3293 			break;
3294 		    }
3295 		}
3296 	}
3297 
3298 	return offset;
3299 }
3300 
3301 static const aim_subtype aim_fnac_family_messaging[] = {
3302 	{ 0x0001, "Error",			     dissect_aim_snac_error },
3303 	{ 0x0002, "Set ICBM Parameter",		     dissect_aim_msg_params },
3304 	{ 0x0003, "Reset ICBM Parameter",	     NULL },
3305 	{ 0x0004, "Request Parameter Info",	     NULL},
3306 	{ 0x0005, "Parameter Info",		     dissect_aim_msg_params },
3307 	{ 0x0006, "Outgoing",			     dissect_aim_msg_outgoing },
3308 	{ 0x0007, "Incoming",			     dissect_aim_msg_incoming },
3309 	{ 0x0008, "Evil Request",		     dissect_aim_msg_evil_req },
3310 	{ 0x0009, "Evil Response",		     dissect_aim_msg_evil_repl  },
3311 	{ 0x000a, "Missed Call", 		     NULL },
3312 	{ 0x000b, "Client Error",		     dissect_aim_msg_client_err },
3313 	{ 0x000c, "Acknowledge",		     dissect_aim_msg_ack },
3314 	{ 0x0014, "Mini Typing Notifications (MTN)", dissect_aim_msg_minityping },
3315 	{ 0, NULL, NULL }
3316 };
3317 
3318 
3319 
3320 /***********************************************************************************************************
3321  * AIM POPUP
3322  ***********************************************************************************************************/
3323 
3324 
3325 #define AIM_POPUP_TLV_MESSAGE_TEXT		0x001
3326 #define AIM_POPUP_TLV_URL_STRING		0x002
3327 #define AIM_POPUP_TLV_WINDOW_WIDTH		0x003
3328 #define AIM_POPUP_TLV_WINDOW_HEIGHT		0x004
3329 #define AIM_POPUP_TLV_AUTOHIDE_DELAY	0x005
3330 
3331 static const aim_tlv aim_popup_tlvs[] = {
3332 	{ AIM_POPUP_TLV_MESSAGE_TEXT, "Message text (html)", dissect_aim_tlv_value_string },
3333 	{ AIM_POPUP_TLV_URL_STRING, "URL string", dissect_aim_tlv_value_string },
3334 	{ AIM_POPUP_TLV_WINDOW_WIDTH, "Window Width (pixels)", dissect_aim_tlv_value_uint16 },
3335 	{ AIM_POPUP_TLV_WINDOW_HEIGHT, "Window Height (pixels)", dissect_aim_tlv_value_uint16 },
3336 	{ AIM_POPUP_TLV_AUTOHIDE_DELAY, "Autohide delay (seconds)", dissect_aim_tlv_value_uint16 },
3337 	{ 0, NULL, NULL }
3338 };
3339 
3340 static int dissect_aim_popup(tvbuff_t *tvb, packet_info *pinfo, proto_tree *popup_tree)
3341 {
3342 	return dissect_aim_tlv(tvb, pinfo, 0, popup_tree, aim_popup_tlvs);
3343 }
3344 
3345 static const aim_subtype aim_fnac_family_popup[] = {
3346 	{ 0x0001, "Error", dissect_aim_snac_error },
3347 	{ 0x0002, "Display Popup Message Server Command" , dissect_aim_popup },
3348 	{ 0, NULL, NULL }
3349 };
3350 
3351 /***********************************************************************************************************
3352  * AIM SIGNON
3353  ***********************************************************************************************************/
3354 
3355 static int dissect_aim_snac_signon_logon(tvbuff_t *tvb, packet_info *pinfo,
3356 					  proto_tree *tree)
3357 {
3358 	int offset = 0;
3359 	while (tvb_reported_length_remaining(tvb, offset) > 0) {
3360 		offset = dissect_aim_tlv(tvb, pinfo, offset, tree, aim_client_tlvs);
3361 	}
3362 	return offset;
3363 }
3364 
3365 static int dissect_aim_snac_signon_logon_reply(tvbuff_t *tvb,
3366 					       packet_info *pinfo,
3367 					       proto_tree *tree)
3368 {
3369 	int offset = 0;
3370 	while (tvb_reported_length_remaining(tvb, offset) > 0) {
3371 		offset = dissect_aim_tlv(tvb, pinfo, offset, tree, aim_client_tlvs);
3372 	}
3373 	return offset;
3374 }
3375 
3376 static int dissect_aim_snac_signon_signon(tvbuff_t *tvb, packet_info *pinfo,
3377 					  proto_tree *tree)
3378 {
3379 	guint8 buddyname_length = 0;
3380 	int offset = 0;
3381 	guint8 *buddyname;
3382 
3383 	/* Info Type */
3384 	proto_tree_add_item(tree, hf_aim_infotype, tvb, offset, 2, ENC_BIG_ENDIAN);
3385 	offset += 2;
3386 
3387 	/* Unknown */
3388 	offset += 1;
3389 
3390 	/* Buddy Name */
3391 	buddyname_length = aim_get_buddyname( pinfo->pool, &buddyname, tvb, offset );
3392 
3393 	col_append_fstr(pinfo->cinfo, COL_INFO, " Username: %s",
3394 			format_text(pinfo->pool, buddyname, buddyname_length));
3395 
3396 	if(tree) {
3397 		offset+=dissect_aim_buddyname(tvb, pinfo, offset, tree);
3398 	}
3399 
3400 	return offset;
3401 }
3402 
3403 static int dissect_aim_snac_signon_signon_reply(tvbuff_t *tvb,
3404 						packet_info *pinfo _U_,
3405 						proto_tree *tree)
3406 {
3407 	int offset = 0;
3408 	guint16 challenge_length = 0;
3409 
3410 	/* Logon Challenge Length */
3411 	challenge_length = tvb_get_ntohs(tvb, offset);
3412 	proto_tree_add_item(tree, hf_aim_signon_challenge_len, tvb, offset, 2, ENC_BIG_ENDIAN);
3413 	offset += 2;
3414 
3415 	/* Challenge */
3416 	proto_tree_add_item(tree, hf_aim_signon_challenge, tvb, offset, challenge_length, ENC_UTF_8|ENC_NA);
3417 	offset += challenge_length;
3418 	return offset;
3419 }
3420 
3421 static int dissect_aim_tlv_value_registration(proto_item *ti _U_, guint16 value_id _U_, tvbuff_t *tvb _U_, packet_info *pinfo _U_)
3422 {
3423 	/* FIXME */
3424 	return 0;
3425 }
3426 
3427 #define REG_TLV_REGISTRATION_INFO 	0x0001
3428 
3429 static const aim_tlv aim_registration_tlvs[] = {
3430 	{ REG_TLV_REGISTRATION_INFO, "Registration Info", dissect_aim_tlv_value_registration },
3431 	{ 0, NULL, NULL },
3432 };
3433 
3434 static int dissect_aim_snac_register (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
3435 {
3436 	return dissect_aim_tlv(tvb, pinfo, 0, tree, aim_registration_tlvs);
3437 }
3438 
3439 static const aim_subtype aim_fnac_family_signon[] = {
3440 	{ 0x0001, "Error", dissect_aim_snac_error },
3441 	{ 0x0002, "Logon", dissect_aim_snac_signon_logon },
3442 	{ 0x0003, "Logon Reply", dissect_aim_snac_signon_logon_reply },
3443 	{ 0x0004, "Request UIN", dissect_aim_snac_register },
3444 	{ 0x0005, "New UIN response", dissect_aim_snac_register },
3445 	{ 0x0006, "Sign-on", dissect_aim_snac_signon_signon },
3446 	{ 0x0007, "Sign-on Reply", dissect_aim_snac_signon_signon_reply },
3447 	{ 0x000a, "Server SecureID Request", NULL },
3448 	{ 0x000b, "Client SecureID Reply", NULL },
3449 	{ 0, NULL, NULL }
3450 };
3451 
3452 /***********************************************************************************************************
3453  * AIM SSI
3454  ***********************************************************************************************************/
3455 #define SSI_RIGHTSINFO_TLV_MAX_ITEMS	0x0004
3456 
3457 static const aim_tlv aim_ssi_rightsinfo_tlvs[] = {
3458 	{ SSI_RIGHTSINFO_TLV_MAX_ITEMS, "Maximums For Items", dissect_aim_tlv_value_bytes },
3459 	{ 0, NULL, NULL },
3460 };
3461 
3462 /* Initialize the protocol and registered fields */
3463 
3464 /** Calculate size of SSI entry
3465  * Size of SSI entry can be calculated as:
3466  *   sizeof(buddy name length field) = sizeof(guint16) = 2
3467  * + sizeof(buddy name string) = buddy name length field = N
3468  * + sizeof(group ID) = sizeof(guint16) = 2
3469  * + sizeof(buddy ID) = sizeof(guint16) = 2
3470  * + sizeof(buddy type) = sizeof(guint16) = 2
3471  * + sizeof(TLV length) = sizeof(guint16) = 2
3472  * + sizeof(TLVs) = TLV length = M
3473  * = 2 + N + 2 * 4 + M
3474  */
3475 static int calc_ssi_entry_size(tvbuff_t *tvb, int offset)
3476 {
3477 	gint ssi_entry_size = 2 + tvb_get_ntohs(tvb, offset) + 2 * 3;
3478 	ssi_entry_size += tvb_get_ntohs(tvb, offset + ssi_entry_size) + 2;
3479 	return ssi_entry_size;
3480 }
3481 
3482 static int dissect_ssi_item(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *ssi_entry)
3483 {
3484 	guint16 buddyname_length = 0;
3485 	int endoffset;
3486 	guint16 tlv_len = 0;
3487 
3488 	/* Buddy Name Length */
3489 	buddyname_length = tvb_get_ntohs(tvb, offset);
3490 	proto_tree_add_item(ssi_entry, hf_aim_fnac_subtype_ssi_buddyname_len, tvb, offset, 2, ENC_BIG_ENDIAN);
3491 	offset += 2;
3492 
3493 	/* Buddy Name */
3494 	if (buddyname_length > 0) {
3495 		proto_tree_add_item(ssi_entry, hf_aim_fnac_subtype_ssi_buddyname, tvb, offset, buddyname_length, ENC_UTF_8|ENC_NA);
3496 		offset += buddyname_length;
3497 	}
3498 
3499 	/* Buddy group ID */
3500 	proto_tree_add_item(ssi_entry, hf_aim_fnac_subtype_ssi_gid, tvb, offset, 2, ENC_BIG_ENDIAN);
3501 	offset += 2;
3502 
3503 	/* Buddy ID */
3504 	proto_tree_add_item(ssi_entry, hf_aim_fnac_subtype_ssi_bid, tvb, offset, 2, ENC_BIG_ENDIAN);
3505 	offset += 2;
3506 
3507 	/* Buddy Type */
3508 	proto_tree_add_item(ssi_entry, hf_aim_fnac_subtype_ssi_type, tvb, offset, 2, ENC_BIG_ENDIAN);
3509 	offset += 2;
3510 
3511 	/* Size of the following TLV in bytes (as opposed to the number of
3512 	   TLV objects in the chain) */
3513 	tlv_len = tvb_get_ntohs(tvb, offset);
3514 	proto_tree_add_item(ssi_entry, hf_aim_fnac_subtype_ssi_tlvlen, tvb, offset, 2, ENC_BIG_ENDIAN);
3515 	offset += 2;
3516 
3517 	endoffset = offset;
3518 	/* For now, we just dump the TLV contents as-is, since there is not a
3519 	   TLV dissection utility that works based on total chain length */
3520 	while(endoffset < offset+tlv_len) {
3521 		endoffset = dissect_aim_tlv(tvb, pinfo, endoffset, ssi_entry, aim_client_tlvs);
3522 	}
3523 	return endoffset;
3524 }
3525 
3526 static int dissect_ssi_ssi_item(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ssi_entry)
3527 {
3528 	return dissect_ssi_item(tvb, pinfo, 0, ssi_entry);
3529 }
3530 
3531 static int dissect_ssi_ssi_items(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
3532 {
3533 	int offset = 0;
3534 	gint ssi_entry_size;
3535 	proto_tree *ssi_entry = NULL;
3536 	int size = tvb_reported_length(tvb);
3537 	while (size > offset)
3538 	{
3539 		ssi_entry_size = calc_ssi_entry_size(tvb, offset);
3540 		ssi_entry = proto_tree_add_subtree(tree, tvb, offset, ssi_entry_size, ett_aim_ssi, NULL, "SSI Entry");
3541 		offset = dissect_ssi_item(tvb, pinfo, offset, ssi_entry);
3542 	}
3543 	return offset;
3544 }
3545 
3546 static int dissect_aim_ssi_rightsinfo(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ssi_tree)
3547 {
3548 	return dissect_aim_tlv_sequence(tvb, pinfo, 0, ssi_tree, aim_ssi_rightsinfo_tlvs);
3549 }
3550 
3551 static int dissect_aim_ssi_was_added(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ssi_tree)
3552 {
3553 	return dissect_aim_buddyname(tvb, pinfo, 0, ssi_tree);
3554 }
3555 
3556 static int dissect_aim_snac_ssi_time_and_items_num(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
3557 {
3558 	int offset = 0;
3559 
3560 	/* get timestamp */
3561 	proto_tree_add_item(tree, hf_aim_fnac_subtype_ssi_last_change_time, tvb, offset, 4, ENC_TIME_SECS|ENC_BIG_ENDIAN);
3562 	offset += 4;
3563 
3564 	/* get number of SSI items */
3565 	proto_tree_add_item(tree, hf_aim_fnac_subtype_ssi_numitems, tvb, offset, 2, ENC_BIG_ENDIAN);
3566 	offset += 2;
3567 
3568 	return offset;
3569 }
3570 
3571 static int dissect_aim_snac_ssi_list(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
3572 {
3573 	int offset = 0;
3574 	proto_tree *ssi_entry = NULL;
3575 	guint16 num_items, i;
3576 	gint ssi_entry_size;
3577 
3578 	/* SSI Version */
3579 	proto_tree_add_item(tree, hf_aim_fnac_subtype_ssi_version, tvb, offset, 1, ENC_BIG_ENDIAN);
3580 	offset += 1;
3581 
3582 	/* Number of items */
3583 	proto_tree_add_item(tree, hf_aim_fnac_subtype_ssi_numitems, tvb, offset, 2, ENC_BIG_ENDIAN);
3584 	num_items = tvb_get_ntohs(tvb, offset);
3585 	offset += 2;
3586 
3587 	for(i = 0; i < num_items; i++) {
3588 		ssi_entry_size = calc_ssi_entry_size(tvb, offset);
3589 		ssi_entry = proto_tree_add_subtree_format(tree, tvb, offset, ssi_entry_size,
3590 				ett_aim_ssi, NULL, "SSI Entry %u", i);
3591 		offset = dissect_ssi_item(tvb, pinfo, offset, ssi_entry);
3592 	}
3593 	proto_tree_add_item(tree, hf_aim_fnac_subtype_ssi_last_change_time, tvb, offset, 4, ENC_TIME_SECS|ENC_BIG_ENDIAN);
3594 
3595 	return offset;
3596 }
3597 
3598 static int dissect_aim_snac_ssi_auth_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
3599 {
3600 	int offset = 0;
3601 	guint16 reason_length;
3602 	/*guint16 unknown;*/
3603 
3604 	/* get buddy length (1 byte) */
3605 	guint8 buddyname_length = tvb_get_guint8(tvb, offset);
3606 	proto_tree_add_item(tree, hf_aim_fnac_subtype_ssi_buddyname_len8, tvb, offset, 1, ENC_BIG_ENDIAN);
3607 	offset += 1;
3608 
3609 	/* show buddy name */
3610 	if (buddyname_length > 0) {
3611 		proto_tree_add_item(tree, hf_aim_fnac_subtype_ssi_buddyname, tvb, offset, buddyname_length, ENC_UTF_8|ENC_NA);
3612 		offset += buddyname_length;
3613 	}
3614 	/* get reason message length (2 bytes) */
3615 	reason_length = tvb_get_ntohs(tvb, offset);
3616 	proto_tree_add_item(tree, hf_aim_fnac_subtype_ssi_reason_str_len, tvb, offset, 2, ENC_BIG_ENDIAN);
3617 	offset += 2;
3618 
3619 	/* show reason message if present */
3620 	if (reason_length > 0) {
3621 		proto_tree_add_item(tree, hf_aim_fnac_subtype_ssi_reason_str, tvb, offset, reason_length, ENC_UTF_8|ENC_NA);
3622 		offset += reason_length;
3623 	}
3624 
3625 	/* unknown (always 0x0000 ???) */
3626 	/*unknown = tvb_get_ntohs(tvb, offset);*/
3627 	proto_tree_add_item(tree, hf_aim_fnac_subtype_ssi_grant_auth_unkn, tvb, offset, 2, ENC_BIG_ENDIAN);
3628 	offset += 2;
3629 
3630 	return offset;
3631 }
3632 
3633 static int dissect_aim_snac_ssi_auth_reply(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
3634 {
3635 	int offset = 0;
3636 	guint16 reason_length;
3637 
3638 	/* get buddy length (1 byte) */
3639 	guint8 buddyname_length = tvb_get_guint8(tvb, offset);
3640 	proto_tree_add_item(tree, hf_aim_fnac_subtype_ssi_buddyname_len8, tvb, offset, 1, ENC_BIG_ENDIAN);
3641 	offset += 1;
3642 
3643 	/* show buddy name */
3644 	if (buddyname_length > 0) {
3645 		proto_tree_add_item(tree, hf_aim_fnac_subtype_ssi_buddyname, tvb, offset, buddyname_length, ENC_UTF_8|ENC_NA);
3646 		offset += buddyname_length;
3647 	}
3648 
3649 	/* accept/reject authorization flag */
3650 	proto_tree_add_item(tree, hf_aim_fnac_subtype_ssi_allow_auth, tvb, offset, 1, ENC_BIG_ENDIAN);
3651 	offset += 1;
3652 
3653 	/* get reason message length (2 bytes) */
3654 	reason_length = tvb_get_ntohs(tvb, offset);
3655 	proto_tree_add_item(tree, hf_aim_fnac_subtype_ssi_reason_str_len, tvb, offset, 2, ENC_BIG_ENDIAN);
3656 	offset += 2;
3657 
3658 	/* show reason message if present */
3659 	if (reason_length > 0) {
3660 		proto_tree_add_item(tree, hf_aim_fnac_subtype_ssi_reason_str, tvb, offset, reason_length, ENC_UTF_8|ENC_NA);
3661 		offset += reason_length;
3662 	}
3663 
3664 	return offset;
3665 }
3666 
3667 static const aim_subtype aim_fnac_family_ssi[] = {
3668 	{ 0x0001, "Error",				 dissect_aim_snac_error },
3669 	{ 0x0002, "Request Rights",			 NULL },
3670 	{ 0x0003, "Rights Info",			 dissect_aim_ssi_rightsinfo },
3671 	{ 0x0004, "Request List (first time)",		 NULL },
3672 	{ 0x0005, "Request List",			 dissect_aim_snac_ssi_time_and_items_num },
3673 	{ 0x0006, "List",				 dissect_aim_snac_ssi_list },
3674 	{ 0x0007, "Activate",				 NULL },
3675 	{ 0x0008, "Add Buddy",				 dissect_ssi_ssi_item },
3676 	{ 0x0009, "Modify Buddy",			 dissect_ssi_ssi_items },
3677 	{ 0x000a, "Delete Buddy",			 dissect_ssi_ssi_item },
3678 	{ 0x000e, "Server Ack",				 dissect_aim_ssi_result },
3679 	{ 0x000f, "No List",				 dissect_aim_snac_ssi_time_and_items_num },
3680 	{ 0x0011, "Edit Start",				 NULL },
3681 	{ 0x0012, "Edit Stop",				 NULL },
3682 	{ 0x0014, "Grant Future Authorization to Buddy", dissect_aim_snac_ssi_auth_request },
3683 	{ 0x0015, "Future Authorization Granted",	 dissect_aim_snac_ssi_auth_request },
3684 	{ 0x0018, "Send Authentication Request",	 dissect_aim_snac_ssi_auth_request },
3685 	{ 0x0019, "Authentication Request",		 dissect_aim_snac_ssi_auth_request },
3686 	{ 0x001a, "Send Authentication Reply",		 dissect_aim_snac_ssi_auth_reply },
3687 	{ 0x001b, "Authentication Reply",		 dissect_aim_snac_ssi_auth_reply },
3688 	{ 0x001c, "Remote User Added Client To List",	 dissect_aim_ssi_was_added },
3689 	{ 0, NULL, NULL }
3690 };
3691 
3692 /***********************************************************************************************************
3693  * AIM SST
3694  ***********************************************************************************************************/
3695 static int dissect_aim_sst_buddy_down_req (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
3696 {
3697 	int offset = dissect_aim_buddyname(tvb, pinfo, 0, tree);
3698 	guint8 md5_size;
3699 
3700 	proto_tree_add_item(tree, hf_aim_sst_unknown, tvb, offset, 4, ENC_NA);
3701 	offset+=4;
3702 
3703 	proto_tree_add_item(tree, hf_aim_sst_md5_hash_size, tvb, offset, 1, ENC_BIG_ENDIAN);
3704 	md5_size = tvb_get_guint8(tvb, offset);
3705 	offset++;
3706 
3707 	proto_tree_add_item(tree, hf_aim_sst_md5_hash, tvb, offset, md5_size, ENC_NA);
3708 
3709 	offset+=md5_size;
3710 	return offset;
3711 }
3712 
3713 static int dissect_aim_sst_buddy_down_repl (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
3714 {
3715 	int offset = dissect_aim_buddyname(tvb, pinfo, 0, tree);
3716 	guint8 md5_size;
3717 	guint16 icon_size;
3718 
3719 	proto_tree_add_item(tree, hf_aim_sst_unknown, tvb, offset, 3, ENC_NA);
3720 	offset+=3;
3721 
3722 	proto_tree_add_item(tree, hf_aim_sst_md5_hash_size, tvb, offset, 1, ENC_BIG_ENDIAN);
3723 	md5_size = tvb_get_guint8(tvb, offset);
3724 	offset++;
3725 
3726 	proto_tree_add_item(tree, hf_aim_sst_md5_hash, tvb, offset, md5_size, ENC_NA);
3727 
3728 	offset+=md5_size;
3729 
3730 	proto_tree_add_item(tree, hf_aim_sst_icon_size, tvb, offset, 2, ENC_BIG_ENDIAN);
3731 	icon_size = tvb_get_ntohs(tvb, offset);
3732 	offset+=2;
3733 
3734 	if (icon_size)
3735 	{
3736 		proto_tree_add_item(tree, hf_aim_sst_icon, tvb, offset, icon_size, ENC_NA);
3737 	}
3738 
3739 	offset+=icon_size;
3740 
3741 	return offset;
3742 }
3743 
3744 static int dissect_aim_sst_buddy_up_repl (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
3745 {
3746 	int offset = 0;
3747 	guint8 md5_size;
3748 
3749 	proto_tree_add_item(tree, hf_aim_sst_unknown, tvb, offset, 4, ENC_NA);
3750 	offset+=4;
3751 
3752 	proto_tree_add_item(tree, hf_aim_sst_md5_hash_size, tvb, offset, 1, ENC_BIG_ENDIAN);
3753 	md5_size = tvb_get_guint8(tvb, offset);
3754 	offset++;
3755 
3756 	proto_tree_add_item(tree, hf_aim_sst_md5_hash, tvb, offset, md5_size, ENC_NA);
3757 
3758 	offset+=md5_size;
3759 	return offset;
3760 }
3761 
3762 static int dissect_aim_sst_buddy_up_req (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
3763 {
3764 	int offset = 0;
3765 	guint16 icon_size;
3766 
3767 	proto_tree_add_item(tree, hf_aim_sst_ref_num, tvb, offset, 2, ENC_BIG_ENDIAN);
3768 	offset+=2;
3769 
3770 	proto_tree_add_item(tree, hf_aim_sst_icon_size, tvb, offset, 2, ENC_BIG_ENDIAN);
3771 	icon_size = tvb_get_ntohs(tvb, offset);
3772 	offset+=2;
3773 
3774 	if (icon_size)
3775 	{
3776 		proto_tree_add_item(tree, hf_aim_sst_icon, tvb, offset, icon_size, ENC_NA);
3777 	}
3778 
3779 	offset+=icon_size;
3780 	return offset;
3781 }
3782 
3783 static const aim_subtype aim_fnac_family_sst[] = {
3784 	{ 0x0001, "Error", dissect_aim_snac_error },
3785 	{ 0x0002, "Upload Buddy Icon Request", dissect_aim_sst_buddy_up_req },
3786 	{ 0x0003, "Upload Buddy Icon Reply", dissect_aim_sst_buddy_up_repl },
3787 	{ 0x0004, "Download Buddy Icon Request", dissect_aim_sst_buddy_down_req },
3788 	{ 0x0005, "Download Buddy Icon Reply", dissect_aim_sst_buddy_down_repl },
3789 	{ 0, NULL, NULL }
3790 };
3791 
3792 static const aim_subtype aim_fnac_family_stats[] = {
3793 	{ 0x0001, "Error", dissect_aim_snac_error },
3794 	{ 0x0002, "Set Report Interval", NULL },
3795 	{ 0x0003, "Report Request", NULL },
3796 	{ 0x0004, "Report Ack", NULL },
3797 	{ 0, NULL, NULL }
3798 };
3799 
3800 static const aim_subtype aim_fnac_family_translate[] = {
3801 	{ 0x0001, "Error", dissect_aim_snac_error },
3802 	{ 0x0002, "Translate Request", NULL },
3803 	{ 0x0003, "Translate Reply", NULL },
3804 	{ 0, NULL, NULL }
3805 };
3806 
3807 /***********************************************************************************************************
3808  * AIM USER LOOKUP
3809  ***********************************************************************************************************/
3810 static int dissect_aim_userlookup_search(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *lookup_tree)
3811 {
3812 	proto_tree_add_item(lookup_tree, hf_aim_userlookup_email, tvb, 0, tvb_reported_length(tvb), ENC_UTF_8|ENC_NA);
3813 	return tvb_reported_length(tvb);
3814 }
3815 
3816 
3817 static int dissect_aim_userlookup_result(tvbuff_t *tvb, packet_info *pinfo, proto_tree *lookup_tree)
3818 {
3819 	return dissect_aim_tlv_sequence(tvb, pinfo, 0, lookup_tree, aim_client_tlvs);
3820 }
3821 
3822 static const aim_subtype aim_fnac_family_userlookup[] = {
3823 	{ 0x0001, "Error", dissect_aim_snac_error },
3824 	{ 0x0002, "Search for user by email address", dissect_aim_userlookup_search },
3825 	{ 0x0003, "Search results", dissect_aim_userlookup_result },
3826 	{ 0, NULL, NULL }
3827 };
3828 
3829 static void
3830 family_free(gpointer p, gpointer user_data _U_)
3831 {
3832 	g_free(p);
3833 }
3834 
3835 static void
3836 aim_shutdown(void)
3837 {
3838 	g_list_foreach(families, family_free, NULL);
3839 	g_list_free(families);
3840 }
3841 
3842 void
3843 proto_register_aim(void)
3844 {
3845 
3846 /* Setup list of header fields */
3847 	static hf_register_info hf[] = {
3848 		{ &hf_aim_cmd_start,
3849 		  { "Command Start", "aim.cmd_start", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }
3850 		},
3851 		{ &hf_aim_channel,
3852 		  { "Channel ID", "aim.channel", FT_UINT8, BASE_HEX, VALS(aim_flap_channels), 0x0, NULL, HFILL }
3853 		},
3854 		{ &hf_aim_seqno,
3855 		  { "Sequence Number", "aim.seqno", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
3856 		},
3857 		{ &hf_aim_version,
3858 		  { "Protocol Version", "aim.version", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL },
3859 		},
3860 		{ &hf_aim_data_len,
3861 		  { "Data Field Length", "aim.datalen", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
3862 		},
3863 		{ &hf_aim_tlv_length,
3864 		  { "Length", "aim.tlv.length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
3865 		},
3866 		{ &hf_aim_tlv_value_id,
3867 		  { "Value ID", "aim.tlv.value_id", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
3868 		},
3869 		{ &hf_aim_data,
3870 		  { "Data", "aim.data", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }
3871 		},
3872 		{ &hf_aim_fnac_family,
3873 		  { "FNAC Family ID", "aim.fnac.family", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }
3874 		},
3875 		{ &hf_aim_fnac_subtype,
3876 		  { "FNAC Subtype ID", "aim.fnac.subtype", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }
3877 		},
3878 		{ &hf_aim_fnac_flags,
3879 		  { "FNAC Flags", "aim.fnac.flags", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }
3880 		},
3881 		{ &hf_aim_fnac_id,
3882 		  { "FNAC ID", "aim.fnac.id", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }
3883 		},
3884 		{ &hf_aim_buddyname_len,
3885 		  { "Buddyname len", "aim.buddynamelen", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }
3886 		},
3887 		{ &hf_aim_buddyname,
3888 		  { "Buddy Name", "aim.buddyname", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }
3889 		},
3890 		{ &hf_aim_tlvcount,
3891 		  { "TLV Count", "aim.tlvcount", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL },
3892 		},
3893 		{ &hf_aim_snac_error,
3894 		  { "SNAC Error", "aim.snac.error", FT_UINT16, BASE_HEX, VALS(aim_snac_errors), 0x0, NULL, HFILL },
3895 		},
3896 		{ &hf_aim_userclass_unconfirmed,
3897 		  { "AOL Unconfirmed account flag", "aim.userclass.unconfirmed", FT_BOOLEAN, 32, TFS(&tfs_set_notset), CLASS_UNCONFIRMED, NULL, HFILL },
3898 		},
3899 		{ &hf_aim_userclass_administrator,
3900 		  { "AOL Administrator flag", "aim.userclass.administrator", FT_BOOLEAN, 32, TFS(&tfs_set_notset), CLASS_ADMINISTRATOR, NULL, HFILL },
3901 		},
3902 		{ &hf_aim_userclass_aol,
3903 		  { "AOL Staff User Flag", "aim.userclass.staff", FT_BOOLEAN, 32, TFS(&tfs_set_notset), CLASS_AOL, NULL, HFILL },
3904 		},
3905 		{ &hf_aim_userclass_commercial,
3906 		  { "AOL commercial account flag", "aim.userclass.commercial", FT_BOOLEAN, 32, TFS(&tfs_set_notset), CLASS_COMMERCIAL, NULL, HFILL },
3907 		},
3908 		{ &hf_aim_userclass_aim,
3909 		  { "AIM user flag", "aim.userclass.free", FT_BOOLEAN, 32, TFS(&tfs_set_notset), CLASS_AIM, NULL, HFILL },
3910 		},
3911 		{ &hf_aim_userclass_away,
3912 		  { "AOL away status flag", "aim.userclass.away", FT_BOOLEAN, 32, TFS(&tfs_set_notset), CLASS_AWAY, NULL, HFILL },
3913 		},
3914 		{ &hf_aim_userclass_icq,
3915 		  { "ICQ user sign", "aim.userclass.icq", FT_BOOLEAN, 32, TFS(&tfs_set_notset), CLASS_ICQ, NULL, HFILL },
3916 		},
3917 		{ &hf_aim_userclass_wireless,
3918 		  { "AOL wireless user", "aim.userclass.wireless", FT_BOOLEAN, 32, TFS(&tfs_set_notset), CLASS_WIRELESS, NULL, HFILL },
3919 		},
3920 		{ &hf_aim_userclass_unknown100,
3921 		  { "Unknown bit", "aim.userclass.unknown100", FT_BOOLEAN, 32, TFS(&tfs_set_notset), CLASS_UNKNOWN100, NULL, HFILL },
3922 		},
3923 		{ &hf_aim_userclass_imf,
3924 		  { "Using IM Forwarding", "aim.userclass.imf", FT_BOOLEAN, 32, TFS(&tfs_set_notset), CLASS_IMF, NULL, HFILL },
3925 		},
3926 		{ &hf_aim_userclass_bot,
3927 		  { "Bot User", "aim.userclass.bot", FT_BOOLEAN, 32, TFS(&tfs_set_notset), CLASS_BOT, NULL, HFILL },
3928 		},
3929 		{ &hf_aim_userclass_unknown800,
3930 		  { "Unknown bit", "aim.userclass.unknown800", FT_BOOLEAN, 32, TFS(&tfs_set_notset), CLASS_UNKNOWN800, NULL, HFILL },
3931 		},
3932 		{ &hf_aim_userclass_one_way_wireless,
3933 		  { "One Way Wireless Device", "aim.userclass.one_way_wireless", FT_BOOLEAN, 32, TFS(&tfs_set_notset), CLASS_ONE_WAY_WIRELESS, NULL, HFILL },
3934 		},
3935 		{ &hf_aim_userclass_unknown2000,
3936 		  { "Unknown bit", "aim.userclass.unknown2000", FT_BOOLEAN, 32, TFS(&tfs_set_notset), CLASS_UNKNOWN2000, NULL, HFILL },
3937 		},
3938 		{ &hf_aim_userclass_unknown4000,
3939 		  { "Unknown bit", "aim.userclass.unknown4000", FT_BOOLEAN, 32, TFS(&tfs_set_notset), CLASS_UNKNOWN4000, NULL, HFILL },
3940 		},
3941 		{ &hf_aim_userclass_unknown8000,
3942 		  { "Unknown bit", "aim.userclass.unknown8000", FT_BOOLEAN, 32, TFS(&tfs_set_notset), CLASS_UNKNOWN8000, NULL, HFILL },
3943 		},
3944 		{ &hf_aim_userclass_unknown10000,
3945 		  { "Unknown bit", "aim.userclass.unknown10000", FT_BOOLEAN, 32, TFS(&tfs_set_notset), CLASS_UNKNOWN10000, NULL, HFILL },
3946 		},
3947 		{ &hf_aim_userclass_unknown20000,
3948 		  { "Unknown bit", "aim.userclass.unknown20000", FT_BOOLEAN, 32, TFS(&tfs_set_notset), CLASS_UNKNOWN20000, NULL, HFILL },
3949 		},
3950 		{ &hf_aim_userclass_no_knock_knock,
3951 		  { "Do not display the 'not on Buddy List' knock-knock", "aim.userclass.no_knock_knock", FT_BOOLEAN, 32, TFS(&tfs_set_notset), CLASS_NO_KNOCK_KNOCK, NULL, HFILL },
3952 		},
3953 		{ &hf_aim_userclass_forward_mobile,
3954 		  { "Forward to mobile if not active", "aim.userclass.forward_mobile", FT_BOOLEAN, 32, TFS(&tfs_set_notset), CLASS_FORWARD_MOBILE, NULL, HFILL },
3955 		},
3956 		{ &hf_aim_nickinfo_caps,
3957 		  { "Client capabilities", "aim.nickinfo.caps", FT_GUID, BASE_NONE, NULL, 0x0, NULL, HFILL },
3958 		},
3959 		{ &hf_aim_nickinfo_short_caps,
3960 		  { "Short client capabilities", "aim.nickinfo.short_caps", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL },
3961 		},
3962 		{ &hf_aim_fnac_flag_next_is_related,
3963 		  { "Followed By SNAC with related information", "aim.fnac.flags.next_is_related", FT_BOOLEAN, 16, TFS(&tfs_set_notset), FNAC_FLAG_NEXT_IS_RELATED, NULL, HFILL },
3964 		},
3965 		{ &hf_aim_fnac_flag_contains_version,
3966 		  { "Contains Version of Family this SNAC is in", "aim.fnac.flags.contains_version", FT_BOOLEAN, 16, TFS(&tfs_set_notset), FNAC_FLAG_CONTAINS_VERSION, NULL, HFILL },
3967 		},
3968 		{ &hf_aim_userinfo_warninglevel,
3969 		  { "Warning Level", "aim.userinfo.warninglevel", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL },
3970 		},
3971 		{ &hf_aim_messageblock_featuresdes,
3972 		  { "Features", "aim.messageblock.featuresdes", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL },
3973 		},
3974 		{ &hf_aim_messageblock_featureslen,
3975 		  { "Features Length", "aim.messageblock.featureslen", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL },
3976 		},
3977 		{ &hf_aim_messageblock_features,
3978 		  { "Features", "aim.messageblock.features", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL },
3979 		},
3980 		{ &hf_aim_messageblock_info,
3981 		  { "Block info", "aim.messageblock.info", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL },
3982 		},
3983 		{ &hf_aim_messageblock_len,
3984 		  { "Block length", "aim.messageblock.length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL },
3985 		},
3986 		{ &hf_aim_messageblock_charset,
3987 		  { "Block Character set", "aim.messageblock.charset", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL },
3988 		},
3989 		{ &hf_aim_messageblock_charsubset,
3990 		  { "Block Character subset", "aim.messageblock.charsubset", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL },
3991 		},
3992 		{ &hf_aim_messageblock_message,
3993 		  { "Message", "aim.messageblock.message", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL },
3994 		},
3995 		{ &hf_aim_dcinfo_ip,
3996 		  { "Internal IP address", "aim.dcinfo.addr", FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL },
3997 		},
3998 		{ &hf_aim_dcinfo_tcpport,
3999 		  { "TCP Port", "aim.dcinfo.tcpport", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL },
4000 		},
4001 		{ &hf_aim_dcinfo_type,
4002 		  { "Type", "aim.dcinfo.type", FT_UINT8, BASE_HEX, VALS(dc_types), 0x0, NULL, HFILL },
4003 		},
4004 		{ &hf_aim_dcinfo_proto_version,
4005 		  { "Protocol Version", "aim.dcinfo.proto_version", FT_UINT16, BASE_DEC, VALS(protocol_versions), 0x0, NULL, HFILL },
4006 		},
4007 		{ &hf_aim_dcinfo_auth_cookie,
4008 		  { "Authorization Cookie", "aim.dcinfo.auth_cookie", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL },
4009 		},
4010 		{ &hf_aim_dcinfo_webport,
4011 		  { "Web Front Port", "aim.dcinfo.webport", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL },
4012 		},
4013 		{ &hf_aim_dcinfo_client_future,
4014 		  { "Client Futures", "aim.dcinfo.client_futures", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL },
4015 		},
4016 		{ &hf_aim_dcinfo_last_info_update,
4017 		  { "Last Info Update", "aim.dcinfo.last_info_update", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL },
4018 		},
4019 		{ &hf_aim_dcinfo_last_ext_info_update,
4020 		  { "Last Extended Info Update", "aim.dcinfo.last_ext_info_update", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL },
4021 		},
4022 		{ &hf_aim_dcinfo_last_ext_status_update,
4023 		  { "Last Extended Status Update", "aim.dcinfo.last_ext_status_update", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL },
4024 		},
4025 		{ &hf_aim_dcinfo_unknown,
4026 		  { "Unknown", "aim.dcinfo.unknown", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL },
4027 		},
4028 		{ &hf_aim_ssi_result_code,
4029 		  { "Last SSI operation result code", "aim.ssi.code", FT_UINT16, BASE_HEX, VALS(aim_ssi_result_codes), 0x0, NULL, HFILL },
4030 		},
4031 		{ &hf_aim_string08,
4032 		  { "Address/Port List", "aim.string08", FT_UINT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL },
4033 		},
4034 	};
4035 
4036 	static hf_register_info hf_admin[] = {
4037 		{ &hf_admin_acctinfo_code,
4038 		  { "Account Information Request Code", "aim_admin.acctinfo.code", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL },
4039 		},
4040 		{ &hf_admin_acctinfo_unknown,
4041 		  { "Unknown", "aim_admin.acctinfo.unknown", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL },
4042 		},
4043 		{ &hf_admin_acctinfo_permissions,
4044 		  { "Account Permissions", "aim_admin.acctinfo.permissions", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL },
4045 		},
4046 		{ &hf_admin_confirm_status,
4047 		  { "Confirmation status", "aim_admin.confirm_status", FT_UINT16, BASE_HEX, VALS(confirm_statusses), 0x0, NULL, HFILL },
4048 		},
4049 	};
4050 
4051 	static hf_register_info hf_bos[] = {
4052 #if 0
4053 		{ &hf_aim_bos_data,
4054 		  { "Data", "aim_bos.data", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }
4055 		},
4056 #endif
4057 		{ &hf_aim_bos_class,
4058 		  { "User class", "aim_bos.userclass", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL },
4059 		},
4060 	};
4061 
4062 	static hf_register_info hf_buddylist[] = {
4063 		{ &hf_aim_buddylist_userinfo_warninglevel,
4064 		  { "Warning Level", "aim_buddylist.userinfo.warninglevel", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL },
4065 		},
4066 	};
4067 
4068 	static hf_register_info hf_chat[] = {
4069 		{ &hf_aim_chat_screen_name,
4070 		  { "Screen Name", "aim_chat.screen_name", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL },
4071 		},
4072 	};
4073 
4074 	static hf_register_info hf_generic[] = {
4075 		{ &hf_generic_servicereq_service,
4076 		  { "Requested Service", "aim_generic.servicereq.service", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL },
4077 		},
4078 		{ &hf_generic_motd_motdtype,
4079 		  { "MOTD Type", "aim_generic.motd.motdtype", FT_UINT16, BASE_HEX, VALS(aim_snac_generic_motd_motdtypes), 0x0, NULL, HFILL },
4080 		},
4081 		{ &hf_generic_family,
4082 		  { "Family", "aim_generic.family", FT_UINT16, BASE_CUSTOM, CF_FUNC(aim_generic_family), 0x0, NULL, HFILL },
4083 		},
4084 		{ &hf_generic_version,
4085 		  { "Version", "aim_generic.version", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL },
4086 		},
4087 		{ &hf_generic_dll_version,
4088 		  { "DLL Version", "aim_generic.dll_version", FT_UINT24, BASE_DEC, NULL, 0x0, NULL, HFILL },
4089 		},
4090 		{ &hf_generic_rateinfo_numclasses,
4091 		  { "Number of Rateinfo Classes", "aim_generic.rateinfo.numclasses", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL },
4092 		},
4093 		{ &hf_generic_rateinfo_windowsize,
4094 		  { "Window Size", "aim_generic.rateinfo.class.window_size", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL },
4095 		},
4096 		{ &hf_generic_rateinfo_clearlevel,
4097 		  { "Clear Level", "aim_generic.rateinfo.class.clearlevel", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL },
4098 		},
4099 		{ &hf_generic_rateinfo_alertlevel,
4100 		  { "Alert Level", "aim_generic.rateinfo.class.alertlevel", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL },
4101 		},
4102 		{ &hf_generic_rateinfo_limitlevel,
4103 		  { "Limit Level", "aim_generic.rateinfo.class.limitlevel", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL },
4104 		},
4105 		{ &hf_generic_rateinfo_disconnectlevel,
4106 		  { "Disconnect Level", "aim_generic.rateinfo.class.disconnectlevel", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL },
4107 		},
4108 		{ &hf_generic_rateinfo_currentlevel,
4109 		  { "Current Level", "aim_generic.rateinfo.class.currentlevel", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL },
4110 		},
4111 		{ &hf_generic_rateinfo_maxlevel,
4112 		  { "Max Level", "aim_generic.rateinfo.class.maxlevel", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL },
4113 		},
4114 		{ &hf_generic_rateinfo_lasttime,
4115 		  { "Last Time", "aim_generic.rateinfo.class.lasttime", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL },
4116 		},
4117 		{ &hf_generic_rateinfo_curstate,
4118 		  { "Current State", "aim_generic.rateinfo.class.curstate", FT_UINT8, BASE_HEX, VALS(rateinfo_states), 0x0, NULL, HFILL },
4119 		},
4120 		{ &hf_generic_rateinfo_classid,
4121 		  { "Class ID", "aim_generic.rateinfo.class.id", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL },
4122 		},
4123 		{ &hf_generic_rateinfo_numpairs,
4124 		  { "Number of Family/Subtype pairs", "aim_generic.rateinfo.class.numpairs", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL },
4125 		},
4126 		{ &hf_generic_rateinfoack_group,
4127 		  { "Acknowledged Rate Class", "aim_generic.rateinfoack.class", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL },
4128 		},
4129 		{ &hf_generic_ratechange_msg,
4130 		  { "Rate Change Message", "aim_generic.ratechange.msg", FT_UINT16, BASE_HEX, VALS(ratechange_msgs), 0x0, NULL, HFILL },
4131 		},
4132 		{ &hf_generic_migration_numfams,
4133 		  { "Number of families to migrate", "aim_generic.migrate.numfams", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL },
4134 		},
4135 		{ &hf_generic_priv_flags,
4136 		  { "Privilege flags", "aim_generic.privilege_flags", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL },
4137 		},
4138 		{ &hf_generic_allow_idle_see,
4139 		  { "Allow other users to see idle time", "aim_generic.privilege_flags.allow_idle", FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x0001, NULL, HFILL },
4140 		},
4141 		{ &hf_generic_allow_member_see,
4142 		  { "Allow other users to see how long account has been a member", "aim_generic.privilege_flags.allow_member", FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x0002, NULL, HFILL },
4143 		},
4144 		{ &hf_generic_selfinfo_warninglevel,
4145 		    { "Warning level", "aim_generic.selfinfo.warn_level", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL },
4146 		},
4147 		{ &hf_generic_evil_new_warn_level,
4148 		    { "New warning level", "aim_generic.evil.new_warn_level", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL },
4149 		},
4150 		{ &hf_generic_idle_time,
4151 		    { "Idle time (seconds)", "aim_generic.idle_time", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL },
4152 		},
4153 		{ &hf_generic_client_ver_req_offset,
4154 		    { "Client Verification Request Offset", "aim_generic.client_verification.offset", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL },
4155 		},
4156 		{ &hf_generic_client_ver_req_length,
4157 		    { "Client Verification Request Length", "aim_generic.client_verification.length", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL },
4158 		},
4159 		{ &hf_generic_client_ver_req_hash,
4160 		    { "Client Verification MD5 Hash", "aim_generic.client_verification.hash", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL },
4161 		},
4162 		{ &hf_generic_ext_status_type,
4163 		    { "Extended Status Type", "aim_generic.ext_status.type", FT_UINT16, BASE_DEC, VALS(ext_status_types), 0x0, NULL, HFILL },
4164 		},
4165 		{ &hf_generic_ext_status_flags,
4166 		    { "Extended Status Flags", "aim_generic.ext_status.flags", FT_UINT8, BASE_HEX, VALS(ext_status_flags), 0x0, NULL, HFILL },
4167 		},
4168 		{ &hf_generic_ext_status_length,
4169 		    { "Extended Status Length", "aim_generic.ext_status.length", FT_UINT8, BASE_HEX, NULL, 0x0, NULL , HFILL },
4170 		},
4171 		{ &hf_generic_ext_status_data,
4172 		    { "Extended Status Data", "aim_generic.ext_status.data", FT_BYTES, BASE_NONE, NULL, 0x0, NULL , HFILL },
4173 		},
4174 	};
4175 
4176 	static hf_register_info hf_icq[] = {
4177 		{ &hf_icq_tlv_data_chunk_size,
4178 		  { "Data chunk size", "aim_icq.chunk_size", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL },
4179 		},
4180 		{ &hf_icq_tlv_request_owner_uid,
4181 		  { "Owner UID", "aim_icq.owner_uid", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL},
4182 		},
4183 		{ &hf_icq_tlv_request_type,
4184 		  {"Request Type", "aim_icq.request_type", FT_UINT16, BASE_DEC, VALS(aim_icq_data_types), 0x0, NULL, HFILL},
4185 		},
4186 		{ &hf_icq_tlv_request_seq_num,
4187 		  {"Request Sequence Number", "aim_icq.request_seq_number", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL},
4188 		},
4189 		{ &hf_icq_dropped_msg_flag,
4190 		  {"Dropped messages flag", "aim_icq.offline_msgs.dropped_flag", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL },
4191 		},
4192 		{ &hf_icq_meta_subtype,
4193 		  {"Meta Request Subtype", "aim_icq.subtype", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL },
4194 		},
4195 	};
4196 
4197 	static hf_register_info hf_location[] = {
4198 		{ &hf_aim_location_buddyname_len,
4199 		  { "Buddyname len", "aim_location.buddynamelen", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }
4200 		},
4201 		{ &hf_aim_location_buddyname,
4202 		  { "Buddy Name", "aim_location.buddyname", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }
4203 		},
4204 		{ &hf_aim_location_userinfo_warninglevel,
4205 		  { "Warning Level", "aim_location.userinfo.warninglevel", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL },
4206 		},
4207 		{ &hf_aim_snac_location_request_user_info_infotype,
4208 		  { "Infotype", "aim_location.snac.request_user_info.infotype", FT_UINT16, BASE_HEX, VALS(aim_snac_location_request_user_info_infotypes), 0x0, NULL, HFILL }
4209 		},
4210 	};
4211 
4212 	static hf_register_info hf_messaging[] = {
4213 		{ &hf_aim_icbm_channel,
4214 		  { "Channel", "aim_messaging.icbm.channel",
4215 		  FT_UINT16, BASE_HEX, VALS(icbm_channel_types), 0x0, NULL, HFILL }
4216 		},
4217 		{ &hf_aim_icbm_msg_flags,
4218 		  { "Message Flags", "aim_messaging.icbm.flags",
4219 		  FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }
4220 		},
4221 		{ &hf_aim_icbm_max_snac_size,
4222 		  { "Max SNAC Size", "aim_messaging.icbm.max_snac",
4223 		  FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }
4224 		},
4225 		{ &hf_aim_icbm_max_sender_warnlevel,
4226 		  { "Max sender warn level", "aim_messaging.icbm.max_sender_warn-level",
4227 		  FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }
4228 		},
4229 		{ &hf_aim_icbm_max_receiver_warnlevel,
4230 		  { "max receiver warn level", "aim_messaging.icbm.max_receiver_warnlevel",
4231 		  FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }
4232 		},
4233 		{ &hf_aim_icbm_min_msg_interval,
4234 		  { "Minimum message interval (milliseconds)", "aim_messaging.icbm.min_msg_interval",
4235 		  FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
4236 		},
4237 		{ &hf_aim_icbm_cookie,
4238 		  { "ICBM Cookie", "aim_messaging.icbmcookie",
4239 		  FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }
4240 		},
4241 		{ &hf_aim_message_channel_id,
4242 		  { "Message Channel ID", "aim_messaging.channelid",
4243 		  FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }
4244 		},
4245 		{ &hf_aim_icbm_evil,
4246 		  { "Send Evil Bit As", "aim_messaging.evilreq.origin",
4247 		  FT_UINT16, BASE_DEC, VALS(evil_origins), 0x0, NULL, HFILL }
4248 		},
4249 		{ &hf_aim_evil_warn_level,
4250 		  { "Old warning level", "aim_messaging.evil.warn_level",
4251 		  FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
4252 		},
4253 		{ &hf_aim_evil_new_warn_level,
4254 		  { "New warning level", "aim_messaging.evil.new_warn_level",
4255 		  FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
4256 		},
4257 		{ &hf_aim_icbm_notification_cookie,
4258 		  { "Notification Cookie", "aim_messaging.notification.cookie",
4259 		  FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }
4260 		},
4261 		{ &hf_aim_icbm_notification_channel,
4262 		  { "Notification Channel", "aim_messaging.notification.channel",
4263 		  FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
4264 		},
4265 		{ &hf_aim_icbm_notification_type,
4266 		  { "Notification Type", "aim_messaging.notification.type",
4267 		  FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
4268 		},
4269 		{ &hf_aim_icbm_rendezvous_nak,
4270 		  { "Rendezvous NAK reason", "aim_messaging.rendezvous_nak",
4271 		  FT_UINT16, BASE_HEX, VALS(rendezvous_nak_reason_types), 0x0, NULL, HFILL }
4272 		},
4273 		{ &hf_aim_icbm_rendezvous_nak_length,
4274 		  { "Rendezvous NAK reason length", "aim_messaging.rendezvous_nak_length",
4275 		  FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }
4276 		},
4277 		{ &hf_aim_rendezvous_msg_type,
4278 		  { "Message Type", "aim_messaging.rendezvous.msg_type",
4279 		  FT_UINT16, BASE_HEX, VALS(rendezvous_msg_types), 0x0, NULL, HFILL }
4280 		},
4281 		{ &hf_aim_icbm_client_err_reason,
4282 		  { "Reason", "aim_messaging.clienterr.reason",
4283 		  FT_UINT16, BASE_DEC, VALS(client_err_reason_types), 0x0, NULL, HFILL }
4284 		},
4285 		{ &hf_aim_icbm_client_err_protocol_version,
4286 		  { "Version", "aim_messaging.clienterr.protocol_version",
4287 		  FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
4288 		},
4289 		{ &hf_aim_icbm_client_err_client_caps_flags,
4290 		  { "Client Capabilities Flags", "aim_messaging.clienterr.client_caps_flags",
4291 		  FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }
4292 		},
4293 		{ &hf_aim_rendezvous_extended_data_message_type,
4294 		  { "Message Type", "aim_messaging.icbm.extended_data.message.type",
4295 		  FT_UINT8, BASE_HEX, VALS(extended_data_message_types), 0x0, NULL, HFILL }
4296 		},
4297 		{ &hf_aim_rendezvous_extended_data_message_flags,
4298 		  { "Message Flags", "aim_messaging.icbm.extended_data.message.flags",
4299 		  FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }
4300 		},
4301 		{ &hf_aim_rendezvous_extended_data_message_flags_normal,
4302 		  { "Normal Message", "aim_messaging.icbm.extended_data.message.flags.normal",
4303 		  FT_BOOLEAN, 16, TFS(&tfs_set_notset), EXTENDED_DATA_MFLAG_NORMAL, NULL, HFILL }
4304 		},
4305 		{ &hf_aim_rendezvous_extended_data_message_flags_auto,
4306 		  { "Auto Message", "aim_messaging.icbm.extended_data.message.flags.auto",
4307 		  FT_BOOLEAN, 16, TFS(&tfs_set_notset), EXTENDED_DATA_MFLAG_AUTO, NULL, HFILL }
4308 		},
4309 		{ &hf_aim_rendezvous_extended_data_message_flags_multi,
4310 		  { "Multiple Recipients Message", "aim_messaging.icbm.rendezvous.extended_data.message.flags.multi",
4311 		  FT_BOOLEAN, 16, TFS(&tfs_set_notset), EXTENDED_DATA_MFLAG_MULTI, NULL, HFILL }
4312 		},
4313 		{ &hf_aim_rendezvous_extended_data_message_status_code,
4314 		  { "Status Code", "aim_messaging.icbm.extended_data.message.status_code",
4315 		  FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
4316 		},
4317 		{ &hf_aim_rendezvous_extended_data_message_priority_code,
4318 		  { "Priority Code", "aim_messaging.icbm.extended_data.message.priority_code",
4319 		  FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
4320 		},
4321 		{ &hf_aim_rendezvous_extended_data_message_text_length,
4322 		  { "Text Length", "aim_messaging.icbm.extended_data.message.text_length",
4323 		  FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
4324 		},
4325 		{ &hf_aim_rendezvous_extended_data_message_text,
4326 		  { "Text", "aim_messaging.icbm.extended_data.message.text",
4327 		  FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }
4328 		},
4329 		/* Generated from convert_proto_tree_add_text.pl */
4330 		{ &hf_aim_messaging_plugin, { "Plugin", "aim_messaging.plugin", FT_GUID, BASE_NONE, NULL, 0x0, NULL, HFILL }},
4331 		{ &hf_aim_icbm_client_err_length, { "Length", "aim_messaging.clienterr.length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
4332 		{ &hf_aim_messaging_unknown_uint8, { "Unknown", "aim_messaging.unknown_uint8", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
4333 		{ &hf_aim_messaging_unknown_uint16, { "Unknown", "aim_messaging.unknown_uint16", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
4334 		{ &hf_aim_icbm_client_err_downcounter, { "Downcounter?", "aim_messaging.clienterr.downcounter", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
4335 		{ &hf_aim_messaging_unknown_data, { "Unknown", "aim_messaging.unknown_bytes", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
4336 		{ &hf_aim_messaging_plugin_specific_data, { "Plugin-specific data", "aim_messaging.plugin_specific_data", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
4337 	};
4338 
4339 	static hf_register_info hf_signon[] = {
4340 		{ &hf_aim_infotype,
4341 		  { "Infotype", "aim_signon.infotype", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }
4342 		},
4343 		{ &hf_aim_signon_challenge_len,
4344 		  { "Signon challenge length", "aim_signon.challengelen", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
4345 		},
4346 		{ &hf_aim_signon_challenge,
4347 		  { "Signon challenge", "aim_signon.challenge", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }
4348 		},
4349 	};
4350 
4351 	static hf_register_info hf_ssi[] = {
4352 		{ &hf_aim_fnac_subtype_ssi_version,
4353 		  { "SSI Version", "aim_ssi.fnac.version", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }
4354 		},
4355 		{ &hf_aim_fnac_subtype_ssi_numitems,
4356 		  { "SSI Object count", "aim_ssi.fnac.numitems", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }
4357 		},
4358 		{ &hf_aim_fnac_subtype_ssi_last_change_time,
4359 		  { "SSI Last Change Time", "aim_ssi.fnac.last_change_time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0, NULL, HFILL }
4360 		},
4361 		{ &hf_aim_fnac_subtype_ssi_buddyname_len,
4362 		  { "SSI Buddy Name length", "aim_ssi.fnac.buddyname_len", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }
4363 		},
4364 		{ &hf_aim_fnac_subtype_ssi_buddyname,
4365 		  { "Buddy Name", "aim_ssi.fnac.buddyname", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }
4366 		},
4367 		{ &hf_aim_fnac_subtype_ssi_gid,
4368 		  { "SSI Buddy Group ID", "aim_ssi.fnac.gid", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }
4369 		},
4370 		{ &hf_aim_fnac_subtype_ssi_bid,
4371 		  { "SSI Buddy ID", "aim_ssi.fnac.bid", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }
4372 		},
4373 		{ &hf_aim_fnac_subtype_ssi_type,
4374 		  { "SSI Buddy type", "aim_ssi.fnac.type", FT_UINT16, BASE_HEX, VALS(aim_fnac_family_ssi_types), 0x0, NULL, HFILL }
4375 		},
4376 		{ &hf_aim_fnac_subtype_ssi_tlvlen,
4377 		  { "SSI TLV Len", "aim_ssi.fnac.tlvlen", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }
4378 		},
4379 #if 0
4380 		{ &hf_aim_fnac_subtype_ssi_data,
4381 		  { "SSI Buddy Data", "aim_ssi.fnac.data", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }
4382 		},
4383 #endif
4384 		{ &hf_aim_fnac_subtype_ssi_buddyname_len8,
4385 		  { "SSI Buddy Name length", "aim_ssi.fnac.buddyname_len8", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }
4386 		},
4387 		{ &hf_aim_fnac_subtype_ssi_reason_str_len,
4388 		  { "Reason Message length", "aim_ssi.fnac.reason_len", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }
4389 		},
4390 		{ &hf_aim_fnac_subtype_ssi_reason_str,
4391 		  { "Reason Message", "aim_ssi.fnac.reason", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }
4392 		},
4393 		{ &hf_aim_fnac_subtype_ssi_grant_auth_unkn,
4394 		  { "Unknown", "aim_ssi.fnac.auth_unkn", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }
4395 		},
4396 		{ &hf_aim_fnac_subtype_ssi_allow_auth,
4397 		  { "Allow flag", "aim_ssi.fnac.allow_auth_flag", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }
4398 		},
4399 	};
4400 
4401 	static hf_register_info hf_sst[] = {
4402 		{ &hf_aim_sst_md5_hash,
4403 		  { "MD5 Hash", "aim_sst.md5", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL },
4404 		},
4405 		{ &hf_aim_sst_md5_hash_size,
4406 		  { "MD5 Hash Size", "aim_sst.md5.size", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL },
4407 		},
4408 		{ &hf_aim_sst_unknown,
4409 		  { "Unknown Data", "aim_sst.unknown", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL },
4410 		},
4411 		{ &hf_aim_sst_ref_num,
4412 		  { "Reference Number", "aim_sst.ref_num", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL },
4413 		},
4414 		{ &hf_aim_sst_icon_size,
4415 		  { "Icon Size", "aim_sst.icon_size", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL },
4416 		},
4417 		{ &hf_aim_sst_icon,
4418 		  { "Icon", "aim_sst.icon", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL },
4419 		},
4420 	};
4421 
4422 	static hf_register_info hf_userlookup[] = {
4423 		{ &hf_aim_userlookup_email,
4424 		  { "Email address looked for", "aim_lookup.email", FT_STRING, BASE_NONE, NULL, 0, "Email address", HFILL }
4425 		},
4426 	};
4427 
4428 	/* Setup protocol subtree array */
4429 	static gint *ett[] = {
4430 		&ett_aim,
4431 		&ett_aim_dcinfo,
4432 		&ett_aim_fnac,
4433 		&ett_aim_fnac_flags,
4434 		&ett_aim_tlv,
4435 		&ett_aim_tlv_value,
4436 		&ett_aim_buddyname,
4437 		&ett_aim_userclass,
4438 		&ett_aim_messageblock,
4439 		&ett_aim_nickinfo_caps,
4440 		&ett_aim_nickinfo_short_caps,
4441 		&ett_aim_string08_array,
4442 
4443 		&ett_aim_admin,
4444 		&ett_aim_adverts,
4445 		&ett_aim_bos,
4446 		&ett_aim_buddylist,
4447 		&ett_aim_chat,
4448 		&ett_aim_chatnav,
4449 		&ett_aim_directory,
4450 		&ett_aim_email,
4451 
4452 		&ett_generic_clientready,
4453 		&ett_generic_migratefamilies,
4454 		&ett_generic_clientready_item,
4455 		&ett_generic_serverready,
4456 		&ett_generic,
4457 		&ett_generic_priv_flags,
4458 		&ett_generic_rateinfo_class,
4459 		&ett_generic_rateinfo_classes,
4460 		&ett_generic_rateinfo_groups,
4461 		&ett_generic_rateinfo_group,
4462 
4463 		&ett_aim_icq,
4464 		&ett_aim_icq_tlv,
4465 		&ett_aim_invitation,
4466 		&ett_aim_location,
4467 		&ett_aim_messaging,
4468 		&ett_aim_rendezvous_data,
4469 		&ett_aim_extended_data,
4470 		&ett_aim_extended_data_message_flags,
4471 		&ett_aim_popup,
4472 		&ett_aim_signon,
4473 		&ett_aim_ssi,
4474 		&ett_ssi,
4475 		&ett_aim_sst,
4476 		&ett_aim_stats,
4477 		&ett_aim_translate,
4478 		&ett_aim_userlookup,
4479 
4480 	};
4481 
4482 	static ei_register_info ei[] = {
4483 		{ &ei_aim_messageblock_len, { "aim.messageblock.length.invalid", PI_PROTOCOL, PI_WARN, "Invalid block length", EXPFILL }},
4484 	};
4485 
4486 	module_t *aim_module;
4487 	expert_module_t *expert_aim;
4488 
4489 	/* Register the protocol name and description */
4490 	proto_aim = proto_register_protocol("AOL Instant Messenger", "AIM", "aim");
4491 	proto_aim_admin = proto_register_protocol("AIM Administrative", "AIM Administration", "aim_admin");
4492 	proto_aim_adverts = proto_register_protocol("AIM Advertisements", "AIM Advertisements", "aim_adverts");
4493 	proto_aim_bos = proto_register_protocol("AIM Privacy Management Service", "AIM BOS", "aim_bos");
4494 	proto_aim_buddylist = proto_register_protocol("AIM Buddylist Service", "AIM Buddylist", "aim_buddylist");
4495 	proto_aim_chat = proto_register_protocol("AIM Chat Service", "AIM Chat", "aim_chat");
4496 	proto_aim_chatnav = proto_register_protocol("AIM Chat Navigation", "AIM ChatNav", "aim_chatnav");
4497 	proto_aim_directory = proto_register_protocol("AIM Directory Search", "AIM Directory", "aim_dir");
4498 	proto_aim_email = proto_register_protocol("AIM E-mail", "AIM Email", "aim_email");
4499 	proto_aim_generic = proto_register_protocol("AIM Generic Service", "AIM Generic", "aim_generic");
4500 	proto_aim_icq = proto_register_protocol("AIM ICQ", "AIM ICQ", "aim_icq");
4501 	proto_aim_invitation = proto_register_protocol("AIM Invitation Service", "AIM Invitation", "aim_invitation");
4502 	proto_aim_location = proto_register_protocol("AIM Location", "AIM Location", "aim_location");
4503 	proto_aim_messaging = proto_register_protocol("AIM Messaging", "AIM Messaging", "aim_messaging");
4504 	proto_aim_popup = proto_register_protocol("AIM Popup", "AIM Popup", "aim_popup");
4505 	proto_aim_signon = proto_register_protocol("AIM Signon", "AIM Signon", "aim_signon");
4506 	proto_aim_ssi = proto_register_protocol("AIM Server Side Info", "AIM SSI", "aim_ssi");
4507 	proto_aim_sst = proto_register_protocol("AIM Server Side Themes", "AIM SST", "aim_sst");
4508 	proto_aim_stats = proto_register_protocol("AIM Statistics", "AIM Stats", "aim_stats");
4509 	proto_aim_translate = proto_register_protocol("AIM Translate", "AIM Translate", "aim_translate");
4510 	proto_aim_userlookup = proto_register_protocol("AIM User Lookup", "AIM User Lookup", "aim_lookup");
4511 
4512 	proto_register_field_array(proto_aim, hf, array_length(hf));
4513 	proto_register_field_array(proto_aim_admin, hf_admin, array_length(hf_admin));
4514 	proto_register_field_array(proto_aim_bos, hf_bos, array_length(hf_bos));
4515 	proto_register_field_array(proto_aim_buddylist, hf_buddylist, array_length(hf_buddylist));
4516 	proto_register_field_array(proto_aim_chat, hf_chat, array_length(hf_chat));
4517 	proto_register_field_array(proto_aim_generic, hf_generic, array_length(hf_generic));
4518 	proto_register_field_array(proto_aim_icq, hf_icq, array_length(hf_icq));
4519 	proto_register_field_array(proto_aim_location, hf_location, array_length(hf_location));
4520 	proto_register_field_array(proto_aim_messaging, hf_messaging, array_length(hf_messaging));
4521 	proto_register_field_array(proto_aim_signon, hf_signon, array_length(hf_signon));
4522 	proto_register_field_array(proto_aim_ssi, hf_ssi, array_length(hf_ssi));
4523 	proto_register_field_array(proto_aim_sst, hf_sst, array_length(hf_sst));
4524 	proto_register_field_array(proto_aim_userlookup, hf_userlookup, array_length(hf_userlookup));
4525 
4526 	proto_register_subtree_array(ett, array_length(ett));
4527 
4528 	expert_aim = expert_register_protocol(proto_aim);
4529 	expert_register_field_array(expert_aim, ei, array_length(ei));
4530 
4531 	aim_handle = register_dissector("aim", dissect_aim, proto_aim);
4532 
4533 	aim_module = prefs_register_protocol(proto_aim, NULL);
4534 
4535 
4536 	prefs_register_bool_preference(aim_module, "desegment",
4537 				       "Reassemble AIM messages spanning multiple TCP segments",
4538 				       "Whether the AIM dissector should reassemble messages spanning multiple TCP segments."
4539 				       " To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
4540 				       &aim_desegment);
4541 
4542 	register_shutdown_routine(aim_shutdown);
4543 }
4544 
4545 void
4546 proto_reg_handoff_aim(void)
4547 {
4548 	/* TCP ports preference */
4549 	dissector_add_uint_range_with_preference("tcp.port", TCP_PORTS_AIM_DEFAULT, aim_handle);
4550 
4551 	ssl_dissector_add(0, aim_handle);
4552 	/* Heuristics disabled by default, it is really weak... */
4553 	heur_dissector_add("tls", dissect_aim_ssl_heur, "AIM over TLS", "aim_tls", proto_aim, HEURISTIC_DISABLE);
4554 
4555 
4556 	aim_init_family(proto_aim_admin, ett_aim_admin, FAMILY_ADMIN, aim_fnac_family_admin);
4557 	aim_init_family(proto_aim_adverts, ett_aim_adverts, FAMILY_ADVERTS, aim_fnac_family_adverts);
4558 	aim_init_family(proto_aim_bos, ett_aim_bos, FAMILY_BOS, aim_fnac_family_bos);
4559 	aim_init_family(proto_aim_buddylist, ett_aim_buddylist, FAMILY_BUDDYLIST, aim_fnac_family_buddylist);
4560 	aim_init_family(proto_aim_chat, ett_aim_chat, FAMILY_CHAT, aim_fnac_family_chat);
4561 	aim_init_family(proto_aim_chatnav, ett_aim_chatnav, FAMILY_CHAT_NAV, aim_fnac_family_chatnav);
4562 	aim_init_family(proto_aim_directory, ett_aim_directory, FAMILY_DIRECTORY, aim_fnac_family_directory);
4563 	aim_init_family(proto_aim_email, ett_aim_email, FAMILY_EMAIL, aim_fnac_family_email);
4564 	aim_init_family(proto_aim_generic, ett_generic, FAMILY_GENERIC, aim_fnac_family_generic);
4565 	aim_init_family(proto_aim_icq, ett_aim_icq, FAMILY_ICQ, aim_fnac_family_icq);
4566 	aim_init_family(proto_aim_invitation, ett_aim_invitation, FAMILY_INVITATION, aim_fnac_family_invitation);
4567 	aim_init_family(proto_aim_location, ett_aim_location, FAMILY_LOCATION, aim_fnac_family_location);
4568 	aim_init_family(proto_aim_messaging, ett_aim_messaging, FAMILY_MESSAGING, aim_fnac_family_messaging);
4569 	aim_init_family(proto_aim_popup, ett_aim_popup, FAMILY_POPUP, aim_fnac_family_popup);
4570 	aim_init_family(proto_aim_signon, ett_aim_signon, FAMILY_SIGNON, aim_fnac_family_signon);
4571 	aim_init_family(proto_aim_ssi, ett_aim_ssi, FAMILY_SSI, aim_fnac_family_ssi);
4572 	aim_init_family(proto_aim_sst, ett_aim_sst, FAMILY_SST, aim_fnac_family_sst);
4573 	aim_init_family(proto_aim_stats, ett_aim_stats, FAMILY_STATS, aim_fnac_family_stats);
4574 	aim_init_family(proto_aim_translate, ett_aim_translate, FAMILY_TRANSLATE, aim_fnac_family_translate);
4575 	aim_init_family(proto_aim_userlookup, ett_aim_userlookup, FAMILY_USERLOOKUP, aim_fnac_family_userlookup);
4576 }
4577 
4578 
4579 /*
4580  * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
4581  *
4582  * Local variables:
4583  * c-basic-offset: 8
4584  * tab-width: 8
4585  * indent-tabs-mode: t
4586  * End:
4587  *
4588  * vi: set shiftwidth=8 tabstop=8 noexpandtab:
4589  * :indentSize=8:tabSize=8:noTabs=false:
4590  */
4591