Example #1
0
static void
socks_udp_dissector(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {

/* Conversation dissector called from UDP dissector. Decode and display */
/* the socks header, the pass the rest of the data to the udp port  */
/* decode routine to  handle the payload.               */

    int                 offset = 0;
    guint32            *ptr;
    socks_hash_entry_t *hash_info;
    conversation_t     *conversation;
    proto_tree         *socks_tree;
    proto_item         *ti;

    conversation = find_conversation( pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype,
        pinfo->srcport, pinfo->destport, 0);

    DISSECTOR_ASSERT( conversation);    /* should always find a conversation */

    hash_info = (socks_hash_entry_t *)conversation_get_proto_data(conversation, proto_socks);

    col_set_str(pinfo->cinfo, COL_PROTOCOL, "Socks");
    col_set_str(pinfo->cinfo, COL_INFO, "Version: 5, UDP Associated packet");

    if ( tree) {
        ti = proto_tree_add_protocol_format( tree, proto_socks, tvb, offset, -1, "Socks" );

        socks_tree = proto_item_add_subtree(ti, ett_socks);

        proto_tree_add_item(socks_tree, hf_socks_reserved2, tvb, offset, 2, ENC_BIG_ENDIAN);
        offset += 2;

        proto_tree_add_item(socks_tree, hf_socks_fragment_number, tvb, offset, 1, ENC_NA);
        offset += 1;

        offset = display_address( tvb, offset, socks_tree);
        hash_info->udp_remote_port = tvb_get_ntohs(tvb, offset);

        proto_tree_add_uint( socks_tree, hf_socks_dstport, tvb,
            offset, 2, hash_info->udp_remote_port);

        offset += 2;
    }
    else {      /* no tree, skip past the socks header */
        offset += 3;
        offset = get_address_v5( tvb, offset, 0) + 2;
    }

    /* set pi src/dst port and call the udp sub-dissector lookup */

    if ( pinfo->srcport == hash_info->port)
        ptr = &pinfo->destport;
    else
        ptr = &pinfo->srcport;

    *ptr = hash_info->udp_remote_port;

    decode_udp_ports( tvb, offset, pinfo, tree, pinfo->srcport, pinfo->destport, -1);

    *ptr = hash_info->udp_port;
}
static void
state_machine_v5( socks_hash_entry_t *hash_info, tvbuff_t *tvb,
	int offset, packet_info *pinfo) {

/* Decode V5 protocol.  This is done on the first pass through the 	*/
/* list.  Based upon the current state, decode the packet and determine	*/
/* what the next state should be.  If we had per packet information, 	*/
/* this would be the place to load them up.				*/


	int temp;

	if ( hash_info->state == None) {

		col_append_str(pinfo->cinfo, COL_INFO, " Connect to server request");

		hash_info->state = Connecting;	/* change state		*/
		hash_info->connect_row = get_packet_ptr;

		temp = tvb_get_guint8(tvb, offset + 1);
						/* skip past auth methods */
		offset = hash_info->connect_offset = offset + 1 + temp;
	}
	else if ( hash_info->state == Connecting){

		guint AuthMethod = tvb_get_guint8(tvb, offset + 1);

		col_append_str(pinfo->cinfo, COL_INFO, " Connect to server response");

		hash_info->auth_method_row = get_packet_ptr;

		if ( AuthMethod == NO_AUTHENTICATION)
			hash_info->state = V5Command;

		else if ( AuthMethod == USER_NAME_AUTHENTICATION)
			hash_info->state = UserNameAuth;

		else if ( AuthMethod == GSS_API_AUTHENTICATION)
			hash_info->state = GssApiAuth;

		else	hash_info->state = Done;	/*Auth failed or error*/

	}

	else if ( hash_info->state == V5Command) {	/* Handle V5 Command */

		/** ?? guint temp; **/

		hash_info->command = tvb_get_guint8(tvb, offset + 1); /* get command */

		if (check_col(pinfo->cinfo, COL_INFO))
			col_append_fstr(pinfo->cinfo, COL_INFO, " Command Request - %s",
				get_command_name(hash_info->command));

		hash_info->state = V5Reply;
		hash_info->command_row = get_packet_ptr;

		offset += 3;			/* skip to address type */

		offset = get_address_v5(tvb, offset, hash_info);

		/** temp = tvb_get_guint8(tvb, offset);  XX: what was this for ? **/

		if (( hash_info->command == CONNECT_COMMAND) ||
		    ( hash_info->command == UDP_ASSOCIATE_COMMAND))
						/* get remote port	*/
			hash_info->port =  tvb_get_ntohs(tvb, offset);
	}

	else if ( hash_info->state == V5Reply) {	/* V5 Command Reply */


		if (check_col(pinfo->cinfo, COL_INFO))
			col_append_fstr(pinfo->cinfo, COL_INFO, " Command Response - %s",
				get_command_name(hash_info->command));

		hash_info->cmd_reply_row = get_packet_ptr;

		if (( hash_info->command == CONNECT_COMMAND) ||
		    (hash_info->command == PING_COMMAND) ||
		    (hash_info->command == TRACERT_COMMAND))
			hash_info->state = Done;

		else if ( hash_info->command == BIND_COMMAND)
			hash_info->state = V5BindReply;

		else if ( hash_info->command == UDP_ASSOCIATE_COMMAND){
			offset += 3;		/* skip to address type */
			offset = get_address_v5(tvb, offset, hash_info);

	/* save server udp port and create udp conversation */
			hash_info->udp_port =  tvb_get_ntohs(tvb, offset);

			if (!pinfo->fd->flags.visited)
				new_udp_conversation( hash_info, pinfo);

/*XXX may need else statement to handle unknowns and generate error message */

		}
	}
	else if ( hash_info->state == V5BindReply) {	/* V5 Bind Second Reply */

		col_append_str(pinfo->cinfo, COL_INFO, " Command Response: Bind remote host info");

		hash_info->bind_reply_row = get_packet_ptr;
		hash_info->state = Done;
	}
	else if ( hash_info->state == UserNameAuth) {	/* Handle V5 User Auth*/
		col_append_str(pinfo->cinfo, COL_INFO,
				" User authentication request");

		hash_info->user_name_auth_row = get_packet_ptr;
		hash_info->state = UserNameAuthReply;

	}
	else if ( hash_info->state == GssApiAuth) {
		col_append_str(pinfo->cinfo, COL_INFO,
						   " GSSAPI Authentication request");
		hash_info->gssapi_auth_row = get_packet_ptr;
		hash_info->state = GssApiAuthReply;
	}
	else if ( hash_info->state == GssApiAuthReply) {
		if (tvb_get_guint8(tvb, offset+1) == 0xFF) {
			col_append_str(pinfo->cinfo, COL_INFO,
							   " GSSAPI Authentication failure");
			hash_info->gssapi_auth_failure_row = get_packet_ptr;
		} else {
			col_append_str(pinfo->cinfo, COL_INFO,
							   " GSSAPI Authentication reply");
			if (tvb_get_ntohs(tvb, offset+2) == 0)
				hash_info->state = V5Command;
			else
				hash_info->state = GssApiAuth;
			hash_info->gssapi_auth_reply_row = get_packet_ptr;
		}
	}
	else if ( hash_info->state == UserNameAuthReply){	/* V5 User Auth reply */
		hash_info->auth_version = get_packet_ptr;
		col_append_str(pinfo->cinfo, COL_INFO, " User authentication reply");
		hash_info->state = V5Command;
	}
}