X-Git-Url: http://git.silcnet.org/gitweb/?p=silc.git;a=blobdiff_plain;f=lib%2Fsilccore%2Fsilcpayload.c;h=294ebac8356d6581dd9c4b160e338e926df417c3;hp=6724a95cbe9d16be3b3402fa636ea83b8d0f3841;hb=e5d8d3db6caa344b3d419b884556c21b15e7d123;hpb=8cf8c85f3fdfcbae751f606bbce44a2cd0ef5bbf diff --git a/lib/silccore/silcpayload.c b/lib/silccore/silcpayload.c index 6724a95c..294ebac8 100644 --- a/lib/silccore/silcpayload.c +++ b/lib/silccore/silcpayload.c @@ -32,7 +32,7 @@ struct SilcIDPayloadStruct { SilcIdType type; - unsigned short len; + uint16 len; unsigned char *id; }; @@ -41,24 +41,30 @@ struct SilcIDPayloadStruct { SilcIDPayload silc_id_payload_parse(SilcBuffer buffer) { SilcIDPayload new; + int ret; SILC_LOG_DEBUG(("Parsing ID payload")); new = silc_calloc(1, sizeof(*new)); - silc_buffer_unformat(buffer, - SILC_STR_UI_SHORT(&new->type), - SILC_STR_UI_SHORT(&new->len), - SILC_STR_END); + ret = silc_buffer_unformat(buffer, + SILC_STR_UI_SHORT(&new->type), + SILC_STR_UI_SHORT(&new->len), + SILC_STR_END); + if (ret == -1) + goto err; silc_buffer_pull(buffer, 4); if (new->len > buffer->len) goto err; - silc_buffer_unformat(buffer, - SILC_STR_UI_XNSTRING_ALLOC(&new->id, new->len), - SILC_STR_END); + ret = silc_buffer_unformat(buffer, + SILC_STR_UI_XNSTRING_ALLOC(&new->id, new->len), + SILC_STR_END); + if (ret == -1) + goto err; + silc_buffer_push(buffer, 4); return new; @@ -71,75 +77,79 @@ SilcIDPayload silc_id_payload_parse(SilcBuffer buffer) /* Parses data and return ID payload into payload structure. */ SilcIDPayload silc_id_payload_parse_data(unsigned char *data, - unsigned int len) + uint32 len) { SilcIDPayload new; - SilcBuffer buffer; + SilcBufferStruct buffer; + int ret; SILC_LOG_DEBUG(("Parsing ID payload")); - buffer = silc_buffer_alloc(len); - silc_buffer_pull_tail(buffer, SILC_BUFFER_END(buffer)); - silc_buffer_put(buffer, data, len); + silc_buffer_set(&buffer, data, len); new = silc_calloc(1, sizeof(*new)); - silc_buffer_unformat(buffer, - SILC_STR_UI_SHORT(&new->type), - SILC_STR_UI_SHORT(&new->len), - SILC_STR_END); + ret = silc_buffer_unformat(&buffer, + SILC_STR_UI_SHORT(&new->type), + SILC_STR_UI_SHORT(&new->len), + SILC_STR_END); + if (ret == -1) + goto err; - silc_buffer_pull(buffer, 4); + silc_buffer_pull(&buffer, 4); - if (new->len > buffer->len) + if (new->len > buffer.len) goto err; - silc_buffer_unformat(buffer, - SILC_STR_UI_XNSTRING_ALLOC(&new->id, new->len), - SILC_STR_END); + ret = silc_buffer_unformat(&buffer, + SILC_STR_UI_XNSTRING_ALLOC(&new->id, new->len), + SILC_STR_END); + if (ret == -1) + goto err; - silc_buffer_free(buffer); return new; err: - silc_buffer_free(buffer); silc_free(new); return NULL; } /* Return the ID directly from the raw payload data. */ -void *silc_id_payload_parse_id(unsigned char *data, unsigned int len) +void *silc_id_payload_parse_id(unsigned char *data, uint32 len) { - SilcBuffer buffer; + SilcBufferStruct buffer; SilcIdType type; - unsigned short idlen; - unsigned char *id; - - buffer = silc_buffer_alloc(len); - silc_buffer_pull_tail(buffer, SILC_BUFFER_END(buffer)); - silc_buffer_put(buffer, data, len); - - silc_buffer_unformat(buffer, - SILC_STR_UI_SHORT(&type), - SILC_STR_UI_SHORT(&idlen), - SILC_STR_END); + uint16 idlen; + unsigned char *id_data = NULL; + int ret; + void *id; + + silc_buffer_set(&buffer, data, len); + + ret = silc_buffer_unformat(&buffer, + SILC_STR_UI_SHORT(&type), + SILC_STR_UI_SHORT(&idlen), + SILC_STR_END); + if (ret == -1) + goto err; - silc_buffer_pull(buffer, 4); + silc_buffer_pull(&buffer, 4); - if (idlen > buffer->len) + if (idlen > buffer.len) goto err; - silc_buffer_unformat(buffer, - SILC_STR_UI_XNSTRING_ALLOC(&id, idlen), - SILC_STR_END); - - silc_buffer_free(buffer); + ret = silc_buffer_unformat(&buffer, + SILC_STR_UI_XNSTRING_ALLOC(&id_data, idlen), + SILC_STR_END); + if (ret == -1) + goto err; - return silc_id_str2id(id, type); + id = silc_id_str2id(id_data, idlen, type); + silc_free(id_data); + return id; err: - silc_buffer_free(buffer); return NULL; } @@ -149,12 +159,14 @@ SilcBuffer silc_id_payload_encode(void *id, SilcIdType type) { SilcBuffer buffer; unsigned char *id_data; - unsigned int len; + uint32 len; - SILC_LOG_DEBUG(("Parsing ID payload")); + SILC_LOG_DEBUG(("Encoding %s ID payload", + type == SILC_ID_CLIENT ? "Client" : + type == SILC_ID_SERVER ? "Server" : "Channel")); id_data = silc_id_id2str(id, type); - len = silc_id_get_len(type); + len = silc_id_get_len(id, type); buffer = silc_buffer_alloc(4 + len); silc_buffer_pull_tail(buffer, SILC_BUFFER_END(buffer)); @@ -174,6 +186,7 @@ void silc_id_payload_free(SilcIDPayload payload) { if (payload) { silc_free(payload->id); + silc_free(payload); } } @@ -181,30 +194,36 @@ void silc_id_payload_free(SilcIDPayload payload) SilcIdType silc_id_payload_get_type(SilcIDPayload payload) { - return payload->type; + return payload ? payload->type : 0; } /* Get ID */ void *silc_id_payload_get_id(SilcIDPayload payload) { - return silc_id_str2id(payload->id, payload->type); + return payload ? silc_id_str2id(payload->id, payload->len, + payload->type) : NULL; } /* Get raw ID data. Data is duplicated. */ unsigned char *silc_id_payload_get_data(SilcIDPayload payload) { - unsigned char *ret = silc_calloc(payload->len, sizeof(*ret)); + unsigned char *ret; + + if (!payload) + return NULL; + + ret = silc_calloc(payload->len, sizeof(*ret)); memcpy(ret, payload->id, payload->len); return ret; } /* Get length of ID */ -unsigned int silc_id_payload_get_len(SilcIDPayload payload) +uint32 silc_id_payload_get_len(SilcIDPayload payload) { - return payload->len; + return payload ? payload->len : 0; } /****************************************************************************** @@ -214,52 +233,56 @@ unsigned int silc_id_payload_get_len(SilcIDPayload payload) ******************************************************************************/ struct SilcArgumentPayloadStruct { - unsigned int argc; + uint32 argc; unsigned char **argv; - unsigned int *argv_lens; - unsigned int *argv_types; - unsigned int pos; + uint32 *argv_lens; + uint32 *argv_types; + uint32 pos; }; /* Parses arguments and returns them into Argument Payload structure. */ SilcArgumentPayload silc_argument_payload_parse(SilcBuffer buffer, - unsigned int argc) + uint32 argc) { SilcArgumentPayload new; - unsigned short payload_len = 0; + uint16 payload_len = 0; unsigned char arg_num = 0; - unsigned int arg_type = 0; - unsigned int pull_len = 0; - int i = 0; + unsigned char arg_type = 0; + uint32 pull_len = 0; + int i = 0, ret; SILC_LOG_DEBUG(("Parsing argument payload")); new = silc_calloc(1, sizeof(*new)); new->argv = silc_calloc(argc, sizeof(unsigned char *)); - new->argv_lens = silc_calloc(argc, sizeof(unsigned int)); - new->argv_types = silc_calloc(argc, sizeof(unsigned int)); + new->argv_lens = silc_calloc(argc, sizeof(uint32)); + new->argv_types = silc_calloc(argc, sizeof(uint32)); /* Get arguments */ arg_num = 1; for (i = 0; i < argc; i++) { - silc_buffer_unformat(buffer, - SILC_STR_UI_SHORT(&payload_len), - SILC_STR_UI_CHAR(&arg_type), - SILC_STR_END); + ret = silc_buffer_unformat(buffer, + SILC_STR_UI_SHORT(&payload_len), + SILC_STR_UI_CHAR(&arg_type), + SILC_STR_END); + if (ret == -1) + goto err; new->argv_lens[i] = payload_len; new->argv_types[i] = arg_type; - if (payload_len > buffer->len) + if (payload_len > buffer->len - 3) break; /* Get argument data */ silc_buffer_pull(buffer, 3); - silc_buffer_unformat(buffer, - SILC_STR_UI_XNSTRING_ALLOC(&new->argv[i], - payload_len), - SILC_STR_END); + ret = silc_buffer_unformat(buffer, + SILC_STR_UI_XNSTRING_ALLOC(&new->argv[i], + payload_len), + SILC_STR_END); + if (ret == -1) + goto err; silc_buffer_pull(buffer, payload_len); pull_len += 3 + payload_len; @@ -295,13 +318,13 @@ SilcArgumentPayload silc_argument_payload_parse(SilcBuffer buffer, /* Encodes arguments in to Argument Paylods returning them to SilcBuffer. */ -SilcBuffer silc_argument_payload_encode(unsigned int argc, +SilcBuffer silc_argument_payload_encode(uint32 argc, unsigned char **argv, - unsigned int *argv_lens, - unsigned int *argv_types) + uint32 *argv_lens, + uint32 *argv_types) { SilcBuffer buffer; - unsigned int len; + uint32 len; int i; SILC_LOG_DEBUG(("Encoding Argument payload")); @@ -334,7 +357,7 @@ SilcBuffer silc_argument_payload_encode(unsigned int argc, SilcBuffer silc_argument_payload_encode_payload(SilcArgumentPayload payload) { SilcBuffer buffer; - unsigned int len; + uint32 len; int i; SILC_LOG_DEBUG(("Encoding Argument payload")); @@ -362,57 +385,7 @@ SilcBuffer silc_argument_payload_encode_payload(SilcArgumentPayload payload) return buffer; } -#if 0 -/* Encodes Argument payload with variable argument list. The arguments - must be: unsigned int, unsigned char *, unsigned int, ... One - {unsigned int, unsigned char * and unsigned int} forms one argument, - thus `argc' in case when sending one {unsigned int, unsigned char * - and unsigned int} equals one (1) and when sending two of those it - equals two (2), and so on. This has to be preserved or bad things - will happen. The variable arguments is: {type, data, data_len}. */ - -SilcBuffer silc_command_encode_payload_va(unsigned int argc, ...) -{ - va_list ap; - unsigned char **argv; - unsigned int *argv_lens = NULL, *argv_types = NULL; - unsigned char *x; - unsigned int x_len; - unsigned int x_type; - SilcBuffer buffer; - int i; - - va_start(ap, argc); - - argv = silc_calloc(argc, sizeof(unsigned char *)); - argv_lens = silc_calloc(argc, sizeof(unsigned int)); - argv_types = silc_calloc(argc, sizeof(unsigned int)); - - for (i = 0; i < argc; i++) { - x_type = va_arg(ap, unsigned int); - x = va_arg(ap, unsigned char *); - x_len = va_arg(ap, unsigned int); - - argv[i] = silc_calloc(x_len + 1, sizeof(unsigned char)); - memcpy(argv[i], x, x_len); - argv_lens[i] = x_len; - argv_types[i] = x_type; - } - - buffer = silc_argument_payload_encode(argc, argv, - argv_lens, argv_types); - - for (i = 0; i < argc; i++) - silc_free(argv[i]); - silc_free(argv); - silc_free(argv_lens); - silc_free(argv_types); - - return buffer; -} -#endif - -/* Free's Command Payload */ +/* Frees Argument Payload */ void silc_argument_payload_free(SilcArgumentPayload payload) { @@ -423,22 +396,27 @@ void silc_argument_payload_free(SilcArgumentPayload payload) silc_free(payload->argv[i]); silc_free(payload->argv); + silc_free(payload->argv_lens); + silc_free(payload->argv_types); silc_free(payload); } } /* Returns number of arguments in payload */ -unsigned int silc_argument_get_arg_num(SilcArgumentPayload payload) +uint32 silc_argument_get_arg_num(SilcArgumentPayload payload) { - return payload->argc; + return payload ? payload->argc : 0; } /* Returns first argument from payload. */ unsigned char *silc_argument_get_first_arg(SilcArgumentPayload payload, - unsigned int *ret_len) + uint32 *ret_len) { + if (!payload) + return NULL; + payload->pos = 0; if (ret_len) @@ -450,8 +428,11 @@ unsigned char *silc_argument_get_first_arg(SilcArgumentPayload payload, /* Returns next argument from payload or NULL if no more arguments. */ unsigned char *silc_argument_get_next_arg(SilcArgumentPayload payload, - unsigned int *ret_len) + uint32 *ret_len) { + if (!payload) + return NULL; + if (payload->pos >= payload->argc) return NULL; @@ -464,11 +445,14 @@ unsigned char *silc_argument_get_next_arg(SilcArgumentPayload payload, /* Returns argument which type is `type'. */ unsigned char *silc_argument_get_arg_type(SilcArgumentPayload payload, - unsigned int type, - unsigned int *ret_len) + uint32 type, + uint32 *ret_len) { int i; + if (!payload) + return NULL; + for (i = 0; i < payload->argc; i++) if (payload->argv_types[i] == type) break;