Пример #1
0
/* XXX - We depend on the UDP dissector finding the conversation first */
void
add_udp_process_info(guint32 frame_num, address *local_addr, address *remote_addr, guint16 local_port, guint16 remote_port, guint32 uid, guint32 pid, gchar *username, gchar *command) {
  conversation_t *conv;
  struct udp_analysis *udpd;
  udp_flow_t *flow = NULL;

  if (!udp_process_info) {
    return;
  }

  conv = find_conversation(frame_num, local_addr, remote_addr, PT_UDP, local_port, remote_port, 0);
  if (!conv) {
    return;
  }

  udpd = (struct udp_analysis *)conversation_get_proto_data(conv, hfi_udp->id);
  if (!udpd) {
    return;
  }

  if ((CMP_ADDRESS(local_addr, &conv->key_ptr->addr1) == 0) && (local_port == conv->key_ptr->port1)) {
    flow = &udpd->flow1;
  } else if ((CMP_ADDRESS(remote_addr, &conv->key_ptr->addr1) == 0) && (remote_port == conv->key_ptr->port1)) {
    flow = &udpd->flow2;
  }
  if (!flow || flow->command) {
    return;
  }

  flow->process_uid = uid;
  flow->process_pid = pid;
  flow->username = wmem_strdup(wmem_file_scope(), username);
  flow->command = wmem_strdup(wmem_file_scope(), command);
}
Пример #2
0
void
xmpp_jingle_session_track(packet_info *pinfo, xmpp_element_t *packet, xmpp_conv_info_t *xmpp_info)
{
    xmpp_element_t *jingle_packet;
    GList *jingle_packet_l;

    jingle_packet_l = xmpp_find_element_by_name(packet,"jingle");
    jingle_packet = (xmpp_element_t *)(jingle_packet_l?jingle_packet_l->data:NULL);

    if (jingle_packet && !pinfo->fd->flags.visited) {
        xmpp_attr_t *attr_id;
        xmpp_attr_t *attr_sid;

        char *se_id;
        char *se_sid;


        attr_id = xmpp_get_attr(packet, "id");
        if (!attr_id) {
            return;
        }

        attr_sid = xmpp_get_attr(jingle_packet, "sid");
        if (!attr_sid) {
            return;
        }

        se_id = wmem_strdup(wmem_file_scope(), attr_id->value);
        se_sid = wmem_strdup(wmem_file_scope(), attr_sid->value);

        wmem_tree_insert_string(xmpp_info->jingle_sessions, se_id, (void*) se_sid, WMEM_TREE_STRING_NOCASE);
    }
}
Пример #3
0
static oid_info_t* add_oid(const char* name, oid_kind_t kind, const oid_value_type_t* type, oid_key_t* key, guint oid_len, guint32 *subids) {
	guint i = 0;
	oid_info_t* c = &oid_root;

	prepopulate_oids();
	oid_len--;

	do {
		oid_info_t* n = (oid_info_t *)wmem_tree_lookup32(c->children,subids[i]);

		if(n) {
			if (i == oid_len) {
				if (n->name) {
					if (!g_str_equal(n->name,name)) {
						D(2,("Renaming Oid from: %s -> %s, this means the same oid is registered more than once",n->name,name));
					}
					wmem_free(wmem_epan_scope(), n->name);
				}

				n->name = wmem_strdup(wmem_epan_scope(), name);

				if (! n->value_type) {
					n->value_type = type;
				}

				return n;
			}
		} else {
			n = wmem_new(wmem_epan_scope(), oid_info_t);
			n->subid = subids[i];
			n->kind = kind;
			n->children = wmem_tree_new(wmem_epan_scope());
			n->value_hfid = -2;
			n->key = key;
			n->parent = c;
			n->bits = NULL;

			wmem_tree_insert32(c->children,n->subid,n);

			if (i == oid_len) {
				n->name = wmem_strdup(wmem_epan_scope(), name);
				n->value_type = type;
				n->kind = kind;
				return n;
			} else {
				n->name = NULL;
				n->value_type = NULL;
				n->kind = OID_KIND_UNKNOWN;
			}
		}
		c = n;
	} while(++i);

	g_assert_not_reached();
	return NULL;
}
Пример #4
0
/* returns the command name */
static const gchar *
csm_fc(guint16 fc, guint16 ct)
{
    if (fc == 0x0000) {
        return wmem_strdup(wmem_packet_scope(),
                           val_to_str(ct, class_type_vals, "0x%04x"));
    } else {
        return wmem_strdup(wmem_packet_scope(),
                           val_to_str(fc, function_code_vals, "0x%04x"));
    }
}
Пример #5
0
static void
wmem_test_strutls(void)
{
    wmem_allocator_t   *allocator;
    const char         *orig_str;
    char               *new_str;
    char              **split_str;

    allocator = wmem_allocator_new(WMEM_ALLOCATOR_STRICT);

    orig_str = "TEST1";
    new_str  = wmem_strdup(allocator, orig_str);
    g_assert_cmpstr(new_str, ==, orig_str);
    new_str[0] = 'X';
    g_assert_cmpstr(new_str, >, orig_str);
    wmem_strict_check_canaries(allocator);

    orig_str = "TEST123456789";
    new_str  = wmem_strndup(allocator, orig_str, 6);
    g_assert_cmpstr(new_str, ==, "TEST12");
    g_assert_cmpstr(new_str, <, orig_str);
    new_str[0] = 'X';
    g_assert_cmpstr(new_str, >, orig_str);
    wmem_strict_check_canaries(allocator);

    new_str = wmem_strdup_printf(allocator, "abc %s %% %d", "boo", 23);
    g_assert_cmpstr(new_str, ==, "abc boo % 23");
    new_str = wmem_strdup_printf(allocator, "%s", STRING_80);
    g_assert_cmpstr(new_str, ==, STRING_80);
    wmem_strict_check_canaries(allocator);

    new_str = wmem_strconcat(allocator, "ABC", NULL);
    g_assert_cmpstr(new_str, ==, "ABC");
    new_str = wmem_strconcat(allocator, "ABC", "DEF", NULL);
    g_assert_cmpstr(new_str, ==, "ABCDEF");
    wmem_strict_check_canaries(allocator);
    new_str = wmem_strconcat(allocator, "", "", "ABCDEF", "", "GH", NULL);
    g_assert_cmpstr(new_str, ==, "ABCDEFGH");
    wmem_strict_check_canaries(allocator);

    split_str = wmem_strsplit(allocator, "A-C", "-", 2);
    g_assert_cmpstr(split_str[0], ==, "A");
    g_assert_cmpstr(split_str[1], ==, "C");
    split_str = wmem_strsplit(allocator, "--aslkf-asio--asfj-as--", "-", 10);
    g_assert_cmpstr(split_str[0], ==, "aslkf");
    g_assert_cmpstr(split_str[1], ==, "asio");
    g_assert_cmpstr(split_str[2], ==, "asfj");
    g_assert_cmpstr(split_str[3], ==, "as");
    split_str = wmem_strsplit(allocator, "--aslkf-asio--asfj-as--", "-", 4);
    g_assert_cmpstr(split_str[0], ==, "aslkf");
    g_assert_cmpstr(split_str[1], ==, "asio");
    g_assert_cmpstr(split_str[2], ==, "-asfj-as--");
    wmem_strict_check_canaries(allocator);

    orig_str = "TeStAsCiIsTrDoWn";
    new_str = wmem_ascii_strdown(allocator, orig_str, -1);
    g_assert_cmpstr(new_str, ==, "testasciistrdown");

    wmem_destroy_allocator(allocator);
}
Пример #6
0
/* expects that *result is NULL */
static void
ssh_choose_algo(gchar *client, gchar *server, gchar **result)
{
	gchar **server_strings=NULL;
	gchar **client_strings=NULL;
	gchar **step;
	GSList *server_list = NULL;

	if (!client || !server || !result || *result)
		return;

	server_strings = g_strsplit(server, ",", 0);
	for (step = server_strings; *step; step++) {
		server_list = g_slist_append(server_list, *step);
	}

	client_strings = g_strsplit(client, ",", 0);
	for (step = client_strings; *step; step++) {
		GSList *agreed;
		if ((agreed=g_slist_find_custom(server_list, *step, ssh_gslist_compare_strings))) {
			*result = wmem_strdup(wmem_file_scope(), (const gchar *)agreed->data);
			break;
		}
	}

	g_strfreev(client_strings);
	g_slist_free(server_list);
	g_strfreev(server_strings);
}
Пример #7
0
void
xmpp_ibb_session_track(packet_info *pinfo, xmpp_element_t *packet, xmpp_conv_info_t *xmpp_info)
{
    xmpp_element_t *ibb_packet = NULL;
    GList *ibb_packet_l;

    if(strcmp(packet->name, "message") == 0)
    {
        ibb_packet_l = xmpp_find_element_by_name(packet,"data");
        ibb_packet = (xmpp_element_t *)(ibb_packet_l?ibb_packet_l->data:NULL);

    } else if(strcmp(packet->name, "iq") == 0)
    {
        ibb_packet_l = xmpp_find_element_by_name(packet,"open");

        if(!ibb_packet_l)
            ibb_packet_l = xmpp_find_element_by_name(packet,"close");
         if(!ibb_packet_l)
            ibb_packet_l = xmpp_find_element_by_name(packet,"data");

        ibb_packet = (xmpp_element_t *)(ibb_packet_l?ibb_packet_l->data:NULL);
    }

    if (ibb_packet && !pinfo->fd->flags.visited) {
        xmpp_attr_t *attr_id;
        xmpp_attr_t *attr_sid;

        char *se_id;
        char *se_sid;


        attr_id = xmpp_get_attr(packet, "id");
        attr_sid = xmpp_get_attr(ibb_packet, "sid");
        if(attr_id && attr_sid)
        {
            se_id = wmem_strdup(wmem_file_scope(), attr_id->value);
            se_sid = wmem_strdup(wmem_file_scope(), attr_sid->value);
            wmem_tree_insert_string(xmpp_info->ibb_sessions, se_id, (void*) se_sid, WMEM_TREE_STRING_NOCASE);
        }
    }
}
Пример #8
0
gchar *
val64_to_str_ext_wmem(wmem_allocator_t *scope, const guint64 val, val64_string_ext *vse, const char *fmt)
{
    const gchar *ret;

    DISSECTOR_ASSERT(fmt != NULL);

    ret = try_val64_to_str_ext(val, vse);
    if (ret != NULL)
        return wmem_strdup(scope, ret);

    return wmem_strdup_printf(scope, fmt, val);
}
Пример #9
0
gchar *
val_to_str_wmem(wmem_allocator_t *scope, const guint32 val, const value_string *vs, const char *fmt)
{
    const gchar *ret;

    DISSECTOR_ASSERT(fmt != NULL);

    ret = try_val_to_str(val, vs);
    if (ret != NULL)
        return wmem_strdup(scope, ret);

    return wmem_strdup_printf(scope, fmt, val);
}
Пример #10
0
/* Like val_to_str, but tries to find a prefix (instead of an exact) match
   of any prefix from the bytes_string array bs against the haystack. */
const gchar *
bytesprefix_to_str(const guint8 *haystack, const size_t haystack_len, const bytes_string *bs, const char *fmt)
{
    const gchar *ret;

    DISSECTOR_ASSERT(fmt != NULL);

    ret = try_bytesprefix_to_str(haystack, haystack_len, bs);
    if (ret != NULL)
        return ret;

    /* XXX See note at bytesval_to_str. */
    return wmem_strdup(wmem_packet_scope(), fmt);
}
Пример #11
0
void
xmpp_gtalk_session_track(packet_info *pinfo, xmpp_element_t *packet, xmpp_conv_info_t *xmpp_info)
{
    xmpp_element_t *gtalk_packet;
    GList *gtalk_packet_l;

    gtalk_packet_l = xmpp_find_element_by_name(packet,"session");
    gtalk_packet = (xmpp_element_t *)(gtalk_packet_l?gtalk_packet_l->data:NULL);


    if (gtalk_packet && !pinfo->fd->flags.visited) {
        xmpp_attr_t *attr_id;
        xmpp_attr_t *attr_sid;

        char *se_id;
        char *se_sid;

        xmpp_attr_t *xmlns = xmpp_get_attr(gtalk_packet, "xmlns");
        if(xmlns && strcmp(xmlns->value,"http://www.google.com/session") != 0)
            return;

        attr_id = xmpp_get_attr(packet, "id");
        if (!attr_id) {
            return;
        }

        attr_sid = xmpp_get_attr(gtalk_packet, "id");
        if (!attr_sid) {
            return;
        }

        se_id = wmem_strdup(wmem_file_scope(), attr_id->value);
        se_sid = wmem_strdup(wmem_file_scope(), attr_sid->value);

        wmem_tree_insert_string(xmpp_info->gtalk_sessions, se_id, (void*) se_sid, WMEM_TREE_STRING_NOCASE);
    }
}
Пример #12
0
void
xmpp_iq_reqresp_track(packet_info *pinfo, xmpp_element_t *packet, xmpp_conv_info_t *xmpp_info)
{
    xmpp_transaction_t *xmpp_trans = NULL;

    xmpp_attr_t *attr_id;
    char *id;

    attr_id = xmpp_get_attr(packet, "id");

    if (!attr_id) {
        return;
    }

    id = wmem_strdup(wmem_packet_scope(), attr_id->value);

    if (!pinfo->fd->flags.visited) {
        xmpp_trans = (xmpp_transaction_t *)wmem_tree_lookup_string(xmpp_info->req_resp, id, WMEM_TREE_STRING_NOCASE);
        if (xmpp_trans) {
            xmpp_trans->resp_frame = pinfo->fd->num;

        } else {
            char *se_id = wmem_strdup(wmem_file_scope(), id);

            xmpp_trans = wmem_new(wmem_file_scope(), xmpp_transaction_t);
            xmpp_trans->req_frame = pinfo->fd->num;
            xmpp_trans->resp_frame = 0;

            wmem_tree_insert_string(xmpp_info->req_resp, se_id, (void *) xmpp_trans, WMEM_TREE_STRING_NOCASE);

        }

    } else {
        wmem_tree_lookup_string(xmpp_info->req_resp, id, WMEM_TREE_STRING_NOCASE);
    }
}
static int call_idmp_oid_callback(tvbuff_t *tvb, int offset, packet_info *pinfo, int op, proto_tree *tree, struct SESSION_DATA_STRUCTURE *session)
{
    if(session != NULL) {

        if((!saved_protocolID) && (op == (ROS_OP_BIND | ROS_OP_RESULT))) {
            /* save for subsequent operations - should be into session data */
            saved_protocolID = wmem_strdup(wmem_file_scope(), protocolID);
        }

        /* mimic ROS! */
        session->ros_op = op;
        offset = call_ros_oid_callback(saved_protocolID ? saved_protocolID : protocolID, tvb, offset, pinfo, tree, session);
    }

    return offset;

}
Пример #14
0
static void
xmpp_error(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *element)
{
    proto_item *error_item;
    proto_tree *error_tree;

    xmpp_element_t *text_element, *cond_element;

    xmpp_attr_info attrs_info[] = {
        {"type", &hf_xmpp_error_type, TRUE, TRUE, NULL, NULL},
        {"code", &hf_xmpp_error_code, FALSE, TRUE, NULL, NULL},
        {"condition", &hf_xmpp_error_condition, TRUE, TRUE, NULL, NULL} /*TODO: validate list to the condition element*/
    };

    gchar *error_info;

    xmpp_attr_t *fake_condition = NULL;

    error_info = wmem_strdup(wmem_packet_scope(), "Stanza error");

    error_item = proto_tree_add_item(tree, hf_xmpp_error, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
    error_tree = proto_item_add_subtree(error_item, ett_xmpp_query_item);

    cond_element = xmpp_steal_element_by_attr(element, "xmlns", "urn:ietf:params:xml:ns:xmpp-stanzas");
    if(cond_element)
    {
        fake_condition = xmpp_ep_init_attr_t(cond_element->name, cond_element->offset, cond_element->length);
        g_hash_table_insert(element->attrs, (gpointer)"condition", fake_condition);

        error_info = wmem_strdup_printf(wmem_packet_scope(), "%s: %s;", error_info, cond_element->name);
    }


    xmpp_display_attrs(error_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));

    while((text_element = xmpp_steal_element_by_name(element, "text")) != NULL)
    {
        xmpp_error_text(error_tree, tvb, text_element);

        error_info = wmem_strdup_printf(wmem_packet_scope(), "%s Text: %s", error_info, text_element->data?text_element->data->value:"");
    }

    expert_add_info_format(pinfo, error_item, &ei_xmpp_response, "%s", error_info);

    xmpp_unknown(error_tree, tvb, pinfo, element);
}
Пример #15
0
/* Like val_to_str except for bytes_string */
const gchar *
bytesval_to_str(const guint8 *val, const size_t val_len, const bytes_string *bs, const char *fmt)
{
    const gchar *ret;

    DISSECTOR_ASSERT(fmt != NULL);

    ret = try_bytesval_to_str(val, val_len, bs);
    if (ret != NULL)
        return ret;

    /*
     * XXX should this use bytes_to_str as format parameter for consistency?
     * Though for bytes I guess most of the time you want to show "Unknown"
     * anyway rather than "Unknown (\x13\x37...)"
     */
    return wmem_strdup(wmem_packet_scope(), fmt);
}
Пример #16
0
void
register_stat_tap_ui(stat_tap_ui *ui, void *userdata)
{
    stat_cmd_arg *newsca;

    if (stat_cmd_arg_list == NULL)
        stat_cmd_arg_list = wmem_list_new(wmem_epan_scope());

    /* Key is already present */
    if (wmem_list_find_custom(stat_cmd_arg_list, ui->cli_string, search_duplicate))
        return;

    newsca = wmem_new(wmem_epan_scope(), stat_cmd_arg);
    newsca->cmd= wmem_strdup(wmem_epan_scope(), ui->cli_string);
    newsca->func=ui->tap_init_cb;
    newsca->userdata=userdata;

    wmem_list_insert_sorted(stat_cmd_arg_list, newsca, sort_by_name);
}
Пример #17
0
static void
ssh_set_mac_length(struct ssh_peer_data *peer_data)
{
	char *size_str;
	guint size=0;
	char *mac_name = peer_data->mac;
	char *strip;

	if (!mac_name) return;
	mac_name = wmem_strdup(NULL, (const gchar *)mac_name);
	if (!mac_name) return;

	/* strip trailing "*****@*****.**" or "@openssh.com" */
	strip = strstr(mac_name, "*****@*****.**");
	if (strip) {
		peer_data->length_is_plaintext = 1;
		*strip = '\0';
	}
	else {
		strip = strstr(mac_name, "@openssh.com");
		if (strip) *strip = '\0';
	}

	if ((size_str=g_strrstr(mac_name, "-")) && ((size=atoi(size_str+1)))) {
		peer_data->mac_length = (size > 0) ? size / 8 : 0;
	}
	else if (strcmp(mac_name, "hmac-sha1") == 0) {
		peer_data->mac_length = 20;
	}
	else if (strcmp(mac_name, "hmac-md5") == 0) {
		peer_data->mac_length = 16;
	}
	else if (strcmp(mac_name, "hmac-ripemd160") == 0) {
		peer_data->mac_length = 20;
	}
	else if (strcmp(mac_name, "none") == 0) {
		peer_data->mac_length = 0;
	}

	wmem_free(NULL, mac_name);
}
Пример #18
0
static void
Cmd_TokenizeString(const char* text)
{
	int start;

	cmd_argc = 0;

	start = 0;
	while (TRUE) {

		/* skip whitespace up to a \n */
		while (*text && *text <= ' ' && *text != '\n') {
			text++;
			start++;
		}

		if (*text == '\n') {
			/* a newline seperates commands in the buffer */
			text++;
			break;
		}

		if (!*text)
			return;

		text = COM_Parse (text);
		if (!text)
			return;

		if (cmd_argc < MAX_ARGS) {
			cmd_argv[cmd_argc] = wmem_strdup(wmem_packet_scope(), com_token);
			cmd_argv_start[cmd_argc] = start + com_token_start;
			cmd_argv_length[cmd_argc] = com_token_length;
			cmd_argc++;
		}

		start += com_token_start + com_token_length;
	}
}
Пример #19
0
// Finds out whether this is the first blip frame in the blip message (which can consist of a series of frames).
// If it is, updates the conversation_entry_ptr->blip_requests hash to record the pinfo->num (wireshark packet number)
static gboolean
is_first_frame_in_msg(blip_conversation_entry_t *conversation_entry_ptr, packet_info *pinfo,
					  guint64 value_frame_flags, guint64 value_message_num) {

	gboolean first_frame_in_msg = TRUE;

	// Temporary pool for the lookup hash_key.	Will get duplicated on the file_scope() pool if needed to be
	// stored in the hashtable.
	gchar *hash_key = message_hash_key_convo(pinfo, value_frame_flags, value_message_num);
	guint* first_frame_number_for_msg = (guint*)wmem_map_lookup(conversation_entry_ptr->blip_requests, (void *) hash_key);

	if (first_frame_number_for_msg != NULL) {
		if (GPOINTER_TO_UINT(first_frame_number_for_msg) != pinfo->num) {
			first_frame_in_msg = FALSE;
		}
	} else {
		// If storing the key in the hashmap, re-allocate it with the file_scope() allocator
		gchar *hash_key_copy = wmem_strdup(wmem_file_scope(), hash_key);

		wmem_map_insert(conversation_entry_ptr->blip_requests, (void *) hash_key_copy, GUINT_TO_POINTER(pinfo->num));
	}

	return first_frame_in_msg;
}
Пример #20
0
/*
 * Process a multipart body-part:
 *      MIME-part-headers [ line-end *OCTET ]
 *      line-end dashed-boundary transport-padding line-end
 *
 * If applicable, call a media subdissector.
 *
 * Return the offset to the start of the next body-part.
 */
static gint
process_body_part(proto_tree *tree, tvbuff_t *tvb, const guint8 *boundary,
        gint boundary_len, packet_info *pinfo, gint start,
        gboolean *last_boundary)
{
    proto_tree *subtree;
    proto_item *ti;
    gint offset = start, next_offset = 0;
    char *parameters = NULL;
    gint body_start, boundary_start, boundary_line_len;

    gchar *content_type_str = NULL;
    gchar *content_encoding_str = NULL;
    char *filename = NULL;
    char *mimetypename = NULL;
    int  len = 0;
    gboolean last_field = FALSE;

    ti = proto_tree_add_item(tree, hf_multipart_part, tvb, start, 0, ENC_ASCII|ENC_NA);
    subtree = proto_item_add_subtree(ti, ett_multipart_body);

    /*
     * Process the MIME-part-headers
     */

    while (!last_field)
    {
        gint colon_offset;
        char *hdr_str;
        char *header_str;

        /* Look for the end of the header (denoted by cr)
         * 3:d argument to imf_find_field_end() maxlen; must be last offset in the tvb.
         */
        next_offset = imf_find_field_end(tvb, offset, tvb_length_remaining(tvb, offset)+offset, &last_field);
        /* If cr not found, won't have advanced - get out to avoid infinite loop! */
        if (next_offset == offset) {
            break;
        }

        hdr_str = tvb_get_string(wmem_packet_scope(), tvb, offset, next_offset - offset);

        header_str = unfold_and_compact_mime_header(hdr_str, &colon_offset);
        if (colon_offset <= 0) {
           proto_tree_add_text(subtree, tvb, offset, next_offset - offset,
                 "%s",
                 tvb_format_text(tvb, offset, next_offset - offset));
        } else {
            gint hf_index;

            /* Split header name from header value */
            header_str[colon_offset] = '\0';
            hf_index = is_known_multipart_header(header_str, colon_offset);

            if (hf_index == -1) {
               proto_tree_add_text(subtree, tvb, offset,
                     next_offset - offset,
                     "%s",
                     tvb_format_text(tvb, offset, next_offset - offset));
            } else {
                char *value_str = header_str + colon_offset + 1;

                proto_tree_add_string_format(subtree,
                      hf_header_array[hf_index], tvb,
                      offset, next_offset - offset,
                      (const char *)value_str, "%s",
                      tvb_format_text(tvb, offset, next_offset - offset));

                switch (hf_index) {
                    case POS_CONTENT_TYPE:
                        {
                            /* The Content-Type starts at colon_offset + 1 */
                            gint semicolon_offset = index_of_char(
                                    value_str, ';');

                            if (semicolon_offset > 0) {
                                value_str[semicolon_offset] = '\0';
                                parameters = wmem_strdup(wmem_packet_scope(), value_str + semicolon_offset + 1);
                            } else {
                                parameters = NULL;
                            }

                            content_type_str = wmem_ascii_strdown(wmem_packet_scope(), value_str, -1);

                            /* Show content-type in root 'part' label */
                            proto_item_append_text(ti, " (%s)", content_type_str);

                            /* find the "name" parameter in case we don't find a content disposition "filename" */
                            if((mimetypename = find_parameter(parameters, "name=", &len)) != NULL) {
                              mimetypename = g_strndup(mimetypename, len);
                            }
                        }


                        break;
                        case POS_CONTENT_TRANSFER_ENCODING:
                        {
                            /* The Content-Transfeing starts at colon_offset + 1 */
                            gint cr_offset = index_of_char(value_str, '\r');

                            if (cr_offset > 0) {
                                value_str[cr_offset] = '\0';
                            }

                            content_encoding_str = wmem_ascii_strdown(wmem_packet_scope(), value_str, -1);
                        }
                        break;
                        case POS_CONTENT_DISPOSITION:
                            {
                            /* find the "filename" parameter */
                            if((filename = find_parameter(value_str, "filename=", &len)) != NULL) {
                                filename = g_strndup(filename, len);
                            }
                        }
                        break;
                    default:
                        break;
                }
            }
        }
        offset = next_offset;
    }

    body_start = next_offset;

    /*
     * Process the body
     */

    boundary_start = find_next_boundary(tvb, body_start, boundary, boundary_len,
            &boundary_line_len, last_boundary);
    if (boundary_start > 0) {
        gint body_len = boundary_start - body_start;
        tvbuff_t *tmp_tvb = tvb_new_subset(tvb, body_start,
                body_len, body_len);

        if (content_type_str) {

            /*
             * subdissection
             */
            void *save_private_data = pinfo->private_data;
            gboolean dissected;

            /*
             * Try and remove any content transfer encoding so that each sub-dissector
             * doesn't have to do it itself
             *
             */

            if(content_encoding_str && remove_base64_encoding) {

                if(!g_ascii_strncasecmp(content_encoding_str, "base64", 6))
                    tmp_tvb = base64_decode(pinfo, tmp_tvb, filename ? filename : (mimetypename ? mimetypename : content_type_str));

            }

            pinfo->private_data = parameters;
            /*
             * First try the dedicated multipart dissector table
             */
            dissected = dissector_try_string(multipart_media_subdissector_table,
                        content_type_str, tmp_tvb, pinfo, subtree, NULL);
            if (! dissected) {
                /*
                 * Fall back to the default media dissector table
                 */
                dissected = dissector_try_string(media_type_dissector_table,
                        content_type_str, tmp_tvb, pinfo, subtree, NULL);
            }
            if (! dissected) {
                const char *save_match_string = pinfo->match_string;
                pinfo->match_string = content_type_str;
                call_dissector(media_handle, tmp_tvb, pinfo, subtree);
                pinfo->match_string = save_match_string;
            }
            pinfo->private_data = save_private_data;
            parameters = NULL; /* Shares same memory as content_type_str */
        } else {
            call_dissector(data_handle, tmp_tvb, pinfo, subtree);
        }
        proto_item_set_len(ti, boundary_start - start);
        if (*last_boundary == TRUE) {
           proto_tree_add_text(tree, tvb,
                 boundary_start, boundary_line_len,
                 "Last boundary: %s",
                 tvb_format_text(tvb, boundary_start,
                    boundary_line_len));
        } else {
           proto_tree_add_text(tree, tvb,
                 boundary_start, boundary_line_len,
                 "Boundary: %s",
                 tvb_format_text(tvb, boundary_start,
                    boundary_line_len));
        }

        g_free(filename);
        g_free(mimetypename);

        return boundary_start + boundary_line_len;
    }

    g_free(filename);
    g_free(mimetypename);

    return -1;
}
Пример #21
0
/*
 * This function dissects an "Ice string", adds hf to "tree" and returns consumed
 * bytes in "*consumed", if errors "*consumed" is -1.
 *
 * "*dest" is a null terminated version of the dissected Ice string.
 */
static void dissect_ice_string(packet_info *pinfo, proto_tree *tree, proto_item *item, int hf_icep,
                               tvbuff_t *tvb, guint32 offset, gint32 *consumed, char **dest)
{
    /* p. 586 chapter 23.2.1 and p. 588 chapter 23.2.5
     * string == Size + content
     * string = 1byte (0..254) + string not null terminated
     * or
     * string = 1byte (255) + 1int (255..2^32-1) + string not null terminated
     */

    guint32 Size = 0;
    char *s = NULL;

    (*consumed) = 0;

    /* check for first byte */
    if ( !tvb_bytes_exist(tvb, offset, 1) ) {

        expert_add_info_format(pinfo, item, &ei_icep_string_malformed, "1st byte of Size missing");
        col_append_str(pinfo->cinfo, COL_INFO, " (1st byte of Size missing)");

        (*consumed) = -1;
        return;
    }

    /* get the Size */
    Size = tvb_get_guint8(tvb, offset);
    offset++;
    (*consumed)++;

    if ( Size == 255 ) {

        /* check for next 4 bytes */
        if ( !tvb_bytes_exist(tvb, offset, 4) ) {

            expert_add_info_format(pinfo, item, &ei_icep_string_malformed, "second field of Size missing");
            col_append_str(pinfo->cinfo, COL_INFO, " (second field of Size missing)");

            (*consumed) = -1;
            return;
        }

        /* get second field of Size */
        Size = tvb_get_letohl(tvb, offset);
        offset += 4;
        (*consumed) += 4;
    }

    DBG1("string.Size --> %d\n", Size);

    /* check if the string exists */
    if ( !tvb_bytes_exist(tvb, offset, Size) ) {

        expert_add_info_format(pinfo, item, &ei_icep_string_malformed, "missing or truncated string");
        col_append_str(pinfo->cinfo, COL_INFO, " (missing or truncated string)");

        (*consumed) = -1;
        return;
    }

    if ( Size > icep_max_ice_string_len ) {

        expert_add_info(pinfo, item, &ei_icep_string_too_long);
        col_append_str(pinfo->cinfo, COL_INFO, " (string too long)");

        (*consumed) = -1;
        return;
    }


    if ( Size != 0 ) {
        s = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, Size, ENC_ASCII);
        proto_tree_add_string(tree, hf_icep, tvb, offset, Size, s);
    } else {
        s = wmem_strdup(wmem_packet_scope(), "(empty)");
        /* display the 0x00 Size byte when click on a empty ice_string */
        proto_tree_add_string(tree, hf_icep, tvb, offset - 1, 1, s);
    }

    if ( dest != NULL )
        *dest = s;

    /*offset += Size;*/
    (*consumed) += Size;
    return;
}
Пример #22
0
char *get_conversation_filter(conv_item_t *conv_item, conv_direction_e direction)
{
    char *sport, *dport, *src_addr, *dst_addr;
    char *str;

    sport = ct_port_to_str(conv_item->ptype, conv_item->src_port);
    dport = ct_port_to_str(conv_item->ptype, conv_item->dst_port);
    src_addr = address_to_str(NULL, &conv_item->src_address);
    dst_addr = address_to_str(NULL, &conv_item->dst_address);

    if (conv_item->src_address.type == AT_STRINGZ || conv_item->src_address.type == AT_USB) {
        char *new_addr;

        new_addr = wmem_strdup_printf(NULL, "\"%s\"", src_addr);
        wmem_free(NULL, src_addr);
        src_addr = new_addr;
    }
    if (conv_item->dst_address.type == AT_STRINGZ || conv_item->dst_address.type == AT_USB) {
        char *new_addr;

        new_addr = wmem_strdup_printf(NULL, "\"%s\"", dst_addr);
        wmem_free(NULL, dst_addr);
        dst_addr = new_addr;
    }

    switch(direction){
    case CONV_DIR_A_TO_FROM_B:
        /* A <-> B */
        str = wmem_strdup_printf(NULL, "%s==%s%s%s%s%s && %s==%s%s%s%s%s",
                              conversation_get_filter_name(conv_item,  CONV_FT_ANY_ADDRESS),
                              src_addr,
                              sport?" && ":"",
                              sport?conversation_get_filter_name(conv_item,  CONV_FT_ANY_PORT):"",
                              sport?"==":"",
                              sport?sport:"",
                              conversation_get_filter_name(conv_item,  CONV_FT_ANY_ADDRESS),
                              dst_addr,
                              dport?" && ":"",
                              dport?conversation_get_filter_name(conv_item,  CONV_FT_ANY_PORT):"",
                              dport?"==":"",
                              dport?dport:""
            );
        break;
    case CONV_DIR_A_TO_B:
        /* A --> B */
        str = wmem_strdup_printf(NULL, "%s==%s%s%s%s%s && %s==%s%s%s%s%s",
                              conversation_get_filter_name(conv_item,  CONV_FT_SRC_ADDRESS),
                              src_addr,
                              sport?" && ":"",
                              sport?conversation_get_filter_name(conv_item,  CONV_FT_SRC_PORT):"",
                              sport?"==":"",
                              sport?sport:"",
                              conversation_get_filter_name(conv_item,  CONV_FT_DST_ADDRESS),
                              dst_addr,
                              dport?" && ":"",
                              dport?conversation_get_filter_name(conv_item,  CONV_FT_DST_PORT):"",
                              dport?"==":"",
                              dport?dport:""
            );
        break;
    case CONV_DIR_A_FROM_B:
        /* A <-- B */
        str = wmem_strdup_printf(NULL, "%s==%s%s%s%s%s && %s==%s%s%s%s%s",
                              conversation_get_filter_name(conv_item,  CONV_FT_DST_ADDRESS),
                              src_addr,
                              sport?" && ":"",
                              sport?conversation_get_filter_name(conv_item,  CONV_FT_DST_PORT):"",
                              sport?"==":"",
                              sport?sport:"",
                              conversation_get_filter_name(conv_item,  CONV_FT_SRC_ADDRESS),
                              dst_addr,
                              dport?" && ":"",
                              dport?conversation_get_filter_name(conv_item,  CONV_FT_SRC_PORT):"",
                              dport?"==":"",
                              dport?dport:""
            );
        break;
    case CONV_DIR_A_TO_FROM_ANY:
        /* A <-> ANY */
        str = wmem_strdup_printf(NULL, "%s==%s%s%s%s%s",
                              conversation_get_filter_name(conv_item,  CONV_FT_ANY_ADDRESS),
                              src_addr,
                              sport?" && ":"",
                              sport?conversation_get_filter_name(conv_item,  CONV_FT_ANY_PORT):"",
                              sport?"==":"",
                              sport?sport:""
            );
        break;
    case CONV_DIR_A_TO_ANY:
        /* A --> ANY */
        str = wmem_strdup_printf(NULL, "%s==%s%s%s%s%s",
                              conversation_get_filter_name(conv_item,  CONV_FT_SRC_ADDRESS),
                              src_addr,
                              sport?" && ":"",
                              sport?conversation_get_filter_name(conv_item,  CONV_FT_SRC_PORT):"",
                              sport?"==":"",
                              sport?sport:""
            );
        break;
    case CONV_DIR_A_FROM_ANY:
        /* A <-- ANY */
        str = wmem_strdup_printf(NULL, "%s==%s%s%s%s%s",
                              conversation_get_filter_name(conv_item,  CONV_FT_DST_ADDRESS),
                              src_addr,
                              sport?" && ":"",
                              sport?conversation_get_filter_name(conv_item,  CONV_FT_DST_PORT):"",
                              sport?"==":"",
                              sport?sport:""
            );
        break;
    case CONV_DIR_ANY_TO_FROM_B:
        /* ANY <-> B */
        str = wmem_strdup_printf(NULL, "%s==%s%s%s%s%s",
                              conversation_get_filter_name(conv_item,  CONV_FT_ANY_ADDRESS),
                              dst_addr,
                              dport?" && ":"",
                              dport?conversation_get_filter_name(conv_item,  CONV_FT_ANY_PORT):"",
                              dport?"==":"",
                              dport?dport:""
            );
        break;
    case CONV_DIR_ANY_FROM_B:
        /* ANY <-- B */
        str = wmem_strdup_printf(NULL, "%s==%s%s%s%s%s",
                              conversation_get_filter_name(conv_item,  CONV_FT_SRC_ADDRESS),
                              dst_addr,
                              dport?" && ":"",
                              dport?conversation_get_filter_name(conv_item,  CONV_FT_SRC_PORT):"",
                              dport?"==":"",
                              dport?dport:""
            );
        break;
    case CONV_DIR_ANY_TO_B:
        /* ANY --> B */
        str = wmem_strdup_printf(NULL, "%s==%s%s%s%s%s",
                              conversation_get_filter_name(conv_item,  CONV_FT_DST_ADDRESS),
                              dst_addr,
                              dport?" && ":"",
                              dport?conversation_get_filter_name(conv_item,  CONV_FT_DST_PORT):"",
                              dport?"==":"",
                              dport?dport:""
            );
        break;
    default:
        str = wmem_strdup(NULL, "INVALID");
        break;
    }
    g_free(sport);
    g_free(dport);
    wmem_free(NULL, src_addr);
    wmem_free(NULL, dst_addr);
    return str;
}
Пример #23
0
	if( acse_ctx_oid_table ){
		g_hash_table_destroy(acse_ctx_oid_table);
		acse_ctx_oid_table = NULL;
	}
	acse_ctx_oid_table = g_hash_table_new(acse_ctx_oid_hash,
			acse_ctx_oid_equal);

}

static void
register_ctx_id_and_oid(packet_info *pinfo _U_, guint32 idx, char *oid)
{
	acse_ctx_oid_t *aco, *tmpaco;
	aco=wmem_new(wmem_file_scope(), acse_ctx_oid_t);
	aco->ctx_id=idx;
	aco->oid=wmem_strdup(wmem_file_scope(), oid);

	/* if this ctx already exists, remove the old one first */
	tmpaco=(acse_ctx_oid_t *)g_hash_table_lookup(acse_ctx_oid_table, aco);
	if(tmpaco){
		g_hash_table_remove(acse_ctx_oid_table, tmpaco);
	}
	g_hash_table_insert(acse_ctx_oid_table, aco, aco);
}
static char *
find_oid_by_ctx_id(packet_info *pinfo _U_, guint32 idx)
{
	acse_ctx_oid_t aco, *tmpaco;
	aco.ctx_id=idx;
	tmpaco=(acse_ctx_oid_t *)g_hash_table_lookup(acse_ctx_oid_table, &aco);
	if(tmpaco){
Пример #24
0
static gchar* dfilter_macro_apply_recurse(const gchar* text, guint depth, gchar** error) {
	enum { OUTSIDE, STARTING, NAME, ARGS } state = OUTSIDE;
	GString* out;
	GString* name = NULL;
	GString* arg = NULL;
	GPtrArray* args = NULL;
	gchar c;
	const gchar* r = text;
	gboolean changed = FALSE;

	if ( depth > 31) {
		if (error != NULL)
			*error = g_strdup("too much nesting in macros");
		return NULL;
	}

#define FGS(n) if (n) g_string_free(n,TRUE); n = NULL

#define FREE_ALL() \
	do { \
		FGS(name); \
		FGS(arg); \
		if (args) { \
			while(args->len) { void* p = g_ptr_array_remove_index_fast(args,0); if (p) g_free(p); } \
			g_ptr_array_free(args,TRUE); \
			args = NULL; \
		} \
	} while(0)

	if (error != NULL)
		*error = NULL;
	out = g_string_sized_new(64);

	while(1) {
		c = *r++;

		switch(state) {
			case OUTSIDE: {
				switch(c) {
					case '\0': {
						goto finish;
					} case '$': {
						state = STARTING;
						break;
					} default: {
						g_string_append_c(out,c);
						break;
					}
				}
				break;
			} case STARTING: {
				switch (c) {
					case '{': {
						args = g_ptr_array_new();
						arg = g_string_sized_new(32);
						name = g_string_sized_new(32);

						state = NAME;

						break;
					} case '\0': {
						g_string_append_c(out,'$');

						goto finish;
					} default: {
						g_string_append_c(out,'$');
						g_string_append_c(out,c);

						state = OUTSIDE;

						break;
					}
				}
				break;
			} case NAME: {
				if ( g_ascii_isalnum(c) || c == '_' || c == '-' || c == '.' ) {
					g_string_append_c(name,c);
				} else if ( c == ':') {
					state = ARGS;
				} else if ( c == '}') {
					gchar* resolved;

					g_ptr_array_add(args,NULL);

					resolved = dfilter_macro_resolve(name->str, (gchar**)args->pdata, error);
					if (resolved == NULL)
						goto on_error;

					changed = TRUE;

					g_string_append(out,resolved);
					wmem_free(NULL, resolved);

					FREE_ALL();

					state = OUTSIDE;
				} else if ( c == '\0') {
					if (error != NULL)
						*error = g_strdup("end of filter in the middle of a macro expression");
					goto on_error;
				} else {
					if (error != NULL)
						*error = g_strdup("invalid character in macro name");
					goto on_error;
				}
				break;
			} case ARGS: {
				switch(c) {
					case '\0': {
						if (error != NULL)
							*error = g_strdup("end of filter in the middle of a macro expression");
						goto on_error;
					} case ';': {
						g_ptr_array_add(args,g_string_free(arg,FALSE));

						arg = g_string_sized_new(32);
						break;
					} case '\\': {
						c = *r++;
						if (c) {
							g_string_append_c(arg,c);
							break;
						} else {
							if (error != NULL)
								*error = g_strdup("end of filter in the middle of a macro expression");
							goto on_error;
						}
					} default: {
						g_string_append_c(arg,c);
						break;
					} case '}': {
						gchar* resolved;
						g_ptr_array_add(args,g_string_free(arg,FALSE));
						g_ptr_array_add(args,NULL);

						arg = NULL;

						resolved = dfilter_macro_resolve(name->str, (gchar**)args->pdata, error);
						if (resolved == NULL)
							goto on_error;

						changed = TRUE;

						g_string_append(out,resolved);
						wmem_free(NULL, resolved);

						FREE_ALL();

						state = OUTSIDE;
						break;
					}
				}
				break;
			}
		}
	}

finish:
	{
		FREE_ALL();

		if (changed) {
			gchar* resolved = dfilter_macro_apply_recurse(out->str, depth + 1, error);
			g_string_free(out,TRUE);
			return resolved;
		} else {
			gchar* out_str = wmem_strdup(NULL, out->str);
			g_string_free(out,TRUE);
			return out_str;
		}
	}
on_error:
	{
		FREE_ALL();
		if (error != NULL) {
			if (*error == NULL)
				*error = g_strdup("unknown error in macro expression");
		}
		g_string_free(out,TRUE);
		return NULL;
	}
}
Пример #25
0
static gchar* dfilter_macro_resolve(gchar* name, gchar** args, gchar** error) {
	GString* text;
	int argc = 0;
	dfilter_macro_t* m = NULL;
	fvt_cache_entry_t* e;
	int* arg_pos_p;
	gchar** parts;
	gchar* ret;
	guint i;

	for (i = 0; i < num_macros; i++) {
		dfilter_macro_t* c = &(macros[i]);
		if ( c->usable && g_str_equal(c->name,name) ) {
			m = c;
			break;
		}
	}

	if (!m) {
		if (fvt_cache &&
		    (e = (fvt_cache_entry_t  *)g_hash_table_lookup(fvt_cache,name)) != NULL) {
			if(e->usable) {
				return wmem_strdup(NULL, e->repr);
			} else {
				if (error != NULL)
					*error = g_strdup_printf("macro '%s' is unusable", name);
				return NULL;
			}
		} else {
			if (error != NULL)
				*error = g_strdup_printf("macro '%s' does not exist", name);
			return NULL;
		}
	}

	DUMP_MACRO(m);

	if (args) {
		while(args[argc]) argc++;
	}

	if (argc != m->argc) {
		if (error != NULL) {
			*error = g_strdup_printf("wrong number of arguments for macro '%s', expecting %d instead of %d",
									  name, m->argc, argc);
		}
		return NULL;
	}

	arg_pos_p = m->args_pos;
	parts = m->parts;

	text = g_string_new(*(parts++));

	if (args) {
		while (*parts) {
			g_string_append_printf(text,"%s%s",
					       args[*(arg_pos_p++)],
					       *(parts++));
		}
	}

	ret = wmem_strdup(NULL, text->str);

	g_string_free(text,TRUE);

	return ret;
}
Пример #26
0
static void
dissect_fw1(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    *volatile fh_tree = NULL;
  char          direction;
  char  chain;
  char          *interface_name;
  guint32       iface_len = 10;
  wmem_strbuf_t *header;
  int           i;
  gboolean      found;
  static const char     fw1_header[] = "FW1 Monitor";
  ethertype_data_t ethertype_data;

  header = wmem_strbuf_new_label(wmem_epan_scope());
  wmem_strbuf_append(header, fw1_header);

  /* Make entries in Protocol column and Info column on summary display */
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "FW1");
  col_clear(pinfo->cinfo, COL_INFO);


  /* g_snprintf(header, sizeof(header), fw1_header); */

  /* fetch info to local variable */
  direction = tvb_get_guint8(tvb, 0);

  if (!fw1_iflist_with_chain)
    chain = ' ';
  else
    chain = tvb_get_guint8(tvb, 1);

  if (fw1_with_uuid)
    iface_len = 6;

  interface_name=(char *)wmem_alloc(wmem_packet_scope(), iface_len+1);
  tvb_get_nstringz0(tvb, 2, iface_len+1, interface_name);

  /* Known interface name - if not, remember it */
  found=FALSE;
  for (i=0; i<interface_anzahl; i++) {
    if ( strcmp(p_interfaces[i], interface_name) == 0 ) {
      found=TRUE;
      break;
    }
  }
  if (!found && interface_anzahl < MAX_INTERFACES) {
    p_interfaces[interface_anzahl] = wmem_strdup(wmem_file_scope(), interface_name);
    interface_anzahl++;
  }

  /* display all interfaces always in the same order */
  for (i=0; i<interface_anzahl; i++) {
    if ( strcmp(p_interfaces[i], interface_name) == 0 ) {
      wmem_strbuf_append_printf(header, "  %c%c %s %c%c",
                                direction == 'i' ? 'i' : (direction == 'O' ? 'O' : ' '),
                                (direction == 'i' || direction == 'O') ? chain : ' ',
                                p_interfaces[i],
                                direction == 'I' ? 'I' : (direction == 'o' ? 'o' : ' '),
                                (direction == 'I' || direction == 'o') ? chain : ' '
        );
    } else {
      wmem_strbuf_append_printf(header, "    %s  ", p_interfaces[i]);
    }
  }

  col_add_str(pinfo->cinfo, COL_IF_DIR, wmem_strbuf_get_str(header) + sizeof(fw1_header) + 1);

  if (tree) {
    if (!fw1_summary_in_tree)
      /* Do not show the summary in Protocol Tree */
      ti = proto_tree_add_protocol_format(tree, proto_fw1, tvb, 0, ETH_HEADER_SIZE, "%s", fw1_header);
    else
      ti = proto_tree_add_protocol_format(tree, proto_fw1, tvb, 0, ETH_HEADER_SIZE, "%s", wmem_strbuf_get_str(header));

    /* create display subtree for the protocol */
    fh_tree = proto_item_add_subtree(ti, ett_fw1);

    proto_tree_add_item(fh_tree, hf_fw1_direction, tvb, 0, 1, ENC_ASCII|ENC_NA);

    if (fw1_iflist_with_chain)
      proto_tree_add_item(fh_tree, hf_fw1_chain, tvb, 1, 1, ENC_ASCII|ENC_NA);

    proto_tree_add_item(fh_tree, hf_fw1_interface, tvb, 2, iface_len, ENC_ASCII|ENC_NA);

    if (fw1_with_uuid)
      proto_tree_add_item(fh_tree, hf_fw1_uuid, tvb, 8, 4, ENC_BIG_ENDIAN);
  }

  ethertype_data.etype = tvb_get_ntohs(tvb, 12);
  ethertype_data.offset_after_ethertype = ETH_HEADER_SIZE;
  ethertype_data.fh_tree = fh_tree;
  ethertype_data.etype_id = hf_fw1_type;
  ethertype_data.trailer_id = hf_fw1_trailer;
  ethertype_data.fcs_len = 0;

  call_dissector_with_data(ethertype_handle, tvb, pinfo, tree, &ethertype_data);
}
Пример #27
0
static void
expert_set_info_vformat(packet_info *pinfo, proto_item *pi, int group, int severity, int hf_index, gboolean use_vaformat,
			const char *format, va_list ap)
{
	char           formatted[ITEM_LABEL_LENGTH];
	int            tap;
	expert_info_t *ei;
	proto_tree    *tree;
	proto_item    *ti;

	if (pinfo == NULL && pi && pi->tree_data) {
		pinfo = PTREE_DATA(pi)->pinfo;
	}

	/* if this packet isn't loaded because of a read filter, don't output anything */
	if (pinfo == NULL || pinfo->num == 0) {
		return;
	}

	if (severity > highest_severity) {
		highest_severity = severity;
	}

	/* XXX: can we get rid of these checks and make them programming errors instead now? */
	if (pi != NULL && PITEM_FINFO(pi) != NULL) {
		expert_set_item_flags(pi, group, severity);
	}

	if ((pi == NULL) || (PITEM_FINFO(pi) == NULL) ||
		((guint)severity >= FI_GET_FLAG(PITEM_FINFO(pi), PI_SEVERITY_MASK))) {
		col_add_str(pinfo->cinfo, COL_EXPERT, val_to_str(severity, expert_severity_vals, "Unknown (%u)"));
	}

	if (use_vaformat) {
		g_vsnprintf(formatted, ITEM_LABEL_LENGTH, format, ap);
	} else {
		g_strlcpy(formatted, format, ITEM_LABEL_LENGTH);
	}

	tree = expert_create_tree(pi, group, severity, formatted);

	if (hf_index == -1) {
		/* If no filterable expert info, just add the message */
		ti = proto_tree_add_string(tree, hf_expert_msg, NULL, 0, 0, formatted);
		PROTO_ITEM_SET_GENERATED(ti);
	} else {
		/* If filterable expert info, hide the "generic" form of the message,
		   and generate the formatted filterable expert info */
		ti = proto_tree_add_none_format(tree, hf_index, NULL, 0, 0, "%s", formatted);
		PROTO_ITEM_SET_GENERATED(ti);
		ti = proto_tree_add_string(tree, hf_expert_msg, NULL, 0, 0, formatted);
		PROTO_ITEM_SET_HIDDEN(ti);
	}

	ti = proto_tree_add_uint_format_value(tree, hf_expert_severity, NULL, 0, 0, severity,
					      "%s", val_to_str_const(severity, expert_severity_vals, "Unknown"));
	PROTO_ITEM_SET_GENERATED(ti);
	ti = proto_tree_add_uint_format_value(tree, hf_expert_group, NULL, 0, 0, group,
					      "%s", val_to_str_const(group, expert_group_vals, "Unknown"));
	PROTO_ITEM_SET_GENERATED(ti);

	tap = have_tap_listener(expert_tap);

	if (!tap)
		return;

	ei = wmem_new(wmem_packet_scope(), expert_info_t);

	ei->packet_num  = pinfo->num;
	ei->group       = group;
	ei->severity    = severity;
	ei->hf_index    = hf_index;
	ei->protocol    = pinfo->current_proto;
	ei->summary     = wmem_strdup(wmem_packet_scope(), formatted);

	/* if we have a proto_item (not a faked item), set expert attributes to it */
	if (pi != NULL && PITEM_FINFO(pi) != NULL) {
		ei->pitem = pi;
	}
	/* XXX: remove this because we don't have an internal-only function now? */
	else {
		ei->pitem = NULL;
	}

	tap_queue_packet(expert_tap, pinfo, ei);
}
Пример #28
0
/*
 * Process a multipart body-part:
 *      MIME-part-headers [ line-end *OCTET ]
 *      line-end dashed-boundary transport-padding line-end
 *
 * If applicable, call a media subdissector.
 *
 * Return the offset to the start of the next body-part.
 */
static gint
process_body_part(proto_tree *tree, tvbuff_t *tvb, multipart_info_t *m_info,
                  packet_info *pinfo, gint start, gint idx,
                  gboolean *last_boundary)
{
    proto_tree *subtree;
    proto_item *ti;
    gint offset = start, next_offset = 0;
    char *parameters = NULL;
    gint body_start, boundary_start, boundary_line_len;

    gchar *content_type_str = NULL;
    gchar *content_encoding_str = NULL;
    char *filename = NULL;
    char *mimetypename = NULL;
    int  len = 0;
    gboolean last_field = FALSE;
    gboolean is_raw_data = FALSE;

    const guint8 *boundary = (guint8 *)m_info->boundary;
    gint boundary_len = m_info->boundary_length;

    ti = proto_tree_add_item(tree, hf_multipart_part, tvb, start, 0, ENC_ASCII|ENC_NA);
    subtree = proto_item_add_subtree(ti, ett_multipart_body);

    /* find the next boundary to find the end of this body part */
    boundary_start = find_next_boundary(tvb, offset, boundary, boundary_len,
                                        &boundary_line_len, last_boundary);

    if (boundary_start <= 0) {
        return -1;
    }

    /*
     * Process the MIME-part-headers
     */

    while (!last_field)
    {
        gint colon_offset;
        char *hdr_str;
        char *header_str;

        /* Look for the end of the header (denoted by cr)
         * 3:d argument to imf_find_field_end() maxlen; must be last offset in the tvb.
         */
        next_offset = imf_find_field_end(tvb, offset, tvb_reported_length_remaining(tvb, offset)+offset, &last_field);
        /* the following should never happen */
        /* If cr not found, won't have advanced - get out to avoid infinite loop! */
        /*
        if (next_offset == offset) {
            break;
        }
        */
        if (last_field && (next_offset+2) <= boundary_start) {
            /* Add the extra CRLF of the last field */
            next_offset += 2;
        } else if((next_offset-2) == boundary_start) {
            /* if CRLF is the start of next boundary it belongs to the boundary and not the field,
               so it's the last field without CRLF */
            last_field = TRUE;
            next_offset -= 2;
        } else if (next_offset > boundary_start) {
            /* if there is no CRLF between last field and next boundary - trim it! */
            next_offset = boundary_start;
        }

        hdr_str = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, next_offset - offset, ENC_ASCII);

        header_str = unfold_and_compact_mime_header(hdr_str, &colon_offset);
        if (colon_offset <= 0) {
            /* if there is no colon it's no header, so break and add complete line to the body */
            next_offset = offset;
            break;
        } else {
            gint hf_index;

            /* Split header name from header value */
            header_str[colon_offset] = '\0';
            hf_index = is_known_multipart_header(header_str, colon_offset);

            if (hf_index == -1) {
                if(isprint_string(hdr_str)) {
                    proto_tree_add_format_text(subtree, tvb, offset, next_offset - offset);
                } else {
                    /* if the header name is unkown and not printable, break and add complete line to the body */
                    next_offset = offset;
                    break;
                }
            } else {
                char *value_str = header_str + colon_offset + 1;

                proto_tree_add_string_format(subtree,
                                             hf_header_array[hf_index], tvb,
                                             offset, next_offset - offset,
                                             (const char *)value_str, "%s",
                                             tvb_format_text(tvb, offset, next_offset - offset));

                switch (hf_index) {
                case POS_ORIGINALCONTENT:
                {
                    gint semicolon_offset;
                    /* The Content-Type starts at colon_offset + 1 or after the type parameter */
                    char* type_str = find_parameter(value_str, "type=", NULL);
                    if(type_str != NULL) {
                        value_str = type_str;
                    }

                    semicolon_offset = index_of_char(
                                           value_str, ';');

                    if (semicolon_offset > 0) {
                        value_str[semicolon_offset] = '\0';
                        m_info->orig_parameters = wmem_strdup(wmem_packet_scope(),
                                                              value_str + semicolon_offset + 1);
                    }

                    m_info->orig_content_type = wmem_ascii_strdown(wmem_packet_scope(), value_str, -1);
                }
                break;
                case POS_CONTENT_TYPE:
                {
                    /* The Content-Type starts at colon_offset + 1 */
                    gint semicolon_offset = index_of_char(
                                                value_str, ';');

                    if (semicolon_offset > 0) {
                        value_str[semicolon_offset] = '\0';
                        parameters = wmem_strdup(wmem_packet_scope(), value_str + semicolon_offset + 1);
                    } else {
                        parameters = NULL;
                    }

                    content_type_str = wmem_ascii_strdown(wmem_packet_scope(), value_str, -1);

                    /* Show content-type in root 'part' label */
                    proto_item_append_text(ti, " (%s)", content_type_str);

                    /* find the "name" parameter in case we don't find a content disposition "filename" */
                    if((mimetypename = find_parameter(parameters, "name=", &len)) != NULL) {
                        mimetypename = g_strndup(mimetypename, len);
                    }

                    if(strncmp(content_type_str, "application/octet-stream",
                               sizeof("application/octet-stream")-1) == 0) {
                        is_raw_data = TRUE;
                    }

                    /* there are only 2 body parts possible and each part has specific content types */
                    if(m_info->protocol && idx == 0
                            && (is_raw_data || g_ascii_strncasecmp(content_type_str, m_info->protocol,
                                    strlen(m_info->protocol)) != 0))
                    {
                        return -1;
                    }
                }
                break;
                case POS_CONTENT_TRANSFER_ENCODING:
                {
                    /* The Content-Transferring starts at colon_offset + 1 */
                    gint cr_offset = index_of_char(value_str, '\r');

                    if (cr_offset > 0) {
                        value_str[cr_offset] = '\0';
                    }

                    content_encoding_str = wmem_ascii_strdown(wmem_packet_scope(), value_str, -1);
                }
                break;
                case POS_CONTENT_DISPOSITION:
                {
                    /* find the "filename" parameter */
                    if((filename = find_parameter(value_str, "filename=", &len)) != NULL) {
                        filename = g_strndup(filename, len);
                    }
                }
                break;
                default:
                    break;
                }
            }
        }
        offset = next_offset;
    }

    body_start = next_offset;

    /*
     * Process the body
     */

    {
        gint body_len = boundary_start - body_start;
        tvbuff_t *tmp_tvb = tvb_new_subset_length(tvb, body_start, body_len);
        /* if multipart subtype is encrypted the protcol string was set */
        /* see: https://msdn.microsoft.com/en-us/library/cc251581.aspx */
        /* there are only 2 body parts possible and each part has specific content types */
        if(m_info->protocol && idx == 1 && is_raw_data)
        {
            gssapi_encrypt_info_t  encrypt;

            memset(&encrypt, 0, sizeof(encrypt));
            encrypt.decrypt_gssapi_tvb=DECRYPT_GSSAPI_NORMAL;

            dissect_kerberos_encrypted_message(tmp_tvb, pinfo, subtree, &encrypt);

            if(encrypt.gssapi_decrypted_tvb) {
                tmp_tvb = encrypt.gssapi_decrypted_tvb;
                is_raw_data = FALSE;
                content_type_str = m_info->orig_content_type;
                parameters = m_info->orig_parameters;
            } else if(encrypt.gssapi_encrypted_tvb) {
                tmp_tvb = encrypt.gssapi_encrypted_tvb;
                proto_tree_add_expert(tree, pinfo, &ei_multipart_decryption_not_possible, tmp_tvb, 0, -1);
            }
        }

        if (!is_raw_data &&
                content_type_str) {

            /*
             * subdissection
             */
            gboolean dissected;

            /*
             * Try and remove any content transfer encoding so that each sub-dissector
             * doesn't have to do it itself
             *
             */

            if(content_encoding_str && remove_base64_encoding) {

                if(!g_ascii_strncasecmp(content_encoding_str, "base64", 6))
                    tmp_tvb = base64_decode(pinfo, tmp_tvb, filename ? filename : (mimetypename ? mimetypename : content_type_str));

            }

            /*
             * First try the dedicated multipart dissector table
             */
            dissected = dissector_try_string(multipart_media_subdissector_table,
                                             content_type_str, tmp_tvb, pinfo, subtree, parameters);
            if (! dissected) {
                /*
                 * Fall back to the default media dissector table
                 */
                dissected = dissector_try_string(media_type_dissector_table,
                                                 content_type_str, tmp_tvb, pinfo, subtree, parameters);
            }
            if (! dissected) {
                const char *save_match_string = pinfo->match_string;
                pinfo->match_string = content_type_str;
                call_dissector_with_data(media_handle, tmp_tvb, pinfo, subtree, parameters);
                pinfo->match_string = save_match_string;
            }
            parameters = NULL; /* Shares same memory as content_type_str */
        } else {
            call_dissector(data_handle, tmp_tvb, pinfo, subtree);
        }
        proto_item_set_len(ti, boundary_start - start);
        if (*last_boundary == TRUE) {
            proto_tree_add_item(tree, hf_multipart_last_boundary, tvb, boundary_start, boundary_line_len, ENC_NA|ENC_ASCII);
        } else {
            proto_tree_add_item(tree, hf_multipart_boundary, tvb, boundary_start, boundary_line_len, ENC_NA|ENC_ASCII);
        }

        g_free(filename);
        g_free(mimetypename);

        return boundary_start + boundary_line_len;
    }
}
Пример #29
0
static void
dissect_quakeworld_ConnectionlessPacket(tvbuff_t *tvb, packet_info *pinfo,
	proto_tree *tree, int direction)
{
	proto_tree	*cl_tree   = NULL;
	proto_tree	*text_tree = NULL;
	guint8		*text;
	int		len;
	int		offset;
	guint32		marker;
	int		command_len;
	const char	*command = "";
	gboolean	command_finished = FALSE;

	marker = tvb_get_ntohl(tvb, 0);
	if (tree) {
		proto_item *cl_item;
		cl_item = proto_tree_add_text(tree, tvb, 0, -1, "Connectionless");
		cl_tree = proto_item_add_subtree(cl_item, ett_quakeworld_connectionless);

		proto_tree_add_uint(cl_tree, hf_quakeworld_connectionless_marker,
				tvb, 0, 4, marker);
	}

	/* all the rest of the packet is just text */
        offset = 4;

	text = tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset, &len, ENC_ASCII|ENC_NA);
	/* actually, we should look for a eol char and stop already there */

        if (cl_tree) {
		proto_item *text_item;
                text_item = proto_tree_add_string(cl_tree, hf_quakeworld_connectionless_text,
						  tvb, offset, len, text);
		text_tree = proto_item_add_subtree(text_item, ett_quakeworld_connectionless_text);
        }

	if (direction == DIR_C2S) {
		/* client to server commands */
		const char *c;

		Cmd_TokenizeString(text);
		c = Cmd_Argv(0);

		/* client to sever commands */
		if (strcmp(c,"ping") == 0) {
			command = "Ping";
			command_len = 4;
		} else if (strcmp(c,"status") == 0) {
			command = "Status";
			command_len = 6;
		} else if (strcmp(c,"log") == 0) {
			command = "Log";
			command_len = 3;
		} else if (strcmp(c,"connect") == 0) {
			int version;
			int qport;
			int challenge;
			const char *infostring;
			proto_tree *argument_tree = NULL;
			command = "Connect";
			command_len = Cmd_Argv_length(0);
			if (text_tree) {
				proto_item *argument_item;
				proto_tree_add_string(text_tree, hf_quakeworld_connectionless_command,
					tvb, offset, command_len, command);
				argument_item = proto_tree_add_string(text_tree,
					hf_quakeworld_connectionless_arguments,
					tvb, offset + Cmd_Argv_start(1), len + 1 - Cmd_Argv_start(1),
					text + Cmd_Argv_start(1));
				argument_tree = proto_item_add_subtree(argument_item,
								       ett_quakeworld_connectionless_arguments);
				command_finished=TRUE;
			}
			version    = atoi(Cmd_Argv(1));
			qport      = atoi(Cmd_Argv(2));
			challenge  = atoi(Cmd_Argv(3));
			infostring = Cmd_Argv(4);
			if (argument_tree) {
				proto_item *info_item;
				proto_tree *info_tree;
				proto_tree_add_uint(argument_tree,
					hf_quakeworld_connectionless_connect_version,
					tvb,
					offset + Cmd_Argv_start(1),
					Cmd_Argv_length(1), version);
				proto_tree_add_uint(argument_tree,
					hf_quakeworld_connectionless_connect_qport,
					tvb,
					offset + Cmd_Argv_start(2),
					Cmd_Argv_length(2), qport);
				proto_tree_add_int(argument_tree,
					hf_quakeworld_connectionless_connect_challenge,
					tvb,
					offset + Cmd_Argv_start(3),
					Cmd_Argv_length(3), challenge);
				info_item = proto_tree_add_string(argument_tree,
					hf_quakeworld_connectionless_connect_infostring,
					tvb,
					offset + Cmd_Argv_start(4),
					Cmd_Argv_length(4), infostring);
				info_tree = proto_item_add_subtree(
					info_item, ett_quakeworld_connectionless_connect_infostring);
				dissect_id_infostring(tvb, info_tree, offset + Cmd_Argv_start(4),
					wmem_strdup(wmem_packet_scope(), infostring),
					ett_quakeworld_connectionless_connect_infostring_key_value,
					hf_quakeworld_connectionless_connect_infostring_key_value,
					hf_quakeworld_connectionless_connect_infostring_key,
					hf_quakeworld_connectionless_connect_infostring_value);
			}
		} else if (strcmp(c,"getchallenge") == 0) {
			command = "Get Challenge";
			command_len = Cmd_Argv_length(0);
		} else if (strcmp(c,"rcon") == 0) {
			const char* password;
			int i;
			char remaining[MAX_TEXT_SIZE+1];
			proto_tree *argument_tree = NULL;
			command = "Remote Command";
			command_len = Cmd_Argv_length(0);
			if (text_tree) {
				proto_item *argument_item;
				proto_tree_add_string(text_tree, hf_quakeworld_connectionless_command,
					tvb, offset, command_len, command);
				argument_item = proto_tree_add_string(text_tree,
					hf_quakeworld_connectionless_arguments,
					tvb, offset + Cmd_Argv_start(1), len - Cmd_Argv_start(1),
					text + Cmd_Argv_start(1));
				argument_tree =	proto_item_add_subtree(argument_item,
								       ett_quakeworld_connectionless_arguments);
				command_finished=TRUE;
			}
			password = Cmd_Argv(1);
			if (argument_tree) {
				proto_tree_add_string(argument_tree,
					hf_quakeworld_connectionless_rcon_password,
					tvb,
					offset + Cmd_Argv_start(1),
					Cmd_Argv_length(1), password);
			}
			remaining[0] = '\0';
			for (i=2; i<Cmd_Argc() ; i++) {
				g_strlcat (remaining, Cmd_Argv(i), MAX_TEXT_SIZE+1);
				g_strlcat (remaining, " ", MAX_TEXT_SIZE+1);
			}
			if (text_tree) {
				proto_tree_add_string(argument_tree,
					hf_quakeworld_connectionless_rcon_command,
					tvb, offset + Cmd_Argv_start(2),
					Cmd_Argv_start(Cmd_Argc()-1) + Cmd_Argv_length(Cmd_Argc()-1) -
					Cmd_Argv_start(2),
					remaining);
			}
		} else if (c[0]==A2A_PING && ( c[1]=='\0' || c[1]=='\n')) {
			command = "Ping";
			command_len = 1;
		} else if (c[0]==A2A_ACK && ( c[1]=='\0' || c[1]=='\n')) {
			command = "Ack";
			command_len = 1;
		} else {
			command = "Unknown";
			command_len = len - 1;
		}
	}
	else {
		/* server to client commands */
		if (text[0] == S2C_CONNECTION) {
			command = "Connected";
			command_len = 1;
		} else if (text[0] == A2C_CLIENT_COMMAND) {
			command = "Client Command";
			command_len = 1;
			/* stringz (command), stringz (localid) */
		} else if (text[0] == A2C_PRINT) {
			command = "Print";
			command_len = 1;
			/* string */
		} else if (text[0] == A2A_PING) {
			command = "Ping";
			command_len = 1;
		} else if (text[0] == S2C_CHALLENGE) {
			command = "Challenge";
			command_len = 1;
			/* string, atoi */
		} else {
			command = "Unknown";
			command_len = len - 1;
		}
	}

	col_append_fstr(pinfo->cinfo, COL_INFO, " %s", command);

	if (!command_finished) {
		proto_tree_add_string(text_tree, hf_quakeworld_connectionless_command,
			tvb, offset, command_len, command);
	}
	/*offset += len;*/
}
Пример #30
0
static int
ssh_dissect_key_exchange(tvbuff_t *tvb, packet_info *pinfo,
		struct ssh_flow_data *global_data,
		int offset, proto_tree *tree, int is_response,
		gboolean *need_desegmentation)
{
	guint 	plen, len;
	guint8	padding_length;
	guint	remain_length;
	int 	last_offset=offset;
	guint 	msg_code;

	proto_item *ti;
	proto_item *key_ex_tree =NULL;

	struct ssh_peer_data *peer_data = &global_data->peer_data[is_response];

	/*
	 * We use "tvb_ensure_length_remaining()" to make sure there
	 * actually *is* data remaining.
	 *
	 * This means we're guaranteed that "remain_length" is positive.
	 */
	remain_length = tvb_ensure_length_remaining(tvb, offset);
	/*
	 * Can we do reassembly?
	 */
	if (ssh_desegment && pinfo->can_desegment) {
		/*
		 * Yes - would an SSH header starting at this offset
		 * be split across segment boundaries?
		 */
		if (remain_length < 4) {
			/*
			 * Yes.  Tell the TCP dissector where the data for
			 * this message starts in the data it handed us and
			 * that we need "some more data."  Don't tell it
			 * exactly how many bytes we need because if/when we
			 * ask for even more (after the header) that will
			 * break reassembly.
			 */
			pinfo->desegment_offset = offset;
			pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT;
			*need_desegmentation = TRUE;
			return offset;
		}
	}
	plen = tvb_get_ntohl(tvb, offset) ;

	if (ssh_desegment && pinfo->can_desegment) {
		if (plen +4 >  remain_length) {
			pinfo->desegment_offset = offset;
			pinfo->desegment_len = plen+4 - remain_length;
			*need_desegmentation = TRUE;
			return offset;
		}
	}
	/*
	 * Need to check plen > 0x80000000 here
	 */

	ti = proto_tree_add_uint(tree, hf_ssh_packet_length, tvb,
					offset, 4, plen);
	if (plen >= 0xffff) {
		expert_add_info_format(pinfo, ti, &ei_ssh_packet_length, "Overly large number %d", plen);
		plen = remain_length-4;
	}
	offset+=4;

	/* padding length */
	padding_length = tvb_get_guint8(tvb, offset);
	proto_tree_add_uint(tree, hf_ssh_padding_length, tvb, offset, 1, padding_length);
	offset += 1;

	key_ex_tree=proto_tree_add_subtree(tree, tvb, offset, -1, ett_key_exchange, NULL, "Key Exchange");

	/* msg_code */
	msg_code = tvb_get_guint8(tvb, offset);

	if (msg_code >= 30 && msg_code < 40) {
		offset = global_data->kex_specific_dissector(msg_code, tvb, pinfo, offset, key_ex_tree);
	} else {
		proto_tree_add_item(key_ex_tree, hf_ssh2_msg_code, tvb, offset, 1, ENC_NA);
		offset += 1;

		col_append_sep_str(pinfo->cinfo, COL_INFO, NULL,
			val_to_str(msg_code, ssh2_msg_vals, "Unknown (%u)"));

		/* 16 bytes cookie  */
		switch(msg_code)
		{
		case SSH_MSG_KEXINIT:
			if ((peer_data->frame_key_start == 0) || (peer_data->frame_key_start == pinfo->fd->num)) {
				offset = ssh_dissect_key_init(tvb, offset, key_ex_tree, is_response, global_data);
				peer_data->frame_key_start = pinfo->fd->num;
			}
			break;
		case SSH_MSG_NEWKEYS:
			if (peer_data->frame_key_end == 0) {
				peer_data->frame_key_end = pinfo->fd->num;
				ssh_choose_algo(global_data->peer_data[CLIENT_PEER_DATA].enc_proposals[is_response],
								global_data->peer_data[SERVER_PEER_DATA].enc_proposals[is_response],
								&peer_data->enc);

				/* some ciphers have their own MAC so the "negotiated" one is meaningless */
				if(peer_data->enc && (0 == strcmp(peer_data->enc, "*****@*****.**") ||
									  0 == strcmp(peer_data->enc, "*****@*****.**"))) {
					peer_data->mac = wmem_strdup(wmem_file_scope(), (const gchar *)"<implicit>");
					peer_data->mac_length = 16;
					peer_data->length_is_plaintext = 1;
				}
				else if(peer_data->enc && 0 == strcmp(peer_data->enc, "*****@*****.**")) {
					peer_data->mac = wmem_strdup(wmem_file_scope(), (const gchar *)"<implicit>");
					peer_data->mac_length = 16;
				}
				else {
					ssh_choose_algo(global_data->peer_data[CLIENT_PEER_DATA].mac_proposals[is_response],
									global_data->peer_data[SERVER_PEER_DATA].mac_proposals[is_response],
									&peer_data->mac);
					ssh_set_mac_length(peer_data);
				}

				ssh_choose_algo(global_data->peer_data[CLIENT_PEER_DATA].comp_proposals[is_response],
								global_data->peer_data[SERVER_PEER_DATA].comp_proposals[is_response],
								&peer_data->comp);
			}
			break;
		}
	}

	len = plen+4-padding_length-(offset-last_offset);
	if (len > 0) {
		proto_tree_add_item(key_ex_tree, hf_ssh_payload, tvb, offset, len, ENC_NA);
	}
	offset +=len;

	/* padding */
	proto_tree_add_item(key_ex_tree, hf_ssh_padding_string, tvb, offset, padding_length, ENC_NA);
	offset+= padding_length;

	return offset;
}