Ethereal-dev: [Ethereal-dev] [PATCH] OSCAR Dissector updates

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

From: Jelmer Vernooij <jelmer@xxxxxxxxx>
Date: Fri, 17 Sep 2004 02:12:19 +0200
Hi,

Here's yet another patch to the OSCAR/AIM Dissector:

- Support for more generic TLV's
- Support for two more SNAC families: email and sst
- Support for extended status (as used by iChat)
- Use correct TLV in SSI RightsInfo
- Dissect and handle FNAC flags field correctly

Cheers,

Jelmer
Index: epan/dissectors/packet-aim-ssi.c
===================================================================
--- epan/dissectors/packet-aim-ssi.c	(revision 12014)
+++ epan/dissectors/packet-aim-ssi.c	(working copy)
@@ -109,8 +109,11 @@
   { 0, NULL }
 };
 
-static const aim_tlv ssi_rights_tlvs[] = {
-	{ 0, NULL, NULL }
+#define SSI_RIGHTSINFO_TLV_MAX_ITEMS	0x0004
+
+static const aim_tlv ssi_rightsinfo_tlvs[] = {
+	{ SSI_RIGHTSINFO_TLV_MAX_ITEMS, "Maximums For Items", dissect_aim_tlv_value_bytes }, 
+	{ 0, NULL, NULL },
 };
 
 static int dissect_aim_snac_ssi_list(tvbuff_t *tvb, packet_info *pinfo _U_, 
@@ -205,7 +208,7 @@
 	  return dissect_aim_snac_ssi_list(tvb, pinfo, offset, ssi_tree, aiminfo->subtype);
 	case FAMILY_SSI_RIGHTSINFO:
 		while(tvb_length_remaining(tvb, offset) > 0) {
-			offset = dissect_aim_tlv(tvb, pinfo, offset, ssi_tree, ssi_rights_tlvs);
+			offset = dissect_aim_tlv(tvb, pinfo, offset, ssi_tree, ssi_rightsinfo_tlvs);
 		}
 	  return offset;
 	case FAMILY_SSI_REQRIGHTS:
Index: epan/dissectors/Makefile.common
===================================================================
--- epan/dissectors/Makefile.common	(revision 12014)
+++ epan/dissectors/Makefile.common	(working copy)
@@ -46,6 +46,7 @@
 	packet-aim-chat.c	\
 	packet-aim-chatnav.c \
 	packet-aim-directory.c	\
+	packet-aim-email.c \
 	packet-aim-generic.c	\
 	packet-aim-icq.c \
 	packet-aim-invitation.c \
@@ -55,6 +56,7 @@
 	packet-aim-popup.c \
 	packet-aim-signon.c \
 	packet-aim-ssi.c \
+	packet-aim-sst.c \
 	packet-aim-stats.c \
 	packet-aim-translate.c \
 	packet-aim-userlookup.c \
Index: epan/dissectors/packet-aim-generic.c
===================================================================
--- epan/dissectors/packet-aim-generic.c	(revision 12014)
+++ epan/dissectors/packet-aim-generic.c	(working copy)
@@ -72,6 +72,7 @@
 #define FAMILY_GENERIC_SETSTATUS      0x001e
 #define FAMILY_GENERIC_CLIENTVERREQ   0x001f
 #define FAMILY_GENERIC_CLIENTVERREPL  0x0020
+#define FAMILY_GENERIC_EXT_STATUS_REP 0x0021
 #define FAMILY_GENERIC_DEFAULT        0xffff
 
 static const value_string aim_fnac_family_generic[] = {
@@ -101,6 +102,7 @@
   { FAMILY_GENERIC_SETSTATUS, "Set Status (ICQ specific)" },
   { FAMILY_GENERIC_CLIENTVERREQ, "Client Verification Requst" },
   { FAMILY_GENERIC_CLIENTVERREPL, "Client Verification Reply" },
+  { FAMILY_GENERIC_EXT_STATUS_REP, "Extended Status Reply" },
   { FAMILY_GENERIC_DEFAULT, "Generic Default" },
   { 0, NULL }
 };
@@ -144,6 +146,27 @@
 	{ 0, NULL },
 };
 
+#define EXT_STATUS_TYPE_BUDDY_ICON_0 0
+#define EXT_STATUS_TYPE_BUDDY_ICON_1 1
+#define EXT_STATUS_TYPE_AVAIL_MSG    2
+#define EXT_STATUS_TYPE_UNKNOWN		 6
+
+static const value_string ext_status_types[] = {
+	{ EXT_STATUS_TYPE_BUDDY_ICON_0, "Request to send buddy icon" },
+	{ EXT_STATUS_TYPE_BUDDY_ICON_1, "Request to send buddy icon" },
+	{ EXT_STATUS_TYPE_AVAIL_MSG, "Extended Status Update" },
+	{ 0, NULL },
+};
+
+#define EXT_STATUS_FLAG_INITIAL_SEND	0x41
+#define EXT_STATUS_FLAG_RESEND			0x81
+
+static const value_string ext_status_flags[] = {
+	{ EXT_STATUS_FLAG_INITIAL_SEND, "First Send Request" },
+	{ EXT_STATUS_FLAG_RESEND, 		"Request To Re-Send" },
+	{ 0, NULL },
+};
+
 static int dissect_aim_snac_generic(tvbuff_t *tvb, packet_info *pinfo, 
 				     proto_tree *tree);
 
@@ -175,6 +198,10 @@
 static int hf_generic_client_ver_req_offset = -1;
 static int hf_generic_client_ver_req_length = -1;
 static int hf_generic_client_ver_req_hash = -1;
+static int hf_generic_ext_status_type = -1;
+static int hf_generic_ext_status_length = -1;
+static int hf_generic_ext_status_flags = -1;
+static int hf_generic_ext_status_data = -1;
 
 /* Initialize the subtree pointers */
 static gint ett_generic_clientready = -1;
@@ -435,6 +462,15 @@
 	case FAMILY_GENERIC_WELLKNOWNURL:
 	  /* FIXME */
 	  return 0;
+	case FAMILY_GENERIC_EXT_STATUS_REP:
+	  {
+		  guint8 length;
+	  proto_tree_add_item(gen_tree, hf_generic_ext_status_type, tvb, offset, 2, FALSE); offset += 2;
+	  proto_tree_add_item(gen_tree, hf_generic_ext_status_flags, tvb, offset, 1, FALSE); offset += 1;
+	  proto_tree_add_item(gen_tree, hf_generic_ext_status_length, tvb, offset, 1, FALSE); length = tvb_get_guint8(tvb, offset); offset += 1;
+	  proto_tree_add_item(gen_tree, hf_generic_ext_status_data, tvb, offset, length, FALSE); offset += 1;
+	  return offset;
+	  }
 	default: return 0;
     }
   return 0;
