h225ras_call_t * new_h225ras_call(h225ras_call_info_key *h225ras_call_key, packet_info *pinfo, e_guid_t *guid, int category)
{
	h225ras_call_info_key *new_h225ras_call_key;
 	h225ras_call_t *h225ras_call = NULL;


	/* Prepare the value data.
	   "req_num" and "rsp_num" are frame numbers;
	   frame numbers are 1-origin, so we use 0
	   to mean "we don't yet know in which frame
	   the reply for this call appears". */
	new_h225ras_call_key = se_alloc(sizeof(h225ras_call_info_key));
	new_h225ras_call_key->reqSeqNum = h225ras_call_key->reqSeqNum;
	new_h225ras_call_key->conversation = h225ras_call_key->conversation;
	h225ras_call = se_alloc(sizeof(h225ras_call_t));
	h225ras_call->req_num = pinfo->fd->num;
	h225ras_call->rsp_num = 0;
	h225ras_call->requestSeqNum = h225ras_call_key->reqSeqNum;
	h225ras_call->responded = FALSE;
	h225ras_call->next_call = NULL;
	h225ras_call->req_time=pinfo->fd->abs_ts;
	h225ras_call->guid=*guid;
	/* store it */
	g_hash_table_insert(ras_calls[category], new_h225ras_call_key, h225ras_call);

	return h225ras_call;
}
Beispiel #2
0
static mncp_rhash_value*
mncp_hash_insert(conversation_t *conversation, guint32 nwconnection, guint8 nwtask, packet_info *pinfo)
{
    mncp_rhash_key      *key;
    mncp_rhash_value    *value;

    /* Now remember the request, so we can find it if we later
       a reply to it. Track by conversation, connection, and task number.
       in NetWare these values determine each unique session */
    key = se_alloc(sizeof(mncp_rhash_key));
    key->conversation = conversation;
    key->nwconnection = nwconnection;
    key->nwtask = nwtask;

    value = se_alloc(sizeof(mncp_rhash_value));

    g_hash_table_insert(mncp_rhash, key, value);

    if (ncp_echo_conn && nwconnection != 65535) {
        expert_add_info_format(pinfo, NULL, PI_RESPONSE_CODE, PI_CHAT, "Detected New Server Session. Connection %d, Task %d", nwconnection, nwtask);
        value->session_start_packet_num = pinfo->fd->num;
    }

    return value;
}
Beispiel #3
0
/*
 * Given a circuit type and circuit ID for a packet, create a new circuit
 * to contain packets for that circuit.
 */
circuit_t *
circuit_new(circuit_type ctype, guint32 circuit_id, guint32 first_frame)
{
	circuit_t *circuit, *old_circuit;
	circuit_key *new_key;

	new_key = se_alloc(sizeof(struct circuit_key));
	new_key->ctype = ctype;
	new_key->circuit_id = circuit_id;

	circuit = se_alloc(sizeof(circuit_t));
	circuit->next = NULL;
	circuit->first_frame = first_frame;
	circuit->last_frame = 0;	/* not known yet */
	circuit->index = new_index;
	circuit->data_list = NULL;
	circuit->dissector_handle = NULL;
	circuit->key_ptr = new_key;

	new_index++;

	/*
	 * Is there already a circuit with this circuit ID?
	 */
	old_circuit = g_hash_table_lookup(circuit_hashtable, new_key);
	if (old_circuit != NULL) {
		/*
		 * Yes.  Find the last circuit in the list of circuits
		 * with this circuit ID, and if its last frame isn't
		 * known, make it be the previous frame to this one.
		 */
		while (old_circuit->next != NULL)
			old_circuit = old_circuit->next;
		if (old_circuit->last_frame == 0)
			old_circuit->last_frame = first_frame - 1;

		/*
		 * Now put the new circuit after the last one in the
		 * list.
		 */
		old_circuit->next = circuit;
	} else {
		/*
		 * No.  This is the first one with this circuit ID; add
		 * it to the hash table.
		 */
		g_hash_table_insert(circuit_hashtable, new_key, circuit);
	}

	return circuit;
}
Beispiel #4
0
static gwtb_entry_t* dissect_gwtb_get_data(packet_info* pinfo)
{
	conversation_t *conversation;
	gwtb_entry_t *data_ptr;

	/*
	 * Do we have a conversation for this connection?
	 */
	conversation = find_or_create_conversation(pinfo);

	/*
	 * Do we already have a state structure for this conv
	 */
	data_ptr = (gwtb_entry_t*)conversation_get_proto_data(conversation, proto_gwtb);
	if (!data_ptr) {
		/*
         * No.  Attach that information to the conversation, and add
		 * it to the list of information structures.
		 */
		data_ptr = (gwtb_entry_t*)se_alloc(sizeof(gwtb_entry_t));
		data_ptr->greeting = NULL;
		data_ptr->request_key[0] = NULL;
		data_ptr->request_key[1] = NULL;
		data_ptr->response_key[0] = NULL;
		data_ptr->response_key[1] = NULL;
		data_ptr->request_rc4 = NULL;
		data_ptr->response_rc4 = NULL;

		conversation_add_proto_data(conversation, proto_gwtb, data_ptr);
	}

	return data_ptr;
}
static void reassemble_message(struct rlc_channel *ch, struct rlc_sdu *sdu, struct rlc_frag *frag)
{
	struct rlc_frag *temp;
	guint16 offs = 0;

	if (!sdu || !ch || !sdu->frags) return;

	if (sdu->data) return; /* already assembled */

	if (frag)
		sdu->reassembled_in = frag;
	else
		sdu->reassembled_in = sdu->last;

	sdu->data = se_alloc(sdu->len);

	temp = sdu->frags;
	while (temp && ((offs + temp->len) <= sdu->len)) {
		memcpy(sdu->data + offs, temp->data, temp->len);
		/* mark this fragment in reassembled table */
		g_hash_table_insert(reassembled_table, temp, sdu);

		offs += temp->len;
		temp = temp->next;
	}
	g_hash_table_remove(fragment_table, ch);
}
Beispiel #6
0
/* Find the current conversation or make a new one if required */
static ts2_conversation* ts2_get_conversation(packet_info *pinfo)
{
	conversation_t *conversation;
	ts2_conversation *conversation_data;
	conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
	if(conversation)
	{

		conversation_data = (ts2_conversation*)conversation_get_proto_data(conversation, proto_ts2);
	}
	else
	{
		conversation_data = se_alloc(sizeof(*conversation_data));
		conversation_data->last_inorder_server_frame=0; /* sequence number should never be zero so we can use this as an initial number */
		conversation_data->last_inorder_client_frame=0;
		conversation_data->server_port=pinfo->srcport;
		conversation_data->server_frag_size=0;
		conversation_data->server_frag_num=0;
		conversation_data->client_frag_size=0;
		conversation_data->client_frag_num=0;
		conversation = conversation_new(pinfo->fd->num,  &pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
		conversation_add_proto_data(conversation, proto_ts2, (void *)conversation_data);
	}
	return conversation_data;
}
Beispiel #7
0
static void dissect_gwtb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	gwtb_entry_t *data_ptr = dissect_gwtb_get_data(pinfo);
	gwtb_info_t *info_ptr = (gwtb_info_t*) p_get_proto_data(pinfo->fd, proto_gwtb, 0);

	if (!info_ptr) {
		info_ptr = (gwtb_info_t*) se_alloc(sizeof(gwtb_info_t));
		info_ptr->length = 0;
		info_ptr->auth = FALSE;
		info_ptr->data = NULL;
		p_add_proto_data(pinfo->fd, proto_gwtb, 0, info_ptr);
	}

	if (pinfo->match_port == pinfo->destport || TCP_PORT_GWTB == pinfo->destport) {
		if ((!data_ptr->request_rc4 || info_ptr->auth) && (!info_ptr->data)) {
			tcp_dissect_pdus(tvb, pinfo, tree, TRUE, FRAME_REQUEST_LEN, get_gwtb_request_len, dissect_gwtb_request);
		} else if (!info_ptr->auth) {
			info_ptr->rc4 = data_ptr->request_rc4;
			tcp_dissect_pdus(tvb, pinfo, tree, TRUE, FRAME_HEADER_LEN, get_gwtb_message_len, dissect_gwtb_message);
		}
	} else {
		if ((!data_ptr->response_rc4 || info_ptr->auth) && (!info_ptr->data)) {
			tcp_dissect_pdus(tvb, pinfo, tree, TRUE, FRAME_RESPONSE_LEN, get_gwtb_response_len, dissect_gwtb_response);
		} else if (!info_ptr->auth) {
			info_ptr->rc4 = data_ptr->response_rc4;
			tcp_dissect_pdus(tvb, pinfo, tree, TRUE, FRAME_HEADER_LEN, get_gwtb_message_len, dissect_gwtb_message);
		}
	}
}
static void h245_setup_channels(packet_info *pinfo, channel_info_t *upcoming_channel_lcl)
{
	gint *key;
	GHashTable *rtp_dyn_payload = NULL;
	struct srtp_info *dummy_srtp_info = NULL;

	if (!upcoming_channel_lcl) return;

	/* T.38 */
	if (!strcmp(upcoming_channel_lcl->data_type_str, "t38fax")) {
		if (upcoming_channel_lcl->media_addr.addr.type!=AT_NONE && upcoming_channel_lcl->media_addr.port!=0 && t38_handle) {
			t38_add_address(pinfo, &upcoming_channel_lcl->media_addr.addr,
							upcoming_channel_lcl->media_addr.port, 0,
							"H245", pinfo->fd->num);
		}
		return;
	}

	/* (S)RTP, (S)RTCP */
	if (upcoming_channel_lcl->rfc2198 > 0) {
		encoding_name_and_rate_t *encoding_name_and_rate = se_alloc( sizeof(encoding_name_and_rate_t));
		rtp_dyn_payload = g_hash_table_new(g_int_hash, g_int_equal);
		encoding_name_and_rate->encoding_name = se_strdup("red");
		encoding_name_and_rate->sample_rate = 8000;
		key = se_alloc(sizeof(gint));
		*key = upcoming_channel_lcl->rfc2198;
		g_hash_table_insert(rtp_dyn_payload, key, encoding_name_and_rate);
	}

	if (upcoming_channel_lcl->srtp_flag) {
		dummy_srtp_info = se_alloc0(sizeof(struct srtp_info));
	}

	/* DEBUG 	g_warning("h245_setup_channels media_addr.addr.type %u port %u",upcoming_channel_lcl->media_addr.addr.type, upcoming_channel_lcl->media_addr.port );
	*/
	if (upcoming_channel_lcl->media_addr.addr.type!=AT_NONE && upcoming_channel_lcl->media_addr.port!=0 && rtp_handle) {
		srtp_add_address(pinfo, &upcoming_channel_lcl->media_addr.addr,
						upcoming_channel_lcl->media_addr.port, 0,
						"H245", pinfo->fd->num, upcoming_channel_lcl->is_video , rtp_dyn_payload, dummy_srtp_info);
	}
	if (upcoming_channel_lcl->media_control_addr.addr.type!=AT_NONE && upcoming_channel_lcl->media_control_addr.port!=0 && rtcp_handle) {
		srtcp_add_address(pinfo, &upcoming_channel_lcl->media_control_addr.addr,
						upcoming_channel_lcl->media_control_addr.port, 0,
						"H245", pinfo->fd->num, dummy_srtp_info);
	}
}
Beispiel #9
0
/* Look for conversation info and display any setup info found */
void show_setup_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	/* Conversation and current data */
	conversation_t *p_conv = NULL;
	struct _msrp_conversation_info *p_conv_data = NULL;

	/* Use existing packet data if available */
	p_conv_data = p_get_proto_data(pinfo->fd, proto_msrp);

	if (!p_conv_data)
	{
		/* First time, get info from conversation */
		p_conv = find_conversation(pinfo->fd->num, &pinfo->net_dst, &pinfo->net_src,
		                           PT_TCP,
		                           pinfo->destport, pinfo->srcport, 0);

		if (p_conv)
		{
			/* Look for data in conversation */
			struct _msrp_conversation_info *p_conv_packet_data;
			p_conv_data = conversation_get_proto_data(p_conv, proto_msrp);

			if (p_conv_data)
			{
				/* Save this conversation info into packet info */
				p_conv_packet_data = se_alloc(sizeof(struct _msrp_conversation_info));
				memcpy(p_conv_packet_data, p_conv_data,
				       sizeof(struct _msrp_conversation_info));

				p_add_proto_data(pinfo->fd, proto_msrp, p_conv_packet_data);
			}
		}
	}

	/* Create setup info subtree with summary info. */
	if (p_conv_data && p_conv_data->setup_method_set)
	{
		proto_tree *msrp_setup_tree;
		proto_item *ti =  proto_tree_add_string_format(tree, hf_msrp_setup, tvb, 0, 0,
		                                               "",
		                                               "Stream setup by %s (frame %u)",
		                                               p_conv_data->setup_method,
		                                               p_conv_data->setup_frame_number);
		PROTO_ITEM_SET_GENERATED(ti);
		msrp_setup_tree = proto_item_add_subtree(ti, ett_msrp_setup);
		if (msrp_setup_tree)
		{
			/* Add details into subtree */
			proto_item* item = proto_tree_add_uint(msrp_setup_tree, hf_msrp_setup_frame,
			                                       tvb, 0, 0, p_conv_data->setup_frame_number);
			PROTO_ITEM_SET_GENERATED(item);
			item = proto_tree_add_string(msrp_setup_tree, hf_msrp_setup_method,
			                             tvb, 0, 0, p_conv_data->setup_method);
			PROTO_ITEM_SET_GENERATED(item);
		}
	}
}
Beispiel #10
0
static int
dissect_bmc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    guint8 message_type;
    guint8 *p_rev, *reversing_buffer;
    gint offset = 0;
    gint i, len;
    proto_item *ti;
    proto_tree *bmc_tree;
    tvbuff_t *bit_reversed_tvb;

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

    ti = proto_tree_add_item(tree, proto_bmc, tvb, 0, -1, ENC_NA);
    bmc_tree = proto_item_add_subtree(ti, ett_bmc);

    /* Needs bit-reversing. Create a new buffer, copy the message to it and bit-reverse */
    len = tvb_length(tvb);
    reversing_buffer = se_alloc(len);
    memcpy(reversing_buffer, tvb_get_ptr(tvb, offset, -1), len);
    
    p_rev = reversing_buffer;
    /* Entire message is bit reversed */
    for (i=0; i<len; i++, p_rev++)
        *p_rev = BIT_SWAP(*p_rev);

    /* Make this new buffer part of the display and provide a way to dispose of it */
    bit_reversed_tvb = tvb_new_real_data(reversing_buffer, len, len);
    tvb_set_child_real_data_tvbuff(tvb, bit_reversed_tvb);
    add_new_data_source(pinfo, bit_reversed_tvb, "Bit-reversed Data");

    message_type = tvb_get_guint8(bit_reversed_tvb, offset);
    proto_tree_add_item(bmc_tree, hf_bmc_message_type, bit_reversed_tvb, offset, 1, ENC_BIG_ENDIAN);
    offset++;
    col_add_fstr(pinfo->cinfo, COL_INFO, "%s", val_to_str(message_type, message_type_vals,"Reserved 0x%02x"));

    switch (message_type) {
        case MESSAGE_TYPE_CBS_MESSAGE:
            offset = dissect_bmc_cbs_message(bit_reversed_tvb, pinfo, bmc_tree);
            break;

        case MESSAGE_TYPE_SCHEDULE_MESSAGE:
            offset = dissect_bmc_schedule_message(bit_reversed_tvb, pinfo, bmc_tree);
            break;

        case MESSAGE_TYPE_CBS41_MESSAGE:
            offset = dissect_bmc_cbs41_message(bit_reversed_tvb, pinfo, bmc_tree);
            break;

        default:
            break;
    }
    
    return offset;
}
Beispiel #11
0
static gboolean
dissect_applemidi_heur( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree ) {

	guint16		 command;
	conversation_t	*p_conv;
	/*struct _rtp_conversation_info *p_conv_data = NULL;*/
	encoding_name_and_rate_t *encoding_name_and_rate = NULL;
	GHashTable *rtp_dyn_payload = NULL;
	gint *key;

	if ( tvb_length( tvb ) < 4)
		return FALSE;  /* not enough bytes to check */

	if ( !test_applemidi( tvb, &command, FALSE ) ) {
		return FALSE;
	}

	/* set dynamic payload-type 97 which is used by Apple for their RTP-MIDI implementation for this
	   address/port-tuple to cause RTP-dissector to call the RTP-MIDI-dissector for payload-decoding */

	encoding_name_and_rate = se_alloc( sizeof( encoding_name_and_rate_t ) );
	rtp_dyn_payload = g_hash_table_new( g_int_hash, g_int_equal );
	encoding_name_and_rate->encoding_name = se_strdup( "rtp-midi" );
	encoding_name_and_rate->sample_rate = 10000;
	key = se_alloc( sizeof( gint ) );
	*key = 97;
	g_hash_table_insert( rtp_dyn_payload, key, encoding_name_and_rate );
        rtp_add_address( pinfo, &pinfo->src, pinfo->srcport, 0, APPLEMIDI_DISSECTOR_SHORTNAME,
			 pinfo->fd->num, FALSE, rtp_dyn_payload);

	/* call dissect_applemidi() from now on for UDP packets on this "connection"
	   it is important to do this step after calling rtp_add_address, otherwise
	   all further packets will go directly to the RTP-dissector!                */

	p_conv = find_or_create_conversation(pinfo);
	conversation_set_dissector( p_conv, applemidi_handle );

	/* punt to actual decoding */

	dissect_applemidi_common( tvb, pinfo, tree, command );
	return TRUE;

}
Beispiel #12
0
/*
 * Given two address/port pairs for a packet, create a new conversation
 * to contain packets between those address/port pairs.
 *
 * The options field is used to specify whether the address 2 value
 * and/or port 2 value are not given and any value is acceptable
 * when searching for this conversation.
 */
conversation_t *
conversation_new(const guint32 setup_frame, const address *addr1, const address *addr2, const port_type ptype,
    const guint32 port1, const guint32 port2, const guint options)
{
/*
	DISSECTOR_ASSERT(!(options | CONVERSATION_TEMPLATE) || ((options | (NO_ADDR2 | NO_PORT2 | NO_PORT2_FORCE))) &&
				"A conversation template may not be constructed without wildcard options");
*/
	GHashTable* hashtable;
	conversation_t *conversation=NULL;
	conversation_key *new_key;

	if (options & NO_ADDR2) {
		if (options & (NO_PORT2|NO_PORT2_FORCE)) {
			hashtable = conversation_hashtable_no_addr2_or_port2;
		} else {
			hashtable = conversation_hashtable_no_addr2;
		}
	} else {
		if (options & (NO_PORT2|NO_PORT2_FORCE)) {
			hashtable = conversation_hashtable_no_port2;
		} else {
			hashtable = conversation_hashtable_exact;
		}
	}

	new_key = se_alloc(sizeof(struct conversation_key));
	new_key->next = conversation_keys;
	conversation_keys = new_key;
	SE_COPY_ADDRESS(&new_key->addr1, addr1);
	SE_COPY_ADDRESS(&new_key->addr2, addr2);
	new_key->ptype = ptype;
	new_key->port1 = port1;
	new_key->port2 = port2;

	conversation = se_new(conversation_t); 
	memset(conversation, 0, sizeof(conversation_t));

	conversation->index = new_index;
	conversation->setup_frame = setup_frame;
	conversation->data_list = NULL;

	/* clear dissector handle */
	conversation->dissector_handle = NULL;

	/* set the options and key pointer */
	conversation->options = options;
	conversation->key_ptr = new_key;

	new_index++;

	conversation_insert_into_hashtable(hashtable, conversation);

	return conversation;
}
Beispiel #13
0
static void dissect_gwtb_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	gwtb_entry_t *data_ptr = dissect_gwtb_get_data(pinfo);
	gwtb_info_t *info_ptr = (gwtb_info_t*) p_get_proto_data(pinfo->fd, proto_gwtb, 0);
	proto_item *gwtb_item = NULL;
	proto_tree *gwtb_tree = NULL;	
	guint32 offset = 0;
	guint32 i;

	if (check_col(pinfo->cinfo, COL_PROTOCOL))
		col_set_str(pinfo->cinfo, COL_PROTOCOL, PROTO_TAG_GWTB);

	if (tvb_get_guint8(tvb, 0) == 1 && tvb_get_guint8(tvb, 2) == 1 && tvb_get_guint8(tvb, 15) == 105) {
		if (check_col(pinfo->cinfo, COL_INFO))
			col_set_str(pinfo->cinfo, COL_INFO, "Authentication Request");

		if (tree) { /* we are being asked for details */
			gwtb_item = proto_tree_add_item(tree, proto_gwtb, tvb, 0, -1, FALSE);
			gwtb_tree = proto_item_add_subtree(gwtb_item, ett_gwtb);

			proto_tree_add_item(gwtb_tree, hf_greeting, tvb, offset, 16, FALSE);
			proto_tree_add_item(gwtb_tree, hf_authkey, tvb, offset+16, 16, FALSE);
			proto_tree_add_item(gwtb_tree, hf_authkey, tvb, offset+32, 16, FALSE);
		}

		if (data_ptr && data_ptr->request_rc4 == NULL) {
			data_ptr->greeting = (gwtb_key_t *)tvb_get_ptr(tvb, offset, sizeof(gwtb_key_t));
			offset += sizeof(gwtb_key_t);

			data_ptr->request_key[0] = (gwtb_key_t *)tvb_get_ptr(tvb, offset, sizeof(gwtb_key_t));
			offset += sizeof(gwtb_key_t);

			data_ptr->request_key[1] = (gwtb_key_t *)tvb_get_ptr(tvb, offset, sizeof(gwtb_key_t));
			offset += sizeof(gwtb_key_t);

			for (i = 0; i < sizeof(gwtb_key_t); i++) {
				data_ptr->request_key[1]->chars[i] ^= data_ptr->request_key[0]->chars[i];
			}

			info_ptr->auth = TRUE;
			data_ptr->request_rc4 = (rc4_state_struct*)se_alloc(sizeof(rc4_state_struct));
			crypt_rc4_init(data_ptr->request_rc4, data_ptr->request_key[1]->chars, sizeof(gwtb_key_t));
		}
	} else {
		if (check_col(pinfo->cinfo, COL_INFO))
			col_set_str(pinfo->cinfo, COL_INFO, "Unknown Data Transmission");

		if (tree) { /* we are being asked for details */
			gwtb_item = proto_tree_add_item(tree, proto_gwtb, tvb, 0, -1, FALSE);
			gwtb_tree = proto_item_add_subtree(gwtb_item, ett_gwtb);
		}
	}
}
Beispiel #14
0
void
circuit_add_proto_data(circuit_t *conv, int proto, void *proto_data)
{
	circuit_proto_data *p1 = se_alloc(sizeof(circuit_proto_data));

	p1->proto = proto;
	p1->proto_data = proto_data;

	/* Add it to the list of items for this circuit. */

	conv->data_list = g_slist_insert_sorted(conv->data_list, (gpointer *)p1,
	    p_compare);
}
/*
 * New record to create, to identify a new transaction
 */
static struct camelsrt_call_t *
new_camelsrt_call(struct camelsrt_call_info_key_t *p_camelsrt_call_key)
{
  struct camelsrt_call_info_key_t *p_new_camelsrt_call_key;
  struct camelsrt_call_t *p_new_camelsrt_call = NULL;

  /* Register the transaction in the hash table
     with the tcap transaction Id as main Key
     Once created, this entry will be updated later */

  p_new_camelsrt_call_key = se_alloc(sizeof(struct camelsrt_call_info_key_t));
  p_new_camelsrt_call_key->SessionIdKey = p_camelsrt_call_key->SessionIdKey;
  p_new_camelsrt_call = se_alloc(sizeof(struct camelsrt_call_t));
  raz_camelsrt_call(p_new_camelsrt_call);
  p_new_camelsrt_call->session_id = camelsrt_global_SessionId++;
#ifdef DEBUG_CAMELSRT
  dbg(10,"D%d ", p_new_camelsrt_call->session_id);
#endif
  /* store it */
  g_hash_table_insert(srt_calls, p_new_camelsrt_call_key, p_new_camelsrt_call);
  return p_new_camelsrt_call;
}
void
conversation_add_proto_data(conversation_t *conv, const int proto, void *proto_data)
{
	conv_proto_data *p1 = se_alloc(sizeof(conv_proto_data));

	p1->proto = proto;
	p1->proto_data = proto_data;

	/* Add it to the list of items for this conversation. */

	conv->data_list = g_slist_insert_sorted(conv->data_list, (gpointer *)p1,
	    p_compare);
}
Beispiel #17
0
void
p_add_proto_data(frame_data *fd, int proto, void *proto_data)
{
  frame_proto_data *p1 = se_alloc(sizeof(frame_proto_data));

  p1->proto = proto;
  p1->proto_data = proto_data;

  /* Add it to the GSLIST */

  fd -> pfd = g_slist_insert_sorted(fd -> pfd,
                    (gpointer *)p1,
                    p_compare);
}
Beispiel #18
0
static void dissect_gwtb_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	gwtb_info_t *info_ptr = (gwtb_info_t*) p_get_proto_data(pinfo->fd, proto_gwtb, 0);
	tvbuff_t *next_tvb;
	proto_item *gwtb_item = NULL;
	proto_tree *gwtb_tree = NULL;
	guint32 offset = 0;
	guint32 length = tvb_length(tvb);
	guint16 size;

	if (!info_ptr->data) {
		info_ptr->auth = FALSE;
		info_ptr->data = (guchar*) se_alloc(length);
		tvb_memcpy(tvb, info_ptr->data, offset, length);
		crypt_rc4(info_ptr->rc4, info_ptr->data, length);
	}

	next_tvb = tvb_new_real_data(info_ptr->data, length, length);
	tvb_set_child_real_data_tvbuff(tvb, next_tvb);
	add_new_data_source(pinfo, next_tvb, "Data");
	length = tvb_length(next_tvb);

	if (check_col(pinfo->cinfo, COL_PROTOCOL))
		col_set_str(pinfo->cinfo, COL_PROTOCOL, PROTO_TAG_GWTB);

	if (check_col(pinfo->cinfo, COL_INFO)) {
		col_clear(pinfo->cinfo, COL_INFO);
		col_add_fstr(pinfo->cinfo, COL_INFO, "%d > %d - %s", 
			pinfo->srcport, 
			pinfo->destport, 
				(pinfo->match_port == pinfo->destport || TCP_PORT_GWTB == pinfo->destport) ? "Request" : "Response"
		);
	}

	if (tree) { /* we are being asked for details */
		while(offset < length) {
			gwtb_item = proto_tree_add_item(tree, proto_gwtb, next_tvb, offset, length-offset, FALSE);
			gwtb_tree = proto_item_add_subtree(gwtb_item, ett_gwtb);

			size = tvb_get_ntohs(next_tvb, offset);

			proto_tree_add_item(gwtb_tree, hf_length, next_tvb, offset, FRAME_HEADER_LEN, FALSE);
			offset += FRAME_HEADER_LEN;

			proto_tree_add_item(gwtb_tree, hf_string, next_tvb, offset, size, FALSE);
			offset += size;
		}
	}
}
Beispiel #19
0
static void add_msproxy_conversation( packet_info *pinfo,
                                      hash_entry_t *hash_info) {

    /* check to see if a conversation already exists, if it does assume 	*/
    /* it's our conversation and quit. Otherwise create a new conversation.	*/
    /* Load the conversation dissector to our  dissector and load the	*/
    /* conversation data structure with the info needed to call the TCP or 	*/
    /* UDP port decoder.							*/

    /* NOTE: Currently this assume that the conversation will be created 	*/
    /* 	during a packet from the server.  If that changes, pinfo->src	*/
    /*	and pinfo->dst will not be correct and this routine will have	*/
    /*	to change.							*/

    conversation_t *conversation;
    redirect_entry_t *new_conv_info;

    if (pinfo->fd->flags.visited) {
        /*
         * We've already processed this frame once, so we
         * should already have done this.
         */
        return;
    }

    conversation = find_conversation( pinfo->fd->num, &pinfo->src,
                                      &pinfo->dst, hash_info->proto, hash_info->server_int_port,
                                      hash_info->clnt_port, 0);

    if ( !conversation) {
        conversation = conversation_new( pinfo->fd->num, &pinfo->src, &pinfo->dst,
                                         hash_info->proto, hash_info->server_int_port,
                                         hash_info->clnt_port, 0);
    }
    conversation_set_dissector(conversation, msproxy_sub_handle);

    new_conv_info = se_alloc(sizeof(redirect_entry_t));

    new_conv_info->remote_addr = hash_info->dst_addr;
    new_conv_info->clnt_port = hash_info->clnt_port;
    new_conv_info->remote_port = hash_info->dst_port;
    new_conv_info->server_int_port = hash_info->server_int_port;
    new_conv_info->proto = hash_info->proto;

    conversation_add_proto_data(conversation, proto_msproxy,
                                new_conv_info);
}
static void
add_sid_name_mapping(char *sid, char *name)
{
	sid_name *sn;
	sid_name old_sn;

	old_sn.sid=sid;
	sn=g_hash_table_lookup(sid_name_table, &old_sn);
	if(sn){
		return;
	}

	sn=se_alloc(sizeof(sid_name));
	sn->sid=g_strdup(sid);
	sn->name=g_strdup(name);
	g_hash_table_insert(sid_name_table, sn, sn);
}
Beispiel #21
0
static spx_hash_value*
spx_hash_insert(conversation_t *conversation, guint32 spx_src, guint16 spx_seq)
{
	spx_hash_key		*key;
	spx_hash_value		*value;

	/* Now remember the packet, so we can find it if we later. */
	key = se_alloc(sizeof(spx_hash_key));
	key->conversation = conversation;
	key->spx_src = spx_src;
	key->spx_seq = spx_seq;

	value = se_alloc0(sizeof(spx_hash_value));

	g_hash_table_insert(spx_hash, key, value);

	return value;
}
h225ras_call_t * append_h225ras_call(h225ras_call_t *prev_call, packet_info *pinfo, e_guid_t *guid, int category _U_)
{
	h225ras_call_t *h225ras_call = NULL;

	/* Prepare the value data.
	   "req_num" and "rsp_num" are frame numbers;
	   frame numbers are 1-origin, so we use 0
	   to mean "we don't yet know in which frame
	   the reply for this call appears". */
	h225ras_call = se_alloc(sizeof(h225ras_call_t));
	h225ras_call->req_num = pinfo->fd->num;
	h225ras_call->rsp_num = 0;
	h225ras_call->requestSeqNum = prev_call->requestSeqNum;
	h225ras_call->responded = FALSE;
	h225ras_call->next_call = NULL;
	h225ras_call->req_time=pinfo->fd->abs_ts;
	h225ras_call->guid=*guid;

	prev_call->next_call = h225ras_call;
	return h225ras_call;
}
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 = ep_strdup(attr_id->value);

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

        } else {
            char *se_id = se_strdup(id);

            xmpp_trans = (xmpp_transaction_t *)se_alloc(sizeof (xmpp_transaction_t));
            xmpp_trans->req_frame = pinfo->fd->num;
            xmpp_trans->resp_frame = 0;

            se_tree_insert_string(xmpp_info->req_resp, se_id, (void *) xmpp_trans, EMEM_TREE_STRING_NOCASE);

        }

    } else {
        se_tree_lookup_string(xmpp_info->req_resp, id, EMEM_TREE_STRING_NOCASE);
    }
}
/*
 * Dissect a standard (reliable) ts2 packet, reassembling if required.
 */
static void ts2_standard_dissect(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ts2_tree, ts2_conversation *conversation_data)
{
    guint8 save_fragmented;
    tvbuff_t *new_tvb, *next_tvb;
    fragment_data *frag_msg ;
    guint16 fragment_number;
    ts2_frag *frag;
    gboolean outoforder;

    guint16 type = tvb_get_letohs(tvb, 2);
    /*guint16 class = tvb_get_letohs(tvb, 0);*/
    proto_tree_add_item(ts2_tree, hf_ts2_seqnum, tvb, 12, 4, TRUE);

    /* XXX: Following fragmentation stuff should be separate from the GUI stuff ??    */
    /* Get our stored fragmentation data or create one! */
    if ( ! ( frag = p_get_proto_data(pinfo->fd, proto_ts2) ) ) {
        frag = se_alloc(sizeof(ts2_frag));
        frag->frag_num=0;
    }

    /* decide if the packet is server to client or client to server
     * then check its fragmentation
     */
    if(!(pinfo->fd->flags.visited))
    {
        if(conversation_data->server_port == pinfo->srcport)
        {
            frag->fragmented = ts2_standard_find_fragments(tvb, &conversation_data->last_inorder_server_frame, &conversation_data->server_frag_size, &conversation_data->server_frag_num, &outoforder);
            frag->frag_num=conversation_data->server_frag_num;
            frag->frag_size=conversation_data->server_frag_size;
        }
        else
        {

            frag->fragmented = ts2_standard_find_fragments(tvb, &conversation_data->last_inorder_client_frame, &conversation_data->client_frag_size, &conversation_data->client_frag_num, &outoforder);
            frag->frag_num=conversation_data->client_frag_num;
            frag->frag_size=conversation_data->client_frag_size;
        }
        frag->outoforder=outoforder;
        p_add_proto_data(pinfo->fd, proto_ts2, frag);
    }

    /* Get our stored fragmentation data */
    frag = p_get_proto_data(pinfo->fd, proto_ts2);

    proto_tree_add_item(ts2_tree, hf_ts2_resend_count, tvb, 16, 2, TRUE);
    proto_tree_add_item(ts2_tree, hf_ts2_fragmentnumber, tvb, 18, 2, TRUE);
    ts2_add_checked_crc32(ts2_tree, hf_ts2_crc32, tvb, 20, tvb_get_letohl(tvb, 20));

    /* Reassemble the packet if its fragmented */
    new_tvb = NULL;
    if(frag->fragmented)
    {
        save_fragmented = pinfo->fragmented;
        frag_msg = NULL;
        pinfo->fragmented = TRUE;
        fragment_number = tvb_get_letohs(tvb, 18);
        frag_msg = fragment_add_seq_check(tvb, 24, pinfo, type,	msg_fragment_table, msg_reassembled_table, frag->frag_num, tvb_length_remaining(tvb, 24), fragment_number);
        new_tvb = process_reassembled_data(tvb, 24, pinfo,"Reassembled Message", frag_msg, &msg_frag_items, NULL, ts2_tree);
        if (frag_msg)
        {   /* Reassembled */
            if (check_col(pinfo->cinfo, COL_INFO)) col_append_str(pinfo->cinfo, COL_INFO, " (Message Reassembled)");
        }
        else
        {   /* Not last packet of reassembled Short Message */
            if (check_col(pinfo->cinfo, COL_INFO))col_append_fstr(pinfo->cinfo, COL_INFO," (Message fragment %u)", frag->frag_num);
        }
        if (new_tvb)
            next_tvb = new_tvb;
        else
            next_tvb = tvb_new_subset_remaining(tvb, 24);
        pinfo->fragmented = save_fragmented;
    }
    else
        next_tvb = tvb_new_subset_remaining(tvb, 24);

    /* If we have a full packet now dissect it */
    if((new_tvb || !frag->fragmented) && !frag->outoforder)
    {
        switch(type)
        {
        case TS2T_LOGINPART2:
            ts2_parse_loginpart2(next_tvb, ts2_tree);
            break;
        case TS2T_CHANNELLIST:
            ts2_parse_channellist(next_tvb, ts2_tree);
            break;
        case TS2T_PLAYERLIST:
            ts2_parse_playerlist(next_tvb, ts2_tree);
            break;
        case TS2T_NEWPLAYERJOINED:
            ts2_parse_newplayerjoined(next_tvb, ts2_tree);
            break;
        case TS2T_KNOWNPLAYERUPDATE:
            ts2_parse_knownplayerupdate(next_tvb, ts2_tree);
            break;
        case TS2T_PLAYERLEFT:
            ts2_parse_playerleft(next_tvb, ts2_tree);
            break;
        case TS2T_PLAYERKICKED:
            ts2_parse_playerleft(next_tvb, ts2_tree);
            break;
        case TS2T_LOGINEND:
            ts2_parse_loginend(next_tvb, ts2_tree);
            break;
        case TS2T_CHANGESTATUS:
            ts2_parse_changestatus(next_tvb, ts2_tree);
            break;
        case TS2T_SWITCHCHANNEL:
            ts2_parse_switchchannel(next_tvb, ts2_tree);
            break;
        case TS2T_CHANNELCHANGE:
            ts2_parse_channelchange(next_tvb, ts2_tree);
            break;
        }
    }
    /* The packet is out of order, update the cinfo and ignore the packet */
    if(frag->outoforder)
        if (check_col(pinfo->cinfo, COL_INFO)) col_append_str(pinfo->cinfo, COL_INFO, " (Out Of Order, ignored)");
}
Beispiel #25
0
/* Check to see if this mac & ip pair represent 2 devices trying to share
   the same IP address - report if found (+ return TRUE and set out param) */
static gboolean check_for_duplicate_addresses(packet_info *pinfo, proto_tree *tree,
                                              tvbuff_t *tvb,
                                              const guint8 *mac, guint32 ip,
                                              guint32 *duplicate_ip)
{
  struct   address_hash_value *value;
  gboolean return_value = FALSE;

  /* Look up any existing entries */
  value = g_hash_table_lookup(address_hash_table, GUINT_TO_POINTER(ip));

  /* If MAC matches table, just update details */
  if (value != NULL)
  {
    if (pinfo->fd->num > value->frame_num)
    {
      if ((memcmp(value->mac, mac, 6) == 0))
      {
        /* Same MAC as before - update existing entry */
        value->frame_num = pinfo->fd->num;
        value->time_of_entry = pinfo->fd->abs_ts.secs;
      }
      else
      {
        /* Doesn't match earlier MAC - report! */
        proto_tree *duplicate_tree;

        /* Create subtree */
        proto_item *ti = proto_tree_add_none_format(tree, hf_arp_duplicate_ip_address,
                                                    tvb, 0, 0,
                                                    "Duplicate IP address detected for %s (%s) - also in use by %s (frame %u)",
                                                    arpproaddr_to_str((guint8*)&ip, 4, ETHERTYPE_IP),
                                                    ether_to_str(mac),
                                                    ether_to_str(value->mac),
                                                    value->frame_num);
        PROTO_ITEM_SET_GENERATED(ti);
        duplicate_tree = proto_item_add_subtree(ti, ett_arp_duplicate_address);

        /* Add item for navigating to earlier frame */
        ti = proto_tree_add_uint(duplicate_tree, hf_arp_duplicate_ip_address_earlier_frame,
                                 tvb, 0, 0, value->frame_num);
        PROTO_ITEM_SET_GENERATED(ti);
        expert_add_info_format(pinfo, ti,
                               PI_SEQUENCE, PI_WARN,
                               "Duplicate IP address configured (%s)",
                               arpproaddr_to_str((guint8*)&ip, 4, ETHERTYPE_IP));

        /* Time since that frame was seen */
        ti = proto_tree_add_uint(duplicate_tree,
                                 hf_arp_duplicate_ip_address_seconds_since_earlier_frame,
                                 tvb, 0, 0,
                                 (guint32)(pinfo->fd->abs_ts.secs - value->time_of_entry));
        PROTO_ITEM_SET_GENERATED(ti);

        *duplicate_ip = ip;
        return_value = TRUE;
      }
    }
  }
  else
  {
    /* No existing entry. Prepare one */
    value = se_alloc(sizeof(struct address_hash_value));
    memcpy(value->mac, mac, 6);
    value->frame_num = pinfo->fd->num;
    value->time_of_entry = pinfo->fd->abs_ts.secs;

    /* Add it */
    g_hash_table_insert(address_hash_table, GUINT_TO_POINTER(ip), value);
  }

  return return_value;
}
Beispiel #26
0
gcp_msg_t* gcp_msg(packet_info* pinfo, int o, gboolean keep_persistent_data) {
    gcp_msg_t* m;
    guint32 framenum = (guint32)pinfo->fd->num;
    guint32 offset = (guint32)o;
    address* src = &(pinfo->src);
    address* dst = &(pinfo->dst);
    address* lo_addr;
    address* hi_addr;

    if (keep_persistent_data) {
        emem_tree_key_t key[] = {
            {1,&(framenum)},
            {1,&offset},
            {0,NULL}
        };

        if (( m = se_tree_lookup32_array(msgs,key) )) {
            m->commited = TRUE;
            return m;
        } else {
            m = se_alloc(sizeof(gcp_msg_t));
            m->framenum = framenum;
            m->time = pinfo->fd->abs_ts;
            m->trxs = NULL;
            m->commited = FALSE;

            se_tree_insert32_array(msgs,key,m);
        }
    } else {
        m = ep_new0(gcp_msg_t);
        m->framenum = framenum;
        m->trxs = NULL;
        m->commited = FALSE;
    }

    if (CMP_ADDRESS(src, dst) < 0)  {
        lo_addr = src;
        hi_addr = dst;
    } else {
        lo_addr = dst;
        hi_addr = src;
    }

    switch(lo_addr->type) {
        case AT_NONE:
            m->lo_addr = 0;
            m->hi_addr = 0;
            break;
        case AT_IPv4:
            memcpy((guint8*)&(m->hi_addr),hi_addr->data,4);
            memcpy((guint8*)&(m->lo_addr),lo_addr->data,4);
            break;
        case AT_SS7PC:
            m->hi_addr = mtp3_pc_hash((const mtp3_addr_pc_t *)hi_addr->data);
            m->lo_addr = mtp3_pc_hash((const mtp3_addr_pc_t *)lo_addr->data);
            break;
        default:
            /* XXX: heuristic and error prone */
            m->hi_addr = g_str_hash(ep_address_to_str(hi_addr));
            m->lo_addr = g_str_hash(ep_address_to_str(lo_addr));
        break;
    }

    return m;
}
Beispiel #27
0
gcp_term_t* gcp_cmd_add_term(gcp_msg_t* m, gcp_trx_t* tr, gcp_cmd_t* c, gcp_term_t* t, gcp_wildcard_t wildcard, gboolean persistent) {
    gcp_terms_t* ct;
    gcp_terms_t* ct2;

    static gcp_term_t all_terms = {"$",(guint8*)"",1,GCP_TERM_TYPE_UNKNOWN,NULL,NULL,NULL};

    if ( !c ) return NULL;

    if ( wildcard == GCP_WILDCARD_CHOOSE) {
        return &all_terms;
    }

    if (persistent) {
        if ( c->msg->commited ) {
            if (wildcard == GCP_WILDCARD_ALL) {
                for (ct = c->ctx->terms.next; ct; ct = ct->next) {
                    /* XXX not handling more wilcards in one msg */
                    if ( ct->term->start == m ) {
                        return ct->term;
                    }
                }
                return NULL;
            } else {
                for (ct = c->ctx->terms.next; ct; ct = ct->next) {
                    if ( g_str_equal(ct->term->str,t->str) ) {
                        return ct->term;
                    }
                }
                return NULL;
            }
        } else {

            for (ct = c->ctx->terms.next; ct; ct = ct->next) {
                if ( g_str_equal(ct->term->str,t->str) || ct->term->start == m) {
                    break;
                }
            }

            if ( ! ct ) {

                if (wildcard == GCP_WILDCARD_ALL) {
                    ct = se_alloc(sizeof(gcp_terms_t));
                    ct->next = NULL;
                    ct->term = se_alloc0(sizeof(gcp_term_t));

                    ct->term->start = m;
                    ct->term->str = "*";
                    ct->term->buffer = NULL;
                    ct->term->len = 0;

                    c->terms.last = c->terms.last->next = ct;

                    ct2 = se_alloc0(sizeof(gcp_terms_t));
                    ct2->term = ct->term;

                    c->ctx->terms.last->next = ct2;
                    c->ctx->terms.last = ct2;

                    return ct->term;
                } else {
                    for (ct = c->ctx->terms.next; ct; ct = ct->next) {
                        /* XXX not handling more wilcards in one msg */
                        if ( ct->term->buffer == NULL && tr->cmds->cmd->msg == ct->term->start ) {
                            ct->term->str = se_strdup(t->str);
                            ct->term->buffer = se_memdup(t->buffer,t->len);
                            ct->term->len = t->len;

                            ct2 = se_alloc0(sizeof(gcp_terms_t));
                            ct2->term = ct->term;

                            c->terms.last = c->terms.last->next = ct2;

                            return ct->term;
                        }

                        if  ( g_str_equal(ct->term->str,t->str) ) {
                            ct2 = se_alloc0(sizeof(gcp_terms_t));
                            ct2->term = ct->term;

                            c->terms.last = c->terms.last->next = ct2;

                            return ct->term;
                        }
                    }

                    ct = se_alloc(sizeof(gcp_terms_t));
                    ct->next = NULL;
                    ct->term = se_alloc0(sizeof(gcp_term_t));

                    ct->term->start = m;
                    ct->term->str = se_strdup(t->str);
                    ct->term->buffer = se_memdup(t->buffer,t->len);
                    ct->term->len = t->len;

                    ct2 = se_alloc0(sizeof(gcp_terms_t));
                    ct2->term = ct->term;

                    c->terms.last = c->terms.last->next = ct2;

                    ct2 = se_alloc0(sizeof(gcp_terms_t));
                    ct2->term = ct->term;

                    c->ctx->terms.last = c->ctx->terms.last->next = ct2;

                    return ct->term;
                }
            } else {
                ct2 = se_alloc0(sizeof(gcp_terms_t));
                ct2->term = ct->term;

                c->terms.last = c->terms.last->next = ct2;
                return ct->term;
            }

            DISSECTOR_ASSERT_NOT_REACHED();
            return NULL;
        }
    } else {
        ct = ep_new(gcp_terms_t);
        ct->term = t;
        ct->next = NULL;
        c->terms.last = c->terms.last->next = ct;

        return t;
    }

}
Beispiel #28
0
gcp_cmd_t* gcp_cmd(gcp_msg_t* m, gcp_trx_t* t, gcp_ctx_t* c, gcp_cmd_type_t type, guint offset, gboolean persistent) {
    gcp_cmd_t* cmd;
    gcp_cmd_msg_t* cmdtrx;
    gcp_cmd_msg_t* cmdctx;

    if ( !m || !t || !c ) return NULL;

    if (persistent) {
        if (m->commited) {
            DISSECTOR_ASSERT(t->cmds != NULL);

            for (cmdctx = t->cmds; cmdctx; cmdctx = cmdctx->next) {
                cmd = cmdctx->cmd;
                if (cmd->msg == m && cmd->offset == offset) {
                    return cmd;
                }
            }

            DISSECTOR_ASSERT(!"called for a command that does not exist!");

            return NULL;
        } else {
            cmd = se_alloc(sizeof(gcp_cmd_t));
            cmdtrx = se_alloc(sizeof(gcp_cmd_msg_t));
            cmdctx = se_alloc(sizeof(gcp_cmd_msg_t));
        }
    } else {
        cmd = ep_new(gcp_cmd_t);
        cmdtrx = ep_new(gcp_cmd_msg_t);
        cmdctx = ep_new(gcp_cmd_msg_t);
    }

    cmd->type = type;
    cmd->offset = offset;
    cmd->terms.term = NULL;
    cmd->terms.next = NULL;
    cmd->terms.last = &(cmd->terms);
    cmd->str = NULL;
    cmd->msg = m;
    cmd->trx = t;
    cmd->ctx = c;
    cmd->error = 0;

    cmdctx->cmd = cmdtrx->cmd = cmd;
    cmdctx->next =  cmdtrx->next = NULL;
    cmdctx->last = cmdtrx->last = NULL;

    if (t->cmds) {
        t->cmds->last->next = cmdtrx;
        t->cmds->last = cmdtrx;
    } else {
        t->cmds = cmdtrx;
        t->cmds->last = cmdtrx;
    }

    if (c->cmds) {
        c->cmds->last->next = cmdctx;
        c->cmds->last = cmdctx;
    } else {
        c->cmds = cmdctx;
        c->cmds->last = cmdctx;
    }

    return cmd;
}
Beispiel #29
0
gcp_ctx_t* gcp_ctx(gcp_msg_t* m, gcp_trx_t* t, guint32 c_id, gboolean persistent) {
    gcp_ctx_t* context = NULL;
    gcp_ctx_t** context_p = NULL;

    if ( !m || !t ) return NULL;

    if (persistent) {

        emem_tree_key_t ctx_key[] = {
            {1,&(m->hi_addr)},
            {1,&(m->lo_addr)},
            {1,&(c_id)},
            {0,NULL}
        };

        emem_tree_key_t trx_key[] = {
            {1,&(m->hi_addr)},
            {1,&(m->lo_addr)},
            {1,&(t->id)},
            {0,NULL}
        };

        if (m->commited) {
            if (( context = se_tree_lookup32_array(ctxs_by_trx,trx_key) )) {
                return context;
            } if ((context_p = se_tree_lookup32_array(ctxs,ctx_key))) {
                context = *context_p;

                do {
                    if (context->initial->framenum <= m->framenum) {
                        return context;
                    }
                } while(( context = context->prev ));

                DISSECTOR_ASSERT(! "a context should exist");
            }
        } else {
            if (c_id == CHOOSE_CONTEXT) {
                if (! ( context = se_tree_lookup32_array(ctxs_by_trx,trx_key))) {
                    context = se_alloc(sizeof(gcp_ctx_t));
                    context->initial = m;
                    context->cmds = NULL;
                    context->id = c_id;
                    context->terms.last = &(context->terms);
                    context->terms.next = NULL;
                    context->terms.term = NULL;

                    se_tree_insert32_array(ctxs_by_trx,trx_key,context);
                }
            } else {
                if (( context = se_tree_lookup32_array(ctxs_by_trx,trx_key) )) {
                    if (( context_p = se_tree_lookup32_array(ctxs,ctx_key) )) {
                        if (context != *context_p) {
                            if(context->id != CHOOSE_CONTEXT) {
                                context = se_alloc(sizeof(gcp_ctx_t));
                            }
                            context->initial = m;
                            context->id = c_id;
                            context->cmds = NULL;
                            context->terms.last = &(context->terms);
                            context->terms.next = NULL;
                            context->terms.term = NULL;

                            context->prev = *context_p;
                            *context_p = context;
                        }
                    } else {
                        context_p = se_alloc(sizeof(void*));
                        *context_p = context;
                        context->initial = m;
                        context->id = c_id;
                        se_tree_insert32_array(ctxs,ctx_key,context_p);
                    }
                } else if (! ( context_p = se_tree_lookup32_array(ctxs,ctx_key) )) {
                    context = se_alloc(sizeof(gcp_ctx_t));
                    context->initial = m;
                    context->id = c_id;
                    context->cmds = NULL;
                    context->terms.last = &(context->terms);
                    context->terms.next = NULL;
                    context->terms.term = NULL;

                    context_p = se_alloc(sizeof(void*));
                    *context_p = context;
                    se_tree_insert32_array(ctxs,ctx_key,context_p);
                } else {
                    context = *context_p;
                }
            }
        }
    } else {
        context = ep_new(gcp_ctx_t);
        context->initial = m;
        context->cmds = NULL;
        context->id = c_id;
        context->terms.last = &(context->terms);
        context->terms.next = NULL;
        context->terms.term = NULL;
    }

    return context;
}
Beispiel #30
0
gcp_trx_t* gcp_trx(gcp_msg_t* m ,guint32 t_id , gcp_trx_type_t type, gboolean keep_persistent_data) {
    gcp_trx_t* t = NULL;
    gcp_trx_msg_t* trxmsg;

    if ( !m ) return NULL;

    if (keep_persistent_data) {
        if (m->commited) {

            for ( trxmsg = m->trxs; trxmsg; trxmsg = trxmsg->next) {
                if (trxmsg->trx && trxmsg->trx->id == t_id) {
                    return trxmsg->trx;
                }
            }
            DISSECTOR_ASSERT_NOT_REACHED();
        } else {
            emem_tree_key_t key[] = {
                {1,&(m->hi_addr)},
                {1,&(m->lo_addr)},
                {1,&(t_id)},
                {0,NULL}
            };

            trxmsg = se_alloc(sizeof(gcp_trx_msg_t));
            t = se_tree_lookup32_array(trxs,key);

            if (!t) {
                t = se_alloc(sizeof(gcp_trx_t));
                t->initial = m;
                t->id = t_id;
                t->type = type;
                t->pendings = 0;
                t->error = 0;
                t->cmds = NULL;

                se_tree_insert32_array(trxs,key,t);
            }

            /* XXX: request, reply and ack + point to frames where they are */
            switch ( type ) {
                case GCP_TRX_PENDING:
                    t->pendings++;
                    break;
                default:
                    break;
            }

        }
    } else {
        t = ep_new(gcp_trx_t);
        trxmsg = ep_new(gcp_trx_msg_t);
        t->initial = NULL;
        t->id = t_id;
        t->type = type;
        t->pendings = 0;
        t->error = 0;
        t->cmds = NULL;
    }

    DISSECTOR_ASSERT(trxmsg);

    trxmsg->trx = t;
    trxmsg->next = NULL;
    trxmsg->last = trxmsg;

    if (m->trxs) {
        m->trxs->last = m->trxs->last->next = trxmsg;
    } else {
        m->trxs = trxmsg;
    }

    return t;
}