Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-ifcp.c
bloba594e666e61679524c9e0bab9c6dcb83f9c52b08
1 /* packet-ifcp.c
2 * Routines for iFCP dissection
3 * RFC 3821, RFC 3643
5 * Copyright 2005 Aboo Valappil (valappil_aboo@emc.com)
6 * 2006 ronnie sahlberg major refactoring
9 * Significantly based on packet-fcip.c by
10 * Copyright 2001, Dinesh G Dutt (ddutt@cisco.com)
12 * Wireshark - Network traffic analyzer
13 * By Gerald Combs <gerald@wireshark.org>
14 * Copyright 1998 Gerald Combs
16 * SPDX-License-Identifier: GPL-2.0-or-later
19 #include "config.h"
21 #include <epan/packet.h>
22 #include <epan/prefs.h>
23 #include <epan/tfs.h>
24 #include <wsutil/array.h>
26 #include "packet-tcp.h"
27 #include "packet-fc.h"
29 void proto_register_ifcp(void);
30 void proto_reg_handoff_ifcp(void);
32 #define iFCP_ENCAP_HEADER_LEN 28
33 #define iFCP_MIN_HEADER_LEN 16 /* up to frame len field */
35 typedef enum {
36 iFCP_EOFn = 0x41,
37 iFCP_EOFt = 0x42,
38 iFCP_EOFrt = 0x44,
39 iFCP_EOFdt = 0x46,
40 iFCP_EOFni = 0x49,
41 iFCP_EOFdti = 0x4E,
42 iFCP_EOFrti = 0x4F,
43 iFCP_EOFa = 0x50
44 } ifcp_eof_t;
46 typedef enum {
47 iFCP_SOFf = 0x28,
48 iFCP_SOFi4 = 0x29,
49 iFCP_SOFi2 = 0x2D,
50 iFCP_SOFi3 = 0x2E,
51 iFCP_SOFn4 = 0x31,
52 iFCP_SOFn2 = 0x35,
53 iFCP_SOFn3 = 0x36,
54 iFCP_SOFc4 = 0x39
55 } ifcp_sof_t;
57 typedef enum {
58 FCENCAP_PROTO_FCIP = 1,
59 FCENCAP_PROTO_iFCP = 2
60 } fcencap_proto_t;
62 static const value_string ifcp_eof_vals[] = {
63 {iFCP_EOFn, "EOFn" },
64 {iFCP_EOFt, "EOFt" },
65 {iFCP_EOFrt, "EOFrt" },
66 {iFCP_EOFdt, "EOFdt" },
67 {iFCP_EOFni, "EOFni" },
68 {iFCP_EOFdti, "EOFdti" },
69 {iFCP_EOFrti, "EOFrti" },
70 {iFCP_EOFa, "EOFa" },
71 {0, NULL},
74 static const value_string ifcp_sof_vals[] = {
75 {iFCP_SOFf, "SOFf" },
76 {iFCP_SOFi4, "SOFi4" },
77 {iFCP_SOFi2, "SOFi2" },
78 {iFCP_SOFi3, "SOFi3" },
79 {iFCP_SOFn4, "SOFn4" },
80 {iFCP_SOFn2, "SOFn2" },
81 {iFCP_SOFn3, "SOFn3" },
82 {iFCP_SOFc4, "SOFc4" },
83 {0, NULL},
86 static const value_string fcencap_proto_vals[] = {
87 {FCENCAP_PROTO_iFCP, "iFCP"},
88 {FCENCAP_PROTO_iFCP, "iFCP"},
89 {0, NULL},
92 /* RFC 4172 section 5.3.1 shows a chart of the iFCP encapsulated Header Format.
93 * It says that bytes 4-7 MUST be zeros. In reality most vendors are putting
94 * some information in these 4 bytes, particularly Nishon.
96 static const uint8_t ifcp_header_4_bytes[4] = {
97 0x02, 0x01, 0xFD, 0xFE
100 static int proto_ifcp;
102 static int hf_ifcp_protocol;
103 static int hf_ifcp_protocol_c;
104 static int hf_ifcp_version;
105 static int hf_ifcp_version_c;
106 static int hf_ifcp_encap_flags_c;
107 static int hf_ifcp_framelen;
108 static int hf_ifcp_framelen_c;
109 static int hf_ifcp_tsec;
110 static int hf_ifcp_tusec;
111 static int hf_ifcp_encap_crc;
112 static int hf_ifcp_sof;
113 static int hf_ifcp_sof_c;
114 static int hf_ifcp_eof;
115 static int hf_ifcp_eof_c;
116 static int hf_ifcp_ls_command_acc;
117 static int hf_ifcp_flags;
118 static int hf_ifcp_flags_ses;
119 static int hf_ifcp_flags_trp;
120 static int hf_ifcp_flags_spc;
121 static int hf_ifcp_common_flags;
122 static int hf_ifcp_common_flags_crcv;
124 static int ett_ifcp;
125 static int ett_ifcp_sof;
126 static int ett_ifcp_eof;
127 static int ett_ifcp_flags;
128 static int ett_ifcp_common_flags;
129 static int ett_ifcp_protocol;
130 static int ett_ifcp_version;
131 static int ett_ifcp_frame_len;
133 static bool ifcp_desegment = true;
135 static dissector_handle_t ifcp_handle;
136 static dissector_handle_t fc_handle;
139 /* This function checks the first 16 bytes of the "header" that it looks sane
140 * and returns true if this looks like iFCP and false if it doesn't.
142 static bool
143 ifcp_header_test(tvbuff_t *tvb, int offset)
145 uint16_t flen, flen1;
147 /* we can only do this test if we have 16 bytes or more */
148 if(tvb_captured_length_remaining(tvb, offset)<iFCP_MIN_HEADER_LEN){
149 return false;
153 * As per the iFCP standard, the following tests must PASS:
154 * 1) Frame Length field validation -- 15 < Frame Length < 545;
155 * 2) Comparison of Frame Length field to its ones complement; and
156 * 3) A valid EOF is found in the word preceding the start of the next
157 * iFCP header as indicated by the Frame Length field, to be tested
158 * as follows:
159 * 1) Bits 24-31 and 16-23 contain identical legal EOF values (the
160 * list of legal EOF values is in the FC Frame Encapsulation
161 * [21]); and
162 * 2) Bits 8-15 and 0-7 contain the ones complement of the EOF
163 * value found in bits 24-31.
165 * As per the iFCP standard, in addition, at least 3 of the following
166 * set of tests must be performed to identify that we've located the
167 * start of an iFCP frame.
168 * a) Protocol# ones complement field (1 test);
169 * b) Version ones complement field (1 test);
170 * c) Replication of encapsulation word 0 in word 1 (1 test);
171 * d) Reserved field and its ones complement (2 tests);
172 * e) Flags field and its ones complement (2 tests);
173 * f) CRC field is equal to zero (1 test); (DON'T DO THIS TEST!)
174 * g) SOF fields and ones complement fields (4 tests);
175 * h) Format and values of FC header (1 test);
176 * i) CRC of FC Frame (2 tests);
177 * j) FC Frame Encapsulation header information in the next iFCP Frame
178 * (1 test).
180 * At least 3 of the 16 tests listed above SHALL be performed. Failure
181 * of any of the above tests actually performed SHALL indicate an
182 * encapsulation error and the FC Frame SHALL NOT be forwarded on to
183 * the FC Entity.
188 * Tests a, b and c
190 if(tvb_memeql(tvb, offset, ifcp_header_4_bytes, 4) != 0){
191 return false;
194 /* check the frame length */
195 flen=tvb_get_ntohs(tvb, offset+12)&0x03FF;
196 if((flen < 15) || (flen > 545)){
197 return false;
200 /* check the complement of the frame length */
201 flen1=tvb_get_ntohs(tvb, offset+14)&0x03FF;
202 if(flen!=((~flen1)&0x03FF)){
203 return false;
207 /* this should be good enough for our heuristics */
208 return true;
212 #define IFCP_FLAGS_SES 0x04
213 #define IFCP_FLAGS_TRP 0x02
214 #define IFCP_FLAGS_SPC 0x01
216 static const true_false_string ifcp_flags_ses_tfs = {
217 "This is a SESSION CONTROL FRAME",
218 "This is a normal frame"
221 static const true_false_string ifcp_flags_trp_tfs = {
222 "Address TRANSPARENT Mode Enabled",
223 "Address TRANSLATION Mode Enabled"
226 static const true_false_string ifcp_flags_spc_tfs = {
227 "This frame requires SPECIAL PROCESSING",
228 "This is a normal frame"
231 static int
232 dissect_ifcpflags(tvbuff_t *tvb, int offset, proto_tree *parent_tree)
234 static int * const flags[] = {
235 &hf_ifcp_flags_ses,
236 &hf_ifcp_flags_trp,
237 &hf_ifcp_flags_spc,
238 NULL
240 proto_tree_add_bitmask(parent_tree, tvb, offset, hf_ifcp_flags,
241 ett_ifcp_flags, flags, ENC_BIG_ENDIAN);
243 offset++;
244 return offset;
248 #define IFCP_COMMON_FLAGS_CRCV 0x04
250 static void
251 dissect_commonflags(tvbuff_t *tvb, int offset, proto_tree *parent_tree)
253 static int * const flags[] = {
254 &hf_ifcp_common_flags_crcv,
255 NULL
258 proto_tree_add_bitmask(parent_tree, tvb, offset, hf_ifcp_common_flags,
259 ett_ifcp_common_flags, flags, ENC_BIG_ENDIAN);
262 static int
263 dissect_ifcp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void* data _U_)
265 int offset = 0, frame_len = 0;
266 uint8_t sof = 0, eof = 0;
267 proto_item *ti;
268 proto_tree *tree = NULL;
269 tvbuff_t *next_tvb;
270 uint8_t protocol;
271 proto_tree *protocol_tree = NULL;
272 proto_tree *version_tree = NULL;
273 proto_tree *frame_len_tree = NULL;
274 proto_tree *sof_tree = NULL;
275 proto_tree *eof_tree = NULL;
276 fc_data_t fc_data;
278 /* verify we have a full header (do we need to do this? */
279 if(tvb_captured_length(tvb)<iFCP_ENCAP_HEADER_LEN){
280 return 0;
283 col_set_str(pinfo->cinfo, COL_PROTOCOL, "iFCP");
285 frame_len = (tvb_get_ntohs (tvb, offset+12) & 0x03FF)*4;
288 if (parent_tree) {
289 if (tvb_bytes_exist (tvb, offset, frame_len-4)) {
290 sof = tvb_get_uint8 (tvb, offset+iFCP_ENCAP_HEADER_LEN);
291 eof = tvb_get_uint8 (tvb, offset+frame_len - 4);
293 ti = proto_tree_add_protocol_format (parent_tree, proto_ifcp, tvb, offset,
294 iFCP_ENCAP_HEADER_LEN,
295 "iFCP (%s/%s)",
296 val_to_str (sof, ifcp_sof_vals,
297 "0x%x"),
298 val_to_str (eof, ifcp_eof_vals,
299 "0x%x"));
300 } else {
301 sof = tvb_get_uint8 (tvb, offset+iFCP_ENCAP_HEADER_LEN);
303 ti = proto_tree_add_protocol_format (parent_tree, proto_ifcp, tvb, offset,
304 iFCP_ENCAP_HEADER_LEN,
305 "iFCP (%s/%s)",
306 val_to_str (sof, ifcp_sof_vals,
307 "0x%x"),
308 "NA");
310 tree = proto_item_add_subtree (ti, ett_ifcp);
315 /* The Common FC Encap header */
316 /* protocol */
317 protocol = tvb_get_uint8 (tvb, offset);
318 ti=proto_tree_add_item(tree, hf_ifcp_protocol, tvb, offset, 1, ENC_BIG_ENDIAN);
319 protocol_tree=proto_item_add_subtree(ti, ett_ifcp_protocol);
321 offset++;
323 /* version */
324 ti=proto_tree_add_item(tree, hf_ifcp_version, tvb, offset, 1, ENC_BIG_ENDIAN);
325 version_tree=proto_item_add_subtree(ti, ett_ifcp_version);
326 offset++;
328 /* protocol complement */
329 proto_tree_add_item(protocol_tree, hf_ifcp_protocol_c, tvb, offset, 1, ENC_BIG_ENDIAN);
330 offset++;
332 /* version complement */
333 proto_tree_add_item(version_tree, hf_ifcp_version_c, tvb, offset, 1, ENC_BIG_ENDIAN);
334 offset++;
336 /* 4 reserved bytes */
337 offset+=4;
339 /* iFCP specific fields */
340 if(protocol==FCENCAP_PROTO_iFCP){
341 /* LS_COMMAND_ACC */
342 proto_tree_add_item(tree, hf_ifcp_ls_command_acc, tvb, offset, 1, ENC_BIG_ENDIAN);
343 offset++;
345 /* iFCP Flags */
346 offset=dissect_ifcpflags(tvb, offset, tree);
348 /* SOF */
349 ti=proto_tree_add_item(tree, hf_ifcp_sof, tvb, offset, 1, ENC_BIG_ENDIAN);
350 sof_tree=proto_item_add_subtree(ti, ett_ifcp_sof);
351 offset++;
353 /* EOF */
354 ti=proto_tree_add_item(tree, hf_ifcp_eof, tvb, offset, 1, ENC_BIG_ENDIAN);
355 eof_tree=proto_item_add_subtree(ti, ett_ifcp_eof);
356 offset++;
357 } else {
358 offset+=4;
359 sof_tree=tree; /* better than nothing */
360 eof_tree=tree;
363 /* Common Flags */
364 dissect_commonflags(tvb, offset, tree);
366 /* frame len */
367 ti=proto_tree_add_item(tree, hf_ifcp_framelen, tvb, offset, 2, ENC_BIG_ENDIAN);
368 frame_len_tree=proto_item_add_subtree(ti, ett_ifcp_frame_len);
369 offset+=2;
371 /* complement of flags and frame len */
372 proto_tree_add_item(frame_len_tree, hf_ifcp_encap_flags_c, tvb, offset, 1, ENC_BIG_ENDIAN);
373 proto_tree_add_item(frame_len_tree, hf_ifcp_framelen_c, tvb, offset, 2, ENC_BIG_ENDIAN);
374 offset+=2;
376 /* timestamp seconds */
377 proto_tree_add_item(tree, hf_ifcp_tsec, tvb, offset, 4, ENC_BIG_ENDIAN);
378 offset+=4;
380 /* timestamp fractions */
381 proto_tree_add_item(tree, hf_ifcp_tusec, tvb, offset, 4, ENC_BIG_ENDIAN);
382 offset+=4;
384 /* crc */
385 proto_tree_add_item(tree, hf_ifcp_encap_crc, tvb, offset, 4, ENC_BIG_ENDIAN);
386 offset+=4;
389 /* FC SOF/-SOF */
390 proto_tree_add_item(sof_tree, hf_ifcp_sof, tvb, offset, 1, ENC_BIG_ENDIAN);
391 offset++;
392 proto_tree_add_item(sof_tree, hf_ifcp_sof, tvb, offset, 1, ENC_BIG_ENDIAN);
393 offset++;
394 proto_tree_add_item(sof_tree, hf_ifcp_sof_c, tvb, offset, 1, ENC_BIG_ENDIAN);
395 offset++;
396 proto_tree_add_item(sof_tree, hf_ifcp_sof_c, tvb, offset, 1, ENC_BIG_ENDIAN);
397 offset++;
399 /* FC EOF/-EOF */
400 if(tvb_bytes_exist(tvb, frame_len-4, 4)) {
401 proto_tree_add_item(eof_tree, hf_ifcp_eof, tvb, frame_len-4, 1, ENC_BIG_ENDIAN);
402 proto_tree_add_item(eof_tree, hf_ifcp_eof, tvb, frame_len-3, 1, ENC_BIG_ENDIAN);
403 proto_tree_add_item(eof_tree, hf_ifcp_eof_c, tvb, frame_len-2, 1, ENC_BIG_ENDIAN);
404 proto_tree_add_item(eof_tree, hf_ifcp_eof_c, tvb, frame_len-1, 1, ENC_BIG_ENDIAN);
408 /* Call the FC Dissector if this is carrying an FC frame */
409 /* Set the SOF/EOF flags in the packet_info header */
410 fc_data.sof_eof = 0;
412 switch(sof){
413 case iFCP_SOFi3:
414 case iFCP_SOFi2:
415 case iFCP_SOFi4:
416 fc_data.sof_eof = FC_DATA_SOF_FIRST_FRAME;
417 break;
418 case iFCP_SOFf:
419 fc_data.sof_eof = FC_DATA_SOF_SOFF;
420 break;
421 default:
422 if(sof){
423 if (eof != iFCP_EOFn) {
424 fc_data.sof_eof |= FC_DATA_EOF_LAST_FRAME;
425 } else if (eof != iFCP_EOFt) {
426 fc_data.sof_eof |= FC_DATA_EOF_INVALID;
431 next_tvb=tvb_new_subset_length(tvb, offset, frame_len-offset-4);
432 fc_data.ethertype = ETHERTYPE_UNK;
434 if(fc_handle){
435 call_dissector_with_data(fc_handle, next_tvb, pinfo, parent_tree, &fc_data);
436 } else {
437 call_data_dissector(next_tvb, pinfo, parent_tree);
440 return tvb_captured_length(tvb);
443 static unsigned
444 get_ifcp_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_)
446 unsigned pdu_len;
448 if(!ifcp_header_test(tvb, offset)){
449 return 0;
452 pdu_len=(tvb_get_ntohs(tvb, offset+12)&0x03FF)*4;
453 return pdu_len;
456 static int
457 dissect_ifcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void* data)
459 tcp_dissect_pdus(tvb, pinfo, parent_tree, ifcp_desegment, iFCP_MIN_HEADER_LEN, get_ifcp_pdu_len, dissect_ifcp_pdu, data);
460 return tvb_captured_length(tvb);
464 /* This is called for those sessions where we have explicitly said
465 * this to be iFCP using "Decode As..."
466 * In this case we will not check the port number for sanity and just
467 * do as the user said.
469 static int
470 dissect_ifcp_handle(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
472 return dissect_ifcp(tvb, pinfo, tree, data);
475 static bool
476 dissect_ifcp_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
478 if(!ifcp_header_test(tvb, 0)){
479 return false;
482 dissect_ifcp(tvb, pinfo, tree, data);
484 /* our heuristics are so strong that if the heuristics above passed
485 * and the dissection of the pdu did not cause any exceptions
486 * then we can set this as our conversation dissector
488 if(ifcp_handle){
489 conversation_t* ifcp_conv;
491 ifcp_conv=find_or_create_conversation(pinfo);
492 /* XXX why does this not work? it doesn't result in dissect_ifcp_handle being called look into later*/
493 conversation_set_dissector(ifcp_conv, ifcp_handle);
496 return true;
499 void
500 proto_register_ifcp (void)
502 /* Setup list of header fields See Section 1.6.1 for details*/
503 static hf_register_info hf[] = {
504 { &hf_ifcp_protocol,
505 {"Protocol", "ifcp.encap.proto", FT_UINT8, BASE_DEC, VALS(fcencap_proto_vals), 0,
506 NULL, HFILL }},
507 { &hf_ifcp_protocol_c,
508 {"Protocol (1's Complement)", "ifcp.encap.protoc", FT_UINT8, BASE_DEC, NULL, 0,
509 NULL, HFILL}},
510 { &hf_ifcp_version,
511 {"Version", "ifcp.encap.version", FT_UINT8, BASE_DEC, NULL, 0,
512 NULL, HFILL}},
513 { &hf_ifcp_version_c,
514 {"Version (1's Complement)", "ifcp.encap.versionc", FT_UINT8, BASE_DEC, NULL, 0,
515 NULL, HFILL}},
516 { &hf_ifcp_encap_flags_c,
517 {"iFCP Encapsulation Flags (1's Complement)", "ifcp.encap_flagsc", FT_UINT8, BASE_HEX, NULL, 0xFC,
518 NULL, HFILL}},
519 { &hf_ifcp_framelen,
520 {"Frame Length (in Words)", "ifcp.encap.framelen", FT_UINT16, BASE_DEC, NULL, 0x03FF,
521 NULL, HFILL}},
522 { &hf_ifcp_framelen_c,
523 {"Frame Length (1's Complement)", "ifcp.encap.framelenc", FT_UINT16, BASE_DEC, NULL, 0x03FF,
524 NULL, HFILL}},
525 { &hf_ifcp_tsec,
526 {"Time (secs)", "ifcp.encap.tsec", FT_UINT32, BASE_DEC, NULL, 0,
527 NULL, HFILL}},
528 { &hf_ifcp_tusec,
529 {"Time (fraction)", "ifcp.encap.tusec", FT_UINT32, BASE_DEC, NULL, 0,
530 NULL, HFILL}},
531 { &hf_ifcp_encap_crc,
532 {"CRC", "ifcp.encap.crc", FT_UINT32, BASE_HEX, NULL, 0,
533 NULL, HFILL}},
534 { &hf_ifcp_sof,
535 {"SOF", "ifcp.sof", FT_UINT8, BASE_HEX, VALS (ifcp_sof_vals), 0,
536 NULL, HFILL}},
537 { &hf_ifcp_eof,
538 {"EOF", "ifcp.eof", FT_UINT8, BASE_HEX, VALS (ifcp_eof_vals), 0,
539 NULL, HFILL}},
540 { &hf_ifcp_sof_c,
541 {"SOF Compliment", "ifcp.sof_c", FT_UINT8, BASE_HEX, NULL , 0,
542 NULL, HFILL}},
543 { &hf_ifcp_eof_c,
544 {"EOF Compliment", "ifcp.eof_c", FT_UINT8, BASE_HEX, NULL , 0,
545 NULL, HFILL}},
546 { &hf_ifcp_ls_command_acc,
547 {"Ls Command Acc", "ifcp.ls_command_acc", FT_UINT8, BASE_HEX, NULL, 0,
548 NULL, HFILL}},
549 { &hf_ifcp_common_flags,
550 {"Flags", "ifcp.common_flags", FT_UINT8, BASE_HEX , NULL, 0xfc,
551 NULL, HFILL }},
552 { &hf_ifcp_common_flags_crcv,
553 {"CRC", "ifcp.common_flags.crcv", FT_BOOLEAN, 8, TFS(&tfs_valid_not_valid), IFCP_COMMON_FLAGS_CRCV,
554 "Is the CRC field valid?", HFILL }},
555 { &hf_ifcp_flags,
556 {"iFCP Flags", "ifcp.flags", FT_UINT8, BASE_HEX , NULL, 0,
557 NULL, HFILL }},
558 { &hf_ifcp_flags_ses,
559 {"SES", "ifcp.flags.ses", FT_BOOLEAN, 8, TFS(&ifcp_flags_ses_tfs), IFCP_FLAGS_SES,
560 "Is this a Session control frame", HFILL }},
561 { &hf_ifcp_flags_trp,
562 {"TRP", "ifcp.flags.trp", FT_BOOLEAN, 8, TFS(&ifcp_flags_trp_tfs), IFCP_FLAGS_TRP,
563 "Is address transparent mode enabled", HFILL }},
564 { &hf_ifcp_flags_spc,
565 {"SPC", "ifcp.flags.spc", FT_BOOLEAN, 8, TFS(&ifcp_flags_spc_tfs), IFCP_FLAGS_SPC,
566 "Is frame part of link service", HFILL }},
569 static int *ett[] = {
570 &ett_ifcp,
571 &ett_ifcp_sof,
572 &ett_ifcp_eof,
573 &ett_ifcp_protocol,
574 &ett_ifcp_version,
575 &ett_ifcp_frame_len,
576 &ett_ifcp_flags,
577 &ett_ifcp_common_flags,
580 module_t *ifcp_module;
582 /* Register the protocol name and description */
583 proto_ifcp = proto_register_protocol("iFCP", "iFCP", "ifcp");
585 proto_register_field_array(proto_ifcp, hf, array_length(hf));
586 proto_register_subtree_array(ett, array_length(ett));
588 ifcp_module = prefs_register_protocol(proto_ifcp, NULL);
589 prefs_register_bool_preference(ifcp_module,
590 "desegment",
591 "Reassemble iFCP messages spanning multiple TCP segments",
592 "Whether the iFCP dissector should reassemble messages spanning multiple TCP segments."
593 " To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
594 &ifcp_desegment);
595 prefs_register_obsolete_preference(ifcp_module, "target_port");
597 ifcp_handle = register_dissector("ifcp", dissect_ifcp_handle, proto_ifcp);
600 void
601 proto_reg_handoff_ifcp (void)
603 heur_dissector_add("tcp", dissect_ifcp_heur, "iFCP over TCP", "ifcp_tcp", proto_ifcp, HEURISTIC_ENABLE);
605 dissector_add_for_decode_as_with_preference("tcp.port", ifcp_handle);
607 fc_handle = find_dissector_add_dependency("fc_ifcp", proto_ifcp);
611 * Editor modelines - https://www.wireshark.org/tools/modelines.html
613 * Local variables:
614 * c-basic-offset: 4
615 * tab-width: 8
616 * indent-tabs-mode: nil
617 * End:
619 * vi: set shiftwidth=4 tabstop=8 expandtab:
620 * :indentSize=4:tabSize=8:noTabs=true: