]>
Commit | Line | Data |
---|---|---|
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 **)¤t_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 |