- defined all substructures for a SA payload
authorJan Hutter <jhutter@hsr.ch>
Mon, 14 Nov 2005 12:04:06 +0000 (12:04 -0000)
committerJan Hutter <jhutter@hsr.ch>
Mon, 14 Nov 2005 12:04:06 +0000 (12:04 -0000)
Source/charon/payloads/encodings.c
Source/charon/payloads/encodings.h
Source/charon/payloads/payload.h
Source/charon/payloads/proposal_substructure.c
Source/charon/payloads/proposal_substructure.h
Source/charon/payloads/sa_payload.c
Source/charon/payloads/sa_payload.h
Source/charon/payloads/transform_attribute.c [new file with mode: 0644]
Source/charon/payloads/transform_attribute.h [new file with mode: 0644]
Source/charon/payloads/transform_substructure.c [new file with mode: 0644]
Source/charon/payloads/transform_substructure.h [new file with mode: 0644]

index 5662a8c..646884c 100644 (file)
@@ -40,5 +40,11 @@ mapping_t encoding_type_t_mappings[] = {
        {SPI, "SPI"},
        {PROPOSALS, "PROPOSALS"},
        {TRANSFORMS, "TRANSFORMS"},
+       {TRANSFORM_ATTRIBUTES, "TRANSFORM_ATTRIBUTES"},
+       {ATTRIBUTE_FORMAT, "ATTRIBUTE_FORMAT"},
+       {ATTRIBUTE_TYPE, "ATTRIBUTE_TYPE"},
+       {ATTRIBUTE_LENGTH_OR_VALUE, "ATTRIBUTE_LENGTH_OR_VALUE"},
+       {ATTRIBUTE_VALUE, "ATTRIBUTE_VALUE"},
        {MAPPING_END, NULL}
 };
+
index e3db108..f2f6ac2 100644 (file)
@@ -213,7 +213,72 @@ enum encoding_type_e{
         * When parsing the parsed transform_substructure_t objects have 
         * to be stored in the pointed linked_list.
         */     
-       TRANSFORMS
+       TRANSFORMS,
+       /**
+        * Representating one or more Attributes of a transform substructure
+        * 
+        * The offset points to a linked_list_t pointer.
+        * 
+        * When generating the transform_attribute_t objects are stored 
+        * in the pointed linked_list.
+        * 
+        * When parsing the parsed transform_attribute_t objects have 
+        * to be stored in the pointed linked_list.
+        */     
+       TRANSFORM_ATTRIBUTES,
+       /**
+        * Representing a 1 Bit flag specifying the format of a transform attribute.
+        * 
+        * When generation, the next bit is set to 1 if the associated value 
+        * in the data struct is TRUE, 0 otherwise. The current write position 
+        * is moved 1 bit forward afterwards.
+        *
+        * When parsing, the next bit is read and stored in the associated data 
+        * struct. 0 means FALSE, 1 means TRUE, The current read pointer 
+        * is moved 1 bit forward afterwards.
+        */
+       ATTRIBUTE_FORMAT,
+       /**
+        * Representing a 15 Bit unsigned int value used as attribute type 
+        * in an attribute transform
+        * 
+        * 
+        * When generating it must be changed from host to network order.
+        * The value is read from the associated data struct.
+        * The current write position is moved 15 bit forward afterwards.
+        * 
+        * When parsing it must be changed from network to host order.
+        * The value is written to the associated data struct.
+        * The current read pointer is moved 15 bit forward afterwards.
+        */
+       ATTRIBUTE_TYPE,
+
+       /**
+        * Depending on the field of type ATTRIBUTE_FORMAT
+        * this field contains the length or the value of an transform attribute.
+        * Its stored in a 16 unsigned integer field
+        * 
+        * When generating it must be changed from host to network order.
+        * The value is read from the associated data struct.
+        * The current write position is moved 16 bit forward afterwards.
+        * 
+        * When parsing it must be changed from network to host order.
+        * The value is written to the associated data struct.
+        * The current read pointer is moved 16 bit forward afterwards.
+        */
+       ATTRIBUTE_LENGTH_OR_VALUE,
+
+       /*      
+        * Depending on the field of type ATTRIBUTE_FORMAT
+        * this field is available or missing and so parsed/generated 
+        * or not parsed/not generated
+        * 
+        * When generating the content of the chunkt pointing to 
+        * is written.
+        * 
+        * When parsing SPI_SIZE bytes are read and written into the chunk pointing to.
+        */
+       ATTRIBUTE_VALUE
 };
 
 /**
index 0749a65..f7b36fc 100644 (file)
@@ -133,6 +133,14 @@ enum payload_type_e{
         * used internally to handle a transform substructure like a payload.
         */
        TRANSFORM_SUBSTRUCTURE = 142,
+       
+       /**
+        * TRANSFORM_ATTRIBUTE has a value of PRIVATE USE space
+        * 
+        * This payload type is not send over wire and just 
+        * used internally to handle a transform attribute like a payload.
+        */
+       TRANSFORM_ATTRIBUTE = 143,
 };
 
 
index 509e2bc..282538b 100644 (file)
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
  */
  /* offsetof macro */
 #include <stddef.h>
 
 #include "proposal_substructure.h"
 
 #include "encodings.h"
+#include "transform_substructure.h"
 #include "../types.h"
 #include "../utils/allocator.h"
 #include "../utils/linked_list.h"
@@ -98,7 +100,7 @@ encoding_rule_t proposal_substructure_encodings[] = {
        { U_INT_8,                      offsetof(private_proposal_substructure_t, next_payload)                         },
        /* Reserved Byte is skipped */
        { RESERVED_BYTE,                0                                                                                                                               },      
-       /* Length of the whole SA payload*/
+       /* Length of the whole proposal substructure payload*/
        { PAYLOAD_LENGTH,               offsetof(private_proposal_substructure_t, proposal_length)      },      
        /* proposal number is a number of 8 bit */
        { U_INT_8,                              offsetof(private_proposal_substructure_t, proposal_number)      },      
@@ -124,7 +126,7 @@ static status_t destroy(private_proposal_substructure_t *this)
        /* all proposals are getting destroyed */ 
        while (this->transforms->get_count(this->transforms) > 0)
        {
-               transforms_substructure_t *current_transform;
+               transform_substructure_t *current_transform;
                if (this->transforms->remove_last(this->transforms,(void **)&current_transform) != SUCCESS)
                {
                        break;
@@ -182,6 +184,24 @@ static size_t get_length(private_proposal_substructure_t *this)
        return this->proposal_length;
 }
 
+/**
+ * Implements proposal_substructure_t's create_transform_substructure_iterator function.
+ * See #proposal_substructure_s.create_transform_substructure_iterator for description.
+ */
+static status_t create_transform_substructure_iterator (private_proposal_substructure_t *this,linked_list_iterator_t **iterator,bool forward)
+{
+       return (this->transforms->create_iterator(this->transforms,iterator,forward));
+}
+
+/**
+ * Implements proposal_substructure_t's add_transform_substructure function.
+ * See #proposal_substructure_s.add_transform_substructure for description.
+ */
+static status_t add_transform_substructure (private_proposal_substructure_t *this,transform_substructure_t *transform)
+{
+       return (this->transforms->insert_last(this->transforms,(void *) transform));
+}
+
 /*
  * Described in header
  */
@@ -198,6 +218,8 @@ proposal_substructure_t *proposal_substructure_create()
        this->public.payload_interface.get_next_type = (payload_type_t (*) (payload_t *)) get_next_type;
        this->public.payload_interface.get_type = (payload_type_t (*) (payload_t *)) get_type;
        this->public.payload_interface.destroy = (status_t (*) (payload_t *))destroy;
+       this->public.create_transform_substructure_iterator = (status_t (*) (proposal_substructure_t *,linked_list_iterator_t **,bool)) create_transform_substructure_iterator;
+       this->public.add_transform_substructure = (status_t (*) (proposal_substructure_t *,transform_substructure_t *)) add_transform_substructure;
        this->public.destroy = (status_t (*) (proposal_substructure_t *)) destroy;
        
        /* set default values of the fields */
@@ -219,5 +241,3 @@ proposal_substructure_t *proposal_substructure_create()
        }
        return (&(this->public));
 }
-
-
index 2d1731c..9146bc8 100644 (file)
 #ifndef PROPOSAL_SUBSTRUCTURE_H_
 #define PROPOSAL_SUBSTRUCTURE_H_
 
-
 #include "../types.h"
 #include "payload.h"
+#include "../utils/linked_list.h"
+#include "transform_substructure.h"
 
 /**
  * Object representing an IKEv2- PROPOSAL SUBSTRUCTURE
@@ -42,8 +43,35 @@ struct proposal_substructure_s {
         * implements payload_t interface
         */
        payload_t payload_interface;
+
+       /**
+        * @brief Creates an iterator of stored transform_substructure_t objects.
+        * 
+        * @warning The created iterator has to get destroyed by the caller!
+        *
+        * @param this                  calling proposal_substructure_t object
+        * @param iterator              the created iterator is stored at the pointed pointer
+        * @param[in] forward   iterator direction (TRUE: front to end)
+        * @return              
+        *                                              - SUCCESS or
+        *                                              - OUT_OF_RES if iterator could not be created
+        */
+       status_t (*create_transform_substructure_iterator) (proposal_substructure_t *this,linked_list_iterator_t **iterator, bool forward);
        
        /**
+        * @brief Adds a transform_substructure_t object to this object.
+        * 
+        * @warning The added transform_substructure_t object  is 
+        *                      getting destroyed in destroy function of proposal_substructure_t.
+        *
+        * @param this          calling proposal_substructure_t object
+        * @param transform transform_substructure_t object to add
+        * @return                      - SUCCESS if succeeded
+        *                                      - FAILED otherwise
+        */
+       status_t (*add_transform_substructure) (proposal_substructure_t *this,transform_substructure_t *transform);
+
+       /**
         * @brief Destroys an proposal_substructure_t object.
         *
         * @param this  proposal_substructure_t object to destroy
index a58570c..34c75a2 100644 (file)
@@ -155,6 +155,24 @@ static size_t get_length(private_sa_payload_t *this)
        return this->payload_length;
 }
 
+/**
+ * Implements sa_payload_t's create_proposal_substructure_iterator function.
+ * See #sa_payload_s.create_proposal_substructure_iterator for description.
+ */
+static status_t create_proposal_substructure_iterator (private_sa_payload_t *this,linked_list_iterator_t **iterator,bool forward)
+{
+       return (this->proposals->create_iterator(this->proposals,iterator,forward));
+}
+
+/**
+ * Implements sa_payload_t's add_proposal_substructure function.
+ * See #sa_payload_s.add_proposal_substructure for description.
+ */
+static status_t add_proposal_substructure (private_sa_payload_t *this,proposal_substructure_t *proposal)
+{
+       return (this->proposals->insert_last(this->proposals,(void *) proposal));
+}
+
 /*
  * Described in header
  */
@@ -171,6 +189,8 @@ sa_payload_t *sa_payload_create()
        this->public.payload_interface.get_next_type = (payload_type_t (*) (payload_t *)) get_next_type;
        this->public.payload_interface.get_type = (payload_type_t (*) (payload_t *)) get_type;
        this->public.payload_interface.destroy = (status_t (*) (payload_t *))destroy;
+       this->public.create_proposal_substructure_iterator = (status_t (*) (sa_payload_t *,linked_list_iterator_t **,bool)) create_proposal_substructure_iterator;
+       this->public.add_proposal_substructure = (status_t (*) (sa_payload_t *,proposal_substructure_t *)) add_proposal_substructure;
        this->public.destroy = (status_t (*) (sa_payload_t *)) destroy;
        
        /* set default values of the fields */
index d53c259..51f2834 100644 (file)
@@ -29,6 +29,7 @@
 #include "../types.h"
 #include "payload.h"
 #include "proposal_substructure.h"
+#include "../utils/linked_list.h"
 
 /**
  * Critical flag must not be set
@@ -55,6 +56,33 @@ struct sa_payload_s {
        payload_t payload_interface;
        
        /**
+        * @brief Creates an iterator of stored proposal_substructure_t objects.
+        * 
+        * @warning The created iterator has to get destroyed by the caller!
+        *
+        * @param this                  calling sa_payload_t object
+        * @param iterator              the created iterator is stored at the pointed pointer
+        * @param[in] forward   iterator direction (TRUE: front to end)
+        * @return              
+        *                                              - SUCCESS or
+        *                                              - OUT_OF_RES if iterator could not be created
+        */
+       status_t (*create_proposal_substructure_iterator) (sa_payload_t *this,linked_list_iterator_t **iterator, bool forward);
+       
+       /**
+        * @brief Adds a proposal_substructure_t object to this object.
+        * 
+        * @warning The added proposal_substructure_t object  is 
+        *                      getting destroyed in destroy function of sa_payload_t.
+        *
+        * @param this          calling sa_payload_t object
+        * @param proposal  proposal_substructure_t object to add
+        * @return                      - SUCCESS if succeeded
+        *                                      - FAILED otherwise
+        */
+       status_t (*add_proposal_substructure) (sa_payload_t *this,proposal_substructure_t *proposal);
+
+       /**
         * @brief Destroys an sa_payload_t object.
         *
         * @param this  sa_payload_t object to destroy
diff --git a/Source/charon/payloads/transform_attribute.c b/Source/charon/payloads/transform_attribute.c
new file mode 100644 (file)
index 0000000..1681eb5
--- /dev/null
@@ -0,0 +1,175 @@
+/**
+ * @file transform_attribute.c
+ * 
+ * @brief Declaration of the class transform_attribute_t. 
+ * 
+ * An object of this type represents an IKEv2 TRANSFORM attribute.
+ * 
+ */
+
+/*
+ * Copyright (C) 2005 Jan Hutter, Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+/* offsetof macro */
+#include <stddef.h>
+
+#include "transform_attribute.h"
+
+#include "encodings.h"
+#include "../types.h"
+#include "../utils/allocator.h"
+
+/**
+ * Private data of an transform_attribute_t Object
+ * 
+ */
+typedef struct private_transform_attribute_s private_transform_attribute_t;
+
+struct private_transform_attribute_s {
+       /**
+        * public transform_attribute_t interface
+        */
+       transform_attribute_t public;
+       
+       /**
+        * Attribute Format Flag
+        * 
+        * - TRUE means value is stored in attribute_length_or_value
+        * - FALSE means value is stored in attribute_value
+        */
+       bool attribute_format;
+       
+       /**
+        * Type of the attribute
+        */
+       u_int16_t attribute_type;
+       
+       /**
+        * Attribute Length if attribute_format is 0, attribute Value otherwise
+        */
+       u_int8_t         attribute_length_or_value;
+       
+       /**
+        * Attribute value as chunk if attribute_format is 0 (FALSE)
+        */
+       chunk_t attribute_value;
+};
+
+
+/**
+ * Encoding rules to parse or generate a Transform attribute
+ * 
+ * The defined offsets are the positions in a object of type 
+ * private_transform_attribute_t.
+ * 
+ */
+encoding_rule_t transform_attribute_encodings[] = {
+       /* Flag defining the format of this payload */
+       { ATTRIBUTE_FORMAT,                     offsetof(private_transform_attribute_t, attribute_format)                       },
+       /* type of the attribute as 15 bit unsigned integer */
+       { ATTRIBUTE_TYPE,                       offsetof(private_transform_attribute_t, attribute_type)                         },      
+       /* Length or value, depending on the attribute format flag */
+       { ATTRIBUTE_LENGTH_OR_VALUE,    offsetof(private_transform_attribute_t, attribute_length_or_value)      },
+       /* Value of attribute if attribute format flag is zero */
+       { ATTRIBUTE_VALUE,                      offsetof(private_transform_attribute_t, attribute_value)                        }
+};
+
+/**
+ * Implements payload_t's and transform_attribute_t's destroy function.
+ * See #payload_s.destroy or transform_attribute_s.destroy for description.
+ */
+static status_t destroy(private_transform_attribute_t *this)
+{
+       if (this->attribute_value.ptr != NULL)
+       {
+               allocator_free(this->attribute_value.ptr);
+       }       
+       allocator_free(this);
+       
+       return SUCCESS;
+}
+
+/**
+ * Implements payload_t's get_encoding_rules function.
+ * See #payload_s.get_encoding_rules for description.
+ */
+static status_t get_encoding_rules(private_transform_attribute_t *this, encoding_rule_t **rules, size_t *rule_count)
+{
+       *rules = transform_attribute_encodings;
+       *rule_count = sizeof(transform_attribute_encodings) / sizeof(encoding_rule_t);
+       
+       return SUCCESS;
+}
+
+/**
+ * Implements payload_t's get_type function.
+ * See #payload_s.get_type for description.
+ */
+static payload_type_t get_type(private_transform_attribute_t *this)
+{
+       return TRANSFORM_ATTRIBUTE;
+}
+
+/**
+ * Implements payload_t's get_next_type function.
+ * See #payload_s.get_next_type for description.
+ */
+static payload_type_t get_next_type(private_transform_attribute_t *this)
+{
+       return (NO_PAYLOAD);
+}
+
+/**
+ * Implements payload_t's get_length function.
+ * See #payload_s.get_length for description.
+ */
+static size_t get_length(private_transform_attribute_t *this)
+{
+       if (this->attribute_format == TRUE)
+       {
+               /*Attribute size is only 4 byte */
+               return 4;
+       }
+       return (this->attribute_length_or_value + 4);
+}
+
+/*
+ * Described in header
+ */
+transform_attribute_t *transform_attribute_create()
+{
+       private_transform_attribute_t *this = allocator_alloc_thing(private_transform_attribute_t);
+       if (this == NULL)
+       {
+               return NULL;    
+       }       
+       
+       this->public.payload_interface.get_encoding_rules = (status_t (*) (payload_t *, encoding_rule_t **, size_t *) ) get_encoding_rules;
+       this->public.payload_interface.get_length = (size_t (*) (payload_t *)) get_length;
+       this->public.payload_interface.get_next_type = (payload_type_t (*) (payload_t *)) get_next_type;
+       this->public.payload_interface.get_type = (payload_type_t (*) (payload_t *)) get_type;
+       this->public.payload_interface.destroy = (status_t (*) (payload_t *))destroy;
+       this->public.destroy = (status_t (*) (transform_attribute_t *)) destroy;
+       
+       /* set default values of the fields */
+       this->attribute_format = TRUE;
+       this->attribute_type = 0;
+       this->attribute_length_or_value = 0;
+       this->attribute_value.ptr = NULL;
+       this->attribute_value.len = 0;
+
+       return (&(this->public));
+}
+
diff --git a/Source/charon/payloads/transform_attribute.h b/Source/charon/payloads/transform_attribute.h
new file mode 100644 (file)
index 0000000..8bfb4fd
--- /dev/null
@@ -0,0 +1,65 @@
+/**
+ * @file transform_attribute.h
+ * 
+ * @brief Declaration of the class transform_attribute_t. 
+ * 
+ * An object of this type represents an IKEv2 TRANSFORM attribute.
+ * 
+ */
+
+/*
+ * Copyright (C) 2005 Jan Hutter, Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#ifndef TRANSFORM_ATTRIBUTE_H_
+#define TRANSFORM_ATTRIBUTE_H_
+
+#include "../types.h"
+#include "payload.h"
+
+/**
+ * Object representing an IKEv2- TRANSFORM Attribute
+ * 
+ * The TRANSFORM ATTRIBUTE format is described in RFC section 3.3.5.
+ * 
+ */
+typedef struct transform_attribute_s transform_attribute_t;
+
+struct transform_attribute_s {
+       /**
+        * implements payload_t interface
+        */
+       payload_t payload_interface;
+       
+       /**
+        * @brief Destroys an transform_attribute_t object.
+        *
+        * @param this  transform_attribute_t object to destroy
+        * @return              
+        *                              SUCCESS in any case
+        */
+       status_t (*destroy) (transform_attribute_t *this);
+};
+
+/**
+ * @brief Creates an empty transform_attribute_t object
+ * 
+ * @return                     
+ *                                     - created transform_attribute_t object, or
+ *                                     - NULL if failed
+ */
+transform_attribute_t *transform_attribute_create();
+
+#endif /*TRANSFORM_ATTRIBUTE_H_*/
diff --git a/Source/charon/payloads/transform_substructure.c b/Source/charon/payloads/transform_substructure.c
new file mode 100644 (file)
index 0000000..6a302fb
--- /dev/null
@@ -0,0 +1,217 @@
+/**
+ * @file transform_substructure.h
+ * 
+ * @brief Declaration of the class transform_substructure_t. 
+ * 
+ * An object of this type represents an IKEv2 TRANSFORM Substructure and contains Attributes.
+ * 
+ */
+
+/*
+ * Copyright (C) 2005 Jan Hutter, Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+ /* offsetof macro */
+#include <stddef.h>
+
+#include "transform_substructure.h"
+
+#include "transform_attribute.h"
+#include "encodings.h"
+#include "../types.h"
+#include "../utils/allocator.h"
+#include "../utils/linked_list.h"
+
+/**
+ * Private data of an transform_substructure_t' Object
+ * 
+ */
+typedef struct private_transform_substructure_s private_transform_substructure_t;
+
+struct private_transform_substructure_s {
+       /**
+        * public transform_substructure_t interface
+        */
+       transform_substructure_t public;
+       
+       /**
+        * next payload type
+        */
+       u_int8_t  next_payload;
+
+       
+       /**
+        * Length of this payload
+        */
+       u_int16_t transform_length;
+       
+       
+       /**
+        * Type of the transform
+        */
+       u_int8_t         transform_type;
+       
+       /**
+        * Transform ID
+        */
+       u_int8_t transform_id;
+       
+       /**
+        * Transforms Attributes are stored in a linked_list_t
+        */
+       linked_list_t * attributes;
+};
+
+
+/**
+ * Encoding rules to parse or generate a Transform substructure
+ * 
+ * The defined offsets are the positions in a object of type 
+ * private_transform_substructure_t.
+ * 
+ */
+encoding_rule_t transform_substructure_encodings[] = {
+       /* 1 Byte next payload type, stored in the field next_payload */
+       { U_INT_8,                      offsetof(private_transform_substructure_t, next_payload)                },
+       /* Reserved Byte is skipped */
+       { RESERVED_BYTE,                0                                                                                                                               },      
+       /* Length of the whole transform substructure*/
+       { PAYLOAD_LENGTH,               offsetof(private_transform_substructure_t, transform_length)    },      
+       /* transform type is a number of 8 bit */
+       { U_INT_8,                              offsetof(private_transform_substructure_t, transform_type)      },      
+       /* Reserved Byte is skipped */
+       { RESERVED_BYTE,                0                                                                                                                               },      
+       /* tranform ID is a number of 8 bit */
+       { U_INT_8,                              offsetof(private_transform_substructure_t, transform_id)                },      
+       /* Attributes are stored in a transform attribute, 
+          offset points to a linked_list_t pointer */
+       { TRANSFORM_ATTRIBUTES, offsetof(private_transform_substructure_t, attributes)          }
+};
+
+/**
+ * Implements payload_t's and transform_substructure_t's destroy function.
+ * See #payload_s.destroy or transform_substructure_s.destroy for description.
+ */
+static status_t destroy(private_transform_substructure_t *this)
+{
+       /* all proposals are getting destroyed */ 
+       while (this->attributes->get_count(this->attributes) > 0)
+       {
+               transform_attribute_t *current_attribute;
+               if (this->attributes->remove_last(this->attributes,(void **)&current_attribute) != SUCCESS)
+               {
+                       break;
+               }
+               current_attribute->destroy(current_attribute);
+       }
+       this->attributes->destroy(this->attributes);
+       
+       allocator_free(this);
+       
+       return SUCCESS;
+}
+
+/**
+ * Implements payload_t's get_encoding_rules function.
+ * See #payload_s.get_encoding_rules for description.
+ */
+static status_t get_encoding_rules(private_transform_substructure_t *this, encoding_rule_t **rules, size_t *rule_count)
+{
+       *rules = transform_substructure_encodings;
+       *rule_count = sizeof(transform_substructure_encodings) / sizeof(encoding_rule_t);
+       
+       return SUCCESS;
+}
+
+/**
+ * Implements payload_t's get_type function.
+ * See #payload_s.get_type for description.
+ */
+static payload_type_t get_type(private_transform_substructure_t *this)
+{
+       return TRANSFORM_SUBSTRUCTURE;
+}
+
+/**
+ * Implements payload_t's get_next_type function.
+ * See #payload_s.get_next_type for description.
+ */
+static payload_type_t get_next_type(private_transform_substructure_t *this)
+{
+       return (this->next_payload);
+}
+
+/**
+ * Implements payload_t's get_length function.
+ * See #payload_s.get_length for description.
+ */
+static size_t get_length(private_transform_substructure_t *this)
+{
+       return this->transform_length;
+}
+
+/**
+ * Implements transform_substructure_t's create_transform_attribute_iterator function.
+ * See #transform_substructure_s.create_transform_attribute_iterator for description.
+ */
+static status_t create_transform_attribute_iterator (private_transform_substructure_t *this,linked_list_iterator_t **iterator,bool forward)
+{
+       return (this->attributes->create_iterator(this->attributes,iterator,forward));
+}
+
+/**
+ * Implements transform_substructure_t's add_transform_attribute function.
+ * See #transform_substructure_s.add_transform_attribute for description.
+ */
+static status_t add_transform_attribute (private_transform_substructure_t *this,transform_attribute_t *attribute)
+{
+       return (this->attributes->insert_last(this->attributes,(void *) attribute));
+}
+
+
+/*
+ * Described in header
+ */
+transform_substructure_t *transform_substructure_create()
+{
+       private_transform_substructure_t *this = allocator_alloc_thing(private_transform_substructure_t);
+       if (this == NULL)
+       {
+               return NULL;    
+       }       
+       
+       this->public.payload_interface.get_encoding_rules = (status_t (*) (payload_t *, encoding_rule_t **, size_t *) ) get_encoding_rules;
+       this->public.payload_interface.get_length = (size_t (*) (payload_t *)) get_length;
+       this->public.payload_interface.get_next_type = (payload_type_t (*) (payload_t *)) get_next_type;
+       this->public.payload_interface.get_type = (payload_type_t (*) (payload_t *)) get_type;
+       this->public.payload_interface.destroy = (status_t (*) (payload_t *))destroy;
+       this->public.create_transform_attribute_iterator = (status_t (*) (transform_substructure_t *,linked_list_iterator_t **,bool)) create_transform_attribute_iterator;
+       this->public.add_transform_attribute = (status_t (*) (transform_substructure_t *,transform_attribute_t *)) add_transform_attribute;
+       this->public.destroy = (status_t (*) (transform_substructure_t *)) destroy;
+       
+       /* set default values of the fields */
+       this->next_payload = NO_PAYLOAD;
+       this->transform_length = 0;
+       this->transform_id = 0;
+       this->transform_type = 0;
+
+       this->attributes = linked_list_create();
+       
+       if (this->attributes == NULL)
+       {
+               allocator_free(this);
+               return NULL;
+       }
+       return (&(this->public));
+}
diff --git a/Source/charon/payloads/transform_substructure.h b/Source/charon/payloads/transform_substructure.h
new file mode 100644 (file)
index 0000000..0454ad6
--- /dev/null
@@ -0,0 +1,94 @@
+/**
+ * @file transform_substructure.h
+ * 
+ * @brief Declaration of the class transform_substructure_t. 
+ * 
+ * An object of this type represents an IKEv2 TRANSFORM Substructure and contains Attributes.
+ * 
+ */
+
+/*
+ * Copyright (C) 2005 Jan Hutter, Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#ifndef TRANSFORM_SUBSTRUCTURE_H_
+#define TRANSFORM_SUBSTRUCTURE_H_
+
+#include "../types.h"
+#include "payload.h"
+#include "../utils/linked_list.h"
+#include "transform_attribute.h"
+
+/**
+ * Object representing an IKEv2- TRANSFORM SUBSTRUCTURE
+ * 
+ * The TRANSFORM SUBSTRUCTURE format is described in RFC section 3.3.2.
+ * 
+ */
+typedef struct transform_substructure_s transform_substructure_t;
+
+struct transform_substructure_s {
+       /**
+        * implements payload_t interface
+        */
+       payload_t payload_interface;
+       
+       /**
+        * @brief Creates an iterator of stored transform_attribute_t objects.
+        * 
+        * @warning The created iterator has to get destroyed by the caller!
+        *
+        * @param this                  calling transform_substructure_t object
+        * @param iterator              the created iterator is stored at the pointed pointer
+        * @param[in] forward   iterator direction (TRUE: front to end)
+        * @return              
+        *                                              - SUCCESS or
+        *                                              - OUT_OF_RES if iterator could not be created
+        */
+       status_t (*create_transform_attribute_iterator) (transform_substructure_t *this,linked_list_iterator_t **iterator, bool forward);
+       
+       /**
+        * @brief Adds a transform_attribute_t object to this object.
+        * 
+        * @warning The added proposal_substructure_t object  is 
+        *                      getting destroyed in destroy function of transform_substructure_t.
+        *
+        * @param this          calling transform_substructure_t object
+        * @param proposal  transform_attribute_t object to add
+        * @return                      - SUCCESS if succeeded
+        *                                      - FAILED otherwise
+        */
+       status_t (*add_transform_attribute) (transform_substructure_t *this,transform_attribute_t *attribute);
+       
+       /**
+        * @brief Destroys an transform_substructure_t object.
+        *
+        * @param this  transform_substructure_t object to destroy
+        * @return              
+        *                              SUCCESS in any case
+        */
+       status_t (*destroy) (transform_substructure_t *this);
+};
+
+/**
+ * @brief Creates an empty transform_substructure_t object
+ * 
+ * @return                     
+ *                                     - created transform_substructure_t object, or
+ *                                     - NULL if failed
+ */
+transform_substructure_t *transform_substructure_create();
+
+#endif /*TRANSFORM_SUBSTRUCTURE_H_*/