int tcomp_udvm_createTempState(tcomp_udvm_t *udvm, uint16_t state_length, uint16_t state_address, uint16_t state_instruction, 
	uint16_t minimum_access_length, uint16_t state_retention_priority, int end_msg)
{
	/*
	* If the specified minimum_access_length does not lie between 6 and 20 inclusive, or if
	* the state_retention_priority is 65535 then the END-MESSAGE
	* instruction fails to make a state creation request of its own
	* (however decompression failure does not occur and the state creation
	* requests made by the STATE-CREATE instruction are still valid).
	*/
	int is_ok = ( (6<=minimum_access_length && minimum_access_length<=20) && state_retention_priority!=65535 );

	// if not ok and not END_MESSAGE --> decompression failure MUST occurs
	if(!is_ok)
	{
		if(end_msg) return 1;

		if(state_retention_priority == 65535)
		{
			tcomp_udvm_createNackInfo2(udvm, NACK_INVALID_STATE_PRIORITY);
		}
		else
		{
			tcomp_udvm_createNackInfo2(udvm, NACK_INVALID_STATE_ID_LENGTH);
		}
		return 0;
	}

	/*
	* decompression failure occurs if the END-MESSAGE instruction makes a state creation request and four
	* instances of the STATE-CREATE instruction have already been encountered.
	*/
	if(tcomp_result_getTempStatesToCreateSize(udvm->lpResult) >= MAX_TEMP_SATES)
	{
		tcomp_udvm_createNackInfo2(udvm, NACK_TOO_MANY_STATE_REQUESTS);
		return 0;
	}

	/*
	*	Is there a state to create?
	*/
	if(is_ok)
	{
		// no byte copy ()
		tcomp_state_t *lpState =  tcomp_state_create(state_length, state_address, state_instruction, minimum_access_length, state_retention_priority);
		tcomp_result_addTempStateToCreate(udvm->lpResult, lpState);
	}

	return 1;
}
예제 #2
0
/**RFC3320-Setction_8.4.  Byte copying
From EXTERNAL to UDVM
*/
int tcomp_udvm_bytecopy_to(tcomp_udvm_t *udvm, uint32_t destination, const uint8_t* source, uint32_t tsk_size_tocopy)
{
	uint32_t byte_copy_left, byte_copy_right;

	if(destination == TCOMP_UDVM_GET_SIZE())
	{
		/* SEGFAULT */
		tcomp_udvm_createNackInfo2(udvm, NACK_SEGFAULT);
		return 0;
	}

	/*
	* The string of bytes is copied in ascending order of memory address,
	* respecting the bounds set by byte_copy_left and byte_copy_right.
	*/
	byte_copy_left = TCOMP_UDVM_GET_2BYTES_VAL(TCOMP_UDVM_HEADER_BYTE_COPY_LEFT_INDEX);
	byte_copy_right = TCOMP_UDVM_GET_2BYTES_VAL(TCOMP_UDVM_HEADER_BYTE_COPY_RIGHT_INDEX);

	// string of bytes is copied one byte at a time
	while((tsk_size_tocopy--))
	{
		*TCOMP_UDVM_GET_BUFFER_AT(destination++) = *(source++);
		
		destination = (destination == byte_copy_right)? byte_copy_left : destination;
	}

	return 1;
}
예제 #3
0
/**RFC3320-Setction_8.4.  Byte copying
From UDVM to EXTERNAL
*/
int tcomp_udvm_bytecopy_from(tcomp_udvm_t *udvm, uint8_t* destination, uint32_t source, uint32_t tsk_size_tocopy)
{
	uint32_t byte_copy_left, byte_copy_right;

	if(source >= TCOMP_UDVM_GET_SIZE()){
		TSK_DEBUG_ERROR("SEGFAULT");
		tcomp_udvm_createNackInfo2(udvm, NACK_SEGFAULT);
		return 0;
	}

	/*
	* The string of bytes is copied in ascending order of memory address,
	* respecting the bounds set by byte_copy_left and byte_copy_right.
	*/
	byte_copy_left = TCOMP_UDVM_GET_2BYTES_VAL(TCOMP_UDVM_HEADER_BYTE_COPY_LEFT_INDEX);
	byte_copy_right = TCOMP_UDVM_GET_2BYTES_VAL(TCOMP_UDVM_HEADER_BYTE_COPY_RIGHT_INDEX);


	// string of bytes is copied one byte at a time
	while((tsk_size_tocopy--)){
		*(destination++) = *TCOMP_UDVM_GET_BUFFER_AT(source++);
		source = (source == byte_copy_right)? byte_copy_left : source;
	}

	return 1;
}
예제 #4
0
/**
reference ($)<br>
<table>
<tr><td>Bytecode</td>                       <td>Operand value</td>      <td>Range</td></tr>
<tr><td>0nnnnnnn</td>                        <td>memory[2 * N]</td>       <td>0 - 65535</td></tr>
<tr><td>10nnnnnn nnnnnnnn </td>              <td>memory[2 * N]</td>       <td>0 - 65535</td></tr>
<tr><td>11000000 nnnnnnnn nnnnnnnn</td>      <td>memory[N]</td>           <td>0 - 65535</td></tr>
</table>
*/
uint16_t tcomp_udvm_opget_reference_param(tcomp_udvm_t *udvm)
{
	const uint8_t* memory_ptr = TCOMP_UDVM_GET_BUFFER_AT(udvm->executionPointer);
	uint16_t result = 0;
	
	switch( *memory_ptr & 0xc0) // 2 first bits
	{
	case 0x00: // 0nnnnnnn                        memory[2 * N]       0 - 65535
	case 0x40: // 0nnnnnnn                        memory[2 * N]       0 - 65535
		{
			uint8_t N = (*(memory_ptr) & 0x7f); // no effect first bit is already nil
			result = 2*N;
			udvm->executionPointer++;
		}
		break;

	case 0x80: // 10nnnnnn nnnnnnnn               memory[2 * N]       0 - 65535
		{
			uint16_t N = (TSK_BINARY_GET_2BYTES(memory_ptr) & 0x3fff);
			result = 2*N;
			udvm->executionPointer+=2;
		}
		break;
	
	case 0xc0: // 11000000 nnnnnnnn nnnnnnnn      memory[N]           0 - 65535
		{
			uint16_t N = TSK_BINARY_GET_2BYTES(memory_ptr+1);
			result = N;
			udvm->executionPointer+=3;
		}
		break;

	default:
		{
			TSK_DEBUG_ERROR("Invalide opcode: %u", *memory_ptr);
			tcomp_udvm_createNackInfo2(udvm, NACK_INVALID_OPERAND);
		}
		break;
	}

	return result;
}
예제 #5
0
/**
literal (#)<br>
<table>
<tr> <td>Bytecode</td>                       <td>Operand value</td>		<td>Range</td></tr>
<tr> <td>0nnnnnnn</td>                        <td>N</td>                  <td>0 - 127</td></tr>
<tr> <td>10nnnnnn nnnnnnnn</td>               <td>N</td>                  <td>0 - 16383</td></tr>
<tr> <td>11000000 nnnnnnnn nnnnnnnn</td>      <td>N</td>                  <td>0 - 65535</td></tr>
</table>
*/
uint16_t tcomp_udvm_opget_literal_param(tcomp_udvm_t *udvm)
{
	uint16_t result = 0;
	const uint8_t* memory_ptr = TCOMP_UDVM_GET_BUFFER_AT(udvm->executionPointer);

	switch( *memory_ptr & 0xc0) // 2 first bits
	{
	case 0x00: // 0nnnnnnn                        N                   0 - 127
	case 0x40: // 0nnnnnnn                        N                   0 - 127
		{
			result = *(memory_ptr);
			udvm->executionPointer++;
		}
		break;

	case 0x80: // 10nnnnnn nnnnnnnn               N                   0 - 16383
		{
			result = TSK_BINARY_GET_2BYTES(memory_ptr)&0x3fff; // All except 2 first bits
			udvm->executionPointer+=2;
		}
		break;
	
	case 0xc0: // 11000000 nnnnnnnn nnnnnnnn      N                   0 - 65535
		{
			result = TSK_BINARY_GET_2BYTES((memory_ptr+1));
			udvm->executionPointer+=3;
		}
		break;

	default:
		{
			TSK_DEBUG_ERROR("Invalide opcode: %u", *memory_ptr);
			tcomp_udvm_createNackInfo2(udvm, NACK_INVALID_OPERAND);
		}
		break;
	}
	return result;
}
예제 #6
0
/**Executes the bytecode.
*/
static tsk_bool_t tcomp_udvm_runByteCode(tcomp_udvm_t *udvm)
{
	uint16_t operand_1, operand_2, operand_3, operand_4, operand_5, operand_6, operand_7;
	tsk_bool_t excution_failed = tsk_false, end_message = tsk_false;
	if(!udvm->isOK) {
		TSK_DEBUG_ERROR("Cannot run()/execute() invalid bytecode");
		return tsk_false;
	}

	// LOOP - EXCUTE all bytecode
	while( !excution_failed && !end_message )
	{
		uint8_t udvm_instruction = * (TCOMP_UDVM_GET_BUFFER_AT(udvm->executionPointer));
		udvm->last_memory_address_of_instruction = udvm->executionPointer;
		udvm->executionPointer++; /* Skip the 1-byte [INSTRUCTION]. */

		switch(udvm_instruction)
		{
		case TCOMP_UDVM_INST__DECOMPRESSION_FAILURE:
			{
				TCOMP_UDVM_EXEC_INST__DECOMPRESSION_FAILURE(udvm);
				excution_failed = tsk_true;
				break;
			}

		case TCOMP_UDVM_INST__AND:
			{
				operand_1 = tcomp_udvm_opget_reference_param(udvm);
				operand_2 = tcomp_udvm_opget_multitype_param(udvm);
				excution_failed = !TCOMP_UDVM_EXEC_INST__AND(udvm, operand_1, operand_2);
				break;
			}

		case TCOMP_UDVM_INST__OR:
			{
				operand_1 = tcomp_udvm_opget_reference_param(udvm);
				operand_2 = tcomp_udvm_opget_multitype_param(udvm);
				excution_failed = !TCOMP_UDVM_EXEC_INST__OR(udvm, operand_1, operand_2);
				break;
			}

		case TCOMP_UDVM_INST__NOT:
			{
				operand_1 = tcomp_udvm_opget_reference_param(udvm);
				excution_failed = !TCOMP_UDVM_EXEC_INST__NOT(udvm, operand_1);
				break;
			}

		case TCOMP_UDVM_INST__LSHIFT:
			{
				operand_1 = tcomp_udvm_opget_reference_param(udvm);
				operand_2 = tcomp_udvm_opget_multitype_param(udvm);
				excution_failed = !TCOMP_UDVM_EXEC_INST__LSHIFT(udvm, operand_1, operand_2);
				break;
			}

		case TCOMP_UDVM_INST__RSHIFT:
			{
				operand_1 = tcomp_udvm_opget_reference_param(udvm);
				operand_2 = tcomp_udvm_opget_multitype_param(udvm);
				excution_failed = !TCOMP_UDVM_EXEC_INST__RSHIFT(udvm, operand_1, operand_2);
				break;
			}

		case TCOMP_UDVM_INST__ADD:
			{
				operand_1 = tcomp_udvm_opget_reference_param(udvm);
				operand_2 = tcomp_udvm_opget_multitype_param(udvm);
				excution_failed = !TCOMP_UDVM_EXEC_INST__ADD(udvm, operand_1, operand_2);
				break;
			}

		case TCOMP_UDVM_INST__SUBTRACT:
			{
				operand_1 = tcomp_udvm_opget_reference_param(udvm);
				operand_2 = tcomp_udvm_opget_multitype_param(udvm);
				excution_failed = !TCOMP_UDVM_EXEC_INST__SUBTRACT(udvm, operand_1, operand_2);
				break;
			}

		case TCOMP_UDVM_INST__MULTIPLY:
			{
				operand_1 = tcomp_udvm_opget_reference_param(udvm);
				operand_2 = tcomp_udvm_opget_multitype_param(udvm);
				excution_failed = !TCOMP_UDVM_EXEC_INST__MULTIPLY(udvm, operand_1, operand_2);
				break;
			}

		case TCOMP_UDVM_INST__DIVIDE:
			{
				operand_1 = tcomp_udvm_opget_reference_param(udvm);
				operand_2 = tcomp_udvm_opget_multitype_param(udvm);
				excution_failed = !TCOMP_UDVM_EXEC_INST__DIVIDE(udvm, operand_1, operand_2);
				break;
			}

		case TCOMP_UDVM_INST__REMAINDER:
			{
				operand_1 = tcomp_udvm_opget_reference_param(udvm);
				operand_2 = tcomp_udvm_opget_multitype_param(udvm);
				excution_failed = !TCOMP_UDVM_EXEC_INST__REMAINDER(udvm, operand_1, operand_2);
				break;
			}

		case TCOMP_UDVM_INST__SORT_ASCENDING:
			{
				operand_1 = tcomp_udvm_opget_multitype_param(udvm);
				operand_2 = tcomp_udvm_opget_multitype_param(udvm);
				operand_3 = tcomp_udvm_opget_multitype_param(udvm);
				excution_failed = !TCOMP_UDVM_EXEC_INST__SORT_ASCENDING(udvm, operand_1, operand_2, operand_3);
				break;
			}

		case TCOMP_UDVM_INST__SORT_DESCENDING:
			{
				operand_1 = tcomp_udvm_opget_multitype_param(udvm);
				operand_2 = tcomp_udvm_opget_multitype_param(udvm);
				operand_3 = tcomp_udvm_opget_multitype_param(udvm);
				excution_failed = !TCOMP_UDVM_EXEC_INST__SORT_DESCENDING(udvm, operand_1, operand_2, operand_3);
				break;
			}

		case TCOMP_UDVM_INST__SHA_1:
			{
				operand_1 = tcomp_udvm_opget_multitype_param(udvm);
				operand_2 = tcomp_udvm_opget_multitype_param(udvm);
				operand_3 = tcomp_udvm_opget_multitype_param(udvm);
				excution_failed = !TCOMP_UDVM_EXEC_INST__SHA_1(udvm, operand_1, operand_2, operand_3);
				break;
			}

		case TCOMP_UDVM_INST__LOAD:
			{
				operand_1 = tcomp_udvm_opget_multitype_param(udvm);
				operand_2 = tcomp_udvm_opget_multitype_param(udvm);
				excution_failed = !TCOMP_UDVM_EXEC_INST__LOAD(udvm, operand_1, operand_2);
				break;
			}

		case TCOMP_UDVM_INST__MULTILOAD:
			{
				operand_1 = tcomp_udvm_opget_multitype_param(udvm);
				operand_2 = tcomp_udvm_opget_literal_param(udvm);
				excution_failed = !TCOMP_UDVM_EXEC_INST__MULTILOAD(udvm, operand_1, operand_2);
				break;
			}

		case TCOMP_UDVM_INST__PUSH:
			{
				excution_failed = !TCOMP_UDVM_EXEC_INST__PUSH2(udvm);
				break;
			}

		case TCOMP_UDVM_INST__POP:
			{
				excution_failed = !TCOMP_UDVM_EXEC_INST__POP2(udvm);
				break;
			}

		case TCOMP_UDVM_INST__COPY:
			{
				operand_1 = tcomp_udvm_opget_multitype_param(udvm);
				operand_2 = tcomp_udvm_opget_multitype_param(udvm);
				operand_3 = tcomp_udvm_opget_multitype_param(udvm);
				excution_failed = !TCOMP_UDVM_EXEC_INST__COPY(udvm, operand_1, operand_2, operand_3);
				break;
			}

		case TCOMP_UDVM_INST__COPY_LITERAL:
			{
				operand_1 = tcomp_udvm_opget_multitype_param(udvm);
				operand_2 = tcomp_udvm_opget_multitype_param(udvm);
				operand_3 = tcomp_udvm_opget_reference_param(udvm);
				excution_failed = !TCOMP_UDVM_EXEC_INST__COPY_LITERAL(udvm, operand_1, operand_2, operand_3);
				break;
			}

		case TCOMP_UDVM_INST__COPY_OFFSET:
			{
				operand_1 = tcomp_udvm_opget_multitype_param(udvm);
				operand_2 = tcomp_udvm_opget_multitype_param(udvm);
				operand_3 = tcomp_udvm_opget_reference_param(udvm);
				excution_failed = !TCOMP_UDVM_EXEC_INST__COPY_OFFSET(udvm, operand_1, operand_2, operand_3);
				break;
			}

		case TCOMP_UDVM_INST__MEMSET:
			{
				operand_1 = tcomp_udvm_opget_multitype_param(udvm);
				operand_2 = tcomp_udvm_opget_multitype_param(udvm);
				operand_3 = tcomp_udvm_opget_multitype_param(udvm);
				operand_4 = tcomp_udvm_opget_multitype_param(udvm);
				excution_failed = !TCOMP_UDVM_EXEC_INST__MEMSET(udvm, operand_1, operand_2, operand_3, operand_4);
				break;
			}

		case TCOMP_UDVM_INST__JUMP:
			{
				excution_failed = !TCOMP_UDVM_EXEC_INST__JUMP2(udvm);
				break;
			}

		case TCOMP_UDVM_INST__COMPARE:
			{
				operand_1 = tcomp_udvm_opget_multitype_param(udvm);
				operand_2 = tcomp_udvm_opget_multitype_param(udvm);
				operand_3 = tcomp_udvm_opget_address_param(udvm, udvm->last_memory_address_of_instruction);
				operand_4 = tcomp_udvm_opget_address_param(udvm, udvm->last_memory_address_of_instruction);
				operand_5 = tcomp_udvm_opget_address_param(udvm, udvm->last_memory_address_of_instruction);
				excution_failed = !TCOMP_UDVM_EXEC_INST__COMPARE(udvm, operand_1, operand_2, operand_3, operand_4, operand_5);
				break;
			}

		case TCOMP_UDVM_INST__CALL:
			{
				operand_1 = tcomp_udvm_opget_address_param(udvm, udvm->last_memory_address_of_instruction);
				excution_failed = !TCOMP_UDVM_EXEC_INST__CALL(udvm, operand_1);
				break;
			}

		case TCOMP_UDVM_INST__RETURN:
			{
				excution_failed = !TCOMP_UDVM_EXEC_INST__RETURN(udvm);
				break;
			}

		case TCOMP_UDVM_INST__SWITCH:
			{
				operand_1 = tcomp_udvm_opget_literal_param(udvm);
				operand_2 = tcomp_udvm_opget_multitype_param(udvm);
				excution_failed = !TCOMP_UDVM_EXEC_INST__SWITCH(udvm, operand_1, operand_2);
				break;
			}

		case TCOMP_UDVM_INST__CRC:
			{
				operand_1 = tcomp_udvm_opget_multitype_param(udvm);
				operand_2 = tcomp_udvm_opget_multitype_param(udvm);
				operand_3 = tcomp_udvm_opget_multitype_param(udvm);
				operand_4 = tcomp_udvm_opget_reference_param(udvm);
				excution_failed = !TCOMP_UDVM_EXEC_INST__CRC(udvm, operand_1, operand_2, operand_3, operand_4);
				break;
			}

		case TCOMP_UDVM_INST__INPUT_BYTES:
			{
				operand_1 = tcomp_udvm_opget_multitype_param(udvm);
				operand_2 = tcomp_udvm_opget_multitype_param(udvm);
				operand_3 = tcomp_udvm_opget_address_param(udvm, udvm->last_memory_address_of_instruction);
				excution_failed = !TCOMP_UDVM_EXEC_INST__INPUT_BYTES(udvm, operand_1, operand_2, operand_3);
				break;
			}

		case TCOMP_UDVM_INST__INPUT_BITS:
			{	
				operand_1 = tcomp_udvm_opget_multitype_param(udvm);
				operand_2 = tcomp_udvm_opget_multitype_param(udvm);
				operand_3 = tcomp_udvm_opget_address_param(udvm, udvm->last_memory_address_of_instruction);
				excution_failed = !TCOMP_UDVM_EXEC_INST__INPUT_BITS(udvm, operand_1, operand_2, operand_3);
				break;
			}

		case TCOMP_UDVM_INST__INPUT_HUFFMAN:
			{
				operand_1 = tcomp_udvm_opget_multitype_param(udvm);
				operand_2 = tcomp_udvm_opget_address_param(udvm, udvm->last_memory_address_of_instruction);
				operand_3 = tcomp_udvm_opget_literal_param(udvm);
				excution_failed = !TCOMP_UDVM_EXEC_INST__INPUT_HUFFMAN(udvm, operand_1, operand_2, operand_3);
				break;
			}

		case TCOMP_UDVM_INST__STATE_ACCESS:
			{
				operand_1 = tcomp_udvm_opget_multitype_param(udvm);
				operand_2 = tcomp_udvm_opget_multitype_param(udvm);
				operand_3 = tcomp_udvm_opget_multitype_param(udvm);
				operand_4 = tcomp_udvm_opget_multitype_param(udvm);
				operand_5 = tcomp_udvm_opget_multitype_param(udvm);
				operand_6 = tcomp_udvm_opget_multitype_param(udvm);
				excution_failed = !TCOMP_UDVM_EXEC_INST__STATE_ACCESS(udvm, operand_1, operand_2, operand_3, operand_4, operand_5, operand_6);
				break;
			}

		case TCOMP_UDVM_INST__STATE_CREATE:
			{
				operand_1 = tcomp_udvm_opget_multitype_param(udvm);
				operand_2 = tcomp_udvm_opget_multitype_param(udvm);
				operand_3 = tcomp_udvm_opget_multitype_param(udvm);
				operand_4 = tcomp_udvm_opget_multitype_param(udvm);
				operand_5 = tcomp_udvm_opget_multitype_param(udvm);
				excution_failed = !TCOMP_UDVM_EXEC_INST__STATE_CREATE(udvm, operand_1, operand_2, operand_3, operand_4, operand_5);
				break;
			}

		case TCOMP_UDVM_INST__STATE_FREE:
			{
				operand_1 = tcomp_udvm_opget_multitype_param(udvm);
				operand_2 = tcomp_udvm_opget_multitype_param(udvm);
				excution_failed = !TCOMP_UDVM_EXEC_INST__STATE_FREE(udvm, operand_1, operand_2);
				break;
			}

		case TCOMP_UDVM_INST__OUTPUT:
			{
				operand_1 = tcomp_udvm_opget_multitype_param(udvm);
				operand_2 = tcomp_udvm_opget_multitype_param(udvm);
				excution_failed = !TCOMP_UDVM_EXEC_INST__OUTPUT(udvm, operand_1, operand_2);
				break;
			}

		case TCOMP_UDVM_INST__END_MESSAGE:
			{
				operand_1 = tcomp_udvm_opget_multitype_param(udvm);
				operand_2 = tcomp_udvm_opget_multitype_param(udvm);
				operand_3 = tcomp_udvm_opget_multitype_param(udvm);
				operand_4 = tcomp_udvm_opget_multitype_param(udvm);
				operand_5 = tcomp_udvm_opget_multitype_param(udvm);
				operand_6 = tcomp_udvm_opget_multitype_param(udvm);
				operand_7 = tcomp_udvm_opget_multitype_param(udvm);
				excution_failed = !TCOMP_UDVM_EXEC_INST__END_MESSAGE(udvm, operand_1, operand_2, operand_3, operand_4, operand_5, operand_6, operand_7);
				end_message = 1;
				break;
			}

		default:
			tcomp_udvm_createNackInfo2(udvm, NACK_INVALID_OPCODE);
			goto bail;
		}

		//TCOMP_UDVM_DEBUG_PRINT(200);
	}

bail:
	udvm->lpResult->consumed_cycles = udvm->consumed_cycles;
	return (!excution_failed);
}
예제 #7
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{
예제 #8
0
/**
multitype(%)<br>
<table>
<tr><td>Bytecode</td>               <td>Operand value</td>     <td>Range</td></tr>
<tr><td>00nnnnnn</td>                        <td>N</td>					<td>0 - 63</td></tr>
<tr><td>01nnnnnn</td>                        <td>memory[2 * N]</td>       <td>0 - 65535</td></tr>
<tr><td>1000011n</td>                        <td>2 ^ (N + 6)</td>			<td>64 , 128</td></tr>
<tr><td>10001nnn</td>                        <td>2 ^ (N + 8)</td>			<td>256 , ... , 32768</td></tr>
<tr><td>111nnnnn</td>						<td>N + 65504</td>			<td>65504 - 65535</td></tr>
<tr><td>1001nnnn nnnnnnnn</td>               <td>N + 61440</td>			<td>61440 - 65535</td></tr>
<tr><td>101nnnnn nnnnnnnn</td>              <td>N</td>					<td>0 - 8191</td></tr>
<tr><td>110nnnnn nnnnnnnn</td>				<td>memory[N]</td>           <td>0 - 65535</td></tr>
<tr><td>10000000 nnnnnnnn nnnnnnnn</td>      <td>N</td>                   <td>0 - 65535</td></tr>
<tr><td>10000001 nnnnnnnn nnnnnnnn</td>      <td>memory[N]</td>           <td>0 - 65535</td></tr>
</table>
*/
uint16_t tcomp_udvm_opget_multitype_param(tcomp_udvm_t *udvm)
{
	const uint8_t* memory_ptr = TCOMP_UDVM_GET_BUFFER_AT(udvm->executionPointer);
	int8_t index = operand_multitype_indexes[*memory_ptr];
	uint16_t result = 0;

	switch(index)
	{
	case 1: // 00nnnnnn                        N                   0 - 63
		{
			result = *(memory_ptr);
			udvm->executionPointer++;
		}
		break;

	case 2: // 01nnnnnn                        memory[2 * N]       0 - 65535
		{
			uint8_t N = (*(memory_ptr) & 0x3f);
			result = TSK_BINARY_GET_2BYTES( TCOMP_UDVM_GET_BUFFER_AT(2*N) );
			udvm->executionPointer++;
		}
		break;

	case 3: // 1000011n                        2 ^ (N + 6)        64 , 128
		{
			uint8_t N = (*(memory_ptr) & 0x01);
			result = (uint16_t)pow( (double)2, (N + 6) );
			udvm->executionPointer++;
		}
		break;

	case 4: // 10001nnn                        2 ^ (N + 8)    256 , ... , 32768
		{
			uint8_t N = (*(memory_ptr) & 0x07);
			result = (uint16_t)pow( (double)2, (N + 8) );
			udvm->executionPointer++;
		}
		break;

	case 5: // 111nnnnn                        N + 65504       65504 - 65535
		{
			result = ((*(memory_ptr) & 0x1f) + 65504 );
			udvm->executionPointer++;
		}
		break;

	case 6: // 1001nnnn nnnnnnnn               N + 61440       61440 - 65535
		{
			result = (TSK_BINARY_GET_2BYTES(memory_ptr) & 0x0fff) + 61440;
			udvm->executionPointer+=2;
		}
		break;

	case 7: // 101nnnnn nnnnnnnn               N                   0 - 8191
		{
			result = (TSK_BINARY_GET_2BYTES(memory_ptr) & 0x1fff);
			udvm->executionPointer+=2;
		}
		break;

	case 8: // 110nnnnn nnnnnnnn               memory[N]           0 - 65535
		{
			uint16_t N = TSK_BINARY_GET_2BYTES(memory_ptr) & 0x1fff;
			result = TSK_BINARY_GET_2BYTES( TCOMP_UDVM_GET_BUFFER_AT(N) );
			udvm->executionPointer+=2;
		}
		break;

	case 9: // 10000000 nnnnnnnn nnnnnnnn      N                   0 - 65535
		{
			result = TSK_BINARY_GET_2BYTES(memory_ptr+1);
			udvm->executionPointer+=3;
		}
		break;

	case 10: // 10000001 nnnnnnnn nnnnnnnn      memory[N]           0 - 65535
		{
			uint16_t N = TSK_BINARY_GET_2BYTES(memory_ptr+1);
			result = TSK_BINARY_GET_2BYTES( TCOMP_UDVM_GET_BUFFER_AT(N) );
			udvm->executionPointer+=3;
		}
		break;

		default: // -1
		{
			TSK_DEBUG_ERROR("Invalide opcode: %u", *memory_ptr);
			tcomp_udvm_createNackInfo2(udvm, NACK_INVALID_OPERAND);
		}
		break;
	}

	return result;
}