/src/wireshark/epan/dissectors/packet-ifcp.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* packet-ifcp.c |
2 | | * Routines for iFCP dissection |
3 | | * RFC 3821, RFC 3643 |
4 | | * |
5 | | * Copyright 2005 Aboo Valappil (valappil_aboo@emc.com) |
6 | | * 2006 ronnie sahlberg major refactoring |
7 | | * |
8 | | * |
9 | | * Significantly based on packet-fcip.c by |
10 | | * Copyright 2001, Dinesh G Dutt (ddutt@cisco.com) |
11 | | * |
12 | | * Wireshark - Network traffic analyzer |
13 | | * By Gerald Combs <gerald@wireshark.org> |
14 | | * Copyright 1998 Gerald Combs |
15 | | * |
16 | | * SPDX-License-Identifier: GPL-2.0-or-later |
17 | | */ |
18 | | |
19 | | #include "config.h" |
20 | | |
21 | | #include <epan/packet.h> |
22 | | #include <epan/prefs.h> |
23 | | #include <epan/tfs.h> |
24 | | #include <wsutil/array.h> |
25 | | |
26 | | #include "packet-tcp.h" |
27 | | #include "packet-fc.h" |
28 | | |
29 | | void proto_register_ifcp(void); |
30 | | void proto_reg_handoff_ifcp(void); |
31 | | |
32 | 0 | #define iFCP_ENCAP_HEADER_LEN 28 |
33 | 2.73k | #define iFCP_MIN_HEADER_LEN 16 /* up to frame len field */ |
34 | | |
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; |
45 | | |
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; |
56 | | |
57 | | typedef enum { |
58 | | FCENCAP_PROTO_FCIP = 1, |
59 | | FCENCAP_PROTO_iFCP = 2 |
60 | | } fcencap_proto_t; |
61 | | |
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}, |
72 | | }; |
73 | | |
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}, |
84 | | }; |
85 | | |
86 | | static const value_string fcencap_proto_vals[] = { |
87 | | {FCENCAP_PROTO_FCIP, "FCIP"}, |
88 | | {FCENCAP_PROTO_iFCP, "iFCP"}, |
89 | | {0, NULL}, |
90 | | }; |
91 | | |
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. |
95 | | */ |
96 | | static const uint8_t ifcp_header_4_bytes[4] = { |
97 | | 0x02, 0x01, 0xFD, 0xFE |
98 | | }; |
99 | | |
100 | | static int proto_ifcp; |
101 | | |
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; |
123 | | |
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; |
132 | | |
133 | | static bool ifcp_desegment = true; |
134 | | |
135 | | static dissector_handle_t ifcp_handle; |
136 | | static dissector_handle_t fc_handle; |
137 | | |
138 | | |
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. |
141 | | */ |
142 | | static bool |
143 | | ifcp_header_test(tvbuff_t *tvb, int offset) |
144 | 2.73k | { |
145 | 2.73k | uint16_t flen, flen1; |
146 | | |
147 | | /* we can only do this test if we have 16 bytes or more */ |
148 | 2.73k | if(tvb_captured_length_remaining(tvb, offset)<iFCP_MIN_HEADER_LEN){ |
149 | 763 | return false; |
150 | 763 | } |
151 | | |
152 | | /* |
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. |
164 | | * |
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). |
179 | | * |
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. |
184 | | */ |
185 | | |
186 | | |
187 | | /* |
188 | | * Tests a, b and c |
189 | | */ |
190 | 1.97k | if(tvb_memeql(tvb, offset, ifcp_header_4_bytes, 4) != 0){ |
191 | 1.96k | return false; |
192 | 1.96k | } |
193 | | |
194 | | /* check the frame length */ |
195 | 7 | flen=tvb_get_ntohs(tvb, offset+12)&0x03FF; |
196 | 7 | if((flen < 15) || (flen > 545)){ |
197 | 4 | return false; |
198 | 4 | } |
199 | | |
200 | | /* check the complement of the frame length */ |
201 | 3 | flen1=tvb_get_ntohs(tvb, offset+14)&0x03FF; |
202 | 3 | if(flen!=((~flen1)&0x03FF)){ |
203 | 3 | return false; |
204 | 3 | } |
205 | | |
206 | | |
207 | | /* this should be good enough for our heuristics */ |
208 | 0 | return true; |
209 | 3 | } |
210 | | |
211 | | |
212 | 14 | #define IFCP_FLAGS_SES 0x04 |
213 | 14 | #define IFCP_FLAGS_TRP 0x02 |
214 | 14 | #define IFCP_FLAGS_SPC 0x01 |
215 | | |
216 | | static const true_false_string ifcp_flags_ses_tfs = { |
217 | | "This is a SESSION CONTROL FRAME", |
218 | | "This is a normal frame" |
219 | | }; |
220 | | |
221 | | static const true_false_string ifcp_flags_trp_tfs = { |
222 | | "Address TRANSPARENT Mode Enabled", |
223 | | "Address TRANSLATION Mode Enabled" |
224 | | }; |
225 | | |
226 | | static const true_false_string ifcp_flags_spc_tfs = { |
227 | | "This frame requires SPECIAL PROCESSING", |
228 | | "This is a normal frame" |
229 | | }; |
230 | | |
231 | | static int |
232 | | dissect_ifcpflags(tvbuff_t *tvb, int offset, proto_tree *parent_tree) |
233 | 0 | { |
234 | 0 | static int * const flags[] = { |
235 | 0 | &hf_ifcp_flags_ses, |
236 | 0 | &hf_ifcp_flags_trp, |
237 | 0 | &hf_ifcp_flags_spc, |
238 | 0 | NULL |
239 | 0 | }; |
240 | 0 | proto_tree_add_bitmask(parent_tree, tvb, offset, hf_ifcp_flags, |
241 | 0 | ett_ifcp_flags, flags, ENC_BIG_ENDIAN); |
242 | |
|
243 | 0 | offset++; |
244 | 0 | return offset; |
245 | 0 | } |
246 | | |
247 | | |
248 | 14 | #define IFCP_COMMON_FLAGS_CRCV 0x04 |
249 | | |
250 | | static void |
251 | | dissect_commonflags(tvbuff_t *tvb, int offset, proto_tree *parent_tree) |
252 | 0 | { |
253 | 0 | static int * const flags[] = { |
254 | 0 | &hf_ifcp_common_flags_crcv, |
255 | 0 | NULL |
256 | 0 | }; |
257 | |
|
258 | 0 | proto_tree_add_bitmask(parent_tree, tvb, offset, hf_ifcp_common_flags, |
259 | 0 | ett_ifcp_common_flags, flags, ENC_BIG_ENDIAN); |
260 | 0 | } |
261 | | |
262 | | static int |
263 | | dissect_ifcp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void* data _U_) |
264 | 0 | { |
265 | 0 | int offset = 0, frame_len = 0; |
266 | 0 | uint8_t sof = 0, eof = 0; |
267 | 0 | proto_item *ti; |
268 | 0 | proto_tree *tree = NULL; |
269 | 0 | tvbuff_t *next_tvb; |
270 | 0 | uint8_t protocol; |
271 | 0 | proto_tree *protocol_tree = NULL; |
272 | 0 | proto_tree *version_tree = NULL; |
273 | 0 | proto_tree *frame_len_tree = NULL; |
274 | 0 | proto_tree *sof_tree = NULL; |
275 | 0 | proto_tree *eof_tree = NULL; |
276 | 0 | fc_data_t fc_data; |
277 | | |
278 | | /* verify we have a full header (do we need to do this? */ |
279 | 0 | if(tvb_captured_length(tvb)<iFCP_ENCAP_HEADER_LEN){ |
280 | 0 | return 0; |
281 | 0 | } |
282 | | |
283 | 0 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "iFCP"); |
284 | |
|
285 | 0 | frame_len = (tvb_get_ntohs (tvb, offset+12) & 0x03FF)*4; |
286 | | |
287 | |
|
288 | 0 | if (parent_tree) { |
289 | 0 | if (tvb_bytes_exist (tvb, offset, frame_len-4)) { |
290 | 0 | sof = tvb_get_uint8 (tvb, offset+iFCP_ENCAP_HEADER_LEN); |
291 | 0 | eof = tvb_get_uint8 (tvb, offset+frame_len - 4); |
292 | |
|
293 | 0 | ti = proto_tree_add_protocol_format (parent_tree, proto_ifcp, tvb, offset, |
294 | 0 | iFCP_ENCAP_HEADER_LEN, |
295 | 0 | "iFCP (%s/%s)", |
296 | 0 | val_to_str (sof, ifcp_sof_vals, |
297 | 0 | "0x%x"), |
298 | 0 | val_to_str (eof, ifcp_eof_vals, |
299 | 0 | "0x%x")); |
300 | 0 | } else { |
301 | 0 | sof = tvb_get_uint8 (tvb, offset+iFCP_ENCAP_HEADER_LEN); |
302 | |
|
303 | 0 | ti = proto_tree_add_protocol_format (parent_tree, proto_ifcp, tvb, offset, |
304 | 0 | iFCP_ENCAP_HEADER_LEN, |
305 | 0 | "iFCP (%s/%s)", |
306 | 0 | val_to_str (sof, ifcp_sof_vals, |
307 | 0 | "0x%x"), |
308 | 0 | "NA"); |
309 | 0 | } |
310 | 0 | tree = proto_item_add_subtree (ti, ett_ifcp); |
311 | 0 | } |
312 | | |
313 | | |
314 | | |
315 | | /* The Common FC Encap header */ |
316 | | /* protocol */ |
317 | 0 | protocol = tvb_get_uint8 (tvb, offset); |
318 | 0 | ti=proto_tree_add_item(tree, hf_ifcp_protocol, tvb, offset, 1, ENC_BIG_ENDIAN); |
319 | 0 | protocol_tree=proto_item_add_subtree(ti, ett_ifcp_protocol); |
320 | |
|
321 | 0 | offset++; |
322 | | |
323 | | /* version */ |
324 | 0 | ti=proto_tree_add_item(tree, hf_ifcp_version, tvb, offset, 1, ENC_BIG_ENDIAN); |
325 | 0 | version_tree=proto_item_add_subtree(ti, ett_ifcp_version); |
326 | 0 | offset++; |
327 | | |
328 | | /* protocol complement */ |
329 | 0 | proto_tree_add_item(protocol_tree, hf_ifcp_protocol_c, tvb, offset, 1, ENC_BIG_ENDIAN); |
330 | 0 | offset++; |
331 | | |
332 | | /* version complement */ |
333 | 0 | proto_tree_add_item(version_tree, hf_ifcp_version_c, tvb, offset, 1, ENC_BIG_ENDIAN); |
334 | 0 | offset++; |
335 | | |
336 | | /* 4 reserved bytes */ |
337 | 0 | offset+=4; |
338 | | |
339 | | /* iFCP specific fields */ |
340 | 0 | if(protocol==FCENCAP_PROTO_iFCP){ |
341 | | /* LS_COMMAND_ACC */ |
342 | 0 | proto_tree_add_item(tree, hf_ifcp_ls_command_acc, tvb, offset, 1, ENC_BIG_ENDIAN); |
343 | 0 | offset++; |
344 | | |
345 | | /* iFCP Flags */ |
346 | 0 | offset=dissect_ifcpflags(tvb, offset, tree); |
347 | | |
348 | | /* SOF */ |
349 | 0 | ti=proto_tree_add_item(tree, hf_ifcp_sof, tvb, offset, 1, ENC_BIG_ENDIAN); |
350 | 0 | sof_tree=proto_item_add_subtree(ti, ett_ifcp_sof); |
351 | 0 | offset++; |
352 | | |
353 | | /* EOF */ |
354 | 0 | ti=proto_tree_add_item(tree, hf_ifcp_eof, tvb, offset, 1, ENC_BIG_ENDIAN); |
355 | 0 | eof_tree=proto_item_add_subtree(ti, ett_ifcp_eof); |
356 | 0 | offset++; |
357 | 0 | } else { |
358 | 0 | offset+=4; |
359 | 0 | sof_tree=tree; /* better than nothing */ |
360 | 0 | eof_tree=tree; |
361 | 0 | } |
362 | | |
363 | | /* Common Flags */ |
364 | 0 | dissect_commonflags(tvb, offset, tree); |
365 | | |
366 | | /* frame len */ |
367 | 0 | ti=proto_tree_add_item(tree, hf_ifcp_framelen, tvb, offset, 2, ENC_BIG_ENDIAN); |
368 | 0 | frame_len_tree=proto_item_add_subtree(ti, ett_ifcp_frame_len); |
369 | 0 | offset+=2; |
370 | | |
371 | | /* complement of flags and frame len */ |
372 | 0 | proto_tree_add_item(frame_len_tree, hf_ifcp_encap_flags_c, tvb, offset, 1, ENC_BIG_ENDIAN); |
373 | 0 | proto_tree_add_item(frame_len_tree, hf_ifcp_framelen_c, tvb, offset, 2, ENC_BIG_ENDIAN); |
374 | 0 | offset+=2; |
375 | | |
376 | | /* timestamp seconds */ |
377 | 0 | proto_tree_add_item(tree, hf_ifcp_tsec, tvb, offset, 4, ENC_BIG_ENDIAN); |
378 | 0 | offset+=4; |
379 | | |
380 | | /* timestamp fractions */ |
381 | 0 | proto_tree_add_item(tree, hf_ifcp_tusec, tvb, offset, 4, ENC_BIG_ENDIAN); |
382 | 0 | offset+=4; |
383 | | |
384 | | /* crc */ |
385 | 0 | proto_tree_add_item(tree, hf_ifcp_encap_crc, tvb, offset, 4, ENC_BIG_ENDIAN); |
386 | 0 | offset+=4; |
387 | | |
388 | | |
389 | | /* FC SOF/-SOF */ |
390 | 0 | proto_tree_add_item(sof_tree, hf_ifcp_sof, tvb, offset, 1, ENC_BIG_ENDIAN); |
391 | 0 | offset++; |
392 | 0 | proto_tree_add_item(sof_tree, hf_ifcp_sof, tvb, offset, 1, ENC_BIG_ENDIAN); |
393 | 0 | offset++; |
394 | 0 | proto_tree_add_item(sof_tree, hf_ifcp_sof_c, tvb, offset, 1, ENC_BIG_ENDIAN); |
395 | 0 | offset++; |
396 | 0 | proto_tree_add_item(sof_tree, hf_ifcp_sof_c, tvb, offset, 1, ENC_BIG_ENDIAN); |
397 | 0 | offset++; |
398 | | |
399 | | /* FC EOF/-EOF */ |
400 | 0 | if(tvb_bytes_exist(tvb, frame_len-4, 4)) { |
401 | 0 | proto_tree_add_item(eof_tree, hf_ifcp_eof, tvb, frame_len-4, 1, ENC_BIG_ENDIAN); |
402 | 0 | proto_tree_add_item(eof_tree, hf_ifcp_eof, tvb, frame_len-3, 1, ENC_BIG_ENDIAN); |
403 | 0 | proto_tree_add_item(eof_tree, hf_ifcp_eof_c, tvb, frame_len-2, 1, ENC_BIG_ENDIAN); |
404 | 0 | proto_tree_add_item(eof_tree, hf_ifcp_eof_c, tvb, frame_len-1, 1, ENC_BIG_ENDIAN); |
405 | 0 | } |
406 | | |
407 | | |
408 | | /* Call the FC Dissector if this is carrying an FC frame */ |
409 | | /* Set the SOF/EOF flags in the packet_info header */ |
410 | 0 | fc_data.sof_eof = 0; |
411 | |
|
412 | 0 | switch(sof){ |
413 | 0 | case iFCP_SOFi3: |
414 | 0 | case iFCP_SOFi2: |
415 | 0 | case iFCP_SOFi4: |
416 | 0 | fc_data.sof_eof = FC_DATA_SOF_FIRST_FRAME; |
417 | 0 | break; |
418 | 0 | case iFCP_SOFf: |
419 | 0 | fc_data.sof_eof = FC_DATA_SOF_SOFF; |
420 | 0 | break; |
421 | 0 | default: |
422 | 0 | if(sof){ |
423 | 0 | if (eof != iFCP_EOFn) { |
424 | 0 | fc_data.sof_eof |= FC_DATA_EOF_LAST_FRAME; |
425 | 0 | } else if (eof != iFCP_EOFt) { |
426 | 0 | fc_data.sof_eof |= FC_DATA_EOF_INVALID; |
427 | 0 | } |
428 | 0 | } |
429 | 0 | } |
430 | | |
431 | 0 | next_tvb=tvb_new_subset_length(tvb, offset, frame_len-offset-4); |
432 | 0 | fc_data.ethertype = ETHERTYPE_UNK; |
433 | |
|
434 | 0 | if(fc_handle){ |
435 | 0 | call_dissector_with_data(fc_handle, next_tvb, pinfo, parent_tree, &fc_data); |
436 | 0 | } else { |
437 | 0 | call_data_dissector(next_tvb, pinfo, parent_tree); |
438 | 0 | } |
439 | |
|
440 | 0 | return tvb_captured_length(tvb); |
441 | 0 | } |
442 | | |
443 | | static unsigned |
444 | | get_ifcp_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_) |
445 | 0 | { |
446 | 0 | unsigned pdu_len; |
447 | |
|
448 | 0 | if(!ifcp_header_test(tvb, offset)){ |
449 | 0 | return 0; |
450 | 0 | } |
451 | | |
452 | 0 | pdu_len=(tvb_get_ntohs(tvb, offset+12)&0x03FF)*4; |
453 | 0 | return pdu_len; |
454 | 0 | } |
455 | | |
456 | | static int |
457 | | dissect_ifcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void* data) |
458 | 0 | { |
459 | 0 | tcp_dissect_pdus(tvb, pinfo, parent_tree, ifcp_desegment, iFCP_MIN_HEADER_LEN, get_ifcp_pdu_len, dissect_ifcp_pdu, data); |
460 | 0 | return tvb_captured_length(tvb); |
461 | 0 | } |
462 | | |
463 | | |
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. |
468 | | */ |
469 | | static int |
470 | | dissect_ifcp_handle(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data) |
471 | 0 | { |
472 | 0 | return dissect_ifcp(tvb, pinfo, tree, data); |
473 | 0 | } |
474 | | |
475 | | static bool |
476 | | dissect_ifcp_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) |
477 | 2.73k | { |
478 | 2.73k | if(!ifcp_header_test(tvb, 0)){ |
479 | 2.73k | return false; |
480 | 2.73k | } |
481 | | |
482 | 0 | dissect_ifcp(tvb, pinfo, tree, data); |
483 | | |
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 |
487 | | */ |
488 | 0 | if(ifcp_handle){ |
489 | 0 | conversation_t* ifcp_conv; |
490 | |
|
491 | 0 | 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 | 0 | conversation_set_dissector(ifcp_conv, ifcp_handle); |
494 | 0 | } |
495 | |
|
496 | 0 | return true; |
497 | 2.73k | } |
498 | | |
499 | | void |
500 | | proto_register_ifcp (void) |
501 | 14 | { |
502 | | /* Setup list of header fields See Section 1.6.1 for details*/ |
503 | 14 | static hf_register_info hf[] = { |
504 | 14 | { &hf_ifcp_protocol, |
505 | 14 | {"Protocol", "ifcp.encap.proto", FT_UINT8, BASE_DEC, VALS(fcencap_proto_vals), 0, |
506 | 14 | NULL, HFILL }}, |
507 | 14 | { &hf_ifcp_protocol_c, |
508 | 14 | {"Protocol (1's Complement)", "ifcp.encap.protoc", FT_UINT8, BASE_DEC, NULL, 0, |
509 | 14 | NULL, HFILL}}, |
510 | 14 | { &hf_ifcp_version, |
511 | 14 | {"Version", "ifcp.encap.version", FT_UINT8, BASE_DEC, NULL, 0, |
512 | 14 | NULL, HFILL}}, |
513 | 14 | { &hf_ifcp_version_c, |
514 | 14 | {"Version (1's Complement)", "ifcp.encap.versionc", FT_UINT8, BASE_DEC, NULL, 0, |
515 | 14 | NULL, HFILL}}, |
516 | 14 | { &hf_ifcp_encap_flags_c, |
517 | 14 | {"iFCP Encapsulation Flags (1's Complement)", "ifcp.encap_flagsc", FT_UINT8, BASE_HEX, NULL, 0xFC, |
518 | 14 | NULL, HFILL}}, |
519 | 14 | { &hf_ifcp_framelen, |
520 | 14 | {"Frame Length (in Words)", "ifcp.encap.framelen", FT_UINT16, BASE_DEC, NULL, 0x03FF, |
521 | 14 | NULL, HFILL}}, |
522 | 14 | { &hf_ifcp_framelen_c, |
523 | 14 | {"Frame Length (1's Complement)", "ifcp.encap.framelenc", FT_UINT16, BASE_DEC, NULL, 0x03FF, |
524 | 14 | NULL, HFILL}}, |
525 | 14 | { &hf_ifcp_tsec, |
526 | 14 | {"Time (secs)", "ifcp.encap.tsec", FT_UINT32, BASE_DEC, NULL, 0, |
527 | 14 | NULL, HFILL}}, |
528 | 14 | { &hf_ifcp_tusec, |
529 | 14 | {"Time (fraction)", "ifcp.encap.tusec", FT_UINT32, BASE_DEC, NULL, 0, |
530 | 14 | NULL, HFILL}}, |
531 | 14 | { &hf_ifcp_encap_crc, |
532 | 14 | {"CRC", "ifcp.encap.crc", FT_UINT32, BASE_HEX, NULL, 0, |
533 | 14 | NULL, HFILL}}, |
534 | 14 | { &hf_ifcp_sof, |
535 | 14 | {"SOF", "ifcp.sof", FT_UINT8, BASE_HEX, VALS (ifcp_sof_vals), 0, |
536 | 14 | NULL, HFILL}}, |
537 | 14 | { &hf_ifcp_eof, |
538 | 14 | {"EOF", "ifcp.eof", FT_UINT8, BASE_HEX, VALS (ifcp_eof_vals), 0, |
539 | 14 | NULL, HFILL}}, |
540 | 14 | { &hf_ifcp_sof_c, |
541 | 14 | {"SOF Compliment", "ifcp.sof_c", FT_UINT8, BASE_HEX, NULL , 0, |
542 | 14 | NULL, HFILL}}, |
543 | 14 | { &hf_ifcp_eof_c, |
544 | 14 | {"EOF Compliment", "ifcp.eof_c", FT_UINT8, BASE_HEX, NULL , 0, |
545 | 14 | NULL, HFILL}}, |
546 | 14 | { &hf_ifcp_ls_command_acc, |
547 | 14 | {"Ls Command Acc", "ifcp.ls_command_acc", FT_UINT8, BASE_HEX, NULL, 0, |
548 | 14 | NULL, HFILL}}, |
549 | 14 | { &hf_ifcp_common_flags, |
550 | 14 | {"Flags", "ifcp.common_flags", FT_UINT8, BASE_HEX , NULL, 0xfc, |
551 | 14 | NULL, HFILL }}, |
552 | 14 | { &hf_ifcp_common_flags_crcv, |
553 | 14 | {"CRC", "ifcp.common_flags.crcv", FT_BOOLEAN, 8, TFS(&tfs_valid_not_valid), IFCP_COMMON_FLAGS_CRCV, |
554 | 14 | "Is the CRC field valid?", HFILL }}, |
555 | 14 | { &hf_ifcp_flags, |
556 | 14 | {"iFCP Flags", "ifcp.flags", FT_UINT8, BASE_HEX , NULL, 0, |
557 | 14 | NULL, HFILL }}, |
558 | 14 | { &hf_ifcp_flags_ses, |
559 | 14 | {"SES", "ifcp.flags.ses", FT_BOOLEAN, 8, TFS(&ifcp_flags_ses_tfs), IFCP_FLAGS_SES, |
560 | 14 | "Is this a Session control frame", HFILL }}, |
561 | 14 | { &hf_ifcp_flags_trp, |
562 | 14 | {"TRP", "ifcp.flags.trp", FT_BOOLEAN, 8, TFS(&ifcp_flags_trp_tfs), IFCP_FLAGS_TRP, |
563 | 14 | "Is address transparent mode enabled", HFILL }}, |
564 | 14 | { &hf_ifcp_flags_spc, |
565 | 14 | {"SPC", "ifcp.flags.spc", FT_BOOLEAN, 8, TFS(&ifcp_flags_spc_tfs), IFCP_FLAGS_SPC, |
566 | 14 | "Is frame part of link service", HFILL }}, |
567 | 14 | }; |
568 | | |
569 | 14 | static int *ett[] = { |
570 | 14 | &ett_ifcp, |
571 | 14 | &ett_ifcp_sof, |
572 | 14 | &ett_ifcp_eof, |
573 | 14 | &ett_ifcp_protocol, |
574 | 14 | &ett_ifcp_version, |
575 | 14 | &ett_ifcp_frame_len, |
576 | 14 | &ett_ifcp_flags, |
577 | 14 | &ett_ifcp_common_flags, |
578 | 14 | }; |
579 | | |
580 | 14 | module_t *ifcp_module; |
581 | | |
582 | | /* Register the protocol name and description */ |
583 | 14 | proto_ifcp = proto_register_protocol("iFCP", "iFCP", "ifcp"); |
584 | | |
585 | 14 | proto_register_field_array(proto_ifcp, hf, array_length(hf)); |
586 | 14 | proto_register_subtree_array(ett, array_length(ett)); |
587 | | |
588 | 14 | ifcp_module = prefs_register_protocol(proto_ifcp, NULL); |
589 | 14 | prefs_register_bool_preference(ifcp_module, |
590 | 14 | "desegment", |
591 | 14 | "Reassemble iFCP messages spanning multiple TCP segments", |
592 | 14 | "Whether the iFCP dissector should reassemble messages spanning multiple TCP segments." |
593 | 14 | " To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.", |
594 | 14 | &ifcp_desegment); |
595 | 14 | prefs_register_obsolete_preference(ifcp_module, "target_port"); |
596 | | |
597 | 14 | ifcp_handle = register_dissector("ifcp", dissect_ifcp_handle, proto_ifcp); |
598 | 14 | } |
599 | | |
600 | | void |
601 | | proto_reg_handoff_ifcp (void) |
602 | 14 | { |
603 | 14 | heur_dissector_add("tcp", dissect_ifcp_heur, "iFCP over TCP", "ifcp_tcp", proto_ifcp, HEURISTIC_ENABLE); |
604 | | |
605 | 14 | dissector_add_for_decode_as_with_preference("tcp.port", ifcp_handle); |
606 | | |
607 | 14 | fc_handle = find_dissector_add_dependency("fc_ifcp", proto_ifcp); |
608 | 14 | } |
609 | | |
610 | | /* |
611 | | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
612 | | * |
613 | | * Local variables: |
614 | | * c-basic-offset: 4 |
615 | | * tab-width: 8 |
616 | | * indent-tabs-mode: nil |
617 | | * End: |
618 | | * |
619 | | * vi: set shiftwidth=4 tabstop=8 expandtab: |
620 | | * :indentSize=4:tabSize=8:noTabs=true: |
621 | | */ |