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; }
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; }
/* * 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; }
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); }
/* 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; }
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); } }
/* 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); } } }
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; }
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; }
/* * 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; }
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); } } }
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); }
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); }
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; } } }
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); }
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)"); }
/* 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; }
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; }
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; } }
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; }
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; }
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; }