@@ -527,6 +563,19 @@
 	{ &hf_generic_client_ver_req_hash,
 		{ "Client Verification MD5 Hash", "aim.client_verification.hash", FT_BYTES, BASE_DEC, NULL, 0x0, "", HFILL },
 	},
+	{ &hf_generic_ext_status_type,
+		{ "Extended Status Type", "aim.ext_status.type", FT_UINT16, BASE_DEC, VALS(ext_status_types), 0x0, "", HFILL },
+	},
+	{ &hf_generic_ext_status_flags,
+		{ "Extended Status Flags", "aim.ext_status.flags", FT_UINT8, BASE_HEX, VALS(ext_status_flags), 0x0, "", HFILL },
+	},
+	{ &hf_generic_ext_status_length,
+		{ "Extended Status Length", "aim.ext_status.length", FT_UINT8, BASE_HEX, NULL, 0x0, "" , HFILL },
+	},
+	{ &hf_generic_ext_status_data,
+		{ "Extended Status Data", "aim.ext_status.data", FT_BYTES, BASE_HEX, NULL, 0x0, "" , HFILL },
+	},
+
   };
 
 /* Setup protocol subtree array */
Index: epan/dissectors/packet-aim.c
===================================================================
--- epan/dissectors/packet-aim.c	(revision 12014)
+++ epan/dissectors/packet-aim.c	(working copy)
@@ -144,7 +144,7 @@
 #define AIM_CLIENT_TLV_CLIENT_MINOR_VERSION    0x0018
 #define AIM_CLIENT_TLV_CLIENT_LESSER_VERSION   0x0019
 #define AIM_CLIENT_TLV_CLIENT_BUILD_NUMBER     0x001a
-#define AIM_CLIENT_TLV_PASSWORD				0x0025
+#define AIM_CLIENT_TLV_PASSWORD_MD5 			0x0025
 #define AIM_CLIENT_TLV_LATESTBETABUILD     	0x0040
 #define AIM_CLIENT_TLV_LATESTBETAURL       	0x0041
 #define AIM_CLIENT_TLV_LATESTBETAINFO      	0x0042
@@ -157,6 +157,22 @@
 #define AIM_CLIENT_TLV_RELEASE_DIGEST_SIG   0x0049
 #define AIM_CLIENT_TLV_CLIENTUSESSI   			0x004a
 #define AIM_CLIENT_TLV_CHANGE_PASSWORD_URL		0x0054
+#define AIM_CLIENT_TLV_AWAITING_AUTH		0x0066
+#define AIM_CLIENT_TLV_MEMBERS				0x00c8
+#define AIM_CLIENT_TLV_VISIBILITY_BITS		0x00c9
+#define AIM_CLIENT_TLV_PRIVACY				0x00ca
+#define AIM_CLIENT_TLV_VISIBLE_CLASS		0x00cb
+#define AIM_CLIENT_TLV_VISIBLE_MISC			0x00cc
+#define AIM_CLIENT_TLV_ICQ2K_SHORTCUT		0x00cd
+#define AIM_CLIENT_TLV_FIRST_LOADED_TIME	0x00d4
+#define AIM_CLIENT_TLV_BUDDY_ICON_MD5SUM	0x00d5
+#define AIM_CLIENT_TLV_GIVEN_NAME			0x0131
+#define AIM_CLIENT_TLV_LOCAL_EMAIL			0x0137
+#define AIM_CLIENT_TLV_LOCAL_SMS			0x013a
+#define AIM_CLIENT_TLV_LOCAL_COMMENT		0x013c
+#define AIM_CLIENT_TLV_LOCAL_PERSONAL_ALERT 0x013d
+#define AIM_CLIENT_TLV_LOCAL_PERSONAL_SOUND	0x013e
+#define AIM_CLIENT_TLV_FIRST_MESSAGE_SENT	0x0145
 
 const aim_tlv client_tlvs[] = {
   {  AIM_CLIENT_TLV_SCREEN_NAME, "Screen name", dissect_aim_tlv_value_string },
@@ -168,6 +184,7 @@
   {  AIM_CLIENT_TLV_CLIENT_MINOR_VERSION, "Client minor version", dissect_aim_tlv_value_uint16 },
   {  AIM_CLIENT_TLV_CLIENT_LESSER_VERSION, "Client lesser version", dissect_aim_tlv_value_uint16 },
   {  AIM_CLIENT_TLV_CLIENT_BUILD_NUMBER, "Client build number", dissect_aim_tlv_value_uint16 },
+  {  AIM_CLIENT_TLV_PASSWORD_MD5, "Password Hash (MD5)", dissect_aim_tlv_value_bytes },
   {  AIM_CLIENT_TLV_CLIENT_DISTRIBUTION_NUM, "Client distribution number", dissect_aim_tlv_value_uint16 },
   {  AIM_CLIENT_TLV_CLIENT_LANGUAGE, "Client language", dissect_aim_tlv_value_string },
   {  AIM_CLIENT_TLV_CLIENT_COUNTRY, "Client country", dissect_aim_tlv_value_string },
@@ -194,6 +211,22 @@
   {  AIM_CLIENT_TLV_CLIENTUSESSI, "Use SSI", dissect_aim_tlv_value_uint8 },
   {  AIM_CLIENT_TLV_GENERIC_SERVICE_ID, "Service (Family) ID", dissect_aim_tlv_value_uint16 },
   { AIM_CLIENT_TLV_CHANGE_PASSWORD_URL, "Change password url", dissect_aim_tlv_value_string },
+  { AIM_CLIENT_TLV_AWAITING_AUTH, "Awaiting Authorization", dissect_aim_tlv_value_bytes },
+  { AIM_CLIENT_TLV_MEMBERS, "Members of this Group", dissect_aim_tlv_value_bytes },
+  { AIM_CLIENT_TLV_VISIBILITY_BITS, "Bitfield", dissect_aim_tlv_value_bytes },
+  { AIM_CLIENT_TLV_PRIVACY, "Privacy Settings" , dissect_aim_tlv_value_uint8 },
+  { AIM_CLIENT_TLV_VISIBLE_CLASS, "Visible To Classes", dissect_aim_tlv_value_userclass },
+  { AIM_CLIENT_TLV_VISIBLE_MISC, "Allow Others to See Data", dissect_aim_tlv_value_bytes },
+  { AIM_CLIENT_TLV_ICQ2K_SHORTCUT, "ICQ2K Shortcut List", dissect_aim_tlv_value_string },
+  { AIM_CLIENT_TLV_FIRST_LOADED_TIME, "First Time Buddy Was Added (Unix Timestamp)" , dissect_aim_tlv_value_uint32 },
+  { AIM_CLIENT_TLV_BUDDY_ICON_MD5SUM, "MD5SUM of Current Buddy Icon", dissect_aim_tlv_value_bytes },
+  { AIM_CLIENT_TLV_GIVEN_NAME, "Locally Specified Buddy Name", dissect_aim_tlv_value_string },
+  { AIM_CLIENT_TLV_LOCAL_EMAIL, "Locally Specified Buddy Email", dissect_aim_tlv_value_string },
+  { AIM_CLIENT_TLV_LOCAL_SMS, "Locally Specified Buddy SMS", dissect_aim_tlv_value_string },
+  { AIM_CLIENT_TLV_LOCAL_COMMENT, "Locally Specified Buddy Comment", dissect_aim_tlv_value_string },
+  { AIM_CLIENT_TLV_LOCAL_PERSONAL_ALERT, "Personal Alert for Buddy", dissect_aim_tlv_value_uint16 },
+  { AIM_CLIENT_TLV_LOCAL_PERSONAL_SOUND, "Personal Sound for Buddy", dissect_aim_tlv_value_string },
+  { AIM_CLIENT_TLV_FIRST_MESSAGE_SENT, " First Time Message Sent to Buddy (Unix Timestamp)", dissect_aim_tlv_value_uint32 },
   { 0, "Unknown", NULL },
 };
 
@@ -284,6 +317,16 @@
 #define CLASS_UNKNOWN400             0x0400
 #define CLASS_UNKNOWN800             0x0800
 
+#define FNAC_FLAG_NEXT_IS_RELATED 	 0x0001
+#define FNAC_FLAG_CONTAINS_VERSION	 0x8000
+
+#define FNAC_TLV_FAMILY_VERSION  0x0001
+
+static const aim_tlv fnac_tlvs[] = {
+  { FNAC_TLV_FAMILY_VERSION, "SNAC Family Version", dissect_aim_tlv_value_uint16 },
+  { 0, "Unknown", NULL }
+};
+
 static int dissect_aim(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
 static guint get_aim_pdu_len(tvbuff_t *tvb, int offset);
 static void dissect_aim_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
@@ -314,6 +357,8 @@
 static int hf_aim_fnac_family = -1;
 static int hf_aim_fnac_subtype = -1;
 static int hf_aim_fnac_flags = -1;
+static int hf_aim_fnac_flag_next_is_related = -1;
+static int hf_aim_fnac_flag_contains_version = -1;
 static int hf_aim_fnac_id = -1;
 static int hf_aim_infotype = -1;
 static int hf_aim_buddyname_len = -1;
@@ -348,6 +393,7 @@
 static gint ett_aim          = -1;
 static gint ett_aim_buddyname= -1;
 static gint ett_aim_fnac     = -1;
+static gint ett_aim_fnac_flags = -1;
 static gint ett_aim_tlv      = -1;
 static gint ett_aim_userclass = -1;
 static gint ett_aim_messageblock = -1;
@@ -621,6 +667,14 @@
 	return dissect_aim_tlv_list(tvb, pinfo, offset, tree, onlinebuddy_tlvs);
 }
 
+int dissect_aim_fnac_flags(tvbuff_t *tvb, int offset, int len, proto_item *ti, guint16 flags)
+{
+	proto_tree *entry = proto_item_add_subtree(ti, ett_aim_fnac_flags);
+	proto_tree_add_boolean(entry, hf_aim_fnac_flag_next_is_related, tvb, offset, len, flags);
+	proto_tree_add_boolean(entry, hf_aim_fnac_flag_contains_version, tvb, offset, len, flags);
+	return offset + len;
+}
+
 static void dissect_aim_snac(tvbuff_t *tvb, packet_info *pinfo, 
 			     int offset, proto_tree *aim_tree, proto_tree *root_tree)
 {
@@ -665,13 +719,24 @@
 			   tvb, offset, 2, "Subtype: %s (0x%04x)", subtype_name?subtype_name:"Unknown", subtype);
       offset += 2;
 
-      proto_tree_add_uint(aim_tree_fnac, hf_aim_fnac_flags, tvb, offset, 
+      ti1 = proto_tree_add_uint(aim_tree_fnac, hf_aim_fnac_flags, tvb, offset, 
 			  2, flags);
-      offset += 2;
+
+	  offset = dissect_aim_fnac_flags(tvb, offset, 2, ti1, flags);
+
       proto_tree_add_uint(aim_tree_fnac, hf_aim_fnac_id, tvb, offset,
 			  4, id);
       offset += 4;
     }
+  
+  if(flags & FNAC_FLAG_CONTAINS_VERSION) {
+	guint16 len = tvb_get_ntohs(tvb, offset); offset+=2;
+	int oldoffset = offset;
+	
+	while(offset < oldoffset + len) {
+	  offset = dissect_aim_tlv(tvb, pinfo, offset, aim_tree, fnac_tlvs);
+	}
+  }
 
   subtvb = tvb_new_subset(tvb, offset, -1, -1);
   aiminfo.tcpinfo = pinfo->private_data;
@@ -1097,6 +1162,12 @@
 	{ &hf_aim_userclass_unknown800,
 		{ "Unknown bit", "aim.userclass.unknown800", FT_BOOLEAN, 32, TFS(&flags_set_truth), CLASS_UNKNOWN800, "", HFILL },
 	},
+	{ &hf_aim_fnac_flag_next_is_related,
+		{ "Followed By SNAC with related information", "aim.fnac.flags.next_is_related", FT_BOOLEAN, 16, TFS(&flags_set_truth), FNAC_FLAG_NEXT_IS_RELATED, "", HFILL },
+	},
+	{ &hf_aim_fnac_flag_contains_version,
+		{ "Contains Version of Family this SNAC is in", "aim.fnac.flags.contains_version", FT_BOOLEAN, 16, TFS(&flags_set_truth), FNAC_FLAG_CONTAINS_VERSION, "", HFILL },
+	},
 	{ &hf_aim_userinfo_warninglevel,
 		{ "Warning Level", "aim.userinfo.warninglevel", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL },
 	},
@@ -1130,6 +1201,7 @@
   static gint *ett[] = {
 	  &ett_aim,
 	  &ett_aim_fnac,
+	  &ett_aim_fnac_flags,
 	  &ett_aim_tlv,
 	  &ett_aim_buddyname,
 	  &ett_aim_userclass,
Index: epan/dissectors/packet-aim-sst.c
===================================================================
--- epan/dissectors/packet-aim-sst.c	(revision 0)
+++ epan/dissectors/packet-aim-sst.c	(revision 0)
@@ -0,0 +1,115 @@
+/* packet-aim-sst.c
+ * Routines for AIM (OSCAR) dissection, SNAC Server Stored Themes
+ * Copyright 2004, Jelmer Vernooij <jelmer@xxxxxxxxx>
+ *
+ * $Id: packet-aim-sst.c 11410 2004-07-18 18:06:47Z gram $
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@xxxxxxxxxxxx>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#include <glib.h>
+
+#include <epan/packet.h>
+#include <epan/strutil.h>
+
+#include "packet-aim.h"
+
+#define FAMILY_SST    0x0010
+
+/* Family Advertising */
+#define FAMILY_SST_ERROR          		0x0001
+#define FAMILY_SST_UPLOAD_ICON_REQ	  	0x0002
+#define FAMILY_SST_UPLOAD_ICON_REPL	  	0x0003
+#define FAMILY_SST_DOWNLOAD_ICON_REQ	0x0004
+#define FAMILY_SST_DOWNLOAD_ICON_REPL	0x0005
+
+static const value_string aim_fnac_family_sst[] = {
+  { FAMILY_SST_ERROR, "Error" },
+  { FAMILY_SST_UPLOAD_ICON_REQ, "Upload Buddy Icon Request" },
+  { FAMILY_SST_UPLOAD_ICON_REPL, "Upload Buddy Icon Reply" },
+  { FAMILY_SST_DOWNLOAD_ICON_REQ, "Download Buddy Icon Request" },
+  { FAMILY_SST_DOWNLOAD_ICON_REPL, "Download Buddy Icon Reply" },
+  { 0, NULL }
+};
+
+
+/* Initialize the protocol and registered fields */
+static int proto_aim_sst = -1;
+
+/* Initialize the subtree pointers */
+static gint ett_aim_sst      = -1;
+
+static int dissect_aim_sst(tvbuff_t *tvb _U_, 
+				     packet_info *pinfo _U_, 
+				     proto_tree *tree _U_)
+{
+	struct aiminfo *aiminfo = pinfo->private_data;
+	int offset = 0;
+
+	switch(aiminfo->subtype) {
+		case FAMILY_SST_ERROR:
+		return dissect_aim_snac_error(tvb, pinfo, offset, tree);
+		default:
+		return 0;
+	}
+
+	return 0;
+}
+
+/* Register the protocol with Ethereal */
+void
+proto_register_aim_sst(void)
+{
+
+/* Setup list of header fields */
+/*FIXME
+  static hf_register_info hf[] = {
+  };*/
+
+/* Setup protocol subtree array */
+  static gint *ett[] = {
+    &ett_aim_sst,
+  };
+
+/* Register the protocol name and description */
+  proto_aim_sst = proto_register_protocol("AIM Server Side Themes", "AIM SST", "aim_sst");
+
+/* Required function calls to register the header fields and subtrees used */
+/*FIXME
+  proto_register_field_array(proto_aim_sst, hf, array_length(hf));*/
+  proto_register_subtree_array(ett, array_length(ett));
+}
+
+void
+proto_reg_handoff_aim_sst(void)
+{
+  dissector_handle_t aim_handle;
+  aim_handle = new_create_dissector_handle(dissect_aim_sst, proto_aim_sst);
+  dissector_add("aim.family", FAMILY_SST, aim_handle);
+  aim_init_family(FAMILY_SST, "Server Stored Themes", aim_fnac_family_sst);
+}
Index: epan/dissectors/packet-aim-email.c
===================================================================
--- epan/dissectors/packet-aim-email.c	(revision 0)
+++ epan/dissectors/packet-aim-email.c	(revision 0)
@@ -0,0 +1,109 @@
+/* packet-aim-email.c
+ * Routines for AIM (OSCAR) dissection, SNAC Email
+ * Copyright 2004, Jelmer Vernooij <jelmer@xxxxxxxxx>
+ *
+ * $Id: packet-aim-adverts.c 11410 2004-07-18 18:06:47Z gram $
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@xxxxxxxxxxxx>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#include <glib.h>
+
+#include <epan/packet.h>
+#include <epan/strutil.h>
+
+#include "packet-aim.h"
+
+#define FAMILY_EMAIL    0x0018
+
+/* Family Advertising */
+#define FAMILY_EMAIL_STATUS_REQ			0x0006
+#define FAMILY_EMAIL_STATUS_REPL		0x0007
+#define FAMILY_EMAIL_ACTIVATE			0x0016
+
+static const value_string aim_fnac_family_email[] = {
+  { FAMILY_EMAIL_STATUS_REQ, "Email Status Request" },
+  { FAMILY_EMAIL_STATUS_REPL, "Email Status Reply" },
+  { FAMILY_EMAIL_ACTIVATE, "Activate Email" },
+  { 0, NULL }
+};
+
+
+/* Initialize the protocol and registered fields */
+static int proto_aim_email = -1;
+
+/* Initialize the subtree pointers */
+static gint ett_aim_email      = -1;
+
+static int dissect_aim_email(tvbuff_t *tvb _U_, 
+				     packet_info *pinfo _U_, 
+				     proto_tree *tree _U_)
+{
+	struct aiminfo *aiminfo = pinfo->private_data;
+
+	switch(aiminfo->subtype) {
+	default:
+			/* FIXME */
+		return 0;
+	}
+
+	return 0;
+}
+
+/* Register the protocol with Ethereal */
+void
+proto_register_aim_email(void)
+{
+
+/* Setup list of header fields */
+/*FIXME
+  static hf_register_info hf[] = {
+  };*/
+
+/* Setup protocol subtree array */
+  static gint *ett[] = {
+    &ett_aim_email,
+  };
+
+/* Register the protocol name and description */
+  proto_aim_email = proto_register_protocol("AIM E-mail", "AIM Email", "aim_email");
+
+/* Required function calls to register the header fields and subtrees used */
+/*FIXME
+  proto_register_field_array(proto_aim_email, hf, array_length(hf));*/
+  proto_register_subtree_array(ett, array_length(ett));
+}
+
+void
+proto_reg_handoff_aim_email(void)
+{
+  dissector_handle_t aim_handle;
+  aim_handle = new_create_dissector_handle(dissect_aim_email, proto_aim_email);
+  dissector_add("aim.family", FAMILY_EMAIL, aim_handle);
+  aim_init_family(FAMILY_EMAIL, "E-mail", aim_fnac_family_email);
+}