/* this will build libpcap filter text that will only pass the packets related to the stream. There is a chance that two streams could intersect, but not a very good one */ char* build_follow_filter( packet_info *pi ) { char* buf; int len; conversation_t *conv=NULL; if( pi->net_src.type == AT_IPv4 && pi->net_dst.type == AT_IPv4 && pi->ipproto == IP_PROTO_TCP && (conv=find_conversation(pi->fd->num, &pi->src, &pi->dst, pi->ptype, pi->srcport, pi->destport, 0)) != NULL ) { /* TCP over IPv4 */ buf = g_strdup_printf("tcp.stream eq %d", conv->index); len = 4; is_ipv6 = FALSE; } else if( pi->net_src.type == AT_IPv4 && pi->net_dst.type == AT_IPv4 && pi->ipproto == IP_PROTO_UDP ) { /* UDP over IPv4 */ buf = g_strdup_printf( "(ip.addr eq %s and ip.addr eq %s) and (udp.port eq %d and udp.port eq %d)", ip_to_str( pi->net_src.data), ip_to_str( pi->net_dst.data), pi->srcport, pi->destport ); len = 4; is_ipv6 = FALSE; } else if( pi->net_src.type == AT_IPv6 && pi->net_dst.type == AT_IPv6 && pi->ipproto == IP_PROTO_TCP && (conv=find_conversation(pi->fd->num, &pi->src, &pi->dst, pi->ptype, pi->srcport, pi->destport, 0)) != NULL ) { /* TCP over IPv6 */ buf = g_strdup_printf("tcp.stream eq %d", conv->index); len = 16; is_ipv6 = TRUE; } else if( pi->net_src.type == AT_IPv6 && pi->net_dst.type == AT_IPv6 && pi->ipproto == IP_PROTO_UDP ) { /* UDP over IPv6 */ buf = g_strdup_printf( "(ipv6.addr eq %s and ipv6.addr eq %s) and (udp.port eq %d and udp.port eq %d)", ip6_to_str((const struct e_in6_addr *)pi->net_src.data), ip6_to_str((const struct e_in6_addr *)pi->net_dst.data), pi->srcport, pi->destport ); len = 16; is_ipv6 = TRUE; } else { return NULL; } memcpy(ip_address[0], pi->net_src.data, len); memcpy(ip_address[1], pi->net_dst.data, len); port[0] = pi->srcport; port[1] = pi->destport; return buf; }
/* A helper function that calls find_conversation() and, if a conversation is * not found, calls conversation_new(). * The frame number and addresses are taken from pinfo. * No options are used, though we could extend this API to include an options * parameter. */ conversation_t * find_or_create_conversation(packet_info *pinfo) { conversation_t *conv=NULL; DPRINT(("called for frame #%d: %s:%d -> %s:%d (ptype=%d)", pinfo->fd->num, address_to_str(wmem_packet_scope(), &pinfo->src), pinfo->srcport, address_to_str(wmem_packet_scope(), &pinfo->dst), pinfo->destport, pinfo->ptype)); DINDENT(); /* Have we seen this conversation before? */ if((conv = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->srcport, pinfo->destport, 0)) != NULL) { DPRINT(("found previous conversation for frame #%d (last_frame=%d)", pinfo->fd->num, conv->last_frame)); if (pinfo->fd->num > conv->last_frame) { conv->last_frame = pinfo->fd->num; } } else { /* No, this is a new conversation. */ DPRINT(("did not find previous conversation for frame #%d", pinfo->fd->num)); DINDENT(); conv = conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->srcport, pinfo->destport, 0); DENDENT(); } DENDENT(); return conv; }
lbttcp_transport_t * lbttcp_transport_add(const address * source_address, guint16 source_port, guint32 session_id, guint32 frame) { lbttcp_transport_t * entry = NULL; conversation_t * conv = NULL; lbttcp_transport_conv_data_t * conv_data = NULL; conv = find_conversation(frame, source_address, &lbttcp_null_address, PT_TCP, source_port, 0, 0); if (conv == NULL) { conv = conversation_new(frame, source_address, &lbttcp_null_address, PT_TCP, source_port, 0, 0); } conv_data = (lbttcp_transport_conv_data_t *) conversation_get_proto_data(conv, proto_lbttcp); if (conv_data == NULL) { conv_data = wmem_new(wmem_file_scope(), lbttcp_transport_conv_data_t); conv_data->frame_tree = wmem_tree_new(wmem_file_scope()); conv_data->session_tree = wmem_tree_new(wmem_file_scope()); conversation_add_proto_data(conv, proto_lbttcp, (void *) conv_data); } entry = (lbttcp_transport_t *) wmem_tree_lookup32(conv_data->session_tree, session_id); if (entry != NULL) { return (entry); } entry = lbttcp_transport_create(source_address, source_port, session_id); wmem_tree_insert32(conv_data->session_tree, session_id, (void *) entry); wmem_tree_insert32(conv_data->frame_tree, frame, (void *) entry); return (entry); }
/* * Given two address/port pairs for a packet, search for a matching * conversation and, if found and it has a conversation dissector, * call that dissector and return TRUE, otherwise return FALSE. * * This helper uses call_dissector_only which will NOT call the default * "data" dissector if the packet was rejected. * Our caller is responsible to call the data dissector explicitely in case * this function returns FALSE. */ gboolean try_conversation_dissector(const address *addr_a, const address *addr_b, const port_type ptype, const guint32 port_a, const guint32 port_b, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { conversation_t *conversation; conversation = find_conversation(pinfo->fd->num, addr_a, addr_b, ptype, port_a, port_b, 0); if (conversation != NULL) { int ret; if (conversation->dissector_handle == NULL) return FALSE; ret=call_dissector_only(conversation->dissector_handle, tvb, pinfo, tree); if(!ret) { /* this packet was rejected by the dissector * so return FALSE in case our caller wants * to do some cleaning up. */ return FALSE; } return TRUE; } return FALSE; }
void lbttcp_transport_sid_add(const address * source_address, guint16 source_port, guint32 frame, guint32 session_id) { conversation_t * conv = NULL; lbttcp_transport_conv_data_t * conv_data = NULL; lbttcp_transport_t * transport = NULL; conv = find_conversation(frame, source_address, &lbttcp_null_address, PT_TCP, source_port, 0, 0); if (conv == NULL) { conv = conversation_new(frame, source_address, &lbttcp_null_address, PT_TCP, source_port, 0, 0); } conv_data = (lbttcp_transport_conv_data_t *) conversation_get_proto_data(conv, proto_lbttcp); if (conv_data == NULL) { conv_data = wmem_new(wmem_file_scope(), lbttcp_transport_conv_data_t); conv_data->frame_tree = wmem_tree_new(wmem_file_scope()); conv_data->session_tree = wmem_tree_new(wmem_file_scope()); conversation_add_proto_data(conv, proto_lbttcp, (void *) conv_data); } /* Lookup by frame */ transport = (lbttcp_transport_t *) wmem_tree_lookup32_le(conv_data->frame_tree, frame); if (transport != NULL) { if (transport->session_id != session_id) { transport = NULL; } } if (transport == NULL) { transport = lbttcp_transport_create(source_address, source_port, session_id); wmem_tree_insert32(conv_data->session_tree, session_id, (void *) transport); wmem_tree_insert32(conv_data->frame_tree, frame, (void *) transport); } }
gboolean lbttcp_transport_sid_find(const address * source_address, guint16 source_port, guint32 frame, guint32 * session_id) { conversation_t * conv = NULL; lbttcp_transport_conv_data_t * conv_data = NULL; lbttcp_transport_t * transport = NULL; conv = find_conversation(frame, source_address, &lbttcp_null_address, PT_TCP, source_port, 0, 0); if (conv == NULL) { return (FALSE); } conv_data = (lbttcp_transport_conv_data_t *) conversation_get_proto_data(conv, proto_lbttcp); if (conv_data == NULL) { return (FALSE); } if (conv_data->frame_tree == NULL) { return (FALSE); } transport = (lbttcp_transport_t *)wmem_tree_lookup32_le(conv_data->frame_tree, frame); if (transport == NULL) { return (FALSE); } *session_id = transport->session_id; return (TRUE); }
/* 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 = g_mem_chunk_alloc(conv_vals); 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; }
/* returns TRUE if this TCP segment carries a MPA FPDU and FALSE otherwise */ static gboolean is_mpa_fpdu(packet_info *pinfo) { conversation_t *conversation = NULL; mpa_state_t *state = NULL; conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->srcport, pinfo->destport, 0); if (!conversation) { return FALSE; } state = get_mpa_state(conversation); if (!state) { return FALSE; } /* make sure all MPA connection parameters have been set */ if (!state->full_operation) { return FALSE; } if (pinfo->fd->num == state->req_frame_num || pinfo->fd->num == state->rep_frame_num) { return FALSE; } else { return TRUE; } }
static void msproxy_sub_dissector( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { /* Conversation dissector called from TCP or UDP dissector. Decode and */ /* display the msproxy header, the pass the rest of the data to the tcp */ /* or udp port decode routine to handle the payload. */ guint32 *ptr; redirect_entry_t *redirect_info; conversation_t *conversation; proto_tree *msp_tree; proto_item *ti; conversation = find_conversation( pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->srcport, pinfo->destport, 0); DISSECTOR_ASSERT( conversation); /* should always find a conversation */ redirect_info = conversation_get_proto_data(conversation, proto_msproxy); col_set_str(pinfo->cinfo, COL_PROTOCOL, "MS Proxy"); if (check_col(pinfo->cinfo, COL_INFO)) col_set_str(pinfo->cinfo, COL_INFO, (( redirect_info->proto == PT_TCP) ? "TCP stream" : "UDP packets")); if ( tree) { ti = proto_tree_add_item( tree, proto_msproxy, tvb, 0, 0, FALSE ); msp_tree = proto_item_add_subtree(ti, ett_msproxy); proto_tree_add_uint( msp_tree, hf_msproxy_dstport, tvb, 0, 0, redirect_info->remote_port); proto_tree_add_ipv4( msp_tree, hf_msproxy_dstaddr, tvb, 0, 0, redirect_info->remote_addr); } /* set pinfo->{src/dst port} and call the UDP sub-dissector lookup */ if ( pinfo->srcport == redirect_info->clnt_port) ptr = &pinfo->destport; else ptr = &pinfo->srcport; *ptr = redirect_info->remote_port; if ( redirect_info->proto == PT_TCP) decode_tcp_ports( tvb, 0, pinfo, tree, pinfo->srcport, pinfo->destport, NULL); else decode_udp_ports( tvb, 0, pinfo, tree, pinfo->srcport, pinfo->destport, -1); *ptr = redirect_info->server_int_port; }
static lbmtcp_transport_t * lbmtcp_transport_add(const address * address1, guint16 port1, const address * address2, guint16 port2, guint32 frame) { lbmtcp_transport_t * entry; conversation_t * conv = NULL; conv = find_conversation(frame, address1, address2, PT_TCP, port1, port2, 0); if (conv == NULL) { conv = conversation_new(frame, address1, address2, PT_TCP, port1, port2, 0); } entry = (lbmtcp_transport_t *) conversation_get_proto_data(conv, lbmpdm_tcp_protocol_handle); if (entry != NULL) { return (entry); } entry = wmem_new(wmem_file_scope(), lbmtcp_transport_t); copy_address_wmem(wmem_file_scope(), &(entry->addr1), address1); entry->port1 = port1; copy_address_wmem(wmem_file_scope(), &(entry->addr2), address2); entry->port2 = port2; lbmtcp_order_key(entry); entry->channel = lbm_channel_assign(LBM_CHANNEL_TCP); conversation_add_proto_data(conv, lbmpdm_tcp_protocol_handle, (void *) entry); return (entry); }
void PacketList::selectionChanged (const QItemSelection & selected, const QItemSelection & deselected) { QTreeView::selectionChanged(selected, deselected); if (!cap_file_) return; int row = selected.first().top(); cf_select_packet(cap_file_, row); related_packet_delegate_.clear(); if (!cap_file_->edt) return; if (proto_tree_ && cap_file_->edt->tree) { proto_tree_->fillProtocolTree(cap_file_->edt->tree); packet_info *pi = &cap_file_->edt->pi; conversation_t *conv = find_conversation(pi->fd->num, &pi->src, &pi->dst, pi->ptype, pi->srcport, pi->destport, 0); if (conv) { related_packet_delegate_.setConversationSpan(conv->setup_frame, conv->last_frame); } viewport()->update(); } if (byte_view_tab_) { GSList *src_le; struct data_source *source; byte_view_tab_->clear(); for (src_le = cap_file_->edt->pi.data_src; src_le != NULL; src_le = src_le->next) { source = (struct data_source *)src_le->data; byte_view_tab_->addTab(get_data_source_name(source), get_data_source_tvb(source), cap_file_->edt->tree, proto_tree_, (packet_char_enc)cap_file_->current_frame->flags.encoding); } byte_view_tab_->setCurrentIndex(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, proto_udp); 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 = se_strdup(username); flow->command = se_strdup(command); }
static gboolean dissect_msrp_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { gint offset = 0; conversation_t* conversation; if ( check_msrp_header(tvb)){ /* * TODO Set up conversation here */ if (pinfo->fd->flags.visited){ /* Look for existing conversation */ conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->srcport, pinfo->destport, 0); /* Create new one if not found */ if (conversation == NULL){ conversation = conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->srcport, pinfo->destport, 0); /* Set dissector */ conversation_set_dissector(conversation, msrp_handle); } } offset = dissect_msrp(tvb, pinfo, tree); return TRUE; } return FALSE; }
/* Set up an MSRP conversation using the info given */ void msrp_add_address( packet_info *pinfo, address *addr, int port, const gchar *setup_method, guint32 setup_frame_number) { address null_addr; conversation_t* p_conv; struct _msrp_conversation_info *p_conv_data = NULL; /* * If this isn't the first time this packet has been processed, * we've already done this work, so we don't need to do it * again. */ if (pinfo->fd->flags.visited) { return; } SET_ADDRESS(&null_addr, AT_NONE, 0, NULL); /* * Check if the ip address and port combination is not * already registered as a conversation. */ p_conv = find_conversation( pinfo->fd->num, addr, &null_addr, PT_TCP, port, 0, NO_ADDR_B | NO_PORT_B); /* * If not, create a new conversation. */ if (!p_conv) { p_conv = conversation_new( pinfo->fd->num, addr, &null_addr, PT_TCP, (guint32)port, 0, NO_ADDR2 | NO_PORT2); } /* Set dissector */ conversation_set_dissector(p_conv, msrp_handle); /* * Check if the conversation has data associated with it. */ p_conv_data = conversation_get_proto_data(p_conv, proto_msrp); /* * If not, add a new data item. */ if (!p_conv_data) { /* Create conversation data */ p_conv_data = se_alloc0(sizeof(struct _msrp_conversation_info)); conversation_add_proto_data(p_conv, proto_msrp, p_conv_data); } /* * Update the conversation data. */ p_conv_data->setup_method_set = TRUE; g_strlcpy(p_conv_data->setup_method, setup_method, MAX_MSRP_SETUP_METHOD_SIZE); p_conv_data->setup_frame_number = setup_frame_number; }
void qq_sys_msg_write(qq_account* ac,LwqqMsgType m_t,const char* serv_id,const char* msg,PurpleMessageFlags type,time_t t) { //ac->qq->dispatch(vp_func_2p,(CALLBACK_FUNC)sys_msg_write,ac->qq,system_msg_new(m_t,serv_id,ac,msg,type,t)); PurpleConversation* conv = find_conversation(m_t,serv_id,ac); if(conv) purple_conversation_write(conv,NULL,msg,type,t); }
/* 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); } } }
/* Set up an MSRP conversation using the info given */ void msrp_add_address( packet_info *pinfo, address *addr, int port, const gchar *setup_method, guint32 setup_frame_number) { address null_addr; conversation_t* p_conv; struct _msrp_conversation_info *p_conv_data = NULL; /* * If this isn't the first time this packet has been processed, * we've already done this work, so we don't need to do it * again. */ if (pinfo->fd->flags.visited) { return; } clear_address(&null_addr); /* * Check if the ip address and port combination is not * already registered as a conversation. */ p_conv = find_conversation( pinfo->num, addr, &null_addr, ENDPOINT_TCP, port, 0, NO_ADDR_B | NO_PORT_B); /* * If not, create a new conversation. */ if (!p_conv) { p_conv = conversation_new( pinfo->num, addr, &null_addr, ENDPOINT_TCP, (guint32)port, 0, NO_ADDR2 | NO_PORT2); } /* Set dissector */ conversation_set_dissector(p_conv, msrp_handle); /* * Check if the conversation has data associated with it. */ p_conv_data = (struct _msrp_conversation_info *)conversation_get_proto_data(p_conv, proto_msrp); /* * If not, add a new data item. */ if (!p_conv_data) { /* Create conversation data */ p_conv_data = wmem_new0(wmem_file_scope(), struct _msrp_conversation_info); conversation_add_proto_data(p_conv, proto_msrp, p_conv_data); }
/* returns TRUE if this TCP segment carries a MPA REQUEST and FLASE otherwise */ static gboolean is_mpa_req(tvbuff_t *tvb, packet_info *pinfo) { conversation_t *conversation = NULL; mpa_state_t *state = NULL; guint8 mcrres; if (tvb_get_ntoh64(tvb, 0) != MPA_REQ_REP_FRAME || tvb_get_ntoh64(tvb, 8) != MPA_ID_REQ_FRAME) return FALSE; conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->srcport, pinfo->destport, 0); if (!conversation) { conversation = conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->srcport, pinfo->destport, 0); } if (!get_mpa_state(conversation)) { /* associate a MPA connection state to this conversation if * there is no MPA state already associated to this connection */ state = init_mpa_state(); /* anaylize MPA connection parameter and record them */ mcrres = tvb_get_guint8(tvb, 16); state->ini_exp_m_res = mcrres & MPA_MARKER_FLAG; state->crc = mcrres & MPA_CRC_FLAG; state->revision = tvb_get_guint8(tvb, 17); state->req_frame_num = pinfo->fd->num; state->minfo[MPA_INITIATOR].port = pinfo->srcport; state->minfo[MPA_RESPONDER].port = pinfo->destport; conversation_add_proto_data(conversation, proto_iwarp_mpa, state); /* update expert info */ if (mcrres & MPA_RESERVED_FLAG) expert_add_info_format(pinfo, NULL, PI_REQUEST_CODE, PI_WARN, "Res field is NOT set to zero as required by RFC 5044"); if (state->revision != 1) expert_add_info_format(pinfo, NULL, PI_REQUEST_CODE, PI_WARN, "Rev field is NOT set to one as required by RFC 5044"); } return TRUE; }
void qq_sys_msg_write(qq_account* ac, LwqqMsgType m_t, const char* serv_id, const char* msg, PurpleMessageFlags type, time_t t) { // ac->qq->dispatch(vp_func_2p,(CALLBACK_FUNC)sys_msg_write,ac->qq,system_msg_new(m_t,serv_id,ac,msg,type,t)); const char* local_id; PurpleConversation* conv = find_conversation(m_t, serv_id, ac, &local_id); if (conv) { purple_conversation_write(conv, NULL, msg, type, t); const char* signal = (m_t == LWQQ_MS_BUDDY_MSG || m_t == LWQQ_MS_SESS_MSG) ? "received-im-msg" : "recieved-chat-msg"; purple_signal_emit(purple_conversations_get_handle(), signal, ac->account, conv->name, msg, conv, type); } }
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, (port_type)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, (port_type)hash_info->proto, hash_info->server_int_port, hash_info->clnt_port, 0); } conversation_set_dissector(conversation, msproxy_sub_handle); new_conv_info = se_new(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); }
/* A helper function that calls find_conversation() and, if a conversation is * not found, calls conversation_new(). * The frame number and addresses are taken from pinfo. * No options are used, though we could extend this API to include an options * parameter. */ conversation_t * find_or_create_conversation(packet_info *pinfo) { conversation_t *conv=NULL; /* Have we seen this conversation before? */ if((conv = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->srcport, pinfo->destport, 0)) == NULL) { /* No, this is a new conversation. */ conv = conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->srcport, pinfo->destport, 0); } return conv; }
lbttcp_transport_t * lbttcp_transport_find(const address * source_address, guint16 source_port, guint32 session_id, guint32 frame) { lbttcp_transport_t * entry = NULL; conversation_t * conv = NULL; lbttcp_transport_conv_data_t * conv_data = NULL; conv = find_conversation(frame, source_address, &lbttcp_null_address, PT_TCP, source_port, 0, 0); if (conv != NULL) { conv_data = (lbttcp_transport_conv_data_t *) conversation_get_proto_data(conv, proto_lbttcp); if (conv_data != NULL) { entry = (lbttcp_transport_t *) wmem_tree_lookup32(conv_data->session_tree, session_id); } } return (entry); }
void add_conversation (address_t * src_address, address_t * dst_address, guint16 src_port, guint16 dst_port, const gchar * data) { conversation_t *conv = NULL; const gchar *old_data = NULL; if (!src_address || !dst_address) { g_my_critical("NULL ptr in add_conversation"); return; } /* Make sure there is not one such conversation */ if ((old_data = find_conversation (src_address, dst_address, src_port, dst_port))) { if (!strcmp (old_data, data)) g_my_critical ("Conflicting conversations %s:%d-%s:%d in add_conversation", address_to_str (src_address), src_port, address_to_str (dst_address), dst_port); else g_my_debug ("Conversation %s:%d-%s:%d %s already exists in add_conversation", address_to_str (src_address), src_port, address_to_str (dst_address), dst_port, data); return; } g_my_debug ("Adding new conversation %s:%d-%s:%d %s", address_to_str (src_address), src_port, address_to_str (dst_address), dst_port, data); conv = g_malloc (sizeof (conversation_t)); g_assert(conv); address_copy(&conv->src_address, src_address); address_copy(&conv->dst_address, dst_address); conv->src_port = src_port; conv->dst_port = dst_port; conv->data = g_strdup (data); conversations = g_list_prepend (conversations, conv); n_conversations++; } /* add_conversation */
/* When seeing a broadcast talking about an open TCP port on a host, create * a conversation to dissect anything sent/received at that address. Setup * protocol data so the TCP dissection knows what broadcast triggered it. */ static void prepare_ldss_transfer_conv(ldss_broadcast_t *broadcast) { if (!find_conversation(broadcast->num, &broadcast->broadcaster->addr, &broadcast->broadcaster->addr, PT_TCP, broadcast->broadcaster->port, broadcast->broadcaster->port, NO_ADDR2|NO_PORT2)) { conversation_t *transfer_conv; ldss_transfer_info_t *transfer_info; transfer_info = wmem_new0(wmem_file_scope(), ldss_transfer_info_t); transfer_info->broadcast = broadcast; /* Preparation for later push/pull dissection */ transfer_conv = conversation_new (broadcast->num, &broadcast->broadcaster->addr, &broadcast->broadcaster->addr, PT_TCP, broadcast->broadcaster->port, broadcast->broadcaster->port, NO_ADDR2|NO_PORT2); conversation_add_proto_data(transfer_conv, proto_ldss, transfer_info); conversation_set_dissector(transfer_conv, ldss_tcp_handle); } }
/* returns TRUE if this TCP segment carries a MPA REPLY and FALSE otherwise */ static gboolean is_mpa_rep(tvbuff_t *tvb, packet_info *pinfo) { conversation_t *conversation = NULL; mpa_state_t *state = NULL; guint8 mcrres; if (tvb_get_ntoh64(tvb, 0) != MPA_REQ_REP_FRAME || tvb_get_ntoh64(tvb, 8) != MPA_ID_REP_FRAME) { return FALSE; } conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->srcport, pinfo->destport, 0); if (!conversation) { return FALSE; } state = get_mpa_state(conversation); if (!state) { return FALSE; } if (!state->full_operation) { /* update state of this conversation */ mcrres = tvb_get_guint8(tvb, 16); state->res_exp_m_ini = mcrres & MPA_MARKER_FLAG; state->crc = state->crc | (mcrres & MPA_CRC_FLAG); state->rep_frame_num = pinfo->fd->num; /* enter Full Operation Phase only if the Reject bit is not set */ if (!(mcrres & MPA_REJECT_FLAG)) state->full_operation = TRUE; else expert_add_info_format(pinfo, NULL, PI_RESPONSE_CODE, PI_NOTE, "Reject bit set by Responder"); } return TRUE; }
static lbttcp_client_transport_t * lbttcp_client_transport_add(lbttcp_transport_t * transport, const address * receiver_address, guint16 receiver_port, guint32 frame) { lbttcp_client_transport_t * entry; conversation_t * client_conv = NULL; wmem_tree_t * session_tree = NULL; if (transport == NULL) { return (NULL); } entry = lbttcp_client_transport_find(transport, receiver_address, receiver_port, frame); if (entry != NULL) { return (entry); } entry = wmem_new(wmem_file_scope(), lbttcp_client_transport_t); copy_address_wmem(wmem_file_scope(), &(entry->receiver_address), receiver_address); entry->receiver_port = receiver_port; entry->id = transport->next_client_id++; /* See if a conversation for this address/port pair exists. */ client_conv = find_conversation(frame, &(transport->source_address), receiver_address, PT_TCP, transport->source_port, receiver_port, 0); if (client_conv == NULL) { client_conv = conversation_new(frame, &(transport->source_address), receiver_address, PT_TCP, transport->source_port, receiver_port, 0); session_tree = wmem_tree_new(wmem_file_scope()); conversation_add_proto_data(client_conv, proto_lbttcp, (void *) session_tree); } session_tree = (wmem_tree_t *) conversation_get_proto_data(client_conv, proto_lbttcp); if (session_tree == NULL) { session_tree = wmem_tree_new(wmem_file_scope()); conversation_add_proto_data(client_conv, proto_lbttcp, (void *) session_tree); } wmem_tree_insert32(session_tree, transport->session_id, (void *) entry); /* Add this client to the transport. */ wmem_list_append(transport->client_list, (void *) entry); return (entry); }
static lbttcp_client_transport_t * lbttcp_client_transport_find(lbttcp_transport_t * transport, const address * receiver_address, guint16 receiver_port, guint32 frame) { lbttcp_client_transport_t * entry = NULL; conversation_t * client_conv = NULL; if (transport == NULL) { return (NULL); } client_conv = find_conversation(frame, &(transport->source_address), receiver_address, PT_TCP, transport->source_port, receiver_port, 0); if (client_conv != NULL) { wmem_tree_t * session_tree = NULL; session_tree = (wmem_tree_t *) conversation_get_proto_data(client_conv, proto_lbttcp); if (session_tree != NULL) { entry = (lbttcp_client_transport_t *) wmem_tree_lookup32(session_tree, transport->session_id); } } return (entry); }
static gboolean dissect_tuxedo_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { if (tvb_length(tvb) >= 8) { guint32 magic; magic = tvb_get_ntohl(tvb, 0); if (magic == TUXEDO_MAGIC || magic == TUXEDO_SMAGIC) { /* Register this dissector for this conversation */ conversation_t *conversation = NULL; conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->srcport, pinfo->destport, 0); if (conversation == NULL) { conversation = conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->srcport, pinfo->destport, 0); } conversation_set_dissector(conversation, tuxedo_handle); dissect_tuxedo(tvb, pinfo, tree); return TRUE; } } return FALSE; }
/* * Main dissection routine. */ static gboolean dissect_iwarp_mpa(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) { tvbuff_t *next_tvb = NULL; conversation_t *conversation = NULL; mpa_state_t *state = NULL; struct tcpinfo *tcpinfo; guint8 endpoint = 3; guint16 ulpdu_length = 0; if (data == NULL) return FALSE; tcpinfo = (struct tcpinfo *)data; /* FPDU */ if (tvb_length(tvb) >= MPA_SMALLEST_FPDU_LEN && is_mpa_fpdu(pinfo)) { conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->srcport, pinfo->destport, 0); state = get_mpa_state(conversation); if (pinfo->srcport == state->minfo[MPA_INITIATOR].port) { endpoint = MPA_INITIATOR; } else if (pinfo->srcport == state->minfo[MPA_RESPONDER].port) { endpoint = MPA_RESPONDER; } else { REPORT_DISSECTOR_BUG("endpoint cannot be determined"); } /* Markers are used by either the Initiator or the Responder or both. */ if ((state->ini_exp_m_res || state->res_exp_m_ini) && endpoint <= MPA_RESPONDER) { /* find the TCP sequence number of the first FPDU */ if (!state->minfo[endpoint].valid) { state->minfo[endpoint].seq = tcpinfo->seq; state->minfo[endpoint].valid = TRUE; } } /* dissect FPDU */ ulpdu_length = dissect_mpa_fpdu(tvb, pinfo, tree, state, tcpinfo, endpoint); /* an ulpdu_length of 0 should never happen */ if (!ulpdu_length) return FALSE; /* removes Markers if any and prepares new tvbuff for next dissector */ if (endpoint <= MPA_RESPONDER && state->minfo[endpoint].valid && number_of_markers(state, tcpinfo, endpoint) > 0) { next_tvb = tvb_new_subset_length(remove_markers(tvb, pinfo, get_first_marker_offset(state, tcpinfo, endpoint), number_of_markers(state, tcpinfo, endpoint), fpdu_total_length(tcpinfo)), MPA_ULPDU_LENGTH_LEN, ulpdu_length); } else { next_tvb = tvb_new_subset_length(tvb, MPA_ULPDU_LENGTH_LEN, ulpdu_length); } /* call subdissector */ if (ddp_rdmap_handle) { call_dissector(ddp_rdmap_handle, next_tvb, pinfo, tree); } else { REPORT_DISSECTOR_BUG("ddp_handle was null"); } return TRUE; } /* MPA REQUEST or MPA REPLY */ if (tvb_length(tvb) >= MPA_REQ_REP_FRAME_HEADER_LEN) { if (is_mpa_req(tvb, pinfo)) return dissect_mpa_req_rep(tvb, pinfo, tree, MPA_REQUEST_FRAME); else if (is_mpa_rep(tvb, pinfo)) return dissect_mpa_req_rep(tvb, pinfo, tree, MPA_REPLY_FRAME); } return FALSE; }
/* initialize the tap t38_info and the conversation */ static void init_t38_info_conv(packet_info *pinfo) { /* tap info */ t38_info_current++; if (t38_info_current==MAX_T38_MESSAGES_IN_PACKET) { t38_info_current=0; } t38_info = &t38_info_arr[t38_info_current]; t38_info->seq_num = 0; t38_info->type_msg = 0; t38_info->data_value = 0; t38_info->t30ind_value =0; t38_info->setup_frame_number = 0; t38_info->Data_Field_field_type_value = 0; t38_info->desc[0] = '\0'; t38_info->desc_comment[0] = '\0'; t38_info->time_first_t4_data = 0; t38_info->frame_num_first_t4_data = 0; /* p_t38_packet_conv hold the conversation info in each of the packets. p_t38_conv hold the conversation info used to reassemble the HDLC packets, and also the Setup info (e.g SDP) If we already have p_t38_packet_conv in the packet, it means we already reassembled the HDLC packets, so we don't need to use p_t38_conv */ p_t38_packet_conv = NULL; p_t38_conv = NULL; /* Use existing packet info if available */ p_t38_packet_conv = (t38_conv *)p_get_proto_data(wmem_file_scope(), pinfo, proto_t38, 0); /* find the conversation used for Reassemble and Setup Info */ p_conv = find_conversation(pinfo->fd->num, &pinfo->net_dst, &pinfo->net_src, pinfo->ptype, pinfo->destport, pinfo->srcport, NO_ADDR_B | NO_PORT_B); /* create a conv if it doen't exist */ if (!p_conv) { p_conv = conversation_new(pinfo->fd->num, &pinfo->net_src, &pinfo->net_dst, pinfo->ptype, pinfo->srcport, pinfo->destport, NO_ADDR_B | NO_PORT_B); /* Set dissector */ conversation_set_dissector(p_conv, t38_udp_handle); } if (!p_t38_packet_conv) { p_t38_conv = (t38_conv *)conversation_get_proto_data(p_conv, proto_t38); /* create the conversation if it doen't exist */ if (!p_t38_conv) { p_t38_conv = wmem_new(wmem_file_scope(), t38_conv); p_t38_conv->setup_method[0] = '\0'; p_t38_conv->setup_frame_number = 0; p_t38_conv->src_t38_info.reass_ID = 0; p_t38_conv->src_t38_info.reass_start_seqnum = -1; p_t38_conv->src_t38_info.reass_data_type = 0; p_t38_conv->src_t38_info.last_seqnum = -1; p_t38_conv->src_t38_info.packet_lost = 0; p_t38_conv->src_t38_info.burst_lost = 0; p_t38_conv->src_t38_info.time_first_t4_data = 0; p_t38_conv->src_t38_info.additional_hdlc_data_field_counter = 0; p_t38_conv->src_t38_info.seqnum_prev_data_field = -1; p_t38_conv->dst_t38_info.reass_ID = 0; p_t38_conv->dst_t38_info.reass_start_seqnum = -1; p_t38_conv->dst_t38_info.reass_data_type = 0; p_t38_conv->dst_t38_info.last_seqnum = -1; p_t38_conv->dst_t38_info.packet_lost = 0; p_t38_conv->dst_t38_info.burst_lost = 0; p_t38_conv->dst_t38_info.time_first_t4_data = 0; p_t38_conv->dst_t38_info.additional_hdlc_data_field_counter = 0; p_t38_conv->dst_t38_info.seqnum_prev_data_field = -1; conversation_add_proto_data(p_conv, proto_t38, p_t38_conv); } /* copy the t38 conversation info to the packet t38 conversation */ p_t38_packet_conv = wmem_new(wmem_file_scope(), t38_conv); g_strlcpy(p_t38_packet_conv->setup_method, p_t38_conv->setup_method, MAX_T38_SETUP_METHOD_SIZE); p_t38_packet_conv->setup_frame_number = p_t38_conv->setup_frame_number; memcpy(&(p_t38_packet_conv->src_t38_info), &(p_t38_conv->src_t38_info), sizeof(t38_conv_info)); memcpy(&(p_t38_packet_conv->dst_t38_info), &(p_t38_conv->dst_t38_info), sizeof(t38_conv_info)); p_add_proto_data(wmem_file_scope(), pinfo, proto_t38, 0, p_t38_packet_conv); } if (ADDRESSES_EQUAL(&p_conv->key_ptr->addr1, &pinfo->net_src)) { p_t38_conv_info = &(p_t38_conv->src_t38_info); p_t38_packet_conv_info = &(p_t38_packet_conv->src_t38_info); } else { p_t38_conv_info = &(p_t38_conv->dst_t38_info); p_t38_packet_conv_info = &(p_t38_packet_conv->dst_t38_info); } /* update t38_info */ t38_info->setup_frame_number = p_t38_packet_conv->setup_frame_number; }