Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-tfp.c
blob47c283249daefd1ef77d4b8c9714644bd118861b
1 /* packet-tfp.c
2 * Routines for Tinkerforge protocol packet disassembly
3 * By Ishraq Ibne Ashraf <ishraq@tinkerforge.com>
4 * Copyright 2013 Ishraq Ibne Ashraf
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * SPDX-License-Identifier: GPL-2.0-or-later
13 #include "config.h"
15 #include <epan/packet.h>
16 #include "packet-usb.h"
18 /* defines */
19 #define tfp_PORT 4223 /* Not IANA registered */
21 #define tfp_USB_VENDOR_ID 0x16D0
22 #define tfp_USB_PRODUCT_ID 0x063D
24 #define BASE58_MAX_STR_SIZE 13
26 void proto_reg_handoff_tfp(void);
27 void proto_register_tfp(void);
29 static dissector_handle_t tfp_handle_tcp;
31 /* variables for creating the tree */
32 static int proto_tfp;
33 static int ett_tfp;
35 /* header field variables */
36 static int hf_tfp_uid;
37 static int hf_tfp_uid_numeric;
38 static int hf_tfp_len;
39 static int hf_tfp_fid;
40 static int hf_tfp_seq;
41 static int hf_tfp_r;
42 static int hf_tfp_a;
43 static int hf_tfp_oo;
44 static int hf_tfp_e;
45 static int hf_tfp_future_use;
46 static int hf_tfp_payload;
48 /* bit and byte offsets for dissection */
49 static const int byte_offset_len = 4;
50 static const int byte_offset_fid = 5;
51 static const int byte_count_tfp_uid = 4;
52 static const int byte_count_tfp_len = 1;
53 static const int byte_count_tfp_fid = 1;
54 static const int byte_count_tfp_flags = 2;
55 static const int bit_count_tfp_seq = 4;
56 static const int bit_count_tfp_r = 1;
57 static const int bit_count_tfp_a = 1;
58 static const int bit_count_tfp_oo = 2;
59 static const int bit_count_tfp_e = 2;
60 static const int bit_count_tfp_future_use = 6;
62 /* base58 encoding variable */
63 static const char BASE58_ALPHABET[] =
64 "123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ";
66 /* function for encoding a number to base58 string */
67 static void
68 base58_encode(uint32_t value, char *str) {
70 uint32_t mod;
71 int i = 0;
72 int k;
73 char reverse_str[BASE58_MAX_STR_SIZE] = {'\0'};
75 while (value >= 58) {
76 mod = value % 58;
77 reverse_str[i] = BASE58_ALPHABET[mod];
78 value = value / 58;
79 ++i;
82 reverse_str[i] = BASE58_ALPHABET[value];
84 for (k = 0; k <= i; k++) {
85 str[k] = reverse_str[i - k];
88 for (; k < BASE58_MAX_STR_SIZE; k++) {
89 str[k] = '\0';
93 /* common dissector function for dissecting TFP payloads */
94 static void
95 dissect_tfp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
97 int byte_offset = 0;
98 int bit_offset = 48;
100 uint8_t hv_tfp_len;
101 uint8_t hv_tfp_fid;
102 uint8_t hv_tfp_seq;
104 char tfp_uid_string[BASE58_MAX_STR_SIZE];
106 base58_encode(tvb_get_letohl(tvb, 0), &tfp_uid_string[0]);
108 hv_tfp_len = tvb_get_uint8(tvb, byte_offset_len);
109 hv_tfp_fid = tvb_get_uint8(tvb, byte_offset_fid);
110 hv_tfp_seq = tvb_get_bits8(tvb, bit_offset, bit_count_tfp_seq);
112 col_add_fstr(pinfo->cinfo, COL_INFO,
113 "UID: %s, Len: %d, FID: %d, Seq: %d",
114 &tfp_uid_string[0], hv_tfp_len, hv_tfp_fid, hv_tfp_seq);
116 /* call for details */
117 if (tree) {
118 proto_tree *tfp_tree;
119 proto_item *ti;
121 ti = proto_tree_add_protocol_format(tree, proto_tfp, tvb, 0, -1,
122 "Tinkerforge Protocol, UID: %s, Len: %d, FID: %d, Seq: %d",
123 &tfp_uid_string[0], hv_tfp_len, hv_tfp_fid, hv_tfp_seq);
124 tfp_tree = proto_item_add_subtree(ti, ett_tfp);
126 /* Use ...string_format_value() so we can show the complete generated string but specify */
127 /* the field length as being just the 4 bytes from which the string is generated. */
128 ti = proto_tree_add_string_format_value(tfp_tree,
129 hf_tfp_uid,
130 tvb, byte_offset, byte_count_tfp_uid,
131 &tfp_uid_string[0], "%s", &tfp_uid_string[0]);
132 proto_item_set_generated(ti);
134 proto_tree_add_item(tfp_tree,
135 hf_tfp_uid_numeric,
136 tvb,
137 byte_offset,
138 byte_count_tfp_uid,
139 ENC_LITTLE_ENDIAN);
141 byte_offset += byte_count_tfp_uid;
143 proto_tree_add_item(tfp_tree,
144 hf_tfp_len,
145 tvb,
146 byte_offset,
147 byte_count_tfp_len,
148 ENC_LITTLE_ENDIAN);
150 byte_offset += byte_count_tfp_len;
152 proto_tree_add_item(tfp_tree,
153 hf_tfp_fid,
154 tvb,
155 byte_offset,
156 byte_count_tfp_fid,
157 ENC_LITTLE_ENDIAN);
159 byte_offset += byte_count_tfp_fid;
161 proto_tree_add_bits_item(tfp_tree,
162 hf_tfp_seq,
163 tvb,
164 bit_offset,
165 bit_count_tfp_seq,
166 ENC_LITTLE_ENDIAN);
168 bit_offset += bit_count_tfp_seq;
170 proto_tree_add_bits_item(tfp_tree,
171 hf_tfp_r,
172 tvb,
173 bit_offset,
174 bit_count_tfp_r,
175 ENC_LITTLE_ENDIAN);
177 bit_offset += bit_count_tfp_r;
179 proto_tree_add_bits_item(tfp_tree,
180 hf_tfp_a,
181 tvb,
182 bit_offset,
183 bit_count_tfp_a,
184 ENC_LITTLE_ENDIAN);
186 bit_offset += bit_count_tfp_a;
188 proto_tree_add_bits_item(tfp_tree,
189 hf_tfp_oo,
190 tvb,
191 bit_offset,
192 bit_count_tfp_oo,
193 ENC_LITTLE_ENDIAN);
195 bit_offset += bit_count_tfp_oo;
197 proto_tree_add_bits_item(tfp_tree,
198 hf_tfp_e,
199 tvb,
200 bit_offset,
201 bit_count_tfp_e,
202 ENC_LITTLE_ENDIAN);
204 bit_offset += bit_count_tfp_e;
206 proto_tree_add_bits_item(tfp_tree,
207 hf_tfp_future_use,
208 tvb,
209 bit_offset,
210 bit_count_tfp_future_use,
211 ENC_LITTLE_ENDIAN);
213 /*bit_offset += bit_count_tfp_future_use;*/
215 if ((tvb_reported_length(tvb)) > 8) {
217 byte_offset += byte_count_tfp_flags;
219 proto_tree_add_item(tfp_tree, hf_tfp_payload, tvb, byte_offset, -1, ENC_NA);
224 /* dissector function for dissecting TCP payloads */
225 static int
226 dissect_tfp_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
228 col_set_str(pinfo->cinfo, COL_PROTOCOL, "TFP over TCP");
229 col_clear(pinfo->cinfo, COL_INFO);
231 dissect_tfp_common(tvb, pinfo, tree);
232 return tvb_captured_length(tvb);
235 /* dissector function for dissecting USB payloads */
236 static bool
237 dissect_tfp_bulk_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
239 urb_info_t *urb = (urb_info_t *)data;
241 if ((urb != NULL) && (urb->conv != NULL) &&
242 (urb->conv->deviceVendor == tfp_USB_VENDOR_ID) &&
243 (urb->conv->deviceProduct == tfp_USB_PRODUCT_ID)) {
244 col_set_str(pinfo->cinfo, COL_PROTOCOL, "TFP over USB");
245 col_clear(pinfo->cinfo, COL_INFO);
246 dissect_tfp_common(tvb, pinfo, tree);
247 return true;
250 return false;
253 /* protocol register function */
254 void
255 proto_register_tfp(void)
257 /* defining header formats */
258 static hf_register_info hf_tfp[] = {
259 { &hf_tfp_uid,
260 { "UID (String)",
261 "tfp.uid",
262 FT_STRINGZ,
263 BASE_NONE,
264 NULL,
265 0x0,
266 NULL,
267 HFILL
270 { &hf_tfp_uid_numeric,
271 { "UID (Numeric)",
272 "tfp.uid_numeric",
273 FT_UINT32,
274 BASE_DEC,
275 NULL,
276 0x0,
277 NULL,
278 HFILL
281 { &hf_tfp_len,
282 { "Length",
283 "tfp.len",
284 FT_UINT8,
285 BASE_DEC,
286 NULL,
287 0x0,
288 NULL,
289 HFILL
292 { &hf_tfp_fid,
293 { "Function ID",
294 "tfp.fid",
295 FT_UINT8,
296 BASE_DEC,
297 NULL,
298 0x0,
299 NULL,
300 HFILL
303 { &hf_tfp_seq,
304 { "Sequence Number",
305 "tfp.seq",
306 FT_UINT8,
307 BASE_DEC,
308 NULL,
309 0x0,
310 NULL,
311 HFILL
314 { &hf_tfp_r,
315 { "Response Expected",
316 "tfp.r",
317 FT_UINT8,
318 BASE_DEC,
319 NULL,
320 0x0,
321 NULL,
322 HFILL
325 { &hf_tfp_a,
326 { "Authentication",
327 "tfp.a",
328 FT_UINT8,
329 BASE_DEC,
330 NULL,
331 0x0,
332 NULL,
333 HFILL
336 { &hf_tfp_oo,
337 { "Other Options",
338 "tfp.oo",
339 FT_UINT8,
340 BASE_DEC,
341 NULL,
342 0x0,
343 NULL,
344 HFILL
347 { &hf_tfp_e,
348 { "Error Code",
349 "tfp.e",
350 FT_UINT8,
351 BASE_DEC,
352 NULL,
353 0x0,
354 NULL,
355 HFILL
358 { &hf_tfp_future_use,
359 { "Future Use",
360 "tfp.future_use",
361 FT_UINT8,
362 BASE_DEC,
363 NULL,
364 0x0,
365 NULL,
366 HFILL
369 { &hf_tfp_payload,
370 { "Payload",
371 "tfp.payload",
372 FT_BYTES,
373 BASE_NONE,
374 NULL,
375 0x0,
376 NULL,
377 HFILL
382 /* setup protocol subtree array */
383 static int *ett[] = {
384 &ett_tfp
387 /* defining the protocol and its names */
388 proto_tfp = proto_register_protocol (
389 "Tinkerforge Protocol",
390 "TFP",
391 "tfp"
394 proto_register_field_array(proto_tfp, hf_tfp, array_length(hf_tfp));
395 proto_register_subtree_array(ett, array_length(ett));
396 tfp_handle_tcp = register_dissector("tfp", dissect_tfp_tcp, proto_tfp);
399 /* handoff function */
400 void
401 proto_reg_handoff_tfp(void) {
403 dissector_add_uint_with_preference("tcp.port", tfp_PORT, tfp_handle_tcp);
404 heur_dissector_add("usb.bulk", dissect_tfp_bulk_heur, "Tinkerforge USB bulk endpoint", "tfp_usb_bulk", proto_tfp, HEURISTIC_ENABLE);
408 * Editor modelines - https://www.wireshark.org/tools/modelines.html
410 * Local variables:
411 * c-basic-offset: 8
412 * tab-width: 8
413 * indent-tabs-mode: t
414 * End:
416 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
417 * :indentSize=8:tabSize=8:noTabs=false: