2 * Routines for Fibre Channel Single Byte Protocol (SBCCS); used in FICON.
3 * This decoder is for FC-SB3 version 1.4
4 * Copyright 2003, Dinesh G Dutt <ddutt@cisco.com>
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
10 * Copyright 1998 Gerald Combs
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
31 #include <epan/packet.h>
32 #include <epan/conversation.h>
33 #include <epan/etypes.h>
34 #include "packet-scsi.h"
35 #include "packet-fc.h"
36 #include "packet-fcsb3.h"
38 /* Initialize the protocol and registered fields */
39 static int proto_fc_sbccs
= -1;
40 static int hf_sbccs_chid
= -1;
41 static int hf_sbccs_cuid
= -1;
42 static int hf_sbccs_devaddr
= -1;
43 static int hf_sbccs_ccw
= -1;
44 static int hf_sbccs_token
= -1;
45 static int hf_sbccs_dib_iucnt
= -1;
46 static int hf_sbccs_dib_datacnt
= -1;
47 static int hf_sbccs_dib_ccw_cmd
= -1;
48 static int hf_sbccs_dib_ccw_cnt
= -1;
49 static int hf_sbccs_dib_residualcnt
= -1;
50 static int hf_sbccs_dib_qtuf
= -1;
51 static int hf_sbccs_dib_qtu
= -1;
52 static int hf_sbccs_dib_dtuf
= -1;
53 static int hf_sbccs_dib_dtu
= -1;
54 static int hf_sbccs_dib_ctlfn
= -1;
55 static int hf_sbccs_lrc
= -1;
56 static int hf_sbccs_dib_iupacing
= -1;
57 static int hf_sbccs_dev_xcp_code
= -1;
58 static int hf_sbccs_prg_pth_errcode
= -1;
59 static int hf_sbccs_prg_rsp_errcode
= -1;
60 static int hf_sbccs_dib_ctccntr
= -1;
61 static int hf_sbccs_dib_lprcode
= -1;
62 static int hf_sbccs_dib_tin_imgid_cnt
= -1;
63 static int hf_sbccs_dib_lrjcode
= -1;
64 static int hf_sbccs_dib_ioprio
= -1;
65 static int hf_sbccs_dib_linkctlfn
= -1;
66 static int hf_sbccs_iui
= -1;
67 static int hf_sbccs_iui_as
= -1;
68 static int hf_sbccs_iui_es
= -1;
69 static int hf_sbccs_iui_val
= -1;
70 static int hf_sbccs_dhflags
= -1;
71 static int hf_sbccs_dhflags_end
= -1;
72 static int hf_sbccs_dhflags_chaining
= -1;
73 static int hf_sbccs_dhflags_earlyend
= -1;
74 static int hf_sbccs_dhflags_nocrc
= -1;
75 static int hf_sbccs_dib_ccw_flags
= -1;
76 static int hf_sbccs_dib_ccw_flags_cd
= -1;
77 static int hf_sbccs_dib_ccw_flags_cc
= -1;
78 static int hf_sbccs_dib_ccw_flags_sli
= -1;
79 static int hf_sbccs_dib_ccw_flags_crr
= -1;
80 static int hf_sbccs_dib_cmdflags
= -1;
81 static int hf_sbccs_dib_cmdflags_du
= -1;
82 static int hf_sbccs_dib_cmdflags_coc
= -1;
83 static int hf_sbccs_dib_cmdflags_syr
= -1;
84 static int hf_sbccs_dib_cmdflags_rex
= -1;
85 static int hf_sbccs_dib_cmdflags_sss
= -1;
86 static int hf_sbccs_dib_statusflags
= -1;
87 static int hf_sbccs_dib_statusflags_ffc
= -1;
88 static int hf_sbccs_dib_statusflags_ci
= -1;
89 static int hf_sbccs_dib_statusflags_cr
= -1;
90 static int hf_sbccs_dib_statusflags_lri
= -1;
91 static int hf_sbccs_dib_statusflags_rv
= -1;
92 static int hf_sbccs_dib_status
= -1;
93 static int hf_sbccs_dib_status_attention
= -1;
94 static int hf_sbccs_dib_status_modifier
= -1;
95 static int hf_sbccs_dib_status_cue
= -1;
96 static int hf_sbccs_dib_status_busy
= -1;
97 static int hf_sbccs_dib_status_channelend
= -1;
98 static int hf_sbccs_dib_status_deviceend
= -1;
99 static int hf_sbccs_dib_status_unit_check
= -1;
100 static int hf_sbccs_dib_status_unit_exception
= -1;
101 static int hf_sbccs_dib_ctlparam
= -1;
102 static int hf_sbccs_dib_ctlparam_rc
= -1;
103 static int hf_sbccs_dib_ctlparam_ru
= -1;
104 static int hf_sbccs_dib_ctlparam_ro
= -1;
105 static int hf_sbccs_dib_linkctlinfo
= -1;
106 static int hf_sbccs_dib_linkctlinfo_ctcconn
= -1;
107 static int hf_sbccs_dib_linkctlinfo_ecrcg
= -1;
109 /* Initialize the subtree pointers */
110 static gint ett_fc_sbccs
= -1;
111 static gint ett_sbccs_iui
= -1;
112 static gint ett_sbccs_dhflags
= -1;
113 static gint ett_sbccs_dib_ccw_flags
= -1;
114 static gint ett_sbccs_dib_cmdflags
= -1;
115 static gint ett_sbccs_dib_statusflags
= -1;
116 static gint ett_sbccs_dib_status
= -1;
117 static gint ett_sbccs_dib_ctlparam
= -1;
118 static gint ett_sbccs_dib_linkctlinfo
= -1;
120 static dissector_handle_t data_handle
;
129 static const value_string fc_sbccs_iu_val
[] = {
130 {FC_SBCCS_IU_DATA
, "Data"},
131 {FC_SBCCS_IU_CMD_HDR
, "Command Header"},
132 {FC_SBCCS_IU_STATUS
, "Status"},
133 {FC_SBCCS_IU_CTL
, "Control"},
134 {FC_SBCCS_IU_CMD_DATA
, "Command Header & Data"},
135 {FC_SBCCS_IU_CMD_LINK_CTL
, "Link Control"},
141 static const value_string fc_sbccs_dib_cmd_val
[] = {
147 { 5, "Write (Modifier)"},
148 { 6, "Read (Modifier)"},
149 { 7, "Control (Modifier)"},
151 { 9, "Write (Modifier)"},
152 {10, "Read (Modifier)"},
153 {11, "Control (Modifier)"},
154 {12, "Read Backward"},
155 {13, "Write (Modifier)"},
156 {14, "Read (Modifier)"},
157 {15, "Control (Modifier)"},
161 static const value_string fc_sbccs_dib_ctl_fn_val
[] = {
162 {FC_SBCCS_CTL_FN_CTL_END
, "Control End"},
163 {FC_SBCCS_CTL_FN_CMD_RSP
, "Command Response"},
164 {FC_SBCCS_CTL_FN_STK_STS
, "Stack Status"},
165 {FC_SBCCS_CTL_FN_CANCEL
, "Cancel"},
166 {FC_SBCCS_CTL_FN_SYS_RST
, "System Reset"},
167 {FC_SBCCS_CTL_FN_SEL_RST
, "Selective Reset"},
168 {FC_SBCCS_CTL_FN_REQ_STS
, "Request Status"},
169 {FC_SBCCS_CTL_FN_DEV_XCP
, "Device Level Exception"},
170 {FC_SBCCS_CTL_FN_STS_ACC
, "Status Accepted"},
171 {FC_SBCCS_CTL_FN_DEV_ACK
, "Device-Level Ack"},
172 {FC_SBCCS_CTL_FN_PRG_PTH
, "Purge Path"},
173 {FC_SBCCS_CTL_FN_PRG_RSP
, "Purge Path Response"},
177 static const value_string fc_sbccs_dib_dev_xcpcode_val
[] = {
178 {1, "Address Exception"},
182 static const value_string fc_sbccs_dib_purge_path_err_val
[] = {
183 { 0, "Error Code Xfer Not Supported"},
184 { 1, "SB-3 Protocol Timeout"},
185 { 2, "SB-3 Link Failure"},
187 { 4, "SB-3 Offline Condition"},
188 { 5, "FC-PH Link Failure"},
189 { 6, "SB-3 Length Error"},
191 { 8, "SB-3 CRC Error"},
192 { 9, "IU Count Error"},
193 {10, "SB-3 Link Level Protocol Error"},
194 {11, "SB-3 Device Level Protocol Error"},
195 {12, "Receive ABTS"},
196 {13, "Cancel Function Timeout"},
197 {14, "Abnormal Termination of Xchg"},
202 static const value_string fc_sbccs_dib_purge_path_rsp_err_val
[] = {
204 { 1, "SB-3 Protocol Timeout"},
205 { 2, "SB-3 Link Failure"},
206 { 3, "Logical Path Timeout Error"},
207 { 4, "SB-3 Offline Condition"},
208 { 5, "FC-PH Link Failure"},
209 { 6, "SB-3 Length Error"},
211 { 8, "SB-3 CRC Error"},
212 { 9, "IU Count Error"},
213 {10, "SB-3 Link Level Protocol Error"},
214 {11, "SB-3 Device Level Protocol Error"},
215 {12, "Receive ABTS"},
217 {14, "Abnormal Termination of Xchg"},
218 {15, "Logical Path Not Estd"},
219 {16, "Test Init Result Error"},
223 static const value_string fc_sbccs_dib_link_ctl_fn_val
[] = {
224 {FC_SBCCS_LINK_CTL_FN_ELP
, "ELP"},
225 {FC_SBCCS_LINK_CTL_FN_RLP
, "RLP"},
226 {FC_SBCCS_LINK_CTL_FN_TIN
, "TIN"},
227 {FC_SBCCS_LINK_CTL_FN_LPE
, "LPE"},
228 {FC_SBCCS_LINK_CTL_FN_LPR
, "LPR"},
229 {FC_SBCCS_LINK_CTL_FN_TIR
, "TIR"},
230 {FC_SBCCS_LINK_CTL_FN_LRJ
, "LRJ"},
231 {FC_SBCCS_LINK_CTL_FN_LBY
, "LBY"},
232 {FC_SBCCS_LINK_CTL_FN_LACK
, "LACK"},
236 static const value_string fc_sbccs_dib_lpr_errcode_val
[] = {
237 {0x0, "Response to RLP"},
238 {0x1, "Optional Features Conflict"},
239 {0x2, "Out of Resources"},
240 {0x3, "Device Init In Progress"},
241 {0x4, "No CU Image"},
245 static const value_string fc_sbccs_dib_lrj_errcode_val
[] = {
246 {0x6, "Logical Path Not Estd"},
247 {0x9, "Protocol Error"},
252 dissect_iui_flags (proto_tree
*parent_tree
, tvbuff_t
*tvb
, int offset
, guint16 flags
)
254 proto_item
*item
= NULL
;
255 proto_tree
*tree
= NULL
;
258 item
=proto_tree_add_uint(parent_tree
, hf_sbccs_iui
,
259 tvb
, offset
, 1, flags
);
260 tree
=proto_item_add_subtree(item
, ett_sbccs_iui
);
263 proto_tree_add_boolean(tree
, hf_sbccs_iui_as
, tvb
, offset
, 1, flags
);
265 proto_item_append_text(item
, " AS");
267 flags
&= (~( 0x10 ));
269 proto_tree_add_boolean(tree
, hf_sbccs_iui_es
, tvb
, offset
, 1, flags
);
271 proto_item_append_text(item
, " ES");
273 flags
&= (~( 0x08 ));
275 proto_tree_add_item (tree
, hf_sbccs_iui_val
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
276 proto_item_append_text(item
, "%s", val_to_str (flags
& 0x7, fc_sbccs_iu_val
, "0x%x"));
277 /*flags &= (~( 0x07 ));*/
281 dissect_linkctlinfo (proto_tree
*parent_tree
, tvbuff_t
*tvb
, int offset
, guint16 flags
)
283 proto_item
*item
= NULL
;
284 proto_tree
*tree
= NULL
;
287 item
=proto_tree_add_uint(parent_tree
, hf_sbccs_dib_linkctlinfo
,
288 tvb
, offset
, 2, flags
);
289 tree
=proto_item_add_subtree(item
, ett_sbccs_dib_linkctlinfo
);
292 proto_tree_add_boolean(tree
, hf_sbccs_dib_linkctlinfo_ctcconn
, tvb
, offset
, 2, flags
);
294 proto_item_append_text(item
, " CTC Conn");
296 flags
&= (~( 0x80 ));
298 proto_tree_add_boolean(tree
, hf_sbccs_dib_linkctlinfo_ecrcg
, tvb
, offset
, 2, flags
);
300 proto_item_append_text(item
, " Enhanced CRC Gen");
302 /*flags &= (~( 0x01 ));*/
307 dissect_dh_flags (proto_tree
*parent_tree
, tvbuff_t
*tvb
, int offset
, guint16 flags
)
309 proto_item
*item
= NULL
;
310 proto_tree
*tree
= NULL
;
313 item
=proto_tree_add_uint(parent_tree
, hf_sbccs_dhflags
,
314 tvb
, offset
, 1, flags
);
315 tree
=proto_item_add_subtree(item
, ett_sbccs_dhflags
);
318 proto_tree_add_boolean(tree
, hf_sbccs_dhflags_end
, tvb
, offset
, 1, flags
);
320 proto_item_append_text(item
, " End");
322 flags
&= (~( 0x80 ));
324 proto_tree_add_boolean(tree
, hf_sbccs_dhflags_chaining
, tvb
, offset
, 1, flags
);
326 proto_item_append_text(item
, " Chaining");
328 flags
&= (~( 0x10 ));
330 proto_tree_add_boolean(tree
, hf_sbccs_dhflags_earlyend
, tvb
, offset
, 1, flags
);
332 proto_item_append_text(item
, " Early End");
334 flags
&= (~( 0x08 ));
336 proto_tree_add_boolean(tree
, hf_sbccs_dhflags_nocrc
, tvb
, offset
, 1, flags
);
338 proto_item_append_text(item
, " No CRC");
340 /*flags &= (~( 0x04 ));*/
345 dissect_ccw_flags (proto_tree
*parent_tree
, tvbuff_t
*tvb
, int offset
, guint8 flags
)
347 proto_item
*item
= NULL
;
348 proto_tree
*tree
= NULL
;
351 item
=proto_tree_add_uint(parent_tree
, hf_sbccs_dib_ccw_flags
,
352 tvb
, offset
, 1, flags
);
353 tree
=proto_item_add_subtree(item
, ett_sbccs_dib_ccw_flags
);
356 proto_tree_add_boolean(tree
, hf_sbccs_dib_ccw_flags_cd
, tvb
, offset
, 1, flags
);
358 proto_item_append_text(item
, " CD");
360 flags
&= (~( 0x80 ));
362 proto_tree_add_boolean(tree
, hf_sbccs_dib_ccw_flags_cc
, tvb
, offset
, 1, flags
);
364 proto_item_append_text(item
, " CC");
366 flags
&= (~( 0x40 ));
368 proto_tree_add_boolean(tree
, hf_sbccs_dib_ccw_flags_sli
, tvb
, offset
, 1, flags
);
370 proto_item_append_text(item
, " SLI");
372 flags
&= (~( 0x20 ));
374 proto_tree_add_boolean(tree
, hf_sbccs_dib_ccw_flags_crr
, tvb
, offset
, 1, flags
);
376 proto_item_append_text(item
, " CRR");
378 /*flags &= (~( 0x08 ));*/
383 dissect_cmd_flags (proto_tree
*parent_tree
, tvbuff_t
*tvb
, int offset
, guint8 flags
)
385 proto_item
*item
= NULL
;
386 proto_tree
*tree
= NULL
;
389 item
=proto_tree_add_uint(parent_tree
, hf_sbccs_dib_cmdflags
,
390 tvb
, offset
, 1, flags
);
391 tree
=proto_item_add_subtree(item
, ett_sbccs_dib_cmdflags
);
394 proto_tree_add_boolean(tree
, hf_sbccs_dib_cmdflags_du
, tvb
, offset
, 1, flags
);
396 proto_item_append_text(item
, " DU");
398 flags
&= (~( 0x10 ));
400 proto_tree_add_boolean(tree
, hf_sbccs_dib_cmdflags_coc
, tvb
, offset
, 1, flags
);
402 proto_item_append_text(item
, " COC");
404 flags
&= (~( 0x08 ));
406 proto_tree_add_boolean(tree
, hf_sbccs_dib_cmdflags_syr
, tvb
, offset
, 1, flags
);
408 proto_item_append_text(item
, " SYR");
410 flags
&= (~( 0x04 ));
412 proto_tree_add_boolean(tree
, hf_sbccs_dib_cmdflags_rex
, tvb
, offset
, 1, flags
);
414 proto_item_append_text(item
, " REX");
416 flags
&= (~( 0x02 ));
418 proto_tree_add_boolean(tree
, hf_sbccs_dib_cmdflags_sss
, tvb
, offset
, 1, flags
);
420 proto_item_append_text(item
, " SSS");
422 /*flags &= (~( 0x01 ));*/
425 static const value_string status_ffc_val
[] = {
427 { 1, "FFC:Queuing Information Valid" },
428 { 2, "FFC:Resetting Event" },
434 dissect_status_flags (proto_tree
*parent_tree
, tvbuff_t
*tvb
, int offset
, guint8 flags
)
436 proto_item
*item
= NULL
;
437 proto_tree
*tree
= NULL
;
440 item
=proto_tree_add_uint(parent_tree
, hf_sbccs_dib_statusflags
,
441 tvb
, offset
, 1, flags
);
442 tree
=proto_item_add_subtree(item
, ett_sbccs_dib_statusflags
);
446 proto_tree_add_item (tree
, hf_sbccs_dib_statusflags_ffc
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
447 proto_item_append_text(item
, "%s", val_to_str ((flags
>>5) & 0x07, status_ffc_val
, "Reserved:0x%x"));
448 flags
&= (~( 0xE0 ));
450 proto_tree_add_boolean(tree
, hf_sbccs_dib_statusflags_ci
, tvb
, offset
, 1, flags
);
452 proto_item_append_text(item
, " CI");
454 flags
&= (~( 0x10 ));
456 proto_tree_add_boolean(tree
, hf_sbccs_dib_statusflags_cr
, tvb
, offset
, 1, flags
);
458 proto_item_append_text(item
, " CR");
460 flags
&= (~( 0x04 ));
462 proto_tree_add_boolean(tree
, hf_sbccs_dib_statusflags_lri
, tvb
, offset
, 1, flags
);
464 proto_item_append_text(item
, " LRI");
466 flags
&= (~( 0x02 ));
468 proto_tree_add_boolean(tree
, hf_sbccs_dib_statusflags_rv
, tvb
, offset
, 1, flags
);
470 proto_item_append_text(item
, " RV");
472 /*flags &= (~( 0x01 ));*/
478 dissect_status (packet_info
*pinfo
, proto_tree
*parent_tree
, tvbuff_t
*tvb
, int offset
, guint8 flags
)
480 proto_item
*item
= NULL
;
481 proto_tree
*tree
= NULL
;
484 item
=proto_tree_add_uint(parent_tree
, hf_sbccs_dib_status
,
485 tvb
, offset
, 1, flags
);
486 tree
=proto_item_add_subtree(item
, ett_sbccs_dib_status
);
490 proto_tree_add_boolean(tree
, hf_sbccs_dib_status_attention
, tvb
, offset
, 1, flags
);
492 proto_item_append_text(item
, " Attention");
493 col_append_str(pinfo
->cinfo
, COL_INFO
, " Attention");
495 flags
&= (~( 0x80 ));
497 proto_tree_add_boolean(tree
, hf_sbccs_dib_status_modifier
, tvb
, offset
, 1, flags
);
499 proto_item_append_text(item
, " Status Modifier");
500 col_append_str(pinfo
->cinfo
, COL_INFO
, " Status Modifier");
502 flags
&= (~( 0x40 ));
504 proto_tree_add_boolean(tree
, hf_sbccs_dib_status_cue
, tvb
, offset
, 1, flags
);
506 proto_item_append_text(item
, " Control-Unit End");
507 col_append_str(pinfo
->cinfo
, COL_INFO
, " Control-Unit End");
509 flags
&= (~( 0x20 ));
511 proto_tree_add_boolean(tree
, hf_sbccs_dib_status_busy
, tvb
, offset
, 1, flags
);
513 proto_item_append_text(item
, " Busy");
514 col_append_str(pinfo
->cinfo
, COL_INFO
, " Busy");
516 flags
&= (~( 0x10 ));
518 proto_tree_add_boolean(tree
, hf_sbccs_dib_status_channelend
, tvb
, offset
, 1, flags
);
520 proto_item_append_text(item
, " Channel End");
521 col_append_str(pinfo
->cinfo
, COL_INFO
, " Channel End");
523 flags
&= (~( 0x08 ));
525 proto_tree_add_boolean(tree
, hf_sbccs_dib_status_deviceend
, tvb
, offset
, 1, flags
);
527 proto_item_append_text(item
, " Device End");
528 col_append_str(pinfo
->cinfo
, COL_INFO
, " Device End");
530 flags
&= (~( 0x04 ));
532 proto_tree_add_boolean(tree
, hf_sbccs_dib_status_unit_check
, tvb
, offset
, 1, flags
);
534 proto_item_append_text(item
, " Unit Check");
535 col_append_str(pinfo
->cinfo
, COL_INFO
, " Unit Check");
537 flags
&= (~( 0x02 ));
539 proto_tree_add_boolean(tree
, hf_sbccs_dib_status_unit_exception
, tvb
, offset
, 1, flags
);
541 proto_item_append_text(item
, " Unit Exception");
542 col_append_str(pinfo
->cinfo
, COL_INFO
, " Unit Exception");
544 /*flags &= (~( 0x01 ));*/
550 dissect_sel_rst_param (proto_tree
*parent_tree
, tvbuff_t
*tvb
, int offset
, guint32 flags
)
552 proto_item
*item
= NULL
;
553 proto_tree
*tree
= NULL
;
556 item
=proto_tree_add_uint(parent_tree
, hf_sbccs_dib_ctlparam
,
557 tvb
, offset
, 3, flags
);
558 tree
=proto_item_add_subtree(item
, ett_sbccs_dib_ctlparam
);
561 proto_tree_add_boolean(tree
, hf_sbccs_dib_ctlparam_rc
, tvb
, offset
, 3, flags
);
563 proto_item_append_text(item
, " RC");
565 flags
&= (~( 0x80 ));
567 proto_tree_add_boolean(tree
, hf_sbccs_dib_ctlparam_ru
, tvb
, offset
, 3, flags
);
569 proto_item_append_text(item
, " RU");
571 flags
&= (~( 0x10 ));
573 proto_tree_add_boolean(tree
, hf_sbccs_dib_ctlparam_ro
, tvb
, offset
, 3, flags
);
575 proto_item_append_text(item
, " RO");
577 /*flags &= (~( 0x08 ));*/
580 static void get_fc_sbccs_conv_data (tvbuff_t
*tvb
, guint offset
,
581 guint16
*ch_cu_id
, guint16
*dev_addr
,
584 *ch_cu_id
= *dev_addr
= *ccw
= 0;
586 *ch_cu_id
= (tvb_get_guint8 (tvb
, offset
+1)) << 8;
587 *ch_cu_id
|= tvb_get_guint8 (tvb
, offset
+3);
588 *dev_addr
= tvb_get_ntohs (tvb
, offset
+4);
589 *ccw
= tvb_get_ntohs (tvb
, offset
+10);
592 /* Decode both the SB-3 and basic IU header */
594 dissect_fc_sbccs_sb3_iu_hdr (tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
598 proto_tree
*sb3hdr_tree
;
599 proto_tree
*iuhdr_tree
;
603 /* Decode the basic SB3 and IU header and determine type of frame */
604 type
= get_fc_sbccs_iu_type (tvb
, offset
);
606 col_add_str (pinfo
->cinfo
, COL_INFO
, val_to_str (type
, fc_sbccs_iu_val
,
610 /* Dissect SB3 header first */
611 subti
= proto_tree_add_text (tree
, tvb
, offset
, FC_SBCCS_SB3_HDR_SIZE
,
613 sb3hdr_tree
= proto_item_add_subtree (subti
, ett_fc_sbccs
);
615 proto_tree_add_item (sb3hdr_tree
, hf_sbccs_chid
, tvb
, offset
+1, 1, ENC_BIG_ENDIAN
);
616 proto_tree_add_item (sb3hdr_tree
, hf_sbccs_cuid
, tvb
, offset
+3, 1, ENC_BIG_ENDIAN
);
617 proto_tree_add_item (sb3hdr_tree
, hf_sbccs_devaddr
, tvb
, offset
+4, 2, ENC_BIG_ENDIAN
);
619 /* Dissect IU Header */
620 subti
= proto_tree_add_text (tree
, tvb
, offset
+ FC_SBCCS_SB3_HDR_SIZE
,
621 FC_SBCCS_IU_HDR_SIZE
, "IU Header");
622 iuhdr_tree
= proto_item_add_subtree (subti
, ett_fc_sbccs
);
623 offset
+= FC_SBCCS_SB3_HDR_SIZE
;
625 iui
= tvb_get_guint8 (tvb
, offset
);
626 dissect_iui_flags(iuhdr_tree
, tvb
, offset
, iui
);
628 dhflags
= tvb_get_guint8 (tvb
, offset
+1);
629 dissect_dh_flags(iuhdr_tree
, tvb
, offset
+1, dhflags
);
631 proto_tree_add_item (iuhdr_tree
, hf_sbccs_ccw
, tvb
, offset
+2, 2, ENC_BIG_ENDIAN
);
632 proto_tree_add_item (iuhdr_tree
, hf_sbccs_token
, tvb
, offset
+5, 3, ENC_BIG_ENDIAN
);
636 static void dissect_fc_sbccs_dib_data_hdr (tvbuff_t
*tvb
,
637 packet_info
*pinfo _U_
,
638 proto_tree
*tree
, guint offset
)
641 proto_tree_add_item (tree
, hf_sbccs_dib_iucnt
, tvb
, offset
+9, 1, ENC_BIG_ENDIAN
);
642 proto_tree_add_item (tree
, hf_sbccs_dib_datacnt
, tvb
, offset
+10, 2, ENC_BIG_ENDIAN
);
643 proto_tree_add_item (tree
, hf_sbccs_lrc
, tvb
, offset
+12, 4, ENC_BIG_ENDIAN
);
647 static void dissect_fc_sbccs_dib_cmd_hdr (tvbuff_t
*tvb
, packet_info
*pinfo
,
648 proto_tree
*tree
, guint offset
)
652 col_append_fstr (pinfo
->cinfo
, COL_INFO
,
653 ": %s", val_to_str (tvb_get_guint8 (tvb
, offset
),
654 fc_sbccs_dib_cmd_val
,
658 proto_tree_add_item (tree
, hf_sbccs_dib_ccw_cmd
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
660 flags
= tvb_get_guint8 (tvb
, offset
+1);
661 dissect_ccw_flags(tree
, tvb
, offset
+1, flags
);
663 proto_tree_add_item (tree
, hf_sbccs_dib_ccw_cnt
, tvb
, offset
+2, 2, ENC_BIG_ENDIAN
);
664 proto_tree_add_item (tree
, hf_sbccs_dib_ioprio
, tvb
, offset
+5, 1, ENC_BIG_ENDIAN
);
666 flags
= tvb_get_guint8 (tvb
, offset
+7);
667 dissect_cmd_flags(tree
, tvb
, offset
+7, flags
);
669 proto_tree_add_item (tree
, hf_sbccs_dib_iucnt
, tvb
, offset
+9, 1, ENC_BIG_ENDIAN
);
670 proto_tree_add_item (tree
, hf_sbccs_dib_datacnt
, tvb
, offset
+10, 2, ENC_BIG_ENDIAN
);
671 proto_tree_add_item (tree
, hf_sbccs_lrc
, tvb
, offset
+12, 4, ENC_BIG_ENDIAN
);
676 static void dissect_fc_sbccs_dib_status_hdr (tvbuff_t
*tvb
, packet_info
*pinfo
,
677 proto_tree
*tree
, guint offset
)
680 gboolean rv_valid
, qparam_valid
;
682 guint16 supp_status_cnt
= 0;
685 flags
= tvb_get_guint8 (tvb
, offset
);
686 rv_valid
= flags
& 0x1; /* if residual count is valid */
687 qparam_valid
= (((flags
& 0xE0) >> 5) == 0x1); /* From the FFC field */
688 dissect_status_flags(tree
, tvb
, offset
, flags
);
690 flags
= tvb_get_guint8 (tvb
, offset
+1);
691 dissect_status(pinfo
, tree
, tvb
, offset
+1, flags
);
694 proto_tree_add_item (tree
, hf_sbccs_dib_residualcnt
, tvb
, offset
+2,
698 proto_tree_add_item (tree
, hf_sbccs_dib_iupacing
, tvb
, offset
+3,
703 proto_tree_add_item (tree
, hf_sbccs_dib_qtuf
, tvb
, offset
+4, 1, ENC_BIG_ENDIAN
);
704 proto_tree_add_item (tree
, hf_sbccs_dib_qtu
, tvb
, offset
+4, 2, ENC_BIG_ENDIAN
);
707 proto_tree_add_item (tree
, hf_sbccs_dib_dtuf
, tvb
, offset
+6, 1, ENC_BIG_ENDIAN
);
708 proto_tree_add_item (tree
, hf_sbccs_dib_dtu
, tvb
, offset
+6, 2, ENC_BIG_ENDIAN
);
710 proto_tree_add_item (tree
, hf_sbccs_dib_iucnt
, tvb
, offset
+9, 1, ENC_BIG_ENDIAN
);
711 proto_tree_add_item (tree
, hf_sbccs_dib_datacnt
, tvb
, offset
+10, 2, ENC_BIG_ENDIAN
);
712 proto_tree_add_item (tree
, hf_sbccs_lrc
, tvb
, offset
+12, 4, ENC_BIG_ENDIAN
);
715 supp_status_cnt
= tvb_get_ntohs (tvb
, offset
+10);
717 if (supp_status_cnt
) {
718 next_tvb
= tvb_new_subset_remaining (tvb
, offset
+FC_SBCCS_DIB_LRC_HDR_SIZE
);
719 call_dissector (data_handle
, next_tvb
, pinfo
, tree
);
723 static void dissect_fc_sbccs_dib_ctl_hdr (tvbuff_t
*tvb
, packet_info
*pinfo
,
724 proto_tree
*tree
, guint offset
)
728 ctlfn
= tvb_get_guint8 (tvb
, offset
);
729 col_append_fstr (pinfo
->cinfo
, COL_INFO
,
732 fc_sbccs_dib_ctl_fn_val
,
736 proto_tree_add_item (tree
, hf_sbccs_dib_ctlfn
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
738 /* Control Function Parameter is to be interpreted in some cases */
740 case FC_SBCCS_CTL_FN_SEL_RST
:
741 dissect_sel_rst_param(tree
, tvb
, offset
+1, tvb_get_ntoh24 (tvb
, offset
+1));
743 case FC_SBCCS_CTL_FN_DEV_XCP
:
744 proto_tree_add_item (tree
, hf_sbccs_dev_xcp_code
, tvb
, offset
+1,
747 case FC_SBCCS_CTL_FN_PRG_PTH
:
748 proto_tree_add_item (tree
, hf_sbccs_prg_pth_errcode
, tvb
, offset
+1,
752 proto_tree_add_item (tree
, hf_sbccs_dib_ctlparam
, tvb
, offset
+1,
757 proto_tree_add_item (tree
, hf_sbccs_dib_iucnt
, tvb
, offset
+9, 1, ENC_BIG_ENDIAN
);
758 proto_tree_add_item (tree
, hf_sbccs_dib_datacnt
, tvb
, offset
+10, 2, ENC_BIG_ENDIAN
);
759 proto_tree_add_item (tree
, hf_sbccs_lrc
, tvb
, offset
+12, 4, ENC_BIG_ENDIAN
);
761 if (ctlfn
== FC_SBCCS_CTL_FN_PRG_RSP
) {
762 /* Need to decode the LESBs */
763 proto_tree_add_item (tree
, hf_sbccs_prg_rsp_errcode
, tvb
, offset
+60,
769 static void dissect_fc_sbccs_dib_link_hdr (tvbuff_t
*tvb
, packet_info
*pinfo
,
770 proto_tree
*tree
, guint offset
)
774 guint link_payload_len
, i
;
776 col_append_fstr (pinfo
->cinfo
, COL_INFO
,
778 val_to_str (tvb_get_guint8 (tvb
, offset
+1),
779 fc_sbccs_dib_link_ctl_fn_val
,
783 link_ctl
= tvb_get_guint8 (tvb
, offset
+1);
784 proto_tree_add_item (tree
, hf_sbccs_dib_linkctlfn
, tvb
, offset
+1, 1, ENC_BIG_ENDIAN
);
786 ctl_info
= tvb_get_ntohs (tvb
, offset
+2);
788 case FC_SBCCS_LINK_CTL_FN_ELP
:
789 case FC_SBCCS_LINK_CTL_FN_LPE
:
790 dissect_linkctlinfo(tree
, tvb
, offset
+2, ctl_info
);
792 case FC_SBCCS_LINK_CTL_FN_LPR
:
793 proto_tree_add_item (tree
, hf_sbccs_dib_lprcode
, tvb
, offset
+2, 1,
796 case FC_SBCCS_LINK_CTL_FN_TIN
:
797 proto_tree_add_item (tree
, hf_sbccs_dib_tin_imgid_cnt
, tvb
,
798 offset
+3, 1, ENC_BIG_ENDIAN
);
800 case FC_SBCCS_LINK_CTL_FN_TIR
:
801 proto_tree_add_item (tree
, hf_sbccs_dib_tin_imgid_cnt
, tvb
,
802 offset
+3, 1, ENC_BIG_ENDIAN
);
804 case FC_SBCCS_LINK_CTL_FN_LRJ
:
805 proto_tree_add_item (tree
, hf_sbccs_dib_lrjcode
, tvb
, offset
+2,
813 proto_tree_add_item (tree
, hf_sbccs_dib_ctccntr
, tvb
, offset
+4, 2, ENC_BIG_ENDIAN
);
814 proto_tree_add_item (tree
, hf_sbccs_dib_iucnt
, tvb
, offset
+9, 1, ENC_BIG_ENDIAN
);
815 proto_tree_add_item (tree
, hf_sbccs_dib_datacnt
, tvb
, offset
+10, 2, ENC_BIG_ENDIAN
);
816 proto_tree_add_item (tree
, hf_sbccs_lrc
, tvb
, offset
+12, 4, ENC_BIG_ENDIAN
);
818 if (link_ctl
== FC_SBCCS_LINK_CTL_FN_TIR
) {
819 link_payload_len
= tvb_get_ntohs (tvb
, offset
+10);
823 while (i
< link_payload_len
) {
824 proto_tree_add_text (tree
, tvb
, offset
, 4,
825 "Logical Paths %d-%d: %s",
827 tvb_bytes_to_str_punct (tvb
, offset
, 4, ':'));
835 static void dissect_fc_sbccs (tvbuff_t
*tvb
, packet_info
*pinfo
,
839 guint16 ch_cu_id
, dev_addr
, ccw
;
842 proto_tree
*sb3_tree
= NULL
;
843 proto_tree
*dib_tree
= NULL
;
845 conversation_t
*conversation
;
847 sb3_task_id_t task_key
;
850 /* Make entries in Protocol column and Info column on summary display */
851 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "FC-SB3");
853 /* Decode the basic SB3 and IU header and determine type of frame */
854 type
= get_fc_sbccs_iu_type (tvb
, offset
);
855 get_fc_sbccs_conv_data (tvb
, offset
, &ch_cu_id
, &dev_addr
, &ccw
);
857 col_add_str (pinfo
->cinfo
, COL_INFO
, val_to_str (type
, fc_sbccs_iu_val
,
860 /* Retrieve conversation state to determine expected payload */
861 conversation
= find_conversation (pinfo
->fd
->num
, &pinfo
->src
, &pinfo
->dst
,
862 PT_SBCCS
, ch_cu_id
, dev_addr
, 0);
866 task_key
.conv_id
= conversation
->index
;
867 task_key
.task_id
= ccw
;
870 else if ((type
== FC_SBCCS_IU_CMD_HDR
) ||
871 (type
!= FC_SBCCS_IU_CMD_DATA
)) {
872 conversation
= conversation_new (pinfo
->fd
->num
, &pinfo
->src
, &pinfo
->dst
,
873 PT_SBCCS
, ch_cu_id
, dev_addr
, 0);
875 task_key
.conv_id
= conversation
->index
;
876 task_key
.task_id
= ccw
;
881 ti
= proto_tree_add_protocol_format (tree
, proto_fc_sbccs
, tvb
, 0, -1,
883 sb3_tree
= proto_item_add_subtree (ti
, ett_fc_sbccs
);
885 dissect_fc_sbccs_sb3_iu_hdr (tvb
, pinfo
, sb3_tree
, offset
);
886 offset
+= (FC_SBCCS_SB3_HDR_SIZE
+ FC_SBCCS_IU_HDR_SIZE
);
888 ti
= proto_tree_add_text (sb3_tree
, tvb
, offset
,
889 FC_SBCCS_DIB_LRC_HDR_SIZE
, "DIB Header");
890 dib_tree
= proto_item_add_subtree (ti
, ett_fc_sbccs
);
893 offset
+= (FC_SBCCS_SB3_HDR_SIZE
+ FC_SBCCS_IU_HDR_SIZE
);
897 case FC_SBCCS_IU_DATA
:
898 dissect_fc_sbccs_dib_data_hdr (tvb
, pinfo
, dib_tree
, offset
);
900 case FC_SBCCS_IU_CMD_HDR
:
901 case FC_SBCCS_IU_CMD_DATA
:
902 dissect_fc_sbccs_dib_cmd_hdr (tvb
, pinfo
, dib_tree
, offset
);
904 case FC_SBCCS_IU_STATUS
:
905 dissect_fc_sbccs_dib_status_hdr (tvb
, pinfo
, dib_tree
, offset
);
907 case FC_SBCCS_IU_CTL
:
908 dissect_fc_sbccs_dib_ctl_hdr (tvb
, pinfo
, dib_tree
, offset
);
910 case FC_SBCCS_IU_CMD_LINK_CTL
:
911 dissect_fc_sbccs_dib_link_hdr (tvb
, pinfo
, dib_tree
, offset
);
914 next_tvb
= tvb_new_subset_remaining (tvb
, offset
);
915 call_dissector (data_handle
, next_tvb
, pinfo
, dib_tree
);
919 if ((get_fc_sbccs_iu_type (tvb
, 0) != FC_SBCCS_IU_CTL
) &&
920 (get_fc_sbccs_iu_type (tvb
, 0) != FC_SBCCS_IU_CMD_LINK_CTL
)) {
921 next_tvb
= tvb_new_subset_remaining (tvb
, offset
+FC_SBCCS_DIB_LRC_HDR_SIZE
);
922 call_dissector (data_handle
, next_tvb
, pinfo
, tree
);
926 /* Register the protocol with Wireshark */
928 /* this format is required because a script is used to build the C function
929 that calls all the protocol registration.
933 proto_register_fcsbccs (void)
935 /* Setup list of header fields See Section 1.6.1 for details*/
936 static hf_register_info hf
[] = {
938 { "Channel Image ID", "fcsb3.chid",
939 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
943 { "Control Unit Image ID", "fcsb3.cuid",
944 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
948 { "Device Address", "fcsb3.devaddr",
949 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
953 { "Information Unit Identifier", "fcsb3.iui",
954 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
958 { "DH Flags", "fcsb3.dhflags",
959 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
963 { "CCW Number", "fcsb3.ccw",
964 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
968 { "Token", "fcsb3.token",
969 FT_UINT24
, BASE_DEC
, NULL
, 0x0,
972 { &hf_sbccs_dib_iucnt
,
973 { "DIB IU Count", "fcsb3.iucnt",
974 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
977 { &hf_sbccs_dib_datacnt
,
978 { "DIB Data Byte Count", "fcsb3.databytecnt",
979 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
982 { &hf_sbccs_dib_ccw_cmd
,
983 { "CCW Command", "fcsb3.ccwcmd",
984 FT_UINT8
, BASE_HEX
, VALS (fc_sbccs_dib_cmd_val
), 0x0,
987 { &hf_sbccs_dib_ccw_cnt
,
988 { "CCW Count", "fcsb3.ccwcnt",
989 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
992 { &hf_sbccs_dib_ioprio
,
993 { "I/O Priority", "fcsb3.ioprio",
994 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
997 { &hf_sbccs_dib_status
,
998 { "Status", "fcsb3.status",
999 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
1002 { &hf_sbccs_dib_residualcnt
,
1003 { "Residual Count", "fcsb3.residualcnt",
1004 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1007 { &hf_sbccs_dib_iupacing
,
1008 { "IU Pacing", "fcsb3.iupacing",
1009 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1012 { &hf_sbccs_dib_qtuf
,
1013 { "Queue-Time Unit Factor", "fcsb3.qtuf",
1014 FT_UINT8
, BASE_DEC
, NULL
, 0xF0,
1017 { &hf_sbccs_dib_qtu
,
1018 { "Queue-Time Unit", "fcsb3.qtu",
1019 FT_UINT16
, BASE_DEC
, NULL
, 0xFFF,
1022 { &hf_sbccs_dib_dtuf
,
1023 { "Defer-Time Unit Function", "fcsb3.dtuf",
1024 FT_UINT8
, BASE_DEC
, NULL
, 0xF0,
1027 { &hf_sbccs_dib_dtu
,
1028 { "Defer-Time Unit", "fcsb3.dtu",
1029 FT_UINT16
, BASE_DEC
, NULL
, 0xFFF,
1032 { &hf_sbccs_dib_ctlfn
,
1033 { "Control Function", "fcsb3.ctlfn",
1034 FT_UINT8
, BASE_HEX
, VALS (fc_sbccs_dib_ctl_fn_val
), 0x0,
1037 { &hf_sbccs_dib_linkctlfn
,
1038 { "Link Control Function", "fcsb3.linkctlfn",
1039 FT_UINT8
, BASE_HEX
, VALS (fc_sbccs_dib_link_ctl_fn_val
), 0x0,
1042 { &hf_sbccs_dib_ctccntr
,
1043 { "CTC Counter", "fcsb3.ctccntr",
1044 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1048 { "LRC", "fcsb3.lrc",
1049 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
1052 { &hf_sbccs_dev_xcp_code
,
1053 { "Device Level Exception Code", "fcsb3.dip.xcpcode",
1054 FT_UINT8
, BASE_DEC
, VALS (fc_sbccs_dib_dev_xcpcode_val
), 0x0,
1057 { &hf_sbccs_prg_pth_errcode
,
1058 { "Purge Path Error Code", "fcsb3.purgepathcode",
1059 FT_UINT8
, BASE_DEC
, VALS (fc_sbccs_dib_purge_path_err_val
), 0x0,
1062 { &hf_sbccs_prg_rsp_errcode
,
1063 { "Purge Path Response Error Code", "fcsb3.purgepathrspcode",
1064 FT_UINT8
, BASE_DEC
, VALS (fc_sbccs_dib_purge_path_rsp_err_val
), 0x0,
1067 { &hf_sbccs_dib_lprcode
,
1068 { "LPR Reason Code", "fcsb3.lprcode",
1069 FT_UINT8
, BASE_DEC
, VALS (fc_sbccs_dib_lpr_errcode_val
), 0xF,
1072 { &hf_sbccs_dib_tin_imgid_cnt
,
1073 { "TIN Image ID", "fcsb3.tinimageidcnt",
1074 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1077 { &hf_sbccs_dib_lrjcode
,
1078 { "LRJ Reaspn Code", "fcsb3.lrjcode",
1079 FT_UINT8
, BASE_HEX
, VALS (fc_sbccs_dib_lrj_errcode_val
), 0x7F,
1083 { "AS", "fcsb3.iui.as",
1084 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), 0x10,
1088 { "ES", "fcsb3.iui.es",
1089 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), 0x08,
1092 { &hf_sbccs_iui_val
,
1093 { "Val", "fcsb3.iui.val",
1094 FT_UINT8
, BASE_HEX
, VALS(fc_sbccs_iu_val
), 0x07,
1097 { &hf_sbccs_dhflags_end
,
1098 { "End", "fcsb3.dhflags.end",
1099 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), 0x80,
1102 { &hf_sbccs_dhflags_chaining
,
1103 { "Chaining", "fcsb3.dhflags.chaining",
1104 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), 0x10,
1107 { &hf_sbccs_dhflags_earlyend
,
1108 { "Early End", "fcsb3.dhflags.earlyend",
1109 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), 0x08,
1112 { &hf_sbccs_dhflags_nocrc
,
1113 { "No CRC", "fcsb3.dhflags.nocrc",
1114 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), 0x04,
1117 { &hf_sbccs_dib_ccw_flags
,
1118 { "CCW Control Flags", "fcsb3.ccwflags",
1119 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
1122 { &hf_sbccs_dib_ccw_flags_cd
,
1123 { "CD", "fcsb3.ccwflags.cd",
1124 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), 0x80,
1127 { &hf_sbccs_dib_ccw_flags_cc
,
1128 { "CC", "fcsb3.ccwflags.cc",
1129 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), 0x40,
1132 { &hf_sbccs_dib_ccw_flags_sli
,
1133 { "SLI", "fcsb3.ccwflags.sli",
1134 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), 0x20,
1137 { &hf_sbccs_dib_ccw_flags_crr
,
1138 { "CRR", "fcsb3.ccwflags.crr",
1139 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), 0x08,
1142 { &hf_sbccs_dib_cmdflags
,
1143 { "Command Flags", "fcsb3.cmdflags",
1144 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
1147 { &hf_sbccs_dib_cmdflags_du
,
1148 { "DU", "fcsb3.cmdflags.du",
1149 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), 0x10,
1152 { &hf_sbccs_dib_cmdflags_coc
,
1153 { "COC", "fcsb3.cmdflags.coc",
1154 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), 0x08,
1157 { &hf_sbccs_dib_cmdflags_syr
,
1158 { "SYR", "fcsb3.cmdflags.syr",
1159 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), 0x04,
1162 { &hf_sbccs_dib_cmdflags_rex
,
1163 { "REX", "fcsb3.cmdflags.rex",
1164 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), 0x02,
1167 { &hf_sbccs_dib_cmdflags_sss
,
1168 { "SSS", "fcsb3.cmdflags.sss",
1169 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), 0x01,
1172 { &hf_sbccs_dib_statusflags
,
1173 { "Status Flags", "fcsb3.statusflags",
1174 FT_UINT8
, BASE_HEX
, NULL
, 0,
1177 { &hf_sbccs_dib_statusflags_ffc
,
1178 { "FFC", "fcsb3.statusflags.ffc",
1179 FT_UINT8
, BASE_HEX
, VALS(status_ffc_val
), 0xE0,
1182 { &hf_sbccs_dib_statusflags_ci
,
1183 { "CI", "fcsb3.statusflags.ci",
1184 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), 0x10,
1187 { &hf_sbccs_dib_statusflags_cr
,
1188 { "CR", "fcsb3.statusflags.cr",
1189 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), 0x04,
1192 { &hf_sbccs_dib_statusflags_lri
,
1193 { "LRI", "fcsb3.statusflags.lri",
1194 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), 0x02,
1197 { &hf_sbccs_dib_statusflags_rv
,
1198 { "RV", "fcsb3.statusflags.rv",
1199 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), 0x01,
1202 { &hf_sbccs_dib_status_attention
,
1203 { "Attention", "fcsb3.status.attention",
1204 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), 0x80,
1207 { &hf_sbccs_dib_status_modifier
,
1208 { "Status Modifier", "fcsb3.status.modifier",
1209 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), 0x40,
1212 { &hf_sbccs_dib_status_cue
,
1213 { "Control-Unit End", "fcsb3.status.cue",
1214 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), 0x20,
1217 { &hf_sbccs_dib_status_busy
,
1218 { "Busy", "fcsb3.status.busy",
1219 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), 0x10,
1222 { &hf_sbccs_dib_status_channelend
,
1223 { "Channel End", "fcsb3.status.channel_end",
1224 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), 0x08,
1227 { &hf_sbccs_dib_status_deviceend
,
1228 { "Device End", "fcsb3.status.device_end",
1229 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), 0x04,
1232 { &hf_sbccs_dib_status_unit_check
,
1233 { "Unit Check", "fcsb3.status.unit_check",
1234 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), 0x02,
1237 { &hf_sbccs_dib_status_unit_exception
,
1238 { "Unit Exception", "fcsb3.status.unitexception",
1239 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), 0x01,
1242 { &hf_sbccs_dib_ctlparam
,
1243 { "Control Parameters", "fcsb3.ctlparam",
1244 FT_UINT24
, BASE_HEX
, NULL
, 0x0,
1247 { &hf_sbccs_dib_ctlparam_rc
,
1248 { "RC", "fcsb3.ctlparam.rc",
1249 FT_BOOLEAN
, 24, TFS(&tfs_set_notset
), 0x80,
1252 { &hf_sbccs_dib_ctlparam_ru
,
1253 { "RU", "fcsb3.ctlparam.ru",
1254 FT_BOOLEAN
, 24, TFS(&tfs_set_notset
), 0x10,
1257 { &hf_sbccs_dib_ctlparam_ro
,
1258 { "RO", "fcsb3.ctlparam.ro",
1259 FT_BOOLEAN
, 24, TFS(&tfs_set_notset
), 0x08,
1262 { &hf_sbccs_dib_linkctlinfo
,
1263 { "Link Control Information", "fcsb3.linkctlinfo",
1264 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
1267 { &hf_sbccs_dib_linkctlinfo_ctcconn
,
1268 { "CTC Conn", "fcsb3.linkctlinfo.ctc_conn",
1269 FT_BOOLEAN
, 16, TFS(&tfs_supported_not_supported
), 0x80,
1272 { &hf_sbccs_dib_linkctlinfo_ecrcg
,
1273 { "Enhanced CRC Generation", "fcsb3.linkctlinfo.ecrcg",
1274 FT_BOOLEAN
, 16, TFS(&tfs_supported_not_supported
), 0x01,
1279 /* Setup protocol subtree array */
1280 static gint
*ett
[] = {
1284 &ett_sbccs_dib_ccw_flags
,
1285 &ett_sbccs_dib_cmdflags
,
1286 &ett_sbccs_dib_statusflags
,
1287 &ett_sbccs_dib_status
,
1288 &ett_sbccs_dib_ctlparam
,
1289 &ett_sbccs_dib_linkctlinfo
,
1292 /* Register the protocol name and description */
1293 proto_fc_sbccs
= proto_register_protocol ("Fibre Channel Single Byte Command",
1296 proto_register_field_array(proto_fc_sbccs
, hf
, array_length(hf
));
1297 proto_register_subtree_array(ett
, array_length(ett
));
1301 proto_reg_handoff_fcsbccs (void)
1303 dissector_handle_t fc_sbccs_handle
;
1305 fc_sbccs_handle
= create_dissector_handle (dissect_fc_sbccs
,
1308 dissector_add_uint("fc.ftype", FC_FTYPE_SBCCS
, fc_sbccs_handle
);
1310 data_handle
= find_dissector ("data");