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, fcwwn_to_str (tvb_get_ptr (tvb, offset, 8))); } 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, fcwwn_to_str (tvb_get_ptr (tvb, offset, 8))); proto_tree_add_item (tree, hf_fcs_portflags, tvb, offset+10, 1, 0); proto_tree_add_item (tree, hf_fcs_porttype, tvb, offset+11, 1, 0); offset += 12; } } } }
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, fcwwn_to_str (tvb_get_ptr (tvb, offset, 8))); } else { proto_tree_add_string (tree, hf_fcs_fabricname, tvb, offset, 8, fcwwn_to_str (tvb_get_ptr (tvb, offset, 8))); } } }
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, 0); } 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, fcwwn_to_str (tvb_get_ptr (tvb, offset, 8))); 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, fcwwn_to_str (tvb_get_ptr (tvb, offset, 8))); } 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), 0); offset += 256; } } } }
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, fcwwn_to_str (tvb_get_ptr (tvb, offset, 8))); proto_tree_add_bytes (tree, hf_fcip_src_entity_id, tvb, offset+8, 8, tvb_get_ptr (tvb, offset+8, 8)); proto_tree_add_bytes (tree, hf_fcip_conn_nonce, tvb, offset+16, 8, tvb_get_ptr (tvb, offset+16, 8)); /* XXX - break out these flags */ proto_tree_add_item (tree, hf_fcip_conn_flags, tvb, offset+24, 1, 0); proto_tree_add_item (tree, hf_fcip_conn_code, tvb, offset+26, 2, 0); proto_tree_add_string (tree, hf_fcip_dst_wwn, tvb, offset+30, 8, fcwwn_to_str (tvb_get_ptr (tvb, offset+30, 8))); proto_tree_add_item (tree, hf_fcip_katov, tvb, offset+38, 4, 0); } }
static void dissect_fcfzs_gzm (tvbuff_t *tvb, proto_tree *tree, guint8 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, 0); proto_tree_add_item (tree, hf_fcfzs_zonename, tvb, offset+1, len, 0); } else { numrec = tvb_get_ntohl (tvb, offset); proto_tree_add_item (tree, hf_fcfzs_nummbrentries, tvb, offset, 4, 0); offset += 4; for (i = 0; i < numrec; i++) { proto_tree_add_item (tree, hf_fcfzs_mbrtype, tvb, offset, 1, 0); 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, fcwwn_to_str (tvb_get_ptr (tvb, offset+4, 8))); 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, fc_to_str (tvb_get_ptr (tvb, offset+4, 3))); break; default: proto_tree_add_string (tree, hf_fcfzs_mbrid, tvb, offset+4, 8, "Unknown member type format"); } offset += 12; } } } }
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, 0); name_type = tvb_get_ntohs (tvb, offset); proto_tree_add_item (tree, hf_auth_initiator_name_len, tvb, offset+2, 2, 0); 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, fcwwn_to_str (tvb_get_ptr (tvb, offset+4, 8))); } else { proto_tree_add_bytes (tree, hf_auth_initiator_name, tvb, offset+4, name_len, tvb_get_ptr (tvb, offset+4, name_len)); } offset += (4+name_len); proto_tree_add_item (tree, hf_auth_usable_proto, tvb, offset, 4, 0); 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, 0); 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, 0); 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_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, fcwwn_to_str (tvb_get_ptr (tvb, offset, 8))); } } }
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, 0); name_type = tvb_get_ntohs (tvb, offset); proto_tree_add_item (tree, hf_auth_responder_name_len, tvb, offset+2, 2, 0); 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, fcwwn_to_str (tvb_get_ptr (tvb, offset+4, 8))); } else { proto_tree_add_bytes (tree, hf_auth_responder_name, tvb, offset+4, name_len, tvb_get_ptr (tvb, offset+4, name_len)); } offset += (4+name_len); proto_tree_add_item (tree, hf_auth_dhchap_hash_type, tvb, offset, 4, 0); proto_tree_add_item (tree, hf_auth_dhchap_group_type, tvb, offset+4, 4, 0); proto_tree_add_item (tree, hf_auth_dhchap_chal_len, tvb, offset+8, 4, 0); param_len = tvb_get_ntohl (tvb, offset+8); proto_tree_add_bytes (tree, hf_auth_dhchap_chal_value, tvb, offset+12, param_len, tvb_get_ptr (tvb, offset+12, param_len)); offset += (param_len + 12); proto_tree_add_item (tree, hf_auth_dhchap_val_len, tvb, offset, 4, 0); param_len = tvb_get_ntohl (tvb, offset); proto_tree_add_bytes (tree, hf_auth_dhchap_dhvalue, tvb, offset+4, param_len, tvb_get_ptr (tvb, offset+4, param_len)); } }
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, fcwwn_to_str (tvb_get_ptr (tvb, offset, 8))); } else { proto_tree_add_item (tree, hf_fcs_physportnum, tvb, offset, 4, 0); } } }
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, fcwwn_to_str (tvb_get_ptr (tvb, offset, 8))); 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, 0); } } }
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, fcwwn_to_str (tvb_get_ptr (tvb, offset, 8))); } 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), 0); } } }
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, fcwwn_to_str (tvb_get_ptr (tvb, offset, 8))); } 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, FALSE); prevlen += len; len = tvb_strsize(tvb, offset+4+prevlen); proto_tree_add_item (tree, hf_fcs_modelname, tvb, offset+4+prevlen, len, FALSE); prevlen += len; len = tvb_strsize(tvb, offset+4+prevlen); proto_tree_add_item (tree, hf_fcs_releasecode, tvb, offset+4+prevlen, len, FALSE); 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; } } } }
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, 0); proto_tree_add_string (tree, hf_fcs_platformnname, tvb, offset+256, 8, fcwwn_to_str (tvb_get_ptr (tvb, offset+256, 8))); } } }
/* 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, fcwwn_to_str (tvb_get_ptr (tvb, offset, 8))); proto_tree_add_item (tree, hf_fcs_ietype, tvb, offset+11, 1, 0); offset += 12; } } }
static void dissect_fip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint op; guint sub; guint rlen; guint flags; 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; tvbuff_t *ls_tvb = NULL; const char *info; char *text; col_set_str(pinfo->cinfo, COL_PROTOCOL, "FIP"); 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; default: info = val_to_str(op, fip_opcodes, "Unknown op 0x%x"); break; } if (check_col(pinfo->cinfo, COL_INFO)) col_set_str(pinfo->cinfo, COL_INFO, info); rlen = tvb_get_ntohs(tvb, 6); flags = tvb_get_ntohs(tvb, 8); 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, FALSE); proto_tree_add_item(fip_tree, hf_fip_op, tvb, 2, 2, FALSE); switch (op) { case FIP_OP_DISC: proto_tree_add_item(fip_tree, hf_fip_disc_subcode, tvb, 5, 1, FALSE); break; case FIP_OP_LS: proto_tree_add_item(fip_tree, hf_fip_ls_subcode, tvb, 5, 1, FALSE); break; case FIP_OP_CTRL: proto_tree_add_item(fip_tree, hf_fip_ctrl_subcode, tvb, 5, 1, FALSE); break; case FIP_OP_VLAN: proto_tree_add_item(fip_tree, hf_fip_vlan_subcode, tvb, 5, 1, FALSE); break; default: proto_tree_add_item(fip_tree, hf_fip_hex_subcode, tvb, 5, 1, FALSE); break; } proto_tree_add_item(fip_tree, hf_fip_dlen, tvb, 6, 2, FALSE); proto_tree_add_bitmask(fip_tree, tvb, 8, hf_fip_flags, ett_fip_flags, hf_fip_flags_fields, FALSE); desc_offset = FIP_HEADER_LEN; rlen *= FIP_BPW; proto_tree_add_text(fip_tree, tvb, desc_offset, rlen, "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_text(fip_tree, tvb, desc_offset, -1, "Descriptor [length error]"); 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; item = proto_tree_add_text(fip_tree, desc_tvb, 0, -1, "Descriptor: %s ", val_to_str(dtype, fip_desc_types, "Unknown 0x%x")); switch (dtype) { case FIP_DT_PRI: subtree = proto_item_add_subtree(item, ett_fip_dt_pri); fip_desc_type_len(subtree, desc_tvb); proto_tree_add_item(subtree, hf_fip_desc_pri, desc_tvb, 3, 1, FALSE); proto_item_append_text(item, "%u", tvb_get_guint8(desc_tvb, 3)); break; case FIP_DT_MAC: subtree = proto_item_add_subtree(item, ett_fip_dt_mac); fip_desc_type_len(subtree, desc_tvb); proto_tree_add_item(subtree, hf_fip_desc_mac, desc_tvb, 2, 6, FALSE); proto_item_append_text(item, "%s", tvb_bytes_to_str_punct(desc_tvb, 2, 6, ':')); break; case FIP_DT_MAP_OUI: subtree = proto_item_add_subtree(item, ett_fip_dt_map); fip_desc_type_len(subtree, desc_tvb); text = fc_to_str(tvb_get_ptr(desc_tvb, 5, 3)); proto_tree_add_string(subtree, hf_fip_desc_map, desc_tvb, 5, 3, text); proto_item_append_text(item, "%s", text); break; case FIP_DT_NAME: subtree = proto_item_add_subtree(item, ett_fip_dt_name); fip_desc_type_len(subtree, desc_tvb); text = fcwwn_to_str(tvb_get_ptr(desc_tvb, 4, 8)); proto_tree_add_string(subtree, hf_fip_desc_name, desc_tvb, 4, 8, text); proto_item_append_text(item, "%s", text); break; case FIP_DT_FAB: subtree = proto_item_add_subtree(item, ett_fip_dt_fab); fip_desc_type_len(subtree, desc_tvb); proto_tree_add_item(subtree, hf_fip_desc_fab_vfid, desc_tvb, 2, 2, FALSE); text = fc_to_str(tvb_get_ptr(desc_tvb, 5, 3)); proto_tree_add_string(subtree, hf_fip_desc_fab_map, desc_tvb, 5, 3, text); text = fcwwn_to_str(tvb_get_ptr(desc_tvb, 8, 8)); proto_tree_add_string(subtree, hf_fip_desc_fab_name, desc_tvb, 8, 8, text); proto_item_append_text(item, "%s", text); break; case FIP_DT_FCOE_SIZE: subtree = proto_item_add_subtree(item, ett_fip_dt_mdl); fip_desc_type_len(subtree, desc_tvb); proto_tree_add_item(subtree, hf_fip_desc_fcoe_size, desc_tvb, 2, 2, FALSE); 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: subtree = proto_item_add_subtree(item, ett_fip_dt_caps); fip_desc_type_len(subtree, desc_tvb); ls_tvb = tvb_new_subset(desc_tvb, 4, dlen - 4, -1); call_dissector(fc_handle, ls_tvb, pinfo, subtree); proto_item_append_text(item, "%u bytes", dlen - 4); break; case FIP_DT_VN: subtree = proto_item_add_subtree(item, ett_fip_dt_vn); fip_desc_type_len(subtree, desc_tvb); proto_tree_add_item(subtree, hf_fip_desc_vn_mac, desc_tvb, 2, 6, FALSE); proto_tree_add_item(subtree, hf_fip_desc_vn_fid, desc_tvb, 9, 3, FALSE); text = fcwwn_to_str(tvb_get_ptr(desc_tvb, 12, 8)); proto_tree_add_string(subtree, hf_fip_desc_vn_wwpn, desc_tvb, 12, 8, text); proto_item_append_text(item, "MAC %s FC_ID %6.6x", tvb_bytes_to_str_punct(desc_tvb, 2, 6, ':'), tvb_get_ntoh24(desc_tvb, 9)); break; case FIP_DT_FKA: subtree = proto_item_add_subtree(item, ett_fip_dt_fka); fip_desc_type_len(subtree, desc_tvb); 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 = proto_item_add_subtree(item, ett_fip_dt_vend); fip_desc_type_len(subtree, desc_tvb); proto_tree_add_item(subtree, hf_fip_desc_vend, desc_tvb, 4, 8, FALSE); if (tvb_bytes_exist(desc_tvb, 9, -1)) { proto_tree_add_item(subtree, hf_fip_desc_vend_data, desc_tvb, 9, -1, FALSE); } break; case FIP_DT_VLAN: subtree = proto_item_add_subtree(item, ett_fip_dt_vlan); fip_desc_type_len(subtree, desc_tvb); proto_tree_add_item(subtree, hf_fip_desc_vlan, desc_tvb, 2, 2, FALSE); proto_item_append_text(item, "%u", tvb_get_ntohs(desc_tvb, 2)); break; default: subtree = proto_item_add_subtree(item, ett_fip_dt_unk); fip_desc_type_len(subtree, desc_tvb); proto_tree_add_item(subtree, hf_fip_desc_unk, desc_tvb, 2, -1, FALSE); 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, 0); proto_tree_add_item (tree, hf_fcfzs_zonesetname, tvb, offset+4, len, 0); 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, 0); 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, 0); proto_tree_add_item (tree, hf_fcfzs_zonename, tvb, offset+4, len, 0); offset += 4 + len + (4-(len % 4)); nummbrs = tvb_get_ntohl (tvb, offset); proto_tree_add_item (tree, hf_fcfzs_nummbrentries, tvb, offset, 4, 0); offset += 4; for (j = 0; j < nummbrs; j++) { proto_tree_add_item (tree, hf_fcfzs_mbrtype, tvb, offset, 1, 0); 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, fcwwn_to_str (tvb_get_ptr (tvb, offset+4, 8))); 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, fc_to_str (tvb_get_ptr (tvb, offset+4, 3))); break; case FC_FZS_ZONEMBR_PWWN_LUN: proto_tree_add_string (tree, hf_fcfzs_mbrid, tvb, offset+4, 8, fcwwn_to_str (tvb_get_ptr (tvb, offset+4, 8))); proto_tree_add_item (tree, hf_fcfzs_mbrid_lun, tvb, offset+8, 8, 0); 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, 0); break; case FC_FZS_ZONEMBR_FCID_LUN: proto_tree_add_string (tree, hf_fcfzs_mbrid, tvb, offset+4, 4, fc_to_str (tvb_get_ptr (tvb, offset+4, 3))); proto_tree_add_item (tree, hf_fcfzs_mbrid_lun, tvb, offset+4, 8, 0); break; default: proto_tree_add_string (tree, hf_fcfzs_mbrid, tvb, offset+4, 8, "Unknown member type format"); } offset += 12; } } } }