epan/dissectors/pidl/ C99 drsuapi
[wireshark-sm.git] / epan / dissectors / packet-hislip.c
blobd8362a34f8a5c448c898c19304a4bf4768948d03
1 /* packet-hislip.c
2 * Routines for High-Speed LAN Instrument Protocol dissection
3 * by Marcel Essig <essig.marcel@gmail.com>
4 * and Guido Kiener <guido.kiener@rohde-schwarz.com>
5 * Copyright (C) 2014 Rohde & Schwarz GmbH & Co. KG
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * SPDX-License-Identifier: GPL-2.0-or-later
14 /* See http://ivifoundation.org/downloads/Class%20Specifications/IVI-6.1_HiSLIP-1.1-2011-02-24.pdf
15 IVI VI-6.1: High-Speed LAN Instrument Protocol (HiSLIP)-*/
18 #include "config.h"
20 #include <epan/packet.h>
21 #include <epan/prefs.h>
22 #include <epan/expert.h>
23 #include "packet-tcp.h"
25 #define PROTO_TAG_HiSLIP "HiSLIP"
26 #define FRAME_HEADER_LEN 16
27 #define MAX_DATA_SHOW_SIZE 60
29 /*Messagetypes*/
30 #define HISLIP_INITIALIZE 0
31 #define HISLIP_INITIALIZERESPONSE 1
32 #define HISLIP_FATALERROR 2
33 #define HISLIP_ERROR 3
34 #define HISLIP_ASYNCLOCK 4
35 #define HISLIP_ASYNCLOCK_RESPONSE 5
36 #define HISLIP_DATA 6
37 #define HISLIP_DATAEND 7
38 #define HISLIP_DEVICECLEARCOMPLETE 8
39 #define HISLIP_DEVICECLEARACKNOWLEDGE 9
40 #define HISLIP_ASYNCREMOTELOCALCONTROL 10
41 #define HISLIP_ASYNCREMOTELOCALRESPONSE 11
42 #define HISLIP_TRIGGER 12
43 #define HISLIP_INTERRUPTED 13
44 #define HISLIP_ASYNCINTERRUPTED 14
45 #define HISLIP_ASYNCMAXIMUMMESSAGESIZE 15
46 #define HISLIP_ASYNCMAXIMUMMESSAGESIZERESPONSE 16
47 #define HISLIP_ASYNCINITIALIZE 17
48 #define HISLIP_ASYNCINITIALIZERESPONSE 18
49 #define HISLIP_ASYNCDEVICECLEAR 19
50 #define HISLIP_ASYNCSERVICEREQUEST 20
51 #define HISLIP_ASYNCSTATUSQUERY 21
52 #define HISLIP_ASYNCSTATUSRESPONSE 22
53 #define HISLIP_ASYNCDEVICECLEARACKNOWLEDGE 23
54 #define HISLIP_ASYNCLOCKINFO 24
55 #define HISLIP_ASYNCLOCKINFORESPONSE 25
59 static int proto_hislip;
61 static dissector_handle_t hislip_handle;
63 /* Request/Response tracking*/
65 typedef struct _hislip_transaction_t
67 uint32_t req_frame;
68 uint32_t rep_frame;
69 uint8_t messagetype;
70 uint8_t controlcode;
71 uint32_t messagepara;
72 } hislip_transaction_t;
74 typedef struct _hislip_conv_info_t
76 uint8_t connectiontype;
77 wmem_tree_t *pdus;
78 }hislip_conv_info_t;
81 typedef struct _hislipinfo
83 uint8_t messagetype;
84 uint8_t controlcode;
85 uint32_t messageparameter;
86 uint64_t payloadlength;
87 unsigned offset;
88 proto_item *hislip_item;
89 } hislipinfo;
92 void proto_register_hislip(void);
93 void proto_reg_handoff_hislip(void);
95 #define HISLIP_PORT 4880
97 /*Field indexs*/
98 static int hf_hislip_prologue;
99 static int hf_hislip_messagetype;
100 static int hf_hislip_controlcode;
101 static int hf_hislip_controlcode_rmt;
102 static int hf_hislip_controlcode_overlap;
103 static int hf_hislip_controlcode_asynclock_code;
104 static int hf_hislip_controlcode_asynclockresponse_code_request;
105 static int hf_hislip_controlcode_asynclockresponse_code_release;
106 static int hf_hislip_controlcode_asynclockinforesponse_code;
107 static int hf_hislip_controlcode_feature_negotiation;
108 static int hf_hislip_controlcode_asyncremotelocalcontrol_code;
109 static int hf_hislip_controlcode_stb;
110 static int hf_hislip_messageparameter;
111 static int hf_hislip_payloadlength;
112 static int hf_hislip_data;
113 static int hf_hislip_msgpara_messageid;
114 static int hf_hislip_msgpara_sessionid;
115 static int hf_hislip_msgpara_serverproto;
116 static int hf_hislip_msgpara_vendorID;
117 static int hf_hislip_msgpara_clientproto;
118 static int hf_hislip_msgpara_clients;
119 static int hf_hislip_msgpara_timeout;
120 static int hf_hislip_fatalerrcode;
121 static int hf_hislip_nonfatalerrorcode;
122 static int hf_hislip_syn;
123 static int hf_hislip_asyn;
124 static int hf_hislip_retransmission;
125 static int hf_hislip_request;
126 static int hf_hislip_maxmessagesize;
127 static int hf_hislip_response;
129 /*Subtree index*/
130 static int ett_hislip;
131 static int ett_hislip_msgpara;
134 static expert_field ei_wrong_prologue;
135 static expert_field ei_msg_not_null;
137 static const range_string messagetypestring[] =
139 { HISLIP_INITIALIZE , HISLIP_INITIALIZE , "Initialize" },
140 { HISLIP_INITIALIZERESPONSE , HISLIP_INITIALIZERESPONSE , "InitializeResponse" },
141 { HISLIP_FATALERROR , HISLIP_FATALERROR , "FatalError" },
142 { HISLIP_ERROR , HISLIP_ERROR , "Error" },
143 { HISLIP_ASYNCLOCK , HISLIP_ASYNCLOCK , "AsyncLock" },
144 { HISLIP_ASYNCLOCK_RESPONSE , HISLIP_ASYNCLOCK_RESPONSE , "AsyncLockResponse" },
145 { HISLIP_DATA , HISLIP_DATA , "Data" },
146 { HISLIP_DATAEND , HISLIP_DATAEND , "DataEnd" },
147 { HISLIP_DEVICECLEARCOMPLETE , HISLIP_DEVICECLEARCOMPLETE , "DeviceClearComplete" },
148 { HISLIP_DEVICECLEARACKNOWLEDGE , HISLIP_DEVICECLEARACKNOWLEDGE , "DeviceClearAcknowledge" },
149 { HISLIP_ASYNCREMOTELOCALCONTROL , HISLIP_ASYNCREMOTELOCALCONTROL , "AsyncRemoteLocalControl" },
150 { HISLIP_ASYNCREMOTELOCALRESPONSE , HISLIP_ASYNCREMOTELOCALRESPONSE , "AsyncRemoteLocalResponse" },
151 { HISLIP_TRIGGER , HISLIP_TRIGGER , "Trigger" },
152 { HISLIP_INTERRUPTED , HISLIP_INTERRUPTED , "Interrupted" },
153 { HISLIP_ASYNCINTERRUPTED , HISLIP_ASYNCINTERRUPTED , "AsyncInterrupted" },
154 { HISLIP_ASYNCMAXIMUMMESSAGESIZE , HISLIP_ASYNCMAXIMUMMESSAGESIZE , "AsyncMaximumMessageSize" },
155 { HISLIP_ASYNCMAXIMUMMESSAGESIZERESPONSE, HISLIP_ASYNCMAXIMUMMESSAGESIZERESPONSE, "AsyncMaximumMessageSizeResponse" },
156 { HISLIP_ASYNCINITIALIZE , HISLIP_ASYNCINITIALIZE , "AsyncInitialize" },
157 { HISLIP_ASYNCINITIALIZERESPONSE , HISLIP_ASYNCINITIALIZERESPONSE , "AsyncInitializeResponse" },
158 { HISLIP_ASYNCDEVICECLEAR , HISLIP_ASYNCDEVICECLEAR , "AsyncDeviceClear" },
159 { HISLIP_ASYNCSERVICEREQUEST , HISLIP_ASYNCSERVICEREQUEST , "AsyncServiceRequest" },
160 { HISLIP_ASYNCSTATUSQUERY , HISLIP_ASYNCSTATUSQUERY , "AsyncStatusQuery" },
161 { HISLIP_ASYNCSTATUSRESPONSE , HISLIP_ASYNCSTATUSRESPONSE , "AsyncStatusResponse" },
162 { HISLIP_ASYNCDEVICECLEARACKNOWLEDGE , HISLIP_ASYNCDEVICECLEARACKNOWLEDGE , "AsyncDeviceClearAcknowledge" },
163 { HISLIP_ASYNCLOCKINFO , HISLIP_ASYNCLOCKINFO , "AsyncLockInfo" },
164 { HISLIP_ASYNCLOCKINFORESPONSE , HISLIP_ASYNCLOCKINFORESPONSE , "AsyncLockInfoResponse" },
165 { 26 , 127 , "reserved for future use"},
166 {128 , 255 , "VendorSpecific" },
167 { 0 , 0 , NULL }
171 static const value_string rmt[] =
173 { 0, "RMT was not delivered" },
174 { 1, "RMT was delivered" },
175 { 0, NULL }
178 static const value_string overlap[] =
180 { 0, "Prefer Synchronized" },
181 { 1, "Prefer Overlap" },
182 { 0, NULL }
185 static const value_string asynclock_code[] =
187 { 0, "Release" },
188 { 1, "Request" },
189 { 0, NULL }
192 static const value_string asynclockresponse_code_request[] =
194 { 0, "Failure" },
195 { 1, "Success" },
196 { 3, "Error" },
197 { 0, NULL }
200 static const value_string asynclockresponse_code_release[] =
202 { 1, "Success exclusive" },
203 { 2, "Success shared" },
204 { 3, "Error" },
205 { 0, NULL }
208 static const value_string asynclockinforesponse_code[] =
210 { 0, "No exclusive lock granted" },
211 { 1, "Exclusive lock granted" },
212 { 0, NULL }
215 static const value_string feature_negotiation[] =
217 { 0, "Synchronized mode" },
218 { 1, "Overlapped mode" },
219 { 0, NULL }
222 static const value_string asyncremotelocalcontrol_code[] =
224 { 0, "Disable remote" },
225 { 1, "Enable remote" },
226 { 2, "Disable remote and go to local" },
227 { 3, "Enable remote and go to remote" },
228 { 4, "Enable remote and lock out local" },
229 { 5, "Enable remote, go to remote, and set local lockout" },
230 { 6, "Go to local without changing state of remote enable" },
231 { 0, NULL }
234 static const value_string remotetype[] =
236 { 0, "(VI_GPIB_REN_DEASSERT)" },
237 { 1, "(VI_GPIB_REN_ASSERT)" },
238 { 2, "(VI_GPIB_REN_DEASSERT_GTL)" },
239 { 3, "(VI_GPIB_REN_ASSERT_ADDRESS)" },
240 { 4, "(VI_GPIB_REN_ASSERT_LLO)" },
241 { 5, "(VI_GPIB_REN_ASSERT_ADDRESS_LLO)" },
242 { 6, "(VI_GPIB_REN_ADDRESS_GTL)" },
243 { 0, NULL}
246 static const range_string fatalerrortype[] =
248 { 0, 0, "Unidentified error" },
249 { 1, 1, "Poorly formed message header" },
250 { 2, 2, "Attempt to use connection without both channels established" },
251 { 3, 3, "Invalid Initialization Sequence" },
252 { 4, 4, "Server refused connection due to maximum number of clients exceeded" },
253 { 5,127, "Reserved for HiSLIP extensions" },
254 {128,255, "Device defined errors" },
255 { 0, 0, NULL }
258 static const range_string nonfatalerrortype[] =
260 { 0, 0, "Unidentified error" },
261 { 1, 1, "Unrecognized Message Type" },
262 { 2, 2, "Unrecognized control code" },
263 { 3, 3, "Unrecognized Vendor Defined Message" },
264 { 4, 4, "Message too large" },
265 { 5,127, "Reserved for HiSLIP extensions" },
266 {128,255, "Device defined errors" },
267 { 0, 0, NULL }
270 /*See http://ivifoundation.org/specifications/default.aspx
271 VPP-9: Instrument Vendor Abbreviations Table 3-1 */
272 /* Sorted by value (spec is not quite in order) */
273 static const value_string vendorID[] =
275 { 0x4143, "Applicos BV" },
276 { 0x4144, "Ando Electric Company Limited" },
277 { 0x4146, "Aeroflex Laboratories" },
278 { 0x4147, "Agilent Technologies" },
279 { 0x4149, "AIM GmbH" },
280 { 0x414D, "AMP Incorporated" },
281 { 0x414E, "Analogic, Corp." },
282 { 0x414F, "AOIP Instrumentation" },
283 { 0x4150, "Audio Precision, Inc" },
284 { 0x4151, "Acqiris" },
285 { 0x4153, "ASCOR Incorporated" },
286 { 0x4154, "Thurlby Thandar Instruments Limited" }, /* Astronics Test Systems Inc ? */
287 { 0x4155, "Anritsu Company" },
288 /* { 0x4155, "Serendipity Systems, Inc." }, XXX - duplicate of "Anritsu Company" */
289 { 0x4156, "Advantest Corporation" },
290 { 0x4241, "BAE Systems" },
291 { 0x4242, "B&B Technologies" },
292 { 0x424B, "Bruel & Kjaer" },
293 { 0x4255, "Bustec Production Ltd." },
294 { 0x4341, "CAL-AV Labs, Inc." },
295 { 0x4343, "Compressor Controls Corporation" },
296 { 0x4348, "C&H Technologies, Inc." },
297 { 0x4349, "Cambridge Instruments" },
298 { 0x4359, "CYTEC Corporation" },
299 { 0x4450, "Directed Perceptions Inc." },
300 { 0x4453, "DSP Technology Inc." },
301 { 0x4456, "IBEKO POWER AB" },
302 { 0x464C, "Fluke Company Inc." },
303 { 0x464F, "fos4X GmbH" },
304 { 0x4749, "EIP Microwave, Inc." },
305 { 0x474b, "gnubi communications, Inc." },
306 { 0x4750, "Hewlett-Packard Company" },
307 { 0x4752, "GenRad" },
308 { 0x4754, "Giga-tronics, Inc." },
309 { 0x4848, "Hoecherl & Hackl GmbH" },
310 { 0x4943, "Integrated Control Systems" },
311 { 0x4945, "Instrumentation Engineering, Inc." },
312 { 0x4946, "IFR" },
313 { 0x4953, "Intepro Systems" },
314 { 0x4B45, "Keithley Instruments" },
315 { 0x4B49, "Kikusui Inc." },
316 { 0x4B50, "Kepco, Inc." },
317 { 0x4B53, "KineticSystems, Corp." },
318 { 0x4B54, "Keysight Technologies (Reserved)" },
319 { 0x4C43, "LeCroy" },
320 { 0x4C50, "LitePoint Corporation" },
321 { 0x4D41, "North Atlantic Instruments" },
322 { 0x4D48, "NH Research" },
323 { 0x4D49, "Marconi Instruments" },
324 { 0x4D50, "MAC Panel Company" },
325 { 0x4D53, "Microscan" },
326 { 0x4D54, "ManTech Test Systems" },
327 { 0x4D57, "Pacific MindWorks, Inc." },
328 { 0x4E44, "Newland Design + Associate, Inc."},
329 { 0x4E49, "National Instruments Corp." },
330 { 0x4E54, "NEUTRIK AG" },
331 { 0x5043, "Picotest" },
332 { 0x5045, "PesMatrix Inc."},
333 { 0x5049, "Pickering Interfaces" },
334 { 0x504D, "Phase Metrics" },
335 { 0x5054, "Power-Tek Inc." },
336 { 0x5241, "Radisys Corp." },
337 { 0x5246, "ThinkRF Corporation" },
338 { 0x5249, "Racal Instruments, Inc." },
339 { 0x5253, "Rohde & Schwarz GmbH" },
340 { 0x5343, "Scicom" },
341 { 0x5349, "SignalCraft Technologies Inc." },
342 { 0x534C, "Schlumberger Technologies" },
343 { 0x5352, "Scientific Research Corporation" },
344 /* { 0x5352, "Sony/Tektronix Corporation" }, XXX - duplicate of "Scientific Research Corporation" */
345 { 0x5353, "Spectrum Signal Processing, Inc." },
346 { 0x5354, "Sony/Tekronix Corporation" },
347 { 0x5441, "Talon Instruments" },
348 { 0x5445, "Teradyne" },
349 { 0x544B, "Tektronix, Inc." },
350 { 0x544D, "Transmagnetics, Inc." },
351 { 0x5453, "Test & Measurement Systems Inc." },
352 { 0x5454, "TTI Testron, Inc." },
353 { 0x554E, "Holding 'Informtest'" },
354 { 0x5553, "Universal Switching Corporation" },
355 { 0x5641, "VXIbus Associates, Inc." },
356 { 0x5645, "Vencon Technologies Inc." },
357 { 0x5650, "Virginia Panel, Corp." },
358 { 0x5654, "VXI Technology, Inc." },
359 { 0x5747, "Wandel & Goltermann" },
360 { 0x5754, "Wavetek Corp." },
361 { 0x575a, "Welzek" },
362 { 0x594B, "Yokogawa Electric Corporation" },
363 { 0x5A54, "ZTEC" },
364 { 0, NULL }
366 static value_string_ext vendorID_ext = VALUE_STRING_EXT_INIT(vendorID);
368 static void
369 decode_messagepara(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, hislipinfo *data)
372 proto_item * item = NULL;
373 proto_tree *msgpara_tree;
374 item = proto_tree_add_item(tree, hf_hislip_messageparameter, tvb, data->offset, 4, ENC_NA);
375 msgpara_tree = proto_item_add_subtree(item, ett_hislip_msgpara);
377 switch (data->messagetype)
379 case HISLIP_INITIALIZE:
381 proto_tree_add_item(msgpara_tree, hf_hislip_msgpara_clientproto, tvb, data->offset, 2, ENC_BIG_ENDIAN );
382 data->offset += 2;
383 proto_tree_add_item(msgpara_tree, hf_hislip_msgpara_vendorID, tvb, data->offset, 2, ENC_BIG_ENDIAN );
384 data->offset += 2;
385 break;
388 case HISLIP_INITIALIZERESPONSE:
390 proto_tree_add_item(msgpara_tree, hf_hislip_msgpara_serverproto, tvb, data->offset, 2, ENC_BIG_ENDIAN );
391 data->offset += 2;
392 proto_tree_add_item(msgpara_tree, hf_hislip_msgpara_sessionid, tvb, data->offset, 2, ENC_BIG_ENDIAN );
393 data->offset += 2;
394 break;
397 case HISLIP_ASYNCLOCK:
399 /*Request or Release?*/
400 if (data->controlcode)
401 { /*Request*/
402 proto_tree_add_item(msgpara_tree, hf_hislip_msgpara_timeout, tvb, data->offset, 4, ENC_BIG_ENDIAN);
404 else
405 { /*Release*/
406 proto_tree_add_item(msgpara_tree, hf_hislip_msgpara_messageid, tvb, data->offset, 4, ENC_BIG_ENDIAN);
408 data->offset += 4;
409 break;
412 case HISLIP_ASYNCLOCKINFORESPONSE:
414 proto_tree_add_item(msgpara_tree, hf_hislip_msgpara_clients, tvb, data->offset, 4, ENC_BIG_ENDIAN );
415 data->offset += 4;
416 break;
419 case HISLIP_ASYNCINITIALIZE:
421 data->offset += 2;
422 proto_tree_add_item(msgpara_tree, hf_hislip_msgpara_sessionid, tvb, data->offset, 2, ENC_BIG_ENDIAN);
423 data->offset += 2;
424 break;
427 case HISLIP_ASYNCINITIALIZERESPONSE:
429 data->offset += 2;
430 proto_tree_add_item(msgpara_tree, hf_hislip_msgpara_vendorID, tvb, data->offset, 2, ENC_BIG_ENDIAN );
431 data->offset += 2;
432 break;
435 case HISLIP_DATA:
436 case HISLIP_DATAEND:
437 case HISLIP_TRIGGER:
438 case HISLIP_INTERRUPTED:
439 case HISLIP_ASYNCINTERRUPTED:
440 case HISLIP_ASYNCSTATUSQUERY:
441 case HISLIP_ASYNCREMOTELOCALCONTROL:
443 proto_tree_add_item(msgpara_tree, hf_hislip_msgpara_messageid, tvb, data->offset, 4, ENC_BIG_ENDIAN );
444 proto_item_append_text(data->hislip_item, ", MessageId: 0x%0x", data->messageparameter);
445 data->offset += 4;
446 break;
449 default:
451 if (data->messageparameter != 0)
453 proto_tree_add_expert(msgpara_tree, pinfo, &ei_msg_not_null, tvb, data->offset, 4);
455 data->offset += 4;
461 static void
462 decode_controlcode(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, hislipinfo *data, uint8_t oldcontrolvalue)
464 proto_item * item = NULL;
465 switch (data->messagetype )
467 case HISLIP_DATA:
468 case HISLIP_DATAEND:
469 case HISLIP_TRIGGER:
470 case HISLIP_ASYNCSTATUSQUERY:
472 proto_tree_add_item(tree, hf_hislip_controlcode_rmt, tvb, data->offset, 1, ENC_BIG_ENDIAN );
473 break;
476 case HISLIP_INITIALIZERESPONSE:
478 proto_tree_add_item(tree, hf_hislip_controlcode_overlap, tvb, data->offset, 1, ENC_BIG_ENDIAN );
479 col_append_fstr(pinfo->cinfo, COL_INFO, " [%s]", val_to_str_const(data->controlcode, overlap, "Unknown"));
480 proto_item_append_text(data->hislip_item, ", %s", val_to_str_const(data->controlcode, overlap, "Unknown"));
481 break;
484 case HISLIP_ASYNCLOCK:
486 item = proto_tree_add_item(tree, hf_hislip_controlcode_asynclock_code, tvb, data->offset, 1, ENC_BIG_ENDIAN );
487 col_append_fstr(pinfo->cinfo, COL_INFO, " [%s", val_to_str_const(data->controlcode, asynclock_code, "Unknown"));
488 proto_item_append_text(data->hislip_item, ", %s", val_to_str_const(data->controlcode, asynclock_code, "Unknown"));
490 /*if release add ] and leave*/
491 if (data->controlcode != 1)
493 col_append_str(pinfo->cinfo, COL_INFO, "]");
494 break;
497 /*shared (Datalength != 0)or exclusive*/
498 if (data->payloadlength == 0)
501 proto_item_append_text(item, "[Exclusive]");
502 col_append_str(pinfo->cinfo, COL_INFO, " Exclusive]");
503 proto_item_append_text(data->hislip_item, " (Exclusive)");
505 else
507 proto_item_append_text(item, "[Shared]");
508 col_append_str(pinfo->cinfo, COL_INFO, " Shared]");
509 proto_item_append_text(data->hislip_item, " (Shared)");
511 break;
514 case HISLIP_FATALERROR:
516 proto_tree_add_item(tree, hf_hislip_fatalerrcode, tvb, data->offset, 1, ENC_BIG_ENDIAN );
517 col_append_fstr(pinfo->cinfo, COL_INFO, " [%s]", rval_to_str_const(data->controlcode, fatalerrortype, "Unknown"));
518 proto_item_append_text(data->hislip_item, ", %s", rval_to_str_const(data->controlcode, fatalerrortype, "Unknown"));
519 break;
522 case HISLIP_ERROR:
524 proto_tree_add_item(tree, hf_hislip_nonfatalerrorcode, tvb, data->offset, 1, ENC_BIG_ENDIAN );
525 col_append_fstr(pinfo->cinfo, COL_INFO, " [%s]", rval_to_str_const(data->controlcode, nonfatalerrortype, "Unknown"));
526 proto_item_append_text(data->hislip_item, ", %s", rval_to_str_const(data->controlcode, nonfatalerrortype, "Unknown"));
527 break;
530 case HISLIP_ASYNCLOCK_RESPONSE:
532 /*Response of Request or Release*/
533 if (oldcontrolvalue == 1)
534 { /*Requestresponse*/
535 proto_tree_add_item(tree, hf_hislip_controlcode_asynclockresponse_code_request, tvb, data->offset, 1, ENC_BIG_ENDIAN );
536 col_append_fstr(pinfo->cinfo, COL_INFO, " [%s]", val_to_str_const(data->controlcode, asynclockresponse_code_request, "Unknown"));
537 proto_item_append_text(data->hislip_item, ", %s", val_to_str_const(data->controlcode, asynclockresponse_code_request, "Unknown"));
539 else
540 { /*Releaseresponse*/
541 proto_tree_add_item(tree, hf_hislip_controlcode_asynclockresponse_code_release, tvb, data->offset, 1, ENC_BIG_ENDIAN );
542 col_append_fstr(pinfo->cinfo, COL_INFO, " [%s]", val_to_str_const(data->controlcode, asynclockresponse_code_release, "Unknown"));
543 proto_item_append_text(data->hislip_item, ", %s", val_to_str_const(data->controlcode, asynclockresponse_code_release, "Unknown"));
545 break;
548 case HISLIP_ASYNCLOCKINFORESPONSE:
550 proto_tree_add_item(tree, hf_hislip_controlcode_asynclockinforesponse_code, tvb, data->offset, 1, ENC_BIG_ENDIAN );
551 col_append_fstr(pinfo->cinfo, COL_INFO, " [%s]", val_to_str_const(data->controlcode, asynclockinforesponse_code, "Unknown"));
552 proto_item_append_text(data->hislip_item, ", %s", val_to_str_const(data->controlcode, asynclockinforesponse_code, "Unknown"));
553 break;
556 case HISLIP_ASYNCREMOTELOCALCONTROL:
558 item = proto_tree_add_item(tree, hf_hislip_controlcode_asyncremotelocalcontrol_code, tvb, data->offset, 1, ENC_BIG_ENDIAN );
559 proto_item_append_text(item, " %s", val_to_str_const(data->controlcode, remotetype, "Unknown"));
560 col_append_fstr(pinfo->cinfo, COL_INFO, " [%s]", val_to_str_const(data->controlcode, asyncremotelocalcontrol_code, "Unknown"));
561 proto_item_append_text(data->hislip_item, ", %s", val_to_str_const(data->controlcode, asyncremotelocalcontrol_code, "Unknown"));
563 break;
566 case HISLIP_ASYNCSTATUSRESPONSE:
567 case HISLIP_ASYNCSERVICEREQUEST:
569 proto_tree_add_item(tree, hf_hislip_controlcode_stb, tvb, data->offset, 1, ENC_BIG_ENDIAN );
570 col_append_fstr(pinfo->cinfo, COL_INFO, " STB (0x%x)", data->controlcode);
571 proto_item_append_text(data->hislip_item, ", STB (0x%x)", data->controlcode);
572 break;
574 case HISLIP_ASYNCDEVICECLEARACKNOWLEDGE:
575 case HISLIP_DEVICECLEARCOMPLETE:
576 case HISLIP_DEVICECLEARACKNOWLEDGE:
578 proto_tree_add_item(tree, hf_hislip_controlcode_feature_negotiation, tvb, data->offset, 1, ENC_BIG_ENDIAN );
579 col_append_fstr(pinfo->cinfo, COL_INFO, " [%s]", val_to_str_const(data->controlcode&0x01, feature_negotiation, "Unknown"));
580 break;
582 default:
583 proto_tree_add_item(tree, hf_hislip_controlcode, tvb, data->offset, 1, ENC_BIG_ENDIAN);
587 data->offset++;
592 static void
593 decode_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, hislipinfo *data)
595 proto_item * item = NULL;
596 /*check for data in packet*/
597 if (data->payloadlength != 0)
599 uint64_t datalength;
600 double max_message_size;
602 switch (data->messagetype)
604 case HISLIP_DATA:
605 case HISLIP_DATAEND:
606 case HISLIP_INITIALIZE:
608 datalength = MAX_DATA_SHOW_SIZE;
610 if (data->payloadlength <= datalength)
611 datalength = data->payloadlength;
613 col_append_fstr(pinfo->cinfo, COL_INFO, " %s", tvb_format_text(pinfo->pool, tvb, data->offset, (uint32_t)datalength));
614 proto_tree_add_item(tree, hf_hislip_data, tvb, data->offset, -1, ENC_UTF_8 |ENC_NA);
616 break;
618 case HISLIP_ASYNCMAXIMUMMESSAGESIZE:
619 case HISLIP_ASYNCMAXIMUMMESSAGESIZERESPONSE:
621 max_message_size = (double)tvb_get_ntoh64(tvb, data->offset);
622 max_message_size = max_message_size/1048576.0;
624 item = proto_tree_add_item(tree, hf_hislip_maxmessagesize, tvb, data->offset, 8, ENC_BIG_ENDIAN);
625 proto_item_append_text(item, " bytes (%.2f Mbytes)", max_message_size);
626 col_append_fstr(pinfo->cinfo, COL_INFO, " Max Message Size: %.2f Mbytes", max_message_size);
628 break;
630 default:
632 proto_tree_add_item(tree, hf_hislip_data, tvb, data->offset, -1, ENC_UTF_8 | ENC_NA);
637 data->offset += (uint32_t)data->payloadlength;
642 /*Search for Retransmission*/
643 static uint32_t
644 search_for_retransmission(wmem_tree_t *pdus, hislipinfo *data, uint32_t fnum )
647 hislip_transaction_t *hislip_trans;
649 hislip_trans = (hislip_transaction_t *)wmem_tree_lookup32_le(pdus, fnum-1);
651 if (hislip_trans)
653 if (hislip_trans->messagetype == data->messagetype && hislip_trans->rep_frame == 0)
654 return hislip_trans->req_frame;
657 return 0;
661 static uint8_t
662 is_connection_syn_or_asyn(uint8_t messagetype)
664 if (messagetype >= HISLIP_ASYNCINTERRUPTED)
666 return HISLIP_ASYNCINITIALIZE;
668 else
670 switch (messagetype)
672 case HISLIP_ASYNCLOCK:
673 case HISLIP_ASYNCLOCK_RESPONSE:
674 case HISLIP_ASYNCREMOTELOCALCONTROL:
675 case HISLIP_ASYNCREMOTELOCALRESPONSE:
677 return HISLIP_ASYNCINITIALIZE;
679 default:
681 return HISLIP_INITIALIZE;
687 static int
688 dissect_hislip_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
690 conversation_t *conversation;
691 hislip_conv_info_t *hislip_info;
692 hislip_transaction_t *hislip_trans;
693 proto_tree *hislip_tree;
694 proto_item *it = NULL;
695 hislipinfo hislip_data;
696 uint8_t oldcontrolvalue = 0;
697 uint32_t frame_number;
699 hislip_tree = NULL;
700 conversation = NULL;
701 hislip_info = NULL;
702 memset(&hislip_data, 0, sizeof(hislip_data));
705 /*Write "HiSLIP" in the protocol column*/
706 col_set_str(pinfo->cinfo, COL_PROTOCOL, PROTO_TAG_HiSLIP);
708 /* Clear out stuff in the info column */
709 col_clear(pinfo->cinfo, COL_INFO);
712 /*Get Message Type*/
713 hislip_data.messagetype = tvb_get_uint8(tvb, hislip_data.offset+2);
714 /*Get Control Code*/
715 hislip_data.controlcode = tvb_get_uint8(tvb, hislip_data.offset+3);
716 /*Get Message Parameter*/
717 hislip_data.messageparameter = tvb_get_ntohl(tvb, hislip_data.offset+4);
718 /*Get Payload Length*/
719 hislip_data.payloadlength = tvb_get_ntoh64(tvb, hislip_data.offset+8);
722 /* Write Messagetype in the info column */
723 col_add_str(pinfo->cinfo, COL_INFO, rval_to_str_const(hislip_data.messagetype, messagetypestring, "Unknown"));
726 if (tree)
728 hislip_data.hislip_item = proto_tree_add_item(tree, proto_hislip, tvb, 0, -1, ENC_NA);
729 hislip_tree = proto_item_add_subtree(hislip_data.hislip_item, ett_hislip);
732 if (tvb_get_ntohs(tvb, 0) != 0x4853)
734 expert_add_info(pinfo, hislip_data.hislip_item, &ei_wrong_prologue);
737 conversation = find_or_create_conversation(pinfo);
739 /*Do we already have a state structure for this conv*/
740 hislip_info = (hislip_conv_info_t *)conversation_get_proto_data(conversation, proto_hislip);
741 if (!hislip_info)
743 hislip_info = (hislip_conv_info_t *)wmem_alloc(wmem_file_scope(), (sizeof(hislip_conv_info_t)));
744 hislip_info->connectiontype = is_connection_syn_or_asyn(hislip_data.messagetype);
745 hislip_info->pdus = wmem_tree_new(wmem_file_scope());
746 conversation_add_proto_data(conversation, proto_hislip, (void *)hislip_info);
749 /*synchronous or asynchronous channel*/
750 if(hislip_info->connectiontype == HISLIP_INITIALIZE)
752 proto_item_append_text(hislip_data.hislip_item, " (Synchron)");
753 it = proto_tree_add_item(hislip_tree, hf_hislip_syn, tvb, 0, 0, ENC_NA);
755 else
757 proto_item_append_text(hislip_data.hislip_item," (Asynchron)");
758 it = proto_tree_add_item(hislip_tree, hf_hislip_asyn, tvb, 0, 0, ENC_NA);
760 proto_item_set_generated(it);
762 switch(hislip_data.messagetype)
764 case HISLIP_ASYNCLOCK:
765 case HISLIP_ASYNCINITIALIZE:
766 case HISLIP_ASYNCMAXIMUMMESSAGESIZE:
767 case HISLIP_INITIALIZE:
768 case HISLIP_ASYNCSTATUSQUERY:
769 case HISLIP_ASYNCLOCKINFO:
771 /*Request*/
772 if(!PINFO_FD_VISITED(pinfo))
774 /* This is a new request */
775 hislip_trans = wmem_new(wmem_file_scope(), hislip_transaction_t);
776 hislip_trans->req_frame = pinfo->num;
777 hislip_trans->rep_frame = 0;
778 hislip_trans->messagetype = hislip_data.messagetype;
779 hislip_trans->controlcode = hislip_data.controlcode;
780 wmem_tree_insert32(hislip_info->pdus, pinfo->num , (void *)hislip_trans);
782 else
784 hislip_trans = (hislip_transaction_t *)wmem_tree_lookup32(hislip_info->pdus, pinfo->num);
786 if(hislip_trans && hislip_trans->rep_frame != 0)
788 it = proto_tree_add_uint(hislip_tree, hf_hislip_response, tvb, 0, 0, hislip_trans->rep_frame);
789 proto_item_set_generated(it);
792 /*Retransmission*/
793 if((frame_number = search_for_retransmission(hislip_info->pdus, &hislip_data , pinfo->num))!=0)
795 it = proto_tree_add_uint( hislip_tree, hf_hislip_retransmission, tvb, 0, 0, frame_number);
796 proto_item_set_generated(it);
799 break;
802 case HISLIP_ASYNCLOCK_RESPONSE:
803 case HISLIP_ASYNCINITIALIZERESPONSE:
804 case HISLIP_ASYNCMAXIMUMMESSAGESIZERESPONSE:
805 case HISLIP_INITIALIZERESPONSE:
806 case HISLIP_ASYNCSTATUSRESPONSE:
807 case HISLIP_ASYNCLOCKINFORESPONSE:
809 /*Response*/
810 hislip_trans = (hislip_transaction_t *) wmem_tree_lookup32_le( hislip_info->pdus, pinfo->num);
811 if (hislip_trans)
813 hislip_trans->rep_frame = pinfo->num;
814 oldcontrolvalue = hislip_trans->controlcode;
815 it = proto_tree_add_uint( hislip_tree, hf_hislip_request,tvb, 0, 0, hislip_trans->req_frame);
816 proto_item_set_generated(it);
818 break;
821 default:
827 /* Actually dissect fields */
829 /* TODO: could control whether this is shown by preference? */
830 proto_tree_add_item(hislip_tree, hf_hislip_prologue, tvb, hislip_data.offset, 2, ENC_ASCII);
831 hislip_data.offset += 2;
833 proto_tree_add_item(hislip_tree, hf_hislip_messagetype, tvb, hislip_data.offset, 1, ENC_BIG_ENDIAN);
834 proto_item_append_text(hislip_data.hislip_item, ", %s", rval_to_str_const(hislip_data.messagetype, messagetypestring, "Unknown"));
835 hislip_data.offset += 1;
837 decode_controlcode(tvb, pinfo, hislip_tree, &hislip_data, oldcontrolvalue );
839 decode_messagepara(tvb, pinfo, hislip_tree, &hislip_data);
841 proto_tree_add_item(hislip_tree, hf_hislip_payloadlength, tvb, hislip_data.offset, 8, ENC_BIG_ENDIAN);
842 hislip_data.offset += 8;
844 decode_data(tvb, pinfo, hislip_tree, &hislip_data );
846 return tvb_captured_length(tvb);
850 static unsigned
851 get_hislip_message_len(packet_info *pinfo _U_, tvbuff_t *tvb,
852 int offset, void *data _U_)
854 /* Data length */
855 uint64_t length = tvb_get_ntoh64(tvb, offset+8);
856 /* Header length */
857 length += FRAME_HEADER_LEN;
859 return (uint32_t)length;
862 static int
863 dissect_hislip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
865 /*Reassembling TCP fragments*/
866 tcp_dissect_pdus(tvb, pinfo, tree, true, FRAME_HEADER_LEN,
867 get_hislip_message_len, dissect_hislip_message, data);
869 return tvb_captured_length(tvb);
872 /*Heuristic*/
873 static bool
874 dissect_hislip_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
876 /* min. 16 bytes?*/
877 if (tvb_captured_length(tvb) < FRAME_HEADER_LEN)
878 return false;
880 /*first two byte == "HS"*/
881 if (tvb_get_ntohs(tvb, 0) != 0x4853)
882 return false;
884 /* XXX: Can it be assumed that all following packets for this connection will also be 'hislip' ?
885 * If so, conversation_set_dissector() should be called.
887 dissect_hislip(tvb, pinfo, tree, data);
888 return true;
893 /*Register HiSLIP with Wireshark*/
894 void
895 proto_register_hislip(void)
898 expert_module_t* expert_hislip;
899 module_t * hislip_module;
901 static hf_register_info hf[] = {
902 { &hf_hislip_prologue,
903 { "Prologue", "hislip.prologue", FT_STRING, BASE_NONE, NULL, 0x0,
904 "HiSLIP Message Prologue (should be \"HS\")", HFILL }},
905 { &hf_hislip_messagetype,
906 { "Message Type", "hislip.messagetype", FT_UINT8, BASE_HEX|BASE_RANGE_STRING, RVALS(messagetypestring), 0x0,
907 "HiSLIP Message Type", HFILL }},
908 { &hf_hislip_controlcode,
909 { "Control Code", "hislip.controlcode", FT_UINT8, BASE_DEC, NULL, 0x0,
910 "HiSLIP Control Code", HFILL }},
911 { &hf_hislip_controlcode_rmt,
912 { "Control Code", "hislip.controlcode.rmt", FT_UINT8, BASE_HEX, VALS(rmt), 0x0,
913 "HiSLIP RMT", HFILL }},
914 { &hf_hislip_controlcode_overlap,
915 { "Control Code", "hislip.controlcode.overlap", FT_UINT8, BASE_HEX, VALS(overlap), 0x0,
916 "HiSLIP overlap", HFILL }},
917 { &hf_hislip_controlcode_asynclockinforesponse_code,
918 { "Control Code", "hislip.controlcode.asynclockinforesponse", FT_UINT8, BASE_HEX, VALS(asynclockinforesponse_code), 0x0,
919 "HiSLIP asynclockinforesponse", HFILL }},
920 { &hf_hislip_controlcode_asynclockresponse_code_release,
921 { "Control Code", "hislip.controlcode.asynclockresponse", FT_UINT8, BASE_HEX, VALS(asynclockresponse_code_release), 0x0,
922 "HiSLIP asynclockresponse code", HFILL }},
923 { &hf_hislip_controlcode_asynclockresponse_code_request,
924 { "Control Code", "hislip.controlcode.asynclockresponse", FT_UINT8, BASE_HEX, VALS(asynclockresponse_code_request), 0x0,
925 "HiSLIP asynclockresponse code", HFILL }},
926 { &hf_hislip_controlcode_asyncremotelocalcontrol_code,
927 { "Control Code", "hislip.controlcode.asyncremotelocalcontrol", FT_UINT8, BASE_HEX, VALS(asyncremotelocalcontrol_code), 0x0,
928 "HiSLIP asyncremotelocalcontrol", HFILL }},
929 { &hf_hislip_controlcode_feature_negotiation,
930 { "Control Code", "hislip.controlcode.featurenegotiation", FT_UINT8, BASE_HEX, VALS(feature_negotiation), 0x0,
931 "HiSLIP feature", HFILL }},
932 { &hf_hislip_controlcode_asynclock_code,
933 { "Control Code", "hislip.controlcode.asynclockcode", FT_UINT8, BASE_HEX, VALS(asynclock_code), 0x0,
934 "HiSLIP asynclock code", HFILL }},
935 { &hf_hislip_controlcode_stb,
936 { "STB", "hislip.controlcode.stb", FT_UINT8, BASE_HEX, NULL, 0x0,
937 "HiSLIP Status Byte", HFILL }},
938 { &hf_hislip_payloadlength,
939 { "Payload Length", "hislip.payloadlength", FT_UINT64, BASE_DEC, NULL, 0x0,
940 "HiSLIP Payload Length", HFILL }},
941 { &hf_hislip_messageparameter,
942 { "Message Parameter", "hislip.msgpara", FT_NONE, BASE_NONE, NULL, 0x0,
943 "HiSLIP Message Parameter", HFILL }},
944 { &hf_hislip_msgpara_messageid,
945 { "MessageID", "hislip.msgpara.messageid", FT_UINT32, BASE_HEX, NULL, 0x0,
946 "HiSLIP MessageID", HFILL }},
947 { &hf_hislip_msgpara_sessionid,
948 { "SessionID", "hislip.msgpara.sessionid", FT_UINT16, BASE_HEX, NULL, 0x0,
949 "HiSLIP SessionID", HFILL }},
950 { &hf_hislip_msgpara_serverproto,
951 { "Server version", "hislip.msgpara.servproto", FT_UINT16, BASE_HEX, NULL, 0x0,
952 "HiSLIP Server Protocol version", HFILL }},
953 { &hf_hislip_msgpara_vendorID,
954 { "VendorID", "hislip.msgpara.vendorID", FT_UINT16, BASE_HEX|BASE_EXT_STRING, &vendorID_ext, 0x0,
955 "HiSLIP VendorID", HFILL }},
956 { &hf_hislip_msgpara_clientproto,
957 { "Client version", "hislip.msgpara.clientproto", FT_UINT16, BASE_HEX, NULL, 0x0,
958 "HiSLIP Client protocol version", HFILL }},
959 { &hf_hislip_msgpara_clients,
960 { "HiSLIP clients holding locks", "hislip.msgpara.clients", FT_UINT32, BASE_DEC, NULL, 0x0,
961 "HiSLIP clients holding locks on the server", HFILL }},
962 { &hf_hislip_msgpara_timeout,
963 { "Timeout[ms]", "hislip.msgpara.timeout", FT_UINT32, BASE_DEC, NULL, 0x0,
964 "Time out from a AsyncLock message", HFILL }},
965 { &hf_hislip_data,
966 { "Data", "hislip.data", FT_STRING, BASE_NONE, NULL, 0x0,
967 "HiSLIP Payload", HFILL }},
968 { &hf_hislip_request,
969 { "Request", "hislip.response", FT_FRAMENUM, BASE_NONE, FRAMENUM_TYPE(FT_FRAMENUM_REQUEST), 0x0,
970 "This is a response to the HiSLIP request in this frame", HFILL }},
971 { &hf_hislip_response,
972 { "Response", "hislip.request", FT_FRAMENUM, BASE_NONE, FRAMENUM_TYPE(FT_FRAMENUM_RESPONSE), 0x0,
973 "A Request in this frame", HFILL }},
974 { &hf_hislip_syn,
975 { "Synchronous Channel", "hislip.syn", FT_NONE, BASE_NONE, NULL, 0x0,
976 "This is the HiSLIP Synchronous Channel", HFILL }},
977 { &hf_hislip_asyn,
978 { "Asynchronous Channel", "hislip.asyn", FT_NONE, BASE_NONE, NULL, 0x0,
979 "This is the HiSLIP Asynchronous Channel", HFILL }},
980 { &hf_hislip_fatalerrcode,
981 { "Fatalerror Code", "hislip.fatalerrcode", FT_UINT8, BASE_HEX|BASE_RANGE_STRING, RVALS(fatalerrortype), 0x0,
982 "HiSLIP Fatalerror Code", HFILL }},
983 { &hf_hislip_retransmission,
984 { "Retransmission from", "hislip.retrans", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
985 "HiSLIP Retransmission", HFILL }},
986 { &hf_hislip_nonfatalerrorcode,
987 { "Nonfatalerror Code", "hislip.nonfatalerrorcode", FT_UINT8, BASE_HEX|BASE_RANGE_STRING, RVALS(nonfatalerrortype), 0x0,
988 "HiSLIP Nonfatalerror Code", HFILL }},
989 { &hf_hislip_maxmessagesize,
990 { "Max Message Size", "hislip.maxmsgsize", FT_UINT64, BASE_DEC, NULL, 0x0,
991 "HiSLIP Maximum Message Size", HFILL }}
995 static int *ett[] = {
996 &ett_hislip,
997 &ett_hislip_msgpara
1001 static ei_register_info ei[] = {
1002 { &ei_wrong_prologue, { "hislip.wrongprologue", PI_UNDECODED, PI_WARN, "Frame hasn't 'HS' as Prologue", EXPFILL }},
1003 { &ei_msg_not_null, { "hislip.msgnotnull", PI_PROTOCOL, PI_WARN, "Message Parameter isn't 0", EXPFILL }}
1006 proto_hislip = proto_register_protocol("High-Speed LAN Instrument Protocol", "HiSLIP", "hislip");
1008 expert_hislip = expert_register_protocol(proto_hislip);
1009 expert_register_field_array(expert_hislip, ei, array_length(ei));
1011 proto_register_field_array(proto_hislip, hf, array_length(hf));
1012 proto_register_subtree_array(ett, array_length(ett));
1014 hislip_module = prefs_register_protocol(proto_hislip, NULL);
1015 prefs_register_obsolete_preference(hislip_module, "enable_heuristic");
1017 hislip_handle = register_dissector("hislip", dissect_hislip, proto_hislip);
1020 void
1021 proto_reg_handoff_hislip(void)
1023 /* disabled by default since heuristic is weak */
1024 heur_dissector_add("tcp", dissect_hislip_heur, "HiSLIP over TCP", "hislip_tcp", proto_hislip, HEURISTIC_DISABLE);
1026 dissector_add_uint_with_preference("tcp.port", HISLIP_PORT, hislip_handle);
1030 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1032 * Local variables:
1033 * c-basic-offset: 4
1034 * tab-width: 8
1035 * indent-tabs-mode: nil
1036 * End:
1038 * vi: set shiftwidth=4 tabstop=8 expandtab:
1039 * :indentSize=4:tabSize=8:noTabs=true: