Ethereal-dev: [Ethereal-dev] patch: DAAP dissector [2nd try]

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

From: "Kelly Byrd" <kbyrd-ethereal@xxxxxxxxxx>
Date: Sat, 21 Aug 2004 08:51:32 -0700 (PDT)
> Kelly Byrd wrote:
>
>> Attached is a patch for packet-daap.c, it's addition to Makefile.common,
>> and some logic in packet-http.c
>
> Unfortunately, it doesn't work:

Sorry about that, cut and pasting into wordpad isn't the best way.

See if this works.

KB
Index: epan/dissectors/Makefile.common
===================================================================
--- epan/dissectors/Makefile.common	(revision 11783)
+++ epan/dissectors/Makefile.common	(working copy)
@@ -106,6 +106,7 @@
 	packet-cpfi.c	\
 	packet-cpha.c	\
 	packet-cups.c	\
+	packet-daap.c	\
 	packet-data.c	\
 	packet-dccp.c	\
 	packet-dcerpc-afs4int.c	\
Index: epan/dissectors/packet-http.c
===================================================================
--- epan/dissectors/packet-http.c	(revision 11783)
+++ epan/dissectors/packet-http.c	(working copy)
@@ -117,6 +117,7 @@
 #define TCP_PORT_PROXY_ADMIN_HTTP	3132
 #define TCP_ALT_PORT_HTTP		8080
 #define TCP_PORT_HKP			11371
+#define TCP_PORT_DAAP			3689
 /*
  * SSDP is implemented atop HTTP (yes, it really *does* run over UDP).
  */
@@ -128,7 +129,8 @@
  */
 typedef enum {
 	PROTO_HTTP,		/* just HTTP */
-	PROTO_SSDP		/* Simple Service Discovery Protocol */
+	PROTO_SSDP,		/* Simple Service Discovery Protocol */
+	PROTO_DAAP		/* Digital Audio Access Protocol */
 } http_proto_t;
 
 typedef void (*RequestDissector)(tvbuff_t*, proto_tree*, int);
@@ -295,6 +297,11 @@
 		proto_tag = "SSDP";
 		break;
 
+	case TCP_PORT_DAAP:	
+		proto = PROTO_DAAP;
+		proto_tag = "DAAP";
+		break;
+
 	default:
 		proto = PROTO_HTTP;
 		proto_tag = "HTTP";
Index: epan/dissectors/packet-daap.c
===================================================================
--- epan/dissectors/packet-daap.c	(revision 0)
+++ epan/dissectors/packet-daap.c	(revision 0)
@@ -0,0 +1,412 @@
+/* packet-daap.c
+ * Routines for Digital Audio Access Protocol dissection
+ * Copyright 2004, Kelly Byrd <kbyrd@xxxxxxxxxx>
+ *
+ * $Id: README.developer 11475 2004-07-23 01:37:35Z guy $
+ *
+ * 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 <glib.h>
+
+#include <epan/packet.h>
+#include <epan/dissectors/packet-http.h>
+
+#define TCP_PORT_DAAP 3689
+
+/* DAAP tags */
+/* Container tags */
+#define daap_mcon       0x6d636f6e
+#define daap_msrv       0x6d737276
+#define daap_mccr       0x6d636372
+#define daap_mdcl       0x6d64636c
+#define daap_mlog       0x6d6c6f67
+#define daap_mupd       0x6d757064
+#define daap_avdb       0x61766462
+#define daap_mlcl       0x6d6c636c
+#define daap_mlit       0x6d6c6974
+#define daap_mbcl       0x6d62636c
+#define daap_adbs       0x61646273
+#define daap_aply       0x61706c79
+#define daap_apso       0x6170736f
+#define daap_mudl       0x6d75646c
+#define daap_abro       0x6162726f
+#define daap_abal       0x6162616c
+#define daap_abcp       0x61626370
+#define daap_abgn       0x6162676e
+#define daap_prsv       0x70727376
+#define daap_arif       0x61726966
+/* String tags */
+#define daap_minm       0x6d696e6d
+#define daap_msts       0x6d737473
+#define daap_mcnm       0x6d636e6d
+#define daap_mcna       0x6d636e61
+#define daap_asal       0x6173616c
+#define daap_asar       0x61736172
+#define daap_ascm       0x6173636d
+#define daap_asfm       0x6173666d
+#define daap_aseq       0x61736571
+#define daap_asgn       0x6173676e
+#define daap_asdt       0x61736474
+#define daap_asul       0x6173756c
+/* uint64 tags */
+#define daap_mper       0x6d706572
+/* uint32 tags */
+#define daap_mstt       0x6d737474
+#define daap_musr       0x6d757372
+#define daap_miid       0x6d696964
+#define daap_mcti       0x6d637469
+#define daap_mpco       0x6d70636f
+#define daap_mimc       0x6d696d63
+#define daap_mrco       0x6d72636f
+#define daap_mtco       0x6d74636f
+#define daap_mstm       0x6d73746d
+#define daap_msdc       0x6d736463
+#define daap_mlid       0x6d6c6964
+#define daap_msur       0x6d737572
+#define daap_asda       0x61736461
+#define daap_asdm       0x6173646d
+#define daap_assr       0x61737372
+#define daap_assz       0x6173737a
+#define daap_asst       0x61737374
+#define daap_assp       0x61737370
+#define daap_astm       0x6173746d
+#define daap_aeNV       0x61654e56
+/* uint16 tags */
+#define daap_mcty       0x6d637479
+#define daap_asbt       0x61736274
+#define daap_asbr       0x61736272
+#define daap_asdc       0x61736463
+#define daap_asdn       0x6173646e
+#define daap_astc       0x61737463
+#define daap_astn       0x6173746e
+#define daap_asyr       0x61737972
+/* byte  tags */
+#define daap_mikd       0x6d696b64
+#define daap_msau       0x6d736175
+#define daap_msty       0x6d737479
+#define daap_asrv       0x61737276
+#define daap_asur       0x61737572
+#define daap_asdk       0x6173646b
+/* boolean  tags */
+#define daap_mslr       0x6d736c72
+#define daap_msal       0x6d73616c
+#define daap_msup       0x6d737570
+#define daap_mspi       0x6d737069
+#define daap_msex       0x6d736578
+#define daap_msbr       0x6d736272
+#define daap_msqy       0x6d737179
+#define daap_msix       0x6d736978
+#define daap_msrs       0x6d737273
+#define daap_asco       0x6173636f
+#define daap_asdb       0x61736462
+#define daap_abpl       0x6162706c
+#define daap_aeSP       0x61655350
+/* version (32-bit)*/
+#define daap_mpro       0x6d70726f
+#define daap_apro       0x6170726f
+
+
+/* Initialize the protocol and registered fields */
+static int proto_daap = -1;
+static int hf_daap_name = -1;
+static int hf_daap_size = -1;
+
+/* Initialize the subtree pointers */
+static gint ett_daap = -1;
+static gint ett_daap_sub = -1;
+
+/* Forward declarations */
+static int dissect_daap_one_tag(proto_tree *tree, tvbuff_t *tvb, int offset, int length);
+
+static void
+dissect_daap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+
+   proto_item *ti;
+   proto_tree *daap_tree;
+   int offset = 0;
+   gboolean is_request = (pinfo->destport == TCP_PORT_DAAP);
+   
+   
+   if (check_col(pinfo->cinfo, COL_PROTOCOL)) 
+      col_set_str(pinfo->cinfo, COL_PROTOCOL, "DAAP");
+   
+   
+   if (check_col(pinfo->cinfo, COL_INFO)) {
+      if (is_request) {
+	 col_add_str(pinfo->cinfo, COL_INFO, "DAAP Request");
+      } else {
+	 /* This is done in two functions on purpose. If the tvb_get_xxx()
+	  * functions fail, at least something will be in the info column
+	  */
+	 col_add_str(pinfo->cinfo, COL_INFO, "DAAP Response");
+	 col_append_fstr(pinfo->cinfo, COL_INFO, " [tag: %s, size: %d]",
+			 tvb_get_string(tvb, offset, 4), 
+			 tvb_get_ntohl(tvb, offset+4));
+      }
+   }
+
+   
+   
+   if (tree) {
+      ti = proto_tree_add_item(tree, proto_daap, tvb, 0, -1, FALSE);
+      daap_tree = proto_item_add_subtree(ti, ett_daap);     
+      dissect_daap_one_tag(daap_tree, tvb, offset, 0);
+   }
+}
+
+static int
+dissect_daap_one_tag(proto_tree *tree, tvbuff_t *tvb, int offset, int length)
+{
+   unsigned int tagname;
+   int tagsize;
+   int new_offset;
+   proto_item *ti = NULL;
+   proto_item *ti2 = NULL;
+   proto_tree *new_tree = NULL;
+   guint64 persistent_id;
+
+   do {
+      if (!tvb_offset_exists(tvb, offset)) 
+	 break;
+
+      tagname = tvb_get_ntohl(tvb, offset);
+      tagsize = tvb_get_ntohl(tvb, offset+4);
+      ti = proto_tree_add_text(tree, tvb, offset, tagsize+8, 
+			       "Tag: %c%c%c%c, Size: %d", 
+			       tvb_get_guint8(tvb, offset),
+			       tvb_get_guint8(tvb, offset+1),
+			       tvb_get_guint8(tvb, offset+2),
+			       tvb_get_guint8(tvb, offset+3),
+			       tagsize);
+
+      ti2 = proto_tree_add_item(tree, hf_daap_name, tvb, offset, 4, FALSE);
+      PROTO_ITEM_SET_HIDDEN(ti2);
+      ti2 = proto_tree_add_item(tree, hf_daap_size, tvb, offset+4, 4, FALSE);
+      PROTO_ITEM_SET_HIDDEN(ti2);
+      offset += 8;
+      length -= 8;
+
+      switch (tagname) {
+      case daap_mcon:
+      case daap_msrv:
+      case daap_mccr:
+      case daap_mdcl:
+      case daap_mlog:
+      case daap_mupd:
+      case daap_avdb:
+      case daap_mlcl:
+      case daap_mlit:
+      case daap_mbcl:
+      case daap_adbs:
+      case daap_aply:
+      case daap_apso:
+      case daap_mudl:
+      case daap_abro:
+      case daap_abal:
+      case daap_abcp:
+      case daap_abgn:
+      case daap_prsv:
+      case daap_arif:
+	 /* Container tags */
+	 new_tree = proto_item_add_subtree(ti, ett_daap_sub);
+	 new_offset = dissect_daap_one_tag(new_tree, tvb, offset, 
+					   tagsize);
+	 break;
+      case daap_minm:
+      case daap_msts:
+      case daap_mcnm:
+      case daap_mcna:
+      case daap_asal:
+      case daap_asar:
+      case daap_ascm:
+      case daap_asfm:
+      case daap_aseq:
+      case daap_asgn:
+      case daap_asdt:
+      case daap_asul:
+	 /* Tags contain strings */
+	 proto_item_append_text(ti, ", Data: %s", 
+				tvb_get_string(tvb, offset, tagsize));
+	 break;
+      case daap_mper:
+	 /* Tags conain uint64 */
+	 persistent_id = tvb_get_ntohl(tvb, offset);
+	 persistent_id <<= 32;
+	 persistent_id = tvb_get_ntohl(tvb, offset+4);
+	 proto_item_append_text(ti, ", Persistent Id: %" PRIu64, 
+				persistent_id);
+	 break;
+      case daap_mstt:
+	 proto_item_append_text(ti, ", Status: %d", 
+				tvb_get_ntohl(tvb, offset));
+	 break;
+      case daap_musr:
+      case daap_msur:
+	 proto_item_append_text(ti, ", Revision: %d", 
+				tvb_get_ntohl(tvb, offset));
+	 break;
+      case daap_miid:
+      case daap_mcti:
+      case daap_mpco:
+      case daap_mlid:
+	 proto_item_append_text(ti, ", Id: %d", 
+				tvb_get_ntohl(tvb, offset));
+	 break;
+      case daap_mrco:
+      case daap_mtco:
+      case daap_mimc:
+      case daap_msdc:
+	 proto_item_append_text(ti, ", Count: %d", 
+				tvb_get_ntohl(tvb, offset));
+	 break;
+      case daap_mstm:
+	 proto_item_append_text(ti, ", Timeout: %d seconds", 
+				tvb_get_ntohl(tvb, offset));
+	 break;
+      case daap_asda:
+      case daap_asdm:
+      case daap_assr:
+      case daap_assz:
+      case daap_asst:
+      case daap_assp:
+      case daap_astm:
+      case daap_aeNV:
+	 /* Tags conain uint32 */
+	 proto_item_append_text(ti, ", Data: %d", 
+				tvb_get_ntohl(tvb, offset));
+	 break;
+
+      case daap_mcty:
+      case daap_asbt:
+      case daap_asbr:
+      case daap_asdc:
+      case daap_asdn:
+      case daap_astc:
+      case daap_astn:
+      case daap_asyr:
+	 /* Tags conain uint16 */
+	 proto_item_append_text(ti, ", Data: %d", 
+				tvb_get_ntohs(tvb, offset));
+	 break;
+
+      case daap_mikd:
+      case daap_msau:
+      case daap_msty:
+      case daap_asrv:
+      case daap_asur:
+      case daap_asdk:
+	 /* Tags conain uint8 */
+	 proto_item_append_text(ti, ", Data: %d", 
+				tvb_get_guint8(tvb, offset));
+
+	 break;
+
+      case daap_mslr:
+      case daap_msal:
+      case daap_msup:
+      case daap_mspi:
+      case daap_msex:
+      case daap_msbr:
+      case daap_msqy:
+      case daap_msix:
+      case daap_msrs:
+      case daap_asco:
+      case daap_asdb:
+      case daap_abpl:
+      case daap_aeSP:
+	 /* Tags ARE boolean. Data is (uint8), but it seems
+	  * the value is always zero. So, if the tag is present
+	  * the "bool" is true. 
+	  */
+	 proto_item_append_text(ti, ", Data: True");
+	 break;
+
+      case daap_mpro:
+      case daap_apro:
+	 /* Tags conain version (uint32) */
+	 proto_item_append_text(ti, ", Version: %d.%d.%d.%d",
+				tvb_get_guint8(tvb, offset),
+				tvb_get_guint8(tvb, offset+1),
+				tvb_get_guint8(tvb, offset+2),
+				tvb_get_guint8(tvb, offset+3));
+	 break;
+
+      default: 
+	 break;
+      }
+      offset += tagsize;
+      length -= tagsize;
+   } while (length > 0);
+   return offset;
+
+}
+
+
+/* Register the protocol with Ethereal */
+void
+proto_register_daap(void)
+{                 
+   
+   static hf_register_info hf[] = {
+      { &hf_daap_name,
+	{ "Name", "daap.name", FT_STRING, BASE_NONE, NULL, 0x0, 
+	  "Tag Name", HFILL}
+      },
+      { &hf_daap_size,
+	{ "Size", "daap.size", FT_UINT32, BASE_DEC, NULL, 0x0, 
+	  "Tag Size", HFILL }
+      }
+   };
+
+   static gint *ett[] = {
+      &ett_daap,
+      &ett_daap_sub,
+   };
+
+   proto_daap = proto_register_protocol("Digital Audio Access Protocol",
+					"DAAP", "daap");
+
+   proto_register_field_array(proto_daap, hf, array_length(hf));
+   proto_register_subtree_array(ett, array_length(ett));
+}
+
+
+/* If this dissector uses sub-dissector registration add a registration routine.
+   This format is required because a script is used to find these routines and
+   create the code that calls these routines.
+*/
+void
+proto_reg_handoff_daap(void)
+{
+	dissector_handle_t daap_handle;
+
+	daap_handle = create_dissector_handle(dissect_daap,
+	    proto_daap);
+       	http_dissector_add(TCP_PORT_DAAP, daap_handle);
+}