Beispiel #1
0
//
//	[[DHCP OPTION - RFC 2132 3.8. Domain Name Server Option]] object definition
//
static tsk_object_t* tnet_dhcp_option_dns_ctor(tsk_object_t * self, va_list * app)
{
	tnet_dhcp_option_dns_t *option = self;
	if(option){
		const void* payload = va_arg(*app, const void*);
		tsk_size_t payload_size = va_arg(*app, tsk_size_t);

		const uint8_t* payloadPtr = (const uint8_t*)payload;
		const uint8_t* payloadEnd = (payloadPtr + payload_size);

		/* init base */
		tnet_dhcp_option_init(TNET_DHCP_OPTION(option), dhcp_code_Domain_Server);

		option->servers = tsk_list_create();

		if(payload_size<4 || payload_size%4){
			TSK_DEBUG_ERROR("DHCP - The minimum length for this option is 4 octets, and the length MUST always be a multiple of 4.");
		}
		else{
			tsk_size_t i;
			char* ip4 = 0;
			uint32_t address;
			tsk_string_t* addrstring;

			for(i=0; i<payload_size && (payloadPtr< payloadEnd); i+=4){
				/*
				Code   Len         Address 1               Address 2
				+-----+-----+-----+-----+-----+-----+-----+-----+--
				|  6  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
				+-----+-----+-----+-----+-----+-----+-----+-----+--
				*/
				address = (uint32_t)tnet_htonl_2(payloadPtr);
				tsk_sprintf(&ip4, "%u.%u.%u.%u", (address>>24)&0xFF, (address>>16)&0xFF, (address>>8)&0xFF, (address>>0)&0xFF);
				
				addrstring = tsk_string_create(ip4);
				tsk_list_push_back_data(option->servers, (void*)&addrstring);

				TSK_FREE(ip4);
				payloadPtr+= 4;
			}
		}
	}
	return self;
}
//=================================================================================================
//	[[RFC 5389 - 15.6.  ERROR-CODE]] object definition
//
static tsk_object_t* tnet_stun_attribute_errorcode_ctor(tsk_object_t * self, va_list * app)
{
	tnet_stun_attribute_errorcode_t *attribute = self;
	if(attribute){
		const uint8_t *payload = (const uint8_t*)va_arg(*app, const void*);
		tsk_size_t payload_size = va_arg(*app, tsk_size_t);

		if(payload_size >4){
			uint32_t code = tnet_htonl_2(payload);
			payload += 4;

			attribute->_class = code >>8;
			attribute->number = (code & 0xFF);
			attribute->reason_phrase = tsk_strndup((const char*)payload, (payload_size-4));
		}
		
		TNET_STUN_ATTRIBUTE(attribute)->type = stun_error_code;
		TNET_STUN_ATTRIBUTE(attribute)->length = payload_size;
	}
//=================================================================================================
//	[[draft-ietf-behave-turn-16 - 14.5.  XOR-RELAYED-ADDRESS]] object definition
//
static tsk_object_t* tnet_turn_attribute_xrelayed_addr_ctor(tsk_object_t * self, va_list * app)
{
	tnet_turn_attribute_xrelayed_addr_t *attribute = self;
	if(attribute){
		const void *payload = va_arg(*app, const void*);
		tsk_size_t payload_size = va_arg(*app, tsk_size_t);

		if(payload && payload_size){
			const uint8_t *payloadPtr = (const uint8_t*)payload;
			payloadPtr += 1; /* Ignore first 8bits */

			TNET_STUN_ATTRIBUTE(attribute)->type = stun_xor_relayed_address;
			TNET_STUN_ATTRIBUTE(attribute)->length = payload_size;
			
			attribute->family = (tnet_stun_addr_family_t)(*(payloadPtr++));

			attribute->xport = tnet_ntohs_2(payloadPtr);
			attribute->xport ^= 0x2112;
			payloadPtr+=2;

			{	/*=== Compute IP address */
				tsk_size_t addr_size = (attribute->family == stun_ipv6) ? 16 : (attribute->family == stun_ipv4 ? 4 : 0);
				if(addr_size){	
					tsk_size_t i;
					uint32_t addr;

					for(i=0; i<addr_size; i+=4){
						addr = tnet_htonl_2(payloadPtr);
						addr ^= TNET_STUN_MAGIC_COOKIE;
						memcpy(&attribute->xaddress[i], &addr, 4);
						payloadPtr+=4;
					}
				}
				else{
					TSK_DEBUG_ERROR("UNKNOWN FAMILY [%u].", attribute->family);
				}
			}			
		}
	}
	return self;
}
/**@ingroup tnet_stun_group
* Creates @ref tnet_stun_attribute_t from raw buffer.
* @param data Raw buffer from which to create the STUN attribute.*
* @param size The size of the eaw buffer.
* @retval @ref tnet_stun_attribute_t object if succeed and NULL other wise.
*/
tnet_stun_attribute_t* tnet_stun_attribute_deserialize(const void* data, tsk_size_t size)
{
	tnet_stun_attribute_t *attribute = 0;
	const uint8_t* dataPtr = data;

	tnet_stun_attribute_type_t type = (tnet_stun_attribute_type_t)tnet_ntohs_2(dataPtr);
	uint16_t length = tnet_ntohs_2(&dataPtr[2]);

	/* Check validity */
	if(!data || size<=4/* Type(2-bytes) plus Length (2-bytes) */)
	{
		return 0;
	}

	dataPtr += (2 /* Type */+ 2/* Length */);

	/* Attribute Value
	*/
	
	switch(type)
	{
	/* RFC 5389 - 15.1.  MAPPED-ADDRESS */
	case stun_mapped_address:
		{
			attribute = (tnet_stun_attribute_t *)tnet_stun_attribute_mapped_address_create(dataPtr, length);
			break;
		}

	/* RFC 5389 -  15.2.  XOR-MAPPED-ADDRESS*/
	case stun_xor_mapped_address:
		{
			attribute = (tnet_stun_attribute_t *)tnet_stun_attribute_xmapped_address_create(dataPtr, length);
			break;
		}

	/* RFC 5389 -  15.3.  USERNAME*/
	case stun_username:
		{
			attribute = (tnet_stun_attribute_t *)tnet_stun_attribute_username_create(dataPtr, length);
			break;
		}


	/* RFC 5389 -  MESSAGE-INTEGRITY*/
	case stun_message_integrity:
		{
			if(length == TSK_SHA1_DIGEST_SIZE){
				attribute = (tnet_stun_attribute_t *)tnet_stun_attribute_integrity_create(dataPtr, length);
			}
			break;
		}

		/* RFC 5389 -  15.5.  FINGERPRINT*/
	case stun_fingerprint:
		{
			uint32_t fingerprint = tnet_htonl_2(dataPtr);
			attribute = (tnet_stun_attribute_t *)tnet_stun_attribute_fingerprint_create(fingerprint);
			break;
		}

	/* RFC 5389 -  15.6.  ERROR-CODE*/
	case stun_error_code:
		{
			attribute = (tnet_stun_attribute_t *)tnet_stun_attribute_errorcode_create(dataPtr, length);
			break;
		}

	/* RFC 5389 -  15.7.  REALM*/
	case stun_realm:
		{
			attribute = (tnet_stun_attribute_t *)tnet_stun_attribute_realm_create(dataPtr, length);
			break;
		}

	/* RFC 5389 -  15.8.  NONCE*/
	case stun_nonce:
		{
			attribute = (tnet_stun_attribute_t *)tnet_stun_attribute_nonce_create(dataPtr, length);
			break;
		}

	/* RFC 5389 -  15.9.  UNKNOWN-ATTRIBUTES*/
	case stun_unknown_attributes:
		{
			TSK_DEBUG_ERROR("DESERIALIZE:UNKNOWN-ATTRIBUTES ==> NOT IMPLEMENTED");
			attribute = tnet_stun_attribute_create();
			break;
		}

	/*	RFC 5389 - 15.10.  SOFTWARE */
	case stun_software:
		{
			attribute = (tnet_stun_attribute_t *)tnet_stun_attribute_software_create(dataPtr, length);
			break;
		}

	/*	RFC 5389 - 15.11.  ALTERNATE-SERVER */
	case stun_alternate_server:
		{
			attribute = (tnet_stun_attribute_t *)tnet_stun_attribute_altserver_create(dataPtr, length);
			break;
		}

	/* draft-ietf-behave-turn-16 subclause 14 */
	case stun_channel_number:
	case stun_lifetime:
	case stun_reserved2:
	case stun_xor_peer_address:
	case stun_data:
	case stun_xor_relayed_address:
	case stun_even_port:
	case stun_requested_transport:
	case stun_dont_fragment:
	case stun_reserved3:
	case stun_reservation_token:
		{
			attribute = tnet_turn_attribute_deserialize(type, length, dataPtr, length);
			break;
		}

	default:
		//TSK_DEBUG_WARN("==> NOT IMPLEMENTED");
		break;
	}

	if(!attribute){
		/* Create default */
		attribute = tnet_stun_attribute_create();
	}
	
	/* Set common values (Do I need this ==> already set by the constructor). */	
	attribute->type = type;
	attribute->length = length;

	return attribute;
}
Beispiel #5
0
static void tdav_codec_mp4ves_encap(tdav_codec_mp4ves_t* mp4v, const uint8_t* pdata, tsk_size_t size)
{
	uint32_t scode; // start code

	if(size <= 4/*32bits: start code size*/){
		TSK_DEBUG_ERROR("Too short");
		return;
	}
	// first 32bits
	scode = tnet_htonl_2(pdata);

/* RFC 3016 - 3.3 Examples of packetized MPEG-4 Visual bitstream

	VS= Visual Object Sequence
	VO= Visual Object
	VOL= Visual Object Layer
	VOP= Visual Object Plane
	GOV= Group of Visual Object Plane
	VP= Video Plane

	 +------+------+------+------+
(a) | RTP  |  VS  |  VO  | VOL  |
    |header|header|header|header|
    +------+------+------+------+

    +------+------+------+------+------------+
(b) | RTP  |  VS  |  VO  | VOL  |Video Packet|
    |header|header|header|header|            |
    +------+------+------+------+------------+

    +------+-----+------------------+
(c) | RTP  | GOV |Video Object Plane|
    |header|     |                  |
    +------+-----+------------------+

    +------+------+------------+  +------+------+------------+
(d) | RTP  | VOP  |Video Packet|  | RTP  |  VP  |Video Packet|
    |header|header|    (1)     |  |header|header|    (2)     |
    +------+------+------------+  +------+------+------------+

    +------+------+------------+------+------------+------+------------+
(e) | RTP  |  VP  |Video Packet|  VP  |Video Packet|  VP  |Video Packet|
    |header|header|     (1)    |header|    (2)     |header|    (3)     |
    +------+------+------------+------+------------+------+------------+

    +------+------+------------+  +------+------------+
(f) | RTP  | VOP  |VOP fragment|  | RTP  |VOP fragment|
    |header|header|    (1)     |  |header|    (2)     | ___
    +------+------+------------+  +------+------------+

     Figure 2 - Examples of RTP packetized MPEG-4 Visual bitstream
*/

/* RFC 3016 - 3.2 Fragmentation of MPEG-4 Visual bitstream

   A fragmented MPEG-4 Visual bitstream is mapped directly onto the RTP
   payload without any addition of extra header fields or any removal of
   Visual syntax elements.  The Combined Configuration/Elementary
   streams mode is used.

   In the following, header means one of the following:

   -  Configuration information (Visual Object Sequence Header, Visual
      Object Header and Video Object Layer Header)
   -  visual_object_sequence_end_code
   -  The header of the entry point function for an elementary stream
      (Group_of_VideoObjectPlane() or the header of VideoObjectPlane(),
      video_plane_with_short_header(), MeshObject() or FaceObject())
   -  The video packet header (video_packet_header() excluding
      next_resync_marker())
   -  The header of gob_layer()
      See 6.2.1 "Start codes" of ISO/IEC 14496-2 [2][9][4] for the
      definition of the configuration information and the entry point
      functions.
*/

	switch(scode){
		case visual_object_sequence_start_code:
		case visual_object_start_code:
		case user_data_start_code:
		case video_object_layer_start_code:
		case group_of_vop_start_code:
		case vop_start_code:
			{
				register uint32_t i, last_index = 0;
				int startcode = 0xffffffff;

				if(scode == visual_object_sequence_start_code && size >=5){
					//uint8_t profile_and_level_indication = pdata[4]; /* IEC 14496-2: 6.3.2 Visual Object Sequence and Visual Object */
					// TSK_DEBUG_INFO("profile_and_level_indication=%d", profile_and_level_indication);
				}

				if(size < MP4V_RTP_PAYLOAD_SIZE){
					goto last;
				}

				for(i = 4; i<(size - 4); i++){
					startcode = (startcode <<8) | pdata[i];
					switch(startcode){
						case visual_object_sequence_start_code:
						case group_of_vop_start_code:
						case vop_start_code:
							tdav_codec_mp4ves_rtp_callback(mp4v, pdata + last_index, (i - last_index), (last_index == size));
							last_index = i;
					}
				}
last:
				if(last_index < size){
					tdav_codec_mp4ves_rtp_callback(mp4v, pdata + last_index, (size - last_index), tsk_true);					
				}
				break;
			}
		default:
			TSK_DEBUG_ERROR("%x is an invalide start code", scode);
			break;
	}
}
//
//	[[DHCP SIP4]] object definition
//
static tsk_object_t* tnet_dhcp_option_sip_ctor(tsk_object_t * self, va_list * app)
{
	tnet_dhcp_option_sip_t *option = self;
	if(option){
		const void* payload = va_arg(*app, const void*);
		tsk_size_t payload_size = va_arg(*app, tsk_size_t);

		const uint8_t* payloadPtr = (const uint8_t*)payload;
		const uint8_t* payloadEnd = (payloadPtr + payload_size);
		
		/* init base */
		tnet_dhcp_option_init(TNET_DHCP_OPTION(option), dhcp_code_SIP_Servers_DHCP_Option);

		option->servers = tsk_list_create();

		/* Set values as per RFC 3361. */
		if(*payloadPtr == 0){ /* enc=0 */
			/*
			+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
			|120|27 | 0 | 7 |'e'|'x'|'a'|'m'|'p'|'l'|'e'| 3 |'c'|'o'|'m'| 0 |
			+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
			+---+---+---+---+---+---+---+---+---+---+---+---+---+ | 7
			|'e'|'x'|'a'|'m'|'p'|'l'|'e'| 3 |'n'|'e'|'t'| 0 | +---+---+---
			+---+---+---+---+---+---+---+---+---+---+
			*/
			tsk_size_t offset = 1;
			char* server = 0;
			payloadPtr++;
			while((payloadPtr < payloadEnd) && !tnet_dns_rr_qname_deserialize(payload, &server, &offset)){
				tsk_string_t* string = tsk_string_create(server);
				tsk_list_push_back_data(option->servers, (void*)&string);
				TSK_FREE(server);
				payloadPtr += offset;
			}
		}
		else{
			/*
			Code   Len   enc   Address 1               Address 2
			+-----+-----+-----+-----+-----+-----+-----+-----+--
			| 120 |  n  |  1  | a1  | a2  | a3  | a4  | a1  |  ...
			+-----+-----+-----+-----+-----+-----+-----+-----+--
			*/
			uint32_t address;
			tsk_string_t* addrstring;
			char* ip4 = 0;

			while(payloadPtr < payloadEnd){
				++payloadPtr;
				address = tnet_htonl_2(payloadPtr);
				
				tsk_sprintf(&ip4, "%u.%u.%u.%u", (address>>24)&0xFF, (address>>16)&0xFF, (address>>8)&0xFF, (address>>0)&0xFF);
				
				addrstring = tsk_string_create(ip4);
				tsk_list_push_back_data(option->servers, (void*)&addrstring);

				TSK_FREE(ip4);

				payloadPtr+= 4;
			}
		}
	}
	return self;
}
/**@ingroup tnet_turn_group
*/
tnet_stun_attribute_t* tnet_turn_attribute_deserialize(tnet_stun_attribute_type_t type, uint16_t length, const void* payload, tsk_size_t payload_size)
{
	tnet_stun_attribute_t *attribute = tsk_null;
	const uint8_t* dataPtr = payload;

	/* Attribute Value
	*/
	
	switch(type)
	{
	/*	draft-ietf-behave-turn-16 - 14.1.  CHANNEL-NUMBER */
	case stun_channel_number:
		{
			uint32_t number = tnet_htonl_2(dataPtr);
			attribute = (tnet_stun_attribute_t *)tnet_turn_attribute_channelnum_create(number);
			break;
		}

	/*	draft-ietf-behave-turn-16 - 14.2.  LIFETIME */
	case stun_lifetime:
		{
			uint32_t lifetime = tnet_htonl_2(dataPtr);
			attribute = (tnet_stun_attribute_t *)tnet_turn_attribute_lifetime_create(lifetime);
			break;
		}

	/*	draft-ietf-behave-turn-16 - 14.3.  XOR-PEER-ADDRESS */
	case stun_xor_peer_address:
		{
			TSK_DEBUG_ERROR("==> NOT IMPLEMENTED");
			break;
		}

	/*	draft-ietf-behave-turn-16 - 14.4.  DATA */
	case stun_data:
		{
			TSK_DEBUG_ERROR("==> NOT IMPLEMENTED");
			break;
		}

	/*	draft-ietf-behave-turn-16 - 14.5.  XOR-RELAYED-ADDRESS */
	case stun_xor_relayed_address:
		{
			attribute = (tnet_stun_attribute_t *)tnet_turn_attribute_xrelayed_addr_create(dataPtr, length);
			break;
		}

	/*	draft-ietf-behave-turn-16 - 14.6.  EVEN-PORT */
	case stun_even_port:
		{
			TSK_DEBUG_ERROR("==> NOT IMPLEMENTED");
			break;
		}

	/*	draft-ietf-behave-turn-16 - 14.7.  REQUESTED-TRANSPORT */
	case stun_requested_transport:
		{
			TSK_DEBUG_ERROR("==> NOT IMPLEMENTED");
			break;
		}

	/*	draft-ietf-behave-turn-16 - 14.8.  DONT-FRAGMENT */
	case stun_dont_fragment:
		{
			TSK_DEBUG_ERROR("==> NOT IMPLEMENTED");
			break;
		}
	
	/*	draft-ietf-behave-turn-16 - 14.9.  RESERVATION-TOKEN */
	case stun_reservation_token:
		{
			TSK_DEBUG_ERROR("==> NOT IMPLEMENTED");
			break;
		}

	default:
		{
			TSK_DEBUG_ERROR("==> NOT IMPLEMENTED");
			break;
		}
	}

	if(!attribute){
		/* Create default */
		attribute = tnet_stun_attribute_create();
	}

	return attribute;
}
Beispiel #8
0
/** Deserializes a DNS RR.
*/
tnet_dns_rr_t* tnet_dns_rr_deserialize(const void* data, tsk_size_t size, tsk_size_t* offset)
{
	tnet_dns_rr_t *rr = tsk_null;
	uint8_t* dataStart = (uint8_t*)data;
	uint8_t* dataPtr = (dataStart + *offset);
	//uint8_t* dataEnd = (dataPtr+size);
	tnet_dns_qtype_t qtype;
	tnet_dns_qclass_t qclass;
	uint32_t ttl;
	uint16_t rdlength;
	char* qname = tsk_null;

	/* Check validity */
	if(!dataPtr || !size){
		goto bail;
	}

	/* == Parse QNAME == */
	tnet_dns_rr_qname_deserialize(dataStart, &qname, offset);
	dataPtr = (dataStart + *offset);
	/* == Parse QTYPE == */
	qtype = (tnet_dns_qtype_t)tnet_ntohs_2(dataPtr);
	dataPtr += 2, *offset += 2;
	/* == Parse QCLASS == */
	qclass = (tnet_dns_qclass_t)tnet_ntohs_2(dataPtr);
	dataPtr += 2, *offset += 2;
	/* == Parse TTL == */
	ttl = tnet_htonl_2(dataPtr);
	dataPtr += 4, *offset += 4;
	/* == Parse RDLENGTH == */
	rdlength = tnet_ntohs_2(dataPtr);
	dataPtr += 2, *offset += 2;

	switch(qtype){
		case qtype_a:
			{
				rr = (tnet_dns_rr_t *)tnet_dns_a_create(qname, qclass, ttl, rdlength, dataStart, *offset);
				break;
			}

		case qtype_aaaa:
			{
				rr = (tnet_dns_rr_t *)tnet_dns_aaaa_create(qname, qclass, ttl, rdlength, dataStart, *offset);
				break;
			}

		case qtype_cname:
			{
				rr = (tnet_dns_rr_t *)tnet_dns_cname_create(qname, qclass, ttl, rdlength, dataStart, *offset);
				break;
			}

		case qtype_mx:
			{
				rr = (tnet_dns_rr_t *)tnet_dns_mx_create(qname, qclass, ttl, rdlength, dataStart, *offset);
				break;
			}

		case qtype_naptr:
			{
				rr = (tnet_dns_rr_t *)tnet_dns_naptr_create(qname, qclass, ttl, rdlength, dataStart, *offset);
				break;
			}

		case qtype_ns:
			{
				rr = (tnet_dns_rr_t *)tnet_dns_ns_create(qname, qclass, ttl, rdlength, dataStart, *offset);
				break;
			}

		case qtype_opt:
			{
				unsigned payload_size = qclass;
				rr = (tnet_dns_rr_t *)tnet_dns_opt_create(payload_size);
				break;
			}

		case qtype_ptr:
			{
				rr = (tnet_dns_rr_t *)tnet_dns_ptr_create(qname, qclass, ttl, rdlength, dataStart, *offset);
				break;
			}

		case qtype_soa:
			{
				rr = (tnet_dns_rr_t *)tnet_dns_soa_create(qname, qclass, ttl, rdlength, dataStart, *offset);
				break;
			}

		case qtype_srv:
			{
				rr = (tnet_dns_rr_t *)tnet_dns_srv_create(qname, qclass, ttl, rdlength, dataStart, *offset);
				break;
			}

		case qtype_txt:
			{
				rr = (tnet_dns_rr_t *)tnet_dns_txt_create(qname, qclass, ttl, rdlength, dataStart, *offset);
				break;
			}

		default:
			{
				TSK_DEBUG_ERROR("NOT IMPLEMENTED");
				break;
			}
	}

bail:
	TSK_FREE(qname);
	
	*offset += rdlength;
	return rr;
}