Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-fcip.c
blob47b87d7dc0959d92d556458fe4938d53f083401f
1 /* packet-fcip.c
2 * Routines for FCIP dissection
3 * RFC 3821, RFC 3643
4 * Copyright 2001, Dinesh G Dutt (ddutt@cisco.com)
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * SPDX-License-Identifier: GPL-2.0-or-later
13 #include "config.h"
15 #include <epan/packet.h>
16 #include <epan/prefs.h>
17 #include <epan/to_str.h>
18 #include "packet-fc.h"
20 void proto_register_fcip(void);
21 void proto_reg_handoff_fcip(void);
23 #define FCIP_ENCAP_HEADER_LEN 28
24 #define FCIP_MIN_HEADER_LEN 16 /* up to frame len field */
25 #define FCIP_IS_SF(pflags) ((pflags & 0x1) == 0x1)
26 #define FCIP_IS_CH(pflags) ((pflags & 0x80) == 0x80)
28 typedef enum {
29 FCIP_EOFn = 0x41,
30 FCIP_EOFt = 0x42,
31 FCIP_EOFrt = 0x44,
32 FCIP_EOFdt = 0x46,
33 FCIP_EOFni = 0x49,
34 FCIP_EOFdti = 0x4E,
35 FCIP_EOFrti = 0x4F,
36 FCIP_EOFa = 0x50
37 } fcip_eof_t;
39 typedef enum {
40 FCIP_SOFf = 0x28,
41 FCIP_SOFi4 = 0x29,
42 FCIP_SOFi2 = 0x2D,
43 FCIP_SOFi3 = 0x2E,
44 FCIP_SOFn4 = 0x31,
45 FCIP_SOFn2 = 0x35,
46 FCIP_SOFn3 = 0x36,
47 FCIP_SOFc4 = 0x39
48 } fcip_sof_t;
50 typedef enum {
51 FCENCAP_PROTO_FCIP = 1,
52 FCENCAP_PROTO_iFCP = 2
53 } fcencap_proto_t;
55 static const value_string fcip_eof_vals[] = {
56 {FCIP_EOFn, "EOFn" },
57 {FCIP_EOFt, "EOFt" },
58 {FCIP_EOFrt, "EOFrt" },
59 {FCIP_EOFdt, "EOFdt" },
60 {FCIP_EOFni, "EOFni" },
61 {FCIP_EOFdti, "EOFdti" },
62 {FCIP_EOFrti, "EOFrti" },
63 {FCIP_EOFa, "EOFa" },
64 {0, NULL},
67 static const value_string fcip_sof_vals[] = {
68 {FCIP_SOFf, "SOFf" },
69 {FCIP_SOFi4, "SOFi4" },
70 {FCIP_SOFi2, "SOFi2" },
71 {FCIP_SOFi3, "SOFi3" },
72 {FCIP_SOFn4, "SOFn4" },
73 {FCIP_SOFn2, "SOFn2" },
74 {FCIP_SOFn3, "SOFn3" },
75 {FCIP_SOFc4, "SOFc4" },
76 {0, NULL},
79 static const value_string fcencap_proto_vals[] = {
80 {FCENCAP_PROTO_FCIP, "FCIP" },
81 {FCENCAP_PROTO_iFCP, "iFCP" },
82 {0, NULL},
85 static const uint8_t fcip_header_8_bytes[8] = {
86 0x01, 0x01, 0xFE, 0xFE,
87 0x01, 0x01, 0xFE, 0xFE
90 static int proto_fcip;
92 static int hf_fcip_protocol;
93 static int hf_fcip_protocol_c;
94 static int hf_fcip_version;
95 static int hf_fcip_version_c;
96 static int hf_fcip_encap_word1;
97 static int hf_fcip_flags;
98 static int hf_fcip_flags_c;
99 static int hf_fcip_framelen;
100 static int hf_fcip_framelen_c;
101 static int hf_fcip_tsec;
102 static int hf_fcip_tusec;
103 static int hf_fcip_encap_crc;
104 static int hf_fcip_sof;
105 static int hf_fcip_sof_c;
106 static int hf_fcip_eof;
107 static int hf_fcip_eof_c;
108 static int hf_fcip_pflags_changed;
109 static int hf_fcip_pflags_special;
110 static int hf_fcip_pflags_c;
111 static int hf_fcip_src_wwn;
112 static int hf_fcip_dst_wwn;
113 static int hf_fcip_conn_code;
114 static int hf_fcip_katov;
115 static int hf_fcip_src_entity_id;
116 static int hf_fcip_conn_nonce;
117 static int hf_fcip_conn_flags;
119 static int ett_fcip;
121 static unsigned fcip_port = 3225;
122 static bool fcip_desegment = true;
124 static dissector_handle_t fc_handle;
125 static dissector_handle_t fcip_handle;
128 /* This routine attempts to locate the position of the next header in the
129 * provided segment
131 static unsigned
132 get_next_fcip_header_offset (tvbuff_t *tvb, packet_info *pinfo, int offset)
134 int bytes_remaining = tvb_reported_length_remaining (tvb, offset);
135 int frame_len;
136 uint16_t flen, flen1;
137 fcip_eof_t eof, eofc;
140 * As per the FCIP standard, the following tests must PASS:
141 * 1) Frame Length field validation -- 15 < Frame Length < 545;
142 * 2) Comparison of Frame Length field to its ones complement; and
143 * 3) A valid EOF is found in the word preceding the start of the next
144 * FCIP header as indicated by the Frame Length field, to be tested
145 * as follows:
146 * 1) Bits 24-31 and 16-23 contain identical legal EOF values (the
147 * list of legal EOF values is in the FC Frame Encapsulation
148 * [21]); and
149 * 2) Bits 8-15 and 0-7 contain the ones complement of the EOF
150 * value found in bits 24-31.
152 * As per the FCIP standard, in addition, at least 3 of the following set
153 * of tests must be performed to identify that we've located the start of
154 * an FCIP frame.
155 * a) Protocol# ones complement field (1 test);
156 * b) Version ones complement field (1 test);
157 * c) Replication of encapsulation word 0 in word 1 (1 test);
158 * d) Reserved field and its ones complement (2 tests);
159 * e) Flags field and its ones complement (2 tests);
160 * f) CRC field is equal to zero (1 test); (DON'T DO THIS TEST!)
161 * g) SOF fields and ones complement fields (4 tests);
162 * h) Format and values of FC header (1 test);
163 * i) CRC of FC Frame (2 tests);
164 * j) FC Frame Encapsulation header information in the next FCIP Frame
165 * (1 test).
167 * At least 3 of the 16 tests listed above SHALL be performed. Failure
168 * of any of the above tests actually performed SHALL indicate an
169 * encapsulation error and the FC Frame SHALL NOT be forwarded on to
170 * the FC Entity.
173 NXT_BYTE: while (bytes_remaining) {
174 if (bytes_remaining < FCIP_ENCAP_HEADER_LEN) {
175 if(fcip_desegment && pinfo->can_desegment) {
177 * This frame doesn't have all of the data for
178 * the message header, but we can do reassembly on it.
180 * Tell the TCP dissector where the data for this
181 * message starts in the data it handed us, and that we need
182 * "some more data." Don't tell it exactly how many bytes
183 * we need because if/when we ask for even more (after the
184 * header) that will break reassembly.
186 pinfo->desegment_offset = offset;
187 pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT;
188 return -2;
192 /* I check that we have a valid header before checking for the frame
193 * length and the other initial tests.
197 * Tests a, b and c
199 if (tvb_memeql(tvb, offset, fcip_header_8_bytes, 8) != 0) {
200 offset++;
201 bytes_remaining--;
202 goto NXT_BYTE;
205 flen = (tvb_get_ntohs (tvb, offset+12)) & 0x03FF;
206 frame_len = (tvb_get_ntohs (tvb, offset+12) & 0x03FF)*4;
208 if ((flen < 15) || (flen > 545)) {
209 /* Frame length check failed. Skip byte and try again */
210 offset++;
211 bytes_remaining--;
212 goto NXT_BYTE;
215 flen1 = (tvb_get_ntohs (tvb, offset+14)) & 0x03FF;
217 if ((flen & 0x03FF) != ((~flen1)&0x03FF)) {
218 /* frame_len and its one's complement are not the same */
219 offset++;
220 bytes_remaining--;
221 goto NXT_BYTE;
224 /* Valid EOF check */
225 if (tvb_bytes_exist (tvb, offset+(frame_len-1)*4, 4)) {
226 eof = (fcip_eof_t)tvb_get_uint8 (tvb, offset+(frame_len-1)*4);
227 eofc = (fcip_eof_t)tvb_get_uint8 (tvb, offset+(frame_len-1)*4+2);
229 if ((eof != FCIP_EOFn) && (eof != FCIP_EOFt) && (eof != FCIP_EOFrt)
230 && (eof != FCIP_EOFdt) && (eof != FCIP_EOFni) &&
231 (eof != FCIP_EOFdti) && (eof != FCIP_EOFrti) &&
232 (eof != FCIP_EOFa)) {
233 offset++;
234 bytes_remaining--;
235 goto NXT_BYTE;
238 if ((eof != ~eofc) ||
239 (eof != tvb_get_uint8 (tvb, offset+(frame_len-1)*4+1)) ||
240 (eofc != tvb_get_uint8 (tvb, offset+(frame_len-1)*4+3))) {
241 offset++;
242 bytes_remaining--;
243 goto NXT_BYTE;
247 /* Test d */
248 if ((tvb_get_uint8 (tvb, offset+9) != 0) ||
249 (tvb_get_uint8 (tvb, offset+11) != 0xFF)) {
250 /* Failed */
251 offset++;
252 bytes_remaining--;
253 goto NXT_BYTE;
256 /* Test e */
259 /* Test f
260 * We don't test this since some implementations actually provide
261 * a CRC here.
264 if (bytes_remaining >= (frame_len)) {
265 if (tvb_bytes_exist (tvb, offset+frame_len, 8)) {
266 /* The start of the next header matches what we wish to see */
267 if (tvb_memeql (tvb, offset+frame_len, fcip_header_8_bytes,
268 8) == 0) {
269 return (offset);
271 else {
272 offset++;
273 bytes_remaining--;
274 goto NXT_BYTE;
277 else {
278 return (offset);
281 else {
282 if(fcip_desegment && pinfo->can_desegment) {
284 * This frame doesn't have all of the data for
285 * this message, but we can do reassembly on it.
287 * Tell the TCP dissector where the data for this
288 * message starts in the data it handed us, and
289 * how many more bytes we need, and return.
291 pinfo->desegment_offset = offset;
292 pinfo->desegment_len = frame_len - bytes_remaining;
293 return -2;
295 else {
296 return (offset);
301 return (-1); /* Unable to find FCIP header */
304 static void
305 dissect_fcencap_header (tvbuff_t *tvb, proto_tree *tree, int offset)
307 uint8_t protocol = tvb_get_uint8 (tvb, offset);
309 if (tree) {
310 proto_tree_add_uint (tree, hf_fcip_protocol, tvb, offset, 1, protocol);
311 proto_tree_add_item (tree, hf_fcip_version, tvb, offset+1, 1, ENC_BIG_ENDIAN);
312 proto_tree_add_item (tree, hf_fcip_protocol_c, tvb, offset+2, 1, ENC_BIG_ENDIAN);
313 proto_tree_add_item (tree, hf_fcip_version_c, tvb, offset+3, 1, ENC_BIG_ENDIAN);
315 if (protocol == FCENCAP_PROTO_FCIP) {
316 proto_tree_add_item (tree, hf_fcip_encap_word1, tvb, offset+4,
317 4, ENC_BIG_ENDIAN);
318 proto_tree_add_item (tree, hf_fcip_pflags_changed, tvb, offset+8,
319 1, ENC_BIG_ENDIAN);
320 proto_tree_add_item (tree, hf_fcip_pflags_special, tvb, offset+8,
321 1, ENC_BIG_ENDIAN);
322 proto_tree_add_item (tree, hf_fcip_pflags_c, tvb, offset+10, 1, ENC_BIG_ENDIAN);
325 /* XXX - break out CRCV flag. */
326 proto_tree_add_item (tree, hf_fcip_flags, tvb, offset+12, 1, ENC_BIG_ENDIAN);
327 proto_tree_add_item (tree, hf_fcip_framelen, tvb, offset+12, 2, ENC_BIG_ENDIAN);
328 proto_tree_add_item (tree, hf_fcip_flags_c, tvb, offset+14, 1, ENC_BIG_ENDIAN);
329 proto_tree_add_item (tree, hf_fcip_framelen_c, tvb, offset+14, 2, ENC_BIG_ENDIAN);
330 proto_tree_add_item (tree, hf_fcip_tsec, tvb, offset+16, 4, ENC_BIG_ENDIAN);
331 proto_tree_add_item (tree, hf_fcip_tusec, tvb, offset+20, 4, ENC_BIG_ENDIAN);
332 /* XXX - check CRC if CRCV is set? */
333 proto_tree_add_item (tree, hf_fcip_encap_crc, tvb, offset+24, 4, ENC_BIG_ENDIAN);
337 static void
338 dissect_fcip_sf (tvbuff_t *tvb, proto_tree *tree, int offset)
340 if (tree) {
341 proto_tree_add_item (tree, hf_fcip_src_wwn, tvb, offset, 8, ENC_NA);
342 proto_tree_add_item (tree, hf_fcip_src_entity_id, tvb, offset+8, 8,
343 ENC_NA);
344 proto_tree_add_item (tree, hf_fcip_conn_nonce, tvb, offset+16, 8,
345 ENC_NA);
346 /* XXX - break out these flags */
347 proto_tree_add_item (tree, hf_fcip_conn_flags, tvb, offset+24, 1, ENC_BIG_ENDIAN);
348 proto_tree_add_item (tree, hf_fcip_conn_code, tvb, offset+26, 2, ENC_BIG_ENDIAN);
349 proto_tree_add_item (tree, hf_fcip_dst_wwn, tvb, offset+30, 8, ENC_NA);
350 proto_tree_add_item (tree, hf_fcip_katov, tvb, offset+38, 4, ENC_BIG_ENDIAN);
354 static bool
355 dissect_fcip (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
356 bool check_port)
358 int offset = 0,
359 start = 0,
360 frame_len = 0;
361 int bytes_remaining = tvb_captured_length (tvb);
362 uint8_t pflags, sof = 0, eof = 0;
363 /* Set up structures needed to add the protocol subtree and manage it */
364 proto_item *ti;
365 proto_tree *fcip_tree = NULL;
366 tvbuff_t *next_tvb;
367 fc_data_t fc_data;
369 if (bytes_remaining < FCIP_ENCAP_HEADER_LEN) {
370 return false;
373 if (check_port &&
374 ((pinfo->srcport != fcip_port) && (pinfo->destport != fcip_port))) {
375 return false;
378 while (bytes_remaining > FCIP_ENCAP_HEADER_LEN) {
379 if ((offset = get_next_fcip_header_offset (tvb, pinfo, offset)) == -1) {
380 return false;
382 else if (offset == -2) {
383 /* We need more data to desegment */
384 return true;
387 start = offset;
388 col_set_str(pinfo->cinfo, COL_PROTOCOL, "FCIP");
390 frame_len = (tvb_get_ntohs (tvb, offset+12) & 0x03FF)*4;
392 if (bytes_remaining < frame_len) {
393 if(fcip_desegment && pinfo->can_desegment) {
395 * This frame doesn't have all of the data for
396 * this message, but we can do reassembly on it.
398 * Tell the TCP dissector where the data for this
399 * message starts in the data it handed us, and
400 * how many more bytes we need, and return.
402 pinfo->desegment_offset = offset;
403 pinfo->desegment_len = frame_len - bytes_remaining;
404 return true;
408 pflags = tvb_get_uint8 (tvb, start+8);
410 if (tree) {
411 if (FCIP_IS_SF (pflags)) {
412 ti = proto_tree_add_protocol_format (tree, proto_fcip, tvb, 0,
413 FCIP_ENCAP_HEADER_LEN,
414 "FCIP");
416 else if (tvb_bytes_exist (tvb, offset, offset+frame_len-4)) {
417 sof = tvb_get_uint8 (tvb, offset+FCIP_ENCAP_HEADER_LEN);
418 eof = tvb_get_uint8 (tvb, offset+frame_len - 4);
420 ti = proto_tree_add_protocol_format (tree, proto_fcip, tvb, 0,
421 FCIP_ENCAP_HEADER_LEN,
422 "FCIP (%s/%s)",
423 val_to_str (sof, fcip_sof_vals,
424 "0x%x"),
425 val_to_str (eof, fcip_eof_vals,
426 "0x%x"));
428 else {
429 sof = tvb_get_uint8 (tvb, offset+FCIP_ENCAP_HEADER_LEN);
431 ti = proto_tree_add_protocol_format (tree, proto_fcip, tvb, 0,
432 FCIP_ENCAP_HEADER_LEN,
433 "FCIP (%s/%s)",
434 val_to_str (sof, fcip_sof_vals,
435 "0x%x"),
436 "NA");
438 fcip_tree = proto_item_add_subtree (ti, ett_fcip);
439 /* Dissect the Common FC Encap header */
440 dissect_fcencap_header (tvb, fcip_tree, offset);
442 offset += FCIP_ENCAP_HEADER_LEN;
444 if (!FCIP_IS_SF (pflags)) {
445 /* print SOF */
446 proto_tree_add_item (fcip_tree, hf_fcip_sof, tvb, offset, 1, ENC_BIG_ENDIAN);
447 proto_tree_add_item (fcip_tree, hf_fcip_sof_c, tvb, offset+2, 1, ENC_BIG_ENDIAN);
448 /* print EOF */
450 offset += (frame_len-FCIP_ENCAP_HEADER_LEN-4);
451 if (tvb_bytes_exist (tvb, offset, 4)) {
452 proto_tree_add_item (fcip_tree, hf_fcip_eof, tvb, offset, 1, ENC_BIG_ENDIAN);
453 proto_tree_add_item (fcip_tree, hf_fcip_eof_c, tvb, offset+2, 1, ENC_BIG_ENDIAN);
458 /* Call the FC Dissector if this is carrying an FC frame */
459 if (!FCIP_IS_SF(pflags)) {
460 /* Set the SOF/EOF flags in the packet_info header */
461 fc_data.sof_eof = 0;
463 if (sof) {
464 if ((sof == FCIP_SOFi3) || (sof == FCIP_SOFi2) || (sof == FCIP_SOFi4)) {
465 fc_data.sof_eof = FC_DATA_SOF_FIRST_FRAME;
467 else if (sof == FCIP_SOFf) {
468 fc_data.sof_eof = FC_DATA_SOF_SOFF;
471 if (eof != FCIP_EOFn) {
472 fc_data.sof_eof |= FC_DATA_EOF_LAST_FRAME;
474 else if (eof != FCIP_EOFt) {
475 fc_data.sof_eof |= FC_DATA_EOF_INVALID;
479 /* Special frame bit is not set */
480 next_tvb = tvb_new_subset_remaining (tvb, FCIP_ENCAP_HEADER_LEN+4);
481 if (fc_handle) {
482 fc_data.ethertype = ETHERTYPE_UNK;
483 call_dissector_with_data(fc_handle, next_tvb, pinfo, tree, &fc_data);
485 else {
486 call_data_dissector(next_tvb, pinfo, tree);
489 else {
490 col_set_str(pinfo->cinfo, COL_INFO, "Special Frame");
491 if (FCIP_IS_CH (pflags)) {
492 col_append_str(pinfo->cinfo, COL_INFO, "(Changed)");
495 dissect_fcip_sf (tvb, fcip_tree, offset+4);
498 bytes_remaining -= frame_len;
501 return true;
504 /* This is called for those sessions where we have explicitly said
505 this to be FCIP using "Decode As..."
506 In this case we will not check the port number for sanity and just
507 do as the user said.
509 static int
510 dissect_fcip_handle(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
512 dissect_fcip (tvb, pinfo, tree, false);
513 return tvb_captured_length(tvb);
516 static bool
517 dissect_fcip_heur (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
519 return (dissect_fcip (tvb, pinfo, tree, true));
522 void
523 proto_register_fcip (void)
526 /* Setup list of header fields See Section 1.6.1 for details*/
527 static hf_register_info hf[] = {
528 { &hf_fcip_protocol,
529 { "Protocol", "fcip.proto", FT_UINT8, BASE_DEC,
530 VALS(fcencap_proto_vals), 0, NULL, HFILL }},
531 { &hf_fcip_protocol_c,
532 {"Protocol (1's Complement)", "fcip.protoc", FT_UINT8, BASE_DEC,
533 NULL, 0, NULL, HFILL}},
534 { &hf_fcip_version,
535 {"Version", "fcip.version", FT_UINT8, BASE_DEC,
536 NULL, 0, NULL, HFILL}},
537 { &hf_fcip_version_c,
538 {"Version (1's Complement)", "fcip.versionc", FT_UINT8, BASE_DEC,
539 NULL, 0, NULL, HFILL}},
540 { &hf_fcip_encap_word1,
541 {"FCIP Encapsulation Word1", "fcip.encap_word1", FT_UINT32, BASE_HEX,
542 NULL, 0, NULL, HFILL}},
543 { &hf_fcip_flags,
544 {"Flags", "fcip.flags", FT_UINT8, BASE_HEX,
545 NULL, 0xFC, NULL, HFILL}},
546 { &hf_fcip_flags_c,
547 {"Flags (1's Complement)", "fcip.flagsc", FT_UINT8, BASE_HEX,
548 NULL, 0xFC, NULL, HFILL}},
549 { &hf_fcip_framelen,
550 {"Frame Length (in Words)", "fcip.framelen", FT_UINT16, BASE_DEC,
551 NULL, 0x03FF, NULL, HFILL}},
552 { &hf_fcip_framelen_c,
553 {"Frame Length (1's Complement)", "fcip.framelenc", FT_UINT16, BASE_DEC,
554 NULL, 0x03FF, NULL, HFILL}},
555 { &hf_fcip_tsec,
556 {"Time (secs)", "fcip.tsec", FT_UINT32, BASE_DEC,
557 NULL, 0, NULL, HFILL}},
558 { &hf_fcip_tusec,
559 {"Time (fraction)", "fcip.tusec", FT_UINT32, BASE_DEC,
560 NULL, 0, NULL, HFILL}},
561 { &hf_fcip_encap_crc,
562 {"CRC", "fcip.encap_crc", FT_UINT32, BASE_HEX,
563 NULL, 0, NULL, HFILL}},
564 { &hf_fcip_sof,
565 {"SOF", "fcip.sof", FT_UINT8, BASE_HEX,
566 VALS (fcip_sof_vals), 0, NULL, HFILL}},
567 { &hf_fcip_sof_c,
568 {"SOF (1's Complement)", "fcip.sofc", FT_UINT8, BASE_HEX,
569 NULL, 0, NULL, HFILL}},
570 { &hf_fcip_eof,
571 {"EOF", "fcip.eof", FT_UINT8, BASE_HEX,
572 VALS (fcip_eof_vals), 0, NULL, HFILL}},
573 { &hf_fcip_eof_c,
574 {"EOF (1's Complement)", "fcip.eofc", FT_UINT8, BASE_HEX,
575 NULL, 0, NULL, HFILL}},
576 { &hf_fcip_pflags_changed,
577 {"Changed Flag", "fcip.pflags.ch", FT_BOOLEAN, 8,
578 NULL, 0x80, NULL, HFILL}},
579 { &hf_fcip_pflags_special,
580 {"Special Frame Flag", "fcip.pflags.sf", FT_BOOLEAN, 8,
581 NULL, 0x1, NULL, HFILL}},
582 { &hf_fcip_pflags_c,
583 {"Pflags (1's Complement)", "fcip.pflagsc", FT_UINT8, BASE_HEX,
584 NULL, 0x0, NULL, HFILL}},
585 { &hf_fcip_src_wwn,
586 {"Source Fabric WWN", "fcip.srcwwn", FT_FCWWN, BASE_NONE,
587 NULL, 0x0, NULL, HFILL}},
588 { &hf_fcip_dst_wwn,
589 {"Destination Fabric WWN", "fcip.dstwwn", FT_FCWWN, BASE_NONE,
590 NULL, 0x0, NULL, HFILL}},
591 { &hf_fcip_src_entity_id,
592 {"FC/FCIP Entity Id", "fcip.srcid", FT_BYTES, BASE_NONE,
593 NULL, 0x0, NULL, HFILL}},
594 { &hf_fcip_conn_flags,
595 {"Connection Usage Flags", "fcip.connflags", FT_UINT8, BASE_HEX,
596 NULL, 0x0, NULL, HFILL}},
597 { &hf_fcip_conn_code,
598 {"Connection Usage Code", "fcip.conncode", FT_UINT16, BASE_HEX,
599 NULL, 0x0, NULL, HFILL}},
600 { &hf_fcip_katov,
601 {"K_A_TOV", "fcip.katov", FT_UINT32, BASE_DEC,
602 NULL, 0x0, NULL, HFILL}},
603 { &hf_fcip_conn_nonce,
604 {"Connection Nonce", "fcip.nonce", FT_BYTES, BASE_NONE,
605 NULL, 0x0, NULL, HFILL}},
608 static int *ett[] = {
609 &ett_fcip,
612 module_t *fcip_module;
614 /* Register the protocol name and description */
615 proto_fcip = proto_register_protocol("FCIP", "Fibre Channel over IP", "fcip");
616 fcip_handle = register_dissector("fcip", dissect_fcip_handle, proto_fcip);
618 proto_register_field_array(proto_fcip, hf, array_length(hf));
619 proto_register_subtree_array(ett, array_length(ett));
621 fcip_module = prefs_register_protocol(proto_fcip, NULL);
622 prefs_register_bool_preference(fcip_module,
623 "desegment",
624 "Reassemble FCIP messages spanning multiple TCP segments",
625 "Whether the FCIP dissector should reassemble messages spanning multiple TCP segments."
626 " To use this option, you must also enable"
627 " \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
628 &fcip_desegment);
629 prefs_register_uint_preference(fcip_module,
630 "target_port",
631 "Target port",
632 "Port number used for FCIP",
634 &fcip_port);
637 void
638 proto_reg_handoff_fcip (void)
640 heur_dissector_add("tcp", dissect_fcip_heur, "FCIP over TCP", "fcip_tcp", proto_fcip, HEURISTIC_ENABLE);
642 dissector_add_for_decode_as_with_preference("tcp.port", fcip_handle);
644 fc_handle = find_dissector_add_dependency("fc", proto_fcip);
648 * Editor modelines - https://www.wireshark.org/tools/modelines.html
650 * Local variables:
651 * c-basic-offset: 4
652 * tab-width: 8
653 * indent-tabs-mode: nil
654 * End:
656 * vi: set shiftwidth=4 tabstop=8 expandtab:
657 * :indentSize=4:tabSize=8:noTabs=true: