aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-daap.c
diff options
context:
space:
mode:
authorguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>2004-08-22 03:04:54 +0000
committerguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>2004-08-22 03:04:54 +0000
commitcea67c8150b4be1b31ddf6a31721c2e0922b71b0 (patch)
treea31cbf7b9a3a16103b3662cba38649ee7188427d /epan/dissectors/packet-daap.c
parent1e72836dcaa776d5a637539d3405f3f71333b169 (diff)
From Kelly Byrd: DAAP support.
git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@11801 f5534014-38df-0310-8fa8-9805f1628bb7
Diffstat (limited to 'epan/dissectors/packet-daap.c')
-rw-r--r--epan/dissectors/packet-daap.c406
1 files changed, 406 insertions, 0 deletions
diff --git a/epan/dissectors/packet-daap.c b/epan/dissectors/packet-daap.c
new file mode 100644
index 0000000000..f3cb243ff6
--- /dev/null
+++ b/epan/dissectors/packet-daap.c
@@ -0,0 +1,406 @@
+/* packet-daap.c
+ * Routines for Digital Audio Access Protocol dissection
+ * Copyright 2004, Kelly Byrd <kbyrd@memcpy.com>
+ *
+ * $Id: README.developer 11475 2004-07-23 01:37:35Z guy $
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@ethereal.com>
+ * 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 <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);
+}