Ejemplo n.º 1
0
static void
dissect_ripng(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
    int offset = 0;
    proto_tree *ripng_tree = NULL, *rte_tree = NULL;
    proto_item *ti, *rte_ti;

    col_set_str(pinfo->cinfo, COL_PROTOCOL, "RIPng");
    if (check_col(pinfo->cinfo, COL_INFO)) {
	col_clear(pinfo->cinfo, COL_INFO);
	col_add_fstr(pinfo->cinfo, COL_INFO," Command %s, Version %u",
		     val_to_str(tvb_get_guint8(tvb, offset), cmdvals, "Unknown (%u)"),
		     tvb_get_guint8(tvb, offset +1));
    }

    if (tree) {
	ti = proto_tree_add_item(tree, proto_ripng, tvb, offset, -1, FALSE);
	ripng_tree = proto_item_add_subtree(ti, ett_ripng);

	/* Command */
	proto_tree_add_item(ripng_tree, hf_ripng_cmd, tvb, offset, 1, FALSE);
	offset += 1;

	/* Version */
	proto_tree_add_item(ripng_tree, hf_ripng_version, tvb, offset, 1, FALSE);
	offset += 1;

	/* Reserved */
	proto_tree_add_item(ripng_tree, hf_ripng_reserved, tvb, offset, 2, FALSE);
	offset += 2;

	/* Route Table Entry */
	while (tvb_reported_length_remaining(tvb, offset) > 0) {

		rte_ti = proto_tree_add_item(ripng_tree, hf_ripng_rte, tvb, offset, 16 + 2 + 1 + 1, FALSE);
		rte_tree = proto_item_add_subtree(rte_ti, ett_ripng_rte);

		/* IPv6 Prefix */
		proto_tree_add_item(rte_tree, hf_ripng_rte_ipv6_prefix, tvb, offset, 16, FALSE);
		proto_item_append_text(rte_ti, ": IPv6 Prefix: %s", tvb_ip6_to_str(tvb, offset));
		offset += 16;

		/* Route Tag */
		proto_tree_add_item(rte_tree, hf_ripng_rte_route_tag, tvb, offset, 2, FALSE);
		offset += 2;

		/* Prefix Length */
		proto_tree_add_item(rte_tree, hf_ripng_rte_prefix_length, tvb, offset, 1, FALSE);
		proto_item_append_text(rte_ti, "/%u", tvb_get_guint8(tvb, offset));
		offset += 1;

		/* Metric */
		proto_tree_add_item(rte_tree, hf_ripng_rte_metric, tvb, offset, 1, FALSE);
		proto_item_append_text(rte_ti, " Metric: %u", tvb_get_guint8(tvb, offset));
		offset += 1;
	}
    }
}
Ejemplo n.º 2
0
static proto_item *
decode_ip_element(nsip_ip_element_info_t *element, build_info_t *bi, proto_tree * element_tree) {
  guint16 udp_port;
  proto_item *tf;
  proto_tree *field_tree;

  field_tree = proto_tree_add_subtree(element_tree, bi->tvb, bi->offset,
                             element->total_length, ett_nsip_ip_element, &tf, "IP Element");
  if (bi->nsip_tree) {

    /* IP address */
    switch (element->version) {
    case NSIP_IP_VERSION_4:
      proto_tree_add_item(field_tree, hf_nsip_ip_address_ipv4,
                          bi->tvb, bi->offset, element->address_length,
                          ENC_BIG_ENDIAN);
      proto_item_append_text(tf, ": IP address: %s",
                             tvb_ip_to_str(bi->tvb, bi->offset));

      break;
    case NSIP_IP_VERSION_6:
      proto_tree_add_item(field_tree, hf_nsip_ip_address_ipv6, bi->tvb,
                          bi->offset, element->address_length,
                          ENC_NA);
      proto_item_append_text(tf, ": IP address: %s",
                             tvb_ip6_to_str(bi->tvb, bi->offset));
      break;
    default:
      ;
    }
  }
  bi->offset += element->address_length;

  if (bi->nsip_tree) {
    /* UDP port value */
    udp_port = tvb_get_ntohs(bi->tvb, bi->offset);
    proto_tree_add_item(field_tree, hf_nsip_ip_element_udp_port,
                               bi->tvb, bi->offset, 2, ENC_BIG_ENDIAN);
    proto_item_append_text(tf, ", UDP Port: %u", udp_port);
  }
  bi->offset += 2;

  if (bi->nsip_tree) {
    /* Signalling weight */
    proto_tree_add_item(field_tree, hf_nsip_ip_element_signalling_weight,
                        bi->tvb, bi->offset, 1, ENC_BIG_ENDIAN);
  }
  bi->offset++;

  if (bi->nsip_tree) {
    /* Data weight */
    proto_tree_add_item(field_tree, hf_nsip_ip_element_data_weight,
                        bi->tvb, bi->offset, 1, ENC_BIG_ENDIAN);
  }
  bi->offset++;
  return tf;
}
Ejemplo n.º 3
0
static void
dissect_sap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    int offset = 0;
    int sap_version, is_ipv6, is_del, is_enc, is_comp, addr_len;
    guint8 vers_flags;
    guint8 auth_len;
    guint16 tmp1;
    guint8 auth_flags;
    tvbuff_t *next_tvb;

    proto_item *si, *sif;
    proto_tree *sap_tree, *sap_flags_tree;

    col_set_str(pinfo->cinfo, COL_PROTOCOL, "SAP");
    col_clear(pinfo->cinfo, COL_INFO);

    vers_flags = tvb_get_guint8(tvb, offset);
    is_ipv6 = vers_flags&MCAST_SAP_BIT_A;
    is_del = vers_flags&MCAST_SAP_BIT_T;
    is_enc = vers_flags&MCAST_SAP_BIT_E;
    is_comp = vers_flags&MCAST_SAP_BIT_C;

    sap_version = (vers_flags&MCAST_SAP_VERSION_MASK)>>MCAST_SAP_VERSION_SHIFT;
    addr_len = (is_ipv6) ? sizeof(struct e_in6_addr) : 4;

    if (check_col(pinfo->cinfo, COL_INFO)) {
        col_add_fstr(pinfo->cinfo, COL_INFO, "%s (v%u)",
                     (is_del) ? "Deletion" : "Announcement", sap_version);
    }

    if (tree) {
        si = proto_tree_add_item(tree, proto_sap, tvb, offset, -1, ENC_NA);
        sap_tree = proto_item_add_subtree(si, ett_sap);

        sif = proto_tree_add_uint(sap_tree, hf_sap_flags, tvb, offset, 1, vers_flags);
        sap_flags_tree = proto_item_add_subtree(sif, ett_sap_flags);
        proto_tree_add_uint(sap_flags_tree, hf_sap_flags_v, tvb, offset, 1, vers_flags);
        proto_tree_add_boolean(sap_flags_tree, hf_sap_flags_a, tvb, offset, 1, vers_flags);
        proto_tree_add_boolean(sap_flags_tree, hf_sap_flags_r, tvb, offset, 1, vers_flags);
        proto_tree_add_boolean(sap_flags_tree, hf_sap_flags_t, tvb, offset, 1, vers_flags);
        proto_tree_add_boolean(sap_flags_tree, hf_sap_flags_e, tvb, offset, 1, vers_flags);
        proto_tree_add_boolean(sap_flags_tree, hf_sap_flags_c, tvb, offset, 1, vers_flags);
        offset++;

        auth_len = tvb_get_guint8(tvb, offset);
        proto_tree_add_text(sap_tree, tvb, offset, 1, "Authentication Length: %u", auth_len);
        offset++;

        tmp1 = tvb_get_ntohs(tvb, offset);
        proto_tree_add_text(sap_tree, tvb, offset, 2, "Message Identifier Hash: 0x%x", tmp1);
        offset +=2;

        proto_tree_add_text(sap_tree, tvb, offset, addr_len, "Originating Source: %s",
                            (is_ipv6) ? tvb_ip6_to_str(tvb, offset) : tvb_ip_to_str(tvb, offset));
        offset += addr_len;

        /* Authentication data lives in its own subtree */
        if (auth_len > 0) {
            guint32 auth_data_len;
            proto_item *sdi, *sai;
            proto_tree *sa_tree, *saf_tree;
            int has_pad;
            guint8 pad_len = 0;

            auth_data_len = auth_len * sizeof(guint32);

            sdi = proto_tree_add_item(sap_tree, hf_auth_data, tvb, offset, auth_data_len, ENC_NA);
            sa_tree = proto_item_add_subtree(sdi, ett_sap_auth);

            auth_flags = tvb_get_guint8(tvb, offset);
            sai = proto_tree_add_uint(sa_tree, hf_auth_flags, tvb, offset, 1, auth_flags);
            saf_tree = proto_item_add_subtree(sai, ett_sap_authf);
            proto_tree_add_uint(saf_tree, hf_auth_flags_v, tvb, offset, 1, auth_flags);
            proto_tree_add_boolean(saf_tree, hf_auth_flags_p, tvb, offset, 1, auth_flags);
            proto_tree_add_uint(saf_tree, hf_auth_flags_t, tvb, offset, 1, auth_flags);

            has_pad = auth_flags&MCAST_SAP_AUTH_BIT_P;
            if (has_pad)
                pad_len = tvb_get_guint8(tvb, offset+auth_data_len-1);

            if ((int) auth_data_len - pad_len - 1 < 0) {
                proto_tree_add_text(sa_tree, tvb, 0, 0,
                                    "Bogus authentication length (%d) or pad length (%d)",
                                    auth_len, pad_len);
                return;
            }


            proto_tree_add_text(sa_tree, tvb, offset+1, auth_data_len-pad_len-1,
                                "Authentication subheader: (%u byte%s)",
                                auth_data_len-1, plurality(auth_data_len-1, "", "s"));
            if (has_pad) {
                proto_tree_add_text(sa_tree, tvb, offset+auth_data_len-pad_len, pad_len,
                                    "Authentication data padding: (%u byte%s)",
                                    pad_len, plurality(pad_len, "", "s"));
                proto_tree_add_text(sa_tree, tvb, offset+auth_data_len-1, 1,
                                    "Authentication data pad count: %u byte%s",
                                    pad_len, plurality(pad_len, "", "s"));
            }

            offset += auth_data_len;
        }
        if (is_enc || is_comp) {
            const char *mangle;
            if (is_enc && is_comp) mangle = "compressed and encrypted";
            else if (is_enc) mangle = "encrypted";
            else mangle = "compressed";
            proto_tree_add_text(sap_tree, tvb, offset, -1,
                                "The rest of the packet is %s", mangle);
            return;
        }

        /* Do we have the optional payload type aka. MIME content specifier */
        if (tvb_strneql(tvb, offset, "v=", strlen("v="))) {
            gint remaining_len;
            guint32 pt_len;
            int pt_string_len;

            remaining_len = tvb_length_remaining(tvb, offset);
            if (remaining_len == 0) {
                /*
                 * "tvb_strneql()" failed because there was no
                * data left in the packet.
                *
                * Set the remaining length to 1, so that
                * we throw the appropriate exception in
                * "tvb_get_ptr()", rather than displaying
                * the payload type.
                */
                remaining_len = 1;
            }
            pt_string_len = tvb_strnlen(tvb, offset, remaining_len);
            if (pt_string_len == -1) {
                /*
                 * We didn't find a terminating '\0'; run to the
                 * end of the buffer.
                 */
                pt_string_len = remaining_len;
                pt_len = pt_string_len;
            } else {
                /*
                 * Include the '\0' in the total item length.
                 */
                pt_len = pt_string_len + 1;
            }
            proto_tree_add_text(sap_tree, tvb, offset, pt_len,
                                "Payload type: %.*s", pt_string_len,
                                tvb_get_ephemeral_string(tvb, offset, pt_string_len));
            offset += pt_len;
        }
    }

    /* Done with SAP */
    next_tvb = tvb_new_subset_remaining(tvb, offset);
    call_dissector(sdp_handle, next_tvb, pinfo, tree);

    return;
}
Ejemplo n.º 4
0
/*
 * For PIM v2, see RFC 4601, RFC 3973 and draft-ietf-pim-sm-v2-new-03
 * (when PIM is run over IPv6, the rules for computing the PIM checksum
 * from the draft in question, not from RFC 2362, should be used).
 */
static void
dissect_pim(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
    int offset = 0;
    guint8 pim_typever;
    guint length, pim_length;
    guint16 pim_cksum, computed_cksum;
    vec_t cksum_vec[4];
    guint32 phdr[2];
    const char *typestr;
    proto_tree *pim_tree = NULL;
    proto_item *ti;
    proto_tree *pimopt_tree = NULL;
    proto_item *tiopt;

    col_set_str(pinfo->cinfo, COL_PROTOCOL, "PIM");
    col_clear(pinfo->cinfo, COL_INFO);

    pim_typever = tvb_get_guint8(tvb, 0);

    switch (PIM_VER(pim_typever)) {
    case 2:
        typestr = val_to_str(PIM_TYPE(pim_typever), type2vals, "Unknown (%u)");
        break;
    case 1:     /* PIMv1 - we should never see this */
    default:
        typestr = "Unknown";
        break;
    }

    if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
        col_add_fstr(pinfo->cinfo, COL_PROTOCOL, "PIMv%d",
                     PIM_VER(pim_typever));
    }
    if (check_col(pinfo->cinfo, COL_INFO))
        col_add_str(pinfo->cinfo, COL_INFO, typestr);

    ti = proto_tree_add_item(tree, proto_pim, tvb, offset, -1, ENC_NA);
    pim_tree = proto_item_add_subtree(ti, ett_pim);

    proto_tree_add_item(pim_tree, hf_pim_version, tvb, offset, 1, ENC_BIG_ENDIAN);
    proto_tree_add_item(pim_tree, hf_pim_type, tvb, offset, 1, ENC_BIG_ENDIAN);
    proto_tree_add_item(pim_tree, hf_pim_res_bytes, tvb, offset + 1, 1, ENC_NA);
    pim_cksum = tvb_get_ntohs(tvb, offset + 2);
    length = tvb_length(tvb);
    if (PIM_VER(pim_typever) == 2) {
        /*
         * Well, it's PIM v2, so we can check whether this is a Register
         * message, and thus can figure out how much to checksum and
         * whether to make the columns read-only.
         */
        if (PIM_TYPE(pim_typever) == 1) {
            /*
             * Register message - the PIM header is 8 bytes long.
             * Also set the columns non-writable. Otherwise the IPv4 or
             * IPv6 dissector for the encapsulated packet that caused
             * this register will overwrite the PIM info in the columns.
             */
            pim_length = 8;
            col_set_writable(pinfo->cinfo, FALSE);
        } else {
            /*
             * Other message - checksum the entire packet.
             */
            pim_length = tvb_reported_length(tvb);
        }
    } else {
        /*
         * We don't know what type of message this is, so say that
         * the length is 0, to force it not to be checksummed.
         */
        pim_length = 0;
    }
    if (!pinfo->fragmented && length >= pim_length) {
        /*
         * The packet isn't part of a fragmented datagram and isn't
         * truncated, so we can checksum it.
         */

        switch (pinfo->src.type) {
        case AT_IPv4:
            cksum_vec[0].ptr = tvb_get_ptr(tvb, 0, pim_length);
            cksum_vec[0].len = pim_length;
            computed_cksum = in_cksum(&cksum_vec[0], 1);
            break;
        case AT_IPv6:
            /* Set up the fields of the pseudo-header. */
            cksum_vec[0].ptr = pinfo->src.data;
            cksum_vec[0].len = pinfo->src.len;
            cksum_vec[1].ptr = pinfo->dst.data;
            cksum_vec[1].len = pinfo->dst.len;
            cksum_vec[2].ptr = (const guint8 *)&phdr;
            phdr[0] = g_htonl(pim_length);
            phdr[1] = g_htonl(IP_PROTO_PIM);
            cksum_vec[2].len = 8;
            cksum_vec[3].ptr = tvb_get_ptr(tvb, 0, pim_length);
            cksum_vec[3].len = pim_length;
            computed_cksum = in_cksum(&cksum_vec[0], 4);
            break;
        default:
            /* PIM is available for IPv4 and IPv6 right now */
            computed_cksum = 0; /* squelch GCC complaints */
            DISSECTOR_ASSERT_NOT_REACHED();
            break;
        }

        if (computed_cksum == 0) {
            proto_tree_add_uint_format(pim_tree, hf_pim_cksum, tvb,
                                       offset + 2, 2, pim_cksum,
                                       "Checksum: 0x%04x [correct]",
                                       pim_cksum);
        } else {
            proto_tree_add_uint_format(pim_tree, hf_pim_cksum, tvb,
                                       offset + 2, 2, pim_cksum,
                                       "Checksum: 0x%04x [incorrect, should be 0x%04x]",
                                       pim_cksum, in_cksum_shouldbe(pim_cksum, computed_cksum));
        }
    } else {
        proto_tree_add_uint(pim_tree, hf_pim_cksum, tvb,
                            offset + 2, 2, pim_cksum);
    }

    offset += 4;

    if (tvb_reported_length_remaining(tvb, offset) > 0) {
        tiopt = proto_tree_add_text(pim_tree, tvb, offset, -1, "PIM options");
        pimopt_tree = proto_item_add_subtree(tiopt, ett_pim_opts);
    } else
        goto done;

    if (PIM_VER(pim_typever) != 2)
        goto done;

    /* version 2 decoder */
    switch (PIM_TYPE(pim_typever)) {
    case 0:     /*hello*/
    {
        int opt_count = 0;

        while (tvb_reported_length_remaining(tvb, offset) >= 2) {
            guint16 hello_opt, opt_len;
            guint16 opt_value;
            proto_item *opt_item;
            proto_tree *opt_tree;

            opt_count++;
            hello_opt = tvb_get_ntohs(tvb, offset);
            opt_len = tvb_get_ntohs(tvb, offset + 2);
            opt_item = proto_tree_add_text(pimopt_tree, tvb, offset, 4 + opt_len,
                                           "Option %u: %s", hello_opt,
                                           val_to_str(hello_opt, pim_opt_vals, "Unknown: %u"));
            opt_tree = proto_item_add_subtree(opt_item, ett_pim_opt);
            proto_tree_add_item(opt_tree, hf_pim_optiontype, tvb, offset, 2, ENC_BIG_ENDIAN);
            proto_tree_add_item(opt_tree, hf_pim_optionlength, tvb, offset + 2, 2, ENC_BIG_ENDIAN);

            switch(hello_opt) {
            case 1: /* Hello Hold Time Option */
                opt_value = tvb_get_ntohs(tvb, offset + 4);
                proto_tree_add_uint_format(opt_tree, hf_pim_holdtime, tvb,
                                           offset + 4, opt_len, opt_value,
                                           "Holdtime: %us %s", opt_value, opt_value == 0 ? "(goodbye)" :
                                           opt_value == 0xffff ? "(infinity)": "");
                proto_item_append_text(opt_item, ": %us %s", opt_value,
                                       opt_value == 0 ? "(goodbye)" :
                                       opt_value == 0xffff ? "(infinity)": "");
                break;

            case 2: /* LAN Prune Delay Option */
                proto_tree_add_item(opt_tree, hf_pim_t, tvb, offset + 4, 1, ENC_BIG_ENDIAN);
                proto_tree_add_item(opt_tree, hf_pim_propagation_delay, tvb, offset + 4, 2, ENC_BIG_ENDIAN);
                proto_tree_add_item(opt_tree, hf_pim_override_interval, tvb, offset + 6, 2, ENC_BIG_ENDIAN);
                proto_item_append_text(opt_item,
                                       ": T = %u, Propagation Delay = %ums, Override Interval = %ums",
                                       tvb_get_guint8(tvb, offset + 4) & 0x80 ? 1 : 0,
                                       tvb_get_ntohs(tvb, offset + 4) & 0x7fff,
                                       tvb_get_ntohs(tvb, offset + 6));
                break;

            case 19: /* DR priority */
                proto_tree_add_item(opt_tree, hf_pim_dr_priority, tvb, offset + 4, 4, ENC_BIG_ENDIAN);
                proto_item_append_text(opt_item, ": %u", tvb_get_ntohl(tvb, offset + 4));
                break;

            case 20: /* Generation ID */
                proto_tree_add_item(opt_tree, hf_pim_generation_id, tvb, offset + 4, 4, ENC_BIG_ENDIAN);
                proto_item_append_text(opt_item, ": %u", tvb_get_ntohl(tvb, offset + 4));
                break;

            case 21: /* State Refresh Capable Option */
                proto_tree_add_item(opt_tree, hf_pim_state_refresh_version, tvb, offset + 4, 1, ENC_BIG_ENDIAN);
                proto_tree_add_item(opt_tree, hf_pim_state_refresh_interval, tvb, offset + 5, 1, ENC_BIG_ENDIAN);
                proto_tree_add_item(opt_tree, hf_pim_state_refresh_reserved, tvb, offset + 6, 2, ENC_BIG_ENDIAN);
                proto_item_append_text(opt_item, ": Version = %u, Interval = %us",
                                       tvb_get_guint8(tvb, offset + 4),
                                       tvb_get_guint8(tvb, offset + 5));
                break;

            case 24: /* address list */
            case 65001: /* address list (old implementations) */
            {
                int i;
                proto_tree *sub_tree = NULL;
                proto_item *addrlist_option;

                addrlist_option = proto_tree_add_text(opt_tree, tvb, offset, 4 + opt_len,
                                                      "%sAddress List (%u)",
                                                      hello_opt == 65001 ? "old " : "",
                                                      hello_opt);
                sub_tree = proto_item_add_subtree(addrlist_option, ett_pim_opt);
                for (i = offset + 4; i < offset + 4 + opt_len; ) {
                    int advance;
                    const char *s;

                    s = dissect_pim_addr(tvb, i, pimv2_unicast, &advance);
                    if (s == NULL)
                        break;
                    proto_tree_add_text(sub_tree, tvb, offset,
                                        advance, "Address: %s", s);
                    i += advance;
                }
                break;
            }

            default:
                if (opt_len)
                    proto_tree_add_item(opt_tree, hf_pim_optionvalue, tvb,
                                        offset + 4, opt_len, ENC_NA);
                break;
            }
            offset += 4 + opt_len;
        }
        proto_item_append_text(tiopt, ": %u", opt_count);
        break;
    }

    case 1:     /* register */
    {
        guint32 flags;
        guint8 v_hl;
        tvbuff_t *next_tvb;
        proto_tree *flag_tree = NULL;
        proto_item *tiflag;

        flags = tvb_get_ntohl(tvb, offset);
        tiflag = proto_tree_add_text(pimopt_tree, tvb, offset, 4,
                                     "Flags: 0x%08x", flags);
        flag_tree = proto_item_add_subtree(tiflag, ett_pim);
        proto_tree_add_text(flag_tree, tvb, offset, 1, "%s",
                            decode_boolean_bitfield(flags, 0x80000000, 32,
                                                    "Border", "Not border"));
        proto_tree_add_text(flag_tree, tvb, offset, 1, "%s",
                            decode_boolean_bitfield(flags, 0x40000000, 32,
                                                    "Null-Register", "Not Null-Register"));
        offset += 4;

        /*
         * The rest of the packet is a multicast data packet.
         */
        next_tvb = tvb_new_subset_remaining(tvb, offset);

        /*
         * It's an IP packet - determine whether it's IPv4 or IPv6.
         */
        v_hl = tvb_get_guint8(tvb, offset);
        switch((v_hl & 0xf0) >> 4) {
        case 0:     /* Null-Register dummy header.
                     * Has the same address family as the encapsulating PIM packet,
                     * e.g. an IPv6 data packet is encapsulated in IPv6 PIM packet.
                     */
            if (pinfo->src.type == AT_IPv4) {
                proto_tree_add_text(pimopt_tree, tvb, offset, -1,
                                    "IPv4 dummy header");
                proto_tree_add_text(pimopt_tree, tvb, offset + 12, 4,
                                    "Source: %s",
                                    tvb_ip_to_str(tvb, offset + 12));
                proto_tree_add_text(pimopt_tree, tvb, offset + 16, 4,
                                    "Group: %s",
                                    tvb_ip_to_str(tvb, offset + 16));
            } else if (pinfo->src.type == AT_IPv6) {
                proto_tree_add_text(pimopt_tree, tvb, offset, -1,
                                    "IPv6 dummy header");
                proto_tree_add_text(pimopt_tree, tvb,
                                    offset + 8, 16,
                                    "Source: %s",
                                    tvb_ip6_to_str(tvb, offset + 8));
                proto_tree_add_text(pimopt_tree, tvb,
                                    offset + 8 + 16, 16,
                                    "Group: %s",
                                    tvb_ip6_to_str(tvb, offset + 8 + 16));
            } else
                proto_tree_add_text(pimopt_tree, tvb, offset, -1,
                                    "Dummy header for an unknown protocol");
            break;
        case 4: /* IPv4 */
#if 0
            call_dissector(ip_handle, next_tvb, pinfo, tree);
#else
            call_dissector(ip_handle, next_tvb, pinfo, pimopt_tree);
#endif
            break;
        case 6: /* IPv6 */
#if 0
            call_dissector(ipv6_handle, next_tvb, pinfo, tree);
#else
            call_dissector(ipv6_handle, next_tvb, pinfo, pimopt_tree);
#endif
            break;
        default:
            proto_tree_add_text(pimopt_tree, tvb, offset, -1,
                                "Unknown IP version %d", (v_hl & 0xf0) >> 4);
            break;
        }
        break;
    }

    case 2:     /* register-stop */
    {
        int advance;
        const char *s;

        s = dissect_pim_addr(tvb, offset, pimv2_group, &advance);
        if (s == NULL)
            break;
        proto_tree_add_text(pimopt_tree, tvb, offset, advance, "Group: %s", s);
        offset += advance;
        s = dissect_pim_addr(tvb, offset, pimv2_unicast, &advance);
        if (s == NULL)
            break;
        proto_tree_add_text(pimopt_tree, tvb, offset, advance, "Source: %s", s);
        break;
    }

    case 3:     /* join/prune */
    case 6:     /* graft */
    case 7:     /* graft-ack */
    {
        int advance;
        int off;
        const char *s;
        int ngroup, i, njoin, nprune, j;
        guint16 holdtime;
        proto_tree *grouptree = NULL;
        proto_item *tigroup;
        proto_tree *subtree = NULL;
        proto_item *tisub;

        s = dissect_pim_addr(tvb, offset, pimv2_unicast, &advance);
        if (s == NULL)
            break;
        proto_tree_add_text(pimopt_tree, tvb, offset, advance,
                            "Upstream-neighbor: %s", s);
        offset += advance;

        proto_tree_add_item(pimopt_tree, hf_pim_res_bytes, tvb, offset, 1, ENC_NA);
        offset += 1;    /* skip reserved field */

        ngroup = tvb_get_guint8(tvb, offset);
        proto_tree_add_item(pimopt_tree, hf_pim_numgroups, tvb, offset, 1, ENC_BIG_ENDIAN);
        offset += 1;

        holdtime = tvb_get_ntohs(tvb, offset);
        proto_tree_add_uint_format(pimopt_tree, hf_pim_holdtime, tvb,
                                   offset, 2, holdtime,
                                   "Holdtime: %us %s", holdtime,
                                   holdtime == 0xffff ? "(infinity)": "");
        offset += 2;

        for (i = 0; i < ngroup; i++) {
            s = dissect_pim_addr(tvb, offset, pimv2_group, &advance);
            if (s == NULL)
                goto breakbreak3;
            tigroup = proto_tree_add_text(pimopt_tree, tvb, offset, advance,
                                          "Group %d: %s", i, s);
            grouptree = proto_item_add_subtree(tigroup, ett_pim);
            offset += advance;

            njoin = tvb_get_ntohs(tvb, offset);
            nprune = tvb_get_ntohs(tvb, offset + 2);
            tisub = proto_tree_add_item(grouptree, hf_pim_numjoins, tvb,
                                        offset, 2, ENC_BIG_ENDIAN);
            subtree = proto_item_add_subtree(tisub, ett_pim);
            off = offset + 4;
            for (j = 0; j < njoin; j++) {
                s = dissect_pim_addr(tvb, off, pimv2_source, &advance);
                if (s == NULL)
                    goto breakbreak3;
                proto_tree_add_text(subtree, tvb, off, advance,
                                    "IP address: %s", s);
                off += advance;
            }

            tisub = proto_tree_add_item(grouptree, hf_pim_numprunes, tvb,
                                        offset + 2, 2, ENC_BIG_ENDIAN);
            subtree = proto_item_add_subtree(tisub, ett_pim);
            for (j = 0; j < nprune; j++) {
                s = dissect_pim_addr(tvb, off, pimv2_source, &advance);
                if (s == NULL)
                    goto breakbreak3;
                proto_tree_add_text(subtree, tvb, off, advance,
                                    "IP address: %s", s);
                off += advance;
            }
            offset = off;
        }
    breakbreak3:
        break;
    }

    case 4:     /* bootstrap */
    {
        const char *s;
        int advance;
        int i, j;
        int frpcnt;
        guint16 holdtime;
        proto_tree *grouptree = NULL;
        proto_item *tigroup;

        proto_tree_add_text(pimopt_tree, tvb, offset, 2,
                            "Fragment tag: 0x%04x", tvb_get_ntohs(tvb, offset));
        offset += 2;

        proto_tree_add_text(pimopt_tree, tvb, offset, 1,
                            "Hash mask len: %u", tvb_get_guint8(tvb, offset));
        offset += 1;
        proto_tree_add_text(pimopt_tree, tvb, offset, 1,
                            "BSR priority: %u", tvb_get_guint8(tvb, offset));
        offset += 1;

        s = dissect_pim_addr(tvb, offset, pimv2_unicast, &advance);
        if (s == NULL)
            break;
        proto_tree_add_text(pimopt_tree, tvb, offset, advance, "BSR: %s", s);
        offset += advance;

        for (i = 0; tvb_reported_length_remaining(tvb, offset) > 0; i++) {
            s = dissect_pim_addr(tvb, offset, pimv2_group, &advance);
            if (s == NULL)
                goto breakbreak4;
            tigroup = proto_tree_add_text(pimopt_tree, tvb, offset, advance,
                                          "Group %d: %s", i, s);
            grouptree = proto_item_add_subtree(tigroup, ett_pim);
            offset += advance;

            proto_tree_add_text(grouptree, tvb, offset, 1,
                                "RP count: %u", tvb_get_guint8(tvb, offset));
            offset += 1;
            frpcnt = tvb_get_guint8(tvb, offset);
            proto_tree_add_text(grouptree, tvb, offset, 1,
                                "FRP count: %u", frpcnt);
            offset += 3;

            for (j = 0; j < frpcnt; j++) {
                s = dissect_pim_addr(tvb, offset, pimv2_unicast, &advance);
                if (s == NULL)
                    goto breakbreak4;
                proto_tree_add_text(grouptree, tvb, offset, advance,
                                    "RP %d: %s", j, s);
                offset += advance;

                holdtime = tvb_get_ntohs(tvb, offset);
                proto_tree_add_uint_format(grouptree, hf_pim_holdtime, tvb,
                                   offset, 2, holdtime,
                                   "Holdtime: %us %s", holdtime,
                                   holdtime == 0xffff ? "(infinity)": "");
                offset += 2;
                proto_tree_add_text(grouptree, tvb, offset, 1,
                                    "Priority: %u", tvb_get_guint8(tvb, offset));
                offset += 2;    /* also skips reserved field */
            }
        }

    breakbreak4:
        break;
    }

    case 5:     /* assert */
    {
        const char *s;
        int advance;
        guint32 pref;

        s = dissect_pim_addr(tvb, offset, pimv2_group, &advance);
        if (s == NULL)
            break;
        proto_tree_add_text(pimopt_tree, tvb, offset, advance, "Group: %s", s);
        offset += advance;

        s = dissect_pim_addr(tvb, offset, pimv2_unicast, &advance);
        if (s == NULL)
            break;
        proto_tree_add_text(pimopt_tree, tvb, offset, advance, "Source: %s", s);
        offset += advance;

        proto_tree_add_item(pimopt_tree, hf_pim_rpt, tvb, offset, 1, ENC_BIG_ENDIAN);
        pref = tvb_get_ntohl(tvb, offset) & 0x7fffffff;
        proto_tree_add_uint_format(pimopt_tree, hf_pim_metric_pref, tvb,
                                   offset, 4, pref,
                                   "Metric Preference: %u", pref);
        offset += 4;

        proto_tree_add_item(pimopt_tree, hf_pim_metric, tvb, offset, 4, ENC_BIG_ENDIAN);
        offset += 4;
        break;
    }

    case 8:     /* Candidate-RP-Advertisement */
    {
        const char *s;
        int advance;
        int pfxcnt;
        guint16 holdtime;
        int i;

        pfxcnt = tvb_get_guint8(tvb, offset);
        proto_tree_add_text(pimopt_tree, tvb, offset, 1,
                            "Prefix-count: %u", pfxcnt);
        offset += 1;
        proto_tree_add_text(pimopt_tree, tvb, offset, 1,
                            "Priority: %u", tvb_get_guint8(tvb, offset));
        offset += 1;
        holdtime = tvb_get_ntohs(tvb, offset);
        proto_tree_add_uint_format(pimopt_tree, hf_pim_holdtime, tvb,
                                   offset, 2, holdtime,
                                   "Holdtime: %us %s", holdtime,
                                   holdtime == 0xffff ? "(infinity)": "");
        offset += 2;

        s = dissect_pim_addr(tvb, offset, pimv2_unicast, &advance);
        if (s == NULL)
            break;
        proto_tree_add_text(pimopt_tree, tvb, offset, advance, "RP: %s", s);
        offset += advance;

        for (i = 0; i < pfxcnt; i++) {
            s = dissect_pim_addr(tvb, offset, pimv2_group, &advance);
            if (s == NULL)
                goto breakbreak8;
            proto_tree_add_text(pimopt_tree, tvb, offset, advance,
                                "Group %d: %s", i, s);
            offset += advance;
        }
    breakbreak8:
        break;
    }

    case 9:     /* State-Refresh */
    {
        const char *s;
        int advance;
        guint32 pref;

        s = dissect_pim_addr(tvb, offset, pimv2_group, &advance);
        if (s == NULL)
            break;
        proto_tree_add_text(pimopt_tree, tvb, offset, advance,
                            "Group: %s", s);
        offset += advance;

        s = dissect_pim_addr(tvb, offset, pimv2_unicast, &advance);
        if (s == NULL)
            break;
        proto_tree_add_text(pimopt_tree, tvb, offset, advance,
                            "Source: %s", s);
        offset += advance;

        s = dissect_pim_addr(tvb, offset, pimv2_unicast, &advance);
        if (s == NULL)
            break;
        proto_tree_add_text(pimopt_tree, tvb, offset, advance,
                            "Originator: %s", s);
        offset += advance;

        proto_tree_add_item(pimopt_tree, hf_pim_rpt, tvb, offset, 1, ENC_BIG_ENDIAN);
        pref = tvb_get_ntohl(tvb, offset) & 0x7fffffff;
        proto_tree_add_uint_format(pimopt_tree, hf_pim_metric_pref, tvb,
                                   offset, 4, pref,
                                   "Metric Preference: %u", pref);
        offset += 4;

        proto_tree_add_item(pimopt_tree, hf_pim_metric, tvb, offset, 4, ENC_BIG_ENDIAN);
        offset += 4;

        proto_tree_add_text(pimopt_tree, tvb, offset, 1,
                            "Masklen: %u", tvb_get_guint8(tvb, offset));
        offset += 1;

        proto_tree_add_text(pimopt_tree, tvb, offset, 1,
                            "TTL: %u", tvb_get_guint8(tvb, offset));
        offset += 1;

        proto_tree_add_text(pimopt_tree, tvb, offset, 1, "Prune indicator %s",
                            decode_boolean_bitfield(tvb_get_guint8(tvb, offset), 0x80, 8,
                                                    "set", "clear"));
        proto_tree_add_text(pimopt_tree, tvb, offset, 1, "Prune now %s",
                            decode_boolean_bitfield(tvb_get_guint8(tvb, offset), 0x40, 8,
                                                    "set", "clear"));
        proto_tree_add_text(pimopt_tree, tvb, offset, 1, "Assert override %s",
                            decode_boolean_bitfield(tvb_get_guint8(tvb, offset), 0x20, 8,
                                                    "set", "clear"));
        offset += 1;

        proto_tree_add_text(pimopt_tree, tvb, offset, 1,
                            "Interval: %u", tvb_get_guint8(tvb, offset));
        offset += 1;

        break;
    }

    default:
        break;
    }
done:;
}
Ejemplo n.º 5
0
static const char *
dissect_pim_addr(tvbuff_t *tvb, int offset, enum pimv2_addrtype at,
                 int *advance) {
    emem_strbuf_t *strbuf;
    guint8 af;
    guint8 et;
    guint8 flags;
    guint8 mask_len;
    int len = 0;

    af = tvb_get_guint8(tvb, offset);
    if (af != AFNUM_INET && af != AFNUM_INET6) {
        /*
         * We don't handle the other formats, and addresses don't include
         * a length field, so we can't even show them as raw bytes.
         */
        return NULL;
    }

    et = tvb_get_guint8(tvb, offset + 1);
    if (et != 0) {
        /*
         * The only defined encoding type is 0, for the native encoding;
         * again, as addresses don't include a length field, we can't
         * even show addresses with a different encoding type as raw
         * bytes.
         */
        return NULL;
    }

    strbuf = ep_strbuf_new_label(NULL);
    switch (at) {
    case pimv2_unicast:
        switch (af) {
        case AFNUM_INET:
            len = 4;
            ep_strbuf_printf(strbuf, "%s", tvb_ip_to_str(tvb, offset + 2));
            break;

        case AFNUM_INET6:
            len = 16;
            ep_strbuf_printf(strbuf, "%s", tvb_ip6_to_str(tvb, offset + 2));
            break;
        }
        if (advance)
            *advance = 2 + len;
        break;

    case pimv2_group:
        mask_len = tvb_get_guint8(tvb, offset + 3);
        switch (af) {
        case AFNUM_INET:
            len = 4;
            ep_strbuf_printf(strbuf, "%s/%u",
                             tvb_ip_to_str(tvb, offset + 4), mask_len);
            break;

        case AFNUM_INET6:
            len = 16;
            ep_strbuf_printf(strbuf, "%s/%u",
                             tvb_ip6_to_str(tvb, offset + 4), mask_len);
            break;
        }
        if (advance)
            *advance = 4 + len;
        break;

    case pimv2_source:
        flags = tvb_get_guint8(tvb, offset + 2);
        mask_len = tvb_get_guint8(tvb, offset + 3);
        switch (af) {
        case AFNUM_INET:
            len = 4;
            ep_strbuf_printf(strbuf, "%s/%u",
                             tvb_ip_to_str(tvb, offset + 4), mask_len);
            break;

        case AFNUM_INET6:
            len = 16;
            ep_strbuf_printf(strbuf, "%s/%u",
                             tvb_ip6_to_str(tvb, offset + 4), mask_len);
            break;
        }
        if (flags) {
            ep_strbuf_append_printf(strbuf,
                                    " (%s%s%s)",
                                    flags & 0x04 ? "S" : "",
                                    flags & 0x02 ? "W" : "",
                                    flags & 0x01 ? "R" : "");
        }
        if (advance)
            *advance = 4 + len;
        break;
    default:
        return NULL;
    }

    return strbuf->str;
}
Ejemplo n.º 6
0
/* This function is only called from the IGMP dissector */
int
dissect_pimv1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
              int offset) {
    guint8 pim_type;
    guint8 pim_ver;
    guint length, pim_length;
    guint16 pim_cksum, computed_cksum;
    vec_t cksum_vec[1];
    proto_tree *pim_tree = NULL;
    proto_item *ti;
    proto_tree *pimopt_tree = NULL;
    proto_item *tiopt;

    if (!proto_is_protocol_enabled(find_protocol_by_id(proto_pim))) {
        /*
         * We are not enabled; skip entire packet to be nice to the
         * IGMP layer (so clicking on IGMP will display the data).
         */
        return offset+tvb_length_remaining(tvb, offset);
    }

    col_set_str(pinfo->cinfo, COL_PROTOCOL, "PIMv1");
    col_clear(pinfo->cinfo, COL_INFO);

    ti = proto_tree_add_item(tree, proto_pim, tvb, offset, -1, ENC_NA);
    pim_tree = proto_item_add_subtree(ti, ett_pim);

    /* Put IGMP type, 0x14, into the tree */
    proto_tree_add_text(pim_tree, tvb, offset, 1,
                        "Type: PIM (0x14)");
    offset += 1;

    pim_type = tvb_get_guint8(tvb, offset);
    if (check_col(pinfo->cinfo, COL_INFO))
        col_add_str(pinfo->cinfo, COL_INFO,
                    val_to_str(pim_type, type1vals, "Unknown (%u)"));

    proto_tree_add_uint(pim_tree, hf_pim_code, tvb, offset, 1, pim_type);
    offset += 1;

    pim_cksum = tvb_get_ntohs(tvb, offset);
    pim_ver = PIM_VER(tvb_get_guint8(tvb, offset + 2));
    if (pim_ver != 1) {
        /*
         * Not PIMv1 - what gives?
         */
        proto_tree_add_uint(pim_tree, hf_pim_cksum, tvb,
                            offset, 2, pim_cksum);

        offset += 2;
        proto_tree_add_item(pim_tree, hf_pim_version, tvb, offset, 1, ENC_BIG_ENDIAN);
        return offset+tvb_length_remaining(tvb, offset);
    }

    /*
     * Well, it's PIM v1, so we can check whether this is a
     * Register message, and thus can figure out how much to
     * checksum and whether to make the columns read-only.
     */
    length = tvb_length(tvb);
    if (pim_type == 1) {
        /*
         * Register message - the PIM header is 8 bytes long.
         * Also set the columns non-writable. Otherwise the IPv4 or
         * IPv6 dissector for the encapsulated packet that caused
         * this register will overwrite the PIM info in the columns.
         */
        pim_length = 8;
        col_set_writable(pinfo->cinfo, FALSE);
    } else {
        /*
         * Other message - checksum the entire packet.
         */
        pim_length = tvb_reported_length(tvb);
    }

    if (!pinfo->fragmented && length >= pim_length) {
        /*
         * The packet isn't part of a fragmented datagram and isn't
         * truncated, so we can checksum it.
         */
        cksum_vec[0].ptr = tvb_get_ptr(tvb, 0, pim_length);
        cksum_vec[0].len = pim_length;
        computed_cksum = in_cksum(&cksum_vec[0], 1);
        if (computed_cksum == 0) {
            proto_tree_add_uint_format(pim_tree, hf_pim_cksum, tvb,
                                       offset, 2, pim_cksum,
                                       "Checksum: 0x%04x [correct]",
                                       pim_cksum);
        } else {
            proto_tree_add_uint_format(pim_tree, hf_pim_cksum, tvb,
                                       offset, 2, pim_cksum,
                                       "Checksum: 0x%04x [incorrect, should be 0x%04x]",
                                       pim_cksum, in_cksum_shouldbe(pim_cksum, computed_cksum));
        }
    } else {
        proto_tree_add_uint(pim_tree, hf_pim_cksum, tvb,
                            offset, 2, pim_cksum);
    }
    offset += 2;

    proto_tree_add_item(pim_tree, hf_pim_version, tvb, offset, 1, ENC_BIG_ENDIAN);
    offset += 1;

    offset += 3;        /* skip reserved stuff */

    if (tvb_reported_length_remaining(tvb, offset) > 0) {
        tiopt = proto_tree_add_text(pim_tree, tvb, offset, -1, "PIM options");
        pimopt_tree = proto_item_add_subtree(tiopt, ett_pim_opts);
    } else
        goto done;

    /* version 1 decoder */
    switch (pim_type) {
    case 0:     /* query */
    {
        guint16 holdtime;

        proto_tree_add_item(pimopt_tree, hf_pim_mode, tvb, offset, 1, ENC_BIG_ENDIAN);
        offset += 2;

        holdtime = tvb_get_ntohs(tvb, offset);
        proto_tree_add_uint_format(pimopt_tree, hf_pim_holdtime, tvb,
                                   offset, 2, holdtime,
                                   "Holdtime: %us %s", holdtime,
                                   holdtime == 0xffff ? "(infinity)": "");
        offset += 2;
        break;
    }

    case 1:     /* register */
    {
        guint8 v_hl;
        tvbuff_t *next_tvb;

        /*
         * The rest of the packet is a multicast data packet.
         */
        next_tvb = tvb_new_subset_remaining(tvb, offset);

        /*
         * It's an IP packet - determine whether it's IPv4 or IPv6.
         */
        v_hl = tvb_get_guint8(tvb, offset);
        switch((v_hl & 0xf0) >> 4) {
        case 0:     /* Null-Register dummy header.
                     * Has the same address family as the encapsulating PIM packet,
                     * e.g. an IPv6 data packet is encapsulated in IPv6 PIM packet.
                     */
            if (pinfo->src.type == AT_IPv4) {
                proto_tree_add_text(pimopt_tree, tvb, offset, -1,
                                    "IPv4 dummy header");
                proto_tree_add_text(pimopt_tree, tvb, offset + 12, 4,
                                    "Source: %s",
                                    tvb_ip_to_str(tvb, offset + 12));
                proto_tree_add_text(pimopt_tree, tvb, offset + 16, 4,
                                    "Group: %s",
                                    tvb_ip_to_str(tvb, offset + 16));
            } else if (pinfo->src.type == AT_IPv6) {
                proto_tree_add_text(pimopt_tree, tvb, offset, -1,
                                    "IPv6 dummy header");
                proto_tree_add_text(pimopt_tree, tvb,
                                    offset + 8, 16,
                                    "Source: %s",
                                    tvb_ip6_to_str(tvb, offset + 8));
                proto_tree_add_text(pimopt_tree, tvb,
                                    offset + 8 + 16, 16,
                                    "Group: %s",
                                    tvb_ip6_to_str(tvb, offset + 8));
            } else
                proto_tree_add_text(pimopt_tree, tvb, offset, -1,
                                    "Dummy header for an unknown protocol");
            break;
        case 4: /* IPv4 */
#if 0
            call_dissector(ip_handle, next_tvb, pinfo, tree);
#else
            call_dissector(ip_handle, next_tvb, pinfo, pimopt_tree);
#endif
            break;
        case 6: /* IPv6 */
#if 0
            call_dissector(ipv6_handle, next_tvb, pinfo, tree);
#else
            call_dissector(ipv6_handle, next_tvb, pinfo, pimopt_tree);
#endif
            break;
        default:
            proto_tree_add_text(pimopt_tree, tvb, offset, -1,
                                "Unknown IP version %d", (v_hl & 0xf0) >> 4);
            break;
        }
        break;
    }

    case 2:     /* register-stop */
    {
        proto_tree_add_text(pimopt_tree, tvb, offset, 4,
                            "Group: %s",
                            tvb_ip_to_str(tvb, offset));
        offset += 4;
        proto_tree_add_text(pimopt_tree, tvb, offset, 4,
                            "Source: %s",
                            tvb_ip_to_str(tvb, offset));
        offset += 4;
        break;
    }

    case 3:     /* join/prune */
    case 6:     /* graft */
    case 7:     /* graft-ack */
    {
        int off;
        const char *s;
        int ngroup, i, njoin, nprune, j;
        guint16 holdtime;
        guint8 mask_len;
        guint8 adr_len;
        proto_tree *grouptree = NULL;
        proto_item *tigroup;
        proto_tree *subtree = NULL;
        proto_item *tisub;

        proto_tree_add_text(pimopt_tree, tvb, offset, 4,
                            "Upstream-neighbor: %s",
                            tvb_ip_to_str(tvb, offset));
        offset += 4;

        offset += 2;    /* skip reserved stuff */

        holdtime = tvb_get_ntohs(tvb, offset);
        proto_tree_add_uint_format(pimopt_tree, hf_pim_holdtime, tvb,
                                   offset, 2, holdtime,
                                   "Holdtime: %us %s", holdtime,
                                   holdtime == 0xffff ? "(infinity)": "");
        offset += 2;

        offset += 1;    /* skip reserved stuff */

        mask_len = tvb_get_guint8(tvb, offset);
        proto_tree_add_text(pimopt_tree, tvb, offset, 1,
                            "Mask length: %u", mask_len);
        offset += 1;

        adr_len = tvb_get_guint8(tvb, offset);
        proto_tree_add_text(pimopt_tree, tvb, offset, 1,
                            "Address length: %u", adr_len);
        offset += 1;

        ngroup = tvb_get_guint8(tvb, offset);
        proto_tree_add_item(pimopt_tree, hf_pim_numgroups, tvb, offset, 1, ENC_BIG_ENDIAN);
        offset += 1;

        for (i = 0; i < ngroup; i++) {
            /*
             * XXX - does the group address have the length "adr_len"
             * and the group mask the length "mask_len"?
             */
            tigroup = proto_tree_add_text(pimopt_tree, tvb, offset, 4,
                                          "Group %d: %s", i,
                                          tvb_ip_to_str(tvb, offset));
            grouptree = proto_item_add_subtree(tigroup, ett_pim);
            offset += 4;

            proto_tree_add_text(grouptree, tvb, offset, 4,
                                "Group %d Mask: %s", i,
                                tvb_ip_to_str(tvb, offset));
            offset += 4;

            njoin = tvb_get_ntohs(tvb, offset);
            nprune = tvb_get_ntohs(tvb, offset + 2);
            tisub = proto_tree_add_item(grouptree, hf_pim_numjoins, tvb,
                                        offset, 2, ENC_BIG_ENDIAN);
            subtree = proto_item_add_subtree(tisub, ett_pim);
            off = offset + 4;
            for (j = 0; j < njoin; j++) {
                s = dissect_pimv1_addr(tvb, off);
                proto_tree_add_text(subtree, tvb, off, 6,
                                    "IP address: %s", s);
                off += 6;
            }

            tisub = proto_tree_add_item(grouptree, hf_pim_numprunes, tvb,
                                        offset + 2, 2, ENC_BIG_ENDIAN);
            subtree = proto_item_add_subtree(tisub, ett_pim);
            for (j = 0; j < nprune; j++) {
                s = dissect_pimv1_addr(tvb, off);
                proto_tree_add_text(subtree, tvb, off, 6,
                                    "IP address: %s", s);
                off += 6;
            }
            offset = off;
        }
        break;
    }

    case 4:     /* rp-reachability */
    {
        guint16 holdtime;

        proto_tree_add_text(pimopt_tree, tvb, offset, 4,
                            "Group Address: %s",
                            tvb_ip_to_str(tvb, offset));
        offset += 4;

        proto_tree_add_text(pimopt_tree, tvb, offset, 4,
                            "Group Mask: %s",
                            tvb_ip_to_str(tvb, offset));
        offset += 4;

        proto_tree_add_text(pimopt_tree, tvb, offset, 4,
                            "RP Address: %s",
                            tvb_ip_to_str(tvb, offset));
        offset += 4;

        offset += 2;    /* skip reserved stuff */

        holdtime = tvb_get_ntohs(tvb, offset);
        proto_tree_add_uint_format(pimopt_tree, hf_pim_holdtime, tvb,
                                   offset, 2, holdtime,
                                   "Holdtime: %us %s", holdtime,
                                   holdtime == 0xffff ? "(infinity)": "");
        offset += 2;
        break;
    }

    case 5:     /* assert */
    {
        guint32 pref;

        proto_tree_add_text(pimopt_tree, tvb, offset, 4,
                            "Group Address: %s",
                            tvb_ip_to_str(tvb, offset));
        offset += 4;

        proto_tree_add_text(pimopt_tree, tvb, offset, 4,
                            "Group Mask: %s",
                            tvb_ip_to_str(tvb, offset));
        offset += 4;

        proto_tree_add_item(pimopt_tree, hf_pim_rpt, tvb, offset, 1, ENC_BIG_ENDIAN);
        pref = tvb_get_ntohl(tvb, offset) & 0x7fffffff;
        proto_tree_add_uint_format(pimopt_tree, hf_pim_metric_pref, tvb,
                                   offset, 4, pref,
                                   "Metric Preference: %u", pref);
        offset += 4;

        proto_tree_add_item(pimopt_tree, hf_pim_metric, tvb, offset, 4, ENC_BIG_ENDIAN);
        offset += 4;
        break;
    }

    default:
        break;
    }
done:;

    return offset+tvb_length_remaining(tvb, offset);
}
Ejemplo n.º 7
0
static void
dissect_ipv6_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
{
  proto_tree_add_item(parameter_tree, hf_parameter_ipv6_address, parameter_tvb, IPV6_ADDRESS_OFFSET, IPV6_ADDRESS_LENGTH, ENC_NA);
  proto_item_append_text(parameter_item, " (%s)", tvb_ip6_to_str(parameter_tvb, IPV6_ADDRESS_OFFSET));
}
Ejemplo n.º 8
0
static int
dissect_lisp_tcp_membership_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *message_tree,
                                    guint offset, guint16 type, guint16 data_len, proto_item *tim)
{
    guint32 iid, sid, rid;
    guint8 err;
    guint64 siteid;
    guint16 afi;

    /* EID AFI (2 bytes) */
    proto_tree_add_item(message_tree, hf_lisp_tcp_message_eid_afi, tvb, offset, 2, ENC_BIG_ENDIAN);
    offset += 2;
    data_len -= 2;

    /* Instance ID (4 bytes) */
    iid = tvb_get_ntohl(tvb, offset);
    proto_tree_add_item(message_tree, hf_lisp_tcp_message_iid, tvb, offset, 4, ENC_BIG_ENDIAN);
    offset += 4;
    data_len -= 4;
    proto_item_append_text(tim, ", IID: %u", iid);

    switch (type) {
    case MEMBERSHIP_BASE + 1:
    case MEMBERSHIP_BASE + 2:
        /* Subscribe ID (4 bytes) */
        sid = tvb_get_ntohl(tvb, offset);
        proto_tree_add_item(message_tree, hf_lisp_tcp_message_sid, tvb, offset, 4, ENC_BIG_ENDIAN);
        offset += 4;
        data_len -= 4;
        col_append_fstr(pinfo->cinfo, COL_INFO, ", Sub ID: %u", sid);
        proto_item_append_text(tim, ", Sub ID: %u", sid);

        if (type == MEMBERSHIP_BASE + 2) {
            /* Error code (1 byte) */
            err = tvb_get_guint8(tvb, offset);
            proto_tree_add_item(message_tree, hf_lisp_tcp_message_err, tvb, offset, 1, ENC_BIG_ENDIAN);
            offset += 1;
            data_len -= 1;
            proto_item_append_text(tim, ", Error code: %s",
                                   val_to_str(err, lisp_tcp_membership_subscribe_errors, "Unknown error code (%u)"));
        }

        break;

    case MEMBERSHIP_BASE + 4:
    case MEMBERSHIP_BASE + 5:
        /* Site ID (8 bytes) */
        siteid = tvb_get_ntoh64(tvb, offset);
        proto_tree_add_item(message_tree, hf_lisp_tcp_message_site_id, tvb, offset, 8, ENC_BIG_ENDIAN);
        offset += 8;
        data_len -= 8;
        proto_item_append_text(tim, ", Site-ID: %"G_GINT64_MODIFIER"u", siteid);

        /* RLOC AFI (2 bytes) */
        afi = tvb_get_ntohs(tvb, offset);
        proto_tree_add_item(message_tree, hf_lisp_tcp_message_rloc_afi, tvb, offset, 2, ENC_BIG_ENDIAN);
        offset += 2;
        data_len -= 2;

        switch (afi) {
        case AFNUM_INET:
            proto_tree_add_item(message_tree, hf_lisp_tcp_message_rloc_ipv4, tvb, offset, INET_ADDRLEN, ENC_NA);
            proto_item_append_text(tim, ", RLOC: %s", tvb_ip_to_str(tvb, offset));
            col_append_fstr(pinfo->cinfo, COL_INFO, " [%u] %s", iid, tvb_ip_to_str(tvb, offset));
            offset += INET_ADDRLEN;
            data_len -= INET_ADDRLEN;
            break;
        case AFNUM_INET6:
            proto_tree_add_item(message_tree, hf_lisp_tcp_message_rloc_ipv6, tvb, offset, INET6_ADDRLEN, ENC_NA);
            proto_item_append_text(tim, ", RLOC: %s", tvb_ip6_to_str(tvb, offset));
            col_append_fstr(pinfo->cinfo, COL_INFO, " [%u] %s", iid, tvb_ip6_to_str(tvb, offset));
            offset += INET6_ADDRLEN;
            data_len -= INET6_ADDRLEN;
            break;
        }

        break;

    case MEMBERSHIP_BASE + 7:
    case MEMBERSHIP_BASE + 8:
        /* Request ID (4 bytes) */
        rid = tvb_get_ntohl(tvb, offset);
        proto_tree_add_item(message_tree, hf_lisp_tcp_message_rid, tvb, offset, 4, ENC_BIG_ENDIAN);
        offset += 4;
        data_len -= 4;
        proto_item_append_text(tim, ", Req ID: %u", rid);
        break;
    }

    if (data_len) {
        proto_tree_add_item(message_tree, hf_lisp_tcp_message_data, tvb, offset, data_len, ENC_NA);
        offset += data_len;
        expert_add_info_format(pinfo, message_tree, &ei_lisp_tcp_undecoded, "Work-in-progress");
    }

    return offset;
}
Ejemplo n.º 9
0
/* -----------------------------
	from netatalk/etc/afpd/status.c
*/
static gint
dissect_dsi_reply_get_status(tvbuff_t *tvb, proto_tree *tree, gint offset)
{
    proto_tree      *sub_tree;
    proto_item	*ti;

    guint16 ofs;
    guint16 flag;
    guint16 sign_ofs = 0;
    guint16 adr_ofs = 0;
    guint16 dir_ofs = 0;
    guint16 utf_ofs = 0;
    guint8	nbe;
    guint8  len;
    guint8  i;

    if (!tree)
        return offset;

    ti = proto_tree_add_text(tree, tvb, offset, -1, "Get Status");
    tree = proto_item_add_subtree(ti, ett_dsi_status);

    ofs = tvb_get_ntohs(tvb, offset +AFPSTATUS_MACHOFF);
    proto_tree_add_text(tree, tvb, offset +AFPSTATUS_MACHOFF, 2, "Machine offset: %d", ofs);

    ofs = tvb_get_ntohs(tvb, offset +AFPSTATUS_VERSOFF);
    proto_tree_add_text(tree, tvb, offset +AFPSTATUS_VERSOFF, 2, "Version offset: %d", ofs);

    ofs = tvb_get_ntohs(tvb, offset +AFPSTATUS_UAMSOFF);
    proto_tree_add_text(tree, tvb, offset +AFPSTATUS_UAMSOFF, 2, "UAMS offset: %d", ofs);

    ofs = tvb_get_ntohs(tvb, offset +AFPSTATUS_ICONOFF);
    proto_tree_add_text(tree, tvb, offset +AFPSTATUS_ICONOFF, 2, "Icon offset: %d", ofs);

    ofs = offset +AFPSTATUS_FLAGOFF;
    ti = proto_tree_add_item(tree, hf_dsi_server_flag, tvb, ofs, 2, ENC_BIG_ENDIAN);
    sub_tree = proto_item_add_subtree(ti, ett_dsi_status_server_flag);
    proto_tree_add_item(sub_tree, hf_dsi_server_flag_copyfile      , tvb, ofs, 2, ENC_BIG_ENDIAN);
    proto_tree_add_item(sub_tree, hf_dsi_server_flag_passwd        , tvb, ofs, 2, ENC_BIG_ENDIAN);
    proto_tree_add_item(sub_tree, hf_dsi_server_flag_no_save_passwd, tvb, ofs, 2, ENC_BIG_ENDIAN);
    proto_tree_add_item(sub_tree, hf_dsi_server_flag_srv_msg       , tvb, ofs, 2, ENC_BIG_ENDIAN);
    proto_tree_add_item(sub_tree, hf_dsi_server_flag_srv_sig       , tvb, ofs, 2, ENC_BIG_ENDIAN);
    proto_tree_add_item(sub_tree, hf_dsi_server_flag_tcpip         , tvb, ofs, 2, ENC_BIG_ENDIAN);
    proto_tree_add_item(sub_tree, hf_dsi_server_flag_notify        , tvb, ofs, 2, ENC_BIG_ENDIAN);
    proto_tree_add_item(sub_tree, hf_dsi_server_flag_reconnect     , tvb, ofs, 2, ENC_BIG_ENDIAN);
    proto_tree_add_item(sub_tree, hf_dsi_server_flag_directory     , tvb, ofs, 2, ENC_BIG_ENDIAN);
    proto_tree_add_item(sub_tree, hf_dsi_server_flag_utf8_name     , tvb, ofs, 2, ENC_BIG_ENDIAN);
    proto_tree_add_item(sub_tree, hf_dsi_server_flag_uuid          , tvb, ofs, 2, ENC_BIG_ENDIAN);
    proto_tree_add_item(sub_tree, hf_dsi_server_flag_ext_sleep     , tvb, ofs, 2, ENC_BIG_ENDIAN);
    proto_tree_add_item(sub_tree, hf_dsi_server_flag_fast_copy     , tvb, ofs, 2, ENC_BIG_ENDIAN);

    proto_tree_add_item(tree, hf_dsi_server_name, tvb, offset +AFPSTATUS_PRELEN, 1, ENC_ASCII|ENC_NA);

    flag = tvb_get_ntohs(tvb, ofs);
    if ((flag & AFPSRVRINFO_SRVSIGNATURE)) {
        ofs = offset +AFPSTATUS_PRELEN +tvb_get_guint8(tvb, offset +AFPSTATUS_PRELEN) +1;
        if ((ofs & 1))
            ofs++;

        sign_ofs = tvb_get_ntohs(tvb, ofs);
        proto_tree_add_text(tree, tvb, ofs, 2, "Signature offset: %d", sign_ofs);
        sign_ofs += offset;

        if ((flag & AFPSRVRINFO_TCPIP)) {
            ofs += 2;
            adr_ofs =  tvb_get_ntohs(tvb, ofs);
            proto_tree_add_text(tree, tvb, ofs, 2, "Network address offset: %d", adr_ofs);
            adr_ofs += offset;
        }

        if ((flag & AFPSRVRINFO_SRVDIRECTORY)) {
            ofs += 2;
            dir_ofs =  tvb_get_ntohs(tvb, ofs);
            proto_tree_add_text(tree, tvb, ofs, 2, "Directory services offset: %d", dir_ofs);
            dir_ofs += offset;
        }
        if ((flag & AFPSRVRINFO_SRVUTF8)) {
            ofs += 2;
            utf_ofs =  tvb_get_ntohs(tvb, ofs);
            proto_tree_add_text(tree, tvb, ofs, 2, "UTF8 server name offset: %d", utf_ofs);
            utf_ofs += offset;
        }
    }

    ofs = offset +tvb_get_ntohs(tvb, offset +AFPSTATUS_MACHOFF);
    if (ofs)
        proto_tree_add_item(tree, hf_dsi_server_type, tvb, ofs, 1, ENC_ASCII|ENC_NA);

    ofs = offset +tvb_get_ntohs(tvb, offset +AFPSTATUS_VERSOFF);
    if (ofs) {
        nbe = tvb_get_guint8(tvb, ofs);
        ti = proto_tree_add_text(tree, tvb, ofs, 1, "Version list: %d", nbe);
        ofs++;
        sub_tree = proto_item_add_subtree(ti, ett_dsi_vers);
        for (i = 0; i < nbe; i++) {
            len = tvb_get_guint8(tvb, ofs);
            proto_tree_add_item(sub_tree, hf_dsi_server_vers, tvb, ofs, 1, ENC_ASCII|ENC_NA);
            ofs += len + 1;
        }
    }

    ofs = offset +tvb_get_ntohs(tvb, offset +AFPSTATUS_UAMSOFF);
    if (ofs) {
        nbe = tvb_get_guint8(tvb, ofs);
        ti = proto_tree_add_text(tree, tvb, ofs, 1, "UAMS list: %d", nbe);
        ofs++;
        sub_tree = proto_item_add_subtree(ti, ett_dsi_uams);
        for (i = 0; i < nbe; i++) {
            len = tvb_get_guint8(tvb, ofs);
            proto_tree_add_item(sub_tree, hf_dsi_server_uams, tvb, ofs, 1, ENC_ASCII|ENC_NA);
            ofs += len + 1;
        }
    }

    ofs = offset +tvb_get_ntohs(tvb, offset +AFPSTATUS_ICONOFF);
    if (ofs)
        proto_tree_add_item(tree, hf_dsi_server_icon, tvb, ofs, 256, ENC_NA);

    if (sign_ofs) {
        proto_tree_add_item(tree, hf_dsi_server_signature, tvb, sign_ofs, 16, ENC_NA);
    }

    if (adr_ofs) {
        proto_tree *adr_tree;
        unsigned char *tmp;
        guint16 net;
        guint8  node;
        guint16 port;

        ofs = adr_ofs;
        nbe = tvb_get_guint8(tvb, ofs);
        ti = proto_tree_add_text(tree, tvb, ofs, 1, "Address list: %d", nbe);
        ofs++;
        adr_tree = proto_item_add_subtree(ti, ett_dsi_addr);
        for (i = 0; i < nbe; i++) {
            guint8 type;

            len = tvb_get_guint8(tvb, ofs);
            type =  tvb_get_guint8(tvb, ofs +1);
            switch (type) {
            case 1:	/* IP */
                ti = proto_tree_add_text(adr_tree, tvb, ofs, len, "ip: %s", tvb_ip_to_str(tvb, ofs+2));
                break;
            case 2: /* IP + port */
                port = tvb_get_ntohs(tvb, ofs+6);
                ti = proto_tree_add_text(adr_tree, tvb, ofs, len, "ip %s:%d", tvb_ip_to_str(tvb, ofs+2), port);
                break;
            case 3: /* DDP, atalk_addr_to_str want host order not network */
                net  = tvb_get_ntohs(tvb, ofs+2);
                node = tvb_get_guint8(tvb, ofs +4);
                port = tvb_get_guint8(tvb, ofs +5);
                ti = proto_tree_add_text(adr_tree, tvb, ofs, len, "ddp: %u.%u:%u",
                                         net, node, port);
                break;
            case 4: /* DNS */
            case 5: /* SSH tunnel */
                if (len > 2) {
                    tmp = tvb_get_string(wmem_packet_scope(), tvb, ofs +2, len -2);
                    ti = proto_tree_add_text(adr_tree, tvb, ofs, len, "%s: %s",
                                             (type==4)?"dns":"ssh tunnel", tmp);
                    break;
                }
                else {
                    ti = proto_tree_add_text(adr_tree, tvb, ofs, len,"Malformed address type %d", type);
                }
                break;
            case 6: /* IP6 */
                ti = proto_tree_add_text(adr_tree, tvb, ofs, len, "ip6: %s",
                                         tvb_ip6_to_str(tvb, ofs+2));
                break;
            case 7: /* IP6 + 2bytes port */
                port = tvb_get_ntohs(tvb, ofs+ 2+INET6_ADDRLEN);
                ti = proto_tree_add_text(adr_tree, tvb, ofs, len, "ip6 %s:%d",
                                         tvb_ip6_to_str(tvb, ofs+2), port);
                break;
            default:
                ti = proto_tree_add_text(adr_tree, tvb, ofs, len,"Unknown type : %d", type);
                break;
            }
            len -= 2;
            sub_tree = proto_item_add_subtree(ti,ett_dsi_addr_line);
            proto_tree_add_item(sub_tree, hf_dsi_server_addr_len, tvb, ofs, 1, ENC_BIG_ENDIAN);
            ofs++;
            proto_tree_add_item(sub_tree, hf_dsi_server_addr_type, tvb, ofs, 1, ENC_BIG_ENDIAN);
            ofs++;
            proto_tree_add_item(sub_tree, hf_dsi_server_addr_value,tvb, ofs, len, ENC_NA);
            ofs += len;
        }
    }

    if (dir_ofs) {
        ofs = dir_ofs;
        nbe = tvb_get_guint8(tvb, ofs);
        ti = proto_tree_add_text(tree, tvb, ofs, 1, "Directory services list: %d", nbe);
        ofs++;
        sub_tree = proto_item_add_subtree(ti, ett_dsi_directory);
        for (i = 0; i < nbe; i++) {
            len = tvb_get_guint8(tvb, ofs);
            proto_tree_add_item(sub_tree, hf_dsi_server_directory, tvb, ofs, 1, ENC_ASCII|ENC_NA);
            ofs += len + 1;
        }
    }
    if (utf_ofs) {
        guint16 ulen;
        char *tmp;

        ofs = utf_ofs;
        ulen = tvb_get_ntohs(tvb, ofs);
        tmp = tvb_get_string(wmem_packet_scope(), tvb, ofs + 2, ulen);
        ti = proto_tree_add_text(tree, tvb, ofs, ulen + 2, "UTF8 server name: %s", tmp);
        sub_tree = proto_item_add_subtree(ti, ett_dsi_utf8_name);
        proto_tree_add_uint(sub_tree, hf_dsi_utf8_server_name_len, tvb, ofs, 2, ulen);
        ofs += 2;
        proto_tree_add_string(sub_tree, hf_dsi_utf8_server_name, tvb, ofs, ulen, tmp);
        ofs += ulen;
    }

    return ofs;
}
Ejemplo n.º 10
0
static void dissect_xdmcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
  gint version = -1, opcode = -1;
  gint offset = 0;
  proto_item *ti;
  proto_tree *xdmcp_tree = 0;

  version = tvb_get_ntohs(tvb, offset);
  if (version != XDMCP_PROTOCOL_VERSION) {
    /* Only version 1 exists, so this probably is not XDMCP at all... */
    return;
  }

  col_set_str(pinfo->cinfo, COL_PROTOCOL, "XDMCP");
  col_clear(pinfo->cinfo, COL_INFO);

  if (tree) {
    ti = proto_tree_add_item(tree, proto_xdmcp, tvb, offset, -1, FALSE);
    xdmcp_tree = proto_item_add_subtree(ti, ett_xdmcp);

    proto_tree_add_uint(xdmcp_tree, hf_xdmcp_version, tvb,
			offset, 2, version);
  }
  offset += 2;

  opcode = tvb_get_ntohs(tvb, offset);
  if (tree) {
    proto_tree_add_uint(xdmcp_tree, hf_xdmcp_opcode, tvb,
			offset, 2, opcode);
  }
  offset += 2;
  if (check_col(pinfo->cinfo, COL_INFO)) {
    col_add_str(pinfo->cinfo, COL_INFO,
                 val_to_str(opcode, opcode_vals, "Unknown (0x%04x)"));

  }

  if (tree) {
    proto_tree_add_item(xdmcp_tree, hf_xdmcp_length, tvb,
			offset, 2, FALSE);
    offset += 2;

    switch (opcode) {
      case XDMCP_FORWARD_QUERY:
      {
	gint alen, plen;
	alen = tvb_get_ntohs(tvb, offset);
	/* I have never seen anything except IPv4 addresses here,
	 * but in theory the protocol should support other address
	 * families. */
	if (alen == 4) {
	  proto_tree_add_text(xdmcp_tree, tvb, offset, alen+2,
			      "Client address: %s",
			      tvb_ip_to_str(tvb, offset+2));
	  offset += 6;
	} else if (alen == 16) {
	  proto_tree_add_text(xdmcp_tree, tvb, offset, alen+2,
			      "Client address: %s",
			      tvb_ip6_to_str(tvb, offset+2));
	  offset += 18;
	} else {
	  offset += xdmcp_add_bytes(xdmcp_tree, "Client address", tvb, offset);
	}

	plen = tvb_get_ntohs(tvb, offset);
	if (plen == 2) {
	  proto_tree_add_text(xdmcp_tree, tvb, offset, plen+2,
			      "Client port: %u",
			      tvb_get_ntohs(tvb, offset+2));
	  offset += 4;
	} else {
	  offset += xdmcp_add_bytes(xdmcp_tree, "Client port", tvb, offset);
	}
      }
      /* fall-through */

      case XDMCP_BROADCAST_QUERY:
      case XDMCP_QUERY:
      case XDMCP_INDIRECT_QUERY:
	offset += xdmcp_add_authentication_names(xdmcp_tree, tvb, offset);
	break;

      case XDMCP_WILLING:
	offset += xdmcp_add_string(xdmcp_tree, hf_xdmcp_authentication_name,
				   tvb, offset);
	offset += xdmcp_add_string(xdmcp_tree, hf_xdmcp_hostname,
				   tvb, offset);
	offset += xdmcp_add_string(xdmcp_tree, hf_xdmcp_status,
				   tvb, offset);
	break;

      case XDMCP_UNWILLING:
	offset += xdmcp_add_string(xdmcp_tree, hf_xdmcp_hostname,
				   tvb, offset);
	offset += xdmcp_add_string(xdmcp_tree, hf_xdmcp_status,
				   tvb, offset);
	break;

      case XDMCP_REQUEST:
      {
	proto_tree *clist_tree;
	proto_item *clist_ti;
	gint ctypes_len, caddrs_len, n;
	gint ctypes_start_offset, caddrs_offset;

	proto_tree_add_item(xdmcp_tree, hf_xdmcp_display_number, tvb,
			    offset, 2, FALSE);
	offset += 2;

	ctypes_len = tvb_get_guint8(tvb, offset);
	ctypes_start_offset = offset;
	caddrs_offset = offset + 1 + 2*ctypes_len;
	caddrs_len = tvb_get_guint8(tvb, caddrs_offset);
	if (ctypes_len != caddrs_len) {
	  proto_tree_add_text(xdmcp_tree, NULL, 0, 0,
			      "Error: Connection type/address arrays don't match");
	  return;
	}

	clist_ti = proto_tree_add_text(xdmcp_tree,
				       tvb, ctypes_start_offset, -1,
				       "Connections (%d)",
				       ctypes_len);
	clist_tree = proto_item_add_subtree(clist_ti, ett_xdmcp_connections);

	offset++;
	caddrs_offset++;

	n = 1;
	while (ctypes_len > 0) {
	  proto_item *connection_ti;
	  proto_tree *connection_tree;
	  const char *ip_string;

	  gint alen;
	  gint ctype = tvb_get_ntohs(tvb, offset);
	  offset += 2;
	  alen = tvb_get_ntohs(tvb, caddrs_offset);
	  caddrs_offset += 2;

	  if ((ctype == 0) && (alen == 4)) {
	    ip_string = tvb_ip_to_str(tvb, caddrs_offset);
	  } else if ((ctype == 6) && (alen == 16)) {
	    ip_string = tvb_ip6_to_str(tvb, caddrs_offset);
	  } else {
	    ip_string = NULL;
	  }

	  connection_ti = proto_tree_add_text(clist_tree, NULL, 0, 0,
					      "Connection %d%s%s", n,
					      (ip_string ? ": " : ""),
					      (ip_string ? ip_string : ""));
	  connection_tree = proto_item_add_subtree(connection_ti,
						   ett_xdmcp_connection);

	  proto_tree_add_text(connection_tree, tvb, offset-2, 2,
			      "Type: %s",
			      val_to_str(ctype, family_vals,
					 "Unknown (0x%04x)"));
	  if (ip_string) {
	    proto_tree_add_text(connection_tree, tvb, caddrs_offset-2, alen+2,
				"Address: %s", ip_string);
	  } else {
	    proto_tree_add_text(connection_tree, tvb, caddrs_offset-2, alen+2,
				"Address: (%u byte%s)", alen,
				plurality(alen, "", "s"));
	  }
	  caddrs_offset += alen;
	  ctypes_len--;
	  n++;
	}
	offset = caddrs_offset;
	proto_item_set_len(clist_ti, offset - ctypes_start_offset);

	offset += xdmcp_add_string(xdmcp_tree, hf_xdmcp_authentication_name,
				   tvb, offset);
	offset += xdmcp_add_bytes(xdmcp_tree, "Authentication data",
				  tvb, offset);

	offset += xdmcp_add_authorization_names(xdmcp_tree, tvb, offset);

	offset += xdmcp_add_text(xdmcp_tree, "Manufacturer display ID",
				 tvb, offset);
	break;
      }

      case XDMCP_ACCEPT:
	proto_tree_add_item(xdmcp_tree, hf_xdmcp_session_id, tvb,
			    offset, 4, FALSE);
	offset += 4;
	offset += xdmcp_add_string(xdmcp_tree, hf_xdmcp_authentication_name,
				   tvb, offset);
	offset += xdmcp_add_bytes(xdmcp_tree, "Authentication data",
				  tvb, offset);
	offset += xdmcp_add_string(xdmcp_tree, hf_xdmcp_authorization_name,
				   tvb, offset);
	offset += xdmcp_add_bytes(xdmcp_tree, "Authorization data",
				  tvb, offset);
	break;

      case XDMCP_DECLINE:
	offset += xdmcp_add_string(xdmcp_tree, hf_xdmcp_status,
				   tvb, offset);
	offset += xdmcp_add_string(xdmcp_tree, hf_xdmcp_authentication_name,
				   tvb, offset);
	offset += xdmcp_add_bytes(xdmcp_tree, "Authentication data",
				  tvb, offset);
	break;

      case XDMCP_MANAGE:
	proto_tree_add_item(xdmcp_tree, hf_xdmcp_session_id, tvb,
			    offset, 4, FALSE);
	offset += 4;

	proto_tree_add_item(xdmcp_tree, hf_xdmcp_display_number, tvb,
			    offset, 2, FALSE);
	offset += 2;

	offset += xdmcp_add_text(xdmcp_tree, "Display class",
				 tvb, offset);
	break;

      case XDMCP_REFUSE:
	proto_tree_add_item(xdmcp_tree, hf_xdmcp_session_id, tvb,
			    offset, 4, FALSE);
	offset += 4;
	break;

      case XDMCP_FAILED:
	proto_tree_add_item(xdmcp_tree, hf_xdmcp_session_id, tvb,
			    offset, 4, FALSE);
	offset += 4;

	offset += xdmcp_add_string(xdmcp_tree, hf_xdmcp_status,
				   tvb, offset);
	break;

      case XDMCP_KEEPALIVE:
	proto_tree_add_item(xdmcp_tree, hf_xdmcp_display_number, tvb,
			    offset, 2, FALSE);
	offset += 2;

	proto_tree_add_item(xdmcp_tree, hf_xdmcp_session_id, tvb,
			    offset, 4, FALSE);
	offset += 4;
	break;

      case XDMCP_ALIVE:
	proto_tree_add_text(xdmcp_tree, tvb, offset, 1,
			    "Session running: %s",
			    (tvb_get_guint8(tvb, offset) ? "Yes" : "No"));
	offset++;

	proto_tree_add_item(xdmcp_tree, hf_xdmcp_session_id, tvb,
			    offset, 4, FALSE);
	offset += 4;
	break;
    }
  }
}
Ejemplo n.º 11
0
/* Code to actually dissect the packets */
static int
rsip_parameter(tvbuff_t *tvb, proto_tree *rsip_tree, int off, int eoff)
{
	int		consumed, i, paramleft;
	guint8		addrtype, flowpolicy, method, number, paramtype, tuntype;
	guint16		error, ind, paramlen, portnum;
	guint32		bid, cid, leasetm, msgc;
	proto_tree	*p_tree, *v_tree;
	proto_item	*pti, *vti;

	/* XXX */
	if (off >= eoff)
		return 0;

	paramtype = tvb_get_guint8(tvb, off);
	paramlen = tvb_get_ntohs(tvb, off + 1);

	p_tree = proto_tree_add_subtree(rsip_tree, tvb, off, 3 + paramlen,
	    ett_rsip_param, &pti,
	    val_to_str(paramtype, param_type_vals, "Unknown (%d)"));

	proto_tree_add_item(p_tree, hf_rsip_parameter_type, tvb,
	    off, 1, ENC_BIG_ENDIAN);
	proto_tree_add_item(p_tree, hf_rsip_parameter_length, tvb,
	    off + 1, 2, ENC_BIG_ENDIAN);
	consumed = 3;

	if (paramlen == 0)
	    return consumed;

	vti = proto_tree_add_item(p_tree, hf_rsip_parameter_value,
	    tvb, off + 3, paramlen, ENC_NA);
	v_tree = proto_item_add_subtree(vti, ett_rsip_param_val);

	switch (paramtype) {
	case 1:		/* Address */
		proto_tree_add_item(v_tree, hf_rsip_parameter_address_type,
		    tvb, off + 3, 1, ENC_BIG_ENDIAN);

		addrtype = tvb_get_guint8(tvb, off + 3);

		switch (addrtype) {
		case 0:		/* Reserved */
			break;
		case 1:		/* IPv4 */
			if (paramlen - 1 > 0) {
				proto_tree_add_item(v_tree,
				    hf_rsip_parameter_address_ipv4, tvb,
				    off + 4, paramlen - 1, ENC_BIG_ENDIAN);
				proto_item_append_text(pti, ": %s",
				    tvb_ip_to_str(tvb, off + 4));
			} else
				proto_item_append_text(pti,
				    ": Any IPv4 Address");
			break;
		case 2:		/* IPv4 netmask */
			if (paramlen - 1 > 0) {
				proto_tree_add_item(v_tree,
				    hf_rsip_parameter_address_ipv4_netmask,
				    tvb, off + 4, paramlen - 1, ENC_BIG_ENDIAN);
				proto_item_append_text(pti, "(netmask): %s",
				    tvb_ip_to_str(tvb, off + 4));
			} else
				proto_item_append_text(pti,
				    ": Any IPv4 Netmask");
			break;
		case 3:		/* IPv6 */
			if (paramlen - 1 > 0) {
				proto_tree_add_item(v_tree,
				    hf_rsip_parameter_address_ipv6, tvb,
				    off + 4, paramlen - 1, ENC_NA);
				proto_item_append_text(pti, ": %s",
				    tvb_ip6_to_str(tvb, off + 4));
			} else
				proto_item_append_text(pti,
				    ": Any IPv6 Address");
			break;
		case 4:		/* FQDN */
			if (paramlen - 1 > 0) {
				proto_tree_add_item(v_tree,
				    hf_rsip_parameter_address_fqdn, tvb,
				    off + 4, paramlen - 1, ENC_ASCII|ENC_NA);
				proto_item_append_text(pti, ": %s",
				    tvb_format_text(tvb, off + 4, paramlen - 1));
			} else
				proto_item_append_text(pti,
				    ": Any Fully Qualified Domain Name");
			break;
		default:
			proto_item_append_text(pti, ": Unknown Address Type");
			break;
		}
		break;
	case 2:		/* Ports */
		proto_tree_add_item(v_tree, hf_rsip_parameter_ports_number,
		    tvb, off + 3, 1, ENC_BIG_ENDIAN);
		number = tvb_get_guint8(tvb, off + 3);
		if (paramlen == 1) {
			switch (number) {
			case 0:
				proto_item_append_text(pti, ": Unspecified");
				break;
			case 1:
				proto_item_append_text(pti, ": Any port");
				break;
			default:
				proto_item_append_text(pti, ": Any %d ports",
				    number);
				break;
			}
		} else {
			portnum = tvb_get_ntohs(tvb, off + 4);
			if (number == 1) {
				proto_tree_add_item(v_tree,
				    hf_rsip_parameter_ports_port_number,
				    tvb, off + 4, 2, ENC_BIG_ENDIAN);
			} else {
				paramleft = paramlen - 1;
				if (paramleft == 2) {
					proto_tree_add_uint_format_value(v_tree,
					    hf_rsip_parameter_ports_port_number,
					    tvb, off + 4, 2, portnum, "%d - %d",
					    portnum, portnum + number);
					proto_item_append_text(pti,
					    ": %d - %d", portnum,
					    portnum + number);
				} else {
					for (i = off + 4;
					    paramleft > 0;
					    i += 2, paramleft -= 2)
						proto_tree_add_item(v_tree,
						    hf_rsip_parameter_ports_port_number,
						    tvb, i, 2, ENC_BIG_ENDIAN);
					proto_item_append_text(pti,
					    ": List of %d Ports", number);
				}
			}
		}
		break;
	case 3:		/* Lease Time */
		/* XXX if paramlen != 4 we've got a protocol violation */
		proto_tree_add_item(v_tree, hf_rsip_parameter_lease_time,
		    tvb, off + 3, paramlen, ENC_BIG_ENDIAN);
		leasetm = tvb_get_ntohl(tvb, off + 3);
		proto_item_append_text(pti, ": %d seconds", leasetm);
		break;
	case 4:		/* Client ID */
		/* XXX if paramlen != 4 we've got a protocol violation */
		proto_tree_add_item(v_tree, hf_rsip_parameter_client_id,
		    tvb, off + 3, paramlen, ENC_BIG_ENDIAN);
		cid = tvb_get_ntohl(tvb, off + 3);
		proto_item_append_text(pti, ": %d", cid);
		break;
	case 5:		/* Bind ID */
		/* XXX if paramlen != 4 we've got a protocol violation */
		proto_tree_add_item(v_tree, hf_rsip_parameter_bind_id,
		    tvb, off + 3, paramlen, ENC_BIG_ENDIAN);
		bid = tvb_get_ntohl(tvb, off + 3);
		proto_item_append_text(pti, ": %d", bid);
		break;
	case 6:		/* Tunnel Type */
		/* XXX if paramlen != 1 we've got a protocol violation */
		proto_tree_add_item(v_tree, hf_rsip_parameter_tunnel_type,
		    tvb, off + 3, paramlen, ENC_BIG_ENDIAN);
		tuntype = tvb_get_guint8(tvb, off + 3);
		proto_item_append_text(pti, ": %s",
		    val_to_str(tuntype, tunnel_type_vals,
		        "Unknown Tunnel Type (%d)"));
		break;
	case 7:		/* RSIP Method */
		/* XXX if paramlen != 1 we've got a protocol violation */
		proto_tree_add_item(v_tree, hf_rsip_parameter_method,
		    tvb, off + 3, paramlen, ENC_BIG_ENDIAN);
		method = tvb_get_guint8(tvb, off + 3);
		proto_item_append_text(pti, ": %s",
		    val_to_str(method, method_vals,
		    "Unknown RSIP Method (%d)"));
		break;
	case 8:		/* Error */
		/* XXX if paramlen != 2 we've got a protocol violation */
		proto_tree_add_item(v_tree, hf_rsip_parameter_error,
		    tvb, off + 3, paramlen, ENC_BIG_ENDIAN);
		error = tvb_get_ntohs(tvb, off + 3);
		proto_item_append_text(pti, ": %s",
		    val_to_str(error, error_number_vals, "Undefined Error (%d)"));
		break;
	case 9:		/* Flow Policy */
		/* XXX if paramlen != 2 we've got a protocol violation */
		proto_tree_add_item(v_tree,
		    hf_rsip_parameter_flow_policy_local, tvb, off + 3, 1, ENC_BIG_ENDIAN);
		flowpolicy = tvb_get_guint8(tvb, off + 3);
		proto_item_append_text(pti, ": %s",
		    val_to_str(flowpolicy, lcl_flow_policy_vals,
		    "Undefined Local Flow Policy (%d)"));
		proto_tree_add_item(v_tree,
		    hf_rsip_parameter_flow_policy_remote, tvb, off + 4, 1,
		    ENC_BIG_ENDIAN);
		flowpolicy = tvb_get_guint8(tvb, off + 4);
		proto_item_append_text(pti, "/%s",
		    val_to_str(flowpolicy, rmt_flow_policy_vals,
		    "Undefined Remote Flow Policy (%d)"));
		break;
	case 10:	/* Indicator */
		/* XXX if paramlen != 2 we've got a protocol violation */
		proto_tree_add_item(v_tree, hf_rsip_parameter_indicator, tvb,
		    off + 3, 2, ENC_BIG_ENDIAN);
		ind = tvb_get_ntohs(tvb, off + 3);
		proto_item_append_text(pti, ": %d", ind);
		break;
	case 11:	/* Message Counter */
		/* XXX if paramlen != 4 we've got a protocol violation */
		proto_tree_add_item(v_tree, hf_rsip_parameter_message_counter,
		    tvb, off + 3, 4, ENC_BIG_ENDIAN);
		msgc = tvb_get_ntohl(tvb, off + 3);
		proto_item_append_text(pti, ": %d", msgc);
		break;
	case 12:	/* Vendor Specific */
		proto_tree_add_item(v_tree,
		    hf_rsip_parameter_vendor_specific_vendor_id, tvb, off + 3,
		    2, ENC_BIG_ENDIAN);
		proto_tree_add_item(v_tree,
		    hf_rsip_parameter_vendor_specific_subtype, tvb, off + 5,
		    2, ENC_BIG_ENDIAN);
		proto_tree_add_item(v_tree,
		    hf_rsip_parameter_vendor_specific_value, tvb, off + 9,
		    paramlen - 4, ENC_NA);
		break;
	case 22:	/* SPI */
		proto_tree_add_item(v_tree, hf_rsip_parameter_spi_number, tvb,
		    off + 3, 2, ENC_BIG_ENDIAN);
		/* XXX need loop? */
		proto_tree_add_item(v_tree, hf_rsip_parameter_spi, tvb,
		    off + 5, 4, ENC_BIG_ENDIAN);
		break;
	default:
		break;
	}

	consumed += paramlen;

	return consumed;
}
Ejemplo n.º 12
0
static void dissect_xdmcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
  gint version = -1, opcode = -1;
  gint offset = 0;
  proto_item *ti;
  proto_tree *xdmcp_tree = 0;

  version = tvb_get_ntohs(tvb, offset);
  if (version != XDMCP_PROTOCOL_VERSION) {
    /* Only version 1 exists, so this probably is not XDMCP at all... */
    return;
  }

  col_set_str(pinfo->cinfo, COL_PROTOCOL, "XDMCP");
  col_clear(pinfo->cinfo, COL_INFO);

  ti = proto_tree_add_item(tree, proto_xdmcp, tvb, offset, -1, ENC_NA);
  xdmcp_tree = proto_item_add_subtree(ti, ett_xdmcp);

  proto_tree_add_uint(xdmcp_tree, hf_xdmcp_version, tvb,
			offset, 2, version);

  offset += 2;

  opcode = tvb_get_ntohs(tvb, offset);
  if (tree) {
    proto_tree_add_uint(xdmcp_tree, hf_xdmcp_opcode, tvb,
			offset, 2, opcode);
  }
  offset += 2;
  if (check_col(pinfo->cinfo, COL_INFO)) {
    col_add_str(pinfo->cinfo, COL_INFO,
                 val_to_str(opcode, opcode_vals, "Unknown (0x%04x)"));

  }

  if (tree) {
    proto_tree_add_item(xdmcp_tree, hf_xdmcp_length, tvb,
			offset, 2, ENC_BIG_ENDIAN);
    offset += 2;

    switch (opcode) {
      case XDMCP_FORWARD_QUERY:
      {
	gint alen, plen;
	alen = tvb_get_ntohs(tvb, offset);
	/* I have never seen anything except IPv4 addresses here,
	 * but in theory the protocol should support other address
	 * families. */
	if (alen == 4) {
      proto_tree_add_item(xdmcp_tree, hf_xdmcp_client_address_ipv4, tvb, offset+2, alen, ENC_BIG_ENDIAN);
	  offset += 6;
	} else if (alen == 16) {
      proto_tree_add_item(xdmcp_tree, hf_xdmcp_client_address_ipv6, tvb, offset+2, alen, ENC_BIG_ENDIAN);
	  offset += 18;
	} else {
	  offset += xdmcp_add_bytes(xdmcp_tree, hf_xdmcp_client_address_bytes, hf_xdmcp_client_address_bytes_len,
                                tvb, offset);
	}

	plen = tvb_get_ntohs(tvb, offset);
	if (plen == 2) {
      proto_tree_add_item(xdmcp_tree, hf_xdmcp_client_port_u16, tvb, offset+2, plen, ENC_BIG_ENDIAN);
	  offset += 4;
	} else {
	  offset += xdmcp_add_bytes(xdmcp_tree, hf_xdmcp_client_port_bytes, hf_xdmcp_client_port_len,
                    tvb, offset);
	}
      }
      /* fall-through */

      case XDMCP_BROADCAST_QUERY:
      case XDMCP_QUERY:
      case XDMCP_INDIRECT_QUERY:
	offset += xdmcp_add_authentication_names(xdmcp_tree, tvb, offset);
	break;

      case XDMCP_WILLING:
	offset += xdmcp_add_string(xdmcp_tree, hf_xdmcp_authentication_name,
				   tvb, offset);
	offset += xdmcp_add_string(xdmcp_tree, hf_xdmcp_hostname,
				   tvb, offset);
	offset += xdmcp_add_string(xdmcp_tree, hf_xdmcp_status,
				   tvb, offset);
	break;

      case XDMCP_UNWILLING:
	offset += xdmcp_add_string(xdmcp_tree, hf_xdmcp_hostname,
				   tvb, offset);
	offset += xdmcp_add_string(xdmcp_tree, hf_xdmcp_status,
				   tvb, offset);
	break;

      case XDMCP_REQUEST:
      {
	proto_tree *clist_tree;
	proto_item *clist_ti;
	gint ctypes_len, caddrs_len, n;
	gint ctypes_start_offset, caddrs_offset;

	ti = proto_tree_add_item(xdmcp_tree, hf_xdmcp_display_number, tvb,
			    offset, 2, ENC_BIG_ENDIAN);
	offset += 2;

	ctypes_len = tvb_get_guint8(tvb, offset);
	ctypes_start_offset = offset;
	caddrs_offset = offset + 1 + 2*ctypes_len;
	caddrs_len = tvb_get_guint8(tvb, caddrs_offset);
	if (ctypes_len != caddrs_len) {
        expert_add_info_format(pinfo, ti, PI_PROTOCOL, PI_WARN, "Error: Connection type/address arrays don't match");
	  return;
	}

	clist_ti = proto_tree_add_text(xdmcp_tree,
				       tvb, ctypes_start_offset, -1,
				       "Connections (%d)",
				       ctypes_len);
	clist_tree = proto_item_add_subtree(clist_ti, ett_xdmcp_connections);

	offset++;
	caddrs_offset++;

	n = 1;
	while (ctypes_len > 0) {
	  proto_item *connection_ti;
	  proto_tree *connection_tree;

	  gint alen;
	  gint ctype = tvb_get_ntohs(tvb, offset);
	  offset += 2;
	  alen = tvb_get_ntohs(tvb, caddrs_offset);
	  caddrs_offset += 2;

	  connection_ti = proto_tree_add_text(clist_tree, NULL, 0, 0,
					      "Connection %d", n);
	  connection_tree = proto_item_add_subtree(connection_ti,
						   ett_xdmcp_connection);

      proto_tree_add_item(connection_tree, hf_xdmcp_connection_type, tvb, offset-2, 2, ENC_BIG_ENDIAN);

	  if ((ctype == 0) && (alen == 4)) {
          proto_tree_add_item(connection_tree, hf_xdmcp_connection_address_ipv4, tvb, caddrs_offset, alen, ENC_BIG_ENDIAN);
          proto_item_append_text(connection_ti, ": %s", tvb_ip_to_str(tvb, caddrs_offset));
      } else if ((ctype == 6) && (alen == 16)) {
          proto_tree_add_item(connection_tree, hf_xdmcp_connection_address_ipv6, tvb, caddrs_offset, alen, ENC_BIG_ENDIAN);
          proto_item_append_text(connection_ti, ": %s", tvb_ip6_to_str(tvb, caddrs_offset));
      } else {
          proto_tree_add_item(connection_tree, hf_xdmcp_connection_address_bytes, tvb, caddrs_offset, alen, ENC_NA);
      }

      caddrs_offset += alen;
	  ctypes_len--;
	  n++;
	}
	offset = caddrs_offset;
	proto_item_set_len(clist_ti, offset - ctypes_start_offset);

	offset += xdmcp_add_string(xdmcp_tree, hf_xdmcp_authentication_name,
				   tvb, offset);
	offset += xdmcp_add_bytes(xdmcp_tree, hf_xdmcp_authentication_data, hf_xdmcp_authentication_data_len, 
				   tvb, offset);

	offset += xdmcp_add_authorization_names(xdmcp_tree, tvb, offset);

	offset += xdmcp_add_bytes(xdmcp_tree, hf_xdmcp_manufacturer_display_id, hf_xdmcp_manufacturer_display_id_len,
				 tvb, offset);
	break;
      }

      case XDMCP_ACCEPT:
	proto_tree_add_item(xdmcp_tree, hf_xdmcp_session_id, tvb,
			    offset, 4, ENC_BIG_ENDIAN);
	offset += 4;
	offset += xdmcp_add_string(xdmcp_tree, hf_xdmcp_authentication_name,
				   tvb, offset);
	offset += xdmcp_add_bytes(xdmcp_tree, hf_xdmcp_authentication_data, hf_xdmcp_authentication_data_len, 
				   tvb, offset);
	offset += xdmcp_add_string(xdmcp_tree, hf_xdmcp_authorization_name,
				   tvb, offset);
	offset += xdmcp_add_bytes(xdmcp_tree, hf_xdmcp_authorization_data, hf_xdmcp_authorization_data_len, 
				   tvb, offset);
	break;

      case XDMCP_DECLINE:
	offset += xdmcp_add_string(xdmcp_tree, hf_xdmcp_status,
				   tvb, offset);
	offset += xdmcp_add_string(xdmcp_tree, hf_xdmcp_authentication_name,
				   tvb, offset);
	offset += xdmcp_add_bytes(xdmcp_tree, hf_xdmcp_authentication_data, hf_xdmcp_authentication_data_len, 
				   tvb, offset);
	break;

      case XDMCP_MANAGE:
	proto_tree_add_item(xdmcp_tree, hf_xdmcp_session_id, tvb,
			    offset, 4, ENC_BIG_ENDIAN);
	offset += 4;

	proto_tree_add_item(xdmcp_tree, hf_xdmcp_display_number, tvb,
			    offset, 2, ENC_BIG_ENDIAN);
	offset += 2;

	offset += xdmcp_add_bytes(xdmcp_tree, hf_xdmcp_display_class, hf_xdmcp_display_class_len,
				 tvb, offset);
	break;

      case XDMCP_REFUSE:
	proto_tree_add_item(xdmcp_tree, hf_xdmcp_session_id, tvb,
			    offset, 4, ENC_BIG_ENDIAN);
	offset += 4;
	break;

      case XDMCP_FAILED:
	proto_tree_add_item(xdmcp_tree, hf_xdmcp_session_id, tvb,
			    offset, 4, ENC_BIG_ENDIAN);
	offset += 4;

	offset += xdmcp_add_string(xdmcp_tree, hf_xdmcp_status,
				   tvb, offset);
	break;

      case XDMCP_KEEPALIVE:
	proto_tree_add_item(xdmcp_tree, hf_xdmcp_display_number, tvb,
			    offset, 2, ENC_BIG_ENDIAN);
	offset += 2;

	proto_tree_add_item(xdmcp_tree, hf_xdmcp_session_id, tvb,
			    offset, 4, ENC_BIG_ENDIAN);
	offset += 4;
	break;

      case XDMCP_ALIVE:
      {
    guint8 session_running = tvb_get_guint8(tvb, offset);
	proto_tree_add_uint_format(xdmcp_tree, hf_xdmcp_session_running, tvb,
			    offset, 1, session_running, "Session running: %s", session_running ? "Yes" : "No");
	offset++;

	proto_tree_add_item(xdmcp_tree, hf_xdmcp_session_id, tvb,
			    offset, 4, ENC_BIG_ENDIAN);
	offset += 4;
      }
	break;
    }
  }
}
Ejemplo n.º 13
0
static void
dissect_ath(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{

  int offset = 0;

  /* various lengths as reported in the packet itself */
  guint8 hlen = 0;
  gint32 clen = 0;
  gint32 dlen = 0;
  gint32 plen = 0;

  /* detect the Tribes (Tomcat) version */
  gint   tribes_version_mark;

  /* store the info */
  const gchar *info_srcaddr = "";
  const gchar *info_domain  = "";
  const gchar *info_command = "";

  proto_item *ti, *hlen_item;
  proto_tree *ath_tree;

  col_set_str(pinfo->cinfo, COL_PROTOCOL, "ATH");

  /* Clear out stuff in the info column */
  col_clear(pinfo->cinfo,COL_INFO);

  ti = proto_tree_add_item(tree, proto_ath, tvb, 0, -1, ENC_NA);
  ath_tree = proto_item_add_subtree(ti, ett_ath);

  /* Determine the Tribes version, which means determining the Tomcat version.
   * There are 2 versions : one for Tomcat 6, and one for Tomcat 7/8
   * We know that Tomcat 6 packets end with "-E" (Ox2d 0x45 or 11589 in decimal)
   * and Tomcat 7/8 packets end with "Ox01 0x00" (256 in decimal)
   * This is why we read these 2 last bytes of the packet
   */
  tribes_version_mark = tvb_get_ntohs(tvb, tvb_reported_length(tvb) - 2);

  /* dissecting a Tomcat 6 packet
   */
  if (tribes_version_mark == 11589) { /* "-E" */

    /* BEGIN
     */
      proto_tree_add_item(ath_tree, hf_ath_begin, tvb, offset, 8, ENC_ASCII|ENC_NA);
      offset += 8;

      /* LENGTH
       */
      proto_tree_add_item(ath_tree, hf_ath_length, tvb, offset, 4, ENC_BIG_ENDIAN);
      offset += 4;

      /* ALIVE TIME
       */
      proto_tree_add_item(ath_tree, hf_ath_alive, tvb, offset, 8, ENC_BIG_ENDIAN);
      offset += 8;

      /* PORT
       */
      proto_tree_add_item(ath_tree, hf_ath_port, tvb, offset, 4, ENC_BIG_ENDIAN);
      offset += 4;

      /* SECURE PORT
       */
      proto_tree_add_item(ath_tree, hf_ath_sport, tvb, offset, 4, ENC_BIG_ENDIAN);
      offset += 4;

      /* HOST LENGTH
       */
      hlen_item = proto_tree_add_item(ath_tree, hf_ath_hlen, tvb, offset, 1, ENC_BIG_ENDIAN);
      hlen = tvb_get_guint8(tvb, offset);
      offset += 1;

      /* HOST
       */
      if (hlen == 4) {
        proto_tree_add_item(ath_tree, hf_ath_ipv4, tvb, offset, 4, ENC_BIG_ENDIAN);
        info_srcaddr = tvb_ip_to_str(tvb, offset);
      } else if (hlen == 6) {
        proto_tree_add_item(ath_tree, hf_ath_ipv6, tvb, offset, 6, ENC_NA);
        info_srcaddr = tvb_ip6_to_str(tvb, offset);
      } else {
        expert_add_info(pinfo, hlen_item, &ei_ath_hlen_invalid);
      }
      offset += hlen;

      /* COMMAND LENGTH
       */
      proto_tree_add_item_ret_int(ath_tree, hf_ath_clen, tvb, offset, 4, ENC_BIG_ENDIAN, &clen);
      offset += 4;

      /* COMMAND
       */
      proto_tree_add_item(ath_tree, hf_ath_comm, tvb, offset, clen, ENC_ASCII|ENC_NA);
      if (clen != -1)
        info_command = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, clen, ENC_ASCII);
      offset += clen;

      /* DOMAIN LENGTH
       */
      proto_tree_add_item_ret_int(ath_tree, hf_ath_dlen, tvb, offset, 4, ENC_BIG_ENDIAN, &dlen);
      offset += 4;

      /* DOMAIN
       */
      proto_tree_add_item(ath_tree, hf_ath_domain, tvb, offset, dlen, ENC_ASCII|ENC_NA);
      if (dlen != 0)
        info_domain = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, dlen, ENC_ASCII);
      offset += dlen;

      /* UNIQUEID
       */
      proto_tree_add_item(ath_tree, hf_ath_unique, tvb, offset, 16, ENC_NA);
      offset += 16;

      /* PAYLOAD LENGTH
       */
      proto_tree_add_item_ret_int(ath_tree, hf_ath_plen, tvb, offset, 4, ENC_BIG_ENDIAN, &plen);
      offset += 4;

      /* PAYLOAD
       */
      proto_tree_add_item(ath_tree, hf_ath_payload, tvb, offset, plen, ENC_ASCII|ENC_NA);
      offset += plen;

      /* END
       */
      proto_tree_add_item(ath_tree, hf_ath_end, tvb, offset, 8, ENC_ASCII|ENC_NA);
  }

  /* dissecting a Tomcat 7/8 packet
   */
  else if (tribes_version_mark == 256) {

    /* BEGIN
     */
      proto_tree_add_item(ath_tree, hf_ath_begin, tvb, offset, 8, ENC_ASCII|ENC_NA);
      offset += 8;

      proto_tree_add_item(ath_tree, hf_ath_padding, tvb, offset, 2, ENC_ASCII|ENC_NA);
      offset += 2;

      /* LENGTH
       */
      proto_tree_add_item(ath_tree, hf_ath_length, tvb, offset, 4, ENC_BIG_ENDIAN);
      offset += 4;

      /* ALIVE TIME
       */
      proto_tree_add_item(ath_tree, hf_ath_alive, tvb, offset, 8, ENC_BIG_ENDIAN);
      offset += 8;

      /* PORT
       */
      proto_tree_add_item(ath_tree, hf_ath_port, tvb, offset, 4, ENC_BIG_ENDIAN);
      offset += 4;

      /* SECURE PORT
       */
      proto_tree_add_item(ath_tree, hf_ath_sport, tvb, offset, 4, ENC_BIG_ENDIAN);
      offset += 4;

      /* UDP PORT, only in Tomcat 7/8
       */
      proto_tree_add_item(ath_tree, hf_ath_uport, tvb, offset, 4, ENC_BIG_ENDIAN);
      offset += 4;

      /* HOST LENGTH
       */
      hlen_item = proto_tree_add_item(ath_tree, hf_ath_hlen, tvb, offset, 1, ENC_BIG_ENDIAN);
      hlen = tvb_get_guint8(tvb, offset);
      offset += 1;

      /* HOST
       */
      if (hlen == 4) {
        proto_tree_add_item(ath_tree, hf_ath_ipv4, tvb, offset, 4, ENC_BIG_ENDIAN);
        info_srcaddr = tvb_ip_to_str(tvb, offset);
      } else if (hlen == 6) {
        proto_tree_add_item(ath_tree, hf_ath_ipv6, tvb, offset, 6, ENC_NA);
        info_srcaddr = tvb_ip6_to_str(tvb, offset);
      } else {
        expert_add_info(pinfo, hlen_item, &ei_ath_hlen_invalid);
      }
      offset += hlen;

      /* COMMAND LENGTH
       */
      proto_tree_add_item_ret_int(ath_tree, hf_ath_clen, tvb, offset, 4, ENC_BIG_ENDIAN, &clen);
      offset += 4;

      /* COMMAND
       */
      proto_tree_add_item(ath_tree, hf_ath_comm, tvb, offset, clen, ENC_ASCII|ENC_NA);
      if (clen != -1)
        info_command = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, clen, ENC_ASCII);
      offset += clen;

      /* DOMAIN LENGTH
       */
      proto_tree_add_item_ret_int(ath_tree, hf_ath_dlen, tvb, offset, 4, ENC_BIG_ENDIAN, &dlen);
      offset += 4;

      /* DOMAIN
       */
      proto_tree_add_item(ath_tree, hf_ath_domain, tvb, offset, dlen, ENC_ASCII|ENC_NA);
      if (dlen != 0)
        info_domain = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, dlen, ENC_ASCII);
      offset += dlen;

      /* UNIQUEID
       */
      proto_tree_add_item(ath_tree, hf_ath_unique, tvb, offset, 16, ENC_NA);
      offset += 16;

      /* PAYLOAD LENGTH
       */
      proto_tree_add_item_ret_int(ath_tree, hf_ath_plen, tvb, offset, 4, ENC_BIG_ENDIAN, &plen);
      offset += 4;

      /* PAYLOAD
       */
      proto_tree_add_item(ath_tree, hf_ath_payload, tvb, offset, plen, ENC_ASCII|ENC_NA);
      offset += plen;

      /* END
       */
      proto_tree_add_item(ath_tree, hf_ath_end, tvb, offset, 8, ENC_ASCII|ENC_NA);

  } else {
    proto_tree_add_expert(tree, pinfo, &ei_ath_hmark_invalid, tvb, offset, -1);
    return;
  }

  /* set the INFO column, and we're done !
   */
  if (strcmp(info_command, "") != 0) {
    if (strcmp(info_command, "BABY-ALEX") == 0) {
      if (strcmp(info_domain, "") != 0) {
        col_append_fstr(pinfo->cinfo, COL_INFO, "%s is leaving domain %s", info_srcaddr, info_domain);
      } else {
        col_append_fstr(pinfo->cinfo, COL_INFO, "%s is leaving default domain", info_srcaddr);
      }
    } else {
      if (strcmp(info_domain, "") != 0) {
        col_append_fstr(pinfo->cinfo, COL_INFO, "Heartbeat from %s to domain %s", info_srcaddr, info_domain);
      } else {
        col_append_fstr(pinfo->cinfo, COL_INFO, "Heartbeat from %s to default domain", info_srcaddr);
      }
    }
  } else {
    if (strcmp(info_domain, "") != 0) {
      col_append_fstr(pinfo->cinfo, COL_INFO, "Heartbeat from %s to domain %s", info_srcaddr, info_domain);
    } else {
      col_append_fstr(pinfo->cinfo, COL_INFO, "Heartbeat from %s to default domain", info_srcaddr);
    }
  }

}