HACK: pinfo->private_data points to smb_info again
[wireshark-wip.git] / epan / dissectors / packet-fcsb3.c
blob4e51ee643bf5d3e3d52f6bfac92ff065457953d3
1 /* packet-fc-sb3.c
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>
6 * $Id$
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.
27 #include "config.h"
29 #include <glib.h>
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;
122 #if 0
123 typedef struct {
124 guint32 conv_id;
125 guint32 task_id;
126 } sb3_task_id_t;
127 #endif
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"},
136 {0x6, "Reserved"},
137 {0x7, "Reserved"},
138 {0x0, NULL},
141 static const value_string fc_sbccs_dib_cmd_val[] = {
142 { 0, "Reserved"},
143 { 1, "Write"},
144 { 2, "Read"},
145 { 3, "Control"},
146 { 4, "Sense"},
147 { 5, "Write (Modifier)"},
148 { 6, "Read (Modifier)"},
149 { 7, "Control (Modifier)"},
150 { 8, "Reserved"},
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)"},
158 {0, NULL},
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"},
174 {0, NULL},
177 static const value_string fc_sbccs_dib_dev_xcpcode_val[] = {
178 {1, "Address Exception"},
179 {0, NULL},
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"},
186 { 3, "Reserved"},
187 { 4, "SB-3 Offline Condition"},
188 { 5, "FC-PH Link Failure"},
189 { 6, "SB-3 Length Error"},
190 { 7, "LRC 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"},
198 {15, "Reserved"},
199 {0, NULL},
202 static const value_string fc_sbccs_dib_purge_path_rsp_err_val[] = {
203 { 0, "No Errors"},
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"},
210 { 7, "LRC 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"},
216 {13, "Reserved"},
217 {14, "Abnormal Termination of Xchg"},
218 {15, "Logical Path Not Estd"},
219 {16, "Test Init Result Error"},
220 {0, NULL},
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"},
233 {0, NULL},
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"},
242 {0x0, NULL},
245 static const value_string fc_sbccs_dib_lrj_errcode_val[] = {
246 {0x6, "Logical Path Not Estd"},
247 {0x9, "Protocol Error"},
248 {0x0, NULL},
251 static void
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;
257 if (parent_tree) {
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);
264 if (flags & 0x10) {
265 proto_item_append_text(item, " AS");
267 flags &= (~( 0x10 ));
269 proto_tree_add_boolean(tree, hf_sbccs_iui_es, tvb, offset, 1, flags);
270 if (flags & 0x08) {
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 ));*/
280 static void
281 dissect_linkctlinfo (proto_tree *parent_tree, tvbuff_t *tvb, int offset, guint16 flags)
283 proto_item *item = NULL;
284 proto_tree *tree = NULL;
286 if (parent_tree) {
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);
293 if (flags & 0x80) {
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);
299 if (flags & 0x01) {
300 proto_item_append_text(item, " Enhanced CRC Gen");
302 /*flags &= (~( 0x01 ));*/
306 static void
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;
312 if (parent_tree) {
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);
319 if (flags & 0x80) {
320 proto_item_append_text(item, " End");
322 flags &= (~( 0x80 ));
324 proto_tree_add_boolean(tree, hf_sbccs_dhflags_chaining, tvb, offset, 1, flags);
325 if (flags & 0x10) {
326 proto_item_append_text(item, " Chaining");
328 flags &= (~( 0x10 ));
330 proto_tree_add_boolean(tree, hf_sbccs_dhflags_earlyend, tvb, offset, 1, flags);
331 if (flags & 0x08) {
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);
337 if (flags & 0x04) {
338 proto_item_append_text(item, " No CRC");
340 /*flags &= (~( 0x04 ));*/
344 static void
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;
350 if (parent_tree) {
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);
357 if (flags & 0x80) {
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);
363 if (flags & 0x40) {
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);
369 if (flags & 0x20) {
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);
375 if (flags & 0x08) {
376 proto_item_append_text(item, " CRR");
378 /*flags &= (~( 0x08 ));*/
382 static void
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;
388 if (parent_tree) {
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);
395 if (flags & 0x10) {
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);
401 if (flags & 0x08) {
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);
407 if (flags & 0x04) {
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);
413 if (flags & 0x02) {
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);
419 if (flags & 0x01) {
420 proto_item_append_text(item, " SSS");
422 /*flags &= (~( 0x01 ));*/
425 static const value_string status_ffc_val[] = {
426 { 0, "" },
427 { 1, "FFC:Queuing Information Valid" },
428 { 2, "FFC:Resetting Event" },
429 { 0, NULL }
433 static void
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;
439 if (parent_tree) {
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);
451 if (flags & 0x10) {
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);
457 if (flags & 0x04) {
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);
463 if (flags & 0x02) {
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);
469 if (flags & 0x01) {
470 proto_item_append_text(item, " RV");
472 /*flags &= (~( 0x01 ));*/
477 static void
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;
483 if (parent_tree) {
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);
491 if (flags & 0x80) {
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);
498 if (flags & 0x40) {
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);
505 if (flags & 0x20) {
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);
512 if (flags & 0x10) {
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);
519 if (flags & 0x08) {
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);
526 if (flags & 0x04) {
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);
533 if (flags & 0x02) {
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);
540 if (flags & 0x01) {
541 proto_item_append_text(item, " Unit Exception");
542 col_append_str(pinfo->cinfo, COL_INFO, " Unit Exception");
544 /*flags &= (~( 0x01 ));*/
549 static void
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;
555 if (parent_tree) {
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);
562 if (flags & 0x80) {
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);
568 if (flags & 0x10) {
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);
574 if (flags & 0x08) {
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,
582 guint16 *ccw)
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 */
593 static void
594 dissect_fc_sbccs_sb3_iu_hdr (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
595 guint offset)
597 proto_item *subti;
598 proto_tree *sb3hdr_tree;
599 proto_tree *iuhdr_tree;
600 guint8 iui, dhflags;
601 guint type;
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,
607 "0x%x"));
609 if (tree) {
610 /* Dissect SB3 header first */
611 subti = proto_tree_add_text (tree, tvb, offset, FC_SBCCS_SB3_HDR_SIZE,
612 "SB-3 Header");
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)
640 if (tree) {
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)
650 guint8 flags;
652 col_append_fstr (pinfo->cinfo, COL_INFO,
653 ": %s", val_to_str (tvb_get_guint8 (tvb, offset),
654 fc_sbccs_dib_cmd_val,
655 "0x%x"));
657 if (tree) {
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)
679 guint8 flags;
680 gboolean rv_valid, qparam_valid;
681 tvbuff_t *next_tvb;
682 guint16 supp_status_cnt = 0;
684 if (tree) {
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);
693 if (rv_valid) {
694 proto_tree_add_item (tree, hf_sbccs_dib_residualcnt, tvb, offset+2,
695 2, ENC_BIG_ENDIAN);
697 else {
698 proto_tree_add_item (tree, hf_sbccs_dib_iupacing, tvb, offset+3,
699 1, ENC_BIG_ENDIAN);
702 if (qparam_valid) {
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)
726 guint8 ctlfn;
728 ctlfn = tvb_get_guint8 (tvb, offset);
729 col_append_fstr (pinfo->cinfo, COL_INFO,
730 ": %s",
731 val_to_str (ctlfn,
732 fc_sbccs_dib_ctl_fn_val,
733 "0x%x"));
735 if (tree) {
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 */
739 switch (ctlfn) {
740 case FC_SBCCS_CTL_FN_SEL_RST:
741 dissect_sel_rst_param(tree, tvb, offset+1, tvb_get_ntoh24 (tvb, offset+1));
742 break;
743 case FC_SBCCS_CTL_FN_DEV_XCP:
744 proto_tree_add_item (tree, hf_sbccs_dev_xcp_code, tvb, offset+1,
745 1, ENC_BIG_ENDIAN);
746 break;
747 case FC_SBCCS_CTL_FN_PRG_PTH:
748 proto_tree_add_item (tree, hf_sbccs_prg_pth_errcode, tvb, offset+1,
749 1, ENC_BIG_ENDIAN);
750 break;
751 default:
752 proto_tree_add_item (tree, hf_sbccs_dib_ctlparam, tvb, offset+1,
753 3, ENC_BIG_ENDIAN);
754 break;
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,
764 1, ENC_BIG_ENDIAN);
769 static void dissect_fc_sbccs_dib_link_hdr (tvbuff_t *tvb, packet_info *pinfo,
770 proto_tree *tree, guint offset)
772 guint8 link_ctl;
773 guint16 ctl_info;
774 guint link_payload_len, i;
776 col_append_fstr (pinfo->cinfo, COL_INFO,
777 ": %s",
778 val_to_str (tvb_get_guint8 (tvb, offset+1),
779 fc_sbccs_dib_link_ctl_fn_val,
780 "0x%x"));
782 if (tree) {
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);
787 switch (link_ctl) {
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);
791 break;
792 case FC_SBCCS_LINK_CTL_FN_LPR:
793 proto_tree_add_item (tree, hf_sbccs_dib_lprcode, tvb, offset+2, 1,
794 ENC_BIG_ENDIAN);
795 break;
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);
799 break;
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);
803 break;
804 case FC_SBCCS_LINK_CTL_FN_LRJ:
805 proto_tree_add_item (tree, hf_sbccs_dib_lrjcode, tvb, offset+2,
806 1, ENC_BIG_ENDIAN);
807 break;
808 default:
809 /* Do Nothing */
810 break;
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);
820 i = 0;
821 offset += 16;
823 while (i < link_payload_len) {
824 proto_tree_add_text (tree, tvb, offset, 4,
825 "Logical Paths %d-%d: %s",
826 i*8, ((i+4)*8) - 1,
827 tvb_bytes_to_str_punct (tvb, offset, 4, ':'));
828 i += 4;
829 offset += 4;
835 static void dissect_fc_sbccs (tvbuff_t *tvb, packet_info *pinfo,
836 proto_tree *tree)
838 guint8 type;
839 guint16 ch_cu_id, dev_addr, ccw;
840 guint offset = 0;
841 proto_item *ti;
842 proto_tree *sb3_tree = NULL;
843 proto_tree *dib_tree = NULL;
844 tvbuff_t *next_tvb;
845 conversation_t *conversation;
846 #if 0
847 sb3_task_id_t task_key;
848 #endif
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,
858 "0x%x"));
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);
864 if (conversation) {
865 #if 0
866 task_key.conv_id = conversation->index;
867 task_key.task_id = ccw;
868 #endif
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);
874 #if 0
875 task_key.conv_id = conversation->index;
876 task_key.task_id = ccw;
877 #endif
880 if (tree) {
881 ti = proto_tree_add_protocol_format (tree, proto_fc_sbccs, tvb, 0, -1,
882 "FC-SB3");
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);
892 else {
893 offset += (FC_SBCCS_SB3_HDR_SIZE + FC_SBCCS_IU_HDR_SIZE);
896 switch (type) {
897 case FC_SBCCS_IU_DATA:
898 dissect_fc_sbccs_dib_data_hdr (tvb, pinfo, dib_tree, offset);
899 break;
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);
903 break;
904 case FC_SBCCS_IU_STATUS:
905 dissect_fc_sbccs_dib_status_hdr (tvb, pinfo, dib_tree, offset);
906 break;
907 case FC_SBCCS_IU_CTL:
908 dissect_fc_sbccs_dib_ctl_hdr (tvb, pinfo, dib_tree, offset);
909 break;
910 case FC_SBCCS_IU_CMD_LINK_CTL:
911 dissect_fc_sbccs_dib_link_hdr (tvb, pinfo, dib_tree, offset);
912 break;
913 default:
914 next_tvb = tvb_new_subset_remaining (tvb, offset);
915 call_dissector (data_handle, next_tvb, pinfo, dib_tree);
916 break;
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.
932 void
933 proto_register_fcsbccs (void)
935 /* Setup list of header fields See Section 1.6.1 for details*/
936 static hf_register_info hf[] = {
937 { &hf_sbccs_chid,
938 { "Channel Image ID", "fcsb3.chid",
939 FT_UINT8, BASE_DEC, NULL, 0x0,
940 NULL, HFILL}},
942 { &hf_sbccs_cuid,
943 { "Control Unit Image ID", "fcsb3.cuid",
944 FT_UINT8, BASE_DEC, NULL, 0x0,
945 NULL, HFILL}},
947 { &hf_sbccs_devaddr,
948 { "Device Address", "fcsb3.devaddr",
949 FT_UINT16, BASE_DEC, NULL, 0x0,
950 NULL, HFILL}},
952 { &hf_sbccs_iui,
953 { "Information Unit Identifier", "fcsb3.iui",
954 FT_UINT8, BASE_HEX, NULL, 0x0,
955 NULL, HFILL}},
957 { &hf_sbccs_dhflags,
958 { "DH Flags", "fcsb3.dhflags",
959 FT_UINT8, BASE_HEX, NULL, 0x0,
960 NULL, HFILL}},
962 { &hf_sbccs_ccw,
963 { "CCW Number", "fcsb3.ccw",
964 FT_UINT16, BASE_HEX, NULL, 0x0,
965 NULL, HFILL}},
967 { &hf_sbccs_token,
968 { "Token", "fcsb3.token",
969 FT_UINT24, BASE_DEC, NULL, 0x0,
970 NULL, HFILL}},
972 { &hf_sbccs_dib_iucnt,
973 { "DIB IU Count", "fcsb3.iucnt",
974 FT_UINT8, BASE_DEC, NULL, 0x0,
975 NULL, HFILL}},
977 { &hf_sbccs_dib_datacnt,
978 { "DIB Data Byte Count", "fcsb3.databytecnt",
979 FT_UINT16, BASE_DEC, NULL, 0x0,
980 NULL, HFILL}},
982 { &hf_sbccs_dib_ccw_cmd,
983 { "CCW Command", "fcsb3.ccwcmd",
984 FT_UINT8, BASE_HEX, VALS (fc_sbccs_dib_cmd_val), 0x0,
985 NULL, HFILL}},
987 { &hf_sbccs_dib_ccw_cnt,
988 { "CCW Count", "fcsb3.ccwcnt",
989 FT_UINT16, BASE_DEC, NULL, 0x0,
990 NULL, HFILL}},
992 { &hf_sbccs_dib_ioprio,
993 { "I/O Priority", "fcsb3.ioprio",
994 FT_UINT8, BASE_DEC, NULL, 0x0,
995 NULL, HFILL}},
997 { &hf_sbccs_dib_status,
998 { "Status", "fcsb3.status",
999 FT_UINT8, BASE_HEX, NULL, 0x0,
1000 NULL, HFILL}},
1002 { &hf_sbccs_dib_residualcnt,
1003 { "Residual Count", "fcsb3.residualcnt",
1004 FT_UINT8, BASE_DEC, NULL, 0x0,
1005 NULL, HFILL}},
1007 { &hf_sbccs_dib_iupacing,
1008 { "IU Pacing", "fcsb3.iupacing",
1009 FT_UINT8, BASE_DEC, NULL, 0x0,
1010 NULL, HFILL}},
1012 { &hf_sbccs_dib_qtuf,
1013 { "Queue-Time Unit Factor", "fcsb3.qtuf",
1014 FT_UINT8, BASE_DEC, NULL, 0xF0,
1015 NULL, HFILL}},
1017 { &hf_sbccs_dib_qtu,
1018 { "Queue-Time Unit", "fcsb3.qtu",
1019 FT_UINT16, BASE_DEC, NULL, 0xFFF,
1020 NULL, HFILL}},
1022 { &hf_sbccs_dib_dtuf,
1023 { "Defer-Time Unit Function", "fcsb3.dtuf",
1024 FT_UINT8, BASE_DEC, NULL, 0xF0,
1025 NULL, HFILL}},
1027 { &hf_sbccs_dib_dtu,
1028 { "Defer-Time Unit", "fcsb3.dtu",
1029 FT_UINT16, BASE_DEC, NULL, 0xFFF,
1030 NULL, HFILL}},
1032 { &hf_sbccs_dib_ctlfn,
1033 { "Control Function", "fcsb3.ctlfn",
1034 FT_UINT8, BASE_HEX, VALS (fc_sbccs_dib_ctl_fn_val), 0x0,
1035 NULL, HFILL}},
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,
1040 NULL, HFILL}},
1042 { &hf_sbccs_dib_ctccntr,
1043 { "CTC Counter", "fcsb3.ctccntr",
1044 FT_UINT16, BASE_DEC, NULL, 0x0,
1045 NULL, HFILL}},
1047 { &hf_sbccs_lrc,
1048 { "LRC", "fcsb3.lrc",
1049 FT_UINT32, BASE_HEX, NULL, 0x0,
1050 NULL, HFILL}},
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,
1055 NULL, HFILL}},
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,
1060 NULL, HFILL}},
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,
1065 NULL, HFILL}},
1067 { &hf_sbccs_dib_lprcode,
1068 { "LPR Reason Code", "fcsb3.lprcode",
1069 FT_UINT8, BASE_DEC, VALS (fc_sbccs_dib_lpr_errcode_val), 0xF,
1070 NULL, HFILL}},
1072 { &hf_sbccs_dib_tin_imgid_cnt,
1073 { "TIN Image ID", "fcsb3.tinimageidcnt",
1074 FT_UINT8, BASE_DEC, NULL, 0x0,
1075 NULL, HFILL}},
1077 { &hf_sbccs_dib_lrjcode,
1078 { "LRJ Reaspn Code", "fcsb3.lrjcode",
1079 FT_UINT8, BASE_HEX, VALS (fc_sbccs_dib_lrj_errcode_val), 0x7F,
1080 NULL, HFILL}},
1082 { &hf_sbccs_iui_as,
1083 { "AS", "fcsb3.iui.as",
1084 FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x10,
1085 NULL, HFILL}},
1087 { &hf_sbccs_iui_es,
1088 { "ES", "fcsb3.iui.es",
1089 FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x08,
1090 NULL, HFILL}},
1092 { &hf_sbccs_iui_val,
1093 { "Val", "fcsb3.iui.val",
1094 FT_UINT8, BASE_HEX, VALS(fc_sbccs_iu_val), 0x07,
1095 NULL, HFILL}},
1097 { &hf_sbccs_dhflags_end,
1098 { "End", "fcsb3.dhflags.end",
1099 FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x80,
1100 NULL, HFILL}},
1102 { &hf_sbccs_dhflags_chaining,
1103 { "Chaining", "fcsb3.dhflags.chaining",
1104 FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x10,
1105 NULL, HFILL}},
1107 { &hf_sbccs_dhflags_earlyend,
1108 { "Early End", "fcsb3.dhflags.earlyend",
1109 FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x08,
1110 NULL, HFILL}},
1112 { &hf_sbccs_dhflags_nocrc,
1113 { "No CRC", "fcsb3.dhflags.nocrc",
1114 FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x04,
1115 NULL, HFILL}},
1117 { &hf_sbccs_dib_ccw_flags,
1118 { "CCW Control Flags", "fcsb3.ccwflags",
1119 FT_UINT8, BASE_HEX, NULL, 0x0,
1120 NULL, HFILL}},
1122 { &hf_sbccs_dib_ccw_flags_cd,
1123 { "CD", "fcsb3.ccwflags.cd",
1124 FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x80,
1125 NULL, HFILL}},
1127 { &hf_sbccs_dib_ccw_flags_cc,
1128 { "CC", "fcsb3.ccwflags.cc",
1129 FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x40,
1130 NULL, HFILL}},
1132 { &hf_sbccs_dib_ccw_flags_sli,
1133 { "SLI", "fcsb3.ccwflags.sli",
1134 FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x20,
1135 NULL, HFILL}},
1137 { &hf_sbccs_dib_ccw_flags_crr,
1138 { "CRR", "fcsb3.ccwflags.crr",
1139 FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x08,
1140 NULL, HFILL}},
1142 { &hf_sbccs_dib_cmdflags,
1143 { "Command Flags", "fcsb3.cmdflags",
1144 FT_UINT8, BASE_HEX, NULL, 0x0,
1145 NULL, HFILL}},
1147 { &hf_sbccs_dib_cmdflags_du,
1148 { "DU", "fcsb3.cmdflags.du",
1149 FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x10,
1150 NULL, HFILL}},
1152 { &hf_sbccs_dib_cmdflags_coc,
1153 { "COC", "fcsb3.cmdflags.coc",
1154 FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x08,
1155 NULL, HFILL}},
1157 { &hf_sbccs_dib_cmdflags_syr,
1158 { "SYR", "fcsb3.cmdflags.syr",
1159 FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x04,
1160 NULL, HFILL}},
1162 { &hf_sbccs_dib_cmdflags_rex,
1163 { "REX", "fcsb3.cmdflags.rex",
1164 FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x02,
1165 NULL, HFILL}},
1167 { &hf_sbccs_dib_cmdflags_sss,
1168 { "SSS", "fcsb3.cmdflags.sss",
1169 FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x01,
1170 NULL, HFILL}},
1172 { &hf_sbccs_dib_statusflags,
1173 { "Status Flags", "fcsb3.statusflags",
1174 FT_UINT8, BASE_HEX, NULL, 0,
1175 NULL, HFILL}},
1177 { &hf_sbccs_dib_statusflags_ffc,
1178 { "FFC", "fcsb3.statusflags.ffc",
1179 FT_UINT8, BASE_HEX, VALS(status_ffc_val), 0xE0,
1180 NULL, HFILL}},
1182 { &hf_sbccs_dib_statusflags_ci,
1183 { "CI", "fcsb3.statusflags.ci",
1184 FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x10,
1185 NULL, HFILL}},
1187 { &hf_sbccs_dib_statusflags_cr,
1188 { "CR", "fcsb3.statusflags.cr",
1189 FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x04,
1190 NULL, HFILL}},
1192 { &hf_sbccs_dib_statusflags_lri,
1193 { "LRI", "fcsb3.statusflags.lri",
1194 FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x02,
1195 NULL, HFILL}},
1197 { &hf_sbccs_dib_statusflags_rv,
1198 { "RV", "fcsb3.statusflags.rv",
1199 FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x01,
1200 NULL, HFILL}},
1202 { &hf_sbccs_dib_status_attention,
1203 { "Attention", "fcsb3.status.attention",
1204 FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x80,
1205 NULL, HFILL}},
1207 { &hf_sbccs_dib_status_modifier,
1208 { "Status Modifier", "fcsb3.status.modifier",
1209 FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x40,
1210 NULL, HFILL}},
1212 { &hf_sbccs_dib_status_cue,
1213 { "Control-Unit End", "fcsb3.status.cue",
1214 FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x20,
1215 NULL, HFILL}},
1217 { &hf_sbccs_dib_status_busy,
1218 { "Busy", "fcsb3.status.busy",
1219 FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x10,
1220 NULL, HFILL}},
1222 { &hf_sbccs_dib_status_channelend,
1223 { "Channel End", "fcsb3.status.channel_end",
1224 FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x08,
1225 NULL, HFILL}},
1227 { &hf_sbccs_dib_status_deviceend,
1228 { "Device End", "fcsb3.status.device_end",
1229 FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x04,
1230 NULL, HFILL}},
1232 { &hf_sbccs_dib_status_unit_check,
1233 { "Unit Check", "fcsb3.status.unit_check",
1234 FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x02,
1235 NULL, HFILL}},
1237 { &hf_sbccs_dib_status_unit_exception,
1238 { "Unit Exception", "fcsb3.status.unitexception",
1239 FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x01,
1240 NULL, HFILL}},
1242 { &hf_sbccs_dib_ctlparam,
1243 { "Control Parameters", "fcsb3.ctlparam",
1244 FT_UINT24, BASE_HEX, NULL, 0x0,
1245 NULL, HFILL}},
1247 { &hf_sbccs_dib_ctlparam_rc,
1248 { "RC", "fcsb3.ctlparam.rc",
1249 FT_BOOLEAN, 24, TFS(&tfs_set_notset), 0x80,
1250 NULL, HFILL}},
1252 { &hf_sbccs_dib_ctlparam_ru,
1253 { "RU", "fcsb3.ctlparam.ru",
1254 FT_BOOLEAN, 24, TFS(&tfs_set_notset), 0x10,
1255 NULL, HFILL}},
1257 { &hf_sbccs_dib_ctlparam_ro,
1258 { "RO", "fcsb3.ctlparam.ro",
1259 FT_BOOLEAN, 24, TFS(&tfs_set_notset), 0x08,
1260 NULL, HFILL}},
1262 { &hf_sbccs_dib_linkctlinfo,
1263 { "Link Control Information", "fcsb3.linkctlinfo",
1264 FT_UINT16, BASE_HEX, NULL, 0x0,
1265 NULL, HFILL}},
1267 { &hf_sbccs_dib_linkctlinfo_ctcconn,
1268 { "CTC Conn", "fcsb3.linkctlinfo.ctc_conn",
1269 FT_BOOLEAN, 16, TFS(&tfs_supported_not_supported), 0x80,
1270 NULL, HFILL}},
1272 { &hf_sbccs_dib_linkctlinfo_ecrcg,
1273 { "Enhanced CRC Generation", "fcsb3.linkctlinfo.ecrcg",
1274 FT_BOOLEAN, 16, TFS(&tfs_supported_not_supported), 0x01,
1275 NULL, HFILL}},
1279 /* Setup protocol subtree array */
1280 static gint *ett[] = {
1281 &ett_fc_sbccs,
1282 &ett_sbccs_iui,
1283 &ett_sbccs_dhflags,
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",
1294 "FC-SB3", "fcsb3");
1296 proto_register_field_array(proto_fc_sbccs, hf, array_length(hf));
1297 proto_register_subtree_array(ett, array_length(ett));
1300 void
1301 proto_reg_handoff_fcsbccs (void)
1303 dissector_handle_t fc_sbccs_handle;
1305 fc_sbccs_handle = create_dissector_handle (dissect_fc_sbccs,
1306 proto_fc_sbccs);
1308 dissector_add_uint("fc.ftype", FC_FTYPE_SBCCS, fc_sbccs_handle);
1310 data_handle = find_dissector ("data");