#include "silc.h"
#include "silcargument.h"
-/******************************************************************************
-
- Argument Payload
-
-******************************************************************************/
+/*************************** Argument Payload *******************************/
struct SilcArgumentPayloadStruct {
SilcUInt32 argc;
/* 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));
}
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;
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;
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);
+}
*
* 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
*
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 */