HACK: pinfo->private_data points to smb_info again
[wireshark-wip.git] / epan / dissectors / packet-fcip.c
blob333741d26c7bac2d7410d903d609fcb0feacb509
1 /* packet-fcip.c
2 * Routines for FCIP dissection
3 * RFC 3821, RFC 3643
4 * Copyright 2001, 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/prefs.h>
34 #define FCIP_ENCAP_HEADER_LEN 28
35 #define FCIP_MIN_HEADER_LEN 16 /* upto frame len field */
36 #define FCIP_IS_SF(pflags) ((pflags & 0x1) == 0x1)
37 #define FCIP_IS_CH(pflags) ((pflags & 0x80) == 0x80)
39 typedef enum {
40 FCIP_EOFn = 0x41,
41 FCIP_EOFt = 0x42,
42 FCIP_EOFrt = 0x44,
43 FCIP_EOFdt = 0x46,
44 FCIP_EOFni = 0x49,
45 FCIP_EOFdti = 0x4E,
46 FCIP_EOFrti = 0x4F,
47 FCIP_EOFa = 0x50
48 } fcip_eof_t;
50 typedef enum {
51 FCIP_SOFf = 0x28,
52 FCIP_SOFi4 = 0x29,
53 FCIP_SOFi2 = 0x2D,
54 FCIP_SOFi3 = 0x2E,
55 FCIP_SOFn4 = 0x31,
56 FCIP_SOFn2 = 0x35,
57 FCIP_SOFn3 = 0x36,
58 FCIP_SOFc4 = 0x39
59 } fcip_sof_t;
61 typedef enum {
62 FCENCAP_PROTO_FCIP = 1,
63 FCENCAP_PROTO_iFCP = 2
64 } fcencap_proto_t;
66 static const value_string fcip_eof_vals[] = {
67 {FCIP_EOFn, "EOFn" },
68 {FCIP_EOFt, "EOFt" },
69 {FCIP_EOFrt, "EOFrt" },
70 {FCIP_EOFdt, "EOFdt" },
71 {FCIP_EOFni, "EOFni" },
72 {FCIP_EOFdti, "EOFdti" },
73 {FCIP_EOFrti, "EOFrti" },
74 {FCIP_EOFa, "EOFa" },
75 {0, NULL},
78 static const value_string fcip_sof_vals[] = {
79 {FCIP_SOFf, "SOFf" },
80 {FCIP_SOFi4, "SOFi4" },
81 {FCIP_SOFi2, "SOFi2" },
82 {FCIP_SOFi3, "SOFi3" },
83 {FCIP_SOFn4, "SOFn4" },
84 {FCIP_SOFn2, "SOFn2" },
85 {FCIP_SOFn3, "SOFn3" },
86 {FCIP_SOFc4, "SOFc4" },
87 {0, NULL},
90 static const value_string fcencap_proto_vals[] = {
91 {FCENCAP_PROTO_FCIP, "FCIP" },
92 {FCENCAP_PROTO_iFCP, "iFCP" },
93 {0, NULL},
96 static const guint8 fcip_header_8_bytes[8] = {
97 0x01, 0x01, 0xFE, 0xFE,
98 0x01, 0x01, 0xFE, 0xFE
101 static int proto_fcip = -1;
103 static int hf_fcip_protocol = -1;
104 static int hf_fcip_protocol_c = -1;
105 static int hf_fcip_version = -1;
106 static int hf_fcip_version_c = -1;
107 static int hf_fcip_encap_word1 = -1;
108 static int hf_fcip_flags = -1;
109 static int hf_fcip_flags_c = -1;
110 static int hf_fcip_framelen = -1;
111 static int hf_fcip_framelen_c = -1;
112 static int hf_fcip_tsec = -1;
113 static int hf_fcip_tusec = -1;
114 static int hf_fcip_encap_crc = -1;
115 static int hf_fcip_sof = -1;
116 static int hf_fcip_sof_c = -1;
117 static int hf_fcip_eof = -1;
118 static int hf_fcip_eof_c = -1;
119 static int hf_fcip_pflags_changed = -1;
120 static int hf_fcip_pflags_special = -1;
121 static int hf_fcip_pflags_c = -1;
122 static int hf_fcip_src_wwn = -1;
123 static int hf_fcip_dst_wwn = -1;
124 static int hf_fcip_conn_code = -1;
125 static int hf_fcip_katov = -1;
126 static int hf_fcip_src_entity_id = -1;
127 static int hf_fcip_conn_nonce = -1;
128 static int hf_fcip_conn_flags = -1;
130 static int ett_fcip = -1;
132 static guint fcip_port = 3225;
133 static gboolean fcip_desegment = TRUE;
135 static dissector_handle_t data_handle;
136 static dissector_handle_t fc_handle;
138 /* This routine attempts to locate the position of the next header in the
139 * provided segment
141 static guint
142 get_next_fcip_header_offset (tvbuff_t *tvb, packet_info *pinfo, gint offset)
144 gint bytes_remaining = tvb_length_remaining (tvb, offset);
145 gint frame_len;
146 guint16 flen, flen1;
147 fcip_eof_t eof, eofc;
150 * As per the FCIP standard, the following tests must PASS:
151 * 1) Frame Length field validation -- 15 < Frame Length < 545;
152 * 2) Comparison of Frame Length field to its ones complement; and
153 * 3) A valid EOF is found in the word preceding the start of the next
154 * FCIP header as indicated by the Frame Length field, to be tested
155 * as follows:
156 * 1) Bits 24-31 and 16-23 contain identical legal EOF values (the
157 * list of legal EOF values is in the FC Frame Encapsulation
158 * [21]); and
159 * 2) Bits 8-15 and 0-7 contain the ones complement of the EOF
160 * value found in bits 24-31.
162 * As per the FCIP standard, in addition, at least 3 of the following set
163 * of tests must be performed to identify that we've located the start of
164 * an FCIP frame.
165 * a) Protocol# ones complement field (1 test);
166 * b) Version ones complement field (1 test);
167 * c) Replication of encapsulation word 0 in word 1 (1 test);
168 * d) Reserved field and its ones complement (2 tests);
169 * e) Flags field and its ones complement (2 tests);
170 * f) CRC field is equal to zero (1 test); (DONT DO THIS TEST!)
171 * g) SOF fields and ones complement fields (4 tests);
172 * h) Format and values of FC header (1 test);
173 * i) CRC of FC Frame (2 tests);
174 * j) FC Frame Encapsulation header information in the next FCIP Frame
175 * (1 test).
177 * At least 3 of the 16 tests listed above SHALL be performed. Failure
178 * of any of the above tests actually performed SHALL indicate an
179 * encapsulation error and the FC Frame SHALL NOT be forwarded on to
180 * the FC Entity.
183 NXT_BYTE: while (bytes_remaining) {
184 if (bytes_remaining < FCIP_ENCAP_HEADER_LEN) {
185 if(fcip_desegment && pinfo->can_desegment) {
187 * This frame doesn't have all of the data for
188 * the message header, but we can do reassembly on it.
190 * Tell the TCP dissector where the data for this
191 * message starts in the data it handed us, and that we need
192 * "some more data." Don't tell it exactly how many bytes
193 * we need because if/when we ask for even more (after the
194 * header) that will break reassembly.
196 pinfo->desegment_offset = offset;
197 pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT;
198 return -2;
202 /* I check that we have a valid header before checking for the frame
203 * length and the other initial tests.
207 * Tests a, b and c
209 if (tvb_memeql(tvb, offset, fcip_header_8_bytes, 8) != 0) {
210 offset++;
211 bytes_remaining--;
212 goto NXT_BYTE;
215 flen = (tvb_get_ntohs (tvb, offset+12)) & 0x03FF;
216 frame_len = (tvb_get_ntohs (tvb, offset+12) & 0x03FF)*4;
218 if ((flen < 15) || (flen > 545)) {
219 /* Frame length check failed. Skip byte and try again */
220 offset++;
221 bytes_remaining--;
222 goto NXT_BYTE;
225 flen1 = (tvb_get_ntohs (tvb, offset+14)) & 0x03FF;
227 if ((flen & 0x03FF) != ((~flen1)&0x03FF)) {
228 /* frame_len and its one's complement are not the same */
229 offset++;
230 bytes_remaining--;
231 goto NXT_BYTE;
234 /* Valid EOF check */
235 if (tvb_bytes_exist (tvb, offset+(frame_len-1)*4, 4)) {
236 eof = (fcip_eof_t)tvb_get_guint8 (tvb, offset+(frame_len-1)*4);
237 eofc = (fcip_eof_t)tvb_get_guint8 (tvb, offset+(frame_len-1)*4+2);
239 if ((eof != FCIP_EOFn) && (eof != FCIP_EOFt) && (eof != FCIP_EOFrt)
240 && (eof != FCIP_EOFdt) && (eof != FCIP_EOFni) &&
241 (eof != FCIP_EOFdti) && (eof != FCIP_EOFrti) &&
242 (eof != FCIP_EOFa)) {
243 offset++;
244 bytes_remaining--;
245 goto NXT_BYTE;
248 if ((eof != ~eofc) ||
249 (eof != tvb_get_guint8 (tvb, offset+(frame_len-1)*4+1)) ||
250 (eofc != tvb_get_guint8 (tvb, offset+(frame_len-1)*4+3))) {
251 offset++;
252 bytes_remaining--;
253 goto NXT_BYTE;
257 /* Test d */
258 if ((tvb_get_guint8 (tvb, offset+9) != 0) ||
259 (tvb_get_guint8 (tvb, offset+11) != 0xFF)) {
260 /* Failed */
261 offset++;
262 bytes_remaining--;
263 goto NXT_BYTE;
266 /* Test e */
269 /* Test f
270 * We dont test this since some implementations actually provide
271 * a CRC here.
274 if (bytes_remaining >= (frame_len)) {
275 if (tvb_bytes_exist (tvb, offset+frame_len, 8)) {
276 /* The start of the next header matches what we wish to see */
277 if (tvb_memeql (tvb, offset+frame_len, fcip_header_8_bytes,
278 8) == 0) {
279 return (offset);
281 else {
282 offset++;
283 bytes_remaining--;
284 goto NXT_BYTE;
287 else {
288 return (offset);
291 else {
292 if(fcip_desegment && pinfo->can_desegment) {
294 * This frame doesn't have all of the data for
295 * this message, but we can do reassembly on it.
297 * Tell the TCP dissector where the data for this
298 * message starts in the data it handed us, and
299 * how many more bytes we need, and return.
301 pinfo->desegment_offset = offset;
302 pinfo->desegment_len = frame_len - bytes_remaining;
303 return -2;
305 else {
306 return (offset);
311 return (-1); /* Unable to find FCIP header */
314 static void
315 dissect_fcencap_header (tvbuff_t *tvb, proto_tree *tree, gint offset)
317 guint8 protocol = tvb_get_guint8 (tvb, offset);
319 if (tree) {
320 proto_tree_add_uint (tree, hf_fcip_protocol, tvb, offset, 1, protocol);
321 proto_tree_add_item (tree, hf_fcip_version, tvb, offset+1, 1, ENC_BIG_ENDIAN);
322 proto_tree_add_item (tree, hf_fcip_protocol_c, tvb, offset+2, 1, ENC_BIG_ENDIAN);
323 proto_tree_add_item (tree, hf_fcip_version_c, tvb, offset+3, 1, ENC_BIG_ENDIAN);
325 if (protocol == FCENCAP_PROTO_FCIP) {
326 proto_tree_add_item (tree, hf_fcip_encap_word1, tvb, offset+4,
327 4, ENC_BIG_ENDIAN);
328 proto_tree_add_item (tree, hf_fcip_pflags_changed, tvb, offset+8,
329 1, ENC_BIG_ENDIAN);
330 proto_tree_add_item (tree, hf_fcip_pflags_special, tvb, offset+8,
331 1, ENC_BIG_ENDIAN);
332 proto_tree_add_item (tree, hf_fcip_pflags_c, tvb, offset+10, 1, ENC_BIG_ENDIAN);
335 /* XXX - break out CRCV flag. */
336 proto_tree_add_item (tree, hf_fcip_flags, tvb, offset+12, 1, ENC_BIG_ENDIAN);
337 proto_tree_add_item (tree, hf_fcip_framelen, tvb, offset+12, 2, ENC_BIG_ENDIAN);
338 proto_tree_add_item (tree, hf_fcip_flags_c, tvb, offset+14, 1, ENC_BIG_ENDIAN);
339 proto_tree_add_item (tree, hf_fcip_framelen_c, tvb, offset+14, 2, ENC_BIG_ENDIAN);
340 proto_tree_add_item (tree, hf_fcip_tsec, tvb, offset+16, 4, ENC_BIG_ENDIAN);
341 proto_tree_add_item (tree, hf_fcip_tusec, tvb, offset+20, 4, ENC_BIG_ENDIAN);
342 /* XXX - check CRC if CRCV is set? */
343 proto_tree_add_item (tree, hf_fcip_encap_crc, tvb, offset+24, 4, ENC_BIG_ENDIAN);
347 static void
348 dissect_fcip_sf (tvbuff_t *tvb, proto_tree *tree, gint offset)
350 if (tree) {
351 proto_tree_add_string (tree, hf_fcip_src_wwn, tvb, offset, 8,
352 tvb_fcwwn_to_str (tvb, offset));
353 proto_tree_add_item (tree, hf_fcip_src_entity_id, tvb, offset+8, 8,
354 ENC_NA);
355 proto_tree_add_item (tree, hf_fcip_conn_nonce, tvb, offset+16, 8,
356 ENC_NA);
357 /* XXX - break out these flags */
358 proto_tree_add_item (tree, hf_fcip_conn_flags, tvb, offset+24, 1, ENC_BIG_ENDIAN);
359 proto_tree_add_item (tree, hf_fcip_conn_code, tvb, offset+26, 2, ENC_BIG_ENDIAN);
360 proto_tree_add_string (tree, hf_fcip_dst_wwn, tvb, offset+30, 8,
361 tvb_fcwwn_to_str (tvb, offset+30));
362 proto_tree_add_item (tree, hf_fcip_katov, tvb, offset+38, 4, ENC_BIG_ENDIAN);
366 static gboolean
367 dissect_fcip (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
368 gboolean check_port)
370 gint offset = 0,
371 start = 0,
372 frame_len = 0;
373 gint bytes_remaining = tvb_length (tvb);
374 guint8 pflags, sof = 0, eof = 0;
375 /* Set up structures needed to add the protocol subtree and manage it */
376 proto_item *ti;
377 proto_tree *fcip_tree = NULL;
378 tvbuff_t *next_tvb;
380 if (bytes_remaining < FCIP_ENCAP_HEADER_LEN) {
381 return FALSE;
384 if (check_port &&
385 ((pinfo->srcport != fcip_port) && (pinfo->destport != fcip_port))) {
386 return FALSE;
389 while (bytes_remaining > FCIP_ENCAP_HEADER_LEN) {
390 if ((offset = get_next_fcip_header_offset (tvb, pinfo, offset)) == -1) {
391 return FALSE;
393 else if (offset == -2) {
394 /* We need more data to desegment */
395 return (TRUE);
398 start = offset;
399 col_set_str(pinfo->cinfo, COL_PROTOCOL, "FCIP");
401 frame_len = (tvb_get_ntohs (tvb, offset+12) & 0x03FF)*4;
403 if (bytes_remaining < frame_len) {
404 if(fcip_desegment && pinfo->can_desegment) {
406 * This frame doesn't have all of the data for
407 * this message, but we can do reassembly on it.
409 * Tell the TCP dissector where the data for this
410 * message starts in the data it handed us, and
411 * how many more bytes we need, and return.
413 pinfo->desegment_offset = offset;
414 pinfo->desegment_len = frame_len - bytes_remaining;
415 return (TRUE);
419 pflags = tvb_get_guint8 (tvb, start+8);
421 if (tree) {
422 if (FCIP_IS_SF (pflags)) {
423 ti = proto_tree_add_protocol_format (tree, proto_fcip, tvb, 0,
424 FCIP_ENCAP_HEADER_LEN,
425 "FCIP");
427 else if (tvb_bytes_exist (tvb, offset, offset+frame_len-4)) {
428 sof = tvb_get_guint8 (tvb, offset+FCIP_ENCAP_HEADER_LEN);
429 eof = tvb_get_guint8 (tvb, offset+frame_len - 4);
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 val_to_str (eof, fcip_eof_vals,
437 "0x%x"));
439 else {
440 sof = tvb_get_guint8 (tvb, offset+FCIP_ENCAP_HEADER_LEN);
442 ti = proto_tree_add_protocol_format (tree, proto_fcip, tvb, 0,
443 FCIP_ENCAP_HEADER_LEN,
444 "FCIP (%s/%s)",
445 val_to_str (sof, fcip_sof_vals,
446 "0x%x"),
447 "NA");
449 fcip_tree = proto_item_add_subtree (ti, ett_fcip);
450 /* Dissect the Common FC Encap header */
451 dissect_fcencap_header (tvb, fcip_tree, offset);
453 offset += FCIP_ENCAP_HEADER_LEN;
455 if (!FCIP_IS_SF (pflags)) {
456 /* print SOF */
457 proto_tree_add_item (fcip_tree, hf_fcip_sof, tvb, offset, 1, ENC_BIG_ENDIAN);
458 proto_tree_add_item (fcip_tree, hf_fcip_sof_c, tvb, offset+2, 1, ENC_BIG_ENDIAN);
459 /* print EOF */
461 offset += (frame_len-FCIP_ENCAP_HEADER_LEN-4);
462 if (tvb_bytes_exist (tvb, offset, 4)) {
463 proto_tree_add_item (fcip_tree, hf_fcip_eof, tvb, offset, 1, ENC_BIG_ENDIAN);
464 proto_tree_add_item (fcip_tree, hf_fcip_eof_c, tvb, offset+2, 1, ENC_BIG_ENDIAN);
469 /* Call the FC Dissector if this is carrying an FC frame */
470 if (!FCIP_IS_SF(pflags)) {
471 /* Set the SOF/EOF flags in the packet_info header */
472 pinfo->sof_eof = 0;
474 if (sof) {
475 if ((sof == FCIP_SOFi3) || (sof == FCIP_SOFi2) || (sof == FCIP_SOFi4)) {
476 pinfo->sof_eof = PINFO_SOF_FIRST_FRAME;
478 else if (sof == FCIP_SOFf) {
479 pinfo->sof_eof = PINFO_SOF_SOFF;
482 if (eof != FCIP_EOFn) {
483 pinfo->sof_eof |= PINFO_EOF_LAST_FRAME;
485 else if (eof != FCIP_EOFt) {
486 pinfo->sof_eof |= PINFO_EOF_INVALID;
490 /* Special frame bit is not set */
491 next_tvb = tvb_new_subset_remaining (tvb, FCIP_ENCAP_HEADER_LEN+4);
492 if (fc_handle) {
493 call_dissector (fc_handle, next_tvb, pinfo, tree);
495 else if (data_handle) {
496 call_dissector (data_handle, next_tvb, pinfo, tree);
499 else {
500 col_set_str(pinfo->cinfo, COL_INFO, "Special Frame");
501 if (FCIP_IS_CH (pflags)) {
502 col_append_str(pinfo->cinfo, COL_INFO, "(Changed)");
505 dissect_fcip_sf (tvb, fcip_tree, offset+4);
508 bytes_remaining -= frame_len;
511 return (TRUE);
514 /* This is called for those sessions where we have explicitely said
515 this to be FCIP using "Decode As..."
516 In this case we will not check the port number for sanity and just
517 do as the user said.
519 static void
520 dissect_fcip_handle(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
522 dissect_fcip (tvb, pinfo, tree, FALSE);
525 static gboolean
526 dissect_fcip_heur (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
528 return (dissect_fcip (tvb, pinfo, tree, TRUE));
531 void
532 proto_register_fcip (void)
535 /* Setup list of header fields See Section 1.6.1 for details*/
536 static hf_register_info hf[] = {
537 { &hf_fcip_protocol,
538 { "Protocol", "fcip.proto", FT_UINT8, BASE_DEC,
539 VALS(fcencap_proto_vals), 0, NULL, HFILL }},
540 { &hf_fcip_protocol_c,
541 {"Protocol (1's Complement)", "fcip.protoc", FT_UINT8, BASE_DEC,
542 NULL, 0, NULL, HFILL}},
543 { &hf_fcip_version,
544 {"Version", "fcip.version", FT_UINT8, BASE_DEC,
545 NULL, 0, NULL, HFILL}},
546 { &hf_fcip_version_c,
547 {"Version (1's Complement)", "fcip.versionc", FT_UINT8, BASE_DEC,
548 NULL, 0, NULL, HFILL}},
549 { &hf_fcip_encap_word1,
550 {"FCIP Encapsulation Word1", "fcip.encap_word1", FT_UINT32, BASE_HEX,
551 NULL, 0, NULL, HFILL}},
552 { &hf_fcip_flags,
553 {"Flags", "fcip.flags", FT_UINT8, BASE_HEX,
554 NULL, 0xFC, NULL, HFILL}},
555 { &hf_fcip_flags_c,
556 {"Flags (1's Complement)", "fcip.flagsc", FT_UINT8, BASE_HEX,
557 NULL, 0xFC, NULL, HFILL}},
558 { &hf_fcip_framelen,
559 {"Frame Length (in Words)", "fcip.framelen", FT_UINT16, BASE_DEC,
560 NULL, 0x03FF, NULL, HFILL}},
561 { &hf_fcip_framelen_c,
562 {"Frame Length (1's Complement)", "fcip.framelenc", FT_UINT16, BASE_DEC,
563 NULL, 0x03FF, NULL, HFILL}},
564 { &hf_fcip_tsec,
565 {"Time (secs)", "fcip.tsec", FT_UINT32, BASE_DEC,
566 NULL, 0, NULL, HFILL}},
567 { &hf_fcip_tusec,
568 {"Time (fraction)", "fcip.tusec", FT_UINT32, BASE_DEC,
569 NULL, 0, NULL, HFILL}},
570 { &hf_fcip_encap_crc,
571 {"CRC", "fcip.encap_crc", FT_UINT32, BASE_HEX,
572 NULL, 0, NULL, HFILL}},
573 { &hf_fcip_sof,
574 {"SOF", "fcip.sof", FT_UINT8, BASE_HEX,
575 VALS (&fcip_sof_vals), 0, NULL, HFILL}},
576 { &hf_fcip_sof_c,
577 {"SOF (1's Complement)", "fcip.sofc", FT_UINT8, BASE_HEX,
578 NULL, 0, NULL, HFILL}},
579 { &hf_fcip_eof,
580 {"EOF", "fcip.eof", FT_UINT8, BASE_HEX,
581 VALS (&fcip_eof_vals), 0, NULL, HFILL}},
582 { &hf_fcip_eof_c,
583 {"EOF (1's Complement)", "fcip.eofc", FT_UINT8, BASE_HEX,
584 NULL, 0, NULL, HFILL}},
585 { &hf_fcip_pflags_changed,
586 {"Changed Flag", "fcip.pflags.ch", FT_BOOLEAN, 8,
587 NULL, 0x80, NULL, HFILL}},
588 { &hf_fcip_pflags_special,
589 {"Special Frame Flag", "fcip.pflags.sf", FT_BOOLEAN, 8,
590 NULL, 0x1, NULL, HFILL}},
591 { &hf_fcip_pflags_c,
592 {"Pflags (1's Complement)", "fcip.pflagsc", FT_UINT8, BASE_HEX,
593 NULL, 0x0, NULL, HFILL}},
594 { &hf_fcip_src_wwn,
595 {"Source Fabric WWN", "fcip.srcwwn", FT_STRING, BASE_NONE,
596 NULL, 0x0, NULL, HFILL}},
597 { &hf_fcip_dst_wwn,
598 {"Destination Fabric WWN", "fcip.dstwwn", FT_STRING, BASE_NONE,
599 NULL, 0x0, NULL, HFILL}},
600 { &hf_fcip_src_entity_id,
601 {"FC/FCIP Entity Id", "fcip.srcid", FT_BYTES, BASE_NONE,
602 NULL, 0x0, NULL, HFILL}},
603 { &hf_fcip_conn_flags,
604 {"Connection Usage Flags", "fcip.connflags", FT_UINT8, BASE_HEX,
605 NULL, 0x0, NULL, HFILL}},
606 { &hf_fcip_conn_code,
607 {"Connection Usage Code", "fcip.conncode", FT_UINT16, BASE_HEX,
608 NULL, 0x0, NULL, HFILL}},
609 { &hf_fcip_katov,
610 {"K_A_TOV", "fcip.katov", FT_UINT32, BASE_DEC,
611 NULL, 0x0, NULL, HFILL}},
612 { &hf_fcip_conn_nonce,
613 {"Connection Nonce", "fcip.nonce", FT_BYTES, BASE_NONE,
614 NULL, 0x0, NULL, HFILL}},
617 static gint *ett[] = {
618 &ett_fcip,
621 module_t *fcip_module;
623 /* Register the protocol name and description */
624 proto_fcip = proto_register_protocol("FCIP", "Fibre Channel over IP", "fcip");
626 proto_register_field_array(proto_fcip, hf, array_length(hf));
627 proto_register_subtree_array(ett, array_length(ett));
629 fcip_module = prefs_register_protocol(proto_fcip, NULL);
630 prefs_register_bool_preference(fcip_module,
631 "desegment",
632 "Reassemble FCIP messages spanning multiple TCP segments",
633 "Whether the FCIP dissector should reassemble messages spanning multiple TCP segments."
634 " To use this option, you must also enable"
635 " \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
636 &fcip_desegment);
637 prefs_register_uint_preference(fcip_module,
638 "target_port",
639 "Target port",
640 "Port number used for FCIP",
642 &fcip_port);
645 void
646 proto_reg_handoff_fcip (void)
648 dissector_handle_t fcip_handle;
650 heur_dissector_add("tcp", dissect_fcip_heur, proto_fcip);
652 fcip_handle = create_dissector_handle(dissect_fcip_handle, proto_fcip);
653 dissector_add_handle("tcp.port", fcip_handle);
655 data_handle = find_dissector("data");
656 fc_handle = find_dissector("fc");