summaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-media.c
blob: 6a06ad83a7b32958598802fdd90035433b16eb40 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/* packet-media.c
 * Routines for displaying an undissected media type (default case),
 * based on the generic "data" dissector.
 *
 * (C) Olivier Biot, 2004
 *
 * Refer to the AUTHORS file or the AUTHORS section in the man page
 * for contacting the author(s) of this file.
 *
 * 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 <wsutil/str_util.h>

#include "packet-media-type.h"

void proto_register_media(void);

static int proto_media;
static int hf_media_type;
static int ett_media;
static heur_dissector_list_t heur_subdissector_list;
static dissector_table_t media_type_suffix_table;

static int
dissect_media(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
{
    int bytes;
    proto_item *ti;
    proto_tree *media_tree = 0;
    media_content_info_t *content_info = (media_content_info_t *)data;
    heur_dtbl_entry_t *hdtbl_entry;
    char* suffix;

    /* XXX - Should we move the other media_type table here, and have
     * dissectors always call this dissector instead of invoking the table,
     * similar to the Ethertype dissector?
     * It would make Decode As with Media Types easier.
     */

    /*
     * RFC 6838 4.2 Naming Requirements
     * "Characters after last plus always specify a structured syntax suffix"
     */
    if (pinfo->match_string &&
        (suffix = strrchr(pinfo->match_string, '+'))) {

        if ((bytes = dissector_try_string_new(media_type_suffix_table,
                suffix + 1, tvb, pinfo, tree, true, data)) > 0) {
            return bytes;
        }
    }

    if (dissector_try_heuristic(heur_subdissector_list, tvb, pinfo, tree, &hdtbl_entry, data)) {
        return tvb_reported_length(tvb);
    }

    /* Add media type to the INFO column if it is visible */
    col_append_fstr(pinfo->cinfo, COL_INFO, " (%s)", (pinfo->match_string) ? pinfo->match_string : "");

    if (tree) {
        if ( (bytes = tvb_reported_length(tvb)) > 0 )
        {
            ti = proto_tree_add_item(tree, proto_media, tvb, 0, -1, ENC_NA);
            media_tree = proto_item_add_subtree(ti, ett_media);

            if (content_info != NULL && content_info->media_str != NULL) {
                /* The media type has parameters */

                proto_tree_add_bytes_format_value(media_tree, hf_media_type, tvb, 0, bytes,
                    NULL, "%s; %s (%d byte%s)",
                    pinfo->match_string, content_info->media_str,
                    bytes, plurality(bytes, "", "s"));
            } else {
                /* The media type has no parameters */
                proto_tree_add_bytes_format_value(media_tree, hf_media_type, tvb, 0, bytes,
                    NULL, "%s (%d byte%s)",
                    pinfo->match_string ? pinfo->match_string : "",
                    bytes, plurality(bytes, "", "s"));
            }
        }
    }

    return tvb_reported_length(tvb);
}

void
proto_register_media(void)
{
    static hf_register_info hf[] = {
      { &hf_media_type,
        { "Media type", "media.type",
          FT_BYTES, BASE_NONE, NULL, 0,
          NULL, HFILL }},
    };
    static int *ett[] = {
        &ett_media
    };

    proto_media = proto_register_protocol (
        "Media Type",   /* name */
        "Media",        /* short name */
        "media"         /* abbrev */
        );
    register_dissector("media", dissect_media, proto_media);
    heur_subdissector_list = register_heur_dissector_list_with_description("media", "Media type", proto_media);
    proto_register_field_array(proto_media, hf, array_length(hf));
    proto_register_subtree_array(ett, array_length(ett));

    /*
     * "Media" is used to dissect something whose normal dissector
     * is disabled, so it cannot itself be disabled.
     */
    proto_set_cant_toggle(proto_media);

    /*
     * https://www.iana.org/assignments/media-type-structured-suffix/media-type-structured-suffix.xhtml
     * Structured Suffixes ("zzz" in "xxx/yyy+zzz") can be used as fallback
     * when the exact media type is not registered.
     */
    media_type_suffix_table = register_dissector_table("media_type.suffix",
        "Internet media type structured suffix",
        proto_media, FT_STRING, STRING_CASE_INSENSITIVE);
}

/*
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
 *
 * Local variables:
 * c-basic-offset: 4
 * tab-width: 8
 * indent-tabs-mode: nil
 * End:
 *
 * vi: set shiftwidth=4 tabstop=8 expandtab:
 * :indentSize=4:tabSize=8:noTabs=true:
 */