/**@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; }
/**@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; }