示例#1
0
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;
}
示例#2
0
/* 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;
}
示例#3
0
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);
}
示例#4
0
/* 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);
    }
示例#5
0
/* WSLUA_ATTRIBUTE Pinfo_conversation WO sets the packet conversation to the given Proto object. */
static int Pinfo_set_conversation(lua_State *L) {
    Pinfo pinfo = checkPinfo(L,1);
    Proto proto = checkProto(L,2);
    conversation_t  *conversation;

    if (!proto->handle) {
        luaL_error(L,"Proto %s has no registered dissector", proto->name? proto->name:"<UKNOWN>");
        return 0;
    }

    conversation = find_or_create_conversation(pinfo->ws_pinfo);
    conversation_set_dissector(conversation,proto->handle);

    return 0;
}
示例#6
0
/* 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 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
gboolean dissect_bt_dht_heur (tvbuff_t *tvb, packet_info *pinfo,
                                        proto_tree *tree)
{
  /* try dissecting */
  /* XXX: This is a very weak heuristic; so: heuristic dissection is disabled by default */
  if( tvb_get_guint8(tvb,0)=='d' )
  {
    conversation_t *conversation;

    conversation = find_or_create_conversation(pinfo);
    conversation_set_dissector(conversation, bt_dht_handle);

    dissect_bt_dht(tvb, pinfo, tree);
    return TRUE;
   }
   return FALSE;
}
示例#9
0
static gboolean
dissect_applemidi_heur( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree ) {

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

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

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

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

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

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

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

	/* punt to actual decoding */

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

}
示例#10
0
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;
}
示例#11
0
/* 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;
}
示例#12
0
/* 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;
}
示例#13
0
static void
dissect_ftp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    gboolean        is_request;
    proto_tree     *ftp_tree          = NULL;
    proto_tree     *reqresp_tree      = NULL;
    proto_item     *ti, *hidden_item;
    gint            offset            = 0;
    const guchar   *line;
    guint32         code;
    gchar           code_str[4];
    gboolean        is_port_request   = FALSE;
    gboolean        is_pasv_response  = FALSE;
    gboolean        is_epasv_response = FALSE;
    gint            next_offset;
    int             linelen;
    int             tokenlen;
    const guchar   *next_token;
    guint32         pasv_ip;
    guint32         ftp_ip;
    guint16         ftp_port;
    address         ftp_ip_address;
    gboolean        ftp_nat;
    conversation_t *conversation;

    ftp_ip_address = pinfo->src;

    if (pinfo->match_uint == pinfo->destport)
        is_request = TRUE;
    else
        is_request = FALSE;

    col_set_str(pinfo->cinfo, COL_PROTOCOL, "FTP");

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

    /*
     * Put the first line from the buffer into the summary
     * (but leave out the line terminator).
     */
    col_add_fstr(pinfo->cinfo, COL_INFO, "%s: %s",
        is_request ? "Request" : "Response",
        format_text(line, linelen));

    if (tree) {
        ti = proto_tree_add_item(tree, proto_ftp, tvb, offset, -1, ENC_NA);
        ftp_tree = proto_item_add_subtree(ti, ett_ftp);

        if (is_request) {
            hidden_item = proto_tree_add_boolean(ftp_tree,
                hf_ftp_request, tvb, 0, 0, TRUE);
            PROTO_ITEM_SET_HIDDEN(hidden_item);
            hidden_item = proto_tree_add_boolean(ftp_tree,
                hf_ftp_response, tvb, 0, 0, FALSE);
            PROTO_ITEM_SET_HIDDEN(hidden_item);
        } else {
            hidden_item = proto_tree_add_boolean(ftp_tree,
                hf_ftp_request, tvb, 0, 0, FALSE);
            PROTO_ITEM_SET_HIDDEN(hidden_item);
            hidden_item = proto_tree_add_boolean(ftp_tree,
                hf_ftp_response, tvb, 0, 0, TRUE);
            PROTO_ITEM_SET_HIDDEN(hidden_item);
        }

        /*
         * Put the line into the protocol tree.
         */
        ti = proto_tree_add_text(ftp_tree, tvb, offset,
            next_offset - offset, "%s",
            tvb_format_text(tvb, offset, next_offset - offset));
        reqresp_tree = proto_item_add_subtree(ti, ett_ftp_reqresp);
    }

    if (is_request) {
        /*
         * Extract the first token, and, if there is a first
         * token, add it as the request.
         */
        tokenlen = get_token_len(line, line + linelen, &next_token);
        if (tokenlen != 0) {
            if (tree) {
                proto_tree_add_item(reqresp_tree,
                    hf_ftp_request_command, tvb, offset,
                    tokenlen, ENC_ASCII|ENC_NA);
            }
            if (strncmp(line, "PORT", tokenlen) == 0)
                is_port_request = TRUE;
        }
    } else {
        /*
         * This is a response; the response code is 3 digits,
         * followed by a space or hyphen, possibly followed by
         * text.
         *
         * If the line doesn't start with 3 digits, it's part of
         * a continuation.
         *
         * XXX - keep track of state in the first pass, and
         * treat non-continuation lines not beginning with digits
         * as errors?
         */
        if (linelen >= 3 && isdigit(line[0]) && isdigit(line[1])
            && isdigit(line[2])) {
            /*
             * One-line reply, or first or last line
             * of a multi-line reply.
             */
            tvb_get_nstringz0(tvb, offset, sizeof(code_str), code_str);
            code = strtoul(code_str, NULL, 10);

            if (tree) {
                proto_tree_add_uint(reqresp_tree,
                    hf_ftp_response_code, tvb, offset, 3, code);
            }

            /*
             * See if it's a passive-mode response.
             *
             * XXX - does anybody do FOOBAR, as per RFC
             * 1639, or has that been supplanted by RFC 2428?
             */
            if (code == 227)
                is_pasv_response = TRUE;

            /*
             * Responses to EPSV command, as per RFC 2428
             * XXX - handle IPv6?
             */
            if (code == 229)
                is_epasv_response = TRUE;

            /*
             * Skip the 3 digits and, if present, the
             * space or hyphen.
             */
            if (linelen >= 4)
                next_token = line + 4;
            else
                next_token = line + linelen;
        } else {
            /*
             * Line doesn't start with 3 digits; assume it's
             * a line in the middle of a multi-line reply.
             */
            next_token = line;
        }
    }
    offset  += (gint) (next_token - line);
    linelen -= (int) (next_token - line);
    line     = next_token;

    if (tree) {
        /*
         * Add the rest of the first line as request or
         * reply data.
         */
        if (linelen != 0) {
            if (is_request) {
                proto_tree_add_item(reqresp_tree,
                    hf_ftp_request_arg, tvb, offset,
                    linelen, ENC_ASCII|ENC_NA);
            } else {
                proto_tree_add_item(reqresp_tree,
                    hf_ftp_response_arg, tvb, offset,
                    linelen, ENC_ASCII|ENC_NA);
            }
        }
        offset = next_offset;
    }

    /*
     * If this is a PORT request or a PASV response, handle it.
     */
    if (is_port_request) {
        if (parse_port_pasv(line, linelen, &ftp_ip, &ftp_port)) {
            if (tree) {
                proto_tree_add_ipv4(reqresp_tree,
                    hf_ftp_active_ip, tvb, 0, 0,
                    ftp_ip);
                proto_tree_add_uint(reqresp_tree,
                    hf_ftp_active_port, tvb, 0, 0,
                    ftp_port);
            }
            SET_ADDRESS(&ftp_ip_address, AT_IPv4, 4, (const guint8 *)&ftp_ip);
            ftp_nat = !ADDRESSES_EQUAL(&pinfo->src, &ftp_ip_address);
            if (ftp_nat) {
                if (tree) {
                    proto_tree_add_boolean(
                        reqresp_tree,
                        hf_ftp_active_nat, tvb,
                        0, 0, ftp_nat);
                }
            }
        }
    }

    if (is_pasv_response) {
        if (linelen != 0) {
            /*
             * This frame contains a PASV response; set up a
             * conversation for the data.
             */
            if (parse_port_pasv(line, linelen, &pasv_ip, &ftp_port)) {
                if (tree) {
                    proto_tree_add_ipv4(reqresp_tree,
                        hf_ftp_pasv_ip, tvb, 0, 0, pasv_ip);
                    proto_tree_add_uint(reqresp_tree,
                        hf_ftp_pasv_port, tvb, 0, 0,
                        ftp_port);
                }
                SET_ADDRESS(&ftp_ip_address, AT_IPv4, 4,
                    (const guint8 *)&pasv_ip);
                ftp_nat = !ADDRESSES_EQUAL(&pinfo->src, &ftp_ip_address);
                if (ftp_nat) {
                    if (tree) {
                        proto_tree_add_boolean(reqresp_tree,
                            hf_ftp_pasv_nat, tvb, 0, 0,
                            ftp_nat);
                    }
                }

                /*
                 * We use "ftp_ip_address", so that if
                 * we're NAT'd we look for the un-NAT'd
                 * connection.
                 *
                 * XXX - should this call to
                 * "find_conversation()" just use
                 * "ftp_ip_address" and "server_port", and
                 * wildcard everything else?
                 */
                conversation = find_conversation(pinfo->fd->num, &ftp_ip_address,
                    &pinfo->dst, PT_TCP, ftp_port, 0,
                    NO_PORT_B);
                if (conversation == NULL) {
                    /*
                     * XXX - should this call to "conversation_new()"
                     * just use "ftp_ip_address" and "server_port",
                     * and wildcard everything else?
                     *
                     * XXX - what if we did find a conversation?  As
                     * we create it only on the first pass through the
                     * packets, if we find one, it's presumably an
                     * unrelated conversation.  Should we remove the
                     * old one from the hash table and put this one in
                     * its place?  Can the conversation code handle
                     * conversations not in the hash table?  Or should
                     * we make conversations support start and end
                     * frames, as circuits do, and treat this as an
                     * indication that one conversation was closed and
                     * a new one was opened?
                     */
                    conversation = conversation_new(
                        pinfo->fd->num, &ftp_ip_address, &pinfo->dst,
                        PT_TCP, ftp_port, 0, NO_PORT2);
                    conversation_set_dissector(conversation, ftpdata_handle);
                }
            }
        }
    }


    if (is_epasv_response) {
        if (linelen != 0) {
            /*
             * This frame contains an  EPSV response; set up a
             * conversation for the data.
             */
            if (parse_extended_pasv_response(line, linelen, &ftp_port)) {
                /* Add port number to tree */
                if (tree) {
                    proto_tree_add_uint(reqresp_tree,
                                        hf_ftp_pasv_port, tvb, 0, 0,
                                        ftp_port);
                }

                /* Find/create conversation for data */
                conversation = find_conversation(pinfo->fd->num, &pinfo->src,
                                                 &pinfo->dst, PT_TCP, ftp_port, 0,
                                                 NO_PORT_B);
                if (conversation == NULL) {
                    conversation = conversation_new(
                        pinfo->fd->num, &pinfo->src, &pinfo->dst,
                        PT_TCP, ftp_port, 0, NO_PORT2);
                    conversation_set_dissector(conversation,
                        ftpdata_handle);
                }
            }
        }
    }

    if (tree) {
        /*
         * Show the rest of the request or response as text,
         * a line at a time.
         * XXX - only if there's a continuation indicator?
         */
        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_text(ftp_tree, tvb, offset,
                next_offset - offset, "%s",
                tvb_format_text(tvb, offset, next_offset - offset));
            offset = next_offset;
        }
    }
}
示例#14
0
static int
dissect_dtpt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	proto_tree	*dtpt_tree = NULL;
	proto_item	*dtpt_item = NULL;
	guint8		version;
	guint8		message_type;
	guint32		flags;
	guint32		payload_size;

	version = tvb_get_guint8(tvb, 0);
	if (version != 1) return 0;
	message_type = tvb_get_guint8(tvb, 1);
	switch (message_type) {
		case LookupBeginRequest:
		case LookupBeginResponse:
		case LookupNextRequest:
		case LookupNextResponse:
		case LookupEndRequest:
			if (tvb_reported_length(tvb) != 20) return 0;
		break;
		case ConnectRequest:
		case ConnectResponseOK:
		case ConnectResponseERR:
			if (tvb_reported_length(tvb) != 36) return 0;
		break;
		default:
			return 0;
	}

	col_set_str(pinfo->cinfo, COL_PROTOCOL, "DTPT");
	if (check_col(pinfo->cinfo, COL_INFO))
		col_add_str(pinfo->cinfo, COL_INFO, val_to_str(message_type, names_message_type, "Unknown (%d)"));

	if (message_type == LookupBeginRequest) {
		conversation_t *c;
		c = find_or_create_conversation(pinfo);
		conversation_set_dissector(c, dtpt_conversation_handle);
	}

	if (tree) {
		dtpt_item = proto_tree_add_item(tree, proto_dtpt,
				tvb, 0, -1, ENC_NA);
		if (dtpt_item)
			dtpt_tree = proto_item_add_subtree(dtpt_item, ett_dtpt);
	}

	if (dtpt_tree) {
		proto_tree_add_uint(dtpt_tree, hf_dtpt_version,
			tvb, 0, 1, version);
		proto_tree_add_uint(dtpt_tree, hf_dtpt_message_type,
			tvb, 1, 1, message_type);

		switch (message_type) {
			case LookupBeginRequest: {
				proto_item* flags_item = NULL;
				proto_tree*	flags_tree = NULL;

				flags = tvb_get_letohl(tvb, 12);

				flags_item = proto_tree_add_uint(dtpt_tree, hf_dtpt_flags,
					tvb, 12, 4, flags);
				if (flags_item) {
					flags_tree = proto_item_add_subtree(flags_item, ett_dtpt_flags);
				}
				if (flags_tree) {
					proto_tree_add_boolean(flags_tree, hf_dtpt_flags_res_service,   tvb, 12, 4, flags);
					proto_tree_add_boolean(flags_tree, hf_dtpt_flags_flushprevious, tvb, 12, 4, flags);
					proto_tree_add_boolean(flags_tree, hf_dtpt_flags_flushcache,    tvb, 12, 4, flags);
					proto_tree_add_boolean(flags_tree, hf_dtpt_flags_return_query_string, tvb, 12, 4, flags);
					proto_tree_add_boolean(flags_tree, hf_dtpt_flags_return_aliases, tvb, 12, 4, flags);
					proto_tree_add_boolean(flags_tree, hf_dtpt_flags_return_blob, tvb, 12, 4, flags);
					proto_tree_add_boolean(flags_tree, hf_dtpt_flags_return_addr, tvb, 12, 4, flags);
					proto_tree_add_boolean(flags_tree, hf_dtpt_flags_return_comment, tvb, 12, 4, flags);
					proto_tree_add_boolean(flags_tree, hf_dtpt_flags_return_version, tvb, 12, 4, flags);
					proto_tree_add_boolean(flags_tree, hf_dtpt_flags_return_type, tvb, 12, 4, flags);
					proto_tree_add_boolean(flags_tree, hf_dtpt_flags_return_name, tvb, 12, 4, flags);
					proto_tree_add_boolean(flags_tree, hf_dtpt_flags_nearest, tvb, 12, 4, flags);
					proto_tree_add_boolean(flags_tree, hf_dtpt_flags_nocontainers, tvb, 12, 4, flags);
					proto_tree_add_boolean(flags_tree, hf_dtpt_flags_containers, tvb, 12, 4, flags);
					proto_tree_add_boolean(flags_tree, hf_dtpt_flags_deep, tvb, 12, 4, flags);
				}
				payload_size = tvb_get_letohl(tvb, 16);
				proto_tree_add_uint(dtpt_tree, hf_dtpt_payload_size,
					tvb, 16, 4, payload_size);
			}
			break;
			case LookupBeginResponse: {
				proto_tree_add_uint64(dtpt_tree, hf_dtpt_handle,
					tvb, 4, 8, tvb_get_letoh64(tvb, 4));
				proto_tree_add_uint(dtpt_tree, hf_dtpt_error,
					tvb, 12, 4, tvb_get_letohl(tvb, 12));
			}
			break;
			case LookupNextRequest: {
				proto_tree_add_uint64(dtpt_tree, hf_dtpt_handle,
					tvb, 4, 8, tvb_get_letoh64(tvb, 4));
				proto_tree_add_uint(dtpt_tree, hf_dtpt_buffer_size,
					tvb, 16, 4, tvb_get_letohl(tvb, 16));
			}
			break;
			case LookupNextResponse: {
				proto_tree_add_uint(dtpt_tree, hf_dtpt_error,
					tvb, 12, 4, tvb_get_letohl(tvb, 12));
				proto_tree_add_uint(dtpt_tree, hf_dtpt_data_size,
					tvb, 16, 4, tvb_get_letohl(tvb, 16));
			}
			break;
			case LookupEndRequest: {
				proto_tree_add_uint64(dtpt_tree, hf_dtpt_handle,
					tvb, 4, 8, tvb_get_letoh64(tvb, 4));
			}
			break;
			case ConnectRequest: {
				dissect_dtpt_sockaddr(tvb, 2, dtpt_tree, hf_dtpt_connect_addr, SOCKADDR_CONNECT);
				proto_tree_add_uint(dtpt_tree, hf_dtpt_error,
					tvb, 32, 4, tvb_get_letohl(tvb, 32));
			}
			break;
			case ConnectResponseOK: {
				dissect_dtpt_sockaddr(tvb, 2, dtpt_tree, hf_dtpt_connect_addr, SOCKADDR_CONNECT);
				proto_tree_add_uint(dtpt_tree, hf_dtpt_error,
					tvb, 32, 4, tvb_get_letohl(tvb, 32));
			}
			break;
			case ConnectResponseERR: {
				dissect_dtpt_sockaddr(tvb, 2, dtpt_tree, hf_dtpt_connect_addr, SOCKADDR_CONNECT);
				proto_tree_add_uint(dtpt_tree, hf_dtpt_error,
					tvb, 32, 4, tvb_get_letohl(tvb, 32));
			}
			break;
		}
	}

	return tvb_length(tvb);
}
示例#15
0
/* Packet dissection routine called by tcp (& udp) when port 873 detected */
static void
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;
    int					offset = 0;
    gchar				version[5];
    gchar				auth_string[10];
    guint				buff_length;
    gchar				magic_string[14];
    gchar				*version_out;

    col_set_str(pinfo->cinfo, COL_PROTOCOL, "RSYNC");

    col_clear(pinfo->cinfo, COL_INFO);

    conversation = find_or_create_conversation(pinfo);

    conversation_data = conversation_get_proto_data(conversation, proto_rsync);

    if (conversation_data == NULL) {
        conversation_data = se_alloc(sizeof(struct rsync_conversation_data));
        conversation_data->state = RSYNC_INIT;
        conversation_add_proto_data(conversation, proto_rsync, conversation_data);
    }

    conversation_set_dissector(conversation, rsync_handle);

    ti = proto_tree_add_item(tree, proto_rsync, tvb, 0, -1, ENC_NA);

    rsync_tree = proto_item_add_subtree(ti, ett_rsync);

    rsync_frame_data_p = p_get_proto_data(pinfo->fd, proto_rsync);
    if (!rsync_frame_data_p) {
        /* then we haven't seen this frame before */
        rsync_frame_data_p = se_alloc(sizeof(struct rsync_frame_data));
        rsync_frame_data_p->state = conversation_data->state;
        p_add_proto_data(pinfo->fd, proto_rsync, rsync_frame_data_p);
    }

    switch (rsync_frame_data_p->state) {
    case RSYNC_INIT:
        proto_tree_add_item(rsync_tree, hf_rsync_hdr_magic, tvb, offset, 8, ENC_ASCII|ENC_NA);
        offset += 8;
        proto_tree_add_item(rsync_tree, hf_rsync_hdr_version, tvb, offset, 4, ENC_ASCII|ENC_NA);
        tvb_get_nstringz0(tvb, offset, sizeof(version), version);
        offset += 4;

        if (check_col(pinfo->cinfo, COL_INFO)) {
            /* XXX - is this really a string? */
            version_out = format_text(version, 4);
            col_append_fstr(pinfo->cinfo, COL_INFO,
                            "Client Initialisation (Version %s)",
                            version_out);
        }

        conversation_data->state = RSYNC_SERV_INIT;

        break;
    case RSYNC_SERV_INIT:
        proto_tree_add_item(rsync_tree, hf_rsync_hdr_magic, tvb, offset, 8, ENC_ASCII|ENC_NA);
        offset += 8;
        proto_tree_add_item(rsync_tree, hf_rsync_hdr_version, tvb, offset, 4, ENC_ASCII|ENC_NA);
        tvb_get_nstringz0(tvb, offset, sizeof(version), version);
        offset += 4;

        if (check_col(pinfo->cinfo, COL_INFO)) {
            /* XXX - is this really a string? */
            version_out = format_text(version, 4);
            col_append_fstr(pinfo->cinfo, COL_INFO,
                            "Server Initialisation (Version %s)",
                            version_out);
        }

        conversation_data->state = RSYNC_CLIENT_QUERY;

        break;
    case RSYNC_CLIENT_QUERY:
        proto_tree_add_item(rsync_tree, hf_rsync_query_string, tvb, offset, -1, ENC_ASCII|ENC_NA);

        col_append_str(pinfo->cinfo, COL_INFO, "Client Query");

        conversation_data->state = RSYNC_SERV_MOTD;

        break;
    case RSYNC_SERV_MOTD:
        proto_tree_add_item(rsync_tree, hf_rsync_motd_string, tvb, offset, -1, ENC_ASCII|ENC_NA);

        col_append_str(pinfo->cinfo, COL_INFO, "Server MOTD");

        conversation_data->state = RSYNC_SERV_RESPONSE;

        break;
    case RSYNC_SERV_RESPONSE:
        /* there are two cases - file list, or authentication */
        tvb_get_nstringz0(tvb, offset, sizeof(auth_string), auth_string);
        if (0 == strncmp("@RSYNCD:", auth_string, 8)) {
            /* matches, so we assume its an authentication message */
            /* needs to handle the AUTHREQD case, but doesn't - FIXME */
            proto_tree_add_item(rsync_tree, hf_rsync_rsyncdok_string, tvb, offset, -1, ENC_ASCII|ENC_NA);

            col_append_str(pinfo->cinfo, COL_INFO, "Authentication");
            conversation_data->state = RSYNC_COMMAND;

        } else { /*  it didn't match, so it is probably a module list */

            proto_tree_add_item(rsync_tree, hf_rsync_response_string, tvb, offset, -1, ENC_ASCII|ENC_NA);

            col_append_str(pinfo->cinfo, COL_INFO, "Module list");

            /* we need to check the end of the buffer for magic string */
            buff_length = tvb_length_remaining(tvb, offset);
            tvb_get_nstringz0(tvb, buff_length-14, sizeof(magic_string), magic_string);
            if (0 == strncmp("@RSYNCD: EXIT", magic_string, 14)) {
                /* that's all, folks */
                conversation_data->state = RSYNC_COMMAND;
            } else { /* there must be more data */
                conversation_data->state = RSYNC_SERV_RESPONSE;
            }
        }

        break;

    case RSYNC_COMMAND:
        if (pinfo->destport == glb_rsync_tcp_port) {
            /* then we are still sending commands */
            proto_tree_add_item(rsync_tree, hf_rsync_command_string, tvb, offset, -1, ENC_ASCII|ENC_NA);

            col_append_str(pinfo->cinfo, COL_INFO, "Command");

            conversation_data->state = RSYNC_COMMAND;

            break;
        } /* else we fall through to the data phase */

    case RSYNC_DATA:
        /* then we are still sending commands */
        proto_tree_add_item(rsync_tree, hf_rsync_data, tvb, offset, -1, ENC_NA);

        col_append_str(pinfo->cinfo, COL_INFO, "Data");

        conversation_data->state = RSYNC_DATA;

        break;

    }

}
示例#16
0
static void
dissect_xyplex(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	proto_tree	*xyplex_tree = NULL;
	proto_item	*ti;
	conversation_t  *conversation;
	gint		offset = 0;

	guint8		prototype;
	guint8		padding;
	guint16		server_port;
	guint16		return_port;
	guint16		reserved;
	guint16		reply;

	col_set_str(pinfo->cinfo, COL_PROTOCOL, "XYPLEX");

	if (tree) {
	  ti = proto_tree_add_item(tree, proto_xyplex, tvb, offset, -1, FALSE);
	  xyplex_tree = proto_item_add_subtree(ti, ett_xyplex);
	}

	if (pinfo->destport == UDP_PORT_XYPLEX) {
		/* This is a registration request from a Unix server
		 * to the Xyplex server.  The server_port indicates
		 * which Xyplex serial port is desired.  The
		 * return_port tells the Xyplex server what TCP port
		 * to open to the Unix server.
		 */
		prototype = tvb_get_guint8(tvb, offset);
		padding = tvb_get_guint8(tvb, offset+1);
		server_port = tvb_get_ntohs(tvb, offset+2);
		return_port = tvb_get_ntohs(tvb, offset+4);
		reserved = tvb_get_ntohs(tvb, offset+6);
		if (check_col(pinfo->cinfo, COL_INFO)) {
		  col_add_fstr(pinfo->cinfo, COL_INFO,
			  "Registration Request: %d Return: %d",
			  server_port, return_port);
		}
		if (tree) {
		  proto_tree_add_uint(xyplex_tree, hf_xyplex_type, tvb,
				    offset, 1, prototype);
		  proto_tree_add_uint(xyplex_tree, hf_xyplex_pad, tvb,
				    offset+1, 1, padding);
		  proto_tree_add_uint(xyplex_tree, hf_xyplex_server_port, tvb,
				    offset+2, 2, server_port);
		  proto_tree_add_uint(xyplex_tree, hf_xyplex_return_port, tvb,
				    offset+4, 2, return_port);
		  proto_tree_add_uint(xyplex_tree, hf_xyplex_reserved, tvb,
				    offset+6, 2, reserved);
		}
		offset += 8;

		/* Look for all future TCP conversations between the
		 * requestiong server and the Xyplex host using the
		 * return_port.
		 */
		conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
				  PT_TCP, return_port, 0, NO_PORT_B);
		if (conversation == NULL) {
		    conversation = conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst,
				    PT_TCP, return_port, 0, NO_PORT2);
		    conversation_set_dissector(conversation, xyplex_handle);
		}
		return;
	}

	if (pinfo->srcport == UDP_PORT_XYPLEX) {
		prototype = tvb_get_guint8(tvb, offset);
		padding = tvb_get_guint8(tvb, offset+1);
		reply = tvb_get_ntohs(tvb, offset+2);
		if (check_col(pinfo->cinfo, COL_INFO)) {
		  col_add_fstr(pinfo->cinfo, COL_INFO, "Registration Reply: %s",
			val_to_str(reply, xyplex_reg_vals, "Unknown (0x%02x)"));
		}
		if (tree) {
		  proto_tree_add_uint(xyplex_tree, hf_xyplex_type, tvb,
				    offset, 1, prototype);
		  proto_tree_add_uint(xyplex_tree, hf_xyplex_pad, tvb,
				    offset+1, 1, padding);
		  proto_tree_add_uint(xyplex_tree, hf_xyplex_reply, tvb,
				    offset+2, 2, reply);
		}
		offset += 4;
		return;
	}

	/*
	 * This must be the TCP data stream.  This will just be
	 * the raw data being transfered from the remote server
	 * and the Xyplex serial port.
	 */
	if (check_col(pinfo->cinfo, COL_INFO)) {
	  col_add_fstr(pinfo->cinfo, COL_INFO, "%d > %d Data",
		  pinfo->srcport, pinfo->destport);
	}
	if (tree) {
	  proto_tree_add_text(xyplex_tree, tvb, offset, -1,
		"Data (%d bytes)", tvb_reported_length_remaining(tvb, offset));
	}
}