Ejemplo n.º 1
0
/**@ingroup tcomp_manager_group
*/
tsk_size_t tcomp_manager_getNextStreamMessage(tcomp_manager_handle_t *handle, tcomp_result_t *lpResult)
{
	tcomp_manager_t *manager = handle;
	if(!manager){
		TSK_DEBUG_ERROR("Invalid parameter");
		return 0;
	}

	if(!lpResult || !tcomp_buffer_getSize(lpResult->output_buffer)){
		TSK_DEBUG_ERROR("Invalid result.");
		return 0;
	}

	if(!lpResult->isStreamBased){
		TSK_DEBUG_ERROR("You MUST provide stream buffer.");
		return 0;
	}

	_tcomp_result_reset(lpResult, tsk_false, tsk_false);
	
	if(tcomp_decompressordisp_getNextMessage(manager->dispatcher_decompressor, lpResult)){
		return *tcomp_buffer_getIndexBytes(lpResult->output_buffer);
	}

	return 0;
}
Ejemplo n.º 2
0
//========================================================
//	UDVM machine definition
//
static tsk_object_t* tcomp_udvm_ctor(tsk_object_t * self, va_list * app)
{
	tcomp_udvm_t *udvm = self;
	if(udvm){
		/* RFC 3320 - 7.  SigComp Message Format */
		udvm->sigCompMessage = va_arg(*app, tcomp_message_t *);
		udvm->stateHandler = va_arg(*app, tcomp_statehandler_t *);
		udvm->lpResult = va_arg(*app, tcomp_result_t *);
		
		udvm->isOK = tsk_true;
		udvm->maximum_UDVM_cycles = 0; /* RFC 3320 subclause 8.6 */
		udvm->consumed_cycles = 0;
		udvm->memory = tcomp_buffer_create_null();

		/* Alloc UDVM memory */
		if(udvm->sigCompMessage->stream_based){
			/*
			* If the transport is stream-based however, then a fixed-size input buffer is required to accommodate the stream, independently of the
			* size of each SigComp message. So, for simplicity, the UDVM memory size is set to (decompression_memory_size / 2).
			*/

			tcomp_buffer_allocBuff(udvm->memory, udvm->stateHandler->sigcomp_parameters->dmsValue/2);
		}
		else{
			/*
			* If the transport is message-based then sufficient memory must be available
			* to buffer the entire SigComp message before it is passed to the UDVM. So if the message is n bytes long, then the UDVM memory size is set
			* to (decompression_memory_size - n), up to a maximum of 65536 bytes.
			*/
			tcomp_buffer_allocBuff(udvm->memory, (udvm->stateHandler->sigcomp_parameters->dmsValue-udvm->sigCompMessage->totalSize));
		}

		/*
		* Has feedback with my state id?
		*/
		if(tcomp_buffer_getSize(udvm->sigCompMessage->ret_feedback_buffer)){
			tsk_size_t size = tcomp_buffer_getSize(udvm->sigCompMessage->ret_feedback_buffer);
			tcomp_buffer_allocBuff(udvm->lpResult->ret_feedback, size);
			memcpy(tcomp_buffer_getBuffer(udvm->lpResult->ret_feedback), tcomp_buffer_getBuffer(udvm->sigCompMessage->ret_feedback_buffer), size);
		}
		
		/*
		*	Has state?
		*/
		if(tcomp_buffer_getSize(udvm->sigCompMessage->stateId)){
			/* Find the provided state */
			tcomp_state_t* lpState = NULL;
			uint16_t match_count = tcomp_statehandler_findState(udvm->stateHandler, udvm->sigCompMessage->stateId, &lpState);
			if( (!match_count || match_count>1 || !lpState)
				|| (lpState->minimum_access_length > tcomp_buffer_getSize(udvm->sigCompMessage->stateId))
				|| ((tsk_size_t)(lpState->address + lpState->length) > TCOMP_UDVM_GET_SIZE()) )
			{
				tcomp_udvm_createNackInfo(udvm, NACK_STATE_NOT_FOUND, udvm->sigCompMessage->stateId, 0);
				udvm->isOK = tsk_false;
				return self;
			}
			//this->sigCompMessage->stateId.print();//FIXME
			/*
			* Copy bytecodes to UDVM memory
			*/
			if( (tsk_size_t)(lpState->address + lpState->length) >= TCOMP_UDVM_GET_SIZE() ){
				tcomp_udvm_createNackInfo2(udvm, NACK_SEGFAULT);
				udvm->isOK = tsk_false;
				return self;
			}
			memcpy( TCOMP_UDVM_GET_BUFFER_AT(lpState->address), 
				tcomp_buffer_getBuffer(lpState->value), 
				tcomp_buffer_getSize(lpState->value) );
			
			//RFC 3320 - 7.2.  Accessing Stored State (Useful values)
			TCOMP_UDVM_SET_2BYTES_VAL(TCOMP_UDVM_HEADER_PARTIAL_STATE_ID_LENGTH_INDEX, tcomp_buffer_getSize(udvm->sigCompMessage->stateId));
			TCOMP_UDVM_SET_2BYTES_VAL(TCOMP_UDVM_HEADER_STATE_LENGTH_INDEX, tcomp_buffer_getSize(lpState->value));
			
			udvm->executionPointer = lpState->instruction;
		}
		else // DON'T HAVE STATE
		{
			/*
			* Copy bytecodes to UDVM memory
			*/
			tsk_size_t bytecodes_destination = udvm->sigCompMessage->bytecodes_destination;
			if( (bytecodes_destination + tcomp_buffer_getSize(udvm->sigCompMessage->uploaded_UDVM_buffer)) >= TCOMP_UDVM_GET_SIZE() ){
				tcomp_udvm_createNackInfo2(udvm, NACK_BYTECODES_TOO_LARGE);
				udvm->isOK = tsk_false;
				return self;
			}
			memcpy( TCOMP_UDVM_GET_BUFFER_AT(bytecodes_destination),
				tcomp_buffer_getBuffer(udvm->sigCompMessage->uploaded_UDVM_buffer),
				tcomp_buffer_getSize(udvm->sigCompMessage->uploaded_UDVM_buffer));

			// Set pointer indicating execution index
			udvm->executionPointer = bytecodes_destination;
		}

		/* RFC 3320-Section_8.6.  UDVM Cycles
		/*
		* To ensure that a SigComp message cannot consume excessive processing
		* resources, SigComp limits the number of "UDVM cycles" allocated to
		* each message.  The number of available UDVM cycles is initialized to
		* 1000 plus the number of bits in the SigComp header (as described in
		* Section 7); this sum is then multiplied by cycles_per_bit.
		*/
		/*maximum_UDVM_cycles = (8 * n + 1000) * cycles_per_bit*///FIXME:header_size
		udvm->maximum_UDVM_cycles = ( (8 * udvm->sigCompMessage->header_size + 1000)* udvm->stateHandler->sigcomp_parameters->cpbValue );
		
		//
		//	RFC 3320 - 7.2.  Useful values
		//
		TCOMP_UDVM_SET_2BYTES_VAL(TCOMP_UDVM_HEADER_UDVM_MEMORY_SIZE_INDEX, TCOMP_UDVM_GET_SIZE());
		TCOMP_UDVM_SET_2BYTES_VAL(TCOMP_UDVM_HEADER_CYCLES_PER_BIT_INDEX, udvm->stateHandler->sigcomp_parameters->cpbValue);
		TCOMP_UDVM_SET_2BYTES_VAL(TCOMP_UDVM_HEADER_SIGCOMP_VERSION_INDEX, udvm->stateHandler->sigcomp_parameters->SigComp_version);
		memset(TCOMP_UDVM_GET_BUFFER_AT(TCOMP_UDVM_HEADER_RESERVED_INDEX), 0, TCOMP_UDVM_HEADER_RESERVED_SIZE);
	}
	else{