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;
            }
        }
    }
}
Beispiel #2
0
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));
        }
    }
}
Beispiel #6
0
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));
        }
    }
}
Beispiel #8
0
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);
        }
    }
}
Beispiel #13
0
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;
            }
        }
    }
}
Beispiel #19
0
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;
            }
        }
    }
}