/* 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; }
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 ipmi_packet_data_t * get_packet_data(packet_info * pinfo) { ipmi_packet_data_t * data; /* get conversation data */ conversation_t * conv = find_or_create_conversation(pinfo); /* get protocol-specific data */ data = (ipmi_packet_data_t *) conversation_get_proto_data(conv, proto_ipmi); if (!data) { /* allocate per-packet data */ data = wmem_new0(wmem_file_scope(), ipmi_packet_data_t); /* allocate request list and frame tree */ data->frame_tree = wmem_tree_new(wmem_file_scope()); data->request_list = wmem_list_new(wmem_file_scope()); /* add protocol data */ conversation_add_proto_data(conv, proto_ipmi, data); } /* check if packet has changed */ if (pinfo->num != data->curr_frame_num) { data->curr_level = 0; data->next_level = 0; } return data; }
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); }
/* 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; }
/* Packet dissection routine called by tcp (& udp) when port 873 detected */ static int dissect_rsync_encap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean desegment _U_) { conversation_t *conversation; struct rsync_conversation_data *conversation_data; struct rsync_frame_data *rsync_frame_data_p; proto_item *ti; proto_tree *rsync_tree; enum rsync_who me; int offset = 0; guint buff_length; col_set_str(pinfo->cinfo, COL_PROTOCOL, "RSYNC"); col_clear(pinfo->cinfo, COL_INFO); me = pinfo->srcport == glb_rsync_tcp_port ? SERVER : CLIENT; conversation = find_or_create_conversation(pinfo); conversation_data = (struct rsync_conversation_data *)conversation_get_proto_data(conversation, hfi_rsync->id); if (conversation_data == NULL) { /* new conversation */ conversation_data = wmem_new(wmem_file_scope(), struct rsync_conversation_data); conversation_data->client_state = RSYNC_INIT; conversation_data->server_state = RSYNC_SERV_INIT; conversation_add_proto_data(conversation, hfi_rsync->id, conversation_data); }
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); }
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); } }
static void new_udp_conversation( socks_hash_entry_t *hash_info, packet_info *pinfo){ conversation_t *conversation = conversation_new( pinfo->fd->num, &pinfo->src, &pinfo->dst, PT_UDP, hash_info->udp_port, hash_info->port, 0); DISSECTOR_ASSERT( conversation); conversation_add_proto_data(conversation, proto_socks, hash_info); conversation_set_dissector(conversation, socks_udp_handle); }
/* 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); }
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 void mark_pmproxy_exchange_complete(packet_info *pinfo) { conversation_t *conversation; pmproxy_conversation_info_t *pmproxy_conversation; conversation = find_or_create_conversation(pinfo); pmproxy_conversation = (pmproxy_conversation_info_t *)conversation_get_proto_data(conversation, proto_pmproxy); if(pmproxy_conversation == NULL) { pmproxy_conversation = wmem_new(wmem_file_scope(), pmproxy_conversation_info_t); } pmproxy_conversation->last_proxy_frame = pinfo->num; conversation_add_proto_data(conversation, proto_pmproxy, pmproxy_conversation); }
/* 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; }
/* 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) { 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); }
static usbip_conv_info_t * usbip_get_usbip_conv(packet_info *pinfo) { conversation_t *conversation; usbip_conv_info_t *usbip_info; conversation = find_or_create_conversation(pinfo); usbip_info = (usbip_conv_info_t *) conversation_get_proto_data(conversation, proto_usbip); if (!usbip_info) { usbip_info = wmem_new(wmem_file_scope(), usbip_conv_info_t); usbip_info->pdus = wmem_tree_new(wmem_file_scope()); conversation_add_proto_data(conversation, proto_usbip, usbip_info); } return usbip_info; }
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); }
static usb_i1d3_conversation_t *usb_i1d3_get_conversation(packet_info *pinfo) { conversation_t *conversation = find_or_create_conversation(pinfo); usb_i1d3_conversation_t* i1d3_conversation = (usb_i1d3_conversation_t *)conversation_get_proto_data( conversation, proto_usb_i1d3); if (!i1d3_conversation) { i1d3_conversation = wmem_new0( wmem_file_scope(), usb_i1d3_conversation_t); i1d3_conversation->request_to_transaction = wmem_map_new( wmem_file_scope(), g_direct_hash, g_direct_equal); i1d3_conversation->response_to_transaction = wmem_map_new( wmem_file_scope(), g_direct_hash, g_direct_equal); conversation_add_proto_data( conversation, proto_usb_i1d3, i1d3_conversation); } return i1d3_conversation; }
struct udp_analysis * get_udp_conversation_data(conversation_t *conv, packet_info *pinfo) { int direction; struct udp_analysis *udpd=NULL; /* Did the caller supply the conversation pointer? */ if (conv == NULL) conv = find_or_create_conversation(pinfo); /* Get the data for this conversation */ udpd=(struct udp_analysis *)conversation_get_proto_data(conv, hfi_udp->id); /* If the conversation was just created or it matched a * conversation with template options, udpd will not * have been initialized. So, initialize * a new udpd structure for the conversation. */ if (!udpd) { udpd = init_udp_conversation_data(); conversation_add_proto_data(conv, hfi_udp->id, udpd); } if (!udpd) { return NULL; } /* check direction and get ua lists */ direction=CMP_ADDRESS(&pinfo->src, &pinfo->dst); /* if the addresses are equal, match the ports instead */ if (direction == 0) { direction= (pinfo->srcport > pinfo->destport) ? 1 : -1; } if (direction >= 0) { udpd->fwd=&(udpd->flow1); udpd->rev=&(udpd->flow2); } else { udpd->fwd=&(udpd->flow2); udpd->rev=&(udpd->flow1); } return udpd; }
/* 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_or_create_conversation(pinfo); 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(pinfo, NULL, &ei_mpa_res_field_not_set0); if (state->revision != 1) expert_add_info(pinfo, NULL, &ei_mpa_rev_field_not_set1); } 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_or_create_conversation(pinfo); conversation_data = (ts2_conversation*)conversation_get_proto_data(conversation, proto_ts2); if (conversation_data == NULL) { conversation_data = wmem_new(wmem_file_scope(), ts2_conversation); 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_add_proto_data(conversation, proto_ts2, (void *)conversation_data); } return conversation_data; }
/* 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; }
/* Set up an T38 conversation */ void t38_add_address(packet_info *pinfo, address *addr, int port, int other_port, const gchar *setup_method, guint32 setup_frame_number) { address null_addr; conversation_t* p_conversation; t38_conv* p_conversation_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) || (t38_udp_handle == NULL)) { 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_conversation = find_conversation( setup_frame_number, addr, &null_addr, PT_UDP, port, other_port, NO_ADDR_B | (!other_port ? NO_PORT_B : 0)); /* * If not, create a new conversation. */ if ( !p_conversation || p_conversation->setup_frame != setup_frame_number) { p_conversation = conversation_new( setup_frame_number, addr, &null_addr, PT_UDP, (guint32)port, (guint32)other_port, NO_ADDR2 | (!other_port ? NO_PORT2 : 0)); } /* Set dissector */ conversation_set_dissector(p_conversation, t38_udp_handle); /* * Check if the conversation has data associated with it. */ p_conversation_data = (t38_conv*)conversation_get_proto_data(p_conversation, proto_t38); /* * If not, add a new data item. */ if ( ! p_conversation_data ) { /* Create conversation data */ p_conversation_data = wmem_new(wmem_file_scope(), t38_conv); conversation_add_proto_data(p_conversation, proto_t38, p_conversation_data); } /* * Update the conversation data. */ g_strlcpy(p_conversation_data->setup_method, setup_method, MAX_T38_SETUP_METHOD_SIZE); p_conversation_data->setup_frame_number = setup_frame_number; p_conversation_data->src_t38_info.reass_ID = 0; p_conversation_data->src_t38_info.reass_start_seqnum = -1; p_conversation_data->src_t38_info.reass_data_type = 0; p_conversation_data->src_t38_info.last_seqnum = -1; p_conversation_data->src_t38_info.packet_lost = 0; p_conversation_data->src_t38_info.burst_lost = 0; p_conversation_data->src_t38_info.time_first_t4_data = 0; p_conversation_data->dst_t38_info.reass_ID = 0; p_conversation_data->dst_t38_info.reass_start_seqnum = -1; p_conversation_data->dst_t38_info.reass_data_type = 0; p_conversation_data->dst_t38_info.last_seqnum = -1; p_conversation_data->dst_t38_info.packet_lost = 0; p_conversation_data->dst_t38_info.burst_lost = 0; p_conversation_data->dst_t38_info.time_first_t4_data = 0; }
static int dissect_skype_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_item *ti; proto_tree *skype_tree = NULL; guint32 offset = 0; guint32 packet_length; guint8 packet_type, packet_unk; conversation_t *conversation = NULL; skype_udp_conv_info_t *skype_udp_info; /* look up the conversation */ conversation = find_or_create_conversation(pinfo); /* if conversation found get the data pointer that you stored */ skype_udp_info = (skype_udp_conv_info_t *)conversation_get_proto_data(conversation, proto_skype); if (!skype_udp_info) { /* new conversation create local data structure */ skype_udp_info = wmem_new(wmem_file_scope(), skype_udp_conv_info_t); skype_udp_info->global_src_ip = 0; skype_udp_info->global_dst_ip = 0; conversation_add_proto_data(conversation, proto_skype, skype_udp_info); } /* at this point the conversation data is ready */ packet_type = tvb_get_guint8(tvb, 2) & SKYPE_SOM_TYPE_MASK; packet_unk = (tvb_get_guint8(tvb, 2) & SKYPE_SOM_UNK_MASK) >> 4; packet_length = tvb_length(tvb); col_set_str(pinfo->cinfo, COL_PROTOCOL, PROTO_SHORT_NAME); col_add_str(pinfo->cinfo, COL_INFO, val_to_str(packet_type, skype_type_vals, "Type 0x%1x")); if (packet_unk) { col_append_fstr(pinfo->cinfo, COL_INFO, " Unk: %1x", packet_unk); } if (tree) { /* Start of message dissection */ ti = proto_tree_add_item(tree, proto_skype, tvb, offset, -1, ENC_NA); skype_tree = proto_item_add_subtree(ti, ett_skype); proto_tree_add_item(skype_tree, hf_skype_som_id, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(skype_tree, hf_skype_som_unk, tvb, offset, 1, ENC_NA); proto_tree_add_item(skype_tree, hf_skype_som_type, tvb, offset, 1, ENC_NA); offset += 1; /* Body dissection */ switch (packet_type) { case SKYPE_TYPE_UNKNOWN_0: proto_tree_add_item(skype_tree, hf_skype_unknown_0_unk1, tvb, offset, -1, ENC_NA); offset = packet_length; break; case SKYPE_TYPE_PAYLOAD: proto_tree_add_item(skype_tree, hf_skype_payload_iv, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; proto_tree_add_item(skype_tree, hf_skype_payload_crc, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; proto_tree_add_item(skype_tree, hf_skype_payload_enc_data, tvb, offset, -1, ENC_NA); offset = packet_length; break; case SKYPE_TYPE_FFR: proto_tree_add_item(skype_tree, hf_skype_ffr_num, tvb, offset, 1, ENC_NA); offset += 1; proto_tree_add_item(skype_tree, hf_skype_ffr_unk1, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; proto_tree_add_item(skype_tree, hf_skype_ffr_iv, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; proto_tree_add_item(skype_tree, hf_skype_ffr_crc, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; proto_tree_add_item(skype_tree, hf_skype_ffr_enc_data, tvb, offset, -1, ENC_NA); offset = packet_length; break; case SKYPE_TYPE_NAT_INFO: proto_tree_add_item(skype_tree, hf_skype_natinfo_srcip, tvb, offset, 4, ENC_BIG_ENDIAN); skype_udp_info->global_src_ip = tvb_get_ipv4(tvb, offset); offset += 4; proto_tree_add_item(skype_tree, hf_skype_natinfo_dstip, tvb, offset, 4, ENC_BIG_ENDIAN); skype_udp_info->global_dst_ip = tvb_get_ipv4(tvb, offset); offset += 4; break; case SKYPE_TYPE_NAT_REPEAT: proto_tree_add_item(skype_tree, hf_skype_natrequest_srcip, tvb, offset, 4, ENC_BIG_ENDIAN); skype_udp_info->global_src_ip = tvb_get_ipv4(tvb, offset); offset += 4; proto_tree_add_item(skype_tree, hf_skype_natrequest_dstip, tvb, offset, 4, ENC_BIG_ENDIAN); skype_udp_info->global_dst_ip = tvb_get_ipv4(tvb, offset); offset += 4; break; case SKYPE_TYPE_AUDIO: proto_tree_add_item(skype_tree, hf_skype_audio_unk1, tvb, offset, -1, ENC_NA); offset = packet_length; break; case SKYPE_TYPE_UNKNOWN_F: proto_tree_add_item(skype_tree, hf_skype_unknown_f_unk1, tvb, offset, -1, ENC_NA); offset = packet_length; break; default: proto_tree_add_item(skype_tree, hf_skype_unknown_packet, tvb, offset, -1, ENC_NA); offset = packet_length; break; } } return offset; }
/* * Dissect ROS PDUs inside a PPDU. */ static int dissect_ros(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void* data) { int offset = 0; int old_offset; proto_item *item; proto_tree *tree; proto_tree *next_tree=NULL; conversation_t *conversation; ros_conv_info_t *ros_info = NULL; asn1_ctx_t asn1_ctx; asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo); /* save parent_tree so subdissectors can create new top nodes */ top_tree=parent_tree; /* do we have application context from the acse dissector? */ if( !data){ if(parent_tree){ proto_tree_add_text(parent_tree, tvb, offset, -1, "Internal error:can't get application context from ACSE dissector."); } return 0; } asn1_ctx.private_data = data; conversation = find_or_create_conversation(pinfo); /* * Do we already have our info */ ros_info = (ros_conv_info_t *)conversation_get_proto_data(conversation, proto_ros); if (ros_info == NULL) { /* No. Attach that information to the conversation. */ ros_info = (ros_conv_info_t *)g_malloc(sizeof(ros_conv_info_t)); ros_info->matched=g_hash_table_new(ros_info_hash_matched, ros_info_equal_matched); ros_info->unmatched=g_hash_table_new(ros_info_hash_unmatched, ros_info_equal_unmatched); conversation_add_proto_data(conversation, proto_ros, ros_info); ros_info->next = ros_info_items; ros_info_items = ros_info; } item = proto_tree_add_item(parent_tree, proto_ros, tvb, 0, -1, ENC_NA); tree = proto_item_add_subtree(item, ett_ros); col_set_str(pinfo->cinfo, COL_PROTOCOL, "ROS"); col_clear(pinfo->cinfo, COL_INFO); while (tvb_reported_length_remaining(tvb, offset) > 0){ old_offset=offset; offset=dissect_ros_ROS(FALSE, tvb, offset, &asn1_ctx , tree, -1); if(offset == old_offset){ item = proto_tree_add_text(tree, tvb, offset, -1,"Unknown ROS PDU"); if(item){ expert_add_info(pinfo, item, &ei_ros_unknown_ros_pdu); next_tree=proto_item_add_subtree(item, ett_ros_unknown); dissect_unknown_ber(pinfo, tvb, offset, next_tree); } break; } } return tvb_length(tvb); }
static void dissect_pop(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { struct pop_proto_data *frame_data_p; gboolean is_request; gboolean is_continuation; proto_tree *pop_tree, *reqresp_tree; proto_item *ti; gint offset = 0; const guchar *line; gint next_offset; int linelen; int tokenlen; const guchar *next_token; fragment_data *frag_msg = NULL; tvbuff_t *next_tvb = NULL; conversation_t *conversation = NULL; struct pop_data_val *data_val = NULL; gint length_remaining; col_set_str(pinfo->cinfo, COL_PROTOCOL, "POP"); /* * Find the end of the first line. * * Note that "tvb_find_line_end()" will return a value that is * not longer than what's in the buffer, so the "tvb_get_ptr()" * call won't throw an exception. */ linelen = tvb_find_line_end(tvb, offset, -1, &next_offset, FALSE); line = tvb_get_ptr(tvb, offset, linelen); if (pinfo->match_port == pinfo->destport) { is_request = TRUE; is_continuation = FALSE; } else { is_request = FALSE; is_continuation = response_is_continuation(line); } frame_data_p = p_get_proto_data(pinfo->fd, proto_pop); if (!frame_data_p) { conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->srcport, pinfo->destport, 0); if (conversation == NULL) { /* No conversation, create one */ conversation = conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->srcport, pinfo->destport, 0); } data_val = conversation_get_proto_data(conversation, proto_pop); if (!data_val) { /* * No - create one and attach it. */ data_val = se_alloc0(sizeof(struct pop_data_val)); conversation_add_proto_data(conversation, proto_pop, data_val); } } if (check_col(pinfo->cinfo, COL_INFO)) { /* * Put the first line from the buffer into the summary * if it's a POP request or reply (but leave out the * line terminator). * Otherwise, just call it a continuation. */ if (is_continuation) { length_remaining = tvb_length_remaining(tvb, offset); col_add_fstr(pinfo->cinfo, COL_INFO, "S: DATA fragment, %d byte%s", length_remaining, plurality (length_remaining, "", "s")); } else col_add_fstr(pinfo->cinfo, COL_INFO, "%s: %s", is_request ? "C" : "S", format_text(line, linelen)); } ti = proto_tree_add_item(tree, proto_pop, tvb, offset, -1, FALSE); pop_tree = proto_item_add_subtree(ti, ett_pop); if (is_continuation) { if (pop_data_desegment) { if (!frame_data_p) { data_val->msg_read_len += tvb_length(tvb); frame_data_p = se_alloc(sizeof(struct pop_proto_data)); frame_data_p->conversation_id = conversation->index; frame_data_p->more_frags = data_val->msg_read_len < data_val->msg_tot_len; p_add_proto_data(pinfo->fd, proto_pop, frame_data_p); } frag_msg = fragment_add_seq_next(tvb, 0, pinfo, frame_data_p->conversation_id, pop_data_segment_table, pop_data_reassembled_table, tvb_length(tvb), frame_data_p->more_frags); next_tvb = process_reassembled_data(tvb, offset, pinfo, "Reassembled DATA", frag_msg, &pop_data_frag_items, NULL, pop_tree); if (next_tvb) { if (imf_handle) call_dissector(imf_handle, next_tvb, pinfo, tree); if (data_val) { /* we have read everything - reset */ data_val->msg_read_len = 0; data_val->msg_tot_len = 0; } pinfo->fragmented = FALSE; } else { pinfo->fragmented = TRUE; } } else { /* * Put the whole packet into the tree as data. */ call_dissector(data_handle,tvb, pinfo, pop_tree); } return; } /* * Put the line into the protocol tree. */ ti = proto_tree_add_string_format(pop_tree, (is_request) ? hf_pop_request : hf_pop_response, tvb, offset, next_offset - offset, "", "%s", tvb_format_text(tvb, offset, next_offset - offset)); reqresp_tree = proto_item_add_subtree(ti, ett_pop_reqresp); /* * Extract the first token, and, if there is a first * token, add it as the request or reply code. */ tokenlen = get_token_len(line, line + linelen, &next_token); if (tokenlen != 0) { proto_tree_add_item(reqresp_tree, (is_request) ? hf_pop_request_command : hf_pop_response_indicator, tvb, offset, tokenlen, FALSE); if (data_val) { if (is_request) { /* see if this is RETR or TOP command */ if (g_ascii_strncasecmp(line, "RETR", 4) == 0 || g_ascii_strncasecmp(line, "TOP", 3) == 0) /* the next response will tell us how many bytes */ data_val->msg_request = TRUE; } else { if (data_val->msg_request) { /* this is a response to a RETR or TOP command */ if (g_ascii_strncasecmp(line, "+OK ", 4) == 0) { /* the message will be sent - work out how many bytes */ data_val->msg_read_len = 0; data_val->msg_tot_len = atoi(line + 4); } data_val->msg_request = FALSE; } } } offset += (gint) (next_token - line); linelen -= (int) (next_token - line); } if (tree) { /* * Add the rest of the first line as request or * reply param/description. */ if (linelen != 0) { proto_tree_add_item(reqresp_tree, (is_request) ? hf_pop_request_parameter : hf_pop_response_description, tvb, offset, linelen, FALSE); } offset = next_offset; /* * Show the rest of the request or response as text, * a line at a time. */ while (tvb_offset_exists(tvb, offset)) { /* * Find the end of the line. */ tvb_find_line_end(tvb, offset, -1, &next_offset, FALSE); /* * Put this line. */ proto_tree_add_string_format(pop_tree, (is_request) ? hf_pop_request_data : hf_pop_response_data, tvb, offset, next_offset - offset, "", "%s", tvb_format_text(tvb, offset, next_offset - offset)); offset = next_offset; } } }
/* main dissector function. wireshark calls it for segments in both * directions. */ static void dissect_ajp13_tcp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint16 mag; /* guint16 len; */ conversation_t *conv = NULL; ajp13_conv_data *cd = NULL; proto_tree *ajp13_tree = NULL; ajp13_frame_data* fd = NULL; /* conversational state really only does us good during the first * in-order traversal */ conv = find_or_create_conversation(pinfo); cd = (ajp13_conv_data*)conversation_get_proto_data(conv, proto_ajp13); if (!cd) { cd = se_new(ajp13_conv_data); cd->content_length = 0; cd->was_get_body_chunk = FALSE; conversation_add_proto_data(conv, proto_ajp13, cd); } /* we use the per segment user data to record the conversational * state for use later on when we're called out of order (see * comments at top of this file) */ fd = (ajp13_frame_data*)p_get_proto_data(pinfo->fd, proto_ajp13); if (!fd) { /*printf("ajp13:dissect_ajp13_common():no frame data, adding");*/ /* since there's no per-packet user data, this must be the first * time we've see the packet, and it must be the first "in order" * pass through the data. */ fd = se_new(ajp13_frame_data); p_add_proto_data(pinfo->fd, proto_ajp13, fd); fd->is_request_body = FALSE; if (cd->content_length) { /* this is screwy, see AJPv13.html. the idea is that if the * request has a body (as determined by the content-length * header), then there's always an immediate follow-up PDU with * no GET_BODY_CHUNK from the container. */ fd->is_request_body = TRUE; } } col_clear(pinfo->cinfo, COL_INFO); mag = tvb_get_ntohs(tvb, 0); /* len = tvb_get_ntohs(tvb, 2); */ col_set_str(pinfo->cinfo, COL_PROTOCOL, "AJP13"); if (mag == 0x1234 && !fd->is_request_body) col_append_fstr(pinfo->cinfo, COL_INFO, "%d:REQ:", conv->index); else if (mag == 0x1234 && fd->is_request_body) col_append_fstr(pinfo->cinfo, COL_INFO, "%d:REQ:Body", conv->index); else if (mag == 0x4142) col_append_fstr(pinfo->cinfo, COL_INFO, "%d:RSP:", conv->index); else col_set_str(pinfo->cinfo, COL_INFO, "AJP13 Error?"); if (tree) { proto_item *ti; ti = proto_tree_add_item(tree, proto_ajp13, tvb, 0, -1, ENC_NA); ajp13_tree = proto_item_add_subtree(ti, ett_ajp13); } if (mag == 0x1234) { if (fd->is_request_body) display_req_body(tvb, ajp13_tree, cd); else display_req_forward(tvb, pinfo, ajp13_tree, cd); } else if (mag == 0x4142) { display_rsp(tvb, pinfo, ajp13_tree, cd); } }
static void dissect_exec(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { /* Set up structures needed to add the protocol subtree and manage it */ proto_item *ti; proto_tree *exec_tree=NULL; /* Variables for extracting and displaying data from the packet */ guchar *field_stringz; /* Temporary storage for each field we extract */ gint length; guint offset = 0; conversation_t *conversation; exec_hash_entry_t *hash_info; conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->srcport, pinfo->destport, 0); if(!conversation){ /* Conversation does not exist yet - create it */ conversation = conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->srcport, pinfo->destport, 0); } /* Retrieve information from conversation * or add it if it isn't there yet */ hash_info = conversation_get_proto_data(conversation, proto_exec); if(!hash_info){ hash_info = se_alloc(sizeof(exec_hash_entry_t)); hash_info->first_packet_number = pinfo->fd->num; hash_info->second_packet_number = 0; hash_info->third_packet_number = 0; hash_info->fourth_packet_number = 0; hash_info->state = WAIT_FOR_STDERR_PORT; /* The first field we'll see */ /* Start with empty username and command strings */ hash_info->username=NULL; hash_info->command=NULL; /* These will be set on the first pass by the first * four packets of the conversation */ hash_info->first_packet_state = NONE; hash_info->second_packet_state = NONE; hash_info->third_packet_state = NONE; hash_info->fourth_packet_state = NONE; conversation_add_proto_data(conversation, proto_exec, hash_info); } /* Store the number of the first three packets of this conversation * as we reach them the first time */ if(!hash_info->second_packet_number && pinfo->fd->num > hash_info->first_packet_number){ /* We're on the second packet of the conversation */ hash_info->second_packet_number = pinfo->fd->num; } else if(hash_info->second_packet_number && !hash_info->third_packet_number && pinfo->fd->num > hash_info->second_packet_number) { /* We're on the third packet of the conversation */ hash_info->third_packet_number = pinfo->fd->num; } else if(hash_info->third_packet_number && !hash_info->fourth_packet_number && pinfo->fd->num > hash_info->third_packet_number) { /* We're on the fourth packet of the conversation */ hash_info->fourth_packet_number = pinfo->fd->num; } /* Save this packet's state so we can retrieve it if this packet * is selected again later. If the packet's state was already stored, * then retrieve it */ if(pinfo->fd->num == hash_info->first_packet_number){ if(hash_info->first_packet_state == NONE){ hash_info->first_packet_state = hash_info->state; } else { hash_info->state = hash_info->first_packet_state; } } if(pinfo->fd->num == hash_info->second_packet_number){ if(hash_info->second_packet_state == NONE){ hash_info->second_packet_state = hash_info->state; } else { hash_info->state = hash_info->second_packet_state; } } if(pinfo->fd->num == hash_info->third_packet_number){ if(hash_info->third_packet_state == NONE){ hash_info->third_packet_state = hash_info->state; } else { hash_info->state = hash_info->third_packet_state; } } if(pinfo->fd->num == hash_info->fourth_packet_number){ if(hash_info->fourth_packet_state == NONE){ hash_info->fourth_packet_state = hash_info->state; } else { hash_info->state = hash_info->fourth_packet_state; } } col_set_str(pinfo->cinfo, COL_PROTOCOL, "EXEC"); if(check_col(pinfo->cinfo, COL_INFO)){ /* First, clear the info column */ col_clear(pinfo->cinfo, COL_INFO); /*username */ if(hash_info->username && preference_info_show_username == TRUE){ col_append_fstr(pinfo->cinfo, COL_INFO, "Username:%s ", hash_info->username); } /* Command */ if(hash_info->command && preference_info_show_command == TRUE){ col_append_fstr(pinfo->cinfo, COL_INFO, "Command:%s ", hash_info->command); } } /* create display subtree for the protocol */ ti = proto_tree_add_item(tree, proto_exec, tvb, 0, -1, FALSE); exec_tree = proto_item_add_subtree(ti, ett_exec); /* If this packet doesn't end with a null terminated string, * then it must be session data only and we can skip looking * for the other fields. */ if(tvb_find_guint8(tvb, tvb_length(tvb)-1, 1, '\0') == -1){ hash_info->state = WAIT_FOR_DATA; } if(hash_info->state == WAIT_FOR_STDERR_PORT && tvb_length_remaining(tvb, offset)){ field_stringz = tvb_get_ephemeral_stringz(tvb, offset, &length); /* Check if this looks like the stderr_port field. * It is optional, so it may only be 1 character long * (the NULL) */ if(length == 1 || (exec_isdigit_string(field_stringz) && length <= EXEC_STDERR_PORT_LEN)){ proto_tree_add_string(exec_tree, hf_exec_stderr_port, tvb, offset, length, (gchar*)field_stringz); /* Next field we need */ hash_info->state = WAIT_FOR_USERNAME; } else { /* Since the data doesn't match this field, it must be data only */ hash_info->state = WAIT_FOR_DATA; } /* Used if the next field is in the same packet */ offset += length; } if(hash_info->state == WAIT_FOR_USERNAME && tvb_length_remaining(tvb, offset)){ field_stringz = tvb_get_ephemeral_stringz(tvb, offset, &length); /* Check if this looks like the username field */ if(length != 1 && length <= EXEC_USERNAME_LEN && exec_isprint_string(field_stringz)){ proto_tree_add_string(exec_tree, hf_exec_username, tvb, offset, length, (gchar*)field_stringz); /* Store the username so we can display it in the * info column of the entire conversation */ if(!hash_info->username){ hash_info->username=se_strdup((gchar*)field_stringz); } /* Next field we need */ hash_info->state = WAIT_FOR_PASSWORD; } else { /* Since the data doesn't match this field, it must be data only */ hash_info->state = WAIT_FOR_DATA; } /* Used if the next field is in the same packet */ offset += length; } if(hash_info->state == WAIT_FOR_PASSWORD && tvb_length_remaining(tvb, offset)){ field_stringz = tvb_get_ephemeral_stringz(tvb, offset, &length); /* Check if this looks like the password field */ if(length != 1 && length <= EXEC_PASSWORD_LEN && exec_isprint_string(field_stringz)){ proto_tree_add_string(exec_tree, hf_exec_password, tvb, offset, length, (gchar*)field_stringz); /* Next field we need */ hash_info->state = WAIT_FOR_COMMAND; } else { /* Since the data doesn't match this field, it must be data only */ hash_info->state = WAIT_FOR_DATA; } /* Used if the next field is in the same packet */ offset += length; /* Next field we are looking for */ hash_info->state = WAIT_FOR_COMMAND; } if(hash_info->state == WAIT_FOR_COMMAND && tvb_length_remaining(tvb, offset)){ field_stringz = tvb_get_ephemeral_stringz(tvb, offset, &length); /* Check if this looks like the command field */ if(length != 1 && length <= EXEC_COMMAND_LEN && exec_isprint_string(field_stringz)){ proto_tree_add_string(exec_tree, hf_exec_command, tvb, offset, length, (gchar*)field_stringz); /* Store the username so we can display it in the * info column of the entire conversation */ if(!hash_info->command){ hash_info->command=se_strdup((gchar*)field_stringz); } } else { /* Since the data doesn't match this field, it must be data only */ hash_info->state = WAIT_FOR_DATA; } } if(hash_info->state == WAIT_FOR_DATA && tvb_length_remaining(tvb, offset)){ if(pinfo->destport == EXEC_PORT){ /* Packet going to the server */ /* offset = 0 since the whole packet is data */ proto_tree_add_text(exec_tree, tvb, 0, -1, "Client -> Server Data"); if(check_col(pinfo->cinfo, COL_INFO)) col_append_str(pinfo->cinfo, COL_INFO, "Client -> Server data"); } else { /* This packet must be going back to the client */ /* offset = 0 since the whole packet is data */ proto_tree_add_text(exec_tree, tvb, 0, -1, "Server -> Client Data"); if(check_col(pinfo->cinfo, COL_INFO)) col_append_str(pinfo->cinfo, COL_INFO, "Server -> Client Data"); } } /* We haven't seen all of the fields yet */ if(hash_info->state < WAIT_FOR_DATA){ col_set_str(pinfo->cinfo, COL_INFO, "Session Establishment"); } }
/**************************************************************** * Main dissection function ****************************************************************/ static int dissect_rlogin(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data) { struct tcpinfo *tcpinfo = (struct tcpinfo *)data; conversation_t *conversation; rlogin_hash_entry_t *hash_info; guint length; gint ti_offset; /* Get or create conversation */ conversation = find_or_create_conversation(pinfo); /* Get or create data associated with this conversation */ hash_info = (rlogin_hash_entry_t *)conversation_get_proto_data(conversation, proto_rlogin); if (!hash_info) { /* Populate new data struct... */ hash_info = wmem_new(wmem_file_scope(), rlogin_hash_entry_t); hash_info->state = NONE; hash_info->info_framenum = 0; /* no frame has the number 0 */ hash_info->user_name[0] = '\0'; /* ... and store in conversation */ conversation_add_proto_data(conversation, proto_rlogin, hash_info); } /* Set protocol column text */ col_set_str(pinfo->cinfo, COL_PROTOCOL, "Rlogin"); /* Set info column */ /* Show user-name if available */ if (hash_info->user_name[0]) { col_add_fstr(pinfo->cinfo, COL_INFO, "User name: %s, ", hash_info->user_name); } else { col_clear(pinfo->cinfo, COL_INFO); } /* Work out packet content summary for display */ length = tvb_reported_length(tvb); if (length != 0) { /* Initial NULL byte represents part of connection handshake */ if (tvb_get_guint8(tvb, 0) == '\0') { col_append_str(pinfo->cinfo, COL_INFO, (pinfo->destport == RLOGIN_PORT) ? "Start Handshake" : "Startup info received"); } else if (tcpinfo && IS_TH_URG(tcpinfo->flags) && length >= tcpinfo->urgent_pointer) { /* Urgent pointer inside current data represents a control message */ col_append_str(pinfo->cinfo, COL_INFO, "Control Message"); } else { /* Search for 2 consecutive ff bytes (signifies window change control message) */ ti_offset = tvb_find_guint8(tvb, 0, -1, 0xff); if (ti_offset != -1 && tvb_bytes_exist(tvb, ti_offset + 1, 1) && tvb_get_guint8(tvb, ti_offset + 1) == 0xff) { col_append_str(pinfo->cinfo, COL_INFO, "Terminal Info"); } else { /* Show any text data in the frame */ int bytes_to_copy = tvb_captured_length(tvb); if (bytes_to_copy > 128) { /* Truncate to 128 bytes for display */ bytes_to_copy = 128; } /* Add data into info column */ col_append_fstr(pinfo->cinfo, COL_INFO, "Data: %s", tvb_format_text(tvb, 0, bytes_to_copy)); } } } /* See if conversation state needs to be updated */ rlogin_state_machine(hash_info, tvb, pinfo); /* Dissect in detail */ rlogin_display(hash_info, tvb, pinfo, tree, tcpinfo); return tvb_captured_length(tvb); }
/* * Function for the PANA PDU dissector. */ static void dissect_pana_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *pana_tree = NULL; guint16 flags; guint16 msg_type; guint32 msg_length; guint32 avp_length; guint32 seq_num; conversation_t *conversation; pana_conv_info_t *pana_info; pana_transaction_t *pana_trans; int offset = 0; col_set_str(pinfo->cinfo, COL_PROTOCOL, "PANA"); col_clear(pinfo->cinfo, COL_INFO); /* Get message length, type and flags */ msg_length = tvb_get_ntohs(tvb, 2); flags = tvb_get_ntohs(tvb, 4); msg_type = tvb_get_ntohs(tvb, 6); seq_num = tvb_get_ntohl(tvb, 12); avp_length = msg_length - 16; col_add_fstr(pinfo->cinfo, COL_INFO, "Type %s-%s", val_to_str(msg_type, msg_type_names, "Unknown (%d)"), val_to_str(flags & PANA_FLAG_R, msg_subtype_names, "Unknown (%d)")); /* Make the protocol tree */ if (tree) { proto_item *ti; ti = proto_tree_add_item(tree, proto_pana, tvb, 0, -1, ENC_NA); pana_tree = proto_item_add_subtree(ti, ett_pana); } /* * We need to track some state for this protocol on a per conversation * basis so we can do neat things like request/response tracking */ conversation = find_or_create_conversation(pinfo); /* * Do we already have a state structure for this conv */ pana_info = (pana_conv_info_t *)conversation_get_proto_data(conversation, proto_pana); if (!pana_info) { /* No. Attach that information to the conversation, and add * it to the list of information structures. */ pana_info = wmem_new(wmem_file_scope(), pana_conv_info_t); pana_info->pdus=wmem_map_new(wmem_file_scope(), g_direct_hash, g_direct_equal); conversation_add_proto_data(conversation, proto_pana, pana_info); } if(!pinfo->fd->flags.visited){ if(flags&PANA_FLAG_R){ /* This is a request */ pana_trans=wmem_new(wmem_file_scope(), pana_transaction_t); pana_trans->req_frame=pinfo->num; pana_trans->rep_frame=0; pana_trans->req_time=pinfo->abs_ts; wmem_map_insert(pana_info->pdus, GUINT_TO_POINTER(seq_num), (void *)pana_trans); } else { pana_trans=(pana_transaction_t *)wmem_map_lookup(pana_info->pdus, GUINT_TO_POINTER(seq_num)); if(pana_trans){ pana_trans->rep_frame=pinfo->num; } } } else { pana_trans=(pana_transaction_t *)wmem_map_lookup(pana_info->pdus, GUINT_TO_POINTER(seq_num)); } if(!pana_trans){ /* create a "fake" pana_trans structure */ pana_trans=wmem_new(wmem_packet_scope(), pana_transaction_t); pana_trans->req_frame=0; pana_trans->rep_frame=0; pana_trans->req_time=pinfo->abs_ts; } /* print state tracking in the tree */ if(flags&PANA_FLAG_R){ /* This is a request */ if(pana_trans->rep_frame){ proto_item *it; it=proto_tree_add_uint(pana_tree, hf_pana_response_in, tvb, 0, 0, pana_trans->rep_frame); PROTO_ITEM_SET_GENERATED(it); } } else { /* This is a reply */ if(pana_trans->req_frame){ proto_item *it; nstime_t ns; it=proto_tree_add_uint(pana_tree, hf_pana_response_to, tvb, 0, 0, pana_trans->req_frame); PROTO_ITEM_SET_GENERATED(it); nstime_delta(&ns, &pinfo->abs_ts, &pana_trans->req_time); it=proto_tree_add_time(pana_tree, hf_pana_response_time, tvb, 0, 0, &ns); PROTO_ITEM_SET_GENERATED(it); } } /* Reserved field */ proto_tree_add_item(pana_tree, hf_pana_reserved_type, tvb, offset, 2, ENC_NA); offset += 2; /* Length */ proto_tree_add_item(pana_tree, hf_pana_length_type, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; /* Flags */ dissect_pana_flags(pana_tree, tvb, offset, flags); offset += 2; /* Message Type */ proto_tree_add_uint_format_value(pana_tree, hf_pana_msg_type, tvb, offset, 2, msg_type, "%s-%s (%d)", val_to_str(msg_type, msg_type_names, "Unknown (%d)"), val_to_str(flags & PANA_FLAG_R, msg_subtype_names, "Unknown (%d)"), msg_type); offset += 2; /* Session ID */ proto_tree_add_item(pana_tree, hf_pana_session_id, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; /* Sequence Number */ proto_tree_add_item(pana_tree, hf_pana_seqnumber, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; /* AVPs */ if(avp_length != 0){ tvbuff_t *avp_tvb; proto_tree *avp_tree; avp_tvb = tvb_new_subset_length(tvb, offset, avp_length); avp_tree = proto_tree_add_subtree(pana_tree, tvb, offset, avp_length, ett_pana_avp, NULL, "Attribute Value Pairs"); dissect_avps(avp_tvb, pinfo, avp_tree); } }
static void dissect_xmpp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { xml_frame_t *xml_frame; gboolean out_packet; conversation_t *conversation; xmpp_conv_info_t *xmpp_info; proto_tree *xmpp_tree = NULL; proto_item *xmpp_item = NULL; xmpp_element_t *packet = NULL; /*check if desegment * now it checks that last char is '>', * TODO checks that first element in packet is closed*/ int indx; gchar last_char; if (xmpp_desegment) { indx = tvb_reported_length(tvb) - 1; if (indx >= 0) { last_char = tvb_get_guint8(tvb, indx); while ((last_char <= ' ') && (indx - 1 >= 0)) { indx--; last_char = tvb_get_guint8(tvb, indx); } if ((indx >= 0) && (last_char != '>')) { pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT; return; } } } col_set_str(pinfo->cinfo, COL_PROTOCOL, "XMPP"); col_clear(pinfo->cinfo, COL_INFO); conversation = find_or_create_conversation(pinfo); xmpp_info = (xmpp_conv_info_t *)conversation_get_proto_data(conversation, proto_xmpp); if (xmpp_info && xmpp_info->ssl_proceed && xmpp_info->ssl_proceed < pinfo->fd->num) { call_dissector(ssl_handle, tvb, pinfo, tree); return; } /*if tree == NULL then xmpp_item and xmpp_tree will also NULL*/ xmpp_item = proto_tree_add_item(tree, proto_xmpp, tvb, 0, -1, ENC_NA); xmpp_tree = proto_item_add_subtree(xmpp_item, ett_xmpp); call_dissector(xml_handle, tvb, pinfo, xmpp_tree); /* If XML dissector is disabled, we can't do much */ if (!proto_is_protocol_enabled(find_protocol_by_id(dissector_handle_get_protocol_index(xml_handle)))) { col_append_str(pinfo->cinfo, COL_INFO, "(XML dissector disabled, can't dissect XMPP)"); expert_add_info_format(pinfo, xmpp_item, PI_UNDECODED, PI_WARN, "XML dissector disabled, can't dissect XMPP"); return; } /*if stream end occurs then return*/ if(xmpp_stream_close(xmpp_tree,tvb, pinfo)) { if(xmpp_tree) xmpp_proto_tree_hide_first_child(xmpp_tree); return; } if(!pinfo->private_data) return; /*data from XML dissector*/ xml_frame = ((xml_frame_t*)pinfo->private_data)->first_child; if(!xml_frame) return; if (!xmpp_info) { xmpp_info = se_new(xmpp_conv_info_t); xmpp_info->req_resp = se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "xmpp_req_resp"); xmpp_info->jingle_sessions = se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "xmpp_jingle_sessions"); xmpp_info->ibb_sessions = se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "xmpp_ibb_sessions"); xmpp_info->gtalk_sessions = se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "xmpp_gtalk_sessions"); xmpp_info->ssl_start = 0; xmpp_info->ssl_proceed = 0; conversation_add_proto_data(conversation, proto_xmpp, (void *) xmpp_info); } if (pinfo->match_uint == pinfo->destport) out_packet = TRUE; else out_packet = FALSE; while(xml_frame) { packet = xmpp_xml_frame_to_element_t(xml_frame, NULL, tvb); DISSECTOR_ASSERT(packet); if (strcmp(packet->name, "iq") == 0) { xmpp_iq_reqresp_track(pinfo, packet, xmpp_info); xmpp_jingle_session_track(pinfo, packet, xmpp_info); xmpp_gtalk_session_track(pinfo, packet, xmpp_info); } if (strcmp(packet->name, "iq") == 0 || strcmp(packet->name, "message") == 0) { xmpp_ibb_session_track(pinfo, packet, xmpp_info); } if (tree) { /* we are being asked for details */ proto_item *outin_item; if (out_packet) outin_item = proto_tree_add_boolean(xmpp_tree, hf_xmpp_out, tvb, 0, 0, TRUE); else outin_item = proto_tree_add_boolean(xmpp_tree, hf_xmpp_in, tvb, 0, 0, TRUE); PROTO_ITEM_SET_HIDDEN(outin_item); /*it hides tree generated by XML dissector*/ xmpp_proto_tree_hide_first_child(xmpp_tree); if (strcmp(packet->name, "iq") == 0) { xmpp_iq(xmpp_tree, tvb, pinfo, packet); } else if (strcmp(packet->name, "presence") == 0) { xmpp_presence(xmpp_tree, tvb, pinfo, packet); } else if (strcmp(packet->name, "message") == 0) { xmpp_message(xmpp_tree, tvb, pinfo, packet); } else if (strcmp(packet->name, "auth") == 0) { xmpp_auth(xmpp_tree, tvb, pinfo, packet); } else if (strcmp(packet->name, "challenge") == 0) { xmpp_challenge_response_success(xmpp_tree, tvb, pinfo, packet, hf_xmpp_challenge, ett_xmpp_challenge, "CHALLENGE"); } else if (strcmp(packet->name, "response") == 0) { xmpp_challenge_response_success(xmpp_tree, tvb, pinfo, packet, hf_xmpp_response, ett_xmpp_response, "RESPONSE"); } else if (strcmp(packet->name, "success") == 0) { xmpp_challenge_response_success(xmpp_tree, tvb, pinfo, packet, hf_xmpp_success, ett_xmpp_success, "SUCCESS"); } else if (strcmp(packet->name, "failure") == 0) { xmpp_failure(xmpp_tree, tvb, pinfo, packet); } else if (strcmp(packet->name, "xml") == 0) { xmpp_xml_header(xmpp_tree, tvb, pinfo, packet); } else if (strcmp(packet->name, "stream") == 0) { xmpp_stream(xmpp_tree, tvb, pinfo, packet); } else if (strcmp(packet->name, "features") == 0) { xmpp_features(xmpp_tree, tvb, pinfo, packet); } else if (strcmp(packet->name, "starttls") == 0) { xmpp_starttls(xmpp_tree, tvb, pinfo, packet, xmpp_info); }else if (strcmp(packet->name, "proceed") == 0) { xmpp_proceed(xmpp_tree, tvb, pinfo, packet, xmpp_info); }else { xmpp_proto_tree_show_first_child(xmpp_tree); expert_add_info_format(pinfo, xmpp_tree, PI_UNDECODED, PI_NOTE, "Unknown packet: %s", packet->name); col_clear(pinfo->cinfo, COL_INFO); col_append_fstr(pinfo->cinfo, COL_INFO, "UNKNOWN PACKET "); } /*appends to COL_INFO information about src or dst*/ if (pinfo->match_uint == pinfo->destport) { xmpp_attr_t *to = xmpp_get_attr(packet, "to"); if (to) col_append_fstr(pinfo->cinfo, COL_INFO, "> %s ", to->value); } else { xmpp_attr_t *from = xmpp_get_attr(packet, "from"); if (from) col_append_fstr(pinfo->cinfo, COL_INFO, "< %s ", from->value); } } xmpp_element_t_tree_free(packet); xml_frame = xml_frame->next_sibling; } }