| File: | epan/dissectors/packet-cpfi.c |
| Warning: | line 317, column 3 Value stored to 'length' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /* packet-cpfi.c |
| 2 | * Routines for CPFI Cross Point Frame Injector dissection |
| 3 | * CPFI - Cross Point Frame Injector is a CNT proprietary |
| 4 | * protocol used to carry Fibre Channel data over UDP |
| 5 | * |
| 6 | * Copyright 2003, Dave Sclarsky <dave_sclarsky[AT]cnt.com> |
| 7 | * |
| 8 | * Wireshark - Network traffic analyzer |
| 9 | * By Gerald Combs <gerald@wireshark.org> |
| 10 | * Copyright 1998 Gerald Combs |
| 11 | * |
| 12 | * Copied from packet-m2tp.c |
| 13 | * Thanks to Heinz Prantner for his motivation and assistance |
| 14 | * |
| 15 | * SPDX-License-Identifier: GPL-2.0-or-later |
| 16 | */ |
| 17 | |
| 18 | #include "config.h" |
| 19 | |
| 20 | #include <epan/packet.h> |
| 21 | #include <epan/prefs.h> |
| 22 | #include "packet-fc.h" |
| 23 | |
| 24 | void proto_register_cpfi(void); |
| 25 | void proto_reg_handoff_cpfi(void); |
| 26 | |
| 27 | #define CPFI_DEFAULT_UDP_PORT5000 5000 /* Not IANA registered */ |
| 28 | #define CPFI_DEFAULT_TTOT_UDP_PORT5001 5001 /* Not IANA registered */ |
| 29 | |
| 30 | #define FIRST_TIO_CARD_ADDRESS0x380 0x380 |
| 31 | |
| 32 | |
| 33 | /* SOF defines */ |
| 34 | #define CPFI_FRAME_TYPE_MASK0xF0000000 0xF0000000 |
| 35 | #define CPFI_FRAME_TYPE_SHIFT28 28 |
| 36 | #define CPFI_SOURCE_MASK0x0FFC0000 0x0FFC0000 |
| 37 | #define CPFI_SOURCE_SHIFT18 18 |
| 38 | #define CPFI_DEST_MASK0x0003FF00 0x0003FF00 |
| 39 | #define CPFI_DEST_SHIFT8 8 |
| 40 | #define CPFI_SOF_TYPE_MASK0x000000F0 0x000000F0 |
| 41 | #define CPFI_SPEED_MASK0x0000000C 0x0000000C |
| 42 | #define CPFI_OPM_ERROR_MASK0x00000002 0x00000002 |
| 43 | #define CPFI_FROM_LCM_MASK0x00000001 0x00000001 |
| 44 | |
| 45 | /* EOF defines */ |
| 46 | #define CPFI_EOF_TYPE_MASK0x78000000 0x78000000 |
| 47 | #define CPFI_EOF_ERROR_MASK0x7FE00000 0x7FE00000 |
| 48 | |
| 49 | /* configurable parameters */ |
| 50 | static unsigned gbl_cpfi_ttot_udp_port = CPFI_DEFAULT_TTOT_UDP_PORT5001; |
| 51 | static bool_Bool cpfi_arrow_moves = true1; |
| 52 | |
| 53 | /* Initialize the protocol and registered fields */ |
| 54 | static int proto_cpfi; |
| 55 | static int hf_cpfi_word_one; |
| 56 | static int hf_cpfi_word_two; |
| 57 | /* SOF word 1: */ |
| 58 | static int hf_cpfi_frame_type; |
| 59 | static int hf_cpfi_source; |
| 60 | static int hf_cpfi_dest; |
| 61 | static int hf_cpfi_SOF_type; |
| 62 | static int hf_cpfi_speed; |
| 63 | static int hf_cpfi_OPM_error; |
| 64 | static int hf_cpfi_from_LCM; |
| 65 | /* EOF */ |
| 66 | static int hf_cpfi_CRC_32; |
| 67 | static int hf_cpfi_EOF_type; |
| 68 | /* Hidden items */ |
| 69 | static int hf_cpfi_t_instance; |
| 70 | static int hf_cpfi_t_src_instance; |
| 71 | static int hf_cpfi_t_dst_instance; |
| 72 | static int hf_cpfi_t_board; |
| 73 | static int hf_cpfi_t_src_board; |
| 74 | static int hf_cpfi_t_dst_board; |
| 75 | static int hf_cpfi_t_port; |
| 76 | static int hf_cpfi_t_src_port; |
| 77 | static int hf_cpfi_t_dst_port; |
| 78 | |
| 79 | static char src_str[20]; |
| 80 | static char dst_str[20]; |
| 81 | static const char l_to_r_arrow[] = "-->"; |
| 82 | static const char r_to_l_arrow[] = "<--"; |
| 83 | static const char *left = src_str; |
| 84 | static const char *right = dst_str; |
| 85 | static const char *arrow = l_to_r_arrow; |
| 86 | static const char direction_and_port_string[] = "[%s %s %s] "; |
| 87 | |
| 88 | |
| 89 | /* Initialize the subtree pointers */ |
| 90 | static int ett_cpfi; |
| 91 | static int ett_cpfi_header; |
| 92 | static int ett_cpfi_footer; |
| 93 | |
| 94 | static dissector_handle_t cpfi_handle; |
| 95 | static dissector_handle_t fc_handle; |
| 96 | |
| 97 | |
| 98 | static const value_string sof_type_vals[] = { |
| 99 | {0, "SOFf"}, |
| 100 | {1, "SOFi2"}, |
| 101 | {2, "SOFn2"}, |
| 102 | {3, "SOFi3"}, |
| 103 | {4, "SOFn3"}, |
| 104 | {5, "SOFc1"}, |
| 105 | {6, "SOFi1"}, |
| 106 | {7, "SOFn1"}, |
| 107 | {8, "SOFc4"}, |
| 108 | {9, "SOFi4"}, |
| 109 | {10, "SOFn4"}, |
| 110 | {0, NULL((void*)0)}, |
| 111 | }; |
| 112 | |
| 113 | static const value_string speed_vals[] = { |
| 114 | {0, "1 GBIT"}, |
| 115 | {1, "2 GBIT"}, |
| 116 | {2, "4 GBIT"}, |
| 117 | {3, "10 GBIT"}, |
| 118 | {0, NULL((void*)0)}, |
| 119 | }; |
| 120 | |
| 121 | static const value_string eof_type_vals[] = { |
| 122 | {0, "EOFn"}, |
| 123 | {1, "EOFt"}, |
| 124 | {2, "EOFni"}, |
| 125 | {3, "EOFa"}, |
| 126 | {4, "EOFdt"}, |
| 127 | {5, "EOFdti"}, |
| 128 | {6, "EOFrt"}, |
| 129 | {7, "EOFrti"}, |
| 130 | {0, NULL((void*)0)}, |
| 131 | }; |
| 132 | |
| 133 | /* Header */ |
| 134 | static void |
| 135 | dissect_cpfi_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) |
| 136 | { |
| 137 | uint32_t word1; |
| 138 | #if 0 |
| 139 | uint32_t word2; |
| 140 | #endif |
| 141 | uint32_t tda; |
| 142 | uint32_t src; |
| 143 | uint8_t src_instance = 0; |
| 144 | uint8_t src_board = 0; |
| 145 | uint8_t src_port = 0; |
| 146 | uint32_t dst; |
| 147 | uint8_t dst_instance = 0; |
| 148 | uint8_t dst_board = 0; |
| 149 | uint8_t dst_port = 0; |
| 150 | proto_tree *extra_tree = NULL((void*)0); |
| 151 | |
| 152 | /* add a tree for the header */ |
| 153 | if ( tree != NULL((void*)0)) |
| 154 | { |
| 155 | proto_item *extra_item; |
| 156 | extra_item = proto_tree_add_protocol_format(tree, proto_cpfi, tvb, 0, -1, "Header"); |
| 157 | extra_tree = proto_item_add_subtree(extra_item, ett_cpfi_header); |
| 158 | } |
| 159 | |
| 160 | /* Extract the common header, and get the bits we need */ |
| 161 | word1 = tvb_get_ntohl (tvb, 0); |
| 162 | #if 0 |
| 163 | word2 = tvb_get_ntohl (tvb, sizeof(word1)); |
| 164 | #endif |
| 165 | |
| 166 | /* Figure out where the frame came from. dstTDA is source of frame! */ |
| 167 | tda = (word1 & CPFI_DEST_MASK0x0003FF00) >> CPFI_DEST_SHIFT8; |
| 168 | if ( tda >= FIRST_TIO_CARD_ADDRESS0x380 ) |
| 169 | { |
| 170 | (void) g_strlcpy(src_str, " CPFI", sizeof(src_str)); |
| 171 | src = 0; /* Make it smallest */ |
| 172 | } |
| 173 | else |
| 174 | { |
| 175 | const uint8_t *srcmac; |
| 176 | |
| 177 | /* Make sure this is an Ethernet address. */ |
| 178 | DISSECTOR_ASSERT(pinfo->src.type == AT_ETHER)((void) ((pinfo->src.type == AT_ETHER) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/dissectors/packet-cpfi.c" , 178, "pinfo->src.type == AT_ETHER")))); |
| 179 | srcmac = (const uint8_t *)pinfo->src.data; |
| 180 | |
| 181 | src_instance = srcmac[2]-1; |
| 182 | src_board = tda >> 4; |
| 183 | src_port = tda & 0x0f; |
| 184 | src = (1 << 24) + (src_instance << 16) + (src_board << 8) + src_port; |
| 185 | snprintf(src_str, sizeof(src_str), "%u.%u.%u", src_instance, src_board, src_port); |
| 186 | } |
| 187 | |
| 188 | /* Figure out where the frame is going. srcTDA is destination of frame! */ |
| 189 | tda = (word1 & CPFI_SOURCE_MASK0x0FFC0000) >> CPFI_SOURCE_SHIFT18; |
| 190 | if ( tda >= FIRST_TIO_CARD_ADDRESS0x380 ) |
| 191 | { |
| 192 | (void) g_strlcpy(dst_str, " CPFI", sizeof(dst_str)); |
| 193 | dst = 0; /* Make it smallest */ |
| 194 | } |
| 195 | else |
| 196 | { |
| 197 | const uint8_t *dstmac; |
| 198 | |
| 199 | /* Make sure this is an Ethernet address. */ |
| 200 | DISSECTOR_ASSERT(pinfo->dst.type == AT_ETHER)((void) ((pinfo->dst.type == AT_ETHER) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/dissectors/packet-cpfi.c" , 200, "pinfo->dst.type == AT_ETHER")))); |
| 201 | dstmac = (const uint8_t *)pinfo->dst.data; |
| 202 | |
| 203 | dst_instance = dstmac[2]-1; |
| 204 | dst_board = tda >> 4; |
| 205 | dst_port = tda & 0x0f; |
| 206 | dst = (1 << 24) + (dst_instance << 16) + (dst_board << 8) + dst_port; |
| 207 | snprintf(dst_str, sizeof(dst_str), "%u.%u.%u", dst_instance, dst_board, dst_port); |
| 208 | } |
| 209 | |
| 210 | /* Set up the source and destination and arrow per user configuration. */ |
| 211 | if ( cpfi_arrow_moves && (dst < src) ) |
| 212 | { |
| 213 | left = dst_str; |
| 214 | arrow = r_to_l_arrow; |
| 215 | right = src_str; |
| 216 | } |
| 217 | else |
| 218 | { |
| 219 | left = src_str; |
| 220 | arrow = l_to_r_arrow; |
| 221 | right = dst_str; |
| 222 | } |
| 223 | |
| 224 | if (extra_tree) { |
| 225 | proto_item *hidden_item; |
| 226 | /* For "real" TDAs (i.e. not for microTDAs), add hidden addresses to allow filtering */ |
| 227 | if ( src != 0 ) |
| 228 | { |
| 229 | hidden_item = proto_tree_add_bytes(extra_tree, hf_cpfi_t_instance, tvb, 0, 1, &src_instance); |
| 230 | proto_item_set_hidden(hidden_item); |
| 231 | hidden_item = proto_tree_add_bytes(extra_tree, hf_cpfi_t_src_instance, tvb, 0, 1, &src_instance); |
| 232 | proto_item_set_hidden(hidden_item); |
| 233 | hidden_item = proto_tree_add_bytes(extra_tree, hf_cpfi_t_board, tvb, 0, 1, &src_board); |
| 234 | proto_item_set_hidden(hidden_item); |
| 235 | hidden_item = proto_tree_add_bytes(extra_tree, hf_cpfi_t_src_board, tvb, 0, 1, &src_board); |
| 236 | proto_item_set_hidden(hidden_item); |
| 237 | hidden_item = proto_tree_add_bytes(extra_tree, hf_cpfi_t_port, tvb, 0, 1, &src_port); |
| 238 | proto_item_set_hidden(hidden_item); |
| 239 | hidden_item = proto_tree_add_bytes(extra_tree, hf_cpfi_t_src_port, tvb, 0, 1, &src_port); |
| 240 | proto_item_set_hidden(hidden_item); |
| 241 | } |
| 242 | if ( dst != 0 ) |
| 243 | { |
| 244 | hidden_item = proto_tree_add_bytes(extra_tree, hf_cpfi_t_instance, tvb, 0, 1, &dst_instance); |
| 245 | proto_item_set_hidden(hidden_item); |
| 246 | hidden_item = proto_tree_add_bytes(extra_tree, hf_cpfi_t_dst_instance, tvb, 0, 1, &dst_instance); |
| 247 | proto_item_set_hidden(hidden_item); |
| 248 | hidden_item = proto_tree_add_bytes(extra_tree, hf_cpfi_t_board, tvb, 0, 1, &dst_board); |
| 249 | proto_item_set_hidden(hidden_item); |
| 250 | hidden_item = proto_tree_add_bytes(extra_tree, hf_cpfi_t_dst_board, tvb, 0, 1, &dst_board); |
| 251 | proto_item_set_hidden(hidden_item); |
| 252 | hidden_item = proto_tree_add_bytes(extra_tree, hf_cpfi_t_port, tvb, 0, 1, &dst_port); |
| 253 | proto_item_set_hidden(hidden_item); |
| 254 | hidden_item = proto_tree_add_bytes(extra_tree, hf_cpfi_t_dst_port, tvb, 0, 1, &dst_port); |
| 255 | proto_item_set_hidden(hidden_item); |
| 256 | } |
| 257 | |
| 258 | /* add word 1 components to the protocol tree */ |
| 259 | proto_tree_add_item(extra_tree, hf_cpfi_word_one , tvb, 0, 4, ENC_BIG_ENDIAN0x00000000); |
| 260 | |
| 261 | proto_tree_add_item(extra_tree, hf_cpfi_frame_type, tvb, 0, 4, ENC_BIG_ENDIAN0x00000000); |
| 262 | proto_tree_add_item(extra_tree, hf_cpfi_source , tvb, 0, 4, ENC_BIG_ENDIAN0x00000000); |
| 263 | proto_tree_add_item(extra_tree, hf_cpfi_dest , tvb, 0, 4, ENC_BIG_ENDIAN0x00000000); |
| 264 | proto_tree_add_item(extra_tree, hf_cpfi_SOF_type , tvb, 0, 4, ENC_BIG_ENDIAN0x00000000); |
| 265 | proto_tree_add_item(extra_tree, hf_cpfi_speed , tvb, 0, 4, ENC_BIG_ENDIAN0x00000000); |
| 266 | proto_tree_add_item(extra_tree, hf_cpfi_OPM_error , tvb, 0, 4, ENC_BIG_ENDIAN0x00000000); |
| 267 | proto_tree_add_item(extra_tree, hf_cpfi_from_LCM , tvb, 0, 4, ENC_BIG_ENDIAN0x00000000); |
| 268 | |
| 269 | /* add word 2 components to the protocol tree */ |
| 270 | proto_tree_add_item(extra_tree, hf_cpfi_word_two , tvb, 4, 4, ENC_BIG_ENDIAN0x00000000); |
| 271 | }; |
| 272 | } |
| 273 | |
| 274 | /* Footer */ |
| 275 | static void |
| 276 | dissect_cpfi_footer(tvbuff_t *tvb, proto_tree *tree) |
| 277 | { |
| 278 | proto_tree *extra_tree = NULL((void*)0); |
| 279 | |
| 280 | /* add a tree for the footer */ |
| 281 | if ( tree != NULL((void*)0)) |
| 282 | { |
| 283 | proto_item *extra_item; |
| 284 | extra_item = proto_tree_add_protocol_format(tree, proto_cpfi, tvb, 0, -1, "Footer"); |
| 285 | extra_tree = proto_item_add_subtree(extra_item, ett_cpfi_footer); |
| 286 | } |
| 287 | |
| 288 | if (extra_tree) { |
| 289 | proto_tree_add_item(extra_tree, hf_cpfi_CRC_32 , tvb, 0, 4, ENC_BIG_ENDIAN0x00000000); |
| 290 | proto_tree_add_item(extra_tree, hf_cpfi_EOF_type, tvb, 4, 4, ENC_BIG_ENDIAN0x00000000); |
| 291 | } |
| 292 | } |
| 293 | |
| 294 | /* CPFI */ |
| 295 | static int |
| 296 | dissect_cpfi(tvbuff_t *message_tvb, packet_info *pinfo, proto_tree *tree, void *data _U___attribute__((unused))) |
| 297 | { |
| 298 | tvbuff_t *header_tvb, *body_tvb, *footer_tvb; |
| 299 | proto_item *cpfi_item = NULL((void*)0); |
| 300 | proto_tree *cpfi_tree = NULL((void*)0); |
| 301 | int length, reported_length, reported_body_length; |
| 302 | uint8_t frame_type; |
| 303 | fc_data_t fc_data; |
| 304 | |
| 305 | frame_type = (tvb_get_ntohl (message_tvb, 0) & CPFI_FRAME_TYPE_MASK0xF0000000) >> CPFI_FRAME_TYPE_SHIFT28; |
| 306 | |
| 307 | /* If this is not a CPFI frame, return 0 to let another dissector try to |
| 308 | * dissect it. |
| 309 | */ |
| 310 | if ( !((frame_type == 9) && fc_handle) ) |
| 311 | return 0; |
| 312 | |
| 313 | /* If we don't have Ethernet addresses, can't do further dissection... */ |
| 314 | if (pinfo->dst.type != AT_ETHER || pinfo->src.type != AT_ETHER) |
| 315 | return 0; |
| 316 | |
| 317 | length = tvb_captured_length_remaining(message_tvb, 8); |
Value stored to 'length' is never read | |
| 318 | reported_length = tvb_reported_length_remaining(message_tvb, 8); |
| 319 | if (reported_length < 8) |
| 320 | { |
| 321 | /* We don't even have enough for the footer. */ |
| 322 | return 0; |
| 323 | } |
| 324 | |
| 325 | /* Length of packet, minus the footer. */ |
| 326 | reported_body_length = reported_length - 8; |
| 327 | /* How much of that do we have in the tvbuff? */ |
| 328 | length = tvb_captured_length_remaining(message_tvb, 8 + reported_body_length); |
| 329 | if (length < 0) |
| 330 | { |
| 331 | /* The footer wasn't captured at all. |
| 332 | XXX - we'd like to throw a BoundsError if that's the case. */ |
| 333 | return 0; |
| 334 | } |
| 335 | |
| 336 | /* In the interest of speed, if "tree" is NULL, don't do any work not |
| 337 | necessary to generate protocol tree items. */ |
| 338 | if (tree) { |
| 339 | /* create the protocol tree */ |
| 340 | cpfi_item = proto_tree_add_item(tree, proto_cpfi, message_tvb, 0, -1, ENC_NA0x00000000); |
| 341 | cpfi_tree = proto_item_add_subtree(cpfi_item, ett_cpfi); |
| 342 | } |
| 343 | |
| 344 | /* Set up the frame controls - can we do better than this? */ |
| 345 | fc_data.sof_eof = 0; |
| 346 | fc_data.sof_eof |= FC_DATA_SOF_FIRST_FRAME0x1; |
| 347 | fc_data.sof_eof |= FC_DATA_EOF_LAST_FRAME0x80; |
| 348 | fc_data.sof_eof |= FC_DATA_EOF_INVALID0x40; |
| 349 | |
| 350 | /* dissect the message */ |
| 351 | |
| 352 | /* extract and process the header */ |
| 353 | header_tvb = tvb_new_subset_length(message_tvb, 0, 8); |
| 354 | dissect_cpfi_header(header_tvb, pinfo, cpfi_tree); |
| 355 | |
| 356 | body_tvb = tvb_new_subset_length(message_tvb, 8, reported_body_length); |
| 357 | fc_data.ethertype = ETHERTYPE_UNK0x0000; |
| 358 | call_dissector_with_data(fc_handle, body_tvb, pinfo, tree, &fc_data); |
| 359 | |
| 360 | /* add more info, now that FC added its */ |
| 361 | proto_item_append_text(cpfi_item, direction_and_port_string, left, arrow, right); |
| 362 | col_prepend_fstr(pinfo->cinfo, COL_INFO, direction_and_port_string, left, arrow, right); |
| 363 | |
| 364 | /* Do the footer */ |
| 365 | footer_tvb = tvb_new_subset_length(message_tvb, 8 + reported_body_length, 8); |
| 366 | dissect_cpfi_footer(footer_tvb, cpfi_tree); |
| 367 | |
| 368 | return tvb_reported_length(message_tvb); |
| 369 | } |
| 370 | |
| 371 | /* Register the protocol with Wireshark */ |
| 372 | void |
| 373 | proto_register_cpfi(void) |
| 374 | { |
| 375 | module_t *cpfi_module; |
| 376 | |
| 377 | /* Setup list of header fields */ |
| 378 | static hf_register_info hf[] = { |
| 379 | |
| 380 | { &hf_cpfi_word_one, |
| 381 | { "Word one", "cpfi.word_one", |
| 382 | FT_UINT32, BASE_HEX, NULL((void*)0), 0x0, |
| 383 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}}, |
| 384 | { &hf_cpfi_word_two, |
| 385 | { "Word two", "cpfi.word_two", |
| 386 | FT_UINT32, BASE_HEX, NULL((void*)0), 0x0, |
| 387 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}}, |
| 388 | |
| 389 | { &hf_cpfi_frame_type, |
| 390 | { "FrmType", "cpfi.frmtype", |
| 391 | FT_UINT32, BASE_HEX, NULL((void*)0), CPFI_FRAME_TYPE_MASK0xF0000000, |
| 392 | "Frame Type", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}}, |
| 393 | { &hf_cpfi_source, |
| 394 | { "srcTDA", "cpfi.srcTDA", |
| 395 | FT_UINT32, BASE_HEX, NULL((void*)0), CPFI_SOURCE_MASK0x0FFC0000, |
| 396 | "Source TDA (10 bits)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}}, |
| 397 | { &hf_cpfi_dest, |
| 398 | { "dstTDA", "cpfi.dstTDA", |
| 399 | FT_UINT32, BASE_HEX, NULL((void*)0), CPFI_DEST_MASK0x0003FF00, |
| 400 | "Source TDA (10 bits)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}}, |
| 401 | { &hf_cpfi_SOF_type, |
| 402 | { "SOFtype", "cpfi.SOFtype", |
| 403 | FT_UINT32, BASE_HEX, VALS(sof_type_vals)((0 ? (const struct _value_string*)0 : ((sof_type_vals)))), CPFI_SOF_TYPE_MASK0x000000F0, |
| 404 | "SOF Type", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}}, |
| 405 | { &hf_cpfi_speed, |
| 406 | { "speed", "cpfi.speed", |
| 407 | FT_UINT32, BASE_HEX, VALS(speed_vals)((0 ? (const struct _value_string*)0 : ((speed_vals)))), CPFI_SPEED_MASK0x0000000C, |
| 408 | "SOF Type", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}}, |
| 409 | { &hf_cpfi_OPM_error, |
| 410 | { "OPMerror", "cpfi.OPMerror", |
| 411 | FT_BOOLEAN, 32, NULL((void*)0), CPFI_OPM_ERROR_MASK0x00000002, |
| 412 | "OPM Error?", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}}, |
| 413 | { &hf_cpfi_from_LCM, |
| 414 | { "fromLCM", "cpfi.fromLCM", |
| 415 | FT_BOOLEAN, 32, NULL((void*)0), CPFI_FROM_LCM_MASK0x00000001, |
| 416 | "from LCM?", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}}, |
| 417 | |
| 418 | { &hf_cpfi_CRC_32, |
| 419 | { "CRC-32", "cpfi.crc-32", |
| 420 | FT_UINT32, BASE_HEX, NULL((void*)0), 0x0, |
| 421 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}}, |
| 422 | |
| 423 | { &hf_cpfi_EOF_type, |
| 424 | { "EOFtype", "cpfi.EOFtype", |
| 425 | FT_UINT32, BASE_HEX, VALS(eof_type_vals)((0 ? (const struct _value_string*)0 : ((eof_type_vals)))), CPFI_EOF_TYPE_MASK0x78000000, |
| 426 | "EOF Type", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}}, |
| 427 | |
| 428 | { &hf_cpfi_t_instance, |
| 429 | { "Instance", "cpfi.instance", |
| 430 | FT_BYTES, BASE_NONE, |
| 431 | NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}}, |
| 432 | |
| 433 | { &hf_cpfi_t_src_instance, |
| 434 | { "Source Instance", "cpfi.src_instance", |
| 435 | FT_BYTES, BASE_NONE, |
| 436 | NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}}, |
| 437 | |
| 438 | { &hf_cpfi_t_dst_instance, |
| 439 | { "Destination Instance", "cpfi.dst_instance", |
| 440 | FT_BYTES, BASE_NONE, |
| 441 | NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}}, |
| 442 | |
| 443 | { &hf_cpfi_t_board, |
| 444 | { "Board", "cpfi.board", |
| 445 | FT_BYTES, BASE_NONE, |
| 446 | NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}}, |
| 447 | |
| 448 | { &hf_cpfi_t_src_board, |
| 449 | { "Source Board", "cpfi.src_board", |
| 450 | FT_BYTES, BASE_NONE, |
| 451 | NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}}, |
| 452 | |
| 453 | { &hf_cpfi_t_dst_board, |
| 454 | { "Destination Board", "cpfi.dst_board", |
| 455 | FT_BYTES, BASE_NONE, |
| 456 | NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}}, |
| 457 | |
| 458 | { &hf_cpfi_t_port, |
| 459 | { "Port", "cpfi.port", |
| 460 | FT_BYTES, BASE_NONE, |
| 461 | NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}}, |
| 462 | |
| 463 | { &hf_cpfi_t_src_port, |
| 464 | { "Source Port", "cpfi.src_port", |
| 465 | FT_BYTES, BASE_NONE, |
| 466 | NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}}, |
| 467 | |
| 468 | { &hf_cpfi_t_dst_port, |
| 469 | { "Destination Port", "cpfi.dst_port", |
| 470 | FT_BYTES, BASE_NONE, |
| 471 | NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}}, |
| 472 | }; |
| 473 | |
| 474 | |
| 475 | /* Setup protocol subtree array */ |
| 476 | static int *ett[] = { |
| 477 | &ett_cpfi, |
| 478 | &ett_cpfi_header, |
| 479 | &ett_cpfi_footer |
| 480 | }; |
| 481 | |
| 482 | |
| 483 | /* Register the protocol name and description */ |
| 484 | proto_cpfi = proto_register_protocol("Cross Point Frame Injector", "CPFI", "cpfi"); |
| 485 | |
| 486 | /* Required function calls to register the header fields and subtrees used */ |
| 487 | proto_register_field_array(proto_cpfi, hf, array_length(hf)(sizeof (hf) / sizeof (hf)[0])); |
| 488 | proto_register_subtree_array(ett, array_length(ett)(sizeof (ett) / sizeof (ett)[0])); |
| 489 | |
| 490 | /* Register our configuration options for CPFI */ |
| 491 | cpfi_module = prefs_register_protocol(proto_cpfi, proto_reg_handoff_cpfi); |
| 492 | prefs_register_uint_preference(cpfi_module, "udp.port2", "InstanceToInstance UDP Port", |
| 493 | "Set the port for InstanceToInstance messages (if other" |
| 494 | " than the default of 5001)", |
| 495 | 10, &gbl_cpfi_ttot_udp_port); |
| 496 | prefs_register_bool_preference(cpfi_module, "arrow_ctl", |
| 497 | "Enable Active Arrow Control", |
| 498 | "Control the way the '-->' is displayed." |
| 499 | " When enabled, keeps the 'lowest valued' endpoint of the src-dest pair" |
| 500 | " on the left, and the arrow moves to distinguish source from dest." |
| 501 | " When disabled, keeps the arrow pointing right so the source of the frame" |
| 502 | " is always on the left.", |
| 503 | &cpfi_arrow_moves); |
| 504 | |
| 505 | cpfi_handle = register_dissector("cpfi", dissect_cpfi, proto_cpfi); |
| 506 | } |
| 507 | |
| 508 | void |
| 509 | proto_reg_handoff_cpfi(void) |
| 510 | { |
| 511 | static bool_Bool cpfi_init_complete = false0; |
| 512 | static unsigned cpfi_ttot_udp_port; |
| 513 | |
| 514 | if ( !cpfi_init_complete ) |
| 515 | { |
| 516 | fc_handle = find_dissector_add_dependency("fc", proto_cpfi); |
| 517 | dissector_add_uint_with_preference("udp.port", CPFI_DEFAULT_UDP_PORT5000, cpfi_handle); |
| 518 | cpfi_init_complete = true1; |
| 519 | } |
| 520 | else |
| 521 | { |
| 522 | dissector_delete_uint("udp.port", cpfi_ttot_udp_port, cpfi_handle); |
| 523 | } |
| 524 | |
| 525 | cpfi_ttot_udp_port = gbl_cpfi_ttot_udp_port; |
| 526 | |
| 527 | /* Port preference has a specific enough name to not use |
| 528 | the "auto" preference */ |
| 529 | dissector_add_uint("udp.port", cpfi_ttot_udp_port, cpfi_handle); |
| 530 | } |
| 531 | |
| 532 | /* |
| 533 | * Editor modelines |
| 534 | * |
| 535 | * Local Variables: |
| 536 | * c-basic-offset: 2 |
| 537 | * tab-width: 8 |
| 538 | * indent-tabs-mode: nil |
| 539 | * End: |
| 540 | * |
| 541 | * ex: set shiftwidth=2 tabstop=8 expandtab: |
| 542 | * :indentSize=2:tabSize=8:noTabs=true: |
| 543 | */ |