/* Parses a ts2 channel list (TS2T_CHANNELLIST) and adds it to the tree */
static void ts2_parse_channellist(tvbuff_t *tvb, proto_tree *ts2_tree)
{
    gint32 offset;
    guint32 string_len;
    offset=0;
    proto_tree_add_item(ts2_tree, hf_ts2_number_of_channels, tvb, offset, 4, TRUE);
    offset+=4;
    while(offset<tvb_length_remaining(tvb, 0))
    {
        proto_tree_add_item(ts2_tree, hf_ts2_channel_id, tvb, offset, 4, TRUE);
        offset+=4;
        proto_tree_add_item(ts2_tree, hf_ts2_channel_flags, tvb, offset, 1, TRUE);
        offset+=1;
        proto_tree_add_item(ts2_tree, hf_ts2_unknown, tvb, offset, 1, TRUE);
        offset+=1;
        proto_tree_add_item(ts2_tree, hf_ts2_codec, tvb, offset, 2, TRUE);
        offset+=2;
        proto_tree_add_item(ts2_tree, hf_ts2_endmarker, tvb, offset, 4, TRUE);
        offset+=4;
        proto_tree_add_item(ts2_tree, hf_ts2_unknown, tvb, offset, 4, TRUE);
        offset+=4;
        tvb_get_ephemeral_stringz(tvb, offset, &string_len);
        proto_tree_add_item(ts2_tree, hf_ts2_channel_name, tvb, offset,string_len , TRUE);
        offset+=string_len;
        tvb_get_ephemeral_stringz(tvb, offset, &string_len);
        proto_tree_add_item(ts2_tree, hf_ts2_channel_topic, tvb, offset,string_len ,TRUE);
        offset+=string_len;
        tvb_get_ephemeral_stringz(tvb, offset, &string_len);
        proto_tree_add_item(ts2_tree, hf_ts2_channel_description, tvb, offset,string_len , TRUE);
        offset+=string_len;
    }
}
Esempio n. 2
0
/* Process an APP2 block.
 *
 * XXX - This code only works on US-ASCII systems!!!
 */
static void
process_app2_segment(proto_tree *tree, tvbuff_t *tvb, guint32 len,
        guint16 marker, const char *marker_name)
{
    proto_item *ti = NULL;
    proto_tree *subtree = NULL;
    char *str;
    gint str_size;

    if (!tree)
        return;

    ti = proto_tree_add_item(tree, hf_marker_segment,
            tvb, 0, -1, ENC_NA);
    subtree = proto_item_add_subtree(ti, ett_marker_segment);

    proto_item_append_text(ti, ": %s (0x%04X)", marker_name, marker);
    proto_tree_add_item(subtree, hf_marker, tvb, 0, 2, ENC_BIG_ENDIAN);

    proto_tree_add_item(subtree, hf_len, tvb, 2, 2, ENC_BIG_ENDIAN);

    str = tvb_get_ephemeral_stringz(tvb, 4, &str_size);
    ti = proto_tree_add_item(subtree, hf_identifier, tvb, 4, str_size, ENC_ASCII|ENC_NA);
    if (strcmp(str, "FPXR") == 0) {
        proto_tree_add_text(tree, tvb, 0, -1, "Exif FlashPix APP2 application marker");
    } else {
        proto_tree_add_text(subtree, tvb, 4 + str_size, -1,
                "Remaining segment data (%u bytes)", len - 2 - str_size);
        proto_item_append_text(ti, " (Unknown identifier)");
    }
}
Esempio n. 3
0
/* Parses a ts2 channel list (TS2T_CHANNELLIST) and adds it to the tree */
static void ts2_parse_channellist(tvbuff_t *tvb, proto_tree *ts2_tree)
{
	gint32 offset;
	guint32 string_len;
	proto_tree	*subtree;
	proto_item	*item;

	offset=0;
	proto_tree_add_item(ts2_tree, hf_ts2_number_of_channels, tvb, offset, 4, ENC_LITTLE_ENDIAN);
	offset+=4;
	while(offset<tvb_length_remaining(tvb, 0))
	{
		proto_tree_add_item(ts2_tree, hf_ts2_channel_id, tvb, offset, 4, ENC_LITTLE_ENDIAN);
		offset+=4;

		/* Channel flags */
		item = proto_tree_add_item(ts2_tree, hf_ts2_channel_flags, tvb, offset, 1, ENC_LITTLE_ENDIAN);
		subtree = proto_item_add_subtree(item, ett_ts2_channel_flags);
		proto_tree_add_item(subtree, hf_ts2_channel_unregistered, tvb, offset, 1, ENC_BIG_ENDIAN);
		proto_tree_add_item(subtree, hf_ts2_channel_moderated, tvb, offset, 1, ENC_BIG_ENDIAN);
		proto_tree_add_item(subtree, hf_ts2_channel_password, tvb, offset, 1, ENC_BIG_ENDIAN);
		proto_tree_add_item(subtree, hf_ts2_channel_subchannels, tvb, offset, 1, ENC_BIG_ENDIAN);
		proto_tree_add_item(subtree, hf_ts2_channel_default, tvb, offset, 1, ENC_BIG_ENDIAN);
		offset+=1;

		proto_tree_add_item(ts2_tree, hf_ts2_unknown, tvb, offset, 1, ENC_NA);
		offset+=1;
		proto_tree_add_item(ts2_tree, hf_ts2_codec, tvb, offset, 2, ENC_LITTLE_ENDIAN);
		offset+=2;
		proto_tree_add_item(ts2_tree, hf_ts2_parent_channel_id, tvb, offset, 4, ENC_LITTLE_ENDIAN);
		offset+=4;
		proto_tree_add_item(ts2_tree, hf_ts2_channel_order, tvb, offset, 2, ENC_LITTLE_ENDIAN);
		offset+=2;
		proto_tree_add_item(ts2_tree, hf_ts2_max_users, tvb, offset, 2, ENC_LITTLE_ENDIAN);
		offset+=2;
		tvb_get_ephemeral_stringz(tvb, offset, &string_len);
		proto_tree_add_item(ts2_tree, hf_ts2_channel_name, tvb, offset,string_len , ENC_ASCII|ENC_NA);
		offset+=string_len;
		tvb_get_ephemeral_stringz(tvb, offset, &string_len);
		proto_tree_add_item(ts2_tree, hf_ts2_channel_topic, tvb, offset,string_len ,ENC_ASCII|ENC_NA);
		offset+=string_len;
		tvb_get_ephemeral_stringz(tvb, offset, &string_len);
		proto_tree_add_item(ts2_tree, hf_ts2_channel_description, tvb, offset,string_len , ENC_ASCII|ENC_NA);
		offset+=string_len;
	}
}
Esempio n. 4
0
WSLUA_METHOD TvbRange_stringz(lua_State* L) {
	/* Obtain a zero terminated string from a TvbRange */
    TvbRange tvbr = checkTvbRange(L,1);

    if ( !(tvbr && tvbr->tvb)) return 0;
    if (tvbr->tvb->expired) {
        luaL_error(L,"expired tvb");
        return 0;
    }

    lua_pushstring(L, (gchar*)tvb_get_ephemeral_stringz(tvbr->tvb->ws_tvb,tvbr->offset,NULL) );

    WSLUA_RETURN(1); /* The zero terminated string */
}
Esempio n. 5
0
int display_ms_string(tvbuff_t *tvb, proto_tree *tree, int offset, int hf_index, char **data)
{
	char *str;
	gint len;

	/* display a string from the tree and return the new offset */

	str = tvb_get_ephemeral_stringz(tvb, offset, &len);
	proto_tree_add_string(tree, hf_index, tvb, offset, len, str);

	/* Return a copy of the string if requested */

	if (data)
		*data = str;

	return 	offset+len;
}
Esempio n. 6
0
static void
dissect_wow_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	proto_item *ti;
	proto_tree *wow_tree, *wow_realms_tree;

	gchar *string, *realm_name;
	guint8 cmd, srp_i_len, srp_g_len, srp_n_len;
	guint16 num_realms;
	guint32 offset = 0;
	gint len, i;

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

	col_clear(pinfo->cinfo, COL_INFO);

	cmd = tvb_get_guint8(tvb, offset);

	if(check_col(pinfo->cinfo, COL_INFO)) {
		col_set_str(pinfo->cinfo, COL_INFO,
			    val_to_str_const(cmd, cmd_vs,
				       "Unrecognized packet type"));
	}

	if(tree) {
		ti = proto_tree_add_item(tree, proto_wow, tvb, 0, -1, ENC_NA);
		wow_tree = proto_item_add_subtree(ti, ett_wow);

		proto_tree_add_item(wow_tree, hf_wow_command, tvb, offset, 1,
				    ENC_LITTLE_ENDIAN);
		offset += 1;

		switch(cmd) {

		case AUTH_LOGON_CHALLENGE :

			if(WOW_CLIENT_TO_SERVER) {
				proto_tree_add_item(wow_tree, hf_wow_error, tvb,
						    offset, 1, ENC_LITTLE_ENDIAN);
				offset += 1;

				proto_tree_add_item(wow_tree, hf_wow_pkt_size,
						    tvb, offset, 2, ENC_LITTLE_ENDIAN);
				offset += 2;

				string = g_strreverse(tvb_get_ephemeral_string(tvb, offset, 4));
				proto_tree_add_string(wow_tree, hf_wow_gamename,
						      tvb, offset, 4, string);
				offset += 4;

				proto_tree_add_item(wow_tree, hf_wow_version1,
						    tvb, offset, 1, ENC_LITTLE_ENDIAN);
				offset += 1;

				proto_tree_add_item(wow_tree, hf_wow_version2,
						    tvb, offset, 1, ENC_LITTLE_ENDIAN);
				offset += 1;

				proto_tree_add_item(wow_tree, hf_wow_version3,
						    tvb, offset, 1, ENC_LITTLE_ENDIAN);
				offset += 1;

				proto_tree_add_item(wow_tree, hf_wow_build, tvb,
						    offset, 2, ENC_LITTLE_ENDIAN);
				offset += 2;

				string = g_strreverse(tvb_get_ephemeral_string(tvb, offset, 4));
				proto_tree_add_string(wow_tree, hf_wow_platform,
						      tvb, offset, 4, string);
				offset += 4;

				string = g_strreverse(tvb_get_ephemeral_string(tvb, offset, 4));
				proto_tree_add_string(wow_tree, hf_wow_os, tvb,
						      offset, 4, string);
				offset += 4;

				string = g_strreverse(tvb_get_ephemeral_string(tvb, offset, 4));
				proto_tree_add_string(wow_tree, hf_wow_country,
						      tvb, offset, 4, string);
				offset += 4;

				proto_tree_add_item(wow_tree,
						    hf_wow_timezone_bias,
						    tvb, offset, 4, ENC_LITTLE_ENDIAN);
				offset += 4;

				proto_tree_add_item(wow_tree, hf_wow_ip, tvb,
						    offset, 4, ENC_BIG_ENDIAN);
				offset += 4;

				proto_tree_add_item(wow_tree,
						    hf_wow_srp_i_len,
						    tvb, offset, 1, ENC_LITTLE_ENDIAN);
				srp_i_len = tvb_get_guint8(tvb, offset);
				offset += 1;

				proto_tree_add_item(wow_tree,
						    hf_wow_srp_i, tvb,
						    offset, srp_i_len,
						    ENC_ASCII|ENC_NA);
				offset += srp_i_len;


			} else if(WOW_SERVER_TO_CLIENT) {
				proto_tree_add_item(wow_tree, hf_wow_error, tvb,
						    offset, 1, ENC_LITTLE_ENDIAN);
				offset += 1;

				offset += 1; /* Unknown field */

				proto_tree_add_item(wow_tree, hf_wow_srp_b, tvb,
						    offset, 32, ENC_NA);
				offset += 32;

				proto_tree_add_item(wow_tree, hf_wow_srp_g_len,
						    tvb, offset, 1, ENC_LITTLE_ENDIAN);
				srp_g_len = tvb_get_guint8(tvb, offset);
				offset += 1;

				proto_tree_add_item(wow_tree, hf_wow_srp_g, tvb,
						    offset, srp_g_len, ENC_NA);
				offset += srp_g_len;

				proto_tree_add_item(wow_tree, hf_wow_srp_n_len,
						    tvb, offset, 1, ENC_LITTLE_ENDIAN);
				srp_n_len = tvb_get_guint8(tvb, offset);
				offset += 1;

				proto_tree_add_item(wow_tree, hf_wow_srp_n, tvb,
						    offset, srp_n_len, ENC_NA);
				offset += srp_n_len;

				proto_tree_add_item(wow_tree, hf_wow_srp_s, tvb,
						    offset, 32, ENC_NA);
				offset += 32;

				offset += 16; /* Unknown field */
			}

			break;

		case AUTH_LOGON_PROOF :

			if(WOW_CLIENT_TO_SERVER) {
				proto_tree_add_item(wow_tree, hf_wow_srp_a, tvb,
						    offset, 32, ENC_NA);
				offset += 32;

				proto_tree_add_item(wow_tree, hf_wow_srp_m1,
						    tvb, offset, 20, ENC_NA);
				offset += 20;

				proto_tree_add_item(wow_tree, hf_wow_crc_hash,
						    tvb, offset, 20, ENC_NA);
				offset += 20;

				proto_tree_add_item(wow_tree, hf_wow_num_keys,
						    tvb, offset, 1, ENC_LITTLE_ENDIAN);
				offset += 1;

				offset += 1; /* Unknown field */

			} else if(WOW_SERVER_TO_CLIENT) {
				proto_tree_add_item(wow_tree, hf_wow_error, tvb,
						    offset, 1, ENC_LITTLE_ENDIAN);
				offset += 1;

				proto_tree_add_item(wow_tree, hf_wow_srp_m2,
						    tvb, offset, 20, ENC_NA);
				offset += 20;

				offset += 4; /* Unknown field */

				offset += 2; /* Unknown field */
			}

			break;

		case REALM_LIST :

			if(WOW_CLIENT_TO_SERVER) {


			} else if(WOW_SERVER_TO_CLIENT) {

				proto_tree_add_item(wow_tree, hf_wow_pkt_size,
						    tvb, offset, 2, ENC_LITTLE_ENDIAN);
				offset += 2;

				offset += 4; /* Unknown field; always 0 */

				proto_tree_add_item(wow_tree, hf_wow_num_realms,
						    tvb, offset, 2, ENC_LITTLE_ENDIAN);
				num_realms = tvb_get_letohs(tvb, offset);
				offset += 2;

				for(i = 1; i <= num_realms; i++) {
					realm_name = tvb_get_ephemeral_stringz(tvb,
								     offset + 3,
								     &len);

					ti = proto_tree_add_text(wow_tree, tvb,
								 offset, 0,
								 "%s",
								 realm_name);

					wow_realms_tree = proto_item_add_subtree(ti, ett_wow_realms);
					proto_tree_add_item(wow_realms_tree, hf_wow_realm_type, tvb, offset, 1, ENC_LITTLE_ENDIAN);
					offset += 1;

					proto_tree_add_item(wow_realms_tree, hf_wow_realm_status, tvb, offset, 1, ENC_LITTLE_ENDIAN);
					offset += 1;

					proto_tree_add_item(wow_realms_tree, hf_wow_realm_color, tvb, offset, 1, ENC_LITTLE_ENDIAN);
					offset += 1;

					proto_tree_add_string(wow_realms_tree, hf_wow_realm_name, tvb, offset, len, realm_name);
					offset += len;

					string = tvb_get_ephemeral_stringz(tvb, offset,
								 &len);
					proto_tree_add_string(wow_realms_tree, hf_wow_realm_socket, tvb, offset, len, string);
					offset += len;

					proto_tree_add_item(wow_realms_tree, hf_wow_realm_population_level, tvb, offset, 4, ENC_LITTLE_ENDIAN);
					offset += 4;

					proto_tree_add_item(wow_realms_tree, hf_wow_realm_num_characters, tvb, offset, 1, ENC_LITTLE_ENDIAN);
					offset += 1;

					proto_tree_add_item(wow_realms_tree, hf_wow_realm_timezone, tvb, offset, 1, ENC_LITTLE_ENDIAN);
					offset += 1;

					offset += 1; /* Unknown field */
				}

				break;
			}
		}
	}
}
Esempio n. 7
0
/* Process an APP1 block.
 *
 * XXX - This code only works on US-ASCII systems!!!
 */
static int
process_app1_segment(proto_tree *tree, tvbuff_t *tvb, guint32 len,
        guint16 marker, const char *marker_name)
{
    proto_item *ti = NULL;
    proto_tree *subtree = NULL;
    char *str;
    gint str_size;
    int offset = 0;
    int tiff_start;

    if (!tree)
        return 0;

    ti = proto_tree_add_item(tree, hf_marker_segment,
            tvb, 0, -1, ENC_NA);
    subtree = proto_item_add_subtree(ti, ett_marker_segment);

    proto_item_append_text(ti, ": %s (0x%04X)", marker_name, marker);
    proto_tree_add_item(subtree, hf_marker, tvb, offset, 2, ENC_BIG_ENDIAN);
    offset += 2;

    proto_tree_add_item(subtree, hf_len, tvb, offset, 2, ENC_BIG_ENDIAN);
    offset += 2;

    str = tvb_get_ephemeral_stringz(tvb, offset, &str_size);
    ti = proto_tree_add_item(subtree, hf_identifier, tvb, offset, str_size, ENC_ASCII|ENC_NA);
    offset += str_size;
    if (strcmp(str, "Exif") == 0) {
        /*
         * Endianness
         */
        gboolean is_little_endian;
        guint16 val_16;
        guint32 val_32;
        guint16 num_fields;

        offset++; /* Skip a byte supposed to be 0x00 */

        tiff_start = offset;
        val_16 = tvb_get_ntohs(tvb, offset);
        if (val_16 == 0x4949) {
            is_little_endian = TRUE;
            proto_tree_add_text(subtree, tvb, offset, 2, "Endianness: little endian");
        } else if (val_16 == 0x4D4D) {
            is_little_endian = FALSE;
            proto_tree_add_text(subtree, tvb, offset, 2, "Endianness: big endian");
        } else {
            /* Error: invalid endianness encoding */
            proto_tree_add_text(subtree, tvb, offset, 2,
                    "Incorrect endianness encoding - skipping the remainder of this application marker");
            return offset;
        }
        offset += 2;
        /*
         * Fixed value 42 = 0x002a
         */
        offset += 2;
        /*
         * Offset to IFD
         */
        if (is_little_endian) {
            val_32 = tvb_get_letohl(tvb, offset);
        } else {
            val_32 = tvb_get_ntohl(tvb, offset);
        }
        /*
         * Check for a bogus val_32 value.
         * XXX - bogus value message should also deal with a
         * value that's too large and causes an overflow.
         * Or should it just check against the segment length,
         * which is 16 bits?
         */
        if (val_32 + tiff_start < (guint32)offset + 4) {
            proto_tree_add_text(subtree, tvb, offset, 4,
                "Start offset of IFD starting from the TIFF header start: %u bytes (bogus, should be >= %u",
                val_32, offset + 4 - tiff_start);
            return offset;
        }
        proto_tree_add_text(subtree, tvb, offset, 4,
            "Start offset of IFD starting from the TIFF header start: %u bytes",
            val_32);
        offset += 4;
        /*
         * Skip the following portion
         */
        if (val_32 + tiff_start > (guint32)offset) {
            proto_tree_add_text(subtree, tvb, offset, val_32 + tiff_start - offset,
                "Skipped data between end of TIFF header and start of IFD (%u bytes)",
                val_32 + tiff_start - offset);
        }
        for (;;) {
            offset = val_32 + tiff_start;
            /*
             * Process the IFD
             */
            if (is_little_endian) {
                num_fields = tvb_get_letohs(tvb, offset);
            } else {
                num_fields = tvb_get_ntohs(tvb, offset);
            }
            proto_tree_add_text(subtree, tvb, offset, 2, "Number of fields in this IFD: %u", num_fields);
            offset += 2;
            while (num_fields-- > 0) {
                guint16 tag, type;
                guint32 count, off;

                if (is_little_endian) {
                    tag = tvb_get_letohs(tvb, offset);
                    type = tvb_get_letohs(tvb, offset + 2);
                    count = tvb_get_letohl(tvb, offset + 4);
                    off = tvb_get_letohl(tvb, offset + 8);
                } else {
                    tag = tvb_get_ntohs(tvb, offset);
                    type = tvb_get_ntohs(tvb, offset + 2);
                    count = tvb_get_ntohl(tvb, offset + 4);
                    off = tvb_get_ntohl(tvb, offset + 8);
                }
                /* TODO - refine this */
                proto_tree_add_text(subtree, tvb, offset, 2,
                    "Exif Tag: 0x%04X (%s), Type: %u (%s), Count: %u, "
                    "Value offset from start of TIFF header: %u",
                    tag, val_to_str(tag, vals_exif_tags, "Unknown Exif tag"),
                    type, val_to_str(type, vals_exif_types, "Unknown Exif type"),
                    count, off);
                offset += 12;
            }
            /*
             * Offset to the next IFD
             */
            if (is_little_endian) {
                val_32 = tvb_get_letohl(tvb, offset);
            } else {
                val_32 = tvb_get_ntohl(tvb, offset);
            }
            if (val_32 != 0 &&
                val_32 + tiff_start < (guint32)offset + 4) {
                proto_tree_add_text(subtree, tvb, offset, 4,
                    "Offset to next IFD from start of TIFF header: %u bytes (bogus, should be >= %u)",
                    val_32, offset + 4 - tiff_start);
                return offset;
            }
            proto_tree_add_text(subtree, tvb, offset, 4,
                "Offset to next IFD from start of TIFF header: %u bytes",
                val_32);
            offset += 4;
            if (val_32 == 0)
                break;
        }
    } else {
        proto_tree_add_text(subtree, tvb, offset, -1,
                "Remaining segment data (%u bytes)", len - 2 - str_size);
        proto_item_append_text(ti, " (Unknown identifier)");
    }
    return offset;
}
Esempio n. 8
0
/* Process an APP0 block.
 *
 * XXX - This code only works on US-ASCII systems!!!
 */
static int
process_app0_segment(proto_tree *tree, tvbuff_t *tvb, guint32 len,
        guint16 marker, const char *marker_name)
{
    proto_item *ti = NULL;
    proto_tree *subtree = NULL;
    proto_tree *subtree_details = NULL;
    guint32 offset;
    char *str;
    gint str_size;

    if (!tree)
        return 0 ;

    ti = proto_tree_add_item(tree, hf_marker_segment,
            tvb, 0, -1, ENC_NA);
    subtree = proto_item_add_subtree(ti, ett_marker_segment);

    proto_item_append_text(ti, ": %s (0x%04X)", marker_name, marker);
    proto_tree_add_item(subtree, hf_marker, tvb, 0, 2, ENC_BIG_ENDIAN);

    proto_tree_add_item(subtree, hf_len, tvb, 2, 2, ENC_BIG_ENDIAN);

    str = tvb_get_ephemeral_stringz(tvb, 4, &str_size);
    ti = proto_tree_add_item(subtree, hf_identifier, tvb, 4, str_size, ENC_ASCII|ENC_NA);
    if (strcmp(str, "JFIF") == 0) {
        /* Version */
        ti = proto_tree_add_none_format(subtree, hf_version,
                tvb, 9, 2, "Version: %u.%u",
                tvb_get_guint8(tvb, 9),
                tvb_get_guint8(tvb, 10));
        subtree_details = proto_item_add_subtree(ti, ett_details);
        proto_tree_add_item(subtree_details, hf_version_major,
                tvb, 9, 1, ENC_BIG_ENDIAN);
        proto_tree_add_item(subtree_details, hf_version_minor,
                tvb, 10, 1, ENC_BIG_ENDIAN);

        proto_tree_add_item(subtree, hf_units,
                tvb, 11, 1, ENC_BIG_ENDIAN);

        /* Aspect ratio */
        proto_tree_add_item(subtree, hf_xdensity,
                tvb, 12, 2, ENC_BIG_ENDIAN);
        proto_tree_add_item(subtree, hf_ydensity,
                tvb, 14, 2, ENC_BIG_ENDIAN);

        /* Thumbnail */
        proto_tree_add_item(subtree, hf_xthumbnail,
                tvb, 16, 1, ENC_BIG_ENDIAN);
        proto_tree_add_item(subtree, hf_ythumbnail,
                tvb, 17, 1, ENC_BIG_ENDIAN);
        {
            guint16 x = tvb_get_guint8(tvb, 16);
            guint16 y = tvb_get_guint8(tvb, 17);
            if (x || y) {
                proto_tree_add_item(subtree, hf_rgb,
                        tvb, 18, 3 * (x * y), ENC_NA);
                offset = 18 + (3 * (x * y));
            } else {
                offset = 18;
            }
        }
    } else if (strcmp(str, "JFXX") == 0) {
        proto_tree_add_item(subtree, hf_extension_code,
                tvb, 9, 1, ENC_BIG_ENDIAN);
        {
            guint8 code = tvb_get_guint8(tvb, 9);
            switch (code) {
                case 0x10: /* Thumbnail coded using JPEG */
                    break;
                case 0x11: /* thumbnail stored using 1 byte per pixel */
                    break;
                case 0x13: /* thumbnail stored using 3 bytes per pixel */
                    break;
                default: /* Error */
                    break;
            }
        }
        offset = 10;
    } else { /* Unknown */
        proto_item_append_text(ti, " (unknown identifier)");
        offset = 4 + str_size;

        proto_tree_add_text(subtree, tvb, offset, -1,
                "Remaining segment data (%u bytes)", len - 2 - str_size);
    }
    return offset;
}
Esempio n. 9
0
static int
dissect_bson_document(tvbuff_t *tvb, packet_info *pinfo, guint offset, proto_tree *tree, int hf_mongo_doc, int nest_level)
{
  gint32 document_length;
  guint final_offset;
  proto_item *ti, *elements, *element, *objectid, *js_code, *js_scope;
  proto_tree *doc_tree, *elements_tree, *element_sub_tree, *objectid_sub_tree, *js_code_sub_tree, *js_scope_sub_tree;

  document_length = tvb_get_letohl(tvb, offset);

  ti = proto_tree_add_item(tree, hf_mongo_doc, tvb, offset, document_length, ENC_NA);
  doc_tree = proto_item_add_subtree(ti, ett_mongo_doc);

  proto_tree_add_item(doc_tree, hf_mongo_document_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);

  if (nest_level > BSON_MAX_NESTING) {
      expert_add_info_format_text(pinfo, ti, &ei_mongo_document_recursion_exceeded, "BSON document recursion exceeds %u", BSON_MAX_NESTING);
      THROW(ReportedBoundsError);
  }

  if (document_length < 5) {
      expert_add_info_format_text(pinfo, ti, &ei_mongo_document_length_bad, "BSON document length too short: %u", document_length);
      THROW(ReportedBoundsError);
  }

  if (document_length > BSON_MAX_DOC_SIZE) {
      expert_add_info_format_text(pinfo, ti, &ei_mongo_document_length_bad, "BSON document length too long: %u", document_length);
      THROW(ReportedBoundsError);
  }

  if (document_length == 5) {
    /* document with length 5 is an empty document */
    /* don't display the element subtree */
    proto_tree_add_item(tree, hf_mongo_document_empty, tvb, offset, document_length, ENC_NA);
    return document_length;
  }

  final_offset = offset + document_length;
  offset += 4;

  elements = proto_tree_add_item(doc_tree, hf_mongo_elements, tvb, offset, document_length-5, ENC_NA);
  elements_tree = proto_item_add_subtree(elements, ett_mongo_elements);

  do {
    /* Read document elements */
    guint8 e_type = -1;  /* Element type */
    gint str_len = -1;   /* String length */
    gint e_len = -1;     /* Element length */
    gint doc_len = -1;   /* Document length */

    e_type = tvb_get_guint8(tvb, offset);
    tvb_get_ephemeral_stringz(tvb, offset+1, &str_len);

    element = proto_tree_add_item(elements_tree, hf_mongo_element_name, tvb, offset+1, str_len-1, ENC_UTF_8|ENC_NA);
    element_sub_tree = proto_item_add_subtree(element, ett_mongo_element);
    proto_tree_add_item(element_sub_tree, hf_mongo_element_type, tvb, offset, 1, ENC_LITTLE_ENDIAN);

    offset += str_len+1;

    switch(e_type) {
      case BSON_ELEMENT_TYPE_DOUBLE:
        proto_tree_add_item(element_sub_tree, hf_mongo_element_value_double, tvb, offset, 8, ENC_LITTLE_ENDIAN);
        offset += 8;
        break;
      case BSON_ELEMENT_TYPE_STRING:
      case BSON_ELEMENT_TYPE_JS_CODE:
      case BSON_ELEMENT_TYPE_SYMBOL:
        str_len = tvb_get_letohl(tvb, offset);
        proto_tree_add_item(element_sub_tree, hf_mongo_element_value_string_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
        proto_tree_add_item(element_sub_tree, hf_mongo_element_value_string, tvb, offset+4, str_len, ENC_UTF_8|ENC_NA);
        offset += str_len+4;
        break;
      case BSON_ELEMENT_TYPE_DOC:
      case BSON_ELEMENT_TYPE_ARRAY:
        offset += dissect_bson_document(tvb, pinfo, offset, element_sub_tree, hf_mongo_document, nest_level+1);
        break;
      case BSON_ELEMENT_TYPE_BINARY:
        e_len = tvb_get_letohl(tvb, offset);
        /* TODO - Add functions to decode various binary subtypes */
        proto_tree_add_item(element_sub_tree, hf_mongo_element_value_binary_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
        proto_tree_add_item(element_sub_tree, hf_mongo_element_value_binary, tvb, offset+5, e_len, ENC_NA);
        offset += e_len+5;
        break;
      case BSON_ELEMENT_TYPE_UNDEF:
      case BSON_ELEMENT_TYPE_NULL:
      case BSON_ELEMENT_TYPE_MIN_KEY:
      case BSON_ELEMENT_TYPE_MAX_KEY:
        /* Nothing to do, as there is no element content */
        break;
      case BSON_ELEMENT_TYPE_OBJ_ID:
        objectid = proto_tree_add_item(element_sub_tree, hf_mongo_element_value_objectid, tvb, offset, 12, ENC_NA);
        objectid_sub_tree = proto_item_add_subtree(objectid, ett_mongo_objectid);
        /* Unlike most BSON elements, parts of ObjectID are stored Big Endian, so they can be compared bit by bit */
        proto_tree_add_item(objectid_sub_tree, hf_mongo_element_value_objectid_time, tvb, offset, 4, ENC_BIG_ENDIAN);
        proto_tree_add_item(objectid_sub_tree, hf_mongo_element_value_objectid_machine, tvb, offset+4, 3, ENC_LITTLE_ENDIAN);
        proto_tree_add_item(objectid_sub_tree, hf_mongo_element_value_objectid_pid, tvb, offset+7, 2, ENC_LITTLE_ENDIAN);
        proto_tree_add_item(objectid_sub_tree, hf_mongo_element_value_objectid_inc, tvb, offset+9, 3, ENC_BIG_ENDIAN);
        offset += 12;
        break;
      case BSON_ELEMENT_TYPE_BOOL:
        proto_tree_add_item(element_sub_tree, hf_mongo_element_value_boolean, tvb, offset, 1, ENC_NA);
        offset += 1;
        break;
      case BSON_ELEMENT_TYPE_REGEX:
        /* regex pattern */
        tvb_get_ephemeral_stringz(tvb, offset, &str_len);
        proto_tree_add_item(element_sub_tree, hf_mongo_element_value_regex_pattern, tvb, offset, str_len, ENC_UTF_8|ENC_NA);
        offset += str_len;
        /* regex options */
        tvb_get_ephemeral_stringz(tvb, offset, &str_len);
        proto_tree_add_item(element_sub_tree, hf_mongo_element_value_regex_options, tvb, offset, str_len, ENC_UTF_8|ENC_NA);
        offset += str_len;
        break;
      case BSON_ELEMENT_TYPE_DB_PTR:
        str_len = tvb_get_letohl(tvb, offset);
        proto_tree_add_item(element_sub_tree, hf_mongo_element_value_string_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
        proto_tree_add_item(element_sub_tree, hf_mongo_element_value_string, tvb, offset+4, str_len, ENC_UTF_8|ENC_NA);
        offset += str_len;
        proto_tree_add_item(element_sub_tree, hf_mongo_element_value_db_ptr, tvb, offset, 12, ENC_NA);
        offset += 12;
        break;
      case BSON_ELEMENT_TYPE_JS_CODE_SCOPE:
        /* code_w_s ::= int32 string document */
        proto_tree_add_item(element_sub_tree, hf_mongo_element_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
        e_len = tvb_get_letohl(tvb, offset);
        offset += 4;
        str_len = tvb_get_letohl(tvb, offset);
        js_code = proto_tree_add_item(element_sub_tree, hf_mongo_element_value_js_code, tvb, offset, str_len+4, ENC_NA);
        js_code_sub_tree = proto_item_add_subtree(js_code, ett_mongo_code);
        proto_tree_add_item(js_code_sub_tree, hf_mongo_element_value_string_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
        proto_tree_add_item(js_code_sub_tree, hf_mongo_element_value_string, tvb, offset+4, str_len, ENC_UTF_8|ENC_NA);
        offset += str_len+4;
        doc_len = e_len - (str_len + 8);
        js_scope = proto_tree_add_item(element_sub_tree, hf_mongo_element_value_js_scope, tvb, offset, doc_len, ENC_NA);
        js_scope_sub_tree = proto_item_add_subtree(js_scope, ett_mongo_code);
        offset += dissect_bson_document(tvb, pinfo, offset, js_scope_sub_tree, hf_mongo_document, nest_level+1);
        break;
      case BSON_ELEMENT_TYPE_INT32:
        proto_tree_add_item(element_sub_tree, hf_mongo_element_value_int32, tvb, offset, 4, ENC_LITTLE_ENDIAN);
        offset += 4;
        break;
      case BSON_ELEMENT_TYPE_DATETIME:
      case BSON_ELEMENT_TYPE_TIMESTAMP:
        /* TODO Implement routine to convert datetime & timestamp values to UTC date/time */
        /* for now, simply display the integer value */
      case BSON_ELEMENT_TYPE_INT64:
        proto_tree_add_item(element_sub_tree, hf_mongo_element_value_int64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
        offset += 8;
        break;
      default:
        break;
    }  /* end switch() */
  } while (offset < final_offset-1);

  return document_length;
}
Esempio n. 10
0
static void
dissect_exec(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	/* Set up structures needed to add the protocol subtree and manage it */
	proto_item *ti;
	proto_tree *exec_tree=NULL;

	/* Variables for extracting and displaying data from the packet */
	guchar *field_stringz; /* Temporary storage for each field we extract */

	gint length;
	guint offset = 0;
	conversation_t *conversation;
	exec_hash_entry_t *hash_info;

	conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->srcport, pinfo->destport, 0);

	if(!conversation){  /* Conversation does not exist yet - create it */
		conversation = conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
	}


	/* Retrieve information from conversation 
	 * or add it if it isn't there yet
	 */
	hash_info = conversation_get_proto_data(conversation, proto_exec);
	if(!hash_info){
		hash_info = se_alloc(sizeof(exec_hash_entry_t));
      
		hash_info->first_packet_number = pinfo->fd->num;
		hash_info->second_packet_number = 0;
		hash_info->third_packet_number  = 0;
		hash_info->fourth_packet_number  = 0;

		hash_info->state = WAIT_FOR_STDERR_PORT; /* The first field we'll see */

		/* Start with empty username and command strings */
		hash_info->username=NULL;
		hash_info->command=NULL;

		/* These will be set on the first pass by the first 
		 * four packets of the conversation
		 */
		hash_info->first_packet_state  = NONE;
		hash_info->second_packet_state = NONE;
		hash_info->third_packet_state  = NONE;
		hash_info->fourth_packet_state  = NONE;

		conversation_add_proto_data(conversation, proto_exec, hash_info);
	}

	/* Store the number of the first three packets of this conversation
	 * as we reach them the first time */

	if(!hash_info->second_packet_number
	&& pinfo->fd->num > hash_info->first_packet_number){
		/* We're on the second packet of the conversation */
		hash_info->second_packet_number = pinfo->fd->num;
	} else if(hash_info->second_packet_number
	 && !hash_info->third_packet_number
	 && pinfo->fd->num > hash_info->second_packet_number) {
		/* We're on the third packet of the conversation */
		hash_info->third_packet_number = pinfo->fd->num;
	} else if(hash_info->third_packet_number
	 && !hash_info->fourth_packet_number
	 && pinfo->fd->num > hash_info->third_packet_number) {
		/* We're on the fourth packet of the conversation */
		hash_info->fourth_packet_number = pinfo->fd->num;
	}

	/* Save this packet's state so we can retrieve it if this packet
	 * is selected again later.  If the packet's state was already stored,
	 * then retrieve it */
	if(pinfo->fd->num == hash_info->first_packet_number){
		if(hash_info->first_packet_state == NONE){
			hash_info->first_packet_state = hash_info->state;
		} else {
			hash_info->state = hash_info->first_packet_state;
		}
	}
      
	if(pinfo->fd->num == hash_info->second_packet_number){
		if(hash_info->second_packet_state == NONE){
			hash_info->second_packet_state = hash_info->state;
		} else {
			hash_info->state = hash_info->second_packet_state;
		}
	}
      
	if(pinfo->fd->num == hash_info->third_packet_number){
		if(hash_info->third_packet_state == NONE){
			hash_info->third_packet_state = hash_info->state;
		} else {
			hash_info->state = hash_info->third_packet_state;
		}
	}
      
	if(pinfo->fd->num == hash_info->fourth_packet_number){
		if(hash_info->fourth_packet_state == NONE){
			hash_info->fourth_packet_state = hash_info->state;
		} else {
			hash_info->state = hash_info->fourth_packet_state;
		}
	}

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

	if(check_col(pinfo->cinfo, COL_INFO)){
		/* First, clear the info column */
		col_clear(pinfo->cinfo, COL_INFO);

		/*username */
		if(hash_info->username && preference_info_show_username == TRUE){
			col_append_fstr(pinfo->cinfo, COL_INFO, "Username:%s ", hash_info->username);
		}
      
		/* Command */
		if(hash_info->command && preference_info_show_command == TRUE){
			col_append_fstr(pinfo->cinfo, COL_INFO, "Command:%s ", hash_info->command);
		}
	}
  
	/* create display subtree for the protocol */
	ti = proto_tree_add_item(tree, proto_exec, tvb, 0, -1, FALSE);
	exec_tree = proto_item_add_subtree(ti, ett_exec);

	/* If this packet doesn't end with a null terminated string,
	 * then it must be session data only and we can skip looking
	 * for the other fields.
	 */
	if(tvb_find_guint8(tvb, tvb_length(tvb)-1, 1, '\0') == -1){
		hash_info->state = WAIT_FOR_DATA;
	}

	if(hash_info->state == WAIT_FOR_STDERR_PORT
	&& tvb_length_remaining(tvb, offset)){
		field_stringz = tvb_get_ephemeral_stringz(tvb, offset, &length);

		/* Check if this looks like the stderr_port field.
		 * It is optional, so it may only be 1 character long
		 * (the NULL)
		 */
		if(length == 1 || (exec_isdigit_string(field_stringz)
		&& length <= EXEC_STDERR_PORT_LEN)){
			proto_tree_add_string(exec_tree, hf_exec_stderr_port, tvb, offset, length, (gchar*)field_stringz);
			 /* Next field we need */
			hash_info->state = WAIT_FOR_USERNAME;
		} else { 
			/* Since the data doesn't match this field, it must be data only */
			hash_info->state = WAIT_FOR_DATA;
		}
       
		/* Used if the next field is in the same packet */
		offset += length;
	}
  
 
	if(hash_info->state == WAIT_FOR_USERNAME
	&& tvb_length_remaining(tvb, offset)){
		field_stringz = tvb_get_ephemeral_stringz(tvb, offset, &length);
	  
		/* Check if this looks like the username field */
		if(length != 1 && length <= EXEC_USERNAME_LEN
		&& exec_isprint_string(field_stringz)){
			proto_tree_add_string(exec_tree, hf_exec_username, tvb, offset, length, (gchar*)field_stringz);

			/* Store the username so we can display it in the 
			 * info column of the entire conversation
			 */
			if(!hash_info->username){
				hash_info->username=se_strdup((gchar*)field_stringz);
			}

			 /* Next field we need */
			hash_info->state = WAIT_FOR_PASSWORD;
		} else { 
			/* Since the data doesn't match this field, it must be data only */
			hash_info->state = WAIT_FOR_DATA;
		}
 
		/* Used if the next field is in the same packet */
		offset += length;
	}
      

	if(hash_info->state == WAIT_FOR_PASSWORD
	&& tvb_length_remaining(tvb, offset)){
		field_stringz = tvb_get_ephemeral_stringz(tvb, offset, &length);
	  
		/* Check if this looks like the password field */
		if(length != 1 && length <= EXEC_PASSWORD_LEN
		&& exec_isprint_string(field_stringz)){
			proto_tree_add_string(exec_tree, hf_exec_password, tvb, offset, length, (gchar*)field_stringz);

			/* Next field we need */
			hash_info->state = WAIT_FOR_COMMAND;
		} else {
			/* Since the data doesn't match this field, it must be data only */
			hash_info->state = WAIT_FOR_DATA;
		}
	  
		/* Used if the next field is in the same packet */
		offset += length;
		 /* Next field we are looking for */
		hash_info->state = WAIT_FOR_COMMAND;
	}
      

	if(hash_info->state == WAIT_FOR_COMMAND
	&& tvb_length_remaining(tvb, offset)){
		field_stringz = tvb_get_ephemeral_stringz(tvb, offset, &length);
	  
		/* Check if this looks like the command field */
		if(length != 1 && length <= EXEC_COMMAND_LEN
		&& exec_isprint_string(field_stringz)){
			proto_tree_add_string(exec_tree, hf_exec_command, tvb, offset, length, (gchar*)field_stringz);
	      
			/* Store the username so we can display it in the 
			 * info column of the entire conversation
			 */
			if(!hash_info->command){
				hash_info->command=se_strdup((gchar*)field_stringz);
			}

		} else {
			/* Since the data doesn't match this field, it must be data only */
			hash_info->state = WAIT_FOR_DATA;
		}
	}

  
	if(hash_info->state == WAIT_FOR_DATA
	&& tvb_length_remaining(tvb, offset)){
		if(pinfo->destport == EXEC_PORT){
			/* Packet going to the server */
			/* offset = 0 since the whole packet is data */
			proto_tree_add_text(exec_tree, tvb, 0, -1, "Client -> Server Data");
	  
			if(check_col(pinfo->cinfo, COL_INFO))
				col_append_str(pinfo->cinfo, COL_INFO, "Client -> Server data");
		} else {
			/* This packet must be going back to the client */
			/* offset = 0 since the whole packet is data */
			proto_tree_add_text(exec_tree, tvb, 0, -1, "Server -> Client Data");
	  
			if(check_col(pinfo->cinfo, COL_INFO))
				col_append_str(pinfo->cinfo, COL_INFO, "Server -> Client Data");
		}
	}

	/* We haven't seen all of the fields yet */
	if(hash_info->state < WAIT_FOR_DATA){
		col_set_str(pinfo->cinfo, COL_INFO, "Session Establishment");
	}
}
Esempio n. 11
0
static void dissect_turbocell(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{

    proto_item *ti, *name_item;
    proto_tree *turbocell_tree = NULL, *network_tree;
    tvbuff_t   *next_tvb;
    int i=0;
    guint8 packet_type;
    guint8 * str_name;
    guint str_len;
    gint remaining_length;

    packet_type = tvb_get_guint8(tvb, 0);

    if (!(packet_type & 0x0F)) {
        col_set_str(pinfo->cinfo, COL_INFO, "Turbocell Packet (Beacon)");
        col_set_str(pinfo->cinfo, COL_PROTOCOL, "Turbocell");
    }  else if ( packet_type == TURBOCELL_TYPE_MANAGEMENT ) {
        col_set_str(pinfo->cinfo, COL_INFO, "Turbocell Packet (Management)");
        col_set_str(pinfo->cinfo, COL_PROTOCOL, "Turbocell");
    } else if ( packet_type == TURBOCELL_TYPE_DATA ) {
        col_set_str(pinfo->cinfo, COL_INFO, "Turbocell Packet (Data)");
        col_set_str(pinfo->cinfo, COL_PROTOCOL, "Turbocell");
    } else {
        col_set_str(pinfo->cinfo, COL_INFO, "Turbocell Packet (Unknown)");
        col_set_str(pinfo->cinfo, COL_PROTOCOL, "Turbocell");
    }

    if (tree) {
        ti = proto_tree_add_item(tree, proto_turbocell, tvb, 0, 20, ENC_NA);

        turbocell_tree = proto_item_add_subtree(ti, ett_turbocell);

        proto_tree_add_item(turbocell_tree, hf_turbocell_type, tvb, 0, 1, ENC_BIG_ENDIAN);
        proto_tree_add_item(turbocell_tree, hf_turbocell_satmode, tvb, 1, 1, ENC_BIG_ENDIAN);
        proto_tree_add_item(turbocell_tree, hf_turbocell_nwid, tvb, 1, 1, ENC_BIG_ENDIAN);

        /* it seem when we have this magic number,that means an alternate header version */

        if (tvb_get_bits64(tvb, 64,48,ENC_BIG_ENDIAN) != G_GINT64_CONSTANT(0x000001fe23dc45ba)) {
            proto_tree_add_item(turbocell_tree, hf_turbocell_counter, tvb, 0x02, 2, ENC_BIG_ENDIAN);
            proto_tree_add_item(turbocell_tree, hf_turbocell_dst, tvb, 0x04, 6, ENC_NA);
            proto_tree_add_item(turbocell_tree, hf_turbocell_timestamp, tvb, 0x0A, 3, ENC_BIG_ENDIAN);

        } else {
            proto_tree_add_item(turbocell_tree, hf_turbocell_timestamp, tvb, 0x02, 3, ENC_BIG_ENDIAN);
            proto_tree_add_item(turbocell_tree, hf_turbocell_counter, tvb, 0x05, 3, ENC_BIG_ENDIAN);
            proto_tree_add_item(turbocell_tree, hf_turbocell_dst, tvb, 0x08, 6, ENC_NA);
        }

        proto_tree_add_item(turbocell_tree, hf_turbocell_unknown, tvb, 0x0E, 2, ENC_BIG_ENDIAN);
        proto_tree_add_item(turbocell_tree, hf_turbocell_ip, tvb, 0x10, 4, ENC_BIG_ENDIAN);

    }

    remaining_length=tvb_length_remaining(tvb, 0x14);

    if (remaining_length > 6) {

        /* If the first character is a printable character that means we have a payload with network info */
        /* I couldn't find anything in the header that would definitvely indicate if payload is either data or network info */
        /* Since the frame size is limited this should work ok */

        if (tvb_get_guint8(tvb, 0x14)>=0x20) {
            name_item = proto_tree_add_item(turbocell_tree, hf_turbocell_name, tvb, 0x14, 30, ENC_ASCII|ENC_NA);
            network_tree = proto_item_add_subtree(name_item, ett_network);

            str_name=tvb_get_ephemeral_stringz(tvb, 0x14, &str_len);
            if (check_col (pinfo->cinfo, COL_INFO) && str_len > 0)
                col_append_fstr(pinfo->cinfo, COL_INFO, ", Network=\"%s\"",format_text(str_name, str_len-1));

            while(tvb_get_guint8(tvb, 0x34 + 8*i)==0x00 && (tvb_length_remaining(tvb,0x34 + 8*i) > 6) && (i<32)) {
                proto_tree_add_item(network_tree, hf_turbocell_station[i], tvb, 0x34+8*i, 6, ENC_NA);
                i++;
            }

            /*Couldn't make sense of the apparently random data in the end*/

            next_tvb = tvb_new_subset_remaining(tvb, 0x34 + 8*i);
            call_dissector(data_handle, next_tvb, pinfo, tree);

        } else {

            tvbuff_t *volatile msdu_tvb = NULL;
            guint32 msdu_offset = 0x04;
            guint16 j = 1;
            guint16 msdu_length;

            proto_item *parent_item;
            proto_tree *mpdu_tree;
            proto_tree *subframe_tree;

            next_tvb = tvb_new_subset(tvb, 0x14, -1, tvb_get_ntohs(tvb, 0x14));
            parent_item = proto_tree_add_protocol_format(tree, proto_aggregate, next_tvb, 0,
                          tvb_reported_length_remaining(next_tvb, 0), "Turbocell Aggregate Frames");
            mpdu_tree = proto_item_add_subtree(parent_item, ett_msdu_aggregation_parent_tree);
            proto_tree_add_item(mpdu_tree, hf_turbocell_aggregate_len, next_tvb, 0x00, 2, ENC_BIG_ENDIAN);
            proto_tree_add_item(mpdu_tree, hf_turbocell_aggregate_unknown1, next_tvb, 0x02, 2, ENC_BIG_ENDIAN);

            remaining_length=tvb_length_remaining(next_tvb, msdu_offset);

            do {
                msdu_length = (tvb_get_letohs(next_tvb, msdu_offset) & 0x0FFF);
                if (msdu_length==0) break;
                parent_item = proto_tree_add_uint_format(mpdu_tree, hf_turbocell_aggregate_msdu_header_text,
                              next_tvb,msdu_offset, msdu_length + 0x02,j, "A-MSDU Subframe #%u", j);

                subframe_tree = proto_item_add_subtree(parent_item, ett_msdu_aggregation_subframe_tree);
                j++;

                proto_tree_add_uint_format(subframe_tree, hf_turbocell_aggregate_msdu_len, next_tvb, msdu_offset, 2,
                                           msdu_length, "MSDU length: %u (0x%04X)", msdu_length,msdu_length);
                proto_tree_add_item(subframe_tree, hf_turbocell_aggregate_unknown2, next_tvb, msdu_offset+1, 1, ENC_BIG_ENDIAN);

                msdu_offset += 0x02;
                remaining_length -= 0x02;
                msdu_tvb = tvb_new_subset(next_tvb, msdu_offset, (msdu_length>remaining_length)?remaining_length:msdu_length, msdu_length);
                call_dissector(eth_handle, msdu_tvb, pinfo, subframe_tree);
                msdu_offset += msdu_length;
                remaining_length -= msdu_length;
            } while (remaining_length > 6);

            if (remaining_length > 2) {
                next_tvb = tvb_new_subset_remaining(next_tvb, msdu_offset);
                call_dissector(data_handle, next_tvb, pinfo, tree);
            }
        }
    }
}
Esempio n. 12
0
static void
dissect_mailslot_browse(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
{
	int offset = 0;
	guint8 cmd;
	proto_tree *tree = NULL;
	proto_item *item = NULL;
	guint32 periodicity;
	gchar host_name[17];
	gchar *utf8_host_name;
	gint namelen;
	guint8 server_count, reset_cmd;
	guint8 os_major_ver, os_minor_ver;
	const gchar *windows_version = NULL;
	int i;
	guint32 uptime;

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

	cmd = tvb_get_guint8(tvb, offset);

	/* Put in something, and replace it later */
	col_add_str(pinfo->cinfo, COL_INFO, val_to_str(cmd, commands, "Unknown command:0x%02x"));


	item = proto_tree_add_item(parent_tree, proto_smb_browse, tvb, offset, -1, ENC_NA);
	tree = proto_item_add_subtree(item, ett_browse);

	/* command */
	proto_tree_add_uint(tree, hf_command, tvb, offset, 1, cmd);
	offset += 1;

	switch (cmd) {
	case BROWSE_DOMAIN_ANNOUNCEMENT:
	case BROWSE_LOCAL_MASTER_ANNOUNCEMENT:
	case BROWSE_HOST_ANNOUNCE: {
		/* update count */
		proto_tree_add_item(tree, hf_update_count, tvb, offset, 1, ENC_LITTLE_ENDIAN);
		offset += 1;

		/* periodicity (in milliseconds) */
		periodicity = tvb_get_letohl(tvb, offset);
		proto_tree_add_uint_format(tree, hf_periodicity, tvb, offset, 4,
		    periodicity,
		    "Update Periodicity: %s",
		    time_msecs_to_str(periodicity));
		offset += 4;

		/* server name */
		tvb_get_nstringz0(tvb, offset, sizeof(host_name), host_name);
		utf8_host_name = g_convert(host_name, strlen(host_name),
			"UTF-8", "CP437", NULL, NULL, NULL);
		if (utf8_host_name == NULL)
			utf8_host_name = host_name;
		col_append_fstr(pinfo->cinfo, COL_INFO, " %s", utf8_host_name);
		proto_tree_add_string_format(tree, hf_server_name,
			tvb, offset, 16,
			utf8_host_name,
			(cmd==BROWSE_DOMAIN_ANNOUNCEMENT)?
				"Domain/Workgroup: %s":
				"Host Name: %s",
			utf8_host_name);
		if (utf8_host_name != host_name)
			g_free(utf8_host_name);
		offset += 16;

		/* Windows version (See "OSVERSIONINFO Structure" on MSDN) */
		os_major_ver = tvb_get_guint8(tvb, offset);
		os_minor_ver = tvb_get_guint8(tvb, offset+1);

		SET_WINDOWS_VERSION_STRING(os_major_ver, os_minor_ver, windows_version);

		if(windows_version)
		  proto_tree_add_text(tree, tvb, offset, 2, "Windows version: %s", windows_version);

		/* OS major version */
		proto_tree_add_item(tree, hf_os_major, tvb, offset, 1, ENC_LITTLE_ENDIAN);
		offset += 1;

		/* OS minor version */
		proto_tree_add_item(tree, hf_os_minor, tvb, offset, 1, ENC_LITTLE_ENDIAN);
		offset += 1;

		/* server type flags */
		offset = dissect_smb_server_type_flags(
			tvb, offset, pinfo, tree, NULL, TRUE);

		if (cmd == BROWSE_DOMAIN_ANNOUNCEMENT && tvb_get_letohs (tvb, offset + 2) != 0xAA55) {
			/*
			 * Network Monitor claims this is a "Comment
			 * Pointer".  I don't believe it.
			 *
			 * It's not a browser protocol major/minor
			 * version number, and signature constant,
			 * however.
			 */
			proto_tree_add_text(tree, tvb, offset, 4,
			    "Mysterious Field: 0x%08x",
			    tvb_get_letohl(tvb, offset));
			offset += 4;
		} else {
			/* browser protocol major version */
			proto_tree_add_item(tree, hf_proto_major, tvb, offset, 1, ENC_LITTLE_ENDIAN);
			offset += 1;

			/* browser protocol minor version */
			proto_tree_add_item(tree, hf_proto_minor, tvb, offset, 1, ENC_LITTLE_ENDIAN);
			offset += 1;

			/* signature constant */
			proto_tree_add_item(tree, hf_sig_const, tvb, offset, 2, ENC_LITTLE_ENDIAN);
			offset += 2;
		}

		/* master browser server name or server comment */
		namelen = tvb_strsize(tvb, offset);
		proto_tree_add_item(tree,
			(cmd==BROWSE_DOMAIN_ANNOUNCEMENT)?
			    hf_mb_server_name : hf_server_comment,
			tvb, offset, namelen, ENC_ASCII|ENC_NA);
		break;
	}
	case BROWSE_REQUEST_ANNOUNCE: {
		guint8 *computer_name;

		/* unused/unknown flags */
		proto_tree_add_item(tree, hf_unused_flags,
			tvb, offset, 1, ENC_LITTLE_ENDIAN);
		offset += 1;

		/* name of computer to which to send reply */
		computer_name = tvb_get_ephemeral_stringz(tvb, offset, &namelen);
		proto_tree_add_string(tree, hf_response_computer_name,
			tvb, offset, namelen, computer_name);
		col_append_fstr(pinfo->cinfo, COL_INFO, " %s", computer_name);
		break;
	}

	case BROWSE_ELECTION_REQUEST:
		/* election version */
		proto_tree_add_item(tree, hf_election_version, tvb, offset, 1, ENC_LITTLE_ENDIAN);
		offset += 1;

		/* criterion */
		dissect_election_criterion(tvb, tree, offset);
		offset += 4;

		/* server uptime */
		uptime = tvb_get_letohl(tvb, offset);
		proto_tree_add_uint_format(tree, hf_server_uptime,
		    tvb, offset, 4, uptime,
		    "Uptime: %s",
		    time_msecs_to_str(uptime));
		offset += 4;

		/* next 4 bytes must be zero */
		offset += 4;

		/* server name */
		namelen = tvb_strsize(tvb, offset);
		proto_tree_add_item(tree, hf_server_name,
			tvb, offset, namelen, ENC_ASCII|ENC_NA);
		break;

	case BROWSE_BACKUP_LIST_REQUEST:
		/* backup list requested count */
		proto_tree_add_item(tree, hf_backup_count, tvb, offset, 1, ENC_LITTLE_ENDIAN);
		offset += 1;

		/* backup requested token */
		proto_tree_add_item(tree, hf_backup_token, tvb, offset, 4, ENC_LITTLE_ENDIAN);
		break;

	case BROWSE_BACKUP_LIST_RESPONSE:
		/* backup list requested count */
		server_count = tvb_get_guint8(tvb, offset);
		proto_tree_add_uint(tree, hf_backup_count, tvb, offset, 1,
		    server_count);
		offset += 1;

		/* backup requested token */
		proto_tree_add_item(tree, hf_backup_token, tvb, offset, 4, ENC_LITTLE_ENDIAN);
		offset += 4;

		/* backup server names */
		for (i = 0; i < server_count; i++) {
			namelen = tvb_strsize(tvb, offset);
			proto_tree_add_item(tree, hf_backup_server,
				tvb, offset, namelen, ENC_ASCII|ENC_NA);
			offset += namelen;
		}
		break;

	case BROWSE_MASTER_ANNOUNCEMENT:
		/* master browser server name */
		namelen = tvb_strsize(tvb, offset);
		proto_tree_add_item(tree, hf_mb_server_name,
			tvb, offset, namelen, ENC_ASCII|ENC_NA);
		break;

	case BROWSE_RESETBROWSERSTATE_ANNOUNCEMENT: {
	        proto_tree *sub_tree;
	        proto_item *reset_item;

		/* the subcommand follows ... one of three values */

	        reset_cmd = tvb_get_guint8(tvb, offset);
		reset_item = proto_tree_add_uint(tree, hf_mb_reset_command, tvb,
						 offset, 1, reset_cmd);
		sub_tree = proto_item_add_subtree(reset_item, ett_browse_reset_cmd_flags);
		proto_tree_add_boolean(sub_tree, hf_mb_reset_demote, tvb,
				       offset, 1, reset_cmd);
		proto_tree_add_boolean(sub_tree, hf_mb_reset_flush, tvb,
				       offset, 1, reset_cmd);
		proto_tree_add_boolean(sub_tree, hf_mb_reset_stop, tvb,
				       offset, 1, reset_cmd);
		break;
	}

	case BROWSE_BECOME_BACKUP:
		/* name of browser to promote */
		namelen = tvb_strsize(tvb, offset);
		proto_tree_add_item(tree, hf_browser_to_promote,
			tvb, offset, namelen, ENC_ASCII|ENC_NA);
		break;
	}
}
/* Code to actually dissect the packets */
static void
dissect_ipa(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    gint remaining;
    gint header_length = 3;
    int offset = 0;

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

    while ((remaining = tvb_reported_length_remaining(tvb, offset)) > 0) {
        proto_item *ti;
        proto_tree *ipa_tree = NULL;
        guint16 len, msg_type;
        tvbuff_t *next_tvb;

        len = tvb_get_ntohs(tvb, offset);
        msg_type = tvb_get_guint8(tvb, offset+2);

        col_append_fstr(pinfo->cinfo, COL_INFO, "%s ",
                        val_to_str(msg_type, ipa_protocol_vals,
                                   "unknown 0x%02x"));

        /*
         * The IPA header is different depending on the transport protocol.
         * With UDP there seems to be a fourth byte for the IPA header.
         * We attempt to detect this by checking if the length from the
         * header + four bytes of the IPA header equals the remaining size.
         */
        if ((pinfo->ipproto == IP_PROTO_UDP) && (len + 4 == remaining)) {
            header_length++;
        }

        if (tree) {
            ti = proto_tree_add_protocol_format(tree, proto_ipa,
                                                tvb, offset, len+header_length,
                                                "IPA protocol ip.access, type: %s",
                                                val_to_str(msg_type, ipa_protocol_vals,
                                                        "unknown 0x%02x"));
            ipa_tree = proto_item_add_subtree(ti, ett_ipa);
            proto_tree_add_item(ipa_tree, hf_ipa_data_len,
                                tvb, offset, 2, ENC_BIG_ENDIAN);
            proto_tree_add_item(ipa_tree, hf_ipa_protocol,
                                tvb, offset+2, 1, ENC_BIG_ENDIAN);
        }

        next_tvb = tvb_new_subset(tvb, offset+header_length, len, len);

        switch (msg_type) {
        case ABISIP_OML:
            /* hand this off to the standard A-bis OML dissector */
            if (sub_handles[SUB_OML])
                call_dissector(sub_handles[SUB_OML], next_tvb,
                               pinfo, tree);
            break;
        case ABISIP_IPACCESS:
            dissect_ipaccess(next_tvb, pinfo, tree);
            break;
        case AIP_SCCP:
            /* hand this off to the standard SCCP dissector */
            call_dissector(sub_handles[SUB_SCCP], next_tvb, pinfo, tree);
            break;
        case IPA_MGCP:
            /* hand this off to the standard MGCP dissector */
            call_dissector(sub_handles[SUB_MGCP], next_tvb, pinfo, tree);
            break;
        case OSMO_EXT:
            dissect_osmo(next_tvb, pinfo, ipa_tree, tree);
            break;
        case HSL_DEBUG:
            if (tree) {
                proto_tree_add_item(ipa_tree, hf_ipa_hsl_debug,
                                    next_tvb, 0, len, ENC_ASCII|ENC_NA);
                if (global_ipa_in_root == TRUE)
                    proto_tree_add_item(tree, hf_ipa_hsl_debug,
                                        next_tvb, 0, len, ENC_ASCII|ENC_NA);
            }
            if (global_ipa_in_info == TRUE)
                col_append_fstr(pinfo->cinfo, COL_INFO, "%s ",
                                tvb_get_ephemeral_stringz(next_tvb, 0, NULL));
            break;
        default:
            if (msg_type < ABISIP_RSL_MAX) {
                /* hand this off to the standard A-bis RSL dissector */
                call_dissector(sub_handles[SUB_RSL], next_tvb, pinfo, tree);
            }
            break;
        }
        offset += len + header_length;
    }
}