From: Pekka Riikonen Date: Fri, 24 Nov 2006 14:47:03 +0000 (+0000) Subject: Added argument list payload parsing. X-Git-Tag: silc.client.1.1.beta1~179 X-Git-Url: http://git.silcnet.org/gitweb/?p=silc.git;a=commitdiff_plain;h=d5559734ec6a879397687380aa2b13ed1ed1bd8b Added argument list payload parsing. --- diff --git a/lib/silccore/silcargument.c b/lib/silccore/silcargument.c index 18446fbe..aae2a6ef 100644 --- a/lib/silccore/silcargument.c +++ b/lib/silccore/silcargument.c @@ -22,11 +22,7 @@ #include "silc.h" #include "silcargument.h" -/****************************************************************************** - - Argument Payload - -******************************************************************************/ +/*************************** Argument Payload *******************************/ struct SilcArgumentPayloadStruct { SilcUInt32 argc; @@ -300,29 +296,22 @@ unsigned char *silc_argument_get_arg_type(SilcArgumentPayload payload, /* Return argument already decoded */ -SilcBool silc_argument_get_decoded(SilcArgumentPayload payload, - SilcUInt32 type, - SilcArgumentDecodeType dec_type, - void *ret_arg, - void **ret_arg_alloc) +static SilcBool silc_argument_decode(unsigned char *data, + SilcUInt32 data_len, + SilcArgumentDecodeType dec_type, + void *ret_arg, + void **ret_arg_alloc) { - unsigned char *tmp; - SilcUInt32 tmp_len; - - tmp = silc_argument_get_arg_type(payload, type, &tmp_len); - if (!tmp) - return FALSE; - switch (dec_type) { case SILC_ARGUMENT_ID: if (ret_arg) - if (!silc_id_payload_parse_id(tmp, tmp_len, (SilcID *)ret_arg)) + if (!silc_id_payload_parse_id(data, data_len, (SilcID *)ret_arg)) return FALSE; if (ret_arg_alloc) { SilcID id; - if (!silc_id_payload_parse_id(tmp, tmp_len, &id)) + if (!silc_id_payload_parse_id(data, data_len, &id)) return FALSE; *ret_arg_alloc = silc_memdup(&id, sizeof(id)); } @@ -335,7 +324,7 @@ SilcBool silc_argument_get_decoded(SilcArgumentPayload payload, if (!ret_arg_alloc) return FALSE; - if (!silc_public_key_payload_decode(tmp, tmp_len, &public_key)) + if (!silc_public_key_payload_decode(data, data_len, &public_key)) return FALSE; *ret_arg_alloc = public_key; @@ -346,37 +335,37 @@ SilcBool silc_argument_get_decoded(SilcArgumentPayload payload, if (!ret_arg_alloc) return FALSE; - *ret_arg_alloc = silc_attribute_payload_parse(tmp, tmp_len); + *ret_arg_alloc = silc_attribute_payload_parse(data, data_len); break; case SILC_ARGUMENT_UINT32: - if (tmp_len != 4) + if (data_len != 4) return FALSE; if (ret_arg) { SilcUInt32 *i = ret_arg; - SILC_GET32_MSB(*i, tmp); + SILC_GET32_MSB(*i, data); } if (ret_arg_alloc) { SilcUInt32 i; - SILC_GET32_MSB(i, tmp); + SILC_GET32_MSB(i, data); *ret_arg_alloc = silc_memdup(&i, sizeof(i)); } break; case SILC_ARGUMENT_BOOL: - if (tmp_len != 1) + if (data_len != 1) return FALSE; if (ret_arg) { SilcBool *b = ret_arg; - *b = (tmp[0] == 0x01 ? TRUE : FALSE); + *b = (data[0] == 0x01 ? TRUE : FALSE); } if (ret_arg_alloc) { SilcBool b; - b = (tmp[0] == 0x01 ? TRUE : FALSE); + b = (data[0] == 0x01 ? TRUE : FALSE); *ret_arg_alloc = silc_memdup(&b, sizeof(b)); } break; @@ -387,3 +376,122 @@ SilcBool silc_argument_get_decoded(SilcArgumentPayload payload, return TRUE; } + +/* Return argument already decoded */ + +SilcBool silc_argument_get_decoded(SilcArgumentPayload payload, + SilcUInt32 type, + SilcArgumentDecodeType dec_type, + void *ret_arg, + void **ret_arg_alloc) +{ + unsigned char *tmp; + SilcUInt32 tmp_len; + + tmp = silc_argument_get_arg_type(payload, type, &tmp_len); + if (!tmp) + return FALSE; + + return silc_argument_decode(tmp, tmp_len, dec_type, ret_arg, ret_arg_alloc); +} + +/************************* Argument List Payload ****************************/ + +/* Parses argument payload list */ + +SilcArgumentPayload +silc_argument_list_parse(const unsigned char *payload, + SilcUInt32 payload_len) +{ + SilcArgumentPayload arg; + SilcUInt16 argc; + + if (payload_len < 5) + return NULL; + + SILC_GET16_MSB(argc, payload); + + arg = silc_argument_payload_parse(payload + 2, payload_len - 2, argc); + + return arg; +} + +/* Parses argument payload list of specific argument types */ + +SilcDList +silc_argument_list_parse_decoded(const unsigned char *payload, + SilcUInt32 payload_len, + SilcArgumentDecodeType dec_type) +{ + SilcArgumentPayload arg; + SilcArgumentDecodedList dec; + unsigned char *data; + SilcUInt32 data_len, type; + SilcDList list; + + arg = silc_argument_list_parse(payload, payload_len); + if (!arg) + return NULL; + + list = silc_dlist_init(); + if (!list) { + silc_argument_payload_free(arg); + return NULL; + } + + data = silc_argument_get_first_arg(arg, &type, &data_len); + while (data) { + dec = silc_calloc(1, sizeof(*dec)); + if (!dec) + continue; + dec->arg_type = type; + if (silc_argument_decode(data, data_len, dec_type, NULL, &dec->argument)) + silc_dlist_add(list, dec); + else + silc_free(dec); + data = silc_argument_get_next_arg(arg, &type, &data_len); + } + + silc_argument_payload_free(arg); + + silc_dlist_start(list); + + return list; +} + +/* Free decoded argument payload list */ + +void silc_argument_list_free(SilcDList list, SilcArgumentDecodeType dec_type) +{ + SilcArgumentDecodedList dec; + + if (!list) + return; + + silc_dlist_start(list); + while ((dec = silc_dlist_get(list))) { + switch (dec_type) { + + case SILC_ARGUMENT_ID: + case SILC_ARGUMENT_UINT32: + case SILC_ARGUMENT_BOOL: + silc_free(dec->argument); + break; + + case SILC_ARGUMENT_PUBLIC_KEY: + silc_pkcs_public_key_free(dec->argument); + break; + + case SILC_ARGUMENT_ATTRIBUTES: + silc_attribute_payload_free(dec->argument); + break; + + default: + break; + } + + silc_free(dec); + } + + silc_dlist_uninit(list); +} diff --git a/lib/silccore/silcargument.h b/lib/silccore/silcargument.h index 24eb2809..cde339f1 100644 --- a/lib/silccore/silcargument.h +++ b/lib/silccore/silcargument.h @@ -21,13 +21,13 @@ * * DESCRIPTION * - * Implementation of the Argument Payload, that is used to include - * argument to other payload that needs arguments. + * Implementations of the Argument Payload and Argument List Payload, that + * is used to include arguments to other payload that needs arguments. * ***/ -#ifndef SILCPAYLOAD_H -#define SILCPAYLOAD_H +#ifndef SILCARGUMENT_H +#define SILCARGUMENT_H /****s* silccore/SilcArgumentAPI/SilcArgumentPayload * @@ -277,4 +277,77 @@ SilcBool silc_argument_get_decoded(SilcArgumentPayload payload, void *ret_arg, void **ret_arg_alloc); -#endif +/****f* silccore/SilcArgumentAPI/silc_argument_list_parse + * + * SYNOPSIS + * + * SilcArgumentPayload + * silc_argument_list_parse(const unsigned char *payload, + * SilcUInt32 payload_len); + * + * DESCRIPTION + * + * Parses argument list payload. Returns parsed SilcArgumentPayload which + * contains all the arguments from the list. The caller must free the + * returned context with silc_argument_payload_free. + * + ***/ +SilcArgumentPayload +silc_argument_list_parse(const unsigned char *payload, SilcUInt32 payload_len); + +/****s* silccore/SilcArgumentAPI/SilcArgumentDecodedList + * + * NAME + * + * typedef struct { ... } *SilcArgumentDecodedList; + * + * DESCRIPTION + * + * This structure is in the list returned by the function + * silc_argument_list_payload_parse_decoded. The caller is responsible + * of freeing the contents of the structure and the structure itself. + * + ***/ +typedef struct { + void *argument; /* Decoded argument, caller must know its type */ + SilcUInt32 arg_type; /* Argument type from the payload */ +} *SilcArgumentDecodedList; + +/****f* silccore/SilcArgumentAPI/silc_argument_list_parse_decoded + * + * SYNOPSIS + * + * SilcDList + * silc_argument_list_parse_decoded(const unsigned char *payload, + * SilcUInt32 payload_len, + * SilcArgumentDecodeType dec_type); + * + * DESCRIPTION + * + * Parses argument list payload of arguments of the type `dec_type'. + * The returned list includes the already decoded arguments. The caller + * is responsible of freeing the the contents of the list and the list + * itself. Each entry in the list is SilcArgumentDecodedList. The + * caller must free the returned list with silc_argument_list_free. + * + ***/ +SilcDList +silc_argument_list_parse_decoded(const unsigned char *payload, + SilcUInt32 payload_len, + SilcArgumentDecodeType dec_type); + +/****f* silccore/SilcArgumentAPI/silc_argument_list_free + * + * SYNOPSIS + * + * void + * silc_argument_list_free(SilcDList list, SilcArgumentDecodeType dec_type); + * + * DESCRIPTION + * + * Free's the decoded argument list and its contents. + * + ***/ +void silc_argument_list_free(SilcDList list, SilcArgumentDecodeType dec_type); + +#endif /* SILCARGUMENT_H */