Introduced payload types sa_payload and proposal_substructure
[strongswan.git] / Source / charon / payloads / proposal_substructure.c
1 /**
2 * @file proposal_substructure.h
3 *
4 * @brief Declaration of the class proposal_substructure_t.
5 *
6 * An object of this type represents an IKEv2 PROPOSAL Substructure and contains transforms.
7 *
8 */
9
10 /*
11 * Copyright (C) 2005 Jan Hutter, Martin Willi
12 * Hochschule fuer Technik Rapperswil
13 *
14 * This program is free software; you can redistribute it and/or modify it
15 * under the terms of the GNU General Public License as published by the
16 * Free Software Foundation; either version 2 of the License, or (at your
17 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
18 *
19 * This program is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
21 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 * for more details.
23 */
24 /* offsetof macro */
25 #include <stddef.h>
26
27 #include "proposal_substructure.h"
28
29 #include "encodings.h"
30 #include "../types.h"
31 #include "../utils/allocator.h"
32 #include "../utils/linked_list.h"
33
34 /**
35 * Private data of an proposal_substructure_t' Object
36 *
37 */
38 typedef struct private_proposal_substructure_s private_proposal_substructure_t;
39
40 struct private_proposal_substructure_s {
41 /**
42 * public proposal_substructure_t interface
43 */
44 proposal_substructure_t public;
45
46 /**
47 * next payload type
48 */
49 u_int8_t next_payload;
50
51
52 /**
53 * Length of this payload
54 */
55 u_int16_t proposal_length;
56
57
58 /**
59 * Proposal number
60 */
61 u_int8_t proposal_number;
62
63 /**
64 * Protocol ID
65 */
66 u_int8_t protocol_id;
67
68 /**
69 * SPI size of the following SPI
70 */
71 u_int8_t spi_size;
72
73 /**
74 * Number of transforms
75 */
76 u_int8_t transforms_count;
77
78 /**
79 * SPI is stored as chunk
80 */
81 chunk_t spi;
82
83 /**
84 * Transforms are stored in a linked_list_t
85 */
86 linked_list_t * transforms;
87 };
88
89 /**
90 * Encoding rules to parse or generate a Proposal substructure
91 *
92 * The defined offsets are the positions in a object of type
93 * private_proposal_substructure_t.
94 *
95 */
96 encoding_rule_t proposal_substructure_encodings[] = {
97 /* 1 Byte next payload type, stored in the field next_payload */
98 { U_INT_8, offsetof(private_proposal_substructure_t, next_payload) },
99 /* Reserved Byte is skipped */
100 { RESERVED_BYTE, 0 },
101 /* Length of the whole SA payload*/
102 { PAYLOAD_LENGTH, offsetof(private_proposal_substructure_t, proposal_length) },
103 /* proposal number is a number of 8 bit */
104 { U_INT_8, offsetof(private_proposal_substructure_t, proposal_number) },
105 /* protocol ID is a number of 8 bit */
106 { U_INT_8, offsetof(private_proposal_substructure_t, protocol_id) },
107 /* SPI Size has its own type */
108 { SPI_SIZE, offsetof(private_proposal_substructure_t, spi_size) },
109 /* Number of transforms is a number of 8 bit */
110 { U_INT_8, offsetof(private_proposal_substructure_t, transforms_count) },
111 /* SPI is a chunk of variable size*/
112 { SPI, offsetof(private_proposal_substructure_t, spi) },
113 /* Transforms are stored in a transform substructure,
114 offset points to a linked_list_t pointer */
115 { TRANSFORMS, offsetof(private_proposal_substructure_t, transforms) }
116 };
117
118 /**
119 * Implements payload_t's and proposal_substructure_t's destroy function.
120 * See #payload_s.destroy or proposal_substructure_s.destroy for description.
121 */
122 static status_t destroy(private_proposal_substructure_t *this)
123 {
124 /* all proposals are getting destroyed */
125 while (this->transforms->get_count(this->transforms) > 0)
126 {
127 transforms_substructure_t *current_transform;
128 if (this->transforms->remove_last(this->transforms,(void **)&current_transform) != SUCCESS)
129 {
130 break;
131 }
132 current_transform->destroy(current_transform);
133 }
134 this->transforms->destroy(this->transforms);
135
136 if (this->spi.ptr != NULL)
137 {
138 allocator_free(this->spi.ptr);
139 }
140
141 allocator_free(this);
142
143 return SUCCESS;
144 }
145
146 /**
147 * Implements payload_t's get_encoding_rules function.
148 * See #payload_s.get_encoding_rules for description.
149 */
150 static status_t get_encoding_rules(private_proposal_substructure_t *this, encoding_rule_t **rules, size_t *rule_count)
151 {
152 *rules = proposal_substructure_encodings;
153 *rule_count = sizeof(proposal_substructure_encodings) / sizeof(encoding_rule_t);
154
155 return SUCCESS;
156 }
157
158 /**
159 * Implements payload_t's get_type function.
160 * See #payload_s.get_type for description.
161 */
162 static payload_type_t get_type(private_proposal_substructure_t *this)
163 {
164 return PROPOSAL_SUBSTRUCTURE;
165 }
166
167 /**
168 * Implements payload_t's get_next_type function.
169 * See #payload_s.get_next_type for description.
170 */
171 static payload_type_t get_next_type(private_proposal_substructure_t *this)
172 {
173 return (this->next_payload);
174 }
175
176 /**
177 * Implements payload_t's get_length function.
178 * See #payload_s.get_length for description.
179 */
180 static size_t get_length(private_proposal_substructure_t *this)
181 {
182 return this->proposal_length;
183 }
184
185 /*
186 * Described in header
187 */
188 proposal_substructure_t *proposal_substructure_create()
189 {
190 private_proposal_substructure_t *this = allocator_alloc_thing(private_proposal_substructure_t);
191 if (this == NULL)
192 {
193 return NULL;
194 }
195
196 this->public.payload_interface.get_encoding_rules = (status_t (*) (payload_t *, encoding_rule_t **, size_t *) ) get_encoding_rules;
197 this->public.payload_interface.get_length = (size_t (*) (payload_t *)) get_length;
198 this->public.payload_interface.get_next_type = (payload_type_t (*) (payload_t *)) get_next_type;
199 this->public.payload_interface.get_type = (payload_type_t (*) (payload_t *)) get_type;
200 this->public.payload_interface.destroy = (status_t (*) (payload_t *))destroy;
201 this->public.destroy = (status_t (*) (proposal_substructure_t *)) destroy;
202
203 /* set default values of the fields */
204 this->next_payload = NO_PAYLOAD;
205 this->proposal_length = 0;
206 this->proposal_number = 0;
207 this->protocol_id = 0;
208 this->transforms_count = 0;
209 this->spi_size = 0;
210 this->spi.ptr = NULL;
211 this->spi.len = 0;
212
213 this->transforms = linked_list_create();
214
215 if (this->transforms == NULL)
216 {
217 allocator_free(this);
218 return NULL;
219 }
220 return (&(this->public));
221 }
222
223