static void dissect_fcfcs_gapnl (tvbuff_t *tvb, proto_tree *tree, gboolean isreq) { int offset = 16; /* past the fcct header */ int numelem, i; if (tree) { if (isreq) { proto_tree_add_string (tree, hf_fcs_portname, tvb, offset, 8, tvb_fcwwn_to_str (tvb, offset)); } else { numelem = tvb_get_ntohl (tvb, offset); proto_tree_add_text (tree, tvb, offset, 4, "Number of Attached Port Entries: %d", numelem); offset += 4; for (i = 0; i < numelem; i++) { proto_tree_add_string (tree, hf_fcs_portname, tvb, offset, 8, tvb_fcwwn_to_str (tvb, offset)); proto_tree_add_item (tree, hf_fcs_portflags, tvb, offset+10, 1, ENC_BIG_ENDIAN); proto_tree_add_item (tree, hf_fcs_porttype, tvb, offset+11, 1, ENC_BIG_ENDIAN); offset += 12; } } } }
static void dissect_ipfc (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { /* Set up structures needed to add the protocol subtree and manage it */ proto_item *ti; proto_tree *ipfc_tree; int offset = 0; tvbuff_t *next_tvb; /* Make entries in Protocol column and Info column on summary display */ col_set_str(pinfo->cinfo, COL_PROTOCOL, "IP/FC"); if (tree) { ti = proto_tree_add_protocol_format (tree, proto_ipfc, tvb, offset, 16, "IP Over FC Network_Header"); ipfc_tree = proto_item_add_subtree (ti, ett_ipfc); proto_tree_add_string (ipfc_tree, hf_ipfc_network_da, tvb, offset, 8, tvb_fcwwn_to_str (tvb, offset)); proto_tree_add_string (ipfc_tree, hf_ipfc_network_sa, tvb, offset+8, 8, tvb_fcwwn_to_str (tvb, offset+8)); } next_tvb = tvb_new_subset_remaining (tvb, 16); call_dissector(llc_handle, next_tvb, pinfo, tree); }
static void dissect_fcfcs_gplnl (tvbuff_t *tvb, proto_tree *tree, gboolean isreq) { int offset = 16; /* past the fcct header */ int numelem, i, len; if (tree) { if (isreq) { len = tvb_get_guint8 (tvb, offset); proto_tree_add_text (tree, tvb, offset, 1, "Platform Name Length: %d", len); proto_tree_add_item (tree, hf_fcs_platformname, tvb, offset+1, len, ENC_NA); } else { numelem = tvb_get_ntohl (tvb, offset); proto_tree_add_text (tree, tvb, offset, 4, "Number of Platform Node Name Entries: %d", numelem); offset += 4; for (i = 0; i < numelem; i++) { proto_tree_add_string (tree, hf_fcs_platformnname, tvb, offset, 8, tvb_fcwwn_to_str (tvb, offset)); offset += 8; } } } }
static void dissect_fcfcs_gmal (tvbuff_t *tvb, proto_tree *tree, gboolean isreq) { int offset = 16; /* past the fcct header */ int numelem, i; if (tree) { if (isreq) { proto_tree_add_string (tree, hf_fcs_iename, tvb, offset, 8, tvb_fcwwn_to_str (tvb, offset)); } else { numelem = tvb_get_ntohl (tvb, offset); proto_tree_add_text (tree, tvb, offset, 4, "Number of Mgmt. Addresses: 0x%d", numelem); offset += 4; for (i = 0; i < numelem; i++) { proto_tree_add_text (tree, tvb, offset, 1, "Name Length: %d", tvb_get_guint8 (tvb, offset)); proto_tree_add_item (tree, hf_fcs_mgmtaddr, tvb, offset+1, tvb_get_guint8 (tvb, offset), ENC_ASCII|ENC_NA); offset += 256; } } } }
static void dissect_fcfcs_gfn (tvbuff_t *tvb, proto_tree *tree, gboolean isreq) { int offset = 16; /* past the fcct header */ if (tree) { if (isreq) { proto_tree_add_string (tree, hf_fcs_iename, tvb, offset, 8, tvb_fcwwn_to_str (tvb, offset)); } else { proto_tree_add_string (tree, hf_fcs_fabricname, tvb, offset, 8, tvb_fcwwn_to_str (tvb, offset)); } } }
static void dissect_fcip_sf (tvbuff_t *tvb, proto_tree *tree, gint offset) { if (tree) { proto_tree_add_string (tree, hf_fcip_src_wwn, tvb, offset, 8, tvb_fcwwn_to_str (tvb, offset)); proto_tree_add_item (tree, hf_fcip_src_entity_id, tvb, offset+8, 8, ENC_NA); proto_tree_add_item (tree, hf_fcip_conn_nonce, tvb, offset+16, 8, ENC_NA); /* XXX - break out these flags */ proto_tree_add_item (tree, hf_fcip_conn_flags, tvb, offset+24, 1, ENC_BIG_ENDIAN); proto_tree_add_item (tree, hf_fcip_conn_code, tvb, offset+26, 2, ENC_BIG_ENDIAN); proto_tree_add_string (tree, hf_fcip_dst_wwn, tvb, offset+30, 8, tvb_fcwwn_to_str (tvb, offset+30)); proto_tree_add_item (tree, hf_fcip_katov, tvb, offset+38, 4, ENC_BIG_ENDIAN); } }
static void dissect_fcfcs_dpln (tvbuff_t *tvb, proto_tree *tree, gboolean isreq) { int offset = 16; /* past the fc_ct header */ if (tree) { if (isreq) { proto_tree_add_string (tree, hf_fcs_platformnname, tvb, offset, 8, tvb_fcwwn_to_str (tvb, offset)); } } }
static void dissect_fcsp_auth_negotiate(tvbuff_t *tvb, proto_tree *tree) { int offset = 12; guint16 name_type, name_len, proto_type, param_len; guint32 num_protos, i; if (tree) { proto_tree_add_item(tree, hf_auth_initiator_name_type, tvb, offset, 2, ENC_BIG_ENDIAN); name_type = tvb_get_ntohs(tvb, offset); proto_tree_add_item(tree, hf_auth_initiator_name_len, tvb, offset+2, 2, ENC_BIG_ENDIAN); name_len = tvb_get_ntohs(tvb, offset+2); if (name_type == FC_AUTH_NAME_TYPE_WWN) { proto_tree_add_string(tree, hf_auth_initiator_wwn, tvb, offset+4, 8, tvb_fcwwn_to_str(tvb, offset+4)); } else { proto_tree_add_item(tree, hf_auth_initiator_name, tvb, offset+4, name_len, ENC_NA); } offset += (4+name_len); proto_tree_add_item(tree, hf_auth_usable_proto, tvb, offset, 4, ENC_BIG_ENDIAN); num_protos = tvb_get_ntohl(tvb, offset); offset += 4; for (i = 0; i < num_protos; i++) { proto_tree_add_item(tree, hf_auth_proto_param_len, tvb, offset, 4, ENC_BIG_ENDIAN); param_len = tvb_get_ntohl(tvb, offset); offset += 4; if (tvb_bytes_exist(tvb, offset, param_len)) { proto_type = tvb_get_ntohl(tvb, offset); proto_tree_add_item(tree, hf_auth_proto_type, tvb, offset, 4, ENC_BIG_ENDIAN); switch (proto_type) { case FC_AUTH_PROTO_TYPE_DHCHAP: dissect_fcsp_dhchap_auth_param(tvb, tree, offset+4, param_len); break; case FC_AUTH_PROTO_TYPE_FCAP: break; default: break; } } offset += param_len; } } }
static void dissect_fcfzs_gzm(tvbuff_t *tvb, proto_tree *tree, gboolean isreq) { int numrec, i, len; int offset = 16; /* past the fc_ct header */ if (tree) { if (isreq) { len = tvb_get_guint8(tvb, offset); proto_tree_add_item(tree, hf_fcfzs_zonenmlen, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(tree, hf_fcfzs_zonename, tvb, offset+1, len, ENC_ASCII|ENC_NA); } else { numrec = tvb_get_ntohl(tvb, offset); proto_tree_add_item(tree, hf_fcfzs_nummbrentries, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; for (i = 0; i < numrec; i++) { proto_tree_add_item(tree, hf_fcfzs_mbrtype, tvb, offset, 1, ENC_BIG_ENDIAN); switch (tvb_get_guint8(tvb, offset)) { case FC_FZS_ZONEMBR_PWWN: case FC_FZS_ZONEMBR_NWWN: proto_tree_add_string(tree, hf_fcfzs_mbrid, tvb, offset+4, 8, tvb_fcwwn_to_str(tvb, offset+4)); break; case FC_FZS_ZONEMBR_DP: proto_tree_add_string_format(tree, hf_fcfzs_mbrid, tvb, offset+4, 3, " ", "0x%x", tvb_get_ntoh24(tvb, offset+4)); break; case FC_FZS_ZONEMBR_FCID: proto_tree_add_string(tree, hf_fcfzs_mbrid, tvb, offset+4, 4, tvb_fc_to_str(tvb, offset+4)); break; default: proto_tree_add_string(tree, hf_fcfzs_mbrid, tvb, offset+4, 8, "Unknown member type format"); } offset += 12; } } } }
static void dissect_fcfcs_gppn (tvbuff_t *tvb, proto_tree *tree, gboolean isreq) { int offset = 16; /* past the fcct header */ if (tree) { if (isreq) { proto_tree_add_string (tree, hf_fcs_portname, tvb, offset, 8, tvb_fcwwn_to_str (tvb, offset)); } else { proto_tree_add_item (tree, hf_fcs_physportnum, tvb, offset, 4, ENC_NA); } } }
static void dissect_fcfcs_gpt (tvbuff_t *tvb, proto_tree *tree, gboolean isreq) { int offset = 16; /* past the fcct header */ if (tree) { if (isreq) { proto_tree_add_string (tree, hf_fcs_portname, tvb, offset, 8, tvb_fcwwn_to_str (tvb, offset)); } else { proto_tree_add_item (tree, hf_fcs_porttype, tvb, offset+3, 1, ENC_BIG_ENDIAN); } } }
static void dissect_fcfcs_rieln (tvbuff_t *tvb, proto_tree *tree, gboolean isreq) { int offset = 16; /* past the fc_ct header */ int len; if (tree) { if (isreq) { proto_tree_add_string (tree, hf_fcs_iename, tvb, offset, 8, tvb_fcwwn_to_str (tvb, offset)); len = tvb_get_guint8 (tvb, offset+8); proto_tree_add_text (tree, tvb, offset+8, 1, "Logical Name Length: %d", len); proto_tree_add_item (tree, hf_fcs_lname, tvb, offset+9, len, ENC_ASCII|ENC_NA); } } }
static void dissect_fcsp_dhchap_challenge(tvbuff_t *tvb, proto_tree *tree) { int offset = 12; guint16 name_type; guint16 param_len, name_len; if (tree) { proto_tree_add_item(tree, hf_auth_responder_name_type, tvb, offset, 2, ENC_BIG_ENDIAN); name_type = tvb_get_ntohs(tvb, offset); proto_tree_add_item(tree, hf_auth_responder_name_len, tvb, offset+2, 2, ENC_BIG_ENDIAN); name_len = tvb_get_ntohs(tvb, offset+2); if (name_type == FC_AUTH_NAME_TYPE_WWN) { proto_tree_add_string(tree, hf_auth_responder_wwn, tvb, offset+4, 8, tvb_fcwwn_to_str(tvb, offset+4)); } else { proto_tree_add_item(tree, hf_auth_responder_name, tvb, offset+4, name_len, ENC_NA); } offset += (4+name_len); proto_tree_add_item(tree, hf_auth_dhchap_hash_type, tvb, offset, 4, ENC_BIG_ENDIAN); proto_tree_add_item(tree, hf_auth_dhchap_group_type, tvb, offset+4, 4, ENC_BIG_ENDIAN); proto_tree_add_item(tree, hf_auth_dhchap_chal_len, tvb, offset+8, 4, ENC_BIG_ENDIAN); param_len = tvb_get_ntohl(tvb, offset+8); proto_tree_add_item(tree, hf_auth_dhchap_chal_value, tvb, offset+12, param_len, ENC_NA); offset += (param_len + 12); proto_tree_add_item(tree, hf_auth_dhchap_val_len, tvb, offset, 4, ENC_BIG_ENDIAN); param_len = tvb_get_ntohl(tvb, offset); proto_tree_add_item(tree, hf_auth_dhchap_dhvalue, tvb, offset+4, param_len, ENC_NA); } }
static void dissect_fcfcs_gieln (tvbuff_t *tvb, proto_tree *tree, gboolean isreq) { int offset = 16; /* past the fcct header */ if (tree) { if (isreq) { proto_tree_add_string (tree, hf_fcs_iename, tvb, offset, 8, tvb_fcwwn_to_str (tvb, offset)); } else { proto_tree_add_text (tree, tvb, offset, 1, "Name Length: %d", tvb_get_guint8 (tvb, offset)); proto_tree_add_item (tree, hf_fcs_lname, tvb, offset+1, tvb_get_guint8 (tvb, offset), ENC_ASCII|ENC_NA); } } }
static void dissect_fcfcs_rpln (tvbuff_t *tvb, proto_tree *tree, gboolean isreq) { int offset = 16; /* past the fc_ct header */ int len; if (tree) { if (isreq) { len = tvb_get_guint8 (tvb, offset); proto_tree_add_text (tree, tvb, offset, 1, "Platform Name Length: %d", len); proto_tree_add_item (tree, hf_fcs_platformname, tvb, offset+1, len, ENC_NA); proto_tree_add_string (tree, hf_fcs_platformnname, tvb, offset+256, 8, tvb_fcwwn_to_str (tvb, offset+256)); } } }
static void dissect_fcfcs_gieil (tvbuff_t *tvb, proto_tree *tree, gboolean isreq) { int offset = 16; /* past the fcct header */ int len, tot_len, prevlen; if (tree) { if (isreq) { proto_tree_add_string (tree, hf_fcs_iename, tvb, offset, 8, tvb_fcwwn_to_str (tvb, offset)); } else { tot_len = tvb_get_guint8 (tvb, offset+3); proto_tree_add_text (tree, tvb, offset+3, 1, "List Length: %d", tot_len); prevlen = 0; len = tvb_strsize(tvb, offset+4); proto_tree_add_item (tree, hf_fcs_vendorname, tvb, offset+4, len, ENC_ASCII|ENC_NA); prevlen += len; len = tvb_strsize(tvb, offset+4+prevlen); proto_tree_add_item (tree, hf_fcs_modelname, tvb, offset+4+prevlen, len, ENC_ASCII|ENC_NA); prevlen += len; len = tvb_strsize(tvb, offset+4+prevlen); proto_tree_add_item (tree, hf_fcs_releasecode, tvb, offset+4+prevlen, len, ENC_ASCII|ENC_NA); prevlen += len; offset += (4+prevlen); while (tot_len > prevlen) { len = tvb_strsize(tvb, offset); proto_tree_add_text (tree, tvb, offset, len, "Vendor-specific Information: %s", tvb_format_text(tvb, offset, len-1)); prevlen += len; offset += len; } } } }
/* Code to actually dissect the packets */ static void dissect_fcfcs_giel (tvbuff_t *tvb, proto_tree *tree, gboolean isreq) { int offset = 16; /* past the ct header */ int numelem, i; if (!isreq && tree) { numelem = tvb_get_ntohl (tvb, offset); proto_tree_add_text (tree, tvb, offset, 4, "Number of IE entries: 0x%d", numelem); offset += 4; for (i = 0; i < numelem; i++) { proto_tree_add_string (tree, hf_fcs_iename, tvb, offset, 8, tvb_fcwwn_to_str (tvb, offset)); proto_tree_add_item (tree, hf_fcs_ietype, tvb, offset+11, 1, ENC_BIG_ENDIAN); offset += 12; } } }
static void dissect_fcfcs_rpl (tvbuff_t *tvb, proto_tree *tree, gboolean isreq) { int offset = 16; /* past the fc_ct header */ int numelem, i, len; if (tree) { if (isreq) { len = tvb_get_guint8 (tvb, offset); proto_tree_add_text (tree, tvb, offset, 1, "Platform Name Length: %d", len); proto_tree_add_item (tree, hf_fcs_platformname, tvb, offset+1, len, ENC_NA); proto_tree_add_item (tree, hf_fcs_platformtype, tvb, offset+256, 4, ENC_BIG_ENDIAN); numelem = tvb_get_ntohl (tvb, offset+260); proto_tree_add_text (tree, tvb, offset+260, 4, "Number of Mgmt. Addr Entries: %d", numelem); offset += 264; for (i = 0; i < numelem; i++) { len = tvb_get_guint8 (tvb, offset); proto_tree_add_text (tree, tvb, offset, 1, "Mgmt. Addr Length: %d", len); proto_tree_add_item (tree, hf_fcs_mgmtaddr, tvb, offset+1, len, ENC_ASCII|ENC_NA); offset += 256; } numelem = tvb_get_ntohl (tvb, offset); proto_tree_add_text (tree, tvb, offset, 4, "Number of Platform Node Name Entries: %d", numelem); offset += 4; for (i = 0; i < numelem; i++) { proto_tree_add_string (tree, hf_fcs_platformnname, tvb, offset, 8, tvb_fcwwn_to_str (tvb, offset)); offset += 8; } } } }
static void dissect_fip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint op; guint sub; guint rlen; proto_item *ti; proto_item *item; proto_tree *fip_tree; proto_tree *subtree; guint dtype; guint dlen; guint desc_offset; guint val; tvbuff_t *desc_tvb; const char *info; col_set_str(pinfo->cinfo, COL_PROTOCOL, "FIP"); col_clear(pinfo->cinfo, COL_INFO); if (!tvb_bytes_exist(tvb, 0, FIP_HEADER_LEN)) { col_set_str(pinfo->cinfo, COL_INFO, "[packet too short]"); if (tree) proto_tree_add_protocol_format(tree, proto_fip, tvb, 0, -1, "FIP [packet too short]"); return; } op = tvb_get_ntohs(tvb, 2); sub = tvb_get_guint8(tvb, 5); switch (op) { case FIP_OP_DISC: info = val_to_str(sub, fip_disc_subcodes, "Discovery 0x%x"); break; case FIP_OP_LS: info = val_to_str(sub, fip_ls_subcodes, "Link Service 0x%x"); break; case FIP_OP_CTRL: info = val_to_str(sub, fip_ctrl_subcodes, "Control 0x%x"); break; case FIP_OP_VLAN: info = val_to_str(sub, fip_vlan_subcodes, "VLAN 0x%x"); break; case FIP_OP_VN2VN: info = val_to_str(sub, fip_vn2vn_subcodes, "VN2VN 0x%x"); break; default: info = val_to_str(op, fip_opcodes, "Unknown op 0x%x"); break; } col_add_str(pinfo->cinfo, COL_INFO, info); rlen = tvb_get_ntohs(tvb, 6); ti = proto_tree_add_protocol_format(tree, proto_fip, tvb, 0, FIP_HEADER_LEN + rlen * FIP_BPW, "FIP %s", info); fip_tree = proto_item_add_subtree(ti, ett_fip); proto_tree_add_item(fip_tree, hf_fip_ver, tvb, 0, 1, ENC_BIG_ENDIAN); proto_tree_add_item(fip_tree, hf_fip_reserved12, tvb, 0, 2, ENC_BIG_ENDIAN); proto_tree_add_item(fip_tree, hf_fip_op, tvb, 2, 2, ENC_BIG_ENDIAN); proto_tree_add_item(fip_tree, hf_fip_reserved8, tvb, 4, 1, ENC_NA); switch (op) { case FIP_OP_DISC: proto_tree_add_item(fip_tree, hf_fip_disc_subcode, tvb, 5, 1, ENC_BIG_ENDIAN); break; case FIP_OP_LS: proto_tree_add_item(fip_tree, hf_fip_ls_subcode, tvb, 5, 1, ENC_BIG_ENDIAN); break; case FIP_OP_CTRL: proto_tree_add_item(fip_tree, hf_fip_ctrl_subcode, tvb, 5, 1, ENC_BIG_ENDIAN); break; case FIP_OP_VLAN: proto_tree_add_item(fip_tree, hf_fip_vlan_subcode, tvb, 5, 1, ENC_BIG_ENDIAN); break; case FIP_OP_VN2VN: proto_tree_add_item(fip_tree, hf_fip_vn2vn_subcode, tvb, 5, 1, ENC_BIG_ENDIAN); break; default: proto_tree_add_item(fip_tree, hf_fip_hex_subcode, tvb, 5, 1, ENC_BIG_ENDIAN); break; } proto_tree_add_item(fip_tree, hf_fip_dlen, tvb, 6, 2, ENC_BIG_ENDIAN); proto_tree_add_bitmask(fip_tree, tvb, 8, hf_fip_flags, ett_fip_flags, hf_fip_flags_fields, ENC_BIG_ENDIAN); desc_offset = FIP_HEADER_LEN; rlen *= FIP_BPW; proto_tree_add_bytes_format(fip_tree, hf_fip_descriptors, tvb, desc_offset, rlen, NULL, "Descriptors"); while ((rlen > 0) && tvb_bytes_exist(tvb, desc_offset, 2)) { dlen = tvb_get_guint8(tvb, desc_offset + 1) * FIP_BPW; if (!dlen) { proto_tree_add_expert(fip_tree, pinfo, &ei_fip_descriptors, tvb, desc_offset, -1); break; } if (!tvb_bytes_exist(tvb, desc_offset, dlen) || dlen > rlen) { break; } desc_tvb = tvb_new_subset(tvb, desc_offset, dlen, -1); dtype = tvb_get_guint8(desc_tvb, 0); desc_offset += dlen; rlen -= dlen; switch (dtype) { case FIP_DT_PRI: subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_pri, &item); proto_tree_add_item(subtree, hf_fip_desc_pri, desc_tvb, 3, 1, ENC_BIG_ENDIAN); proto_item_append_text(item, "%u", tvb_get_guint8(desc_tvb, 3)); break; case FIP_DT_MAC: subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_mac, &item); proto_tree_add_item(subtree, hf_fip_desc_mac, desc_tvb, 2, 6, ENC_NA); proto_item_append_text(item, "%s", tvb_bytes_to_str_punct(wmem_packet_scope(), desc_tvb, 2, 6, ':')); break; case FIP_DT_MAP_OUI: subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_map, &item); proto_tree_add_item(subtree, hf_fip_desc_map, desc_tvb, 5, 3, ENC_NA); proto_item_append_text(item, "%s", tvb_fc_to_str(desc_tvb, 5)); break; case FIP_DT_NAME: subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_name, &item); proto_tree_add_item(subtree, hf_fip_desc_name, desc_tvb, 4, 8, ENC_NA); proto_item_append_text(item, "%s", tvb_fcwwn_to_str(desc_tvb, 4)); break; case FIP_DT_FAB: subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_fab, &item); proto_tree_add_item(subtree, hf_fip_desc_fab_vfid, desc_tvb, 2, 2, ENC_BIG_ENDIAN); proto_tree_add_item(subtree, hf_fip_desc_fab_map, desc_tvb, 5, 3, ENC_NA); proto_tree_add_item(subtree, hf_fip_desc_fab_name, desc_tvb, 8, 8, ENC_NA); proto_item_append_text(item, "%s", tvb_fcwwn_to_str(desc_tvb, 8)); break; case FIP_DT_FCOE_SIZE: subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_mdl, &item); proto_tree_add_item(subtree, hf_fip_desc_fcoe_size, desc_tvb, 2, 2, ENC_BIG_ENDIAN); proto_item_append_text(item, "%u", tvb_get_ntohs(desc_tvb, 2)); break; case FIP_DT_FLOGI: case FIP_DT_FDISC: case FIP_DT_LOGO: case FIP_DT_ELP: { tvbuff_t *ls_tvb; fc_data_t fc_data = {ETHERTYPE_FIP, 0}; subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_caps, &item); ls_tvb = tvb_new_subset(desc_tvb, 4, dlen - 4, -1); call_dissector_with_data(fc_handle, ls_tvb, pinfo, subtree, &fc_data); proto_item_append_text(item, "%u bytes", dlen - 4); } break; case FIP_DT_VN: subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_vn, &item); proto_tree_add_item(subtree, hf_fip_desc_vn_mac, desc_tvb, 2, 6, ENC_NA); proto_tree_add_item(subtree, hf_fip_desc_vn_fid, desc_tvb, 9, 3, ENC_BIG_ENDIAN); proto_tree_add_item(subtree, hf_fip_desc_vn_wwpn, desc_tvb, 12, 8, ENC_NA); proto_item_append_text(item, "MAC %s FC_ID %6.6x", tvb_bytes_to_str_punct(wmem_packet_scope(), desc_tvb, 2, 6, ':'), tvb_get_ntoh24(desc_tvb, 9)); break; case FIP_DT_FKA: subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_fka, &item); val = tvb_get_ntohl(desc_tvb, 4); proto_tree_add_uint_format_value(subtree, hf_fip_desc_fka, desc_tvb, 4, 4, val, "%u ms", val); proto_item_append_text(item, "%u ms", val); break; case FIP_DT_VEND: subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_vend, &item); proto_tree_add_item(subtree, hf_fip_desc_vend, desc_tvb, 4, 8, ENC_NA); if (tvb_bytes_exist(desc_tvb, 9, -1)) { proto_tree_add_item(subtree, hf_fip_desc_vend_data, desc_tvb, 9, -1, ENC_NA); } break; case FIP_DT_VLAN: subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_vlan, &item); proto_tree_add_item(subtree, hf_fip_desc_vlan, desc_tvb, 2, 2, ENC_BIG_ENDIAN); proto_item_append_text(item, "%u", tvb_get_ntohs(desc_tvb, 2)); break; case FIP_DT_FC4F: subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_fc4f, &item); fip_desc_fc4f(desc_tvb, subtree, item); break; default: subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_unk, &item); proto_tree_add_item(subtree, hf_fip_desc_unk, desc_tvb, 2, -1, ENC_NA); break; } } }
/* Code to actually dissect the packets */ static void dissect_fcfzs_zoneset(tvbuff_t *tvb, proto_tree *tree, int offset) { int numzones, nummbrs, i, j, len; /* The zoneset structure has the following format */ /* zoneset name (len[not including pad], name, pad), * number of zones, * for each zone, * Zone name (len[not including pad], name, pad), num zone mbrs * for each zone mbr, * zone mbr id type, zone mbr id (len, name, pad) */ if (tree) { /* Zoneset Name */ len = tvb_get_guint8(tvb, offset); proto_tree_add_item(tree, hf_fcfzs_zonesetnmlen, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(tree, hf_fcfzs_zonesetname, tvb, offset+4, len, ENC_ASCII|ENC_NA); offset += 4 + len + (4-(len % 4)); /* Number of zones */ numzones = tvb_get_ntohl(tvb, offset); proto_tree_add_item(tree, hf_fcfzs_numzones, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; /* For each zone... */ for (i = 0; i < numzones; i++) { len = tvb_get_guint8(tvb, offset); proto_tree_add_item(tree, hf_fcfzs_zonenmlen, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(tree, hf_fcfzs_zonename, tvb, offset+4, len, ENC_ASCII|ENC_NA); offset += 4 + len + (4-(len % 4)); nummbrs = tvb_get_ntohl(tvb, offset); proto_tree_add_item(tree, hf_fcfzs_nummbrentries, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; for (j = 0; j < nummbrs; j++) { proto_tree_add_item(tree, hf_fcfzs_mbrtype, tvb, offset, 1, ENC_BIG_ENDIAN); switch (tvb_get_guint8(tvb, offset)) { case FC_FZS_ZONEMBR_PWWN: case FC_FZS_ZONEMBR_NWWN: proto_tree_add_string(tree, hf_fcfzs_mbrid, tvb, offset+4, 8, tvb_fcwwn_to_str(tvb, offset+4)); break; case FC_FZS_ZONEMBR_DP: proto_tree_add_string_format(tree, hf_fcfzs_mbrid, tvb, offset+4, 3, " ", "0x%x", tvb_get_ntoh24(tvb, offset+4)); break; case FC_FZS_ZONEMBR_FCID: proto_tree_add_string(tree, hf_fcfzs_mbrid, tvb, offset+4, 4, tvb_fc_to_str(tvb, offset+4)); break; case FC_FZS_ZONEMBR_PWWN_LUN: proto_tree_add_string(tree, hf_fcfzs_mbrid, tvb, offset+4, 8, tvb_fcwwn_to_str(tvb, offset+4)); proto_tree_add_item(tree, hf_fcfzs_mbrid_lun, tvb, offset+8, 8, ENC_NA); break; case FC_FZS_ZONEMBR_DP_LUN: proto_tree_add_string_format(tree, hf_fcfzs_mbrid, tvb, offset+4, 3, " ", "0x%x", tvb_get_ntoh24(tvb, offset+4)); proto_tree_add_item(tree, hf_fcfzs_mbrid_lun, tvb, offset+4, 8, ENC_NA); break; case FC_FZS_ZONEMBR_FCID_LUN: proto_tree_add_string(tree, hf_fcfzs_mbrid, tvb, offset+4, 4, tvb_fc_to_str(tvb, offset+4)); proto_tree_add_item(tree, hf_fcfzs_mbrid_lun, tvb, offset+4, 8, ENC_NA); break; default: proto_tree_add_string(tree, hf_fcfzs_mbrid, tvb, offset+4, 8, "Unknown member type format"); } offset += 12; } } } }