Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-hsms.c
blob50f844c8bec47cea03b52affd21ff668e41bf16b
1 /* packet-hsms.c
2 * Routines for High-speed SECS message service dissection
3 * Copyright 2016, Benjamin Parzella <bparzella@gmail.com>
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
13 * HSMS - High-speed SECS message service (SEMI-E37)
14 * SECS - SEMI equipment communications standard (SEMI-E5)
16 * TCP based protocol for semiconductor factory automation
17 * defined by SEMI (http://www.semi.org)
19 * Usual TCP port: 5000
22 #include <config.h>
24 #include <epan/packet.h>
25 #include <epan/prefs.h>
26 #include "packet-tcp.h"
27 #include <epan/expert.h>
29 #define PTYPE_SECS 0
31 #define STYPE_SECS_DATA 0
32 #define STYPE_SELECT_REQ 1
33 #define STYPE_SELECT_RSP 2
34 #define STYPE_DESELECT_REQ 3
35 #define STYPE_DESELECT_RSP 4
36 #define STYPE_LINKTEST_REQ 5
37 #define STYPE_LINKTEST_RSP 6
38 #define STYPE_REJECT_REQ 7
39 #define STYPE_SEPARATE_REQ 9
41 #define FORMAT_CODE_LIST 000
42 #define FORMAT_CODE_BINARY 010
43 #define FORMAT_CODE_BOOLEAN 011
44 #define FORMAT_CODE_ASCII 020
45 #define FORMAT_CODE_JIS8 021
46 #define FORMAT_CODE_2BYTE 022
47 #define FORMAT_CODE_I8 030
48 #define FORMAT_CODE_I1 031
49 #define FORMAT_CODE_I2 032
50 #define FORMAT_CODE_I4 034
51 #define FORMAT_CODE_F8 040
52 #define FORMAT_CODE_F4 044
53 #define FORMAT_CODE_U8 050
54 #define FORMAT_CODE_U1 051
55 #define FORMAT_CODE_U2 052
56 #define FORMAT_CODE_U4 054
58 /* Prototypes */
59 void proto_reg_handoff_hsms(void);
60 void proto_register_hsms(void);
62 static dissector_handle_t hsms_handle;
64 /* Initialize the protocol and registered fields */
65 static int proto_hsms;
67 static int hf_hsms_packet_length;
68 static int hf_hsms_header_sessionid;
69 static int hf_hsms_header_statusbyte2;
70 static int hf_hsms_header_wbit;
71 static int hf_hsms_header_stream;
72 static int hf_hsms_header_statusbyte3;
73 static int hf_hsms_header_function;
74 static int hf_hsms_header_ptype;
75 static int hf_hsms_header_stype;
76 static int hf_hsms_header_system;
77 static int hf_hsms_data_item_format;
78 static int hf_hsms_data_item_length_bytes;
79 static int hf_hsms_data_item_length;
80 static int hf_hsms_data_item_value_binary;
81 static int hf_hsms_data_item_value_boolean;
82 static int hf_hsms_data_item_value_string;
83 static int hf_hsms_data_item_value_i8;
84 static int hf_hsms_data_item_value_i1;
85 static int hf_hsms_data_item_value_i2;
86 static int hf_hsms_data_item_value_i4;
87 static int hf_hsms_data_item_value_f8;
88 static int hf_hsms_data_item_value_f4;
89 static int hf_hsms_data_item_value_u8;
90 static int hf_hsms_data_item_value_u1;
91 static int hf_hsms_data_item_value_u2;
92 static int hf_hsms_data_item_value_u4;
94 static expert_field ei_hsms_ptype;
96 static wmem_map_t *value_lengths;
99 * Presentation type (ptype)
101 * 0 => SECS-II Encoding
102 * 1-127 => Reserved for subsidiary standards
103 * 128-255 => Reserved, not used
105 static const value_string ptype_names[] = {
106 { PTYPE_SECS, "SECS" },
107 { 0, NULL }
111 * Session type (stype)
113 * 0 => SECS-II data message
114 * 1 => Select request
115 * 2 => Select response
116 * 3 => Deselect request
117 * 4 => Deselect response
118 * 5 => Link test request
119 * 6 => Link test response
120 * 7 => Packet reject request
121 * 8 => Reserved, not used
122 * 9 => Separate request
123 * 10 => Reserved, not used
124 * 11-127 => Reserved for subsidiary standards
125 * 128-255 => Reserved, not used
127 static const value_string stype_names[] = {
128 { STYPE_SECS_DATA, "Data message" },
129 { STYPE_SELECT_REQ, "Select.req" },
130 { STYPE_SELECT_RSP, "Select.rsp" },
131 { STYPE_DESELECT_REQ, "Deselect.req" },
132 { STYPE_DESELECT_RSP, "Deselect.rsp" },
133 { STYPE_LINKTEST_REQ, "Linktest.req" },
134 { STYPE_LINKTEST_RSP, "Linktest.rsp" },
135 { STYPE_REJECT_REQ, "Reject.req" },
136 { STYPE_SEPARATE_REQ, "Separate.req" },
137 { 0, NULL }
140 static const value_string item_format_names[] = {
141 { FORMAT_CODE_LIST, "List" },
142 { FORMAT_CODE_BINARY, "Binary" },
143 { FORMAT_CODE_BOOLEAN, "Boolean" },
144 { FORMAT_CODE_ASCII, "ASCII" },
145 { FORMAT_CODE_JIS8, "JIS-8" },
146 { FORMAT_CODE_2BYTE, "2-Byte Char" },
147 { FORMAT_CODE_I8, "I8" },
148 { FORMAT_CODE_I1, "I1" },
149 { FORMAT_CODE_I2, "I2" },
150 { FORMAT_CODE_I4, "I4" },
151 { FORMAT_CODE_F8, "F8" },
152 { FORMAT_CODE_F4, "F4" },
153 { FORMAT_CODE_U8, "U8" },
154 { FORMAT_CODE_U1, "U1" },
155 { FORMAT_CODE_U2, "U2" },
156 { FORMAT_CODE_U4, "U4" },
157 { 0, NULL }
160 /* Global sample port preference - real port preferences should generally
161 * default to 0 unless there is an IANA-registered (or equivalent) port for your
162 * protocol. */
163 #define HSMS_TCP_PORT 0
165 /* Initialize the subtree pointers */
166 static int ett_hsms;
167 static int ett_hsms_header;
168 static int ett_hsms_data;
169 static int ett_hsms_data_item;
171 /* A sample #define of the minimum length (in bytes) of the protocol data.
172 * If data is received with fewer than this many bytes it is rejected by
173 * the current dissector. */
174 #define HSMS_MIN_LENGTH 14
176 static int
177 // NOLINTNEXTLINE(misc-no-recursion)
178 dissect_secs_variable(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data, int *offset)
180 proto_item *hdr_stream_item;
181 proto_tree *hsms_data_item_tree, *hsms_data_item_header_tree;
183 proto_item *hdr_item = NULL;
185 unsigned item_format_code = -1;
186 unsigned length_bytes = -1;
187 unsigned length = 0;
189 unsigned *value_length = NULL;
191 int len = 0;
192 int itemLength = 0;
194 /* extract item format code and number of length bytes from byte #1 */
195 item_format_code = (tvb_get_uint8(tvb, *offset) & 0xFC) >> 2;
196 length_bytes = (tvb_get_uint8(tvb, *offset) & 0x3);
198 /* extract item length in bytes */
199 switch (length_bytes)
201 case 3:
202 length = tvb_get_ntoh24(tvb, *offset + 1);
203 break;
204 case 2:
205 length = tvb_get_ntohs(tvb, *offset + 1);
206 break;
207 case 1:
208 length = tvb_get_uint8(tvb, *offset + 1);
209 break;
210 default:
211 return -1;
214 /* list has no item length and length is alreaty the count of items */
215 if (item_format_code != 0)
217 value_length = (unsigned*)wmem_map_lookup(value_lengths, GUINT_TO_POINTER(item_format_code));
219 /* length must be dividable by item length, because it must be a multiple of items */
220 if (length % GPOINTER_TO_UINT(value_length) != 0)
221 return -1;
223 /* shorten length to actual count of items */
224 length = length / GPOINTER_TO_UINT(value_length);
227 /* add the item tree to the parent tree */
228 hsms_data_item_tree = proto_tree_add_subtree_format(tree, tvb, *offset, -1, ett_hsms_data_item, &hdr_item, "%s (%d items)", val_to_str(item_format_code, item_format_names, "Unknown (%02o)"), length);
230 /* add the formatcode/length bytes to the item tree */
231 hsms_data_item_header_tree = proto_tree_add_subtree_format(hsms_data_item_tree, tvb, *offset, 1, ett_hsms_header, &hdr_stream_item, "Data format: %s, Length bytes: %d", val_to_str(item_format_code, item_format_names, "Unknown (%02o)"), length_bytes);
232 proto_tree_add_item(hsms_data_item_header_tree, hf_hsms_data_item_format, tvb, *offset, 1, ENC_BIG_ENDIAN);
233 proto_tree_add_item(hsms_data_item_header_tree, hf_hsms_data_item_length_bytes, tvb, *offset, 1, ENC_BIG_ENDIAN);
234 *offset += 1;
236 /* add the length to the item tree */
237 len = length_bytes;
238 proto_tree_add_item(hsms_data_item_tree, hf_hsms_data_item_length, tvb, *offset, len, ENC_BIG_ENDIAN);
239 *offset += len;
241 /* add the actual item to the item tree */
242 switch(item_format_code)
244 case FORMAT_CODE_BINARY:
245 /* add binary value as one to item list */
246 value_length = (unsigned*)wmem_map_lookup(value_lengths, GUINT_TO_POINTER(item_format_code));
248 len = GPOINTER_TO_UINT(value_length) * length;
249 proto_tree_add_item(hsms_data_item_tree, hf_hsms_data_item_value_binary, tvb, *offset, len, ENC_NA);
250 itemLength = len;
251 *offset += len;
252 break;
253 case FORMAT_CODE_ASCII:
254 /* add ascii value as one to item list */
255 value_length = (unsigned*)wmem_map_lookup(value_lengths, GUINT_TO_POINTER(item_format_code));
257 len = GPOINTER_TO_UINT(value_length) * length;
258 proto_tree_add_item(hsms_data_item_tree, hf_hsms_data_item_value_string, tvb, *offset, len, ENC_ASCII);
259 itemLength = len;
260 *offset += len;
261 break;
262 default:
263 /* walk through the items */
264 for(unsigned int counter=0; counter<length; counter++)
266 if (item_format_code == 0)
268 /* add sub items for list element to item tree */
269 increment_dissection_depth(pinfo);
270 int subItemLength = dissect_secs_variable(tvb, pinfo, hsms_data_item_tree, data, offset);
271 decrement_dissection_depth(pinfo);
273 /* check for parsing error in sub list */
274 if (subItemLength == -1)
276 return -1;
279 itemLength += subItemLength;
281 else
283 /* add single item of type item tree */
284 value_length = (unsigned*)wmem_map_lookup(value_lengths, GUINT_TO_POINTER(item_format_code));
286 len = GPOINTER_TO_UINT(value_length);
287 switch(item_format_code)
289 case FORMAT_CODE_BOOLEAN:
290 proto_tree_add_item(hsms_data_item_tree, hf_hsms_data_item_value_boolean, tvb, *offset, len, ENC_BIG_ENDIAN);
291 break;
292 case FORMAT_CODE_I8:
293 proto_tree_add_item(hsms_data_item_tree, hf_hsms_data_item_value_i8, tvb, *offset, len, ENC_BIG_ENDIAN);
294 break;
295 case FORMAT_CODE_I1:
296 proto_tree_add_item(hsms_data_item_tree, hf_hsms_data_item_value_i1, tvb, *offset, len, ENC_BIG_ENDIAN);
297 break;
298 case FORMAT_CODE_I2:
299 proto_tree_add_item(hsms_data_item_tree, hf_hsms_data_item_value_i2, tvb, *offset, len, ENC_BIG_ENDIAN);
300 break;
301 case FORMAT_CODE_I4:
302 proto_tree_add_item(hsms_data_item_tree, hf_hsms_data_item_value_i4, tvb, *offset, len, ENC_BIG_ENDIAN);
303 break;
304 case FORMAT_CODE_F8:
305 proto_tree_add_item(hsms_data_item_tree, hf_hsms_data_item_value_f8, tvb, *offset, len, ENC_BIG_ENDIAN);
306 break;
307 case FORMAT_CODE_F4:
308 proto_tree_add_item(hsms_data_item_tree, hf_hsms_data_item_value_f4, tvb, *offset, len, ENC_BIG_ENDIAN);
309 break;
310 case FORMAT_CODE_U8:
311 proto_tree_add_item(hsms_data_item_tree, hf_hsms_data_item_value_u8, tvb, *offset, len, ENC_BIG_ENDIAN);
312 break;
313 case FORMAT_CODE_U1:
314 proto_tree_add_item(hsms_data_item_tree, hf_hsms_data_item_value_u1, tvb, *offset, len, ENC_BIG_ENDIAN);
315 break;
316 case FORMAT_CODE_U2:
317 proto_tree_add_item(hsms_data_item_tree, hf_hsms_data_item_value_u2, tvb, *offset, len, ENC_BIG_ENDIAN);
318 break;
319 case FORMAT_CODE_U4:
320 proto_tree_add_item(hsms_data_item_tree, hf_hsms_data_item_value_u4, tvb, *offset, len, ENC_BIG_ENDIAN);
321 break;
322 default:
323 return -1;
325 itemLength += len;
326 *offset += len;
331 /* update length of item tree */
332 proto_item_set_len(hsms_data_item_tree, itemLength + length_bytes + 1);
334 return 1 + length_bytes + itemLength;
337 static int
338 dissect_secs_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data, int *offset)
340 return dissect_secs_variable(tvb, pinfo, tree, data, offset);
343 /* Code to actually dissect the hsms packets */
344 static int
345 dissect_hsms_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
347 proto_item *hdr_item = NULL;
349 /* Set up structures needed to add the protocol subtree and manage it */
350 proto_item *ti;
351 proto_tree *hsms_tree, *hsms_header_tree, *hsms_header_stream_tree;
353 /* Other misc. local variables. */
354 unsigned offset = 0;
356 unsigned sessionId = -1;
357 unsigned byte2 = -1;
358 unsigned byte3 = -1;
359 unsigned pType = -1;
360 unsigned sType = -1;
362 /*** HEURISTICS ***/
364 /* Check that the packet is long enough for it to belong to us. */
365 if (tvb_reported_length(tvb) < HSMS_MIN_LENGTH)
366 return 0;
368 /* Check if first byte describes length) */
369 if ((tvb_get_ntohl(tvb, 0) + 4) != tvb_reported_length(tvb))
370 return 0;
372 sessionId = tvb_get_ntohs(tvb, 4);
373 byte2 = tvb_get_uint8(tvb, 6);
374 byte3 = tvb_get_uint8(tvb, 7);
375 pType = tvb_get_uint8(tvb, 8);
376 sType = tvb_get_uint8(tvb, 9);
378 /* sTypes 8, 10 and 128+ are unused, 11-127 might be used for subsidiary standards */
379 if ((sType == 8) || (sType == 10) || (sType > 127))
380 return 0;
382 /* see definition of stype_names for details on the sType values */
383 switch (sType)
385 case STYPE_SECS_DATA:
386 if (byte2 == 0) // stream must be set
387 return 0;
388 break;
389 case STYPE_SELECT_REQ:
390 case STYPE_DESELECT_REQ:
391 case STYPE_SEPARATE_REQ:
392 if ((byte2 != 0) || (byte3 != 0)) // byte2&3 must be zero
393 return 0;
394 if (tvb_reported_length(tvb) > HSMS_MIN_LENGTH) // no data for sType != 0
395 return 0;
396 break;
397 case STYPE_SELECT_RSP:
398 case STYPE_DESELECT_RSP:
399 if (byte2 != 0) // byte2 must be zero
400 return 0;
401 if (tvb_reported_length(tvb) > HSMS_MIN_LENGTH) // no data for sType != 0
402 return 0;
403 break;
404 case STYPE_LINKTEST_REQ:
405 case STYPE_LINKTEST_RSP:
406 if (sessionId != 0xFFFF) // Session ID must be max
407 return 0;
408 if (byte2 != 0) // byte2 must be zero
409 return 0;
410 if (byte3 != 0) // byte3 must be zero
411 return 0;
412 if (tvb_reported_length(tvb) > HSMS_MIN_LENGTH) // no data for sType != 0
413 return 0;
414 break;
415 case STYPE_REJECT_REQ:
416 if (tvb_reported_length(tvb) > HSMS_MIN_LENGTH) // no data for sType != 0
417 return 0;
418 break;
421 /*** COLUMN DATA ***/
423 col_set_str(pinfo->cinfo, COL_PROTOCOL, "HSMS");
425 /* Clear out stuff in the info column */
426 col_clear(pinfo->cinfo,COL_INFO);
428 if (sType == STYPE_SECS_DATA)
430 col_add_fstr(pinfo->cinfo, COL_INFO, "HSMS SECS Stream/Function S%02dF%02d",
431 byte2 & 0x7F, byte3);
433 else
435 col_add_fstr(pinfo->cinfo, COL_INFO, "HSMS Message %s",
436 val_to_str(sType, stype_names, "Unknown (%02d)"));
440 /*** PROTOCOL TREE ***/
442 /* create display subtree for the protocol */
443 ti = proto_tree_add_item(tree, proto_hsms, tvb, 0, -1, ENC_NA);
445 hsms_tree = proto_item_add_subtree(ti, ett_hsms);
447 /* packet size = 4 bytes */
448 proto_tree_add_item(hsms_tree, hf_hsms_packet_length, tvb, offset, 4, ENC_BIG_ENDIAN);
449 offset += 4;
451 /* header = 10 bytes */
453 /* see definition of stype_names for details on the sType values */
454 switch (sType)
456 case STYPE_SECS_DATA:
457 hsms_header_tree = proto_tree_add_subtree_format(hsms_tree, tvb, offset, 10, ett_hsms_header, &hdr_item, "Header (S%02dF%02d)", byte2 & 0x7F, byte3);
458 break;
459 default:
460 hsms_header_tree = proto_tree_add_subtree_format(hsms_tree, tvb, offset, 10, ett_hsms_header, &hdr_item, "Header (%s)", val_to_str(sType, stype_names, "Unknown (%02d)"));
461 break;
464 /* session id = 2 bytes */
465 proto_tree_add_item(hsms_header_tree, hf_hsms_header_sessionid, tvb, offset, 2, ENC_BIG_ENDIAN);
466 offset += 2;
468 /* see definition of stype_names for details on the sType values */
469 switch (sType)
471 case STYPE_SECS_DATA:
472 /* wbit=1bit + stream=7bits = 1 byte */
473 hsms_header_stream_tree = proto_tree_add_subtree_format(hsms_header_tree, tvb, offset, 1, ett_hsms_header, &hdr_item, "Stream %d, Response requested: %s", byte2 & 0x7F, ((byte2 & 0x80) > 0) ? "Yes" : "No");
474 proto_tree_add_item(hsms_header_stream_tree, hf_hsms_header_wbit, tvb, offset, 1, ENC_BIG_ENDIAN);
475 proto_tree_add_item(hsms_header_stream_tree, hf_hsms_header_stream, tvb, offset, 1, ENC_BIG_ENDIAN);
476 offset += 1;
478 /* function = 1 byte */
479 proto_tree_add_item(hsms_header_tree, hf_hsms_header_function, tvb, offset, 1, ENC_BIG_ENDIAN);
480 offset += 1;
481 break;
482 default:
483 /* status byte 2 = 1 byte */
484 proto_tree_add_item(hsms_header_tree, hf_hsms_header_statusbyte2, tvb, offset, 1, ENC_BIG_ENDIAN);
485 offset += 1;
486 /* status byte 3 = 1 byte */
487 proto_tree_add_item(hsms_header_tree, hf_hsms_header_statusbyte3, tvb, offset, 1, ENC_BIG_ENDIAN);
488 offset += 1;
489 break;
492 /* ptype = 1 byte */
493 ti = proto_tree_add_item(hsms_header_tree, hf_hsms_header_ptype, tvb, offset, 1, ENC_BIG_ENDIAN);
494 offset += 1;
496 if (pType != 0)
497 expert_add_info(pinfo, ti, &ei_hsms_ptype);
499 /* stype = 1 byte */
500 proto_tree_add_item(hsms_header_tree, hf_hsms_header_stype, tvb, offset, 1, ENC_BIG_ENDIAN);
501 offset += 1;
503 /* system = 4 bytes */
504 proto_tree_add_item(hsms_header_tree, hf_hsms_header_system, tvb, offset, 4, ENC_BIG_ENDIAN);
505 offset += 4;
507 /* decode secs data if available */
508 if (tvb_reported_length(tvb) > HSMS_MIN_LENGTH)
510 if (pType == PTYPE_SECS)
511 dissect_secs_message(tvb, pinfo, hsms_tree, data, &offset);
513 return offset;
516 /* determine PDU length of protocol foo */
517 static unsigned
518 get_hsms_message_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_)
520 /* first four bytes are length information */
521 return (unsigned)tvb_get_ntohl(tvb, offset) + 4;
524 /* The main dissecting routine */
525 static int
526 dissect_hsms(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
528 tcp_dissect_pdus(tvb, pinfo, tree, true, 4,
529 get_hsms_message_len, dissect_hsms_message, data);
530 return tvb_captured_length(tvb);
533 static void
534 hsms_init(void)
536 value_lengths = wmem_map_new(wmem_epan_scope(), g_direct_hash, g_direct_equal);
538 wmem_map_insert(value_lengths, GINT_TO_POINTER(FORMAT_CODE_LIST), GINT_TO_POINTER(0));
539 wmem_map_insert(value_lengths, GINT_TO_POINTER(FORMAT_CODE_BINARY), GINT_TO_POINTER(1));
540 wmem_map_insert(value_lengths, GINT_TO_POINTER(FORMAT_CODE_BOOLEAN), GINT_TO_POINTER(1));
541 wmem_map_insert(value_lengths, GINT_TO_POINTER(FORMAT_CODE_ASCII), GINT_TO_POINTER(1));
542 wmem_map_insert(value_lengths, GINT_TO_POINTER(FORMAT_CODE_JIS8), GINT_TO_POINTER(2));
543 wmem_map_insert(value_lengths, GINT_TO_POINTER(FORMAT_CODE_2BYTE), GINT_TO_POINTER(2));
544 wmem_map_insert(value_lengths, GINT_TO_POINTER(FORMAT_CODE_I8), GINT_TO_POINTER(8));
545 wmem_map_insert(value_lengths, GINT_TO_POINTER(FORMAT_CODE_I1), GINT_TO_POINTER(1));
546 wmem_map_insert(value_lengths, GINT_TO_POINTER(FORMAT_CODE_I2), GINT_TO_POINTER(2));
547 wmem_map_insert(value_lengths, GINT_TO_POINTER(FORMAT_CODE_I4), GINT_TO_POINTER(4));
548 wmem_map_insert(value_lengths, GINT_TO_POINTER(FORMAT_CODE_F8), GINT_TO_POINTER(8));
549 wmem_map_insert(value_lengths, GINT_TO_POINTER(FORMAT_CODE_F4), GINT_TO_POINTER(4));
550 wmem_map_insert(value_lengths, GINT_TO_POINTER(FORMAT_CODE_U8), GINT_TO_POINTER(8));
551 wmem_map_insert(value_lengths, GINT_TO_POINTER(FORMAT_CODE_U1), GINT_TO_POINTER(1));
552 wmem_map_insert(value_lengths, GINT_TO_POINTER(FORMAT_CODE_U2), GINT_TO_POINTER(2));
553 wmem_map_insert(value_lengths, GINT_TO_POINTER(FORMAT_CODE_U4), GINT_TO_POINTER(4));
556 void
557 proto_register_hsms(void)
559 expert_module_t* expert_hsms;
561 static hf_register_info hf[] = {
562 { &hf_hsms_packet_length,
563 { "Packet length", "hsms.length",
564 FT_UINT32, BASE_DEC,
565 NULL, 0x0,
566 NULL, HFILL }
568 { &hf_hsms_header_sessionid,
569 { "Session ID", "hsms.header.sessionid",
570 FT_UINT16, BASE_DEC,
571 NULL, 0x0,
572 NULL, HFILL }
574 { &hf_hsms_header_statusbyte2,
575 { "Status byte 2", "hsms.header.statusbyte2",
576 FT_UINT8, BASE_DEC,
577 NULL, 0x0,
578 NULL, HFILL }
580 { &hf_hsms_header_wbit,
581 { "W-bit (Response required)", "hsms.header.wbit",
582 FT_BOOLEAN, 8,
583 NULL, 0x80,
584 NULL, HFILL }
586 { &hf_hsms_header_stream,
587 { "Stream", "hsms.header.stream",
588 FT_UINT8, BASE_DEC,
589 NULL, 0x7F,
590 NULL, HFILL }
592 { &hf_hsms_header_statusbyte3,
593 { "Status byte 3", "hsms.header.statusbyte3",
594 FT_UINT8, BASE_DEC,
595 NULL, 0x0,
596 NULL, HFILL }
598 { &hf_hsms_header_function,
599 { "Function", "hsms.header.function",
600 FT_UINT8, BASE_DEC,
601 NULL, 0x0,
602 NULL, HFILL }
604 { &hf_hsms_header_ptype,
605 { "PType (Presentation type)", "hsms.header.ptype",
606 FT_UINT8, BASE_DEC,
607 VALS(ptype_names), 0x0,
608 NULL, HFILL }
610 { &hf_hsms_header_stype,
611 { "SType (Session type)", "hsms.header.stype",
612 FT_UINT8, BASE_DEC,
613 VALS(stype_names), 0x0,
614 NULL, HFILL }
616 { &hf_hsms_header_system,
617 { "System Bytes", "hsms.header.system",
618 FT_UINT32, BASE_DEC,
619 NULL, 0x0,
620 NULL, HFILL }
622 { &hf_hsms_data_item_format,
623 { "Data type", "hsms.data.item.format",
624 FT_UINT8, BASE_OCT,
625 VALS(item_format_names), 0xFC,
626 NULL, HFILL }
628 { &hf_hsms_data_item_length_bytes,
629 { "Length bytes", "hsms.data.item.length_bytes",
630 FT_UINT8, BASE_OCT,
631 NULL, 0x03,
632 NULL, HFILL }
634 { &hf_hsms_data_item_length,
635 { "Length", "hsms.data.item.length",
636 FT_UINT32, BASE_DEC,
637 NULL, 0x00,
638 NULL, HFILL }
640 { &hf_hsms_data_item_value_binary,
641 { "Value", "hsms.data.item.value.binary",
642 FT_BYTES, SEP_COLON,
643 NULL, 0x00,
644 NULL, HFILL }
646 { &hf_hsms_data_item_value_boolean,
647 { "Value", "hsms.data.item.value.boolean",
648 FT_BOOLEAN, 8,
649 NULL, 0x01,
650 NULL, HFILL }
652 { &hf_hsms_data_item_value_string,
653 { "Value", "hsms.data.item.value.string",
654 FT_STRING, BASE_NONE,
655 NULL, 0x00,
656 NULL, HFILL }
658 { &hf_hsms_data_item_value_i8,
659 { "Value", "hsms.data.item.value.int64",
660 FT_INT64, BASE_DEC,
661 NULL, 0x00,
662 NULL, HFILL }
664 { &hf_hsms_data_item_value_i1,
665 { "Value", "hsms.data.item.value.int8",
666 FT_INT8, BASE_DEC,
667 NULL, 0x00,
668 NULL, HFILL }
670 { &hf_hsms_data_item_value_i2,
671 { "Value", "hsms.data.item.value.int16",
672 FT_INT16, BASE_DEC,
673 NULL, 0x00,
674 NULL, HFILL }
676 { &hf_hsms_data_item_value_i4,
677 { "Value", "hsms.data.item.value.int32",
678 FT_INT32, BASE_DEC,
679 NULL, 0x00,
680 NULL, HFILL }
682 { &hf_hsms_data_item_value_f8,
683 { "Value", "hsms.data.item.value.double",
684 FT_DOUBLE, BASE_NONE,
685 NULL, 0x00,
686 NULL, HFILL }
688 { &hf_hsms_data_item_value_f4,
689 { "Value", "hsms.data.item.value.float",
690 FT_FLOAT, BASE_NONE,
691 NULL, 0x00,
692 NULL, HFILL }
694 { &hf_hsms_data_item_value_u8,
695 { "Value", "hsms.data.item.value.uint64",
696 FT_UINT64, BASE_DEC,
697 NULL, 0x00,
698 NULL, HFILL }
700 { &hf_hsms_data_item_value_u1,
701 { "Value", "hsms.data.item.value.uint8",
702 FT_UINT8, BASE_DEC,
703 NULL, 0x00,
704 NULL, HFILL }
706 { &hf_hsms_data_item_value_u2,
707 { "Value", "hsms.data.item.value.uint16",
708 FT_UINT16, BASE_DEC,
709 NULL, 0x00,
710 NULL, HFILL }
712 { &hf_hsms_data_item_value_u4,
713 { "Value", "hsms.data.item.value.uint32",
714 FT_UINT32, BASE_DEC,
715 NULL, 0x00,
716 NULL, HFILL }
720 /* Setup protocol subtree array */
721 static int *ett[] = {
722 &ett_hsms,
723 &ett_hsms_header,
724 &ett_hsms_data,
725 &ett_hsms_data_item
728 static ei_register_info ei[] = {
729 { &ei_hsms_ptype,
730 { "hsms.header.ptype.unknown",
731 PI_RESPONSE_CODE,
732 PI_NOTE,
733 "Unknown presentation type (ptype)",
734 EXPFILL }
738 /* Register the protocol name and description */
739 proto_hsms = proto_register_protocol ("High-speed SECS Message Service Protocol", "HSMS", "hsms");
741 /* Required function calls to register the header fields and subtrees */
742 proto_register_field_array(proto_hsms, hf, array_length(hf));
743 proto_register_subtree_array(ett, array_length(ett));
745 expert_hsms = expert_register_protocol(proto_hsms);
746 expert_register_field_array(expert_hsms, ei, array_length(ei));
748 hsms_handle = register_dissector("hsms", dissect_hsms, proto_hsms);
750 hsms_init();
753 void
754 proto_reg_handoff_hsms(void)
756 dissector_add_for_decode_as_with_preference("tcp.port", hsms_handle);
760 * Editor modelines - https://www.wireshark.org/tools/modelines.html
762 * Local variables:
763 * c-basic-offset: 4
764 * tab-width: 8
765 * indent-tabs-mode: nil
766 * End:
768 * vi: set shiftwidth=4 tabstop=8 expandtab:
769 * :indentSize=4:tabSize=8:noTabs=true: