Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-fcfcs.c
blob743840c4db61d1a81992ea27c757d29bc7b6efba
1 /* packet-fcfcs.c
2 * Routines for FC Fabric Configuration Server
3 * Copyright 2001, Dinesh G Dutt <ddutt@andiamo.com>
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
12 #include "config.h"
14 #include <epan/packet.h>
15 #include <epan/to_str.h>
16 #include <epan/expert.h>
17 #include "packet-fc.h"
18 #include "packet-fcct.h"
19 #include "packet-fcfcs.h"
21 void proto_register_fcfcs(void);
22 void proto_reg_handoff_fcfcs(void);
24 static dissector_handle_t fcs_handle;
27 * See the FC-GS3 specification.
30 /* Initialize the protocol and registered fields */
31 static int proto_fcfcs;
32 static int hf_fcs_opcode;
33 static int hf_fcs_iename;
34 static int hf_fcs_ietype;
35 static int hf_fcs_iedomainid;
36 static int hf_fcs_mgmtid;
37 static int hf_fcs_fabricname;
38 static int hf_fcs_mgmtaddr;
39 static int hf_fcs_lname;
40 static int hf_fcs_vendorname;
41 static int hf_fcs_modelname;
42 static int hf_fcs_portname;
43 static int hf_fcs_portmodtype;
44 static int hf_fcs_porttxtype;
45 static int hf_fcs_porttype;
46 static int hf_fcs_physportnum;
47 static int hf_fcs_portflags;
48 static int hf_fcs_portstate;
49 static int hf_fcs_platformname_len;
50 static int hf_fcs_platformname;
51 static int hf_fcs_platformnname;
52 static int hf_fcs_platformtype;
53 static int hf_fcs_platformaddr;
54 static int hf_fcs_reason;
55 static int hf_fcs_rjtdetail;
56 static int hf_fcs_vendor;
57 static int hf_fcs_numcap;
58 static int hf_fcs_mgmt_subtype;
59 static int hf_fcs_unsmask;
60 static int hf_fcs_vnd_capmask;
61 static int hf_fcs_fcsmask;
62 static int hf_fcs_maxres_size;
63 static int hf_fcs_releasecode;
65 /* Generated from convert_proto_tree_add_text.pl */
66 static int hf_fcfcs_num_ie_entries;
67 static int hf_fcfcs_num_mgmt_addresses;
68 static int hf_fcfcs_list_length;
69 static int hf_fcfcs_vendor_specific_information;
70 static int hf_fcfcs_num_port_entries;
71 static int hf_fcfcs_num_attached_port_entries;
72 static int hf_fcfcs_num_platform_node_name_entries;
73 static int hf_fcfcs_num_mgmt_address_entries;
74 static int hf_fcfcs_num_platform_name_entries;
76 /* Generated from convert_proto_tree_add_text.pl */
77 static expert_field ei_fcfcs_no_record_of_exchange;
79 /* Initialize the subtree pointers */
80 static int ett_fcfcs;
82 typedef struct _fcfcs_conv_key {
83 uint32_t conv_idx;
84 } fcfcs_conv_key_t;
86 typedef struct _fcfcs_conv_data {
87 uint32_t opcode;
88 } fcfcs_conv_data_t;
90 static wmem_map_t *fcfcs_req_hash;
93 * Hash Functions
95 static int
96 fcfcs_equal(const void *v, const void *w)
98 const fcfcs_conv_key_t *v1 = (const fcfcs_conv_key_t *)v;
99 const fcfcs_conv_key_t *v2 = (const fcfcs_conv_key_t *)w;
101 return (v1->conv_idx == v2->conv_idx);
104 static unsigned
105 fcfcs_hash (const void *v)
107 const fcfcs_conv_key_t *key = (const fcfcs_conv_key_t *)v;
108 unsigned val;
110 val = key->conv_idx;
112 return val;
115 /* Code to actually dissect the packets */
116 static void
117 dissect_fcfcs_giel (tvbuff_t *tvb, proto_tree *tree, bool isreq)
119 int offset = 16; /* past the ct header */
120 uint32_t numelem, i;
122 if (!isreq && tree) {
123 proto_tree_add_item_ret_uint(tree, hf_fcfcs_num_ie_entries, tvb, offset, 4, ENC_BIG_ENDIAN, &numelem);
124 offset += 4;
125 for (i = 0; i < numelem; i++) {
126 proto_tree_add_item (tree, hf_fcs_iename, tvb, offset, 8, ENC_NA);
127 proto_tree_add_item (tree, hf_fcs_ietype, tvb, offset+11, 1, ENC_BIG_ENDIAN);
128 offset += 12;
133 static void
134 dissect_fcfcs_giet (tvbuff_t *tvb, proto_tree *tree, bool isreq)
136 int offset = 16; /* past the fcct header */
138 if (tree) {
139 if (isreq) {
140 proto_tree_add_item (tree, hf_fcs_iename, tvb, offset, 8, ENC_NA);
142 else {
143 proto_tree_add_item (tree, hf_fcs_ietype, tvb, offset+3, 1, ENC_BIG_ENDIAN);
148 static void
149 dissect_fcfcs_gdid (tvbuff_t *tvb, proto_tree *tree, bool isreq)
151 int offset = 16; /* past the fcct header */
153 if (tree) {
154 if (isreq) {
155 proto_tree_add_item (tree, hf_fcs_iename, tvb, offset, 8, ENC_NA);
157 else {
158 proto_tree_add_item (tree, hf_fcs_iedomainid, tvb, offset+1, 1, ENC_BIG_ENDIAN);
163 static void
164 dissect_fcfcs_gmid (tvbuff_t *tvb, proto_tree *tree, bool isreq)
166 int offset = 16; /* past the fcct header */
168 if (tree) {
169 if (isreq) {
170 proto_tree_add_item (tree, hf_fcs_iename, tvb, offset, 8, ENC_NA);
172 else {
173 proto_tree_add_item (tree, hf_fcs_mgmtid, tvb, offset+1, 3, ENC_NA);
178 static void
179 dissect_fcfcs_gfn (tvbuff_t *tvb, proto_tree *tree, bool isreq)
181 int offset = 16; /* past the fcct header */
183 if (tree) {
184 if (isreq) {
185 proto_tree_add_item (tree, hf_fcs_iename, tvb, offset, 8, ENC_NA);
187 else {
188 proto_tree_add_item (tree, hf_fcs_fabricname, tvb, offset, 8, ENC_NA);
193 static void
194 dissect_fcfcs_gieln (tvbuff_t *tvb, proto_tree *tree, bool isreq)
196 int offset = 16; /* past the fcct header */
198 if (tree) {
199 if (isreq) {
200 proto_tree_add_item (tree, hf_fcs_iename, tvb, offset, 8, ENC_NA);
202 else {
203 proto_tree_add_item (tree, hf_fcs_lname, tvb, offset,
204 1, ENC_ASCII|ENC_BIG_ENDIAN);
209 static void
210 dissect_fcfcs_gmal (tvbuff_t *tvb, proto_tree *tree, bool isreq)
212 int offset = 16; /* past the fcct header */
213 uint32_t numelem, i;
215 if (tree) {
216 if (isreq) {
217 proto_tree_add_item (tree, hf_fcs_iename, tvb, offset, 8, ENC_NA);
219 else {
220 proto_tree_add_item_ret_uint(tree, hf_fcfcs_num_mgmt_addresses, tvb, offset, 4, ENC_BIG_ENDIAN, &numelem);
222 offset += 4;
223 for (i = 0; i < numelem; i++) {
224 proto_tree_add_item (tree, hf_fcs_mgmtaddr, tvb, offset, 1, ENC_ASCII|ENC_BIG_ENDIAN);
225 offset += 256;
231 static void
232 dissect_fcfcs_gieil (tvbuff_t *tvb, proto_tree *tree, bool isreq)
234 int offset = 16; /* past the fcct header */
235 unsigned len;
236 uint32_t tot_len, prevlen;
238 if (isreq) {
239 proto_tree_add_item (tree, hf_fcs_iename, tvb, offset, 8, ENC_NA);
241 else {
242 proto_tree_add_item_ret_uint(tree, hf_fcfcs_list_length, tvb, offset+3, 1, ENC_NA, &tot_len);
244 prevlen = 0;
245 len = tvb_strsize(tvb, offset+4);
246 proto_tree_add_item (tree, hf_fcs_vendorname, tvb, offset+4,
247 len, ENC_ASCII);
248 prevlen += len;
250 len = tvb_strsize(tvb, offset+4+prevlen);
251 proto_tree_add_item (tree, hf_fcs_modelname, tvb, offset+4+prevlen,
252 len, ENC_ASCII);
253 prevlen += len;
255 len = tvb_strsize(tvb, offset+4+prevlen);
256 proto_tree_add_item (tree, hf_fcs_releasecode, tvb,
257 offset+4+prevlen, len, ENC_ASCII);
258 prevlen += len;
259 offset += (4+prevlen);
260 while (tot_len > prevlen) {
261 len = tvb_strsize(tvb, offset);
262 proto_tree_add_item(tree, hf_fcfcs_vendor_specific_information, tvb, offset, len, ENC_NA|ENC_ASCII);
263 prevlen += len;
264 offset += len;
269 static void
270 dissect_fcfcs_gpl (tvbuff_t *tvb, proto_tree *tree, bool isreq)
272 int offset = 16; /* past the fcct header */
273 uint32_t numelem, i;
275 if (tree) {
276 if (isreq) {
277 proto_tree_add_item (tree, hf_fcs_iename, tvb, offset, 8, ENC_NA);
279 else {
280 proto_tree_add_item_ret_uint(tree, hf_fcfcs_num_port_entries, tvb, offset, 4, ENC_BIG_ENDIAN, &numelem);
281 offset += 4;
283 for (i = 0; i < numelem; i++) {
284 proto_tree_add_item (tree, hf_fcs_portname, tvb, offset, 8, ENC_NA);
285 proto_tree_add_item (tree, hf_fcs_portmodtype, tvb, offset+9,
286 1, ENC_BIG_ENDIAN);
287 proto_tree_add_item (tree, hf_fcs_porttxtype, tvb, offset+10,
288 1, ENC_BIG_ENDIAN);
289 proto_tree_add_item (tree, hf_fcs_porttype, tvb, offset+11,
290 1, ENC_BIG_ENDIAN);
291 offset += 12;
297 static void
298 dissect_fcfcs_gpt (tvbuff_t *tvb, proto_tree *tree, bool isreq)
300 int offset = 16; /* past the fcct header */
302 if (tree) {
303 if (isreq) {
304 proto_tree_add_item (tree, hf_fcs_portname, tvb, offset, 8, ENC_NA);
306 else {
307 proto_tree_add_item (tree, hf_fcs_porttype, tvb, offset+3, 1, ENC_BIG_ENDIAN);
312 static void
313 dissect_fcfcs_gppn (tvbuff_t *tvb, proto_tree *tree, bool isreq)
315 int offset = 16; /* past the fcct header */
317 if (tree) {
318 if (isreq) {
319 proto_tree_add_item (tree, hf_fcs_portname, tvb, offset, 8, ENC_NA);
321 else {
322 proto_tree_add_item (tree, hf_fcs_physportnum, tvb, offset, 4, ENC_NA);
327 static void
328 dissect_fcfcs_gapnl (tvbuff_t *tvb, proto_tree *tree, bool isreq)
330 int offset = 16; /* past the fcct header */
331 uint32_t numelem, i;
333 if (tree) {
334 if (isreq) {
335 proto_tree_add_item (tree, hf_fcs_portname, tvb, offset, 8, ENC_NA);
337 else {
338 proto_tree_add_item_ret_uint(tree, hf_fcfcs_num_attached_port_entries, tvb, offset, 4, ENC_BIG_ENDIAN, &numelem);
339 offset += 4;
340 for (i = 0; i < numelem; i++) {
341 proto_tree_add_item (tree, hf_fcs_portname, tvb, offset, 8, ENC_NA);
342 proto_tree_add_item (tree, hf_fcs_portflags, tvb, offset+10,
343 1, ENC_BIG_ENDIAN);
344 proto_tree_add_item (tree, hf_fcs_porttype, tvb, offset+11,
345 1, ENC_BIG_ENDIAN);
346 offset += 12;
352 static void
353 dissect_fcfcs_gps (tvbuff_t *tvb, proto_tree *tree, bool isreq)
355 int offset = 16; /* past the fcct header */
357 if (tree) {
358 if (isreq) {
359 proto_tree_add_item (tree, hf_fcs_portname, tvb, offset, 8, ENC_NA);
361 else {
362 proto_tree_add_item (tree, hf_fcs_porttype, tvb, offset+3, 1, ENC_BIG_ENDIAN);
363 proto_tree_add_item (tree, hf_fcs_portstate, tvb, offset+7, 1, ENC_BIG_ENDIAN);
368 static void
369 dissect_fcfcs_gplnl (tvbuff_t *tvb, proto_tree *tree, bool isreq)
371 int offset = 16; /* past the fcct header */
372 uint32_t numelem, i, len;
374 if (tree) {
375 if (isreq) {
376 len = tvb_get_uint8 (tvb, offset);
377 proto_tree_add_uint(tree, hf_fcs_platformname_len, tvb, offset, 1, len);
378 proto_tree_add_item (tree, hf_fcs_platformname, tvb, offset+1,
379 len, ENC_NA);
381 else {
382 proto_tree_add_item_ret_uint(tree, hf_fcfcs_num_platform_node_name_entries, tvb, offset, 4, ENC_BIG_ENDIAN, &numelem);
383 offset += 4;
384 for (i = 0; i < numelem; i++) {
385 proto_tree_add_item (tree, hf_fcs_platformnname, tvb, offset,
386 8, ENC_NA);
387 offset += 8;
393 static void
394 dissect_fcfcs_gplt (tvbuff_t *tvb, proto_tree *tree, bool isreq)
396 int offset = 16; /* past the fcct header */
397 int len;
399 if (tree) {
400 if (isreq) {
401 len = tvb_get_uint8 (tvb, offset);
402 proto_tree_add_uint(tree, hf_fcs_platformname_len, tvb, offset, 1, len);
403 proto_tree_add_item (tree, hf_fcs_platformname, tvb, offset+1,
404 len, ENC_NA);
406 else {
407 proto_tree_add_item (tree, hf_fcs_platformtype, tvb, offset+3,
408 1, ENC_BIG_ENDIAN);
413 static void
414 dissect_fcfcs_gplml (tvbuff_t *tvb, proto_tree *tree, bool isreq)
416 int offset = 16; /* past the fcct header */
417 uint32_t numelem, i, len;
419 if (tree) {
420 if (isreq) {
421 len = tvb_get_uint8 (tvb, offset);
422 proto_tree_add_uint(tree, hf_fcs_platformname_len, tvb, offset, 1, len);
423 proto_tree_add_item (tree, hf_fcs_platformname, tvb, offset+1,
424 len, ENC_NA);
426 else {
427 proto_tree_add_item_ret_uint(tree, hf_fcfcs_num_mgmt_address_entries, tvb, offset, 4, ENC_BIG_ENDIAN, &numelem);
428 offset += 4;
429 for (i = 0; i < numelem; i++) {
430 proto_tree_add_item (tree, hf_fcs_platformaddr, tvb, offset, 1, ENC_ASCII|ENC_BIG_ENDIAN);
431 offset += 256;
437 static void
438 dissect_fcfcs_gnpl (tvbuff_t *tvb, proto_tree *tree, bool isreq)
440 int offset = 16; /* past the fcct header */
441 int len;
443 if (tree) {
444 if (isreq) {
445 proto_tree_add_item (tree, hf_fcs_platformnname, tvb, offset, 8, ENC_NA);
447 else {
448 len = tvb_get_uint8 (tvb, offset);
449 proto_tree_add_uint (tree, hf_fcs_platformname_len, tvb, offset, 1, len);
450 proto_tree_add_item (tree, hf_fcs_platformname, tvb, offset+1,
451 len, ENC_NA);
456 static void
457 dissect_fcfcs_gpnl (tvbuff_t *tvb, proto_tree *tree, bool isreq)
459 int offset = 16; /* past the fcct header */
460 uint32_t numelem, i, len;
462 if (tree) {
463 if (!isreq) {
464 proto_tree_add_item_ret_uint(tree, hf_fcfcs_num_platform_name_entries, tvb, offset, 4, ENC_BIG_ENDIAN, &numelem);
465 offset += 4;
466 for (i = 0; i < numelem; i++) {
467 len = tvb_get_uint8 (tvb, offset);
468 proto_tree_add_uint (tree, hf_fcs_platformname_len, tvb, offset, 1, len);
469 proto_tree_add_item (tree, hf_fcs_platformname, tvb, offset+1,
470 len, ENC_NA);
471 offset += 256;
477 static void
478 dissect_fcfcs_rieln (tvbuff_t *tvb, proto_tree *tree, bool isreq)
480 int offset = 16; /* past the fc_ct header */
482 if (tree) {
483 if (isreq) {
484 proto_tree_add_item (tree, hf_fcs_iename, tvb, offset, 8, ENC_NA);
485 proto_tree_add_item (tree, hf_fcs_lname, tvb, offset+8, 1, ENC_ASCII|ENC_BIG_ENDIAN);
490 static void
491 dissect_fcfcs_rpl (tvbuff_t *tvb, proto_tree *tree, bool isreq)
493 int offset = 16; /* past the fc_ct header */
494 uint32_t numelem, i, len;
496 if (tree) {
497 if (isreq) {
498 len = tvb_get_uint8 (tvb, offset);
499 proto_tree_add_uint (tree, hf_fcs_platformname_len, tvb, offset, 1, len);
500 proto_tree_add_item (tree, hf_fcs_platformname, tvb, offset+1,
501 len, ENC_NA);
502 proto_tree_add_item (tree, hf_fcs_platformtype, tvb, offset+256, 4,
503 ENC_BIG_ENDIAN);
504 proto_tree_add_item_ret_uint(tree, hf_fcfcs_num_mgmt_address_entries, tvb, offset+260, 4, ENC_BIG_ENDIAN, &numelem);
505 offset += 264;
506 for (i = 0; i < numelem; i++) {
507 proto_tree_add_item (tree, hf_fcs_mgmtaddr, tvb, offset, 1, ENC_ASCII|ENC_BIG_ENDIAN);
508 offset += 256;
511 proto_tree_add_item_ret_uint(tree, hf_fcfcs_num_platform_node_name_entries, tvb, offset, 4, ENC_BIG_ENDIAN, &numelem);
512 offset += 4;
513 for (i = 0; i < numelem; i++) {
514 proto_tree_add_item (tree, hf_fcs_platformnname, tvb, offset, 8, ENC_NA);
515 offset += 8;
521 static void
522 dissect_fcfcs_rpln (tvbuff_t *tvb, proto_tree *tree, bool isreq)
524 int offset = 16; /* past the fc_ct header */
525 int len;
527 if (tree) {
528 if (isreq) {
529 len = tvb_get_uint8 (tvb, offset);
530 proto_tree_add_uint (tree, hf_fcs_platformname_len, tvb, offset, 1, len);
531 proto_tree_add_item (tree, hf_fcs_platformname, tvb, offset+1,
532 len, ENC_NA);
533 proto_tree_add_item (tree, hf_fcs_platformnname, tvb, offset+256,
534 8, ENC_NA);
539 static void
540 dissect_fcfcs_rplt (tvbuff_t *tvb, proto_tree *tree, bool isreq)
542 int offset = 16; /* past the fc_ct header */
543 int len;
545 if (tree) {
546 if (isreq) {
547 len = tvb_get_uint8 (tvb, offset);
548 proto_tree_add_uint (tree, hf_fcs_platformname_len, tvb, offset, 1, len);
549 proto_tree_add_item (tree, hf_fcs_platformname, tvb, offset+1,
550 len, ENC_NA);
551 proto_tree_add_item (tree, hf_fcs_platformtype, tvb, offset+256,
552 4, ENC_BIG_ENDIAN);
557 static void
558 dissect_fcfcs_rplm (tvbuff_t *tvb, proto_tree *tree, bool isreq)
560 int offset = 16; /* past the fc_ct header */
561 int len;
563 if (tree) {
564 if (isreq) {
565 len = tvb_get_uint8 (tvb, offset);
566 proto_tree_add_uint (tree, hf_fcs_platformname_len, tvb, offset, 1, len);
567 proto_tree_add_item (tree, hf_fcs_platformname, tvb, offset+1,
568 len, ENC_NA);
569 proto_tree_add_item (tree, hf_fcs_platformaddr, tvb, offset+256,
570 1, ENC_ASCII|ENC_BIG_ENDIAN);
575 static void
576 dissect_fcfcs_dpl (tvbuff_t *tvb, proto_tree *tree, bool isreq)
578 int offset = 16; /* past the fc_ct header */
579 int len;
581 if (tree) {
582 if (isreq) {
583 len = tvb_get_uint8 (tvb, offset);
584 proto_tree_add_uint (tree, hf_fcs_platformname_len, tvb, offset, 1, len);
585 proto_tree_add_item (tree, hf_fcs_platformname, tvb, offset+1,
586 len, ENC_NA);
591 static void
592 dissect_fcfcs_dpln (tvbuff_t *tvb, proto_tree *tree, bool isreq)
594 int offset = 16; /* past the fc_ct header */
596 if (tree) {
597 if (isreq) {
598 proto_tree_add_item(tree, hf_fcs_platformnname, tvb, offset, 8, ENC_NA);
603 static void
604 dissect_fcfcs_dplml (tvbuff_t *tvb, proto_tree *tree, bool isreq)
606 int offset = 16; /* past the fc_ct header */
607 int len;
609 if (tree) {
610 if (isreq) {
611 len = tvb_get_uint8 (tvb, offset);
612 proto_tree_add_uint (tree, hf_fcs_platformname_len, tvb, offset, 1, len);
613 proto_tree_add_item (tree, hf_fcs_platformname, tvb, offset+1,
614 len, ENC_NA);
619 static void
620 dissect_fcfcs_gcap (tvbuff_t *tvb, proto_tree *tree, bool isreq)
622 int offset = 16; /* past the fc_ct header */
623 int numrec, i;
624 uint8_t subtype;
626 if (tree) {
627 if (!isreq) {
628 numrec = tvb_get_ntohl (tvb, offset);
629 proto_tree_add_item (tree, hf_fcs_numcap, tvb, offset, 4, ENC_BIG_ENDIAN);
631 offset += 4;
632 for (i = 0; i < numrec; i++) {
633 subtype = tvb_get_uint8 (tvb, offset);
634 proto_tree_add_uint (tree, hf_fcs_mgmt_subtype, tvb, offset,
635 1, subtype);
637 proto_tree_add_item (tree, hf_fcs_vnd_capmask, tvb, offset+1,
638 3, ENC_BIG_ENDIAN);
639 if (subtype == FCCT_GSSUBTYPE_FCS) {
640 proto_tree_add_item (tree, hf_fcs_fcsmask, tvb, offset+4,
641 4, ENC_BIG_ENDIAN);
643 else if (subtype == FCCT_GSSUBTYPE_UNS) {
644 proto_tree_add_item (tree, hf_fcs_unsmask, tvb, offset+4,
645 4, ENC_BIG_ENDIAN);
647 offset += 8;
653 static void
654 dissect_fcfcs_rjt (tvbuff_t *tvb, proto_tree *tree)
656 int offset = 0;
658 if (tree) {
659 proto_tree_add_item (tree, hf_fcs_reason, tvb, offset+13, 1, ENC_BIG_ENDIAN);
660 proto_tree_add_item (tree, hf_fcs_rjtdetail, tvb, offset+14, 1,
661 ENC_BIG_ENDIAN);
662 proto_tree_add_item (tree, hf_fcs_vendor, tvb, offset+15, 1, ENC_BIG_ENDIAN);
667 static int
668 dissect_fcfcs (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
671 /* Set up structures needed to add the protocol subtree and manage it */
672 int offset = 0;
673 proto_item *ti;
674 proto_tree *fcfcs_tree = NULL;
675 fc_ct_preamble cthdr;
676 bool isreq = 1;
677 conversation_t *conversation;
678 fcfcs_conv_data_t *cdata;
679 fcfcs_conv_key_t ckey, *req_key;
680 int opcode,
681 failed_opcode = 0;
682 fc_hdr *fchdr;
684 /* Reject the packet if data is NULL */
685 if (data == NULL)
686 return 0;
687 fchdr = (fc_hdr *)data;
689 /* Make entries in Protocol column and Info column on summary display */
690 col_set_str(pinfo->cinfo, COL_PROTOCOL, "FC-FCS");
692 ti = proto_tree_add_protocol_format (tree, proto_fcfcs, tvb, 0,
693 tvb_reported_length (tvb),
694 "FCS");
695 fcfcs_tree = proto_item_add_subtree (ti, ett_fcfcs);
697 tvb_memcpy (tvb, (uint8_t *)&cthdr, offset, FCCT_PRMBL_SIZE);
698 cthdr.revision = tvb_get_uint8 (tvb, offset);
699 cthdr.in_id = tvb_get_ntoh24 (tvb, offset+1);
700 cthdr.opcode = g_ntohs (cthdr.opcode);
701 opcode = tvb_get_ntohs (tvb, offset+8);
702 cthdr.maxres_size = g_ntohs (cthdr.maxres_size);
704 if ((opcode != FCCT_MSG_ACC) && (opcode != FCCT_MSG_RJT)) {
705 conversation = find_conversation (pinfo->num, &pinfo->src, &pinfo->dst,
706 conversation_pt_to_conversation_type(pinfo->ptype), fchdr->oxid,
707 fchdr->rxid, NO_PORT_B);
708 if (!conversation) {
709 conversation = conversation_new (pinfo->num, &pinfo->src, &pinfo->dst,
710 conversation_pt_to_conversation_type(pinfo->ptype), fchdr->oxid,
711 fchdr->rxid, NO_PORT2);
714 ckey.conv_idx = conversation->conv_index;
716 cdata = (fcfcs_conv_data_t *)wmem_map_lookup (fcfcs_req_hash,
717 &ckey);
718 if (cdata) {
719 /* Since we never free the memory used by an exchange, this maybe a
720 * case of another request using the same exchange as a previous
721 * req.
723 cdata->opcode = opcode;
725 else {
726 req_key = wmem_new(wmem_file_scope(), fcfcs_conv_key_t);
727 req_key->conv_idx = conversation->conv_index;
729 cdata = wmem_new(wmem_file_scope(), fcfcs_conv_data_t);
730 cdata->opcode = opcode;
732 wmem_map_insert (fcfcs_req_hash, req_key, cdata);
734 col_add_str (pinfo->cinfo, COL_INFO,
735 val_to_str (opcode, fc_fcs_opcode_abbrev_val, "0x%x"));
737 else {
738 /* Opcode is ACC or RJT */
739 conversation = find_conversation (pinfo->num, &pinfo->src, &pinfo->dst,
740 conversation_pt_to_conversation_type(pinfo->ptype), fchdr->oxid,
741 fchdr->rxid, NO_PORT_B);
742 isreq = 0;
743 if (!conversation) {
744 if (opcode == FCCT_MSG_ACC) {
745 col_add_str (pinfo->cinfo, COL_INFO,
746 val_to_str (opcode, fc_fcs_opcode_abbrev_val,
747 "0x%x"));
748 /* No record of what this accept is for. Can't decode */
749 proto_tree_add_expert(fcfcs_tree, pinfo, &ei_fcfcs_no_record_of_exchange, tvb, 0, -1);
750 return 0;
753 else {
754 ckey.conv_idx = conversation->conv_index;
756 cdata = (fcfcs_conv_data_t *)wmem_map_lookup (fcfcs_req_hash,
757 &ckey);
759 if (cdata != NULL) {
760 if (opcode == FCCT_MSG_ACC)
761 opcode = cdata->opcode;
762 else
763 failed_opcode = cdata->opcode;
766 if (opcode != FCCT_MSG_RJT) {
767 col_add_fstr (pinfo->cinfo, COL_INFO, "MSG_ACC (%s)",
768 val_to_str (opcode, fc_fcs_opcode_abbrev_val,
769 "0x%x"));
771 else {
772 col_add_fstr (pinfo->cinfo, COL_INFO, "MSG_RJT (%s)",
773 val_to_str (failed_opcode,
774 fc_fcs_opcode_abbrev_val,
775 "0x%x"));
778 if ((cdata == NULL) && (opcode != FCCT_MSG_RJT)) {
779 /* No record of what this accept is for. Can't decode */
780 proto_tree_add_expert(fcfcs_tree, pinfo, &ei_fcfcs_no_record_of_exchange, tvb, 0, -1);
781 return 0;
787 if (tree) {
788 proto_tree_add_item (fcfcs_tree, hf_fcs_opcode, tvb, offset+8, 2, ENC_BIG_ENDIAN);
789 proto_tree_add_item (fcfcs_tree, hf_fcs_maxres_size, tvb, offset+10,
790 2, ENC_BIG_ENDIAN);
793 switch (opcode) {
794 case FCCT_MSG_RJT:
795 dissect_fcfcs_rjt (tvb, fcfcs_tree);
796 break;
797 case FCFCS_GIEL:
798 dissect_fcfcs_giel (tvb, fcfcs_tree, isreq);
799 break;
800 case FCFCS_GIET:
801 dissect_fcfcs_giet (tvb, fcfcs_tree, isreq);
802 break;
803 case FCFCS_GDID:
804 dissect_fcfcs_gdid (tvb, fcfcs_tree, isreq);
805 break;
806 case FCFCS_GMID:
807 dissect_fcfcs_gmid (tvb, fcfcs_tree, isreq);
808 break;
809 case FCFCS_GFN:
810 dissect_fcfcs_gfn (tvb, fcfcs_tree, isreq);
811 break;
812 case FCFCS_GIELN:
813 dissect_fcfcs_gieln (tvb, fcfcs_tree, isreq);
814 break;
815 case FCFCS_GMAL:
816 dissect_fcfcs_gmal (tvb, fcfcs_tree, isreq);
817 break;
818 case FCFCS_GIEIL:
819 dissect_fcfcs_gieil (tvb, fcfcs_tree, isreq);
820 break;
821 case FCFCS_GPL:
822 dissect_fcfcs_gpl (tvb, fcfcs_tree, isreq);
823 break;
824 case FCFCS_GPT:
825 dissect_fcfcs_gpt (tvb, fcfcs_tree, isreq);
826 break;
827 case FCFCS_GPPN:
828 dissect_fcfcs_gppn (tvb, fcfcs_tree, isreq);
829 break;
830 case FCFCS_GAPNL:
831 dissect_fcfcs_gapnl (tvb, fcfcs_tree, isreq);
832 break;
833 case FCFCS_GPS:
834 dissect_fcfcs_gps (tvb, fcfcs_tree, isreq);
835 break;
836 case FCFCS_GPLNL:
837 dissect_fcfcs_gplnl (tvb, fcfcs_tree, isreq);
838 break;
839 case FCFCS_GPLT:
840 dissect_fcfcs_gplt (tvb, fcfcs_tree, isreq);
841 break;
842 case FCFCS_GPLML:
843 dissect_fcfcs_gplml (tvb, fcfcs_tree, isreq);
844 break;
845 case FCFCS_GNPL:
846 dissect_fcfcs_gnpl (tvb, fcfcs_tree, isreq);
847 break;
848 case FCFCS_GPNL:
849 dissect_fcfcs_gpnl (tvb, fcfcs_tree, isreq);
850 break;
851 case FCFCS_RIELN:
852 dissect_fcfcs_rieln (tvb, fcfcs_tree, isreq);
853 break;
854 case FCFCS_RPL:
855 dissect_fcfcs_rpl (tvb, fcfcs_tree, isreq);
856 break;
857 case FCFCS_RPLN:
858 dissect_fcfcs_rpln (tvb, fcfcs_tree, isreq);
859 break;
860 case FCFCS_RPLT:
861 dissect_fcfcs_rplt (tvb, fcfcs_tree, isreq);
862 break;
863 case FCFCS_RPLM:
864 dissect_fcfcs_rplm (tvb, fcfcs_tree, isreq);
865 break;
866 case FCFCS_DPL:
867 dissect_fcfcs_dpl (tvb, fcfcs_tree, isreq);
868 break;
869 case FCFCS_DPLN:
870 dissect_fcfcs_dpln (tvb, fcfcs_tree, isreq);
871 break;
872 case FCFCS_DPLML:
873 dissect_fcfcs_dplml (tvb, fcfcs_tree, isreq);
874 break;
875 case FCFCS_GCAP:
876 dissect_fcfcs_gcap (tvb, fcfcs_tree, isreq);
877 break;
878 default:
879 call_data_dissector(tvb, pinfo, fcfcs_tree);
880 break;
883 return tvb_captured_length(tvb);
886 /* Register the protocol with Wireshark */
888 void
889 proto_register_fcfcs (void)
892 static hf_register_info hf[] = {
893 { &hf_fcs_opcode,
894 {"Opcode", "fcs.opcode", FT_UINT16, BASE_HEX,
895 VALS (fc_fcs_opcode_val), 0x0, NULL, HFILL}},
896 { &hf_fcs_iename,
897 {"Interconnect Element Name", "fcs.ie.name", FT_FCWWN, BASE_NONE,
898 NULL, 0x0, NULL, HFILL}},
899 { &hf_fcs_ietype,
900 {"Interconnect Element Type", "fcs.ie.type", FT_UINT8, BASE_HEX,
901 VALS (fc_fcs_ietype_val), 0x0, NULL, HFILL}},
902 { &hf_fcs_iedomainid,
903 {"Interconnect Element Domain ID", "fcs.ie.domainid", FT_UINT8,
904 BASE_HEX, NULL, 0x0, NULL, HFILL}},
905 { &hf_fcs_mgmtid,
906 {"Interconnect Element Mgmt. ID", "fcs.ie.mgmtid", FT_BYTES,
907 SEP_DOT, NULL, 0x0, NULL, HFILL}},
908 { &hf_fcs_fabricname,
909 {"Interconnect Element Fabric Name", "fcs.ie.fname", FT_FCWWN,
910 BASE_NONE, NULL, 0x0, NULL, HFILL}},
911 { &hf_fcs_mgmtaddr,
912 {"Interconnect Element Mgmt. Address", "fcs.ie.mgmtaddr", FT_UINT_STRING,
913 BASE_NONE, NULL, 0x0, NULL, HFILL}},
914 { &hf_fcs_lname,
915 {"Interconnect Element Logical Name", "fcs.ie.logname", FT_UINT_STRING,
916 BASE_NONE, NULL, 0x0, NULL, HFILL}},
917 { &hf_fcs_vendorname,
918 {"Vendor Name", "fcs.vendorname", FT_STRING, BASE_NONE, NULL, 0x0, NULL,
919 HFILL}},
920 { &hf_fcs_modelname,
921 {"Model Name/Number", "fcs.modelname", FT_STRING, BASE_NONE, NULL,
922 0x0, NULL, HFILL}},
923 { &hf_fcs_portname,
924 {"Port Name", "fcs.port.name", FT_FCWWN, BASE_NONE, NULL, 0x0, NULL,
925 HFILL}},
926 { &hf_fcs_portmodtype,
927 {"Port Module Type", "fcs.port.moduletype", FT_UINT8, BASE_HEX,
928 VALS (fc_fcs_port_modtype_val), 0x0, NULL, HFILL}},
929 { &hf_fcs_porttxtype,
930 {"Port TX Type", "fcs.port.txtype", FT_UINT8, BASE_HEX,
931 VALS (fc_fcs_port_txtype_val), 0x0, NULL, HFILL}},
932 { &hf_fcs_porttype,
933 {"Port Type", "fcs.port.type", FT_UINT8, BASE_HEX,
934 VALS (fc_fcs_port_type_val), 0x0, NULL, HFILL}},
935 { &hf_fcs_physportnum,
936 {"Physical Port Number", "fcs.port.physportnum", FT_BYTES, BASE_NONE,
937 NULL, 0x0, NULL, HFILL}},
938 { &hf_fcs_portflags,
939 {"Port Flags", "fcs.port.flags", FT_BOOLEAN, BASE_NONE,
940 TFS (&fc_fcs_portflags_tfs), 0x0, NULL, HFILL}},
941 { &hf_fcs_portstate,
942 {"Port State", "fcs.port.state", FT_UINT8, BASE_HEX,
943 VALS (fc_fcs_port_state_val), 0x0, NULL, HFILL}},
944 { &hf_fcs_platformname_len,
945 {"Platform Name Length", "fcs.platform.len", FT_UINT8, BASE_DEC,
946 NULL, 0x0, NULL, HFILL}},
947 { &hf_fcs_platformname,
948 {"Platform Name", "fcs.platform.name", FT_BYTES, BASE_NONE, NULL, 0x0,
949 NULL, HFILL}},
950 { &hf_fcs_platformnname,
951 {"Platform Node Name", "fcs.platform.nodename", FT_FCWWN, BASE_NONE,
952 NULL, 0x0, NULL, HFILL}},
953 { &hf_fcs_platformtype,
954 {"Platform Type", "fcs.platform.type", FT_UINT32, BASE_HEX,
955 VALS(fc_fcs_plat_type_val), 0x0, NULL, HFILL}},
956 { &hf_fcs_platformaddr,
957 {"Management Address", "fcs.platform.mgmtaddr", FT_UINT_STRING, BASE_NONE,
958 NULL, 0x0, NULL, HFILL}},
959 { &hf_fcs_reason,
960 {"Reason Code", "fcs.reason", FT_UINT8, BASE_HEX,
961 VALS (fc_ct_rjt_code_vals), 0x0, NULL, HFILL}},
962 { &hf_fcs_rjtdetail,
963 {"Reason Code Explanation", "fcs.reasondet", FT_UINT8, BASE_HEX,
964 VALS (fc_fcs_rjt_code_val), 0x0, NULL, HFILL}},
965 { &hf_fcs_vendor,
966 {"Vendor Unique Reject Code", "fcs.err.vendor", FT_UINT8, BASE_HEX,
967 NULL, 0x0, NULL, HFILL}},
968 { &hf_fcs_numcap,
969 {"Number of Capabilities", "fcs.numcap", FT_UINT32, BASE_DEC, NULL,
970 0x0, NULL, HFILL}},
971 { &hf_fcs_mgmt_subtype,
972 {"Management GS Subtype", "fcs.gssubtype", FT_UINT8, BASE_HEX, NULL,
973 0x0, NULL, HFILL}},
974 { &hf_fcs_vnd_capmask,
975 {"Vendor Unique Capability Bitmask", "fcs.vbitmask", FT_UINT24,
976 BASE_HEX, NULL, 0x0, NULL, HFILL}},
977 { &hf_fcs_fcsmask,
978 {"Subtype Capability Bitmask", "fcs.fcsmask", FT_UINT32, BASE_HEX,
979 VALS (fc_fcs_fcsmask_val), 0x0, NULL, HFILL}},
980 { &hf_fcs_unsmask,
981 {"Subtype Capability Bitmask", "fcs.unsmask", FT_UINT32, BASE_HEX,
982 VALS (fc_fcs_unsmask_val), 0x0, NULL, HFILL}},
983 { &hf_fcs_maxres_size,
984 {"Maximum/Residual Size", "fcs.maxres_size", FT_UINT16, BASE_DEC,
985 NULL, 0x0, NULL, HFILL}},
986 { &hf_fcs_releasecode,
987 {"Release Code", "fcs.releasecode", FT_STRING, BASE_NONE, NULL, 0x0,
988 NULL, HFILL}},
989 /* Generated from convert_proto_tree_add_text.pl */
990 { &hf_fcfcs_num_ie_entries, { "Number of IE entries", "fcfcs.num_ie_entries", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
991 { &hf_fcfcs_num_mgmt_addresses, { "Number of Mgmt. Addresses", "fcfcs.num_mgmt_addresses", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
992 { &hf_fcfcs_list_length, { "List Length", "fcfcs.list_length", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
993 { &hf_fcfcs_vendor_specific_information, { "Vendor-specific Information", "fcfcs.vendor_specific_information", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
994 { &hf_fcfcs_num_port_entries, { "Number of Port Entries", "fcfcs.num_port_entries", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
995 { &hf_fcfcs_num_attached_port_entries, { "Number of Attached Port Entries", "fcfcs.num_attached_port_entries", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
996 { &hf_fcfcs_num_platform_node_name_entries, { "Number of Platform Node Name Entries", "fcfcs.num_platform_node_name_entries", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
997 { &hf_fcfcs_num_mgmt_address_entries, { "Number of Mgmt. Address Entries", "fcfcs.num_mgmt_address_entries", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
998 { &hf_fcfcs_num_platform_name_entries, { "Number of Platform Name Entries", "fcfcs.num_platform_name_entries", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1001 static int *ett[] = {
1002 &ett_fcfcs,
1005 static ei_register_info ei[] = {
1006 /* Generated from convert_proto_tree_add_text.pl */
1007 { &ei_fcfcs_no_record_of_exchange, { "fcfcs.no_record_of_exchange", PI_UNDECODED, PI_WARN, "No record of Exchg. Unable to decode MSG_ACC/RJT", EXPFILL }},
1010 expert_module_t* expert_fcfcs;
1012 proto_fcfcs = proto_register_protocol("FC Fabric Configuration Server",
1013 "FC-FCS", "fcs");
1015 proto_register_field_array(proto_fcfcs, hf, array_length(hf));
1016 proto_register_subtree_array(ett, array_length(ett));
1017 expert_fcfcs = expert_register_protocol(proto_fcfcs);
1018 expert_register_field_array(expert_fcfcs, ei, array_length(ei));
1020 fcfcs_req_hash = wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), fcfcs_hash, fcfcs_equal);
1022 fcs_handle = register_dissector("fcs", dissect_fcfcs, proto_fcfcs);
1025 void
1026 proto_reg_handoff_fcfcs (void)
1028 dissector_add_uint("fcct.server", FCCT_GSRVR_FCS, fcs_handle);
1032 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1034 * Local variables:
1035 * c-basic-offset: 4
1036 * tab-width: 8
1037 * indent-tabs-mode: nil
1038 * End:
1040 * vi: set shiftwidth=4 tabstop=8 expandtab:
1041 * :indentSize=4:tabSize=8:noTabs=true: