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_fcfcs_gmid (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_mgmtid, tvb, offset+1, 3, fc_to_str (tvb_get_ptr (tvb, offset+1, 3))); } } }
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; } } } }