tsk_buffer_t* tmsrp_data_out_get(tmsrp_data_out_t* self) { tsk_buffer_t* ret = tsk_null; tsk_size_t toread; if(!self){ return tsk_null; } if(!(toread = self->size > TMSRP_MAX_CHUNK_SIZE ? TMSRP_MAX_CHUNK_SIZE : self->size)){ return tsk_null; } if(self->message){ ret = tsk_buffer_create(TSK_BUFFER_DATA(self->message), toread); tsk_buffer_remove(self->message, 0, toread); self->size = self->message->size; } else if(self->file){ // Buffer hack tsk_size_t read; ret = tsk_buffer_create_null(); ret->data = tsk_calloc(toread, sizeof(uint8_t)); ret->size = toread; if((read = fread(ret->data, sizeof(uint8_t), toread, self->file)) == toread){ self->size -= toread; } else{ TSK_OBJECT_SAFE_FREE(ret); } } return ret; }
//================================================================================================= // HTTP action object definition // static tsk_object_t* thttp_action_ctor(tsk_object_t * self, va_list * app) { thttp_action_t *action = self; if(action){ va_list* app_2; thttp_action_param_type_t curr; action->type = va_arg(*app, thttp_action_type_t); action->url = tsk_strdup(va_arg(*app, const char*)); action->method = tsk_strdup(va_arg(*app, const char*)); app_2 = va_arg(*app, va_list*); action->options = tsk_list_create(); action->headers = tsk_list_create(); if(!app_2){ /* XCAP stack will pass null va_list */ goto bail; } while((curr = va_arg(*app_2, thttp_action_param_type_t)) != thttp_aptype_null){ switch(curr){ case thttp_aptype_option: { /* (thttp_action_option_t)ID_ENUM, (const char*)VALUE_STR */ thttp_action_option_t id = va_arg(*app_2, thttp_action_option_t); const char* value = va_arg(*app_2, const char *); tsk_options_add_option(&action->options, id, value); break; } case thttp_aptype_header: { /* (const char*)NAME_STR, (const char*)VALUE_STR */ const char* name = va_arg(*app_2, const char *); const char* value = va_arg(*app_2, const char *); tsk_params_add_param(&action->headers, name, value); break; } case thttp_aptype_payload: { /* (const void*)PAY_PTR, (tsk_size_t)PAY_SIZE */ const void* payload = va_arg(*app_2, const void *); tsk_size_t size = va_arg(*app_2, tsk_size_t); if(payload && size){ TSK_OBJECT_SAFE_FREE(action->payload); action->payload = tsk_buffer_create(payload, size); } break; } default: { /* va_list will be unsafe ==> exit */ TSK_DEBUG_ERROR("NOT SUPPORTED."); goto bail; } } /* switch */ } /* while */ } bail: return self; }
tsk_buffer_t* trtp_rtcp_sdes_item_serialize(const trtp_rtcp_sdes_item_t* self) { tsk_buffer_t*buffer = tsk_null; if(!self){ TSK_DEBUG_ERROR("Invalid parameter"); return tsk_null; } if((buffer = tsk_buffer_create(tsk_null, trtp_rtcp_sdes_item_get_size(self)))){ if(trtp_rtcp_sdes_item_serialize_to(self, buffer->data, buffer->size) != 0){ TSK_OBJECT_SAFE_FREE(buffer); } } return buffer; }
trtp_rtcp_sdes_item_t* trtp_rtcp_sdes_item_create(trtp_rtcp_sdes_item_type_t type, const void* data, uint8_t length) { trtp_rtcp_sdes_item_t* item; if(!(item = _trtp_rtcp_sdes_item_create_null(type))){ TSK_DEBUG_ERROR("Failed to create new SDES item"); return tsk_null; } item->type = type; if(data && length){ item->data = tsk_buffer_create(data, length); } return item; }
//================================================================================================= // [[draft-ietf-behave-turn-16 - 14.4. DATA]] object definition // static tsk_object_t* tnet_turn_attribute_data_ctor(tsk_object_t * self, va_list * app) { tnet_turn_attribute_data_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){ attribute->value = tsk_buffer_create(payload, payload_size); } TNET_STUN_ATTRIBUTE(attribute)->type = stun_data; TNET_STUN_ATTRIBUTE(attribute)->length = (uint16_t)payload_size; } return self; }
//================================================================================================= // MSRP outgoing data object definition // static void* tmsrp_data_out_ctor(tsk_object_t * self, va_list * app) { tmsrp_data_out_t *data_out = self; if(data_out){ tsk_istr_t id; const void* pdata = va_arg(*app, const void*); tsk_size_t size = va_arg(*app, tsk_size_t); tsk_bool_t isfilepath = va_arg(*app, tsk_bool_t); if(isfilepath){ if((data_out->file = fopen((const char*)pdata, "rb"))){ int ret; if((ret = fseek(data_out->file, 0L, SEEK_END))){ TSK_DEBUG_ERROR("fseek for file:[%s] failed with error code %d.", (const char*)pdata, ret); TMSRP_DATA(data_out)->isOK = tsk_false; } else{ data_out->size = ftell(data_out->file); if((ret = fseek(data_out->file, 0L, SEEK_SET))){ TSK_DEBUG_ERROR("fseek for file:[%s] failed with error code %d.", (const char*)pdata, ret); TMSRP_DATA(data_out)->isOK = tsk_false; } else{ TMSRP_DATA(data_out)->isOK = tsk_true; } } } else{ TSK_DEBUG_ERROR("Failed to open(rb) this file:[%s]", (const char*)pdata); TMSRP_DATA(data_out)->isOK = tsk_false; } } else{ if((data_out->message = tsk_buffer_create(pdata, size))){ TMSRP_DATA(data_out)->isOK = (data_out->message->size == size); data_out->size = data_out->message->size; } } // content type TMSRP_DATA(data_out)->ctype = tsk_strdup("application/octet-stream"); TMSRP_DATA(data_out)->wctype = tsk_strdup("text/plain"); // random id tsk_strrandom(&id); TMSRP_DATA(data_out)->id = tsk_strdup(id); } return self; }
tsk_buffer_t* trtp_rtcp_packet_serialize(const trtp_rtcp_packet_t* self, tsk_size_t num_bytes_pad) { tsk_size_t size = trtp_rtcp_packet_get_size(self); if(self && size){ tsk_buffer_t* buffer; const tsk_size_t _size = (size + num_bytes_pad); if((buffer = tsk_buffer_create(tsk_null, _size))){ if(trtp_rtcp_packet_serialize_to(self, buffer->data, size) != 0){ TSK_OBJECT_SAFE_FREE(buffer); } else buffer->size = size; return buffer; } } return tsk_null; }
tnet_dhcp_option_t* tnet_dhcp_option_deserialize(const void* data, tsk_size_t size) { tnet_dhcp_option_t *option = 0; uint8_t* dataPtr = ((uint8_t*)data); //uint8_t* dataEnd = (dataPtr+size); tnet_dhcp_option_code_t code; uint8_t len; /* Check validity */ if(!dataPtr || size<2/*Code Len*/){ goto bail; } code = (tnet_dhcp_option_code_t)*dataPtr++; len = *dataPtr++; switch(code) { case dhcp_code_SIP_Servers_DHCP_Option: { option = (tnet_dhcp_option_t *)tnet_dhcp_option_sip_create(dataPtr, len); break; } case dhcp_code_Domain_Server: { option = (tnet_dhcp_option_t *)tnet_dhcp_option_dns_create(dataPtr, len); break; } default: { option = tnet_dhcp_option_create(code); } } /* In all case */ if(option && !option->value && len){ option->value = tsk_buffer_create((((uint8_t*)data) + 2/*Code Len*/), len); } bail: return option; }
// num_bytes_pad: number of bytes to add to the buffer. Useful to have the packet byte aligned or to prepare for SRTP protection // the padding bytes will not be added to the final buffer size tsk_buffer_t* trtp_rtp_packet_serialize(const trtp_rtp_packet_t *self, tsk_size_t num_bytes_pad) { tsk_buffer_t* buffer = tsk_null; tsk_size_t size; if(!self || !self->header){ TSK_DEBUG_ERROR("Invalid parameter"); return tsk_null; } size = (trtp_rtp_packet_guess_serialbuff_size(self) + num_bytes_pad); if(size & 0x03) size += (4 - (size & 0x03)); if(!(buffer = tsk_buffer_create(tsk_null, size))){ TSK_DEBUG_ERROR("Failed to create buffer with size = %u", (unsigned)size); return tsk_null; } // shorten the buffer to hide the padding buffer->size = trtp_rtp_packet_serialize_to(self, buffer->data, buffer->size); return buffer; }
int tsk_hmac_xxxcompute(const uint8_t* input, tsk_size_t input_size, const char* key, tsk_size_t key_size, tsk_hash_type_t type, uint8_t* digest) { #define TSK_MAX_BLOCK_SIZE TSK_SHA1_BLOCK_SIZE tsk_size_t i, newkey_size; tsk_size_t block_size = type == md5 ? TSK_MD5_BLOCK_SIZE : TSK_SHA1_BLOCK_SIZE; // Only SHA-1 and MD5 are supported for now tsk_size_t digest_size = type == md5 ? TSK_MD5_DIGEST_SIZE : TSK_SHA1_DIGEST_SIZE; char hkey [TSK_MAX_BLOCK_SIZE]; uint8_t ipad [TSK_MAX_BLOCK_SIZE]; uint8_t opad [TSK_MAX_BLOCK_SIZE]; memset(ipad, 0, sizeof(ipad)); memset(opad, 0, sizeof(ipad)); /* * H(K XOR opad, H(K XOR ipad, input)) */ // Check key len if (key_size > block_size){ if(type == md5){ TSK_MD5_DIGEST_CALC(key, key_size, (uint8_t*)hkey); } else if(type == sha1){ TSK_SHA1_DIGEST_CALC((uint8_t*)key, (unsigned int)key_size, (uint8_t*)hkey); } else return -3; newkey_size = digest_size; } else{ memcpy(hkey, key, key_size); newkey_size = key_size; } memcpy(ipad, hkey, newkey_size); memcpy(opad, hkey, newkey_size); /* [K XOR ipad] and [K XOR opad]*/ for (i=0; i<block_size; i++){ ipad[i] ^= 0x36; opad[i] ^= 0x5c; } { tsk_buffer_t *passx; // pass1 or pass2 int pass1_done = 0; passx = tsk_buffer_create(ipad, block_size); // pass1 tsk_buffer_append(passx, input, input_size); digest_compute: if(type == md5){ TSK_MD5_DIGEST_CALC(TSK_BUFFER_TO_U8(passx), (unsigned int)TSK_BUFFER_SIZE(passx), digest); } else{ TSK_SHA1_DIGEST_CALC(TSK_BUFFER_TO_U8(passx), (unsigned int)TSK_BUFFER_SIZE(passx), digest); } if(pass1_done){ TSK_OBJECT_SAFE_FREE(passx); goto pass1_and_pass2_done; } else{ pass1_done = 1; } tsk_buffer_cleanup(passx); tsk_buffer_append(passx, opad, block_size); // pass2 tsk_buffer_append(passx, digest, digest_size); goto digest_compute; } pass1_and_pass2_done: return 0; }
/** internal fuction used to config a SIP action */ int _tsip_action_set(tsip_action_handle_t* self, va_list* app) { tsip_action_param_type_t curr; tsip_action_t* action = self; if(!action){ /* Nothing to do */ return 0; } while((curr = va_arg(*app, tsip_action_param_type_t)) != aptype_null){ switch(curr){ case aptype_header: { /* (const char*)NAME_STR, (const char*)VALUE_STR */ const char* name = va_arg(*app, const char *); const char* value = va_arg(*app, const char *); tsk_params_add_param(&action->headers, name, value); break; } case aptype_config: { /* (const tsip_action_handle_t*)ACTION_CONFIG_HANDLE */ const tsip_action_t* handle = va_arg(*app, const tsip_action_handle_t *); if(handle && handle->type == tsip_atype_config){ /* Copy headers */ if(!TSK_LIST_IS_EMPTY(handle->headers)){ tsk_list_pushback_list(action->headers, handle->headers); } /* Copy payload */ if(handle->payload && handle->payload->data && handle->payload->size){ TSK_OBJECT_SAFE_FREE(action->payload); action->payload = tsk_buffer_create(handle->payload->data, handle->payload->size); } /* Copy resp line */ action->line_resp.code = handle->line_resp.code; tsk_strupdate(&action->line_resp.phrase, handle->line_resp.phrase); /* Copy media params */ if(!TSK_LIST_IS_EMPTY(handle->media.params)){ if(!action->media.params){ action->media.params = tmedia_params_create(); } tsk_list_pushback_list(action->media.params, handle->media.params); } } else if(handle){ /* Only invalid type should cause error */ TSK_DEBUG_ERROR("Invalid action configuration handle."); return -2; } break; } case aptype_payload: { /* (const void*)PAY_PTR, (tsk_size_t)PAY_SIZE */ const void* payload = va_arg(*app, const void *); tsk_size_t size = va_arg(*app, tsk_size_t); if(payload && size){ TSK_OBJECT_SAFE_FREE(action->payload); action->payload = tsk_buffer_create(payload, size); } break; } case aptype_resp_line: { /* (int32_t)CODE_INT, (const char*)PHRASE_STR */ int32_t code = va_arg(*app, int32_t); const char* phrase = va_arg(*app, const void *); action->line_resp.code = (short)code; tsk_strupdate(&action->line_resp.phrase, phrase); break; } case aptype_media: { /* ... */ tmedia_params_L_t* params; if((params = tmedia_params_create_2(app))){ if(action->media.params){ tsk_list_pushback_list(action->media.params, params); } else{ action->media.params = tsk_object_ref(params); } TSK_OBJECT_SAFE_FREE(params); } break; } default: { /* va_list will be unsafe ==> exit */ TSK_DEBUG_ERROR("NOT SUPPORTED."); return -3; } } /* switch */ } /* while */ return 0; }
/** internal function used to deserialize a buffer containing a SMS-DELIVER message. */ tsms_tpdu_message_t* _tsms_tpdu_deliver_deserialize(const void* data, tsk_size_t size) { /* You don't need to test data and test, this is an internal function called by tsms_tpdu_message_deserialize() */ tsms_tpdu_deliver_t* self = tsms_tpdu_deliver_create(tsk_null, tsk_null); tsk_bool_t failed = tsk_false; tsk_size_t any_len; const uint8_t* pdata = data; const uint8_t* pend = pdata + size; /* SMSC address */ #if TSMS_TPDU_APPEND_SMSC if(!(self->smsc = tsms_address_deserialize(data, size, tsms_addr_smsc, &any_len)) || !any_len){ TSK_DEBUG_ERROR("SMS-DELIVER == Failed to parse SMSC address"); failed = tsk_true; goto bail; } else{ if((pdata += any_len) >= pend){ TSMS_ERROR_TOO_SHORT(); } } #endif /* SMS-DELIVER first Octect: - TP-Message-Type-Indicator(2b) - TP-More-Messages-to-Send(1b) - TP-Loop-Prevention(1b) - TP-Reply-Path(1b) - TP-User-Data-Header-Indicator(1b) - TP-Status-Report-Indication(1b) +----+----+----+----+----+----+----+----+ | RP|UDHI|SRI | |LP |MMS | MTI | +----+----+----+----+----+----+----+----+ */ TSMS_TPDU_MESSAGE(self)->mti = (*pdata & 0x03); self->mms = (*pdata & 0x04)>>2, self->lp = (*pdata & 0x08)>>3, self->sri = (*pdata & 0x20)>>5, self->udhi = (*pdata & 0x40)>>6, self->rp = (*pdata & 0x80)>>7; if((++pdata) >= pend){ TSMS_ERROR_TOO_SHORT(); } /* 3GPP TS 23.040 ==> TP-Originating-Address (TP-OA)*/ if(!(self->oa = tsms_address_deserialize(pdata, (pend-pdata), tsms_addr_oa, &any_len)) || !any_len){ TSK_DEBUG_ERROR("SMS-DELIVER == Failed to parse OA address"); failed = tsk_true; goto bail; } else{ if((pdata += any_len) >= pend){ TSMS_ERROR_TOO_SHORT(); } } /* 3GPP TS 23.040 ==> 9.2.3.9 TP-Protocol-Identifier (TP-PID) * 1o */ TSMS_TPDU_MESSAGE(self)->pid = *pdata; if((++pdata) >= pend){ TSMS_ERROR_TOO_SHORT(); } /* 3GPP TS 23.040 ==> 9.2.3.10 TP-Data-Coding-Scheme (TP-DCS) * 1o */ TSMS_TPDU_MESSAGE(self)->dcs = *pdata; if((++pdata) >= pend){ TSMS_ERROR_TOO_SHORT(); } /* 3GPP TS 23.040 ==> TP-Service-Centre-Time-Stamp (TP-SCTS) * 7o */ if((pend - pdata)<=7){ TSMS_ERROR_TOO_SHORT(); } memcpy(self->scts, pdata, 7); pdata += 7; /* 3GPP TS 23.040 ==> 9.2.3.16 TP-User-Data-Length (TP-UDL) * 1o */ TSMS_TPDU_MESSAGE(self)->udl = *pdata; pdata++; /* 3GPP TS 23.040 ==> 9.2.3.24 TP-User Data (TP-UD) */ if((pend-pdata) > 0){ TSMS_TPDU_MESSAGE(self)->ud = tsk_buffer_create(pdata, (pend-pdata)); } bail: if(failed){ TSK_OBJECT_SAFE_FREE(self); } return TSMS_TPDU_MESSAGE(self); }
/**@ingroup tsk_buffer_group * Creates a new empty buffer. * @retval A new empty buffer object. * @sa tsk_buffer_create. */ tsk_buffer_t* tsk_buffer_create_null() { return tsk_buffer_create(tsk_null, 0); }