wireshark/epan/dissectors/packet-daap.c

808 lines
26 KiB
C

/* packet-daap.c
* Routines for Digital Audio Access Protocol dissection
* Copyright 2004, Kelly Byrd <kbyrd@memcpy.com>
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "config.h"
#include <epan/packet.h>
#include <epan/exceptions.h>
#include <wsutil/str_util.h>
#include <epan/expert.h>
#include <epan/proto_data.h>
#include "packet-http.h"
#define TCP_PORT_DAAP 3689
/* DAAP tags */
/* Some information taken from http://tapjam.net/daap/ */
/* and http://www.deleet.de/projekte/daap/?ContentCodes */
/* DACP tags */
/* Information from http://dacp.jsharkey.org/ */
/* and http://code.google.com/p/tunesremote-plus/ */
/* 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_abar 0x61626172
#define daap_arsv 0x61727376
#define daap_abal 0x6162616c
#define daap_abcp 0x61626370
#define daap_abgn 0x6162676e
#define daap_prsv 0x70727376
#define daap_arif 0x61726966
#define daap_mctc 0x6d637463
#define dacp_casp 0x63617370
#define dacp_cmst 0x636d7374
#define dacp_cmgt 0x636d6774
/* 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
#define daap_ascp 0x61736370
#define daap_asct 0x61736374
#define daap_ascn 0x6173636e
#define daap_aslc 0x61736c63
#define daap_asky 0x61736b79
#define daap_aeSN 0x6165534e
#define daap_aeNN 0x61654e4e
#define daap_aeEN 0x6165454e
#define daap_assn 0x6173736e
#define daap_assa 0x61737361
#define daap_assl 0x6173736c
#define daap_assc 0x61737363
#define daap_asss 0x61737373
#define daap_asaa 0x61736161
#define daap_aspu 0x61737075
#define daap_aeCR 0x61654352
#define dacp_cana 0x63616e61
#define dacp_cang 0x63616e67
#define dacp_canl 0x63616e6c
#define dacp_cann 0x63616e6e
/* uint64 tags */
#define daap_mper 0x6d706572
#define daap_aeGU 0x61654755
#define daap_aeGR 0x61654752
#define daap_asai 0x61736169
#define daap_asls 0x61736c73
/* 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
#define daap_ascd 0x61736364
#define daap_ascs 0x61736373
#define daap_aeSV 0x61655356
#define daap_aePI 0x61655049
#define daap_aeCI 0x61654349
#define daap_aeGI 0x61654749
#define daap_aeAI 0x61654149
#define daap_aeSI 0x61655349
#define daap_aeES 0x61654553
#define daap_aeSU 0x61655355
#define daap_asbo 0x6173626f
#define daap_aeGH 0x61654748
#define daap_aeGD 0x61654744
#define daap_aeGE 0x61654745
#define daap_meds 0x6d656473
#define dacp_cmsr 0x636d7372
#define dacp_cant 0x63616e74
#define dacp_cast 0x63617374
#define dacp_cmvo 0x636d766f
/*TODO:
#define daap_msto 0x6d7374OO utcoffset
*/
/* 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
#define daap_ased 0x61736564
/* byte tags */
#define daap_mikd 0x6d696b64
#define daap_msau 0x6d736175
#define daap_msty 0x6d737479
#define daap_asrv 0x61737276 /* XXX: may be uint16 in newer iTunes versions! */
#define daap_asur 0x61737572
#define daap_asdk 0x6173646b
#define daap_muty 0x6d757479
#define daap_msas 0x6d736173
#define daap_aeHV 0x61654856
#define daap_aeHD 0x61654844
#define daap_aePC 0x61655043
#define daap_aePP 0x61655050
#define daap_aeMK 0x61654d4b
#define daap_aeSG 0x61655347
#define daap_apsm 0x6170736d
#define daap_aprm 0x6170726d
#define daap_asgp 0x61736770
#define daap_aePS 0x61655053
#define daap_asbk 0x6173626b
#define dacp_cafs 0x63616673
#define dacp_caps 0x63617073
#define dacp_carp 0x63617270
#define dacp_cash 0x63617368
#define dacp_cavs 0x63617673
/* 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
#define daap_ashp 0x61736870
/* version (32-bit)*/
#define daap_mpro 0x6d70726f
#define daap_apro 0x6170726f
/* now playing */
#define dacp_canp 0x63616e70
#define daap_png 0x89504e47
/* date/time */
/* TODO:
#define daap_mstc 0xMMSSTTCC utctime
#define daap_asdr ("daap.songdatereleased")
#define daap_asdp ("daap.songdatepurchased")
*/
void proto_register_daap(void);
void proto_reg_handoff_daap(void);
static dissector_handle_t png_handle;
/*XXX: Sorted by value definition since it appears that the "value" is just */
/* the ascii representation of the last 4 letters of the definition. */
/* (Sorted so a binary search can be done when using value_string_ext) */
static const value_string vals_tag_code[] = {
{ daap_abal, "browse album listing" },
{ daap_abar, "browse artist listing" },
{ daap_abcp, "browse composer listing" },
{ daap_abgn, "browse genre listing" },
{ daap_abpl, "base playlist" },
{ daap_abro, "database browse" },
{ daap_adbs, "database songs" },
{ daap_aeAI, "com.apple.itunes.itms-artistid" },
{ daap_aeCI, "com.apple.itunes.itms-composerid" },
{ daap_aeCR, "com.apple.itunes.content-rating" },
{ daap_aeEN, "com.apple.itunes.episode-num-str" },
{ daap_aeES, "com.apple.itunes.episode-sort" },
{ daap_aeGD, "com.apple.itunes.gapless-enc-dr" },
{ daap_aeGE, "com.apple.itunes.gapless-enc-del" },
{ daap_aeGH, "com.apple.itunes.gapless-heur" },
{ daap_aeGI, "com.apple.itunes.itms-genreid" },
{ daap_aeGR, "com.apple.itunes.gapless-resy" },
{ daap_aeGU, "com.apple.itunes.gapless-dur" },
{ daap_aeHD, "com.apple.itunes.is-hd-video" },
{ daap_aeHV, "com.apple.itunes.has-video" },
{ daap_aeMK, "com.apple.itunes.mediakind" },
{ daap_aeNN, "com.apple.itunes.network-name" },
{ daap_aeNV, "com.apple.itunes.norm-volume" },
{ daap_aePC, "com.apple.itunes.is-podcast" },
{ daap_aePI, "com.apple.itunes.itms-playlistid" },
{ daap_aePP, "com.apple.itunes.is-podcast-playlist" },
{ daap_aePS, "com.apple.itunes.special-playlist" },
{ daap_aeSG, "com.apple.itunes.saved-genius" },
{ daap_aeSI, "com.apple.itunes.itms-songid" },
{ daap_aeSN, "com.apple.itunes.series-name" },
{ daap_aeSP, "com.apple.itunes.smart-playlist" },
{ daap_aeSU, "com.apple.itunes.season-num" },
{ daap_aeSV, "com.apple.itunes.music-sharing-version" },
{ daap_aply, "database playlists" },
{ daap_aprm, "playlist repeat mode" },
{ daap_apro, "protocol (application?) version (apro)" },
{ daap_apsm, "playlist shuffle mode" },
{ daap_apso, "playlist songs" },
{ daap_arif, "resolveinfo" },
{ daap_arsv, "resolve" },
{ daap_asaa, "song album artist" },
{ daap_asai, "song album id"},
{ daap_asal, "song album" },
{ daap_asar, "song artist" },
{ daap_asbk, "song bookmarkable" },
{ daap_asbo, "song bookmark" },
{ daap_asbr, "song bitrate" },
{ daap_asbt, "song beats-per-minute" },
{ daap_ascd, "song codec type" },
{ daap_ascm, "song comment" },
{ daap_ascn, "song content description" },
{ daap_asco, "song compilation" },
{ daap_ascp, "song composer" },
{ daap_ascs, "song codec subtype" },
{ daap_asct, "song category" },
{ daap_asda, "song date added" },
{ daap_asdb, "song disabled" },
{ daap_asdc, "song disccount" },
{ daap_asdk, "song data kind" },
{ daap_asdm, "song date modified" },
{ daap_asdn, "song discnumber" },
{ daap_asdt, "song description" },
{ daap_ased, "song extra data" },
{ daap_aseq, "song eq preset" },
{ daap_asfm, "song format" },
{ daap_asgn, "song genre" },
{ daap_asgp, "song gapless" },
{ daap_ashp, "song has been played" },
{ daap_asky, "song keywords" },
{ daap_aslc, "song long content description" },
{ daap_asls, "song long size"},
{ daap_aspu, "song podcast url" },
{ daap_asrv, "song relative volume" },
{ daap_assa, "sort artist" },
{ daap_assc, "sort composer" },
{ daap_assn, "sort name" },
{ daap_assp, "song stop time (milliseconds)" },
{ daap_assr, "song sample rate" },
{ daap_asss, "sort seriesname" },
{ daap_asst, "song start time (milliseconds)" },
{ daap_assz, "song size" },
{ daap_astc, "song track count" },
{ daap_astm, "song time (milliseconds)" },
{ daap_astn, "song track number" },
{ daap_asul, "song data url" },
{ daap_asur, "song user rating" },
{ daap_asyr, "song year" },
{ daap_avdb, "server databases" },
{ dacp_cafs, "fullscreen" },
{ dacp_cana, "song artist" },
{ dacp_cang, "song genre" },
{ dacp_canl, "song album" },
{ dacp_cann, "song name" },
{ dacp_canp, "now playing" },
{ dacp_cant, "song time remaining (milliseconds)" },
{ dacp_caps, "play status" },
{ dacp_carp, "repeat" },
{ dacp_cash, "shuffle" },
{ dacp_casp, "speakers container" },
{ dacp_cast, "song time total (milliseconds)" },
{ dacp_cavs, "visualizer" },
{ dacp_cmgt, "container (cmgt)" },
{ dacp_cmsr, "status revision" },
{ dacp_cmst, "control container" },
{ dacp_cmvo, "volume" },
{ daap_mbcl, "bag (mbcl)" },
{ daap_mccr, "content codes response" },
{ daap_mcna, "content codes name" },
{ daap_mcnm, "content codes number" },
{ daap_mcon, "container (mcon)" },
{ daap_mctc, "container count" },
{ daap_mcti, "container item id (mcti)" },
{ daap_mcty, "content codes type" },
{ daap_mdcl, "dictionary (mdcl)" },
{ daap_meds, "edit commands supported" },
{ daap_miid, "item id (miid)" },
{ daap_mikd, "item kind (mikd)" },
{ daap_mimc, "item count (mimc)" },
{ daap_minm, "item name (minm)" },
{ daap_mlcl, "listing (mlcl)" },
{ daap_mlid, "session id" },
{ daap_mlit, "listing item (mlit)" },
{ daap_mlog, "login response" },
{ daap_mpco, "parent container id (mpco)" },
{ daap_mper, "persistent id (mper)" },
{ daap_mpro, "protocol version (mpro)" },
{ daap_mrco, "returned count (mrco)" },
{ daap_msal, "supports auto-logout (msal)" },
{ daap_msas, "authentication schemes" },
{ daap_msau, "authentication method (msau)" },
{ daap_msbr, "supports browse" },
{ daap_msdc, "databases count" },
{ daap_msex, "supports extensions (msex)" },
{ daap_msix, "supports index" },
{ daap_mslr, "login required (mslr)" },
{ daap_mspi, "supports persistent ids (mspi)" },
{ daap_msqy, "supports query" },
{ daap_msrs, "supports resolve" },
{ daap_msrv, "server info response (msrv)" },
{ daap_mstm, "timeout interval" },
{ daap_msts, "status string (msts)" },
{ daap_mstt, "status (mstt)" },
{ daap_msup, "supports update (msup)" },
{ daap_msur, "server revision" },
{ daap_mtco, "specified total count (mtco)" },
{ daap_mudl, "deleted id listing" },
{ daap_mupd, "update response" },
{ daap_musr, "server revision" },
{ daap_muty, "update type" },
{ daap_prsv, "resolve" },
{ 0, NULL}
};
static value_string_ext vals_tag_code_ext = VALUE_STRING_EXT_INIT(vals_tag_code);
/* Initialize the protocol and registered fields */
static int proto_daap = -1;
static int hf_daap_name = -1;
static int hf_daap_size = -1;
static int hf_daap_data_string = -1;
static int hf_daap_persistent_id = -1;
static int hf_daap_status = -1;
static int hf_daap_rev = -1;
static int hf_daap_id = -1;
static int hf_daap_cnt = -1;
static int hf_daap_timeout = -1;
static int hf_daap_data = -1;
static int hf_daap_playlist_id = -1;
static int hf_daap_track_id = -1;
/* Initialize the subtree pointers */
static gint ett_daap = -1;
static gint ett_daap_sub = -1;
static expert_field ei_daap_max_recursion_depth_reached = EI_INIT;
/* Forward declarations */
static void dissect_daap_one_tag(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb);
static int
dissect_daap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
{
proto_item *ti;
proto_tree *daap_tree;
guint first_tag;
first_tag = tvb_get_ntohl(tvb, 0);
col_set_str(pinfo->cinfo, COL_PROTOCOL, "DAAP");
/*
* This catches album art coming back from iTunes.
* XXX - will those have a media type of image/png
* rather than application/x-dmap-tagged? If so,
* this is no longer necessary.
*/
if (first_tag == daap_png) {
call_dissector(png_handle, tvb, pinfo, tree);
return tvb_captured_length(tvb);
}
/* 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_set_str(pinfo->cinfo, COL_INFO, "DAAP Response");
col_append_fstr(pinfo->cinfo, COL_INFO, " [first tag: %s, size: %d]",
tvb_format_text(tvb, 0, 4),
tvb_get_ntohl(tvb, 4));
ti = proto_tree_add_item(tree, proto_daap, tvb, 0, -1, ENC_NA);
daap_tree = proto_item_add_subtree(ti, ett_daap);
dissect_daap_one_tag(daap_tree, pinfo, tvb);
return tvb_captured_length(tvb);
}
#define DAAP_MAX_RECURSION_DEPTH 100
static void
dissect_daap_one_tag(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb)
{
guint offset = 0;
guint32 tagname, tagsize;
proto_item *tag_ti;
proto_tree *tag_tree;
tvbuff_t *new_tvb;
unsigned recursion_depth = p_get_proto_depth(pinfo, proto_daap);
if (++recursion_depth >= DAAP_MAX_RECURSION_DEPTH) {
proto_tree_add_expert(tree, pinfo, &ei_daap_max_recursion_depth_reached,
tvb, 0, 0);
return;
}
p_set_proto_depth(pinfo, proto_daap, recursion_depth);
while (offset < tvb_reported_length(tvb)) {
tagname = tvb_get_ntohl(tvb, offset);
tagsize = tvb_get_ntohl(tvb, offset+4);
tag_tree = proto_tree_add_subtree(tree, tvb, offset, -1,
ett_daap_sub, &tag_ti, "Tag: ");
proto_tree_add_item_ret_uint(tag_tree, hf_daap_name,
tvb, offset, 4, ENC_ASCII|ENC_NA, &tagname);
offset += 4;
proto_tree_add_item_ret_uint(tag_tree, hf_daap_size,
tvb, offset, 4, ENC_BIG_ENDIAN, &tagsize);
offset += 4;
proto_item_append_text(tag_ti, "%s, %u byte%c",
val_to_str_ext(tagname, &vals_tag_code_ext, "Unknown tag (0x%0x)"),
tagsize, plurality(tagsize, ' ', 's'));
proto_item_set_len(tag_ti, 8+tagsize);
if (tagsize > G_MAXINT)
break;
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_abar:
case daap_arsv:
case daap_abal:
case daap_abcp:
case daap_abgn:
case daap_prsv:
case daap_arif:
case dacp_casp:
case dacp_cmgt:
case dacp_cmst:
/* Container tags */
new_tvb = tvb_new_subset_length(tvb, offset, (gint)tagsize);
dissect_daap_one_tag(tag_tree, pinfo, new_tvb);
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:
case daap_ascp:
case daap_asct:
case daap_ascn:
case daap_aslc:
case daap_asky:
case daap_aeSN:
case daap_aeNN:
case daap_aeEN:
case daap_assn:
case daap_assa:
case daap_assl:
case daap_assc:
case daap_asss:
case daap_asaa:
case daap_aspu:
case daap_aeCR:
case dacp_cana:
case dacp_cang:
case dacp_canl:
case dacp_cann:
/* Tags contain strings
XXX - verify that they're really 7bit ASCII */
proto_tree_add_item(tag_tree, hf_daap_data_string,
tvb, offset, tagsize, ENC_ASCII|ENC_NA);
break;
case daap_mper:
case daap_aeGR:
case daap_aeGU:
case daap_asai:
case daap_asls:
proto_tree_add_item(tag_tree, hf_daap_persistent_id,
tvb, offset, tagsize, ENC_BIG_ENDIAN);
break;
case daap_mstt:
proto_tree_add_item(tag_tree, hf_daap_status,
tvb, offset, tagsize, ENC_BIG_ENDIAN);
break;
case daap_musr:
case daap_msur:
proto_tree_add_item(tag_tree, hf_daap_rev,
tvb, offset, tagsize, ENC_BIG_ENDIAN);
break;
case daap_miid:
case daap_mcti:
case daap_mpco:
case daap_mlid:
proto_tree_add_item(tag_tree, hf_daap_id,
tvb, offset, tagsize, ENC_BIG_ENDIAN);
break;
case daap_mrco:
case daap_mtco:
case daap_mimc:
case daap_msdc:
case daap_mctc:
proto_tree_add_item(tag_tree, hf_daap_cnt,
tvb, offset, tagsize, ENC_BIG_ENDIAN);
break;
case daap_mstm:
proto_tree_add_item(tag_tree, hf_daap_timeout,
tvb, offset, tagsize, ENC_BIG_ENDIAN);
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:
case daap_ascd:
case daap_ascs:
case daap_aeSV:
case daap_aePI:
case daap_aeCI:
case daap_aeGI:
case daap_aeAI:
case daap_aeSI:
case daap_aeES:
case daap_asbo:
case daap_aeGH:
case daap_aeGD:
case daap_aeGE:
case dacp_cant:
case dacp_cast:
case dacp_cmsr:
case dacp_cmvo:
case daap_meds:
/* Tags contain uint32
XXX - check tagsize here and below */
proto_tree_add_item(tag_tree, hf_daap_data,
tvb, offset, tagsize, ENC_BIG_ENDIAN);
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:
case daap_ased:
/* Tags contain uint16 */
proto_tree_add_item(tag_tree, hf_daap_data,
tvb, offset, tagsize, ENC_BIG_ENDIAN);
break;
case daap_mikd:
case daap_msau:
case daap_msty:
case daap_asrv:
case daap_asur:
case daap_asdk:
case daap_muty:
case daap_msas:
case daap_aeHV:
case daap_aeHD:
case daap_aePC:
case daap_aePP:
case daap_aeMK:
case daap_aeSG:
case daap_apsm:
case daap_aprm:
case daap_asgp:
case daap_aePS:
case dacp_cafs:
case dacp_caps:
case dacp_carp:
case dacp_cash:
case dacp_cavs:
/* Tags contain uint8 */
proto_tree_add_item(tag_tree, hf_daap_data,
tvb, offset, tagsize, ENC_BIG_ENDIAN);
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:
case daap_asbk:
/* 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(tag_ti, "; Data: True");
break;
case daap_mpro:
case daap_apro:
/* Tags contain version (uint32) */
proto_item_append_text(tag_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;
case dacp_canp:
/* now playing */
/* bytes 4-7 contain uint32 playlist id */
/* bytes 12-15 contain uint32 track id */
proto_tree_add_item(tag_tree, hf_daap_playlist_id,
tvb, offset+4, 4, ENC_BIG_ENDIAN);
proto_tree_add_item(tag_tree, hf_daap_track_id,
tvb, offset+12, 4, ENC_BIG_ENDIAN);
break;
default:
break;
}
offset += tagsize;
}
}
/* Register the protocol with Wireshark */
void
proto_register_daap(void)
{
static hf_register_info hf[] = {
{ &hf_daap_name,
{ "Tag name", "daap.name", FT_UINT32,
BASE_HEX|BASE_EXT_STRING, &vals_tag_code_ext, 0, NULL, HFILL }
},
{ &hf_daap_size,
{ "Tag size", "daap.size",
FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }
},
{ &hf_daap_data_string,
{ "Data string", "daap.data_string",
FT_STRING, STR_ASCII, NULL, 0, NULL, HFILL }
},
{ &hf_daap_persistent_id,
{ "Persistent Id", "daap.persistent_id",
FT_UINT64, BASE_HEX, NULL, 0, NULL, HFILL }
},
{ &hf_daap_status,
{ "Status", "daap.status",
FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }
},
{ &hf_daap_rev,
{ "Revision", "daap.revision",
FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }
},
{ &hf_daap_id,
{ "Id", "daap.id",
FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }
},
{ &hf_daap_cnt,
{ "Count", "daap.count",
FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }
},
{ &hf_daap_timeout,
{ "Timeout (seconds)", "daap.timeout",
FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }
},
/* this will hold data for the tags that contain
32, 16 or 8 bits of payload */
{ &hf_daap_data,
{ "Data", "daap.data",
FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }
},
{ &hf_daap_playlist_id,
{ "Playlist Id", "daap.playlist_id",
FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }
},
{ &hf_daap_track_id,
{ "Track Id", "daap.track_id",
FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }
}
};
static gint *ett[] = {
&ett_daap,
&ett_daap_sub,
};
expert_module_t *expert_daap;
static ei_register_info ei[] = {
{ &ei_daap_max_recursion_depth_reached, { "daap.max_recursion_depth_reached",
PI_PROTOCOL, PI_WARN, "Maximum allowed recursion depth reached - stop decoding", EXPFILL }}
};
proto_daap = proto_register_protocol("Digital Audio Access Protocol",
"DAAP", "daap");
expert_daap = expert_register_protocol(proto_daap);
expert_register_field_array(expert_daap, ei, array_length(ei));
proto_register_field_array(proto_daap, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
}
void
proto_reg_handoff_daap(void)
{
dissector_handle_t daap_handle;
daap_handle = create_dissector_handle(dissect_daap, proto_daap);
http_tcp_port_add(TCP_PORT_DAAP);
dissector_add_string("media_type", "application/x-dmap-tagged", daap_handle);
png_handle = find_dissector_add_dependency("png", proto_daap);
}
/*
* Editor modelines - https://www.wireshark.org/tools/modelines.html
*
* Local Variables:
* c-basic-offset: 3
* tab-width: 8
* indent-tabs-mode: nil
* End:
*
* ex: set shiftwidth=3 tabstop=8 expandtab:
* :indentSize=3:tabSize=8:noTabs=true:
*/