Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-scop.c
blobb4f7cb91518a1e7b886163e58d13cf2e32e9a3a8
1 /* packet-scop.c
2 * Owen Kirby <osk@exegin.com>
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
8 * SPDX-License-Identifier: GPL-2.0-or-later
9 */
11 #include "config.h"
13 #include <epan/packet.h>
14 #include "packet-tcp.h"
16 /* Default SCOP Port numbers. */
17 #define SCOP_DEFAULT_PORT_RANGE "17755-17756"
19 void proto_register_scop(void);
21 /* Structure to contain information from the SCoP packet. */
22 typedef struct {
23 uint8_t transport;
24 uint8_t version;
25 uint16_t length;
26 bool encrypted;
27 uint8_t service;
28 uint8_t type;
29 } scop_packet;
31 /* Header definitions for use with the TCP transport layer. */
32 #define SCOP_HEADER_LENGTH 4
33 #define SCOP_LENGTH_OFFSET 2
35 /* SCoP Transport Types */
36 #define SCOP_TRANSPORT_UDP 1
37 #define SCOP_TRANSPORT_TCP 2
38 #define SCOP_TRANSPORT_UDP_CCM 129
39 #define SCOP_TRANSPORT_TCP_CCM 130
40 #define SCOP_TRANSPORT_TCP_SSL 131
42 /* Service Identifier Field */
43 #define SCOP_SERVICE_SCOP 0x00
44 #define SCOP_SERVICE_BRIDGE 0x01
45 #define SCOP_SERVICE_GATEWAY 0x02
47 /* SCoP Command Values */
48 #define SCOP_CMD_HELLO 0x00
49 #define SCOP_CMD_HELLO_RESP 0x01
50 #define SCOP_CMD_HELLO_ACK 0x02
51 #define SCOP_CMD_GOODBYE 0x04
52 #define SCOP_CMD_GOODBYE_RESP 0x05
53 #define SCOP_CMD_KEEPALIVE_PING 0x06
54 #define SCOP_CMD_KEEPALIVE_PONG 0x07
56 /* Bridge Command type values. */
57 #define SCOP_BRIDGE_CMD 0x00
58 #define SCOP_BRIDGE_MSG 0x01
60 /* Function declarations */
61 void proto_reg_handoff_scop(void);
63 static void dissect_scop_zip (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
64 static void dissect_scop_bridge (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
66 static unsigned get_scop_length(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data);
68 /* Initialize protocol and registered fields */
69 static int proto_scop;
70 static int hf_scop_transport;
71 static int hf_scop_version;
72 static int hf_scop_length;
73 static int hf_scop_service;
74 static int hf_scop_type;
75 static int hf_scop_status;
77 static int ett_scop;
79 static const value_string scop_transports [] = {
80 { SCOP_TRANSPORT_UDP, "UDP Mode 1" },
81 { SCOP_TRANSPORT_TCP, "TCP Mode 2" },
82 { SCOP_TRANSPORT_UDP_CCM, "UDP Mode 1 with CCM* Security" },
83 { SCOP_TRANSPORT_TCP_CCM, "TCP Mode 2 with CCM* Security" },
84 { SCOP_TRANSPORT_TCP_SSL, "TCP Mode 3 with SSL/TSL Tunnel" },
85 { 0, NULL }
88 static const value_string scop_types [] = {
89 { SCOP_CMD_HELLO, "Hello" },
90 { SCOP_CMD_HELLO_RESP, "Hello Response" },
91 { SCOP_CMD_HELLO_ACK, "Hello Acknowledgment" },
92 { SCOP_CMD_GOODBYE, "Goodbye" },
93 { SCOP_CMD_GOODBYE_RESP, "Goodbye Response" },
94 { SCOP_CMD_KEEPALIVE_PING, "Keep Alive Ping" },
95 { SCOP_CMD_KEEPALIVE_PONG, "Keep Alive Pong" },
96 { 0, NULL }
99 static const value_string scop_services [] = {
100 { SCOP_SERVICE_SCOP, "SCoP" },
101 { SCOP_SERVICE_BRIDGE, "Bridge" },
102 { SCOP_SERVICE_GATEWAY, "Gateway" },
103 { 0, NULL }
106 /* Dissector handle */
107 static dissector_handle_t ieee802154_handle;
108 static dissector_handle_t scop_udp_handle;
109 static dissector_handle_t scop_tcp_handle;
112 /*FUNCTION:------------------------------------------------------
113 * NAME
114 * dissect_scop
115 * DESCRIPTION
116 * ZigBee SCoP packet dissection routine for Wireshark.
117 * PARAMETERS
118 * tvbuff_t *tvb - pointer to buffer containing raw packet.
119 * packet_info *pinfo - pointer to packet information fields
120 * proto_tree *tree - pointer to data tree Wireshark uses to display packet.
121 * RETURNS
122 * void
123 *---------------------------------------------------------------
125 static int
126 dissect_scop(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
128 tvbuff_t *next_tvb;
129 proto_item *proto_root;
130 proto_tree *scop_tree;
132 unsigned offset = 0;
133 scop_packet packet;
135 memset(&packet, 0, sizeof(packet));
137 /* Set the protocol name. */
138 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SCoP");
140 /* Clear the info column. */
141 col_clear(pinfo->cinfo, COL_INFO);
143 /* Create the protocol display tree. */
144 proto_root = proto_tree_add_protocol_format(tree, proto_scop, tvb, 0, tvb_captured_length(tvb),
145 "ZigBee SCoP");
146 scop_tree = proto_item_add_subtree(proto_root, ett_scop);
148 /* Extract the SCoP Transport type. */
149 packet.transport = tvb_get_uint8(tvb, offset);
150 proto_tree_add_uint(scop_tree, hf_scop_transport, tvb, offset, 1, packet.transport);
151 offset += 1;
153 /* Extract the SCoP Version. */
154 packet.version = tvb_get_uint8(tvb, offset);
155 proto_tree_add_uint(scop_tree, hf_scop_version, tvb, offset, 1, packet.version);
156 offset += 1;
158 /* Extract the SCoP Packet length. */
159 packet.length = tvb_get_ntohs(tvb, offset);
160 proto_tree_add_uint(scop_tree, hf_scop_length, tvb, offset, 2, packet.length);
161 offset += 2;
163 if ( (packet.transport == SCOP_TRANSPORT_UDP_CCM)
164 || (packet.transport == SCOP_TRANSPORT_TCP_CCM)) {
165 /* Decryption Failed. */
166 return offset;
168 next_tvb = tvb;
170 /* Extract the service type. */
171 packet.service = tvb_get_uint8(next_tvb, offset);
172 proto_tree_add_uint(scop_tree, hf_scop_service, next_tvb, offset, 1, packet.service);
173 offset += 1;
175 /* Call the appropriate helper routine to dissect based on the service type. */
176 switch (packet.service) {
177 case SCOP_SERVICE_SCOP:
178 dissect_scop_zip(tvb_new_subset_remaining(next_tvb, offset), pinfo, scop_tree);
179 break;
180 case SCOP_SERVICE_BRIDGE:
181 dissect_scop_bridge(tvb_new_subset_remaining(next_tvb, offset), pinfo, scop_tree);
182 break;
183 case SCOP_SERVICE_GATEWAY:
184 /* Nothing yet defined for the gateway. Fall-Through. */
185 default:
186 /* Unknown Service Type. */
187 call_data_dissector(tvb_new_subset_remaining(next_tvb, offset), pinfo, tree);
188 break;
191 return tvb_captured_length(tvb);
192 } /* dissect_scop() */
194 /*FUNCTION:------------------------------------------------------
195 * NAME
196 * get_scop_length
197 * DESCRIPTION
198 * Returns the length of a SCoP packet. For use with the TCP
199 * transport type.
200 * PARAMETERS
201 * packet_info *pinfo - pointer to packet information fields
202 * tvbuff_t *tvb - pointer to buffer containing the packet.
203 * int offset - beginning of packet.
204 * RETURNS
205 * unsigned - Length of SCoP packet
206 *---------------------------------------------------------------
208 static unsigned
209 get_scop_length(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_)
211 /* Byte 0: Protocol Type.
212 * Byte 1: Protocol Version.
213 * Bytes 2-3: Packet Length (network order).
215 return tvb_get_ntohs(tvb, offset + SCOP_LENGTH_OFFSET);
216 } /* get_scop_length */
218 /*FUNCTION:------------------------------------------------------
219 * NAME
220 * dissect_scop_tcp
221 * DESCRIPTION
222 * ZigBee SCoP packet dissection routine for Wireshark.
223 * for use with TCP ports.
224 * PARAMETERS
225 * tvbuff_t *tvb - pointer to buffer containing raw packet.
226 * packet_info *pinfo - pointer to packet information fields
227 * proto_tree *tree - pointer to data tree Wireshark uses to display packet.
228 * RETURNS
229 * void
230 *---------------------------------------------------------------
232 static int
233 dissect_scop_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
235 tcp_dissect_pdus(tvb, pinfo, tree, true, SCOP_HEADER_LENGTH, get_scop_length, dissect_scop, data);
236 return tvb_captured_length(tvb);
237 } /* dissect_scop_tcp */
240 /*FUNCTION:------------------------------------------------------
241 * NAME
242 * dissect_scop_zip
243 * DESCRIPTION
244 * Intermediate dissector for the SCoP service type.
245 * PARAMETERS
246 * tvbuff_t *tvb - pointer to buffer containing raw packet.
247 * packet_info *pinfo - pointer to packet information fields
248 * proto_tree *tree - pointer to data tree Wireshark uses to display packet.
249 * RETURNS
250 * void
251 *---------------------------------------------------------------
253 static void
254 dissect_scop_zip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
256 unsigned offset = 0;
257 uint8_t type = tvb_get_uint8(tvb, offset);
258 uint16_t status;
260 /* Display the Packet type*/
261 proto_tree_add_uint(tree, hf_scop_type, tvb, offset, 1, type);
262 proto_item_append_text(tree, ", %s", val_to_str_const(type, scop_types, "Reserved Type"));
263 col_set_str(pinfo->cinfo, COL_INFO, val_to_str_const(type, scop_types, "Reserved Type"));
264 offset += 2;
266 if (type == SCOP_CMD_HELLO_RESP) {
267 status = tvb_get_ntohs(tvb, 1);
268 proto_tree_add_uint_format_value(tree, hf_scop_status, tvb, offset, 2, status, "%s", (status==0x0000)?"Success":"Failure");
269 offset += 2;
272 /* If there are any bytes left over, pass them to the data dissector. */
273 if (offset < tvb_reported_length(tvb)) {
274 tvbuff_t *payload_tvb = tvb_new_subset_remaining(tvb, offset);
275 proto_tree *root = proto_tree_get_root(tree);
276 call_data_dissector(payload_tvb, pinfo, root);
278 } /* dissect_scop_zip() */
280 /*FUNCTION:------------------------------------------------------
281 * NAME
282 * dissect_scop_bridge
283 * DESCRIPTION
284 * Intermediate dissector for the Bridge service type.
285 * PARAMETERS
286 * tvbuff_t *tvb - pointer to buffer containing raw packet.
287 * packet_info *pinfo - pointer to packet information fields
288 * proto_tree *tree - pointer to data tree Wireshark uses to display packet.
289 * RETURNS
290 * void
291 *---------------------------------------------------------------
293 static void
294 dissect_scop_bridge(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
296 call_dissector(ieee802154_handle, tvb, pinfo, proto_tree_get_root(tree));
297 } /* dissect_scop_bridge() */
299 /*FUNCTION:------------------------------------------------------
300 * NAME
301 * proto_register_scop
302 * DESCRIPTION
303 * SCoP protocol registration.
304 * PARAMETERS
305 * none
306 * RETURNS
307 * void
308 *---------------------------------------------------------------
310 void proto_register_scop(void)
312 static hf_register_info hf[] = {
313 { &hf_scop_transport,
314 { "Transport Type", "scop.transport", FT_UINT8, BASE_DEC, VALS(scop_transports), 0x0,
315 "The type of transport used.", HFILL }},
317 { &hf_scop_version,
318 { "Version", "scop.version", FT_UINT8, BASE_DEC, NULL, 0x0,
319 "The version of the sniffer.", HFILL }},
321 { &hf_scop_length,
322 { "Length", "scop.length", FT_UINT16, BASE_DEC, NULL, 0x0,
323 NULL, HFILL }},
325 { &hf_scop_service,
326 { "Service Identifier", "scop.service", FT_UINT8, BASE_DEC, VALS(scop_services), 0x0,
327 NULL, HFILL }},
329 { &hf_scop_type,
330 { "Packet Type", "scop.type", FT_UINT8, BASE_DEC, VALS(scop_types), 0x0,
331 "Service-specific packet type.", HFILL }},
333 { &hf_scop_status,
334 { "Status", "scop.status", FT_UINT16, BASE_HEX, NULL, 0x0,
335 "Status of the SCoP Command.", HFILL }}
338 static int *ett[] = {
339 &ett_scop
342 /* Register protocol name and description. */
343 proto_scop = proto_register_protocol("ZigBee SCoP", "SCoP", "scop");
345 /* Register header fields and subtrees. */
346 proto_register_field_array(proto_scop, hf, array_length(hf));
347 proto_register_subtree_array(ett, array_length(ett));
349 /* Register dissector with Wireshark. */
350 scop_udp_handle = register_dissector("scop.udp", dissect_scop, proto_scop);
351 scop_tcp_handle = register_dissector("scop.tcp", dissect_scop_tcp, proto_scop);
352 } /* proto_register_scop() */
354 /*FUNCTION:------------------------------------------------------
355 * NAME
356 * proto_reg_handoff_scop
357 * DESCRIPTION
358 * Registers the zigbee dissector with Wireshark.
359 * Will be called every time 'apply' is pressed in the preferences menu.
360 * PARAMETERS
361 * none
362 * RETURNS
363 * void
364 *---------------------------------------------------------------
366 void proto_reg_handoff_scop(void)
368 ieee802154_handle = find_dissector_add_dependency("wpan_nofcs", proto_scop);
370 dissector_add_uint_range_with_preference("udp.port", SCOP_DEFAULT_PORT_RANGE, scop_udp_handle);
371 dissector_add_uint_range_with_preference("tcp.port", SCOP_DEFAULT_PORT_RANGE, scop_tcp_handle);
375 * Editor modelines - https://www.wireshark.org/tools/modelines.html
377 * Local variables:
378 * c-basic-offset: 4
379 * tab-width: 8
380 * indent-tabs-mode: nil
381 * End:
383 * vi: set shiftwidth=4 tabstop=8 expandtab:
384 * :indentSize=4:tabSize=8:noTabs=true: