/src/wireshark/epan/dissectors/packet-dpauxmon.c
Line | Count | Source |
1 | | /* packet-dpauxmon.c |
2 | | * Routines for DisplayPort AUX-Channel monitor dissection |
3 | | * Copyright 2018, Dirk Eibach, Guntermann & Drunck GmbH <dirk.eibach@gdsys.cc> |
4 | | * |
5 | | * Wireshark - Network traffic analyzer |
6 | | * By Gerald Combs <gerald@wireshark.org> |
7 | | * Copyright 1998 Gerald Combs |
8 | | * |
9 | | * SPDX-License-Identifier: GPL-2.0-or-later |
10 | | */ |
11 | | |
12 | | #include <config.h> |
13 | | |
14 | | #include <epan/packet.h> |
15 | | #include <epan/conversation.h> |
16 | | #include <epan/proto_data.h> |
17 | | #include <wiretap/wtap.h> |
18 | | |
19 | | #include "packet-dpaux.h" |
20 | | |
21 | | enum { |
22 | | DPAUXMON_DATA = 0x00, |
23 | | DPAUXMON_DATA_END = 0x01, |
24 | | DPAUXMON_EVENT = 0x02, |
25 | | DPAUXMON_START = 0x03, |
26 | | DPAUXMON_STOP = 0x04, |
27 | | DPAUXMON_TS_OVERFLOW = 0x84, |
28 | | }; |
29 | | |
30 | | void proto_reg_handoff_dpauxmon(void); |
31 | | void proto_register_dpauxmon(void); |
32 | | |
33 | | static dissector_handle_t dpaux_handle; |
34 | | static dissector_handle_t dpauxmon_handle; |
35 | | |
36 | | /* Initialize the protocol and registered fields */ |
37 | | static int proto_dpauxmon; |
38 | | |
39 | | static int hf_packet_type; |
40 | | static int hf_origin; |
41 | | static int hf_inputs; |
42 | | static int hf_hpd; |
43 | | static int hf_in0; |
44 | | static int hf_in1; |
45 | | static int hf_in2; |
46 | | |
47 | | static int * const input_fields[] = { |
48 | | &hf_hpd, |
49 | | &hf_in0, |
50 | | &hf_in1, |
51 | | &hf_in2, |
52 | | NULL |
53 | | }; |
54 | | |
55 | | /* Initialize the subtree pointers */ |
56 | | static int ett_dpauxmon; |
57 | | |
58 | | static const value_string packet_type_vals[] = { |
59 | | { DPAUXMON_DATA, "Data" }, |
60 | | { DPAUXMON_EVENT, "Event" }, |
61 | | { DPAUXMON_START, "Start" }, |
62 | | { DPAUXMON_STOP, "Stop" }, |
63 | | { DPAUXMON_TS_OVERFLOW, "Timestamp Overflow" }, |
64 | | { 0, NULL } |
65 | | }; |
66 | | |
67 | | static const value_string origin_vals[] = { |
68 | | { 0, "Sink" }, |
69 | | { 1, "Source" }, |
70 | | { 0, NULL } |
71 | | }; |
72 | | |
73 | | static int |
74 | | dissect_dpauxmon(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, |
75 | | void *data _U_) |
76 | 3 | { |
77 | 3 | proto_item *ti; |
78 | 3 | proto_tree *dpauxmon_tree; |
79 | 3 | uint32_t packet_type; |
80 | | |
81 | 3 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "DPAUXMON"); |
82 | 3 | col_set_str(pinfo->cinfo, COL_RES_DL_DST, "N/A"); |
83 | 3 | col_set_str(pinfo->cinfo, COL_RES_DL_SRC, "Internal"); |
84 | | |
85 | | /* create display subtree for the protocol */ |
86 | 3 | ti = proto_tree_add_item(tree, proto_dpauxmon, tvb, 0, -1, ENC_NA); |
87 | 3 | dpauxmon_tree = proto_item_add_subtree(ti, ett_dpauxmon); |
88 | | |
89 | 3 | proto_tree_add_item_ret_uint(dpauxmon_tree, hf_packet_type, tvb, 0, 1, ENC_NA, &packet_type); |
90 | 3 | col_add_fstr(pinfo->cinfo, COL_INFO, "DisplayPort AUX channel - %s", val_to_str_const(packet_type, packet_type_vals, "Unknown")); |
91 | | |
92 | 3 | switch (packet_type) { |
93 | 2 | case DPAUXMON_DATA: { |
94 | 2 | struct dpaux_info dpaux_info; |
95 | | |
96 | 2 | dpaux_info.from_source = tvb_get_uint8(tvb, 1); |
97 | 2 | proto_tree_add_uint(dpauxmon_tree, hf_origin, tvb, 1, 1, dpaux_info.from_source); |
98 | | |
99 | 2 | call_dissector_with_data(dpaux_handle, tvb_new_subset_remaining(tvb, 2), |
100 | 2 | pinfo, dpauxmon_tree, &dpaux_info); |
101 | 2 | break; |
102 | 0 | } |
103 | 0 | case DPAUXMON_EVENT: |
104 | 0 | case DPAUXMON_START: |
105 | 0 | proto_tree_add_bitmask(dpauxmon_tree, tvb, 1, hf_inputs, 0, input_fields, |
106 | 0 | ENC_BIG_ENDIAN); |
107 | 0 | break; |
108 | 0 | case DPAUXMON_STOP: |
109 | 0 | break; |
110 | 0 | case DPAUXMON_TS_OVERFLOW: |
111 | 0 | break; |
112 | 3 | }; |
113 | | |
114 | 2 | return tvb_captured_length(tvb); |
115 | 3 | } |
116 | | |
117 | | void |
118 | | proto_register_dpauxmon(void) |
119 | 15 | { |
120 | | /* Setup protocol subtree array */ |
121 | 15 | static int *ett[] = { |
122 | 15 | &ett_dpauxmon |
123 | 15 | }; |
124 | | |
125 | | /* Setup list of header fields See Section 1.5 of README.dissector for |
126 | | * details. */ |
127 | 15 | static hf_register_info hf[] = { |
128 | 15 | { &hf_packet_type, |
129 | 15 | { "Packet Type", "dpauxmon.packet_type", |
130 | 15 | FT_UINT8, BASE_DEC, VALS(packet_type_vals), 0, |
131 | 15 | NULL, HFILL } |
132 | 15 | }, |
133 | 15 | { &hf_origin, |
134 | 15 | { "Origin", "dpauxmon.origin", |
135 | 15 | FT_UINT8, BASE_DEC, VALS(origin_vals), 0, |
136 | 15 | NULL, HFILL } |
137 | 15 | }, |
138 | 15 | { &hf_inputs, |
139 | 15 | { "Inputs", "dpauxmon.inputs", |
140 | 15 | FT_UINT8, BASE_HEX, NULL, 0, |
141 | 15 | NULL, HFILL } |
142 | 15 | }, |
143 | 15 | { &hf_hpd, |
144 | 15 | { "Hotplug Detect", "dpauxmon.hpd", |
145 | 15 | FT_BOOLEAN, 4, NULL, 0x1, |
146 | 15 | NULL, HFILL } |
147 | 15 | }, |
148 | 15 | { &hf_in0, |
149 | 15 | { "IN0", "dpauxmon.in0", |
150 | 15 | FT_BOOLEAN, 4, NULL, 0x2, |
151 | 15 | NULL, HFILL } |
152 | 15 | }, |
153 | 15 | { &hf_in1, |
154 | 15 | { "IN1", "dpauxmon.in1", |
155 | 15 | FT_BOOLEAN, 4, NULL, 0x4, |
156 | 15 | NULL, HFILL } |
157 | 15 | }, |
158 | 15 | { &hf_in2, |
159 | 15 | { "IN2", "dpauxmon.in2", |
160 | 15 | FT_BOOLEAN, 4, NULL, 0x8, |
161 | 15 | NULL, HFILL } |
162 | 15 | }, |
163 | 15 | }; |
164 | | |
165 | | /* Register the protocol name and description */ |
166 | 15 | proto_dpauxmon = proto_register_protocol("DPAUXMON DisplayPort AUX channel monitor", "DPAUXMON", "dpauxmon"); |
167 | 15 | proto_register_field_array(proto_dpauxmon, hf, array_length(hf)); |
168 | 15 | proto_register_subtree_array(ett, array_length(ett)); |
169 | | |
170 | 15 | dpauxmon_handle = register_dissector("dpauxmon", dissect_dpauxmon, proto_dpauxmon); |
171 | 15 | } |
172 | | |
173 | | void |
174 | | proto_reg_handoff_dpauxmon(void) |
175 | 15 | { |
176 | 15 | static bool initialized = false; |
177 | | |
178 | 15 | dpaux_handle = find_dissector_add_dependency("dpaux", proto_dpauxmon); |
179 | | |
180 | 15 | if (!initialized) { |
181 | 15 | initialized = true; |
182 | 15 | } else { |
183 | 0 | dissector_delete_uint("wtap_encap", WTAP_ENCAP_DPAUXMON, dpauxmon_handle); |
184 | 0 | } |
185 | | |
186 | 15 | dissector_add_uint("wtap_encap", WTAP_ENCAP_DPAUXMON, dpauxmon_handle); |
187 | 15 | } |
188 | | |
189 | | /* |
190 | | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
191 | | * |
192 | | * Local variables: |
193 | | * c-basic-offset: 4 |
194 | | * tab-width: 8 |
195 | | * indent-tabs-mode: nil |
196 | | * End: |
197 | | * |
198 | | * vi: set shiftwidth=4 tabstop=8 expandtab: |
199 | | * :indentSize=4:tabSize=8:noTabs=true: |
200 | | */ |