Ethereal-dev: [Ethereal-dev] patch: DAAP dissector

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 01:45:03 -0700 (PDT)
Attached is a patch for packet-daap.c, it's addition to Makefile.common,
and some logic in packet-http.c

I didn't factor out the http code that assigns zero length requests
to a specific protocol.

I also didn't tackle adding a real 64-bit type and the corrosponding tvb_*
functions. I'm unsure where that (the FT_ type as guint64) would be done,
so I punted and just stole some code from rsvp. I'd be happy to do this if
someone can give me more hints.

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);
+}