Huge thanks to our Platinum Members Endace and LiveAction,
and our Silver Member Veeam, for supporting the Wireshark Foundation and project.

Ethereal-dev: [Ethereal-dev] [PATCH] More AIM updates

Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.

From: Jelmer Vernooij <jelmer@xxxxxxxxxxx>
Date: Mon, 19 Apr 2004 23:02:07 +0200
Hi, 

Here's another update to the AIM dissector. 

This patch adds support for a couple more SNAC's. TLV's are 
now handled in a somewhat more extendible manner It also fixes
a bug in the buddylist dissector that caused pango warnings. 

I hope to get another set of updates (perhaps the ICQ SNAC) ready in
one to two weeks.

Cheers,

Jelmer
-- 
Jelmer Vernooij <jelmer@xxxxxxxxxxx> - http://jelmer.vernstok.nl/
? TODO-aim
? current.diff
? ethereal-aim-5.diff
? ethereal-aim-6.diff
? ethereal-aim-6.diff.info
? gtk/.main.c.swp
Index: packet-aim-admin.c
===================================================================
RCS file: /cvsroot/ethereal/packet-aim-admin.c,v
retrieving revision 1.1
diff -u -3 -p -d -u -r1.1 packet-aim-admin.c
--- packet-aim-admin.c	23 Mar 2004 06:21:16 -0000	1.1
+++ packet-aim-admin.c	19 Apr 2004 20:59:20 -0000
@@ -39,8 +39,6 @@
 
 #include "packet-aim.h"
 
-#define MAX_BUDDYNAME_LENGTH 30
-
 #define FAMILY_ADMIN      0x0007
 
 /* Family Admin */
@@ -65,11 +63,23 @@ static const value_string aim_fnac_famil
   { 0, NULL }
 };
 
+#define CONFIRM_STATUS_EMAIL_SENT 		 0x00
+#define CONFIRM_STATUS_ALREADY_CONFIRMED 0x1E
+#define CONFIRM_STATUS_SERVER_ERROR	     0x23
+
+static const value_string confirm_statusses[] = {
+	{ CONFIRM_STATUS_EMAIL_SENT, "A confirmation email has been sent" },
+	{ CONFIRM_STATUS_ALREADY_CONFIRMED, "Account was already confirmed" },
+	{ CONFIRM_STATUS_SERVER_ERROR, "Server couldn't start confirmation process" },
+	{ 0, NULL }
+};
+
 /* Initialize the protocol and registered fields */
 static int proto_aim_admin = -1;
 static int hf_admin_acctinfo_code = -1;
 static int hf_admin_acctinfo_permissions = -1;
 static int hf_admin_acctinfo_tlvcount = -1;
+static int hf_admin_confirm_status = -1;
 
 /* Initialize the subtree pointers */
 static gint ett_aim_admin          = -1;
@@ -86,11 +96,14 @@ static int dissect_aim_admin(tvbuff_t *t
     }
 	
 	switch(aiminfo->subtype) {
+	case FAMILY_ADMIN_ERROR:
+		return dissect_aim_snac_error(tvb, pinfo, 0, admin_tree);
 	case FAMILY_ADMIN_ACCNT_INFO_REQ:
 		proto_tree_add_item(admin_tree, hf_admin_acctinfo_code, tvb, 0, 2, tvb_get_ntohs(tvb, 0)); 
 		proto_tree_add_text(admin_tree, tvb, 2, 2, "Unknown");
 		return 4;
 		
+	case FAMILY_ADMIN_INFOCHANGEREPLY:
     case FAMILY_ADMIN_ACCNT_INFO_REPL:
 		{
 			guint16 numtlvs, i;
@@ -103,11 +116,19 @@ static int dissect_aim_admin(tvbuff_t *t
 		}
 		return offset;
 	case FAMILY_ADMIN_INFOCHANGEREQ:
-	case FAMILY_ADMIN_INFOCHANGEREPLY:
+		while(tvb_length_remaining(tvb, offset) > 0) {
+			offset = dissect_aim_tlv(tvb, pinfo, offset, admin_tree);
+		}
+		return offset;
 	case FAMILY_ADMIN_ACCT_CFRM_REQ:
-	case FAMILY_ADMIN_ACCT_CFRM_REPL:
-		/* FIXME */
+		/* No data */
 		return 0;
+	case FAMILY_ADMIN_ACCT_CFRM_REPL:
+		proto_tree_add_uint(admin_tree, hf_admin_confirm_status, tvb, offset, 2, tvb_get_ntohs(tvb, offset)); offset+=2;
+		while(tvb_length_remaining(tvb, offset) > 0) {
+			offset = dissect_aim_tlv(tvb, pinfo, offset, admin_tree);
+		}
+		return offset;
 
 	default: return 0;
 	}
@@ -130,6 +151,9 @@ proto_register_aim_admin(void)
 	  { &hf_admin_acctinfo_tlvcount,
 		  { "TLV Count", "aim.acctinfo.tlvcount", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL },
 	  },
+	  { &hf_admin_confirm_status,
+		  { "Confirmation status", "admin.confirm_status", FT_UINT16, BASE_HEX, VALS(confirm_statusses), 0x0, "", HFILL },
+																					 },
   };
 
 /* Setup protocol subtree array */
Index: packet-aim-adverts.c
===================================================================
RCS file: /cvsroot/ethereal/packet-aim-adverts.c,v
retrieving revision 1.2
diff -u -3 -p -d -u -r1.2 packet-aim-adverts.c
--- packet-aim-adverts.c	23 Mar 2004 18:36:05 -0000	1.2
+++ packet-aim-adverts.c	19 Apr 2004 20:59:20 -0000
@@ -75,7 +75,7 @@ static int dissect_aim_adverts(tvbuff_t 
 		break;
 		case FAMILY_ADVERTS_REQUEST:
 		case FAMILY_ADVERTS_DATA:
-		/* FIXME */
+		/* FIXME: */
 		return 0;
 	}
 
Index: packet-aim-bos.c
===================================================================
RCS file: /cvsroot/ethereal/packet-aim-bos.c,v
retrieving revision 1.1
diff -u -3 -p -d -u -r1.1 packet-aim-bos.c
--- packet-aim-bos.c	23 Mar 2004 06:21:16 -0000	1.1
+++ packet-aim-bos.c	19 Apr 2004 20:59:20 -0000
@@ -78,6 +78,9 @@ static const value_string aim_fnac_famil
 #define CLASS_UNKNOWN400		     0x0400
 #define CLASS_UNKNOWN800		     0x0800
 
+static const aim_tlv bos_tlvs[] = {
+	{ 0, "Unknown", 0 },
+};
 
 /* Initialize the protocol and registered fields */
 static int proto_aim_bos = -1;
@@ -138,12 +141,18 @@ proto_tree_add_boolean(entry, hf_aim_bos
 			}
 			return 4;
 		case FAMILY_BOS_RIGHTS:
+			while(tvb_length_remaining(tvb, offset) > 0) {
+				offset = dissect_aim_tlv_specific(tvb, pinfo, offset, bos_tree, bos_tlvs);
+			}
+			return offset;
 		case FAMILY_BOS_ADD_TO_VISIBLE:
 		case FAMILY_BOS_DEL_FROM_VISIBLE:
 	  	case FAMILY_BOS_ADD_TO_INVISIBLE:
 	  	case FAMILY_BOS_DEL_FROM_INVISIBLE:
-			/* FIXME */
-			return 0;
+			while(tvb_length_remaining(tvb, offset) > 0) {
+				offset = dissect_aim_buddyname(tvb, pinfo, offset, bos_tree);
+			}
+			return offset;
 			
 		default:
 			return 0;
Index: packet-aim-buddylist.c
===================================================================
RCS file: /cvsroot/ethereal/packet-aim-buddylist.c,v
retrieving revision 1.1
diff -u -3 -p -d -u -r1.1 packet-aim-buddylist.c
--- packet-aim-buddylist.c	23 Mar 2004 06:21:16 -0000	1.1
+++ packet-aim-buddylist.c	19 Apr 2004 20:59:20 -0000
@@ -86,6 +86,14 @@ static int dissect_aim_snac_buddylist(tv
   guint16 tlv_count = 0;
   struct aiminfo *aiminfo = pinfo->private_data;
   int offset = 0;
+  proto_item *ti;
+  proto_tree *buddy_tree = NULL;
+
+  if(tree) {
+	  ti = proto_tree_add_text(tree, tvb, 0, -1, "Buddy List Service");
+	  buddy_tree = proto_item_add_subtree(ti, ett_aim_buddylist);   
+  }
+
 
   switch(aiminfo->subtype)
     {
@@ -93,15 +101,22 @@ static int dissect_aim_snac_buddylist(tv
 	case FAMILY_BUDDYLIST_WATCHERS_REQ:
 		/* No data */
 		return 0;
-	case FAMILY_BUDDYLIST_ERROR:
-      return dissect_aim_snac_error(tvb, pinfo, offset, tree);
-	case FAMILY_BUDDYLIST_RIGHTSINFO:
-	case FAMILY_BUDDYLIST_ADDBUDDY:
 	case FAMILY_BUDDYLIST_REMBUDDY:
+	case FAMILY_BUDDYLIST_ADDBUDDY:
 	case FAMILY_BUDDYLIST_WATCHERS_REP:
+		while(tvb_length_remaining(tvb, offset) > 0) {
+			offset = dissect_aim_buddyname( tvb, pinfo, offset, buddy_tree);
+		}
+		return offset;
+	case FAMILY_BUDDYLIST_ERROR:
+      return dissect_aim_snac_error(tvb, pinfo, offset, buddy_tree);
+	case FAMILY_BUDDYLIST_RIGHTSINFO:
+		while(tvb_length_remaining(tvb, offset) > 0) {
+			offset = dissect_aim_tlv_buddylist( tvb, pinfo, offset, buddy_tree);
+		}
+		return offset;
 	case FAMILY_BUDDYLIST_REJECT:
-	  /* FIXME */
-	  return 0;
+		return dissect_aim_buddyname(tvb, pinfo, offset, buddy_tree);
     case FAMILY_BUDDYLIST_ONCOMING:
       buddyname_length = aim_get_buddyname( buddyname, tvb, offset, offset + 1 );
 
@@ -110,25 +125,25 @@ static int dissect_aim_snac_buddylist(tv
 	col_append_fstr(pinfo->cinfo, COL_INFO, ": %s", buddyname);
       }
       
-      if (tree) {
-	proto_tree_add_text(tree, tvb, offset + 1, buddyname_length, 
+      if (buddy_tree) {
+	proto_tree_add_text(buddy_tree, tvb, offset + 1, buddyname_length, 
 			    "Screen Name: %s", buddyname);
       }
       offset += buddyname_length + 1;
 
       /* Warning level */
-      proto_tree_add_item(tree, hf_aim_userinfo_warninglevel, tvb, offset, 
+      proto_tree_add_item(buddy_tree, hf_aim_userinfo_warninglevel, tvb, offset, 
 			  2, FALSE);
       offset += 2;
       
       /* TLV Count */
       tlv_count = tvb_get_ntohs(tvb, offset);
-      proto_tree_add_item(tree, hf_aim_userinfo_tlvcount, tvb, offset, 
+      proto_tree_add_item(buddy_tree, hf_aim_userinfo_tlvcount, tvb, offset, 
 			  2, FALSE);
       offset += 2;
 
       while (tvb_length_remaining(tvb, offset) > 0) {
-	offset = dissect_aim_tlv_buddylist(tvb, pinfo, offset, tree);
+	offset = dissect_aim_tlv_buddylist(tvb, pinfo, offset, buddy_tree);
       }
 
       return offset;
@@ -141,20 +156,20 @@ static int dissect_aim_snac_buddylist(tv
 	col_append_fstr(pinfo->cinfo, COL_INFO, ": %s", buddyname);
       }
       
-      if (tree) {
-	proto_tree_add_text(tree, tvb, offset + 1, buddyname_length, 
+      if (buddy_tree) {
+	proto_tree_add_text(buddy_tree, tvb, offset + 1, buddyname_length, 
 			    "Screen Name: %s", buddyname);
       }
       offset += buddyname_length + 1;
 
       /* Warning level */
-      proto_tree_add_item(tree, hf_aim_userinfo_warninglevel, tvb, offset, 
+      proto_tree_add_item(buddy_tree, hf_aim_userinfo_warninglevel, tvb, offset, 
 			  2, FALSE);
       offset += 2;
       
       /* TLV Count */
       tlv_count = tvb_get_ntohs(tvb, offset);
-      proto_tree_add_item(tree, hf_aim_userinfo_tlvcount, tvb, offset, 
+      proto_tree_add_item(buddy_tree, hf_aim_userinfo_tlvcount, tvb, offset, 
 			  2, FALSE);
       offset += 2;
 
Index: packet-aim-chat.c
===================================================================
RCS file: /cvsroot/ethereal/packet-aim-chat.c,v
retrieving revision 1.2
diff -u -3 -p -d -u -r1.2 packet-aim-chat.c
--- packet-aim-chat.c	23 Mar 2004 18:36:05 -0000	1.2
+++ packet-aim-chat.c	19 Apr 2004 20:59:20 -0000
@@ -82,13 +82,27 @@ static int dissect_aim_snac_chat(tvbuff_
   struct aiminfo *aiminfo = pinfo->private_data;
   char buddyname[MAX_BUDDYNAME_LENGTH + 1];
   guchar msg[1000];
+  proto_item *ti;
+  proto_tree *chat_tree = NULL;
+                                                                                                                              
+  if(tree) {
+      ti = proto_tree_add_text(tree, tvb, 0, -1, "Chat Service");
+      chat_tree = proto_item_add_subtree(ti, ett_aim_chat);
+  }
 
   switch(aiminfo->subtype)
     {
 	case FAMILY_CHAT_ERROR:
-      return dissect_aim_snac_error(tvb, pinfo, offset, tree);
+      return dissect_aim_snac_error(tvb, pinfo, offset, chat_tree);
 	case FAMILY_CHAT_ROOMINFOUPDATE:
+	  /* FIXME */
+	  return 0;
 	case FAMILY_CHAT_USERJOIN:
+	  while(tvb_length_remaining(tvb, offset) > 0) {
+		  offset = dissect_aim_buddyname(tvb, pinfo, offset, chat_tree);
+		  /* FIXME */
+	  }
+	  return offset;
 	case FAMILY_CHAT_USERLEAVE:
 	case FAMILY_CHAT_EVIL_REQ:
 	case FAMILY_CHAT_EVIL_REPLY:
@@ -114,8 +128,8 @@ static int dissect_aim_snac_chat(tvbuff_
 	col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s", msg);
       }
       
-      if(tree) {
-	proto_tree_add_text(tree, tvb, 31, buddyname_length, 
+      if(chat_tree) {
+	proto_tree_add_text(chat_tree, tvb, 31, buddyname_length, 
 			    "Screen Name: %s", buddyname);
       }
 	  return tvb_length(tvb);
Index: packet-aim-chatnav.c
===================================================================
RCS file: /cvsroot/ethereal/packet-aim-chatnav.c,v
retrieving revision 1.3
diff -u -3 -p -d -u -r1.3 packet-aim-chatnav.c
--- packet-aim-chatnav.c	24 Mar 2004 06:36:32 -0000	1.3
+++ packet-aim-chatnav.c	19 Apr 2004 20:59:20 -0000
@@ -72,6 +72,38 @@ static int proto_aim_chatnav = -1;
 
 int ett_aim_chatnav = -1;
 
+static int dissect_aim_chatnav(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+  struct aiminfo *aiminfo = pinfo->private_data;
+	
+  proto_item *ti;
+  proto_tree *chatnav_tree = NULL;
+
+  if(tree) {
+      ti = proto_tree_add_text(tree, tvb, 0, -1, "Chat Navigation Service");
+      chatnav_tree = proto_item_add_subtree(ti, ett_aim_chatnav);
+  }
+
+  switch(aiminfo->subtype) {
+	  case FAMILY_CHATNAV_ERROR:
+		  return dissect_aim_snac_error(tvb, pinfo, 0, chatnav_tree);
+	case FAMILY_CHATNAV_LIMITS_REQ:
+		  /* No data */
+		  return 0;
+	case FAMILY_CHATNAV_EXCHANGE_REQ:
+	case FAMILY_CHATNAV_ROOM_INFO_REQ:
+	case FAMILY_CHATNAV_ROOMIF_EXT_REQ:
+	case FAMILY_CHATNAV_MEMBERLIST_REQ:
+	case FAMILY_CHATNAV_SEARCH_ROOM:
+	case FAMILY_CHATNAV_CREATE_ROOM:
+	case FAMILY_CHATNAV_INFO_REPLY:
+	case FAMILY_CHATNAV_DEFAULT:
+  /* FIXME */
+	  return 0;
+	default: return 0;
+  }
+}
+
 /* Register the protocol with Ethereal */
 void
 proto_register_aim_chatnav(void)
@@ -98,11 +130,10 @@ proto_register_aim_chatnav(void)
 void
 proto_reg_handoff_aim_chatnav(void)
 {
-  /*dissector_handle_t aim_handle;*/
+  dissector_handle_t aim_handle;
 
-  /* FIXME: dissect
-   * aim_handle = new_create_dissector_handle(dissect_aim_chatnav, proto_aim_chatnav);
-   * dissector_add("aim.family", FAMILY_CHAT_NAV, aim_handle);
-   */
+  aim_handle = new_create_dissector_handle(dissect_aim_chatnav, proto_aim_chatnav);
+  dissector_add("aim.family", FAMILY_CHAT_NAV, aim_handle);
+  
   aim_init_family(FAMILY_CHAT_NAV, "Chat Navigation", aim_fnac_family_chatnav);
 }
Index: packet-aim-directory.c
===================================================================
RCS file: /cvsroot/ethereal/packet-aim-directory.c,v
retrieving revision 1.2
diff -u -3 -p -d -u -r1.2 packet-aim-directory.c
--- packet-aim-directory.c	23 Mar 2004 18:36:05 -0000	1.2
+++ packet-aim-directory.c	19 Apr 2004 20:59:20 -0000
@@ -57,6 +57,32 @@ static const value_string aim_fnac_famil
 };
 
 static int proto_aim_directory = -1;
+static int ett_aim_directory = -1;
+
+static int dissect_aim_directory(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+	struct aiminfo *aiminfo = pinfo->private_data;
+	proto_item *ti;
+	proto_tree *directory_tree = NULL;
+
+    if(tree) {
+    	ti = proto_tree_add_text(tree, tvb, 0, -1, "Directory Service");
+    	directory_tree = proto_item_add_subtree(ti, ett_aim_directory);
+   	}
+
+	switch(aiminfo->subtype) {
+	case FAMILY_DIRECTORY_ERROR:
+		return dissect_aim_snac_error(tvb, pinfo, 0, directory_tree);
+	case FAMILY_DIRECTORY_INTERESTS_LIST_REQ:
+		return 0;
+	case FAMILY_DIRECTORY_SEARCH_USER_REQ:
+	case FAMILY_DIRECTORY_SEARCH_USER_REPL:
+	case FAMILY_DIRECTORY_INTERESTS_LIST_REP:
+		/* FIXME */
+		return 0;
+	}
+	return 0;
+}
 
 /* Register the protocol with Ethereal */
 void
@@ -69,24 +95,23 @@ proto_register_aim_directory(void)
   };*/
 
 /* Setup protocol subtree array */
-/*FIXME
   static gint *ett[] = {
-  };*/
+	  &ett_aim_directory
+  };
 /* Register the protocol name and description */
   proto_aim_directory = proto_register_protocol("AIM Directory Search", "AIM Directory", "aim_dir");
 
 /* Required function calls to register the header fields and subtrees used */
 /*FIXME
   proto_register_field_array(proto_aim_directory, hf, array_length(hf));*/
-/*FIXME
-  proto_register_subtree_array(ett, array_length(ett));*/
+  proto_register_subtree_array(ett, array_length(ett));
 }
 
 void
 proto_reg_handoff_aim_directory(void)
 {
-/*FIXME:  dissector_handle_t aim_handle;
+  dissector_handle_t aim_handle;
   aim_handle = new_create_dissector_handle(dissect_aim_directory, proto_aim_directory);
-  dissector_add("aim.family", FAMILY_DIRECTORY, aim_handle); */
+  dissector_add("aim.family", FAMILY_DIRECTORY, aim_handle); 
   aim_init_family(FAMILY_DIRECTORY, "Directory", aim_fnac_family_directory);
 }
Index: packet-aim-generic.c
===================================================================
RCS file: /cvsroot/ethereal/packet-aim-generic.c,v
retrieving revision 1.1
diff -u -3 -p -d -u -r1.1 packet-aim-generic.c
--- packet-aim-generic.c	23 Mar 2004 06:21:16 -0000	1.1
+++ packet-aim-generic.c	19 Apr 2004 20:59:20 -0000
@@ -205,12 +205,14 @@ static int dissect_generic_rateinfo(tvbu
 	guint16 i;
 	proto_item *ti;
 	guint16 numclasses = tvb_get_ntohs(tvb, 0);	
-	proto_tree *classes_tree, *groups_tree, *group_tree;
+	proto_tree *classes_tree = NULL, *groups_tree, *group_tree;
     proto_tree_add_uint(tree, hf_generic_rateinfo_numclasses, tvb, 0, 2, numclasses );
 	offset+=2;
 
-	ti = proto_tree_add_text(tree, tvb, offset, 33*numclasses, "Available Rate Classes");
-	classes_tree = proto_item_add_subtree(ti, ett_generic_rateinfo_classes);
+	if(tree) {
+		ti = proto_tree_add_text(tree, tvb, offset, 33*numclasses, "Available Rate Classes");
+		classes_tree = proto_item_add_subtree(ti, ett_generic_rateinfo_classes);
+	}
 
 	for(i = 0; i < numclasses; i++) {
 		guint16 myid = tvb_get_ntohs(tvb, offset); 
@@ -252,35 +254,33 @@ static int dissect_generic_rateinfo(tvbu
 static int dissect_aim_snac_generic(tvbuff_t *tvb, packet_info *pinfo, 
 				    proto_tree *tree)
 {
-  int offset = 0;
-  const char *name;
-  struct aiminfo *aiminfo = pinfo->private_data;
-  guint16 n, i;
-  proto_item *ti = NULL;
-  proto_tree *gen_tree = NULL;
-  proto_tree *entry = NULL;
+	int offset = 0;
+	const char *name;
+	struct aiminfo *aiminfo = pinfo->private_data;
+	guint16 n, i;
+  	proto_item *ti = NULL;
+	proto_tree *gen_tree = NULL;
+	proto_tree *entry = NULL;
 
-  if(tree) {
-    ti = proto_tree_add_text(tree, tvb, 0, -1,"AIM Generic Service");
-    gen_tree = proto_item_add_subtree(ti, ett_generic);
-  }
+	if(tree) {
+		ti = proto_tree_add_text(tree, tvb, 0, -1,"AIM Generic Service");
+		gen_tree = proto_item_add_subtree(ti, ett_generic);
+	}
 	
-  if ((name = match_strval(aiminfo->subtype, aim_fnac_family_generic)) != NULL) {
-    if (ti)
-      proto_item_append_text(ti, ", %s", name);
+	if ((name = match_strval(aiminfo->subtype, aim_fnac_family_generic)) != NULL) {
+	  if (ti) proto_item_append_text(ti, ", %s", name);
 
-    if (check_col(pinfo->cinfo, COL_INFO))
-      col_add_fstr(pinfo->cinfo, COL_INFO, name);
-  }
+      if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, name);
+	}
 
   switch(aiminfo->subtype)
     {
 	case FAMILY_GENERIC_ERROR:
-	   return dissect_aim_snac_error(tvb, pinfo, 0, gen_tree);
+      return dissect_aim_snac_error(tvb, pinfo, 0, gen_tree);
 	case FAMILY_GENERIC_CLIENTREADY:
-	   ti = proto_tree_add_text(gen_tree, tvb, 0, -1, "Supported services");
+	   ti = proto_tree_add_text(gen_tree, tvb, 0, tvb_length_remaining(tvb, 0), "Supported services");
 	   entry = proto_item_add_subtree(ti, ett_generic_clientready);
-	   while(tvb_reported_length_remaining(tvb, offset) > 0) {
+	   while(tvb_length_remaining(tvb, offset) > 0) {
 			guint16 famnum = tvb_get_ntohs(tvb, offset);
 			const char *famname = aim_get_familyname(famnum);
 			proto_tree *subentry;
@@ -289,8 +289,8 @@ static int dissect_aim_snac_generic(tvbu
 			
 			subentry = proto_item_add_subtree(ti, ett_generic_clientready_item);
 
-			proto_tree_add_text(subentry, tvb, offset, 2, "Version: %u", tvb_get_ntohs(tvb, offset) ); offset += 2;
-			proto_tree_add_text(subentry, tvb, offset, 4, "DLL Version: %u", tvb_get_ntoh24(tvb, offset) ); offset += 4;
+			proto_tree_add_text(subentry, tvb, offset, 2, "Version: %d", tvb_get_ntohs(tvb, offset) ); offset += 2;
+			proto_tree_add_text(subentry, tvb, offset, 4, "DLL Version: %lu", tvb_get_ntoh24(tvb, offset) ); offset += 4;
 	  }
 	  return offset;
 	case FAMILY_GENERIC_SERVERREADY:
@@ -305,7 +305,7 @@ static int dissect_aim_snac_generic(tvbu
 	  return offset;
 	case FAMILY_GENERIC_SERVICEREQ:
 	  name = aim_get_familyname( tvb_get_ntohs(tvb, offset) );
-	  proto_tree_add_uint_format(gen_tree, hf_generic_servicereq_service, tvb, offset, 2, tvb_get_ntohs(tvb, offset), "%s (0x%04x)", name?name:"Unknown", tvb_get_ntohs(tvb, offset) );
+      proto_tree_add_uint_format(gen_tree, hf_generic_servicereq_service, tvb, offset, 2, tvb_get_ntohs(tvb, offset), "%s (0x%04x)", name?name:"Unknown", tvb_get_ntohs(tvb, offset) );
 	  offset+=2;
 	  return offset;
 	case FAMILY_GENERIC_REDIRECT:
@@ -336,7 +336,7 @@ static int dissect_aim_snac_generic(tvbu
 
 
     case FAMILY_GENERIC_MOTD: 
-	  proto_tree_add_item(gen_tree, hf_generic_motd_motdtype, tvb, offset, 
+      proto_tree_add_item(gen_tree, hf_generic_motd_motdtype, tvb, offset, 
 			  2, tvb_get_ntohs(tvb, offset));
 	  offset+=2;
 	  while(tvb_length_remaining(tvb, offset) > 0) {
@@ -363,7 +363,7 @@ static int dissect_aim_snac_generic(tvbu
 	  
 
 	case FAMILY_GENERIC_CLIENTPAUSEACK:
-	  while(tvb_length_remaining(tvb, offset) > 0) {
+	   while(tvb_length_remaining(tvb, offset) > 0) {
 			guint16 famnum = tvb_get_ntohs(tvb, offset);
 			const char *famname = aim_get_familyname(famnum);
 			proto_tree_add_text(gen_tree, tvb, offset, 4, "Family: %s (0x%x)", famname?famname:"Unknown Family", famnum);
@@ -404,8 +404,10 @@ static int dissect_aim_snac_generic(tvbu
 		  offset+=4;
 	  }
 	  return offset;
-	case FAMILY_GENERIC_SELFINFO:
 	case FAMILY_GENERIC_EVIL:
+	  /* FIXME */
+	  return offset;
+	case FAMILY_GENERIC_SELFINFO:
 	case FAMILY_GENERIC_SETIDLE:
 	case FAMILY_GENERIC_SETSTATUS:
 	case FAMILY_GENERIC_WELLKNOWNURL:
Index: packet-aim-icq.c
===================================================================
RCS file: /cvsroot/ethereal/packet-aim-icq.c,v
retrieving revision 1.2
diff -u -3 -p -d -u -r1.2 packet-aim-icq.c
--- packet-aim-icq.c	23 Mar 2004 18:36:05 -0000	1.2
+++ packet-aim-icq.c	19 Apr 2004 20:59:20 -0000
@@ -57,6 +57,13 @@ static const value_string aim_fnac_famil
   { 0, NULL }
 };
 
+#define TLV_ICQ_META_DATA 			  0x0001
+
+static const aim_tlv icq_tlv[] = {
+   { TLV_ICQ_META_DATA, "Encapsulated ICQ Meta Data", dissect_aim_tlv_value_bytes },
+   { 0, "Unknown", NULL },
+};
+
 /* Initialize the protocol and registered fields */
 static int proto_aim_icq = -1;
 
@@ -72,6 +79,7 @@ static int dissect_aim_icq(tvbuff_t *tvb
    case FAMILY_ICQ_ERROR:
 	   return dissect_aim_snac_error(tvb, pinfo, offset, tree);
    case FAMILY_ICQ_LOGINREQUEST:
+	   return dissect_aim_tlv_specific(tvb, pinfo, offset, tree, icq_tlv);
    case FAMILY_ICQ_LOGINRESPONSE:
    case FAMILY_ICQ_AUTHREQUEST:
 	case FAMILY_ICQ_AUTHRESPONSE:
@@ -87,9 +95,8 @@ proto_register_aim_icq(void)
 {
 
 /* Setup list of header fields */
-/*FIXME
   static hf_register_info hf[] = {
-  };*/
+  };
 
 /* Setup protocol subtree array */
   static gint *ett[] = {
@@ -100,8 +107,7 @@ proto_register_aim_icq(void)
   proto_aim_icq = proto_register_protocol("AIM ICQ", "AIM ICQ", "aim_icq");
 
 /* Required function calls to register the header fields and subtrees used */
-/*FIXME
-  proto_register_field_array(proto_aim_icq, hf, array_length(hf));*/
+  proto_register_field_array(proto_aim_icq, hf, array_length(hf));
   proto_register_subtree_array(ett, array_length(ett));
 }
 
Index: packet-aim-location.c
===================================================================
RCS file: /cvsroot/ethereal/packet-aim-location.c,v
retrieving revision 1.2
diff -u -3 -p -d -u -r1.2 packet-aim-location.c
--- packet-aim-location.c	30 Mar 2004 17:38:45 -0000	1.2
+++ packet-aim-location.c	19 Apr 2004 20:59:20 -0000
@@ -74,11 +74,11 @@ static const value_string aim_fnac_famil
 #define FAMILY_LOCATION_USERINFO_CAPS          0x0005
                                                                                                                               
 static const aim_tlv aim_fnac_family_location_userinfo_tlv[] = {
-  { FAMILY_LOCATION_USERINFO_INFOENCODING, "Info Msg Encoding", FT_STRING },
-  { FAMILY_LOCATION_USERINFO_INFOMSG, "Info Message", FT_STRING },
-  { FAMILY_LOCATION_USERINFO_AWAYENCODING, "Away Msg Encoding", FT_STRING },
-  { FAMILY_LOCATION_USERINFO_AWAYMSG, "Away Message", FT_STRING },
-  { FAMILY_LOCATION_USERINFO_CAPS, "Capabilities", FT_BYTES },
+  { FAMILY_LOCATION_USERINFO_INFOENCODING, "Info Msg Encoding", dissect_aim_tlv_value_string},
+  { FAMILY_LOCATION_USERINFO_INFOMSG, "Info Message", dissect_aim_tlv_value_string },
+  { FAMILY_LOCATION_USERINFO_AWAYENCODING, "Away Msg Encoding", dissect_aim_tlv_value_string },
+  { FAMILY_LOCATION_USERINFO_AWAYMSG, "Away Message", dissect_aim_tlv_value_string },
+  { FAMILY_LOCATION_USERINFO_CAPS, "Capabilities", dissect_aim_tlv_value_bytes },
   { 0, "Unknown", 0 }
 };
 
Index: packet-aim-messaging.c
===================================================================
RCS file: /cvsroot/ethereal/packet-aim-messaging.c,v
retrieving revision 1.3
diff -u -3 -p -d -u -r1.3 packet-aim-messaging.c
--- packet-aim-messaging.c	2 Apr 2004 07:59:22 -0000	1.3
+++ packet-aim-messaging.c	19 Apr 2004 20:59:20 -0000
@@ -85,19 +85,26 @@ static const value_string aim_fnac_famil
 #define INCOMING_CH1_TYPING            0x000b
 
 static const aim_tlv messaging_incoming_ch1_tlvs[] = {
-  { INCOMING_CH1_MESSAGE_BLOCK, "Message Block", FT_BYTES },
-  { INCOMING_CH1_SERVER_ACK_REQ, "Server Ack Requested", FT_BYTES },
-  { INCOMING_CH1_MESSAGE_AUTH_RESP, "Message is Auto Response", FT_BYTES },
-  { INCOMING_CH1_MESSAGE_OFFLINE, "Message was received offline", FT_BYTES },
-  { INCOMING_CH1_ICON_PRESENT, "Icon present", FT_BYTES },
-  { INCOMING_CH1_BUDDY_REQ, "Buddy Req", FT_BYTES },
-  { INCOMING_CH1_TYPING, "Non-direct connect typing notification", FT_BYTES },
-  { 0, "Unknown", 0 }
+  { INCOMING_CH1_MESSAGE_BLOCK, "Message Block", dissect_aim_tlv_value_bytes },
+  { INCOMING_CH1_SERVER_ACK_REQ, "Server Ack Requested", dissect_aim_tlv_value_bytes },
+  { INCOMING_CH1_MESSAGE_AUTH_RESP, "Message is Auto Response", dissect_aim_tlv_value_bytes },
+  { INCOMING_CH1_MESSAGE_OFFLINE, "Message was received offline", dissect_aim_tlv_value_bytes },
+  { INCOMING_CH1_ICON_PRESENT, "Icon present", dissect_aim_tlv_value_bytes },
+  { INCOMING_CH1_BUDDY_REQ, "Buddy Req", dissect_aim_tlv_value_bytes },
+  { INCOMING_CH1_TYPING, "Non-direct connect typing notification", dissect_aim_tlv_value_bytes },
+  { 0, "Unknown", 0, NULL }
 };
 
 /* Initialize the protocol and registered fields */
 static int proto_aim_messaging = -1;
+static int hf_aim_icbm_channel = -1;
 static int hf_aim_icbm_cookie = -1;
+static int hf_aim_icbm_msg_flags = -1;
+static int hf_aim_icbm_max_sender_warnlevel = -1;
+static int hf_aim_icbm_max_receiver_warnlevel = -1;
+static int hf_aim_icbm_max_snac_size = -1;
+static int hf_aim_icbm_min_msg_interval = -1;
+static int hf_aim_icbm_unknown = -1;
 static int hf_aim_message_channel_id = -1;
 static int hf_aim_userinfo_warninglevel = -1;
 static int hf_aim_userinfo_tlvcount = -1;
@@ -110,15 +117,26 @@ static int dissect_aim_messaging(tvbuff_
 {
   guint8 buddyname_length = 0;
   char buddyname[MAX_BUDDYNAME_LENGTH + 1];
+  guint16 tlv_count = 0;
   guchar msg[1000];
   int offset = 0;
   struct aiminfo *aiminfo = pinfo->private_data;
-  guint16 tlv_count = 0;
+  proto_item *ti = NULL;
+  proto_tree *msg_tree = NULL;
+  
+    if(tree) {
+        ti = proto_tree_add_text(tree, tvb, 0, -1,"AIM Messaging Service");
+        msg_tree = proto_item_add_subtree(ti, ett_aim_messaging);
+    }
 
   switch(aiminfo->subtype)
     {    
 	case FAMILY_MESSAGING_ERROR:
-      return dissect_aim_snac_error(tvb, pinfo, offset, tree);
+      return dissect_aim_snac_error(tvb, pinfo, offset, msg_tree);
+	case FAMILY_MESSAGING_RESETICBMPARAM:
+	case FAMILY_MESSAGING_REQPARAMINFO:
+	  /* No data */
+	  return 0;
     case FAMILY_MESSAGING_OUTGOING:
 
       /* Unknown */
@@ -139,8 +157,8 @@ static int dissect_aim_messaging(tvbuff_
 	col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s", msg);
       }
       
-      if(tree) {
-	proto_tree_add_text(tree, tvb, offset, buddyname_length, 
+      if(msg_tree) {
+	proto_tree_add_text(msg_tree, tvb, 27, buddyname_length, 
 			    "Screen Name: %s", buddyname);
       }
       
@@ -167,9 +185,9 @@ static int dissect_aim_messaging(tvbuff_
 	
 	col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s", msg);
       }
-
-      if(tree) {
-	proto_tree_add_text(tree, tvb, offset, buddyname_length, 
+      
+      if(msg_tree) {
+	proto_tree_add_text(msg_tree, tvb, 27, buddyname_length, 
 			    "Screen Name: %s", buddyname);
       }
 
@@ -193,9 +211,15 @@ static int dissect_aim_messaging(tvbuff_
       
       return offset;
 	case FAMILY_MESSAGING_SETICBMPARAM:
-	case FAMILY_MESSAGING_RESETICBMPARAM:
-	case FAMILY_MESSAGING_REQPARAMINFO:
 	case FAMILY_MESSAGING_PARAMINFO:
+	  proto_tree_add_item(msg_tree, hf_aim_icbm_channel, tvb, offset, 2, tvb_get_ntohs(tvb, offset)); offset+=2;
+	  proto_tree_add_item(msg_tree, hf_aim_icbm_msg_flags, tvb, offset, 4, tvb_get_ntoh24(tvb, offset)); offset+=4;
+	  proto_tree_add_item(msg_tree, hf_aim_icbm_max_snac_size, tvb, offset, 2, tvb_get_ntohs(tvb, offset)); offset+=2;
+	  proto_tree_add_item(msg_tree, hf_aim_icbm_max_sender_warnlevel, tvb, offset, 2, tvb_get_ntohs(tvb, offset)); offset+=2;
+	  proto_tree_add_item(msg_tree, hf_aim_icbm_max_receiver_warnlevel, tvb, offset, 2, tvb_get_ntohs(tvb, offset)); offset+=2;
+	  proto_tree_add_item(msg_tree, hf_aim_icbm_min_msg_interval, tvb, offset, 2, tvb_get_ntohs(tvb, offset)); offset+=2;
+	  proto_tree_add_item(msg_tree, hf_aim_icbm_unknown, tvb, offset, 2, tvb_get_ntohs(tvb, offset)); offset+=2;
+	  return offset;
 	case FAMILY_MESSAGING_EVIL:
 	case FAMILY_MESSAGING_MISSEDCALL:
 	case FAMILY_MESSAGING_CLIENTAUTORESP:
@@ -216,6 +240,27 @@ proto_register_aim_messaging(void)
 
 /* Setup list of header fields */
   static hf_register_info hf[] = {
+	{ &hf_aim_icbm_channel,
+	   { "Channel to setup", "aim.icbm.channel", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL },
+	},
+	{ &hf_aim_icbm_msg_flags, 
+		{ "Message Flags", "aim.icbm.flags", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL },
+	},
+	{ &hf_aim_icbm_max_snac_size,
+		{ "Max SNAC Size", "aim.icbm.max_snac", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL },
+	},
+	{ &hf_aim_icbm_max_sender_warnlevel,
+		{ "Max sender warn level", "aim.icbm.max_sender_warn-level", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL },
+	},
+    { &hf_aim_icbm_max_receiver_warnlevel,
+		{ "max receiver warn level", "aim.icbm.max_receiver_warnlevel", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL },
+	},
+	{ &hf_aim_icbm_min_msg_interval,
+		{ "Minimum message interval (seconds)", "aim.icbm.min_msg_interval", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL },
+	},
+	{ &hf_aim_icbm_unknown,
+		{ "Uknown parameter", "aim.icbm.unknown", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL },
+	},
     { &hf_aim_icbm_cookie,
       { "ICBM Cookie", "aim.messaging.icbmcookie", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }
     },
@@ -238,7 +283,7 @@ proto_register_aim_messaging(void)
 /* Register the protocol name and description */
   proto_aim_messaging = proto_register_protocol("AIM Messaging", "AIM Messaging", "aim_messaging");
 
-  /* Required function calls to register the header fields and subtrees used */
+/* Required function calls to register the header fields and subtrees used */
   proto_register_field_array(proto_aim_messaging, hf, array_length(hf));
   proto_register_subtree_array(ett, array_length(ett));
 }
Index: packet-aim-oft.c
===================================================================
RCS file: /cvsroot/ethereal/packet-aim-oft.c,v
retrieving revision 1.3
diff -u -3 -p -d -u -r1.3 packet-aim-oft.c
--- packet-aim-oft.c	24 Mar 2004 06:36:32 -0000	1.3
+++ packet-aim-oft.c	19 Apr 2004 20:59:20 -0000
@@ -51,29 +51,25 @@ proto_register_aim_oft(void)
 {
 
 /* Setup list of header fields */
-/*FIXME
-  static hf_register_info hf[] = {
+/*  static hf_register_info hf[] = {
   };*/
 
 /* Setup protocol subtree array */
-/*FIXME
-  static gint *ett[] = {
+/*  static gint *ett[] = {
   };*/
 
 /* Register the protocol name and description */
   proto_aim_oft = proto_register_protocol("AIM OFT", "AIM OFT", "aim_oft");
 
 /* Required function calls to register the header fields and subtrees used */
-/*FIXME
-  proto_register_field_array(proto_aim_oft, hf, array_length(hf));*/
-/*FIXME
+/*  proto_register_field_array(proto_aim_oft, hf, array_length(hf));
   proto_register_subtree_array(ett, array_length(ett));*/
 }
 
 void
 proto_reg_handoff_aim_oft(void)
 {
-  /*dissector_handle_t aim_handle;*/
+  dissector_handle_t aim_handle;
 
   /* FIXME 
   aim_handle = new_create_dissector_handle(dissect_aim, proto_aim);
Index: packet-aim-ssi.c
===================================================================
RCS file: /cvsroot/ethereal/packet-aim-ssi.c,v
retrieving revision 1.1
diff -u -3 -p -d -u -r1.1 packet-aim-ssi.c
--- packet-aim-ssi.c	23 Mar 2004 06:21:17 -0000	1.1
+++ packet-aim-ssi.c	19 Apr 2004 20:59:20 -0000
@@ -147,7 +147,29 @@ static int dissect_aim_snac_ssi(tvbuff_t
       return dissect_aim_snac_error(tvb, pinfo, offset, ssi_tree);
     case FAMILY_SSI_LIST:
 	  return dissect_aim_snac_ssi_list(tvb, pinfo, offset, ssi_tree, aiminfo->subtype);
+	case FAMILY_SSI_REQRIGHTS:
+	case FAMILY_SSI_RIGHTSINFO:
+	case FAMILY_SSI_REQLIST_FIRSTTIME:
+	case FAMILY_SSI_REQLIST:
+	case FAMILY_SSI_ACTIVATE:
+	case FAMILY_SSI_ADD:
+	case FAMILY_SSI_MOD:
+	case FAMILY_SSI_DEL:
+	case FAMILY_SSI_SRVACK:
+	case FAMILY_SSI_NOLIST:
+	case FAMILY_SSI_EDITSTART:
+	case FAMILY_SSI_EDITSTOP:
+	case FAMILY_SSI_GRANT_FUTURE_AUTH:
+	case FAMILY_SSI_FUTUR_AUTH_GRANTED:
+	case FAMILY_SSI_SEND_AUTH_REQ: 
+	case FAMILY_SSI_AUTH_REQ:
+	case FAMILY_SSI_SEND_AUTH_REPLY:
+	case FAMILY_SSI_AUTH_REPLY:
+	case FAMILY_SSI_WAS_ADDED:
+
 	  /* FIXME */
+	  return 0;
+	 
     default:
 	  return 0;
     }
Index: packet-aim-translate.c
===================================================================
RCS file: /cvsroot/ethereal/packet-aim-translate.c,v
retrieving revision 1.3
diff -u -3 -p -d -u -r1.3 packet-aim-translate.c
--- packet-aim-translate.c	24 Mar 2004 06:36:32 -0000	1.3
+++ packet-aim-translate.c	19 Apr 2004 20:59:20 -0000
@@ -60,6 +60,12 @@ static int proto_aim_translate = -1;
 /* Initialize the subtree pointers */
 static gint ett_aim_translate = -1;
 
+static int dissect_aim_translate(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
+	
+	/* FIXME */
+	return 0;
+}
+
 /* Register the protocol with Ethereal */
 void
 proto_register_aim_translate(void)
@@ -86,8 +92,8 @@ proto_register_aim_translate(void)
 void
 proto_reg_handoff_aim_translate(void)
 {
-  /*dissector_handle_t aim_handle;*/
-/*FIXME  aim_handle = new_create_dissector_handle(dissect_aim, proto_aim);
-  dissector_add("tcp.port", TCP_PORT_AIM, aim_handle);*/
+  dissector_handle_t aim_handle;
+  aim_handle = new_create_dissector_handle(dissect_aim_translate, proto_aim_translate);
+  dissector_add("aim.family", FAMILY_TRANSLATE, aim_handle);
   aim_init_family(FAMILY_TRANSLATE, "Translate", aim_fnac_family_translate);
 }
Index: packet-aim.c
===================================================================
RCS file: /cvsroot/ethereal/packet-aim.c,v
retrieving revision 1.37
diff -u -3 -p -d -u -r1.37 packet-aim.c
--- packet-aim.c	11 Apr 2004 20:57:10 -0000	1.37
+++ packet-aim.c	19 Apr 2004 20:59:20 -0000
@@ -147,35 +147,34 @@ static const value_string aim_snac_error
 #define AIM_TLV_CLIENTUSESSI   			0x004a
 
 const aim_tlv global_tlvs[] = {
-  {  AIM_TLV_SCREEN_NAME, "Screen name", FT_STRING },
-  {  AIM_TLV_ROASTED_PASSWORD, "Roasted password array", FT_BYTES },
-  {  AIM_TLV_CLIENT_ID_STRING, "Client id string (name, version)", FT_STRING },
-  {  AIM_TLV_CLIENT_ID, "Client id number", FT_UINT16 },
-  {  AIM_TLV_CLIENT_MAJOR_VERSION, "Client major version", FT_UINT16 },
-  {  AIM_TLV_CLIENT_MINOR_VERSION, "Client minor version", FT_UINT16 },
-  {  AIM_TLV_CLIENT_LESSER_VERSION, "Client lesser version", FT_UINT16 },
-  {  AIM_TLV_CLIENT_BUILD_NUMBER, "Client build number", FT_UINT16 },
-  {  AIM_TLV_CLIENT_DISTRIBUTION_NUM, "Client distribution number", FT_UINT16 },
-  {  AIM_TLV_CLIENT_LANGUAGE, "Client language", FT_STRING },
-  {  AIM_TLV_CLIENT_COUNTRY, "Client country", FT_STRING },
-  {  AIM_TLV_BOS_SERVER_STRING, "BOS server string", FT_STRING },
-  {  AIM_TLV_AUTH_COOKIE, "Authorization cookie", FT_BYTES },
-  {  AIM_TLV_ERRORURL, "Error URL", FT_STRING },
-  {  AIM_TLV_ERRORCODE, "Error Code", FT_UINT16 },
-  {  AIM_TLV_EMAILADDR, "Account Email address", FT_STRING },
-  {  AIM_TLV_REGSTATUS, "Registration Status", FT_UINT16 },
-  {  AIM_TLV_PASSWORD, "Password Hash", FT_BYTES },
-  {  AIM_TLV_LATESTBETABUILD, "Latest Beta Build", FT_UINT32 },
-  {  AIM_TLV_LATESTBETAURL, "Latest Beta URL", FT_STRING },
-  {  AIM_TLV_LATESTBETAINFO, "Latest Beta Info", FT_STRING },
-  {  AIM_TLV_LATESTBETANAME, "Latest Beta Name", FT_STRING },
-  {  AIM_TLV_LATESTRELEASEBUILD, "Latest Release Build", FT_UINT32 },
-  {  AIM_TLV_LATESTRELEASEURL, "Latest Release URL", FT_STRING },
-  {  AIM_TLV_LATESTRELEASEINFO, "Latest Release Info", FT_STRING },
-  {  AIM_TLV_LATESTRELEASENAME, "Latest Release Name", FT_STRING },
-  {  AIM_TLV_CLIENTUSESSI, "Use SSI", FT_UINT8 },
-  {  AIM_TLV_GENERIC_SERVICE_ID, "Service (Family) ID", FT_UINT16 },
-  { 0, "Unknown", 0 },
+  {  AIM_TLV_SCREEN_NAME, "Screen name", dissect_aim_tlv_value_string },
+  {  AIM_TLV_ROASTED_PASSWORD, "Roasted password array", dissect_aim_tlv_value_bytes  },
+  {  AIM_TLV_CLIENT_ID_STRING, "Client id string (name, version)", dissect_aim_tlv_value_string },
+  {  AIM_TLV_CLIENT_ID, "Client id number", dissect_aim_tlv_value_uint16 },
+  {  AIM_TLV_CLIENT_MAJOR_VERSION, "Client major version", dissect_aim_tlv_value_uint16 },
+  {  AIM_TLV_CLIENT_MINOR_VERSION, "Client minor version", dissect_aim_tlv_value_uint16 },
+  {  AIM_TLV_CLIENT_LESSER_VERSION, "Client lesser version", dissect_aim_tlv_value_uint16 },
+  {  AIM_TLV_CLIENT_BUILD_NUMBER, "Client build number", dissect_aim_tlv_value_uint16 },
+  {  AIM_TLV_CLIENT_DISTRIBUTION_NUM, "Client distribution number", dissect_aim_tlv_value_uint16 },
+  {  AIM_TLV_CLIENT_LANGUAGE, "Client language", dissect_aim_tlv_value_string },
+  {  AIM_TLV_CLIENT_COUNTRY, "Client country", dissect_aim_tlv_value_string },
+  {  AIM_TLV_BOS_SERVER_STRING, "BOS server string", dissect_aim_tlv_value_string },
+  {  AIM_TLV_AUTH_COOKIE, "Authorization cookie", dissect_aim_tlv_value_bytes },
+  {  AIM_TLV_ERRORURL, "Error URL", dissect_aim_tlv_value_string },
+  {  AIM_TLV_ERRORCODE, "Error Code", dissect_aim_tlv_value_uint16 },
+  {  AIM_TLV_EMAILADDR, "Account Email address", dissect_aim_tlv_value_string },
+  {  AIM_TLV_REGSTATUS, "Registration Status", dissect_aim_tlv_value_uint16 },
+  {  AIM_TLV_LATESTBETABUILD, "Latest Beta Build", dissect_aim_tlv_value_uint32 },
+  {  AIM_TLV_LATESTBETAURL, "Latest Beta URL", dissect_aim_tlv_value_string },
+  {  AIM_TLV_LATESTBETAINFO, "Latest Beta Info", dissect_aim_tlv_value_string },
+  {  AIM_TLV_LATESTBETANAME, "Latest Beta Name", dissect_aim_tlv_value_string },
+  {  AIM_TLV_LATESTRELEASEBUILD, "Latest Release Build", dissect_aim_tlv_value_uint32 },
+  {  AIM_TLV_LATESTRELEASEURL, "Latest Release URL", dissect_aim_tlv_value_string },
+  {  AIM_TLV_LATESTRELEASEINFO, "Latest Release Info", dissect_aim_tlv_value_string  },
+  {  AIM_TLV_LATESTRELEASENAME, "Latest Release Name", dissect_aim_tlv_value_string },
+  {  AIM_TLV_CLIENTUSESSI, "Use SSI", dissect_aim_tlv_value_uint8 },
+  {  AIM_TLV_GENERIC_SERVICE_ID, "Service (Family) ID", dissect_aim_tlv_value_uint16 },
+  { 0, "Unknown", NULL },
 };
 
                                                                                                                               
@@ -192,18 +191,18 @@ const aim_tlv global_tlvs[] = {
 #define FAMILY_BUDDYLIST_ICQSESSIONLEN  0x0010
                                                                                                                               
 static const aim_tlv buddylist_tlvs[] = {
-  { FAMILY_BUDDYLIST_USERFLAGS, "User flags", FT_UINT16 },
-  { FAMILY_BUDDYLIST_MEMBERSINCE, "Member since date", FT_UINT32 },
-  { FAMILY_BUDDYLIST_ONSINCE, "Online since", FT_UINT32 },
-  { FAMILY_BUDDYLIST_IDLETIME, "Idle time (sec)", FT_UINT16 },
-  { FAMILY_BUDDYLIST_ICQSTATUS, "ICQ Online status", FT_UINT16 },
-  { FAMILY_BUDDYLIST_ICQIPADDR, "ICQ User IP Address", FT_IPv4 },
-  { FAMILY_BUDDYLIST_ICQSTUFF, "ICQ Info", FT_BYTES },
-  { FAMILY_BUDDYLIST_CAPINFO, "Capability Info", FT_BYTES },
-  { FAMILY_BUDDYLIST_UNKNOWN, "Unknown", FT_UINT16 },
-  { FAMILY_BUDDYLIST_SESSIONLEN, "Session Length (sec)", FT_UINT32 },
-  { FAMILY_BUDDYLIST_SESSIONLEN, "ICQ Session Length (sec)", FT_UINT32 },
-  { 0, "Unknown", 0 }
+  { FAMILY_BUDDYLIST_USERFLAGS, "User flags", dissect_aim_tlv_value_uint16 },
+  { FAMILY_BUDDYLIST_MEMBERSINCE, "Member since date", dissect_aim_tlv_value_uint32 },
+  { FAMILY_BUDDYLIST_ONSINCE, "Online since", dissect_aim_tlv_value_uint32 },
+  { FAMILY_BUDDYLIST_IDLETIME, "Idle time (sec)", dissect_aim_tlv_value_uint16 },
+  { FAMILY_BUDDYLIST_ICQSTATUS, "ICQ Online status", dissect_aim_tlv_value_uint16 },
+  { FAMILY_BUDDYLIST_ICQIPADDR, "ICQ User IP Address", dissect_aim_tlv_value_ipv4 },
+  { FAMILY_BUDDYLIST_ICQSTUFF, "ICQ Info", dissect_aim_tlv_value_bytes },
+  { FAMILY_BUDDYLIST_CAPINFO, "Capability Info", dissect_aim_tlv_value_bytes },
+  { FAMILY_BUDDYLIST_UNKNOWN, "Unknown", dissect_aim_tlv_value_uint16 },
+  { FAMILY_BUDDYLIST_SESSIONLEN, "Session Length (sec)", dissect_aim_tlv_value_uint32 },
+  { FAMILY_BUDDYLIST_SESSIONLEN, "ICQ Session Length (sec)", dissect_aim_tlv_value_uint32 },
+  { 0, "Unknown", NULL }
 };
 
 struct aim_family {
@@ -217,8 +216,8 @@ static GList *families = NULL;
 #define FAMILY_GENERIC_MOTD_MOTD					   0x000B
 
 static const aim_tlv aim_fnac_family_generic_motd_tlv[] = {
-  { FAMILY_GENERIC_MOTD_MOTD, "Message of the day message", FT_STRING },
-  { 0, "Unknown", 0 }
+  { FAMILY_GENERIC_MOTD_MOTD, "Message of the day message", dissect_aim_tlv_value_string },
+  { 0, "Unknown", NULL }
 };
 
 #define FAMILY_GENERIC_REDIRECT_SERVER_ADDRESS		   0x0005
@@ -226,10 +225,10 @@ static const aim_tlv aim_fnac_family_gen
 #define FAMILY_GENERIC_REDIRECT_FAMILY_ID              0x000D
 
 static const aim_tlv aim_fnac_family_generic_redirect_tlv[] = {
-  { FAMILY_GENERIC_REDIRECT_SERVER_ADDRESS, "Server address and (optional) port", FT_STRING },
-  { FAMILY_GENERIC_REDIRECT_AUTH_COOKIE, "Authorization cookie", FT_STRING },
-  { FAMILY_GENERIC_REDIRECT_FAMILY_ID, "Family ID", FT_UINT16 },
-  { 0, "Unknown", 0 }
+  { FAMILY_GENERIC_REDIRECT_SERVER_ADDRESS, "Server address and (optional) port", dissect_aim_tlv_value_string },
+  { FAMILY_GENERIC_REDIRECT_AUTH_COOKIE, "Authorization cookie", dissect_aim_tlv_value_string },
+  { FAMILY_GENERIC_REDIRECT_FAMILY_ID, "Family ID", dissect_aim_tlv_value_uint16 },
+  { 0, "Unknown", NULL }
 };
 
 #define FAMILY_GENERIC_MOTD_MOTDTYPE_MDT_UPGRADE       0x0001
@@ -253,7 +252,7 @@ static void dissect_aim_pdu(tvbuff_t *tv
 
 static void dissect_aim_newconn(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *tree);
 static void dissect_aim_snac(tvbuff_t *tvb, packet_info *pinfo, 
-			     int offset, proto_tree *tree);
+			     int offset, proto_tree *tree, proto_tree *root_tree);
 static void dissect_aim_flap_err(tvbuff_t *tvb, packet_info *pinfo, 
 				 int offset, proto_tree *tree);
 static void dissect_aim_keep_alive(tvbuff_t *tvb, packet_info *pinfo, 
@@ -288,6 +287,7 @@ static int hf_aim_authcookie = -1;
 
 /* Initialize the subtree pointers */
 static gint ett_aim          = -1;
+static gint ett_aim_buddyname= -1;
 static gint ett_aim_fnac     = -1;
 static gint ett_aim_tlv      = -1;
 
@@ -374,7 +374,7 @@ static void dissect_aim_pdu(tvbuff_t *tv
       dissect_aim_newconn(tvb, pinfo, offset, aim_tree);
       break;
     case CHANNEL_SNAC_DATA:
-      dissect_aim_snac(tvb, pinfo, offset, aim_tree);
+      dissect_aim_snac(tvb, pinfo, offset, aim_tree, tree);
       break;
     case CHANNEL_FLAP_ERR:
       dissect_aim_flap_err(tvb, pinfo, offset, aim_tree);
@@ -550,7 +550,7 @@ int dissect_aim_snac_error(tvbuff_t *tvb
 }
 
 static void dissect_aim_snac(tvbuff_t *tvb, packet_info *pinfo, 
-			     int offset, proto_tree *aim_tree)
+			     int offset, proto_tree *aim_tree, proto_tree *root_tree)
 {
   guint16 family;
   guint16 subtype;
@@ -614,7 +614,7 @@ static void dissect_aim_snac(tvbuff_t *t
 	 else col_append_fstr(pinfo->cinfo, COL_INFO, ", Subtype: 0x%04x", subtype);
   }
 
-  if(tvb_length_remaining(tvb,offset) == 0 || !dissector_try_port(subdissector_table, family, subtvb, pinfo, aim_tree)) {
+  if(tvb_length_remaining(tvb,offset) == 0 || !dissector_try_port(subdissector_table, family, subtvb, pinfo, root_tree)) {
     /* Show the undissected payload */
     if (tvb_length_remaining(tvb, offset) > 0)
       proto_tree_add_item(aim_tree, hf_aim_data, tvb, offset, -1, FALSE);
@@ -669,6 +669,29 @@ static void dissect_aim_unknown_channel(
     proto_tree_add_item(tree, hf_aim_data, tvb, offset, -1, FALSE);
 }
 
+int dissect_aim_buddyname(tvbuff_t *tvb, packet_info *pinfo _U_, int offset,
+                       proto_tree *tree)
+{
+  guint8 buddyname_length = 0;
+  char *buddyname;
+  proto_item *ti = NULL;
+  proto_tree *buddy_tree = NULL;
+                                                                                                                              
+  buddyname_length = tvb_get_guint8(tvb, offset);
+  offset++;
+  buddyname = tvb_get_string(tvb, offset, buddyname_length);
+                                                                                                                              
+  if(tree) {
+      ti = proto_tree_add_text(tree, tvb, offset-1, 1+buddyname_length,"Buddy: %s", buddyname);
+      buddy_tree = proto_item_add_subtree(ti, ett_aim_buddyname);
+  }
+                                                                                                                              
+   proto_tree_add_item(buddy_tree, hf_aim_buddyname_len, tvb, offset-1, 1, FALSE);
+   proto_tree_add_item(buddy_tree, hf_aim_buddyname, tvb, offset, buddyname_length, FALSE);
+   return offset+buddyname_length;
+}
+
+
 
 int dissect_aim_tlv(tvbuff_t *tvb, packet_info *pinfo _U_, 
 			   int offset, proto_tree *tree)
@@ -684,6 +707,45 @@ int dissect_aim_tlv_buddylist(tvbuff_t *
 	return dissect_aim_tlv_specific(tvb, pinfo, offset, tree, buddylist_tlvs);
 }
 
+int dissect_aim_tlv_value_string (proto_item *ti, guint16 valueid _U_, tvbuff_t *tvb)
+{
+   guint8 *buf;
+   buf = tvb_get_string(tvb, 0, tvb_length(tvb));
+   proto_item_set_text(ti, "Value: %s", buf);
+   g_free(buf);
+   return tvb_length(tvb);
+}
+
+int dissect_aim_tlv_value_bytes (proto_item *ti, guint16 valueid, tvbuff_t *tvb)
+{
+   return tvb_length(tvb);
+}
+
+int dissect_aim_tlv_value_uint8 (proto_item *ti, guint16 valueid _U_, tvbuff_t *tvb){
+  guint8 value8 = tvb_get_guint8(tvb, 0);
+  proto_item_set_text(ti, "Value: %d", value8);
+  return 1;
+}
+
+int dissect_aim_tlv_value_uint16 (proto_item *ti, guint16 valueid _U_, tvbuff_t *tvb){
+  guint16 value16 = tvb_get_ntohs(tvb, 0);
+  proto_item_set_text(ti, "Value: %d", value16);
+  return 2;
+}
+
+int dissect_aim_tlv_value_ipv4 (proto_item *ti, guint16 valueid, tvbuff_t *tvb){
+  /* FIXME: Somewhat more readable format ? */
+  guint32 value32 = tvb_get_ntoh24(tvb, 0);
+  proto_item_set_text(ti, "Value: %d", value32);
+  return 4;
+}
+
+int dissect_aim_tlv_value_uint32 (proto_item *ti, guint16 valueid _U_, tvbuff_t *tvb){
+  guint32 value32 = tvb_get_ntoh24(tvb, 0);
+  proto_item_set_text(ti, "Value: %d", value32);
+  return 4;
+}
+
 /* Dissect a TLV value */
 int dissect_aim_tlv_specific(tvbuff_t *tvb, packet_info *pinfo _U_, 
 			   int offset, proto_tree *tree, const aim_tlv *tlv)
@@ -695,8 +757,6 @@ int dissect_aim_tlv_specific(tvbuff_t *t
   proto_item *ti1;
   proto_tree *tlv_tree;
   int orig_offset;
-  guint16 value16;
-  guint32 value32;
 
   /* Record the starting offset so we can reuse it at the second pass */
   orig_offset = offset;
@@ -726,29 +786,7 @@ int dissect_aim_tlv_specific(tvbuff_t *t
   if (tree) {
     offset = orig_offset;
     
-    /* Show the info in the top of the tree if it's one of the standard
-       data types */
-    if (tmp[i].datatype == FT_STRING && length > 0) {
-      guint8 *buf;
-      buf = tvb_get_string(tvb, offset + 4, length);
-      ti1 = proto_tree_add_text(tree, tvb, offset, length + 4, 
-				"%s: %s", tmp[i].desc, buf);
-      g_free(buf);
-    }
-    else if (tmp[i].datatype == FT_UINT16) {
-      value16 = tvb_get_ntohs(tvb, offset + 4);
-      ti1 = proto_tree_add_text(tree, tvb, offset, length + 4, 
-				"%s: %d", tmp[i].desc, value16);
-    }
-    else if (tmp[i].datatype == FT_UINT32) {
-      value32 = tvb_get_ntohl(tvb, offset + 4);
-      ti1 = proto_tree_add_text(tree, tvb, offset, length + 4, 
-				"%s: %d", tmp[i].desc, value32);
-    }
-    else {
-      ti1 = proto_tree_add_text(tree, tvb, offset, length + 4, 
-				"%s", tmp[i].desc);
-    }
+	ti1 = proto_tree_add_text(tree, tvb, offset, length, "TLV: %s", tmp[i].desc);
 
     tlv_tree = proto_item_add_subtree(ti1, ett_aim_tlv);
 
@@ -762,6 +800,11 @@ int dissect_aim_tlv_specific(tvbuff_t *t
 
     ti1 = proto_tree_add_text(tlv_tree, tvb, offset, length,
 			      "Value");
+	
+	if (tmp[i].dissector) {
+	   tmp[i].dissector(ti1, valueid, tvb_new_subset(tvb, offset, length, length));
+	} 
+
     offset += length;
   }
 
@@ -839,6 +882,7 @@ proto_register_aim(void)
     &ett_aim,
     &ett_aim_fnac,
     &ett_aim_tlv,
+	&ett_aim_buddyname
   };
   module_t *aim_module;
 
Index: packet-aim.h
===================================================================
RCS file: /cvsroot/ethereal/packet-aim.h,v
retrieving revision 1.1
diff -u -3 -p -d -u -r1.1 packet-aim.h
--- packet-aim.h	23 Mar 2004 06:21:17 -0000	1.1
+++ packet-aim.h	19 Apr 2004 20:59:20 -0000
@@ -1,7 +1,7 @@
-/* packet-aim.h
+/* packet-tcp.h
  * Copyright 2004, Jelmer Vernooij <jelmer@xxxxxxxxx>
  *
- * $Id: packet-aim.h,v 1.1 2004/03/23 06:21:17 guy Exp $
+ * $Id: packet-tcp.h,v 1.21 2003/12/30 00:03:48 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@xxxxxxxxxxxx>
@@ -30,7 +30,7 @@
 typedef struct _aim_tlv {
   guint16 valueid;
   char *desc;
-  int datatype;
+  int (*dissector) (proto_item *ti, guint16 value_id, tvbuff_t *tvb);
 } aim_tlv;
 
 struct aiminfo {
@@ -41,6 +41,7 @@ struct aiminfo {
 
 void aim_init_family(guint16 family, const char *name, const value_string *subtypes);
 
+int dissect_aim_buddyname(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *tree);
 void aim_get_message( guchar *msg, tvbuff_t *tvb, int msg_offset, int msg_length);
 int aim_get_buddyname( char *name, tvbuff_t *tvb, int len_offset, int name_offset);
 
@@ -59,5 +60,11 @@ int dissect_aim_tlv_specific(tvbuff_t *t
 const char *aim_get_familyname( guint16 family );
 const char *aim_get_subtypename( guint16 family, guint16 subtype);
 
+int dissect_aim_tlv_value_string(proto_item *ti, guint16, tvbuff_t *);
+int dissect_aim_tlv_value_uint8(proto_item *ti, guint16, tvbuff_t *);
+int dissect_aim_tlv_value_uint16(proto_item *ti, guint16, tvbuff_t *);
+int dissect_aim_tlv_value_uint32(proto_item *ti, guint16, tvbuff_t *);
+int dissect_aim_tlv_value_bytes(proto_item *ti, guint16, tvbuff_t *);
+int dissect_aim_tlv_value_ipv4(proto_item *ti, guint16, tvbuff_t *);
 
 #endif