Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-lat.c
blob7896f6d99eb3f254c89b91f31694c90bb36e8325
1 /* packet-lat.c
2 * Routines for the disassembly of DEC's LAT protocol
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 <string.h>
15 #include <epan/packet.h>
16 #include <epan/expert.h>
17 #include <epan/unit_strings.h>
18 #include "etypes.h"
20 void proto_register_lat(void);
21 void proto_reg_handoff_lat(void);
24 * Information on LAT taken from the LAT specification at
26 * http://www.bitsavers.org/pdf/dec/ethernet/lat/AA-NL26A-TE_LAT_Specification_Jun89.pdf
29 static dissector_handle_t lat_handle;
31 static int proto_lat;
32 static int hf_lat_rrf;
33 static int hf_lat_master;
34 static int hf_lat_msg_typ;
35 static int hf_lat_nbr_slots;
36 static int hf_lat_dst_cir_id;
37 static int hf_lat_src_cir_id;
38 static int hf_lat_msg_seq_nbr;
39 static int hf_lat_msg_ack_nbr;
40 static int hf_lat_min_rcv_datagram_size;
41 static int hf_lat_prtcl_ver;
42 static int hf_lat_prtcl_eco;
43 static int hf_lat_max_sim_slots;
44 static int hf_lat_nbr_dl_bufs;
45 static int hf_lat_server_circuit_timer;
46 static int hf_lat_keep_alive_timer;
47 static int hf_lat_facility_number;
48 static int hf_lat_prod_type_code;
49 static const value_string prod_type_code_vals[] = {
50 { 1, "Ethernet terminal server" },
51 { 2, "DECserver 100" },
52 { 3, "VAX/VMS" },
53 { 4, "RSX11-M" },
54 { 5, "RSX11-M+" },
55 { 6, "TOPS-20" },
56 { 7, "TOPS-10" },
57 { 8, "Ultrix-11" },
58 { 9, "LAT-11" },
59 { 10, "RSTS/E" },
60 { 11, "Ultrix-32" },
61 { 12, "ELN" },
62 { 13, "MS/DOS" },
63 { 14, "P/OS" },
64 { 15, "PCSG-LAT" },
65 { 16, "DELIX" },
66 { 17, "DECserver 200" },
67 { 18, "DECserver 500" },
68 { 19, "Actor" },
69 { 0, NULL }
71 static int hf_lat_prod_vers_numb;
72 static int hf_lat_slave_node_name;
73 static int hf_lat_master_node_name;
74 static int hf_lat_location_text;
75 static int hf_lat_param_code;
76 static int hf_lat_param_len;
77 static int hf_lat_param_data;
78 static int hf_lat_slot_dst_slot_id;
79 static int hf_lat_slot_src_slot_id;
80 static int hf_lat_slot_byte_count;
81 static int hf_lat_slot_credits;
82 static int hf_lat_slot_type;
83 static int hf_lat_start_slot_service_class;
84 static int hf_lat_start_slot_minimum_attention_slot_size;
85 static int hf_lat_start_slot_minimum_data_slot_size;
86 static int hf_lat_start_slot_obj_srvc;
87 static int hf_lat_start_slot_subj_dscr;
88 static int hf_lat_start_slot_class_1_param_code;
89 static int hf_lat_status_remaining;
90 static int hf_lat_slot_data;
91 static int hf_lat_data_b_slot_control_flags;
92 static int hf_lat_data_b_slot_control_flags_enable_input_flow_control;
93 static int hf_lat_data_b_slot_control_flags_disable_input_flow_control;
94 static int hf_lat_data_b_slot_control_flags_enable_output_flow_control;
95 static int hf_lat_data_b_slot_control_flags_disable_output_flow_control;
96 static int hf_lat_data_b_slot_control_flags_break_detected;
97 static int hf_lat_data_b_slot_control_flags_set_port_char;
98 static int hf_lat_data_b_slot_control_flags_report_port_char;
99 static int * const data_b_slot_control_flags_fields[] = {
100 &hf_lat_data_b_slot_control_flags_enable_input_flow_control,
101 &hf_lat_data_b_slot_control_flags_disable_input_flow_control,
102 &hf_lat_data_b_slot_control_flags_enable_output_flow_control,
103 &hf_lat_data_b_slot_control_flags_disable_output_flow_control,
104 &hf_lat_data_b_slot_control_flags_break_detected,
105 &hf_lat_data_b_slot_control_flags_set_port_char,
106 &hf_lat_data_b_slot_control_flags_report_port_char,
107 NULL
109 static int hf_lat_data_b_slot_stop_output_channel_char;
110 static int hf_lat_data_b_slot_start_output_channel_char;
111 static int hf_lat_data_b_slot_stop_input_channel_char;
112 static int hf_lat_data_b_slot_start_input_channel_char;
113 static int hf_lat_data_b_slot_param_code;
114 static const value_string data_b_slot_param_code_vals[] = {
115 { 0, "End of parameters" },
116 { 1, "Parity and frame size" },
117 { 2, "Input speed" },
118 { 3, "Output speed" },
119 { 4, "Bell-on-discard preference" },
120 { 5, "Transparency mode" },
121 { 6, "Status" },
122 { 0, NULL }
124 static int hf_lat_slot_data_remaining;
125 static int hf_lat_attention_slot_control_flags;
126 static int hf_lat_attention_slot_control_flags_abort;
127 static int * const attention_slot_control_flags_fields[] = {
128 &hf_lat_attention_slot_control_flags_abort,
129 NULL
131 static int hf_lat_mbz;
132 static int hf_lat_reason;
133 static int hf_lat_circuit_disconnect_reason;
134 static int hf_lat_reason_text;
135 static int hf_lat_high_prtcl_ver;
136 static int hf_lat_low_prtcl_ver;
137 static int hf_lat_cur_prtcl_ver;
138 static int hf_lat_cur_prtcl_eco;
139 static int hf_lat_msg_inc;
140 static int hf_lat_change_flags;
141 static int hf_lat_data_link_rcv_frame_size;
142 static int hf_lat_node_multicast_timer;
143 static int hf_lat_node_status;
144 static int hf_lat_node_group_len;
145 static int hf_lat_node_groups;
146 static int hf_lat_node_name;
147 static int hf_lat_node_description;
148 static int hf_lat_service_name_count;
149 static int hf_lat_service_rating;
150 static int hf_lat_node_service_len;
151 static int hf_lat_node_service_class;
153 static int hf_lat_prtcl_format;
154 static int hf_lat_request_identifier;
155 static int hf_lat_entry_identifier;
156 static int hf_lat_command_type;
157 static const value_string command_type_vals[] = {
158 { 1, "Solicit non-queued access to the service" },
159 { 2, "Solicit queued access to the service" },
160 { 3, "Cancel entry in the queue" },
161 { 4, "Send status of the entry" },
162 { 5, "Send status of the queue" },
163 { 6, "Send status of multiple entries" },
164 { 0, NULL }
166 static int hf_lat_command_modifier;
167 static int hf_lat_command_modifier_send_status_periodically;
168 static int hf_lat_command_modifier_send_status_on_queue_depth_change;
169 static int * const lat_command_modifier_fields[] = {
170 &hf_lat_command_modifier_send_status_periodically,
171 &hf_lat_command_modifier_send_status_on_queue_depth_change,
172 NULL
174 static int hf_lat_obj_node_name;
175 static int hf_lat_subj_group_len;
176 static int hf_lat_subj_group;
177 static int hf_lat_subj_node_name;
178 static int hf_lat_subj_port_name;
179 static int hf_lat_status_retransmit_timer;
180 static int hf_lat_entries_counter;
181 static int hf_lat_entry_length;
182 static int hf_lat_entry_status;
183 static int hf_lat_entry_status_rejected;
184 static int hf_lat_entry_status_additional_information;
185 static int * const lat_entry_status_fields[] = {
186 &hf_lat_entry_status_rejected,
187 &hf_lat_entry_status_additional_information,
188 NULL
190 #define ENTRY_STATUS_REJECTED 0x80
191 #define ENTRY_STATUS_ADDITIONAL_INFORMATION 0x7F
192 static const value_string additional_information_vals[] = {
193 { 0, "No additional information is provided" },
194 { 1, "Request is already queued" },
195 { 2, "Entry is accepted for processing" },
196 { 3, "Periodic status return is not supported" },
197 { 4, "Queue-depth status report is not supported" },
198 { 0, NULL }
200 static int hf_lat_entry_error;
201 static const value_string entry_error_vals[] = {
202 { 1, "reason is unknown" },
203 { 2, "user requested disconnect" },
204 { 3, "system shutdown in progress" },
205 { 4, "invalid slot received" },
206 { 5, "invalid service class" },
207 { 6, "insufficient resources to satisfy request" },
208 { 7, "service in use" },
209 { 8, "no such service" },
210 { 9, "service is disabled" },
211 { 10, "service is not offered by the requested port" },
212 { 11, "port name is unknown" },
213 { 12, "invalid password" },
214 { 13, "entry is not in the queue" },
215 { 14, "immediate access rejected" },
216 { 15, "access denied" },
217 { 16, "COMMAND_TYPE code is illegal/not supported" },
218 { 17, "Start slot can't be set" },
219 { 18, "Queue entry deleted by local node" },
220 { 19, "Inconsistent or illegal request parameters" },
221 { 0, NULL }
223 static int hf_lat_elapsed_queue_time;
224 static int hf_lat_min_queue_position;
225 static int hf_lat_max_queue_position;
226 static int hf_lat_obj_srvc_name;
227 static int hf_lat_obj_port_name;
228 static int hf_lat_subj_description;
230 static int hf_lat_solicit_identifier;
231 static int hf_lat_response_timer;
232 static int hf_lat_dst_node_name;
233 static int hf_lat_src_node_group_len;
234 static int hf_lat_src_node_groups;
235 static int hf_lat_src_node_name;
236 static int hf_lat_dst_srvc_name;
238 static int hf_lat_response_status;
239 static int hf_lat_response_status_node_does_not_offer_requested_service;
240 static int * const lat_response_status_fields[] = {
241 &hf_lat_response_status_node_does_not_offer_requested_service,
242 NULL
244 static int hf_lat_src_node_status;
245 static int hf_lat_src_node_status_node_is_disabled;
246 static int hf_lat_src_node_status_start_message_can_be_sent;
247 static int hf_lat_src_node_status_command_message_can_be_sent;
248 static int * const lat_src_node_status_fields[] = {
249 &hf_lat_src_node_status_node_is_disabled,
250 &hf_lat_src_node_status_start_message_can_be_sent,
251 &hf_lat_src_node_status_command_message_can_be_sent,
252 NULL
254 static int hf_lat_source_node_addr;
255 static int hf_lat_src_node_mc_timer;
256 static int hf_lat_src_node_desc;
257 static int hf_lat_srvc_count;
258 static int hf_lat_srvc_entry_len;
259 static int hf_lat_srvc_class_len;
260 static int hf_lat_srvc_class;
261 static int hf_lat_srvc_status;
262 static int hf_lat_srvc_status_enabled;
263 static int hf_lat_srvc_status_supports_queueing;
264 static int * const lat_srvc_status_fields[] = {
265 &hf_lat_srvc_status_enabled,
266 &hf_lat_srvc_status_supports_queueing,
267 NULL
269 static int hf_lat_srvc_rating;
270 static int hf_lat_srvc_group_len;
271 static int hf_lat_srvc_groups;
272 static int hf_lat_srvc_name;
273 static int hf_lat_srvc_desc;
275 static int hf_lat_service_name;
276 static int hf_lat_service_description;
277 static int hf_lat_unknown_command_data;
279 static int ett_lat;
280 static int ett_data_b_slot_control_flags;
281 static int ett_lat_attention_slot_control_flags;
282 static int ett_lat_command_modifier;
283 static int ett_lat_entry_status;
284 static int ett_lat_response_status;
285 static int ett_lat_src_node_status;
286 static int ett_lat_srvc_status;
288 static expert_field ei_slot_data_len_invalid;
289 static expert_field ei_entry_length_too_short;
290 static expert_field ei_srvc_entry_len_too_short;
291 static expert_field ei_mbz_data_nonzero;
293 /* LAT message types. */
294 #define LAT_MSG_TYP_RUN 0
295 #define LAT_MSG_TYP_START 1
296 #define LAT_MSG_TYP_STOP 2
297 #define LAT_MSG_TYP_SERVICE_ANNOUNCEMENT 10
298 #define LAT_MSG_TYP_COMMAND 12
299 #define LAT_MSG_TYP_STATUS 13
300 #define LAT_MSG_TYP_SOLICIT_INFORMATION 14
301 #define LAT_MSG_TYP_RESPONSE_INFORMATION 15
303 static const value_string msg_typ_vals[] = {
304 { LAT_MSG_TYP_RUN, "Run" },
305 { LAT_MSG_TYP_START, "Start" },
306 { LAT_MSG_TYP_STOP, "Stop" },
307 { LAT_MSG_TYP_SERVICE_ANNOUNCEMENT, "Service announcement" },
308 { LAT_MSG_TYP_COMMAND, "Command" },
309 { LAT_MSG_TYP_STATUS, "Status" },
310 { LAT_MSG_TYP_SOLICIT_INFORMATION, "Solicit information" },
311 { LAT_MSG_TYP_RESPONSE_INFORMATION, "Response information" },
312 { 0, NULL },
315 static void dissect_lat_run(tvbuff_t *tvb, int offset, proto_tree *tree,
316 packet_info *pinfo);
317 static void dissect_lat_start(tvbuff_t *tvb, int offset, proto_tree *tree);
318 static void dissect_lat_stop(tvbuff_t *tvb, int offset, proto_tree *tree);
319 static void dissect_lat_service_announcement(tvbuff_t *tvb, int offset,
320 proto_tree *tree);
321 static void dissect_lat_command(tvbuff_t *tvb, int offset, proto_tree *tree);
322 static void dissect_lat_status(tvbuff_t *tvb, int offset, proto_tree *tree,
323 packet_info *pinfo);
324 static void dissect_lat_solicit_information(tvbuff_t *tvb, int offset,
325 proto_tree *tree);
326 static void dissect_lat_response_information(tvbuff_t *tvb, int offset,
327 proto_tree *tree, packet_info *pinfo);
329 static int dissect_lat_string(tvbuff_t *tvb, int offset, int hf,
330 proto_tree *tree);
332 static unsigned dissect_lat_header(tvbuff_t *tvb, int offset, proto_tree *tree);
334 static void dissect_lat_slots(tvbuff_t *tvb, int offset, unsigned nbr_slots,
335 proto_tree *tree, packet_info *pinfo);
337 static int
338 dissect_lat(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
340 int offset = 0;
341 proto_item *ti;
342 proto_tree *lat_tree = NULL;
343 uint8_t command;
345 col_set_str(pinfo->cinfo, COL_PROTOCOL, "LAT");
346 col_clear(pinfo->cinfo, COL_INFO);
348 command = tvb_get_uint8(tvb, offset) >> 2;
350 col_add_str(pinfo->cinfo, COL_INFO,
351 val_to_str(command, msg_typ_vals, "Unknown command (%u)"));
353 if (tree) {
354 ti = proto_tree_add_item(tree, proto_lat, tvb, offset, -1,
355 ENC_NA);
356 lat_tree = proto_item_add_subtree(ti, ett_lat);
358 /* First byte of LAT header */
359 proto_tree_add_item(lat_tree, hf_lat_rrf, tvb, offset, 1,
360 ENC_LITTLE_ENDIAN);
361 proto_tree_add_item(lat_tree, hf_lat_master, tvb, offset, 1,
362 ENC_LITTLE_ENDIAN);
363 proto_tree_add_item(lat_tree, hf_lat_msg_typ, tvb, offset, 1,
364 ENC_LITTLE_ENDIAN);
365 offset += 1;
367 switch (command) {
369 case LAT_MSG_TYP_RUN:
370 dissect_lat_run(tvb, offset, lat_tree, pinfo);
371 break;
373 case LAT_MSG_TYP_START:
374 dissect_lat_start(tvb, offset, lat_tree);
375 break;
377 case LAT_MSG_TYP_STOP:
378 dissect_lat_stop(tvb, offset, lat_tree);
379 break;
381 case LAT_MSG_TYP_SERVICE_ANNOUNCEMENT:
382 dissect_lat_service_announcement(tvb, offset, lat_tree);
383 break;
385 case LAT_MSG_TYP_COMMAND:
386 dissect_lat_command(tvb, offset, lat_tree);
387 break;
389 case LAT_MSG_TYP_STATUS:
390 dissect_lat_status(tvb, offset, lat_tree, pinfo);
391 break;
393 case LAT_MSG_TYP_SOLICIT_INFORMATION:
394 dissect_lat_solicit_information(tvb, offset, lat_tree);
395 break;
397 case LAT_MSG_TYP_RESPONSE_INFORMATION:
398 dissect_lat_response_information(tvb, offset, lat_tree,
399 pinfo);
400 break;
402 default:
403 proto_tree_add_item(lat_tree, hf_lat_unknown_command_data,
404 tvb, offset, -1, ENC_NA);
405 break;
409 return tvb_captured_length(tvb);
413 * Virtual circuit message header.
415 static unsigned
416 dissect_lat_header(tvbuff_t *tvb, int offset, proto_tree *tree)
418 uint32_t nbr_slots;
420 proto_tree_add_item_ret_uint(tree, hf_lat_nbr_slots, tvb, offset, 1,
421 ENC_LITTLE_ENDIAN, &nbr_slots);
422 offset += 1;
424 proto_tree_add_item(tree, hf_lat_dst_cir_id, tvb, offset, 2, ENC_LITTLE_ENDIAN);
425 offset += 2;
427 proto_tree_add_item(tree, hf_lat_src_cir_id, tvb, offset, 2, ENC_LITTLE_ENDIAN);
428 offset += 2;
430 proto_tree_add_item(tree, hf_lat_msg_seq_nbr, tvb, offset, 1, ENC_LITTLE_ENDIAN);
431 offset += 1;
433 proto_tree_add_item(tree, hf_lat_msg_ack_nbr, tvb, offset, 1, ENC_LITTLE_ENDIAN);
434 /*offset += 1;*/
436 return nbr_slots;
439 static void
440 dissect_lat_start(tvbuff_t *tvb, int offset, proto_tree *tree)
442 uint8_t timer;
443 uint32_t param_code;
444 uint32_t param_len;
446 dissect_lat_header(tvb, offset, tree);
447 offset += 1 + 2 + 2 + 1 + 1;
448 proto_tree_add_item(tree, hf_lat_min_rcv_datagram_size, tvb, offset, 2, ENC_LITTLE_ENDIAN);
449 offset += 2;
450 proto_tree_add_item(tree, hf_lat_prtcl_ver, tvb, offset, 1, ENC_LITTLE_ENDIAN);
451 offset += 1;
452 proto_tree_add_item(tree, hf_lat_prtcl_eco, tvb, offset, 1, ENC_LITTLE_ENDIAN);
453 offset += 1;
454 proto_tree_add_item(tree, hf_lat_max_sim_slots, tvb, offset, 1, ENC_LITTLE_ENDIAN);
455 offset += 1;
456 proto_tree_add_item(tree, hf_lat_nbr_dl_bufs, tvb, offset, 1, ENC_LITTLE_ENDIAN);
457 offset += 1;
458 timer = tvb_get_uint8(tvb, offset);
459 proto_tree_add_uint_format_value(tree, hf_lat_server_circuit_timer, tvb,
460 offset, 1, timer, "%u milliseconds", timer*10);
461 offset += 1;
462 proto_tree_add_item(tree, hf_lat_keep_alive_timer, tvb, offset, 1, ENC_LITTLE_ENDIAN);
463 offset += 1;
464 proto_tree_add_item(tree, hf_lat_facility_number, tvb, offset, 2, ENC_LITTLE_ENDIAN);
465 offset += 2;
466 proto_tree_add_item(tree, hf_lat_prod_type_code, tvb, offset, 1, ENC_LITTLE_ENDIAN);
467 offset += 1;
468 proto_tree_add_item(tree, hf_lat_prod_vers_numb, tvb, offset, 1, ENC_LITTLE_ENDIAN);
469 offset += 1;
470 offset = dissect_lat_string(tvb, offset, hf_lat_slave_node_name, tree);
471 offset = dissect_lat_string(tvb, offset, hf_lat_master_node_name, tree);
472 offset = dissect_lat_string(tvb, offset, hf_lat_location_text, tree);
473 for (;;) {
474 proto_tree_add_item_ret_uint(tree, hf_lat_param_code, tvb, offset, 1, ENC_LITTLE_ENDIAN, &param_code);
475 offset += 1;
476 if (param_code == 0)
477 break;
478 proto_tree_add_item_ret_uint(tree, hf_lat_param_len, tvb, offset, 1, ENC_LITTLE_ENDIAN, &param_len);
479 offset += 1;
480 proto_tree_add_item(tree, hf_lat_param_data, tvb, offset, param_len, ENC_NA);
481 offset += param_len;
485 static void
486 dissect_lat_run(tvbuff_t *tvb, int offset, proto_tree *tree,
487 packet_info *pinfo)
489 uint8_t nbr_slots;
491 nbr_slots = dissect_lat_header(tvb, offset, tree);
492 offset += 1 + 2 + 2 + 1 + 1;
493 dissect_lat_slots(tvb, offset, nbr_slots, tree, pinfo);
497 * Slot types.
499 #define START_SLOT 9
500 #define DATA_A_SLOT 0
501 #define DATA_B_SLOT 10
502 #define ATTENTION_SLOT 11
503 #define REJECT_SLOT 12
504 #define STOP_SLOT 13
506 static const value_string slot_type_vals[] = {
507 { START_SLOT, "Start" },
508 { DATA_A_SLOT, "Data_a" },
509 { DATA_B_SLOT, "Data_b" },
510 { ATTENTION_SLOT, "Attention" },
511 { REJECT_SLOT, "Reject" },
512 { STOP_SLOT, "Stop" },
513 { 0, NULL }
516 static const value_string reason_code_vals[] = {
517 { 1, "reason is unknown" },
518 { 2, "user requested disconnect" },
519 { 3, "system shutdown in progress" },
520 { 4, "invalid slot received" },
521 { 5, "invalid service class" },
522 { 6, "insufficient resources to satisfy request" },
523 { 7, "service in use" },
524 { 8, "no such service" },
525 { 9, "service is disabled" },
526 { 10, "service is not offered by the requested port" },
527 { 11, "port name is unknown" },
528 { 12, "invalid password" },
529 { 13, "entry is not in the queue" },
530 { 14, "immediate access rejected" },
531 { 15, "access denied" },
532 { 16, "corrupted solicit request" },
533 { 0, NULL }
536 static int
537 dissect_lat_channel_char(proto_tree *tree, int hf, tvbuff_t *tvb, int offset)
539 uint8_t character;
541 character = tvb_get_uint8(tvb, offset);
542 if (g_ascii_isprint(character)) {
543 proto_tree_add_uint_format_value(tree, hf, tvb, offset, 1,
544 character, "'%c'", character);
545 } else if (character < 0x20) {
546 proto_tree_add_uint_format_value(tree, hf, tvb, offset, 1,
547 character, "^%c", character + 0x40);
548 } else {
549 proto_tree_add_uint_format_value(tree, hf, tvb, offset, 1,
550 character, "0x%02x", character);
552 offset++;
553 return offset;
556 #define CHECK_SLOT_DATA_BOUNDS(len) \
557 if (slot_byte_count < (len)) { \
558 expert_add_info(pinfo, length_ti, &ei_slot_data_len_invalid); \
559 goto end_slot; \
562 #define SERVICE_CLASS_TERMINAL 1
564 static const value_string service_class_vals[] = {
565 { 0, "Reserved" },
566 { SERVICE_CLASS_TERMINAL, "Application and interactive terminals" },
567 { 0, NULL }
570 static const value_string start_slot_class_1_param_code_vals[] = {
571 { 0, "End of parameters" },
572 { 1, "Flag word" },
573 { 2, "Identifier of the particular entry in the queue" },
574 { 3, "Reserved" },
575 { 4, "Destination node port name" },
576 { 5, "Source node port name" },
577 { 6, "Source service group codes" },
578 { 7, "Service password" },
579 { 0, NULL }
582 static int
583 dissect_lat_terminal_parameters(tvbuff_t *tvb, int offset,
584 uint32_t slot_byte_count, proto_item *length_ti, proto_tree *tree,
585 packet_info *pinfo)
587 uint32_t param_code;
588 uint32_t param_len;
589 int length_dissected = 0;
591 for (;;) {
592 CHECK_SLOT_DATA_BOUNDS(1);
593 proto_tree_add_item_ret_uint(tree, hf_lat_start_slot_class_1_param_code,
594 tvb, offset, 1, ENC_LITTLE_ENDIAN, &param_code);
595 offset += 1;
596 slot_byte_count -= 1;
597 length_dissected += 1;
598 if (param_code == 0)
599 break;
601 CHECK_SLOT_DATA_BOUNDS(1);
602 proto_tree_add_item_ret_uint(tree, hf_lat_param_len, tvb, offset, 1, ENC_LITTLE_ENDIAN, &param_len);
603 offset += 1;
604 slot_byte_count -= 1;
605 length_dissected += 1;
608 * XXX - dissect specific parameters as per A.6.1
609 * Start Slot Status Field
611 CHECK_SLOT_DATA_BOUNDS(param_len);
612 proto_tree_add_item(tree, hf_lat_param_data, tvb, offset, param_len, ENC_NA);
613 offset += param_len;
614 slot_byte_count -= param_len;
615 length_dissected += param_len;
618 end_slot:
619 return length_dissected;
622 static void
623 dissect_lat_slots(tvbuff_t *tvb, int offset, unsigned nbr_slots, proto_tree *tree,
624 packet_info *pinfo)
626 unsigned i;
627 proto_item *length_ti;
628 uint32_t slot_byte_count;
629 uint32_t slot_type_byte;
630 int slot_padding;
631 uint32_t start_slot_service_class;
632 uint32_t name_len;
633 int length_dissected;
634 uint32_t param_code;
635 uint32_t param_len;
636 uint32_t mbz;
637 proto_item *mbz_ti;
639 for (i = 0; i < nbr_slots; i++) {
640 proto_tree_add_item(tree, hf_lat_slot_dst_slot_id,
641 tvb, offset, 1, ENC_LITTLE_ENDIAN);
642 offset += 1;
644 proto_tree_add_item(tree, hf_lat_slot_src_slot_id,
645 tvb, offset, 1, ENC_LITTLE_ENDIAN);
646 offset += 1;
648 length_ti = proto_tree_add_item_ret_uint(tree, hf_lat_slot_byte_count, tvb,
649 offset, 1, ENC_LITTLE_ENDIAN, &slot_byte_count);
650 offset += 1;
651 slot_padding = slot_byte_count & 1;
653 slot_type_byte = tvb_get_uint8(tvb, offset);
654 switch (slot_type_byte >> 4) {
656 case START_SLOT:
657 proto_tree_add_item(tree, hf_lat_slot_credits, tvb,
658 offset, 1, ENC_LITTLE_ENDIAN);
659 proto_tree_add_item(tree, hf_lat_slot_type, tvb,
660 offset, 1, ENC_LITTLE_ENDIAN);
661 offset += 1;
663 CHECK_SLOT_DATA_BOUNDS(1);
664 proto_tree_add_item_ret_uint(tree, hf_lat_start_slot_service_class,
665 tvb, offset, 1, ENC_LITTLE_ENDIAN,
666 &start_slot_service_class);
667 offset += 1;
668 slot_byte_count -= 1;
670 CHECK_SLOT_DATA_BOUNDS(1);
671 proto_tree_add_item(tree, hf_lat_start_slot_minimum_attention_slot_size,
672 tvb, offset, 1, ENC_LITTLE_ENDIAN);
673 offset += 1;
674 slot_byte_count -= 1;
676 CHECK_SLOT_DATA_BOUNDS(1);
677 proto_tree_add_item(tree, hf_lat_start_slot_minimum_data_slot_size,
678 tvb, offset, 1, ENC_LITTLE_ENDIAN);
679 offset += 1;
680 slot_byte_count -= 1;
682 CHECK_SLOT_DATA_BOUNDS(1);
683 name_len = tvb_get_uint8(tvb, offset);
684 CHECK_SLOT_DATA_BOUNDS(1 + name_len);
685 proto_tree_add_item(tree, hf_lat_start_slot_obj_srvc,
686 tvb, offset, 1, ENC_ASCII|ENC_LITTLE_ENDIAN);
687 offset += 1 + name_len;
688 slot_byte_count -= 1 + name_len;
690 CHECK_SLOT_DATA_BOUNDS(1);
691 name_len = tvb_get_uint8(tvb, offset);
692 CHECK_SLOT_DATA_BOUNDS(1 + name_len);
693 proto_tree_add_item(tree, hf_lat_start_slot_subj_dscr,
694 tvb, offset, 1, ENC_ASCII|ENC_LITTLE_ENDIAN);
695 offset += 1 + name_len;
696 slot_byte_count -= 1 + name_len;
698 if (slot_byte_count != 0) {
699 switch (start_slot_service_class) {
701 case SERVICE_CLASS_TERMINAL:
702 length_dissected =
703 dissect_lat_terminal_parameters(tvb,
704 offset, slot_byte_count,
705 length_ti, tree, pinfo);
706 offset += length_dissected;
707 slot_byte_count -= length_dissected;
708 break;
710 default:
711 break;
714 if (slot_byte_count != 0) {
715 proto_tree_add_item(tree, hf_lat_status_remaining,
716 tvb, offset, slot_byte_count, ENC_NA);
717 offset += slot_byte_count;
720 break;
722 case DATA_A_SLOT:
723 proto_tree_add_item(tree, hf_lat_slot_credits, tvb,
724 offset, 1, ENC_LITTLE_ENDIAN);
725 proto_tree_add_item(tree, hf_lat_slot_type, tvb,
726 offset, 1, ENC_LITTLE_ENDIAN);
727 offset += 1;
729 if (slot_byte_count != 0) {
730 proto_tree_add_item(tree, hf_lat_slot_data,
731 tvb, offset, slot_byte_count, ENC_NA);
732 offset += slot_byte_count;
734 break;
736 case DATA_B_SLOT:
737 proto_tree_add_item(tree, hf_lat_slot_credits, tvb,
738 offset, 1, ENC_LITTLE_ENDIAN);
739 proto_tree_add_item(tree, hf_lat_slot_type, tvb,
740 offset, 1, ENC_LITTLE_ENDIAN);
741 offset += 1;
743 if (slot_byte_count == 0)
744 break;
747 * XXX - this is only for service class 1, and
748 * we don't know the service class here, but
749 * are there any other service classes used
750 * in practice?
752 proto_tree_add_bitmask(tree, tvb, offset,
753 hf_lat_data_b_slot_control_flags,
754 ett_data_b_slot_control_flags,
755 data_b_slot_control_flags_fields,
756 ENC_LITTLE_ENDIAN);
757 offset += 1;
758 slot_byte_count -= 1;
760 CHECK_SLOT_DATA_BOUNDS(1);
761 offset = dissect_lat_channel_char(tree,
762 hf_lat_data_b_slot_stop_output_channel_char,
763 tvb, offset);
764 slot_byte_count -= 1;
766 CHECK_SLOT_DATA_BOUNDS(1);
767 offset = dissect_lat_channel_char(tree,
768 hf_lat_data_b_slot_start_output_channel_char,
769 tvb, offset);
770 slot_byte_count -= 1;
772 CHECK_SLOT_DATA_BOUNDS(1);
773 offset = dissect_lat_channel_char(tree,
774 hf_lat_data_b_slot_stop_input_channel_char,
775 tvb, offset);
776 slot_byte_count -= 1;
778 CHECK_SLOT_DATA_BOUNDS(1);
779 offset = dissect_lat_channel_char(tree,
780 hf_lat_data_b_slot_start_input_channel_char,
781 tvb, offset);
782 slot_byte_count -= 1;
784 for (;;) {
785 CHECK_SLOT_DATA_BOUNDS(1);
786 proto_tree_add_item_ret_uint(tree,
787 hf_lat_data_b_slot_param_code, tvb, offset, 1, ENC_LITTLE_ENDIAN, &param_code);
788 offset += 1;
789 slot_byte_count -= 1;
790 if (param_code == 0)
791 break;
793 CHECK_SLOT_DATA_BOUNDS(1);
794 proto_tree_add_item_ret_uint(tree, hf_lat_param_len, tvb, offset, 1, ENC_LITTLE_ENDIAN, &param_len);
795 offset += 1;
796 slot_byte_count -= 1;
798 CHECK_SLOT_DATA_BOUNDS(param_len);
799 proto_tree_add_item(tree, hf_lat_param_data, tvb, offset, param_len, ENC_NA);
800 offset += param_len;
801 slot_byte_count -= param_len;
804 if (slot_byte_count != 0) {
805 proto_tree_add_item(tree, hf_lat_slot_data_remaining,
806 tvb, offset, slot_byte_count, ENC_NA);
807 offset += slot_byte_count;
809 break;
811 case ATTENTION_SLOT:
812 mbz_ti = proto_tree_add_item_ret_uint(tree, hf_lat_mbz, tvb,
813 offset, 1, ENC_LITTLE_ENDIAN, &mbz);
814 if (mbz != 0) {
815 expert_add_info(pinfo, mbz_ti,
816 &ei_mbz_data_nonzero);
818 proto_tree_add_item(tree, hf_lat_slot_type, tvb,
819 offset, 1, ENC_LITTLE_ENDIAN);
820 offset += 1;
823 * XXX - this is only for service class 1, and
824 * we don't know the service class here, but
825 * are there any other service classes used
826 * in practice?
828 if (slot_byte_count >= 1) {
829 proto_tree_add_bitmask(tree, tvb, offset,
830 hf_lat_attention_slot_control_flags,
831 ett_lat_attention_slot_control_flags,
832 attention_slot_control_flags_fields,
833 ENC_LITTLE_ENDIAN);
834 offset += 1;
835 slot_byte_count -= 1;
838 if (slot_byte_count != 0) {
839 proto_tree_add_item(tree, hf_lat_slot_data_remaining,
840 tvb, offset, slot_byte_count, ENC_NA);
841 offset += slot_byte_count;
843 break;
845 case REJECT_SLOT:
846 case STOP_SLOT:
847 proto_tree_add_item(tree, hf_lat_reason, tvb,
848 offset, 1, ENC_LITTLE_ENDIAN);
849 proto_tree_add_item(tree, hf_lat_slot_type, tvb,
850 offset, 1, ENC_LITTLE_ENDIAN);
851 offset += 1;
853 if (slot_byte_count != 0) {
854 proto_tree_add_item(tree, hf_lat_slot_data,
855 tvb, offset, slot_byte_count, ENC_NA);
856 offset += slot_byte_count;
858 break;
860 default:
861 proto_tree_add_item(tree, hf_lat_slot_type, tvb,
862 offset, 1, ENC_LITTLE_ENDIAN);
863 offset += 1;
865 if (slot_byte_count != 0) {
866 proto_tree_add_item(tree, hf_lat_slot_data,
867 tvb, offset, slot_byte_count, ENC_NA);
868 offset += slot_byte_count;
870 break;
873 end_slot:
874 /* Padding */
875 offset += slot_padding;
879 static const value_string circuit_disconnect_reason_code_vals[] = {
880 { 1, "reason is unknown" },
881 { 2, "No slots connected on virtual circuit" },
882 { 3, "Illegal message or slot format received" },
883 { 4, "VC_halt from user" },
884 { 5, "No progress is being made" },
885 { 6, "Time limit expired" },
886 { 7, "LAT_MESSAGE_RETRANSMIT_LIMIT reached" },
887 { 8, "Insufficient resources to satisfy request" },
888 { 9, "SERVER_CIRCUIT_TIMER out of desired range" },
889 { 10, "Number of virtual circuits is exceeded" },
890 { 0, NULL }
893 static void
894 dissect_lat_stop(tvbuff_t *tvb, int offset, proto_tree *tree)
896 dissect_lat_header(tvb, offset, tree);
897 offset += 1 + 2 + 2 + 1 + 1;
899 proto_tree_add_item(tree, hf_lat_circuit_disconnect_reason, tvb,
900 offset, 1, ENC_LITTLE_ENDIAN);
901 offset += 1;
902 proto_tree_add_item(tree, hf_lat_reason_text, tvb, offset, 1,
903 ENC_ASCII|ENC_LITTLE_ENDIAN);
906 static const value_string node_status_vals[] = {
907 { 2, "Accepting connections" },
908 { 3, "Not accepting connections" },
909 { 0, NULL },
912 static void
913 dissect_lat_service_announcement(tvbuff_t *tvb, int offset, proto_tree *tree)
915 uint8_t timer;
916 uint32_t node_group_len;
917 uint32_t service_name_count;
918 uint32_t node_service_len;
919 unsigned i;
921 timer = tvb_get_uint8(tvb, offset);
922 proto_tree_add_uint_format_value(tree, hf_lat_server_circuit_timer, tvb,
923 offset, 1, timer, "%u milliseconds", timer*10);
924 offset += 1;
926 proto_tree_add_item(tree, hf_lat_high_prtcl_ver, tvb, offset, 1, ENC_LITTLE_ENDIAN);
927 offset += 1;
929 proto_tree_add_item(tree, hf_lat_low_prtcl_ver, tvb, offset, 1, ENC_LITTLE_ENDIAN);
930 offset += 1;
932 proto_tree_add_item(tree, hf_lat_cur_prtcl_ver, tvb, offset, 1, ENC_LITTLE_ENDIAN);
933 offset += 1;
935 proto_tree_add_item(tree, hf_lat_cur_prtcl_eco, tvb, offset, 1, ENC_LITTLE_ENDIAN);
936 offset += 1;
938 proto_tree_add_item(tree, hf_lat_msg_inc, tvb, offset, 1, ENC_LITTLE_ENDIAN);
939 offset += 1;
941 proto_tree_add_item(tree, hf_lat_change_flags, tvb, offset, 1, ENC_LITTLE_ENDIAN);
942 offset += 1;
944 proto_tree_add_item(tree, hf_lat_data_link_rcv_frame_size, tvb, offset, 2, ENC_LITTLE_ENDIAN);
945 offset += 2;
947 timer = tvb_get_uint8(tvb, offset);
948 proto_tree_add_uint_format(tree, hf_lat_node_multicast_timer, tvb,
949 offset, 1, timer, "Multicast timer: %u seconds", timer);
950 offset += 1;
952 proto_tree_add_item(tree, hf_lat_node_status, tvb, offset, 1, ENC_LITTLE_ENDIAN);
953 offset += 1;
955 proto_tree_add_item_ret_uint(tree, hf_lat_node_group_len,
956 tvb, offset, 1, ENC_LITTLE_ENDIAN, &node_group_len);
957 offset += 1;
959 /* This is a bitmask */
960 proto_tree_add_item(tree, hf_lat_node_groups, tvb, offset, node_group_len, ENC_NA);
961 offset += node_group_len;
963 offset = dissect_lat_string(tvb, offset, hf_lat_node_name, tree);
965 offset = dissect_lat_string(tvb, offset, hf_lat_node_description, tree);
967 proto_tree_add_item_ret_uint(tree, hf_lat_service_name_count,
968 tvb, offset, 1, ENC_LITTLE_ENDIAN, &service_name_count);
969 offset += 1;
971 for (i = 0; i < service_name_count; i++) {
972 proto_tree_add_item(tree, hf_lat_service_rating, tvb,
973 offset, 1, ENC_LITTLE_ENDIAN);
974 offset += 1;
975 offset = dissect_lat_string(tvb, offset, hf_lat_service_name,
976 tree);
977 offset = dissect_lat_string(tvb, offset, hf_lat_service_description,
978 tree);
981 proto_tree_add_item_ret_uint(tree, hf_lat_node_service_len,
982 tvb, offset, 1, ENC_LITTLE_ENDIAN, &node_service_len);
983 offset += 1;
985 for (i = 0; i < node_service_len; i++) {
986 proto_tree_add_item(tree, hf_lat_node_service_class,
987 tvb, offset, 1, ENC_LITTLE_ENDIAN);
991 static void
992 dissect_lat_command(tvbuff_t *tvb, int offset, proto_tree *tree)
994 uint32_t subj_group_len;
995 uint32_t param_code;
996 uint32_t param_len;
998 proto_tree_add_item(tree, hf_lat_prtcl_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
999 offset += 1;
1001 proto_tree_add_item(tree, hf_lat_high_prtcl_ver, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1002 offset += 1;
1004 proto_tree_add_item(tree, hf_lat_low_prtcl_ver, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1005 offset += 1;
1007 proto_tree_add_item(tree, hf_lat_cur_prtcl_ver, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1008 offset += 1;
1010 proto_tree_add_item(tree, hf_lat_cur_prtcl_eco, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1011 offset += 1;
1013 proto_tree_add_item(tree, hf_lat_data_link_rcv_frame_size, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1014 offset += 2;
1016 proto_tree_add_item(tree, hf_lat_request_identifier, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1017 offset += 2;
1019 proto_tree_add_item(tree, hf_lat_entry_identifier, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1020 offset += 2;
1022 proto_tree_add_item(tree, hf_lat_command_type, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1023 offset += 1;
1025 proto_tree_add_bitmask(tree, tvb, offset, hf_lat_command_modifier,
1026 ett_lat_command_modifier, lat_command_modifier_fields,
1027 ENC_LITTLE_ENDIAN);
1028 offset += 1;
1030 offset = dissect_lat_string(tvb, offset, hf_lat_obj_node_name, tree);
1032 proto_tree_add_item_ret_uint(tree, hf_lat_subj_group_len,
1033 tvb, offset, 1, ENC_LITTLE_ENDIAN, &subj_group_len);
1034 offset += 1;
1036 /* This is a bitmask */
1037 proto_tree_add_item(tree, hf_lat_subj_group, tvb, offset, subj_group_len, ENC_NA);
1038 offset += subj_group_len;
1040 offset = dissect_lat_string(tvb, offset, hf_lat_subj_node_name, tree);
1042 offset = dissect_lat_string(tvb, offset, hf_lat_subj_port_name, tree);
1044 offset = dissect_lat_string(tvb, offset, hf_lat_subj_description, tree);
1046 offset = dissect_lat_string(tvb, offset, hf_lat_obj_srvc_name, tree);
1048 offset = dissect_lat_string(tvb, offset, hf_lat_obj_port_name, tree);
1050 for (;;) {
1051 proto_tree_add_item_ret_uint(tree, hf_lat_param_code, tvb, offset, 1, ENC_LITTLE_ENDIAN, &param_code);
1052 offset += 1;
1053 if (param_code == 0)
1054 break;
1055 proto_tree_add_item_ret_uint(tree, hf_lat_param_len, tvb, offset, 1, ENC_LITTLE_ENDIAN, &param_len);
1056 offset += 1;
1057 proto_tree_add_item(tree, hf_lat_param_data, tvb, offset, param_len, ENC_NA);
1058 offset += param_len;
1062 static void
1063 dissect_lat_status(tvbuff_t *tvb, int offset, proto_tree *tree,
1064 packet_info *pinfo)
1066 uint32_t entries_counter;
1067 uint32_t subj_node_name_len;
1068 unsigned i;
1070 proto_tree_add_item(tree, hf_lat_prtcl_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1071 offset += 1;
1073 proto_tree_add_item(tree, hf_lat_high_prtcl_ver, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1074 offset += 1;
1076 proto_tree_add_item(tree, hf_lat_low_prtcl_ver, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1077 offset += 1;
1079 proto_tree_add_item(tree, hf_lat_cur_prtcl_ver, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1080 offset += 1;
1082 proto_tree_add_item(tree, hf_lat_cur_prtcl_eco, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1083 offset += 1;
1085 proto_tree_add_item(tree, hf_lat_data_link_rcv_frame_size, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1086 offset += 2;
1088 proto_tree_add_item(tree, hf_lat_status_retransmit_timer, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1089 offset += 2;
1091 proto_tree_add_item_ret_uint(tree, hf_lat_entries_counter, tvb, offset, 1,
1092 ENC_LITTLE_ENDIAN, &entries_counter);
1093 offset += 1;
1095 proto_tree_add_item_ret_length(tree, hf_lat_subj_node_name, tvb, offset, 1,
1096 ENC_LITTLE_ENDIAN, &subj_node_name_len);
1097 offset += subj_node_name_len;
1098 if (!(subj_node_name_len & 0x01)) {
1100 * This length includes the length of the length field,
1101 * which is 1 byte; if it's *even*, we need to pad.
1103 offset++;
1106 for (i = 0; i < entries_counter; i++) {
1107 proto_item *entry_length_ti;
1108 uint32_t entry_length;
1109 unsigned entry_padding;
1110 uint64_t entry_status;
1111 proto_item *mbz_ti;
1112 uint32_t mbz;
1113 unsigned name_len;
1115 entry_length_ti = proto_tree_add_item_ret_uint(tree, hf_lat_entry_length, tvb, offset, 1,
1116 ENC_LITTLE_ENDIAN, &entry_length);
1117 offset += 1;
1118 entry_padding = (entry_length + 1) & 1;
1120 if (entry_length == 0) {
1121 expert_add_info(pinfo, entry_length_ti, &ei_entry_length_too_short);
1122 goto end_entry;
1124 proto_tree_add_bitmask_ret_uint64(tree, tvb, offset, hf_lat_entry_status,
1125 ett_lat_entry_status, lat_entry_status_fields,
1126 ENC_LITTLE_ENDIAN, &entry_status);
1127 offset += 1;
1128 entry_length -= 1;
1130 if (entry_length == 0) {
1131 expert_add_info(pinfo, entry_length_ti, &ei_entry_length_too_short);
1132 goto end_entry;
1134 if (entry_status & ENTRY_STATUS_REJECTED) {
1135 proto_tree_add_item(tree, hf_lat_entry_error, tvb, offset, 1,
1136 ENC_LITTLE_ENDIAN);
1137 } else {
1138 /* No status, must be zero */
1139 mbz_ti = proto_tree_add_item_ret_uint(tree, hf_lat_mbz, tvb, offset, 1,
1140 ENC_LITTLE_ENDIAN, &mbz);
1141 if (mbz != 0)
1142 expert_add_info(pinfo, mbz_ti, &ei_entry_length_too_short);
1144 offset += 1;
1145 entry_length -= 1;
1147 if (entry_length == 0) {
1148 expert_add_info(pinfo, entry_length_ti, &ei_entry_length_too_short);
1149 goto end_entry;
1151 /* Reserved, MBZ - do MBZ checks */
1152 offset += 1;
1153 entry_length -= 1;
1155 if (entry_length < 2) {
1156 expert_add_info(pinfo, entry_length_ti, &ei_entry_length_too_short);
1157 goto end_entry;
1159 proto_tree_add_item(tree, hf_lat_request_identifier, tvb, offset, 2,
1160 ENC_LITTLE_ENDIAN);
1161 offset += 2;
1162 entry_length -= 2;
1164 if (entry_length < 2) {
1165 expert_add_info(pinfo, entry_length_ti, &ei_entry_length_too_short);
1166 goto end_entry;
1168 proto_tree_add_item(tree, hf_lat_entry_identifier, tvb, offset, 2,
1169 ENC_LITTLE_ENDIAN);
1170 offset += 2;
1171 entry_length -= 2;
1173 if (entry_length < 2) {
1174 expert_add_info(pinfo, entry_length_ti, &ei_entry_length_too_short);
1175 goto end_entry;
1177 proto_tree_add_item(tree, hf_lat_elapsed_queue_time, tvb, offset, 2,
1178 ENC_LITTLE_ENDIAN);
1179 offset += 2;
1180 entry_length -= 2;
1182 if (entry_length < 2) {
1183 expert_add_info(pinfo, entry_length_ti, &ei_entry_length_too_short);
1184 goto end_entry;
1186 proto_tree_add_item(tree, hf_lat_min_queue_position, tvb, offset, 2,
1187 ENC_LITTLE_ENDIAN);
1188 offset += 2;
1189 entry_length -= 2;
1191 if (entry_length < 2) {
1192 expert_add_info(pinfo, entry_length_ti, &ei_entry_length_too_short);
1193 goto end_entry;
1195 proto_tree_add_item(tree, hf_lat_max_queue_position, tvb, offset, 2,
1196 ENC_LITTLE_ENDIAN);
1197 offset += 2;
1198 entry_length -= 2;
1200 if (entry_length == 0) {
1201 expert_add_info(pinfo, entry_length_ti, &ei_entry_length_too_short);
1202 goto end_entry;
1204 name_len = tvb_get_uint8(tvb, offset);
1205 if (entry_length < 1 + name_len) {
1206 expert_add_info(pinfo, entry_length_ti, &ei_entry_length_too_short);
1207 offset += entry_length;
1208 goto end_entry;
1210 proto_tree_add_item(tree, hf_lat_obj_srvc_name,
1211 tvb, offset, 1, ENC_ASCII|ENC_LITTLE_ENDIAN);
1212 offset += 1 + name_len;
1213 entry_length -= 1 + name_len;
1215 if (entry_length == 0) {
1216 expert_add_info(pinfo, entry_length_ti, &ei_entry_length_too_short);
1217 goto end_entry;
1219 name_len = tvb_get_uint8(tvb, offset);
1220 if (entry_length < 1 + name_len) {
1221 expert_add_info(pinfo, entry_length_ti, &ei_entry_length_too_short);
1222 offset += entry_length;
1223 goto end_entry;
1225 proto_tree_add_item(tree, hf_lat_obj_port_name,
1226 tvb, offset, 1, ENC_ASCII|ENC_LITTLE_ENDIAN);
1227 offset += 1 + name_len;
1228 entry_length -= 1 + name_len;
1230 if (entry_length == 0) {
1231 expert_add_info(pinfo, entry_length_ti, &ei_entry_length_too_short);
1232 goto end_entry;
1234 name_len = tvb_get_uint8(tvb, offset);
1235 if (entry_length < 1 + name_len) {
1236 expert_add_info(pinfo, entry_length_ti, &ei_entry_length_too_short);
1237 offset += entry_length;
1238 goto end_entry;
1240 proto_tree_add_item(tree, hf_lat_subj_description,
1241 tvb, offset, 1, ENC_ASCII|ENC_LITTLE_ENDIAN);
1242 offset += 1 + name_len;
1243 entry_length -= 1 + name_len;
1245 end_entry:
1246 /* Padding */
1247 offset += entry_padding;
1249 for (;;) {
1250 uint32_t param_code;
1251 uint32_t param_len;
1253 proto_tree_add_item_ret_uint(tree, hf_lat_param_code, tvb, offset, 1, ENC_LITTLE_ENDIAN, &param_code);
1254 offset += 1;
1255 if (param_code == 0)
1256 break;
1257 proto_tree_add_item_ret_uint(tree, hf_lat_param_len, tvb, offset, 1, ENC_LITTLE_ENDIAN, &param_len);
1258 offset += 1;
1259 proto_tree_add_item(tree, hf_lat_param_data, tvb, offset, param_len, ENC_NA);
1260 offset += param_len;
1264 static void
1265 dissect_lat_solicit_information(tvbuff_t *tvb, int offset, proto_tree *tree)
1267 uint32_t src_node_group_len;
1269 proto_tree_add_item(tree, hf_lat_prtcl_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1270 offset += 1;
1272 proto_tree_add_item(tree, hf_lat_high_prtcl_ver, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1273 offset += 1;
1275 proto_tree_add_item(tree, hf_lat_low_prtcl_ver, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1276 offset += 1;
1278 proto_tree_add_item(tree, hf_lat_cur_prtcl_ver, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1279 offset += 1;
1281 proto_tree_add_item(tree, hf_lat_cur_prtcl_eco, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1282 offset += 1;
1284 proto_tree_add_item(tree, hf_lat_data_link_rcv_frame_size, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1285 offset += 2;
1287 proto_tree_add_item(tree, hf_lat_solicit_identifier, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1288 offset += 2;
1290 proto_tree_add_item(tree, hf_lat_response_timer, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1291 offset += 2;
1293 offset = dissect_lat_string(tvb, offset, hf_lat_dst_node_name, tree);
1295 proto_tree_add_item_ret_uint(tree, hf_lat_src_node_group_len, tvb, offset, 1,
1296 ENC_LITTLE_ENDIAN, &src_node_group_len);
1297 offset += 1;
1299 /* This is a bitmask */
1300 proto_tree_add_item(tree, hf_lat_src_node_groups, tvb, offset, src_node_group_len, ENC_NA);
1301 offset += src_node_group_len;
1303 offset = dissect_lat_string(tvb, offset, hf_lat_src_node_name, tree);
1305 offset = dissect_lat_string(tvb, offset, hf_lat_dst_srvc_name, tree);
1307 for (;;) {
1308 uint32_t param_code;
1309 uint32_t param_len;
1311 proto_tree_add_item_ret_uint(tree, hf_lat_param_code, tvb, offset, 1, ENC_LITTLE_ENDIAN, &param_code);
1312 offset += 1;
1313 if (param_code == 0)
1314 break;
1315 proto_tree_add_item_ret_uint(tree, hf_lat_param_len, tvb, offset, 1, ENC_LITTLE_ENDIAN, &param_len);
1316 offset += 1;
1317 proto_tree_add_item(tree, hf_lat_param_data, tvb, offset, param_len, ENC_NA);
1318 offset += param_len;
1322 static void
1323 dissect_lat_response_information(tvbuff_t *tvb, int offset, proto_tree *tree,
1324 packet_info *pinfo)
1326 uint32_t srvc_count;
1327 uint32_t src_node_group_len;
1328 unsigned i;
1330 proto_tree_add_item(tree, hf_lat_prtcl_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1331 offset += 1;
1333 proto_tree_add_item(tree, hf_lat_high_prtcl_ver, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1334 offset += 1;
1336 proto_tree_add_item(tree, hf_lat_low_prtcl_ver, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1337 offset += 1;
1339 proto_tree_add_item(tree, hf_lat_cur_prtcl_ver, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1340 offset += 1;
1342 proto_tree_add_item(tree, hf_lat_cur_prtcl_eco, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1343 offset += 1;
1345 proto_tree_add_item(tree, hf_lat_data_link_rcv_frame_size, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1346 offset += 2;
1348 proto_tree_add_item(tree, hf_lat_solicit_identifier, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1349 offset += 2;
1351 proto_tree_add_bitmask(tree, tvb, offset, hf_lat_response_status,
1352 ett_lat_response_status, lat_response_status_fields,
1353 ENC_LITTLE_ENDIAN);
1354 offset += 2;
1356 proto_tree_add_bitmask(tree, tvb, offset, hf_lat_src_node_status,
1357 ett_lat_src_node_status, lat_src_node_status_fields,
1358 ENC_LITTLE_ENDIAN);
1359 offset += 2;
1361 proto_tree_add_item(tree, hf_lat_source_node_addr, tvb, offset, 6, ENC_NA);
1362 offset += 6;
1364 proto_tree_add_item(tree, hf_lat_src_node_mc_timer, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1365 offset += 2;
1367 offset = dissect_lat_string(tvb, offset, hf_lat_dst_node_name, tree);
1369 proto_tree_add_item_ret_uint(tree, hf_lat_src_node_group_len, tvb, offset, 1,
1370 ENC_LITTLE_ENDIAN, &src_node_group_len);
1371 offset += 1;
1373 /* This is a bitmask */
1374 proto_tree_add_item(tree, hf_lat_src_node_groups, tvb, offset, src_node_group_len, ENC_NA);
1375 offset += src_node_group_len;
1377 offset = dissect_lat_string(tvb, offset, hf_lat_src_node_name, tree);
1379 offset = dissect_lat_string(tvb, offset, hf_lat_src_node_desc, tree);
1381 proto_tree_add_item_ret_uint(tree, hf_lat_srvc_count, tvb, offset, 1,
1382 ENC_LITTLE_ENDIAN, &srvc_count);
1384 for (i = 0; i < srvc_count; i++) {
1385 proto_item *srvc_entry_len_ti;
1386 uint32_t srvc_entry_len;
1387 uint32_t srvc_class_len;
1388 unsigned j;
1389 uint32_t srvc_group_len;
1390 unsigned string_len;
1392 srvc_entry_len_ti = proto_tree_add_item_ret_uint(tree, hf_lat_srvc_entry_len,
1393 tvb, offset, 1, ENC_LITTLE_ENDIAN, &srvc_entry_len);
1394 offset += 1;
1396 if (srvc_entry_len == 0) {
1397 expert_add_info(pinfo, srvc_entry_len_ti, &ei_srvc_entry_len_too_short);
1398 goto end_entry;
1400 proto_tree_add_item_ret_uint(tree, hf_lat_srvc_class_len,
1401 tvb, offset, 1, ENC_LITTLE_ENDIAN, &srvc_class_len);
1402 offset += 1;
1403 srvc_entry_len -= 1;
1405 for (j = 0; j < srvc_class_len; j++) {
1406 if (srvc_entry_len == 0) {
1407 expert_add_info(pinfo, srvc_entry_len_ti, &ei_srvc_entry_len_too_short);
1408 goto end_entry;
1410 proto_tree_add_item(tree, hf_lat_srvc_class,
1411 tvb, offset, 1, ENC_LITTLE_ENDIAN);
1412 offset++;
1413 srvc_entry_len -= 1;
1416 if (srvc_entry_len == 0) {
1417 expert_add_info(pinfo, srvc_entry_len_ti, &ei_srvc_entry_len_too_short);
1418 goto end_entry;
1420 proto_tree_add_bitmask(tree, tvb, offset, hf_lat_srvc_status,
1421 ett_lat_srvc_status, lat_srvc_status_fields,
1422 ENC_LITTLE_ENDIAN);
1423 offset += 1;
1424 srvc_entry_len -= 1;
1426 if (srvc_entry_len == 0) {
1427 expert_add_info(pinfo, srvc_entry_len_ti, &ei_srvc_entry_len_too_short);
1428 goto end_entry;
1430 proto_tree_add_item(tree, hf_lat_srvc_rating,
1431 tvb, offset, 1, ENC_LITTLE_ENDIAN);
1432 offset += 1;
1433 srvc_entry_len -= 1;
1435 if (srvc_entry_len == 0) {
1436 expert_add_info(pinfo, srvc_entry_len_ti, &ei_srvc_entry_len_too_short);
1437 goto end_entry;
1439 proto_tree_add_item_ret_uint(tree, hf_lat_srvc_group_len,
1440 tvb, offset, 1, ENC_LITTLE_ENDIAN, &srvc_group_len);
1441 offset += 1;
1442 srvc_entry_len -= 1;
1444 /* This is a bitmask */
1445 if (srvc_entry_len < srvc_group_len) {
1446 expert_add_info(pinfo, srvc_entry_len_ti, &ei_srvc_entry_len_too_short);
1447 goto end_entry;
1449 proto_tree_add_item(tree, hf_lat_srvc_groups, tvb, offset, srvc_group_len, ENC_NA);
1450 offset += srvc_group_len;
1451 srvc_entry_len -= srvc_group_len;
1453 if (srvc_entry_len == 0) {
1454 expert_add_info(pinfo, srvc_entry_len_ti, &ei_srvc_entry_len_too_short);
1455 goto end_entry;
1457 string_len = tvb_get_uint8(tvb, offset);
1458 if (srvc_entry_len < 1 + string_len) {
1459 expert_add_info(pinfo, srvc_entry_len_ti, &ei_srvc_entry_len_too_short);
1460 offset += srvc_entry_len;
1461 goto end_entry;
1463 proto_tree_add_item(tree, hf_lat_srvc_name,
1464 tvb, offset, 1, ENC_ASCII|ENC_LITTLE_ENDIAN);
1465 offset += 1 + string_len;
1466 srvc_entry_len -= 1 + string_len;
1468 if (srvc_entry_len == 0) {
1469 expert_add_info(pinfo, srvc_entry_len_ti, &ei_srvc_entry_len_too_short);
1470 goto end_entry;
1472 string_len = tvb_get_uint8(tvb, offset);
1473 if (srvc_entry_len < 1 + string_len) {
1474 expert_add_info(pinfo, srvc_entry_len_ti, &ei_srvc_entry_len_too_short);
1475 offset += srvc_entry_len;
1476 goto end_entry;
1478 proto_tree_add_item(tree, hf_lat_srvc_desc,
1479 tvb, offset, 1, ENC_ASCII|ENC_LITTLE_ENDIAN);
1480 offset += 1 + string_len;
1481 srvc_entry_len -= 1 + string_len;
1483 end_entry:
1484 /* There shouldn't be padding, but if there is... */
1485 offset += srvc_entry_len;
1488 for (;;) {
1489 uint32_t param_code;
1490 uint32_t param_len;
1492 proto_tree_add_item_ret_uint(tree, hf_lat_param_code, tvb, offset, 1, ENC_LITTLE_ENDIAN, &param_code);
1493 offset += 1;
1494 if (param_code == 0)
1495 break;
1496 proto_tree_add_item_ret_uint(tree, hf_lat_param_len, tvb, offset, 1, ENC_LITTLE_ENDIAN, &param_len);
1497 offset += 1;
1498 proto_tree_add_item(tree, hf_lat_param_data, tvb, offset, param_len, ENC_NA);
1499 offset += param_len;
1503 static int
1504 dissect_lat_string(tvbuff_t *tvb, int offset, int hf, proto_tree *tree)
1506 int item_length;
1508 proto_tree_add_item_ret_length(tree, hf, tvb, offset, 1, ENC_ASCII|ENC_LITTLE_ENDIAN, &item_length);
1509 return offset + item_length;
1512 void
1513 proto_register_lat(void)
1515 static hf_register_info hf[] = {
1516 { &hf_lat_rrf,
1517 { "RRF", "lat.rrf", FT_BOOLEAN, 8,
1518 NULL, 0x01, NULL, HFILL}},
1520 { &hf_lat_master,
1521 { "Master", "lat.master", FT_BOOLEAN, 8,
1522 NULL, 0x02, NULL, HFILL}},
1524 { &hf_lat_msg_typ,
1525 { "Message type", "lat.msg_typ", FT_UINT8, BASE_DEC,
1526 VALS(msg_typ_vals), 0xFC, NULL, HFILL}},
1528 { &hf_lat_nbr_slots,
1529 { "Number of slots", "lat.nbr_slots", FT_UINT8, BASE_DEC,
1530 NULL, 0x0, NULL, HFILL}},
1532 { &hf_lat_dst_cir_id,
1533 { "Destination circuit ID", "lat.dst_cir_id", FT_UINT16,
1534 BASE_HEX, NULL, 0x0, NULL, HFILL}},
1536 { &hf_lat_src_cir_id,
1537 { "Source circuit ID", "lat.src_cir_id", FT_UINT16,
1538 BASE_HEX, NULL, 0x0, NULL, HFILL}},
1540 { &hf_lat_msg_seq_nbr,
1541 { "Message sequence number", "lat.msg_seq_nbr", FT_UINT8,
1542 BASE_DEC, NULL, 0x0, NULL, HFILL}},
1544 { &hf_lat_msg_ack_nbr,
1545 { "Message acknowledgment number", "lat.msg_ack_nbr", FT_UINT8,
1546 BASE_DEC, NULL, 0x0, NULL, HFILL}},
1549 * Yes, the DEC spec says "MIN" in the field name and "maximum"
1550 * in the field description. Go figure.
1552 { &hf_lat_min_rcv_datagram_size,
1553 { "Maximum LAT message size", "lat.min_rcv_datagram_size", FT_UINT16,
1554 BASE_DEC, NULL, 0x0, NULL, HFILL}},
1556 { &hf_lat_prtcl_ver,
1557 { "Protocol version of this session", "lat.prtcl_ver", FT_UINT8,
1558 BASE_DEC, NULL, 0x0, NULL, HFILL}},
1560 { &hf_lat_prtcl_eco,
1561 { "ECO level of protocol version of this session", "lat.prtcl_eco", FT_UINT8,
1562 BASE_DEC, NULL, 0x0, NULL, HFILL}},
1564 { &hf_lat_max_sim_slots,
1565 { "Maximum simultaneous sessions on this circuit", "lat.max_sim_slots", FT_UINT8,
1566 BASE_DEC, NULL, 0x0, NULL, HFILL}},
1568 { &hf_lat_nbr_dl_bufs,
1569 { "Number of extra data link buffers queued", "lat.nbr_dl_bufs", FT_UINT8,
1570 BASE_DEC, NULL, 0x0, NULL, HFILL}},
1572 { &hf_lat_server_circuit_timer,
1573 { "Server circuit timer", "lat.server_circuit_timer", FT_UINT8,
1574 BASE_DEC, NULL, 0x0, NULL, HFILL}},
1576 { &hf_lat_keep_alive_timer,
1577 { "Keep-alive timer", "lat.keep_alive_timer", FT_UINT8,
1578 BASE_DEC|BASE_UNIT_STRING, UNS(&units_second_seconds), 0x0, NULL, HFILL}},
1580 { &hf_lat_facility_number,
1581 { "Facility number", "lat.facility_number", FT_UINT16,
1582 BASE_DEC, NULL, 0x0, NULL, HFILL}},
1584 { &hf_lat_prod_type_code,
1585 { "Product type code", "lat.prod_type_code", FT_UINT8,
1586 BASE_DEC, VALS(prod_type_code_vals), 0x0, NULL, HFILL}},
1588 { &hf_lat_prod_vers_numb,
1589 { "Product version number", "lat.prod_vers_numb", FT_UINT8,
1590 BASE_DEC, NULL, 0x0, NULL, HFILL}},
1592 { &hf_lat_slave_node_name,
1593 { "Slave node name", "lat.slave_node_name", FT_UINT_STRING,
1594 BASE_NONE, NULL, 0x0, NULL, HFILL}},
1596 { &hf_lat_master_node_name,
1597 { "Master node name", "lat.master_node_name", FT_UINT_STRING,
1598 BASE_NONE, NULL, 0x0, NULL, HFILL}},
1600 { &hf_lat_location_text,
1601 { "Location", "lat.location_text", FT_UINT_STRING,
1602 BASE_NONE, NULL, 0x0, NULL, HFILL}},
1604 { &hf_lat_param_code,
1605 { "Parameter code", "lat.param_code", FT_UINT8,
1606 BASE_DEC, NULL, 0x0, NULL, HFILL}},
1608 { &hf_lat_param_len,
1609 { "Parameter length", "lat.param_len", FT_UINT8,
1610 BASE_DEC, NULL, 0x0, NULL, HFILL}},
1612 { &hf_lat_param_data,
1613 { "Parameter data", "lat.param_data", FT_BYTES,
1614 BASE_NONE, NULL, 0x0, NULL, HFILL}},
1616 { &hf_lat_slot_dst_slot_id,
1617 { "Destination slot ID", "lat.slot.dst_slot_id", FT_UINT8,
1618 BASE_DEC, NULL, 0x0, NULL, HFILL}},
1620 { &hf_lat_slot_src_slot_id,
1621 { "Source slot ID", "lat.slot.src_slot_id", FT_UINT8,
1622 BASE_DEC, NULL, 0x0, NULL, HFILL}},
1624 { &hf_lat_slot_byte_count,
1625 { "Slot data byte count", "lat.slot.byte_count", FT_UINT8,
1626 BASE_DEC, NULL, 0x0, NULL, HFILL}},
1628 { &hf_lat_slot_credits,
1629 { "Credits", "lat.slot.credits", FT_UINT8,
1630 BASE_DEC, NULL, 0x0F, NULL, HFILL}},
1632 { &hf_lat_slot_type,
1633 { "Slot type", "lat.slot.type", FT_UINT8,
1634 BASE_HEX, VALS(slot_type_vals), 0xF0, NULL, HFILL}},
1636 { &hf_lat_start_slot_service_class,
1637 { "Service class", "lat.start_slot.service_class", FT_UINT8,
1638 BASE_DEC, VALS(service_class_vals), 0x0, NULL, HFILL}},
1640 { &hf_lat_start_slot_minimum_attention_slot_size,
1641 { "Minimum attention slot size", "lat.start_slot.minimum_attention_slot_size", FT_UINT8,
1642 BASE_DEC, NULL, 0x0, NULL, HFILL}},
1644 { &hf_lat_start_slot_minimum_data_slot_size,
1645 { "Minimum data slot size", "lat.start_slot.minimum_data_slot_size", FT_UINT8,
1646 BASE_DEC, NULL, 0x0, NULL, HFILL}},
1648 { &hf_lat_start_slot_obj_srvc,
1649 { "Name of the destination service", "lat.start_slot.obj_srvc", FT_UINT_STRING,
1650 BASE_NONE, NULL, 0x0, NULL, HFILL}},
1652 { &hf_lat_start_slot_subj_dscr,
1653 { "Description of the source service", "lat.start_slot.subj_dscr", FT_UINT_STRING,
1654 BASE_NONE, NULL, 0x0, NULL, HFILL}},
1656 { &hf_lat_start_slot_class_1_param_code,
1657 { "Parameter code", "lat.start_slot.class_1.param_code", FT_UINT8,
1658 BASE_DEC, VALS(start_slot_class_1_param_code_vals),
1659 0x0, NULL, HFILL }},
1661 { &hf_lat_status_remaining,
1662 { "Remainder of status", "lat.slot.status_remaining", FT_BYTES,
1663 BASE_NONE, NULL, 0x0, NULL, HFILL}},
1665 { &hf_lat_slot_data,
1666 { "Slot data", "lat.slot.slot_data", FT_BYTES,
1667 BASE_NONE, NULL, 0x0, NULL, HFILL}},
1669 { &hf_lat_data_b_slot_control_flags,
1670 { "Control flags", "lat.data_b_slot.control_flags", FT_UINT8,
1671 BASE_HEX, NULL, 0x0, NULL, HFILL }},
1673 { &hf_lat_data_b_slot_control_flags_enable_input_flow_control,
1674 { "Enable usage of input flow control characters",
1675 "lat.data_b_slot.control_flags.enable_input_flow_control",
1676 FT_BOOLEAN, 8, NULL, 0x01, NULL, HFILL }},
1678 { &hf_lat_data_b_slot_control_flags_disable_input_flow_control,
1679 { "Disable recognition of input flow control characters",
1680 "lat.data_b_slot.control_flags.disable_input_flow_control",
1681 FT_BOOLEAN, 8, NULL, 0x02, NULL, HFILL }},
1683 { &hf_lat_data_b_slot_control_flags_enable_output_flow_control,
1684 { "Enable usage of output flow control characters",
1685 "lat.data_b_slot.control_flags.enable_output_flow_control",
1686 FT_BOOLEAN, 8, NULL, 0x04, NULL, HFILL }},
1688 { &hf_lat_data_b_slot_control_flags_disable_output_flow_control,
1689 { "Disable recognition of output flow control characters",
1690 "lat.data_b_slot.control_flags.disable_output_flow_control",
1691 FT_BOOLEAN, 8, NULL, 0x08, NULL, HFILL }},
1693 { &hf_lat_data_b_slot_control_flags_break_detected,
1694 { "Break condition detected",
1695 "lat.data_b_slot.control_flags.break_detected",
1696 FT_BOOLEAN, 8, NULL, 0x10, NULL, HFILL }},
1698 { &hf_lat_data_b_slot_control_flags_set_port_char,
1699 { "Set port characteristics",
1700 "lat.data_b_slot.control_flags.set_port_characteristics",
1701 FT_BOOLEAN, 8, NULL, 0x20, NULL, HFILL }},
1703 { &hf_lat_data_b_slot_control_flags_report_port_char,
1704 { "Report port characteristics",
1705 "lat.data_b_slot.control_flags.report_port_characteristics",
1706 FT_BOOLEAN, 8, NULL, 0x40, NULL, HFILL }},
1708 { &hf_lat_data_b_slot_stop_output_channel_char,
1709 { "Output channel stop character",
1710 "lat.data_b_slot.stop_output_channel_char", FT_UINT8,
1711 BASE_HEX, NULL, 0x0, NULL, HFILL }},
1713 { &hf_lat_data_b_slot_start_output_channel_char,
1714 { "Output channel start character",
1715 "lat.data_b_slot.start_output_channel_char", FT_UINT8,
1716 BASE_HEX, NULL, 0x0, NULL, HFILL }},
1718 { &hf_lat_data_b_slot_stop_input_channel_char,
1719 { "Input channel stop character",
1720 "lat.data_b_slot.stop_input_channel_char", FT_UINT8,
1721 BASE_HEX, NULL, 0x0, NULL, HFILL }},
1723 { &hf_lat_data_b_slot_start_input_channel_char,
1724 { "Input channel start character",
1725 "lat.data_b_slot.start_input_channel_char", FT_UINT8,
1726 BASE_HEX, NULL, 0x0, NULL, HFILL }},
1728 { &hf_lat_data_b_slot_param_code,
1729 { "Parameter code", "lat.data_b_slot.param_code", FT_UINT8,
1730 BASE_DEC, VALS(data_b_slot_param_code_vals),
1731 0x0, NULL, HFILL }},
1733 { &hf_lat_slot_data_remaining,
1734 { "Slot data remaining", "lat.slot.slot_data_remaining", FT_BYTES,
1735 BASE_NONE, NULL, 0x0, NULL, HFILL}},
1737 { &hf_lat_attention_slot_control_flags,
1738 { "Control flags", "lat.attention_slot.control_flags", FT_UINT8,
1739 BASE_DEC, NULL, 0x0, NULL, HFILL }},
1741 { &hf_lat_attention_slot_control_flags_abort,
1742 { "Abort", "lat.attention_slot.control_flags.abort", FT_BOOLEAN,
1743 8, NULL, 0x20, NULL, HFILL }},
1745 { &hf_lat_mbz,
1746 { "MBZ", "lat.slot.mbz", FT_UINT8,
1747 BASE_DEC, NULL, 0x0, NULL, HFILL}},
1749 { &hf_lat_reason,
1750 { "Reason", "lat.slot.reason", FT_UINT8,
1751 BASE_DEC, VALS(reason_code_vals), 0x0, NULL, HFILL}},
1753 { &hf_lat_circuit_disconnect_reason,
1754 { "Circuit disconnect reason", "lat.circuit_disconnect_reason", FT_UINT8,
1755 BASE_DEC, VALS(circuit_disconnect_reason_code_vals), 0x0, NULL, HFILL}},
1757 { &hf_lat_reason_text,
1758 { "Reason", "lat.reason_text", FT_UINT_STRING,
1759 BASE_NONE, NULL, 0x0, NULL, HFILL}},
1761 { &hf_lat_high_prtcl_ver,
1762 { "Highest protocol version supported", "lat.high_prtcl_ver", FT_UINT8,
1763 BASE_DEC, NULL, 0x0, NULL, HFILL}},
1765 { &hf_lat_low_prtcl_ver,
1766 { "Lowest protocol version supported", "lat.low_prtcl_ver", FT_UINT8,
1767 BASE_DEC, NULL, 0x0, NULL, HFILL}},
1769 { &hf_lat_cur_prtcl_ver,
1770 { "Protocol version of this message", "lat.cur_prtcl_ver", FT_UINT8,
1771 BASE_DEC, NULL, 0x0, NULL, HFILL}},
1773 { &hf_lat_cur_prtcl_eco,
1774 { "ECO level of current protocol version", "lat.cur_prtcl_eco", FT_UINT8,
1775 BASE_DEC, NULL, 0x0, NULL, HFILL}},
1777 { &hf_lat_msg_inc,
1778 { "Message incarnation", "lat.msg_inc", FT_UINT8,
1779 BASE_DEC, NULL, 0x0, NULL, HFILL}},
1781 { &hf_lat_change_flags,
1782 { "Change flags", "lat.change_flags", FT_UINT8,
1783 BASE_HEX, NULL, 0x0, NULL, HFILL}},
1785 { &hf_lat_data_link_rcv_frame_size,
1786 { "Maximum LAT message size", "lat.data_link_rcv_frame_size", FT_UINT16,
1787 BASE_DEC, NULL, 0x0, NULL, HFILL}},
1789 { &hf_lat_node_multicast_timer,
1790 { "Node multicast timer", "lat.node_multicast_timer", FT_UINT8,
1791 BASE_DEC, NULL, 0x0, NULL, HFILL}},
1793 { &hf_lat_node_status,
1794 { "Node status", "lat.node_status", FT_UINT8,
1795 BASE_DEC, VALS(node_status_vals), 0x0, NULL, HFILL}},
1797 { &hf_lat_node_group_len,
1798 { "Node group length", "lat.node_group_len", FT_UINT8,
1799 BASE_DEC, NULL, 0x0, NULL, HFILL}},
1801 { &hf_lat_node_groups,
1802 { "Node groups", "lat.node_groups", FT_BYTES,
1803 BASE_NONE, NULL, 0x0, NULL, HFILL}},
1805 { &hf_lat_node_name,
1806 { "Node name", "lat.node_name", FT_UINT_STRING,
1807 BASE_NONE, NULL, 0x0, NULL, HFILL}},
1809 { &hf_lat_node_description,
1810 { "Node description", "lat.node_description", FT_UINT_STRING,
1811 BASE_NONE, NULL, 0x0, NULL, HFILL}},
1813 { &hf_lat_service_name_count,
1814 { "Number of service names", "lat.service_name_count", FT_UINT8,
1815 BASE_DEC, NULL, 0x0, NULL, HFILL}},
1817 { &hf_lat_service_rating,
1818 { "Service rating", "lat.service.rating", FT_UINT8,
1819 BASE_DEC, NULL, 0x0, NULL, HFILL}},
1821 { &hf_lat_node_service_len,
1822 { "Node service classes length", "lat.node_service_len", FT_UINT8,
1823 BASE_DEC, NULL, 0x0, NULL, HFILL}},
1825 { &hf_lat_node_service_class,
1826 { "Node service classes", "lat.node_service_class", FT_UINT8,
1827 BASE_DEC, VALS(service_class_vals), 0x0, NULL, HFILL}},
1829 { &hf_lat_prtcl_format,
1830 { "Protocol format", "lat.prtcl_format", FT_UINT8,
1831 BASE_HEX, NULL, 0x0, NULL, HFILL}},
1833 { &hf_lat_request_identifier,
1834 { "Request identifier", "lat.request_identifier", FT_UINT16,
1835 BASE_DEC, NULL, 0x0, NULL, HFILL}},
1837 { &hf_lat_entry_identifier,
1838 { "Entry identifier", "lat.entry_identifier", FT_UINT16,
1839 BASE_DEC, NULL, 0x0, NULL, HFILL}},
1841 { &hf_lat_command_type,
1842 { "Command type", "lat.command_type", FT_UINT8,
1843 BASE_DEC, VALS(command_type_vals), 0x0, NULL, HFILL}},
1845 { &hf_lat_command_modifier,
1846 { "Command modifier", "lat.command_modifier", FT_UINT8,
1847 BASE_HEX, NULL, 0x0, NULL, HFILL}},
1849 { &hf_lat_command_modifier_send_status_periodically,
1850 { "Send status of the entries periodically",
1851 "lat.command_modifier.send_status_periodically", FT_BOOLEAN,
1852 8, NULL, 0x01, NULL, HFILL}},
1854 { &hf_lat_command_modifier_send_status_on_queue_depth_change,
1855 { "Send status of the entries every time the queue depth changes",
1856 "lat.command_modifier.send_status_on_queue_depth_change", FT_BOOLEAN,
1857 8, NULL, 0x02, NULL, HFILL}},
1859 { &hf_lat_obj_node_name,
1860 { "Destination node name", "lat.obj_node.name", FT_UINT_STRING,
1861 BASE_NONE, NULL, 0x0,
1862 NULL, HFILL}},
1864 { &hf_lat_subj_group_len,
1865 { "Subject group code length", "lat.subj_group_len", FT_UINT8,
1866 BASE_DEC, NULL, 0x0, NULL, HFILL}},
1868 { &hf_lat_subj_group,
1869 { "Subject group code mask", "lat.subj_group", FT_BYTES,
1870 BASE_NONE, NULL, 0x0, NULL, HFILL}},
1872 { &hf_lat_subj_node_name,
1873 { "Subject node name", "lat.subj_node_name", FT_UINT_STRING,
1874 BASE_NONE, NULL, 0x0, NULL, HFILL}},
1876 { &hf_lat_subj_port_name,
1877 { "Subject port name", "lat.subj_port_name", FT_UINT_STRING,
1878 BASE_NONE, NULL, 0x0, NULL, HFILL}},
1880 { &hf_lat_status_retransmit_timer,
1881 { "Status retransmit timer", "lat.status_retransmit_timer", FT_UINT16,
1882 BASE_DEC, NULL, 0x0, NULL, HFILL}},
1884 { &hf_lat_entries_counter,
1885 { "Entries counter", "lat.entries_counter", FT_UINT8,
1886 BASE_DEC, NULL, 0x0,
1887 "Number of entries whose status is reported in the message",
1888 HFILL}},
1890 { &hf_lat_entry_length,
1891 { "Entry length", "lat.entry_length", FT_UINT8,
1892 BASE_DEC, NULL, 0x0, "Length of status entry, in bytes",
1893 HFILL}},
1895 { &hf_lat_entry_status,
1896 { "Entry status", "lat.entry_status", FT_UINT8,
1897 BASE_HEX, NULL, 0x0, NULL, HFILL}},
1899 { &hf_lat_entry_status_rejected,
1900 { "Rejected", "lat.entry_status.rejected", FT_BOOLEAN,
1901 8, NULL, ENTRY_STATUS_REJECTED, "Solicitation request was rejected",
1902 HFILL}},
1904 { &hf_lat_entry_status_additional_information,
1905 { "Additional information", "lat.entry_status.additional_information", FT_UINT8,
1906 BASE_DEC, VALS(additional_information_vals),
1907 ENTRY_STATUS_ADDITIONAL_INFORMATION, NULL, HFILL}},
1909 { &hf_lat_entry_error,
1910 { "Entry error", "lat.entry_error", FT_UINT8,
1911 BASE_DEC, VALS(entry_error_vals), 0x0,
1912 "Solicitation rejection reason", HFILL}},
1914 { &hf_lat_elapsed_queue_time,
1915 { "Elapsed queue time", "lat.elapsed_queue_time", FT_UINT16,
1916 BASE_DEC, NULL, 0x0, NULL, HFILL}},
1918 { &hf_lat_min_queue_position,
1919 { "Minimum queue position", "lat.min_queue_position", FT_UINT16,
1920 BASE_DEC, NULL, 0x0, NULL, HFILL}},
1922 { &hf_lat_max_queue_position,
1923 { "Maximum queue position", "lat.max_queue_position", FT_UINT16,
1924 BASE_DEC, NULL, 0x0, NULL, HFILL}},
1926 { &hf_lat_obj_srvc_name,
1927 { "Service name", "lat.obj_service_name", FT_UINT_STRING,
1928 BASE_NONE, NULL, 0x0, NULL, HFILL}},
1930 { &hf_lat_obj_port_name,
1931 { "Port name", "lat.obj_port_name", FT_UINT_STRING,
1932 BASE_NONE, NULL, 0x0, NULL, HFILL}},
1934 { &hf_lat_subj_description,
1935 { "Source service description", "lat.subj_description", FT_UINT_STRING,
1936 BASE_NONE, NULL, 0x0, NULL, HFILL}},
1938 { &hf_lat_solicit_identifier,
1939 { "Solicit identifier", "lat.solicit_identifier", FT_UINT16,
1940 BASE_DEC, NULL, 0x0, NULL, HFILL}},
1942 { &hf_lat_response_timer,
1943 { "Response timer", "lat.response_timer", FT_UINT16,
1944 BASE_DEC, NULL, 0x0, NULL, HFILL}},
1946 { &hf_lat_dst_node_name,
1947 { "Destination node name", "lat.dst_node_name", FT_UINT_STRING,
1948 BASE_NONE, NULL, 0x0, NULL, HFILL}},
1950 { &hf_lat_src_node_group_len,
1951 { "Source node group length", "lat.src_node_group_len", FT_UINT8,
1952 BASE_DEC, NULL, 0x0, NULL, HFILL}},
1954 { &hf_lat_src_node_groups,
1955 { "Source node groups", "lat.src_node_groups", FT_BYTES,
1956 BASE_NONE, NULL, 0x0, NULL, HFILL}},
1958 { &hf_lat_src_node_name,
1959 { "Source node name", "lat.src_node_name", FT_UINT_STRING,
1960 BASE_NONE, NULL, 0x0, NULL, HFILL}},
1962 { &hf_lat_dst_srvc_name,
1963 { "Destination service name", "lat.dst_srvc_name", FT_UINT_STRING,
1964 BASE_NONE, NULL, 0x0, NULL, HFILL}},
1966 { &hf_lat_response_status,
1967 { "Response status", "lat.response_status", FT_UINT16,
1968 BASE_HEX, NULL, 0x0, NULL, HFILL}},
1970 { &hf_lat_response_status_node_does_not_offer_requested_service,
1971 { "Node does not offer requested service",
1972 "lat.response_status.node_does_not_offer_requested_service",
1973 FT_BOOLEAN, 16, NULL, 0x0002, NULL, HFILL}},
1975 { &hf_lat_src_node_status,
1976 { "Source node status", "lat.src_node_status", FT_UINT16,
1977 BASE_HEX, NULL, 0x0, NULL, HFILL}},
1979 { &hf_lat_src_node_status_node_is_disabled,
1980 { "Node is disabled",
1981 "lat.src_node_status.node_is_disabled",
1982 FT_BOOLEAN, 16, NULL, 0x0001, NULL, HFILL}},
1984 { &hf_lat_src_node_status_start_message_can_be_sent,
1985 { "Start message can be sent",
1986 "lat.src_node_status.start_message_can_be_sent",
1987 FT_BOOLEAN, 16, NULL, 0x0002,
1988 "Start message can be sent by the subject node to this node",
1989 HFILL}},
1991 { &hf_lat_src_node_status_command_message_can_be_sent,
1992 { "Command message can be sent",
1993 "lat.src_node_status.command_message_can_be_sent",
1994 FT_BOOLEAN, 16, NULL, 0x0004,
1995 "Command message can be sent by the subject node to this node",
1996 HFILL}},
1998 { &hf_lat_source_node_addr,
1999 { "Source node address", "lat.source_node_addr", FT_ETHER,
2000 BASE_NONE, NULL, 0x0, NULL, HFILL}},
2002 { &hf_lat_src_node_mc_timer,
2003 { "Multicast timer", "lat.mc_timer", FT_UINT16,
2004 BASE_DEC, NULL, 0x0, NULL, HFILL}},
2006 { &hf_lat_src_node_desc,
2007 { "Source node description", "lat.src_node_desc", FT_UINT_STRING,
2008 BASE_NONE, NULL, 0x0, NULL, HFILL}},
2010 { &hf_lat_srvc_count,
2011 { "Service count", "lat.srvc_count", FT_UINT8,
2012 BASE_DEC, NULL, 0x0, "Total number of service entries in the message", HFILL}},
2014 { &hf_lat_srvc_entry_len,
2015 { "Service entry length", "lat.srvc_entry_len", FT_UINT8,
2016 BASE_DEC, NULL, 0x0, "Length of service entry, in bytes", HFILL}},
2018 { &hf_lat_srvc_class_len,
2019 { "Service class length", "lat.srvc_class_len", FT_UINT8,
2020 BASE_DEC, NULL, 0x0, "Length of service class list", HFILL}},
2022 { &hf_lat_srvc_class,
2023 { "Service class", "lat.srvc_class", FT_UINT8,
2024 BASE_DEC, VALS(service_class_vals), 0x0, NULL, HFILL}},
2026 { &hf_lat_srvc_status,
2027 { "Service status", "lat.srvc_status", FT_UINT8,
2028 BASE_HEX, NULL, 0x0, NULL, HFILL}},
2030 { &hf_lat_srvc_status_enabled,
2031 { "Service is enabled", "lat.srvc_status.enabled", FT_BOOLEAN,
2032 8, NULL, 0x01, NULL, HFILL}},
2034 { &hf_lat_srvc_status_supports_queueing,
2035 { "Service supports queueing", "lat.srvc_status.supports_queueing", FT_BOOLEAN,
2036 8, NULL, 0x02, NULL, HFILL}},
2038 { &hf_lat_srvc_rating,
2039 { "Service rating", "lat.srvc_rating", FT_UINT8,
2040 BASE_DEC, NULL, 0x0, NULL, HFILL}},
2042 { &hf_lat_srvc_group_len,
2043 { "Service group code length", "lat.srvc_group_len", FT_UINT8,
2044 BASE_DEC, NULL, 0x0, NULL, HFILL}},
2046 { &hf_lat_srvc_groups,
2047 { "Service group code mask", "lat.srvc_groups", FT_BYTES,
2048 BASE_NONE, NULL, 0x0, NULL, HFILL}},
2050 { &hf_lat_srvc_name,
2051 { "Service name", "lat.srvc_name", FT_UINT_STRING,
2052 BASE_NONE, NULL, 0x0, NULL, HFILL}},
2054 { &hf_lat_srvc_desc,
2055 { "Service description", "lat.srvc_desc", FT_UINT_STRING,
2056 BASE_NONE, NULL, 0x0, NULL, HFILL}},
2058 { &hf_lat_service_name,
2059 { "Service name", "lat.service.name", FT_UINT_STRING,
2060 BASE_NONE, NULL, 0x0, NULL, HFILL}},
2062 { &hf_lat_service_description,
2063 { "Service description", "lat.service.description", FT_UINT_STRING,
2064 BASE_NONE, NULL, 0x0, NULL, HFILL}},
2066 { &hf_lat_unknown_command_data,
2067 { "Unknown command data", "lat.unknown_command_data", FT_BYTES,
2068 BASE_NONE, NULL, 0x0, NULL, HFILL}},
2070 static int *ett[] = {
2071 &ett_lat,
2072 &ett_data_b_slot_control_flags,
2073 &ett_lat_attention_slot_control_flags,
2074 &ett_lat_command_modifier,
2075 &ett_lat_entry_status,
2076 &ett_lat_response_status,
2077 &ett_lat_src_node_status,
2078 &ett_lat_srvc_status
2080 static ei_register_info ei[] = {
2081 { &ei_slot_data_len_invalid,
2082 { "lat.slot.data_len_invalid", PI_PROTOCOL, PI_ERROR, "Slot data length is too short", EXPFILL }},
2083 { &ei_entry_length_too_short,
2084 { "lat.entry_length_too_short", PI_PROTOCOL, PI_ERROR, "Entry length in status message is too short", EXPFILL }},
2085 { &ei_srvc_entry_len_too_short,
2086 { "lat.srvc_entry_len_too_short", PI_PROTOCOL, PI_ERROR, "Entry length in response information message is too short", EXPFILL }},
2087 { &ei_mbz_data_nonzero,
2088 { "lat.mbz_data_nonzero", PI_PROTOCOL, PI_ERROR, "Must-be-zero data is nonzero", EXPFILL }},
2090 expert_module_t* expert_lat;
2092 proto_lat = proto_register_protocol("Local Area Transport",
2093 "LAT", "lat");
2094 lat_handle = register_dissector("lat", dissect_lat, proto_lat);
2095 proto_register_field_array(proto_lat, hf, array_length(hf));
2096 proto_register_subtree_array(ett, array_length(ett));
2097 expert_lat = expert_register_protocol(proto_lat);
2098 expert_register_field_array(expert_lat, ei, array_length(ei));
2101 void
2102 proto_reg_handoff_lat(void)
2104 dissector_add_uint("ethertype", ETHERTYPE_LAT, lat_handle);
2108 * Editor modelines - https://www.wireshark.org/tools/modelines.html
2110 * Local variables:
2111 * c-basic-offset: 8
2112 * tab-width: 8
2113 * indent-tabs-mode: t
2114 * End:
2116 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
2117 * :indentSize=8:tabSize=8:noTabs=false: