e687f2707c25f1a2c15969d00a603ce7c5874b08
[strongswan.git] / src / libcharon / encoding / payloads / payload.c
1 /*
2 * Copyright (C) 2007 Tobias Brunner
3 * Copyright (C) 2005-2006 Martin Willi
4 * Copyright (C) 2005 Jan Hutter
5 * Hochschule fuer Technik Rapperswil
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 * for more details.
16 */
17
18
19 #include "payload.h"
20
21 #include <encoding/payloads/ike_header.h>
22 #include <encoding/payloads/sa_payload.h>
23
24 #include <encoding/payloads/nonce_payload.h>
25 #include <encoding/payloads/id_payload.h>
26 #include <encoding/payloads/ke_payload.h>
27 #include <encoding/payloads/notify_payload.h>
28 #include <encoding/payloads/auth_payload.h>
29 #include <encoding/payloads/cert_payload.h>
30 #include <encoding/payloads/certreq_payload.h>
31 #include <encoding/payloads/encrypted_payload.h>
32 #include <encoding/payloads/ts_payload.h>
33 #include <encoding/payloads/delete_payload.h>
34 #include <encoding/payloads/vendor_id_payload.h>
35 #include <encoding/payloads/cp_payload.h>
36 #include <encoding/payloads/configuration_attribute.h>
37 #include <encoding/payloads/eap_payload.h>
38 #include <encoding/payloads/hash_payload.h>
39 #include <encoding/payloads/fragment_payload.h>
40 #include <encoding/payloads/unknown_payload.h>
41
42 ENUM_BEGIN(payload_type_names, PL_NONE, PL_NONE,
43 "PL_NONE");
44 ENUM_NEXT(payload_type_names, PLV1_SECURITY_ASSOCIATION, PLV1_CONFIGURATION, PL_NONE,
45 "SECURITY_ASSOCIATION_V1",
46 "PROPOSAL_V1",
47 "TRANSFORM_V1",
48 "KEY_EXCHANGE_V1",
49 "ID_V1",
50 "CERTIFICATE_V1",
51 "CERTREQ_V1",
52 "HASH_V1",
53 "SIGNATURE_V1",
54 "NONCE_V1",
55 "NOTIFY_V1",
56 "DELETE_V1",
57 "VENDOR_ID_V1",
58 "CONFIGURATION_V1");
59 ENUM_NEXT(payload_type_names, PLV1_NAT_D, PLV1_NAT_OA, PLV1_CONFIGURATION,
60 "NAT_D_V1",
61 "NAT_OA_V1");
62 ENUM_NEXT(payload_type_names, PLV2_SECURITY_ASSOCIATION, PLV2_GSPM, PLV1_NAT_OA,
63 "SECURITY_ASSOCIATION",
64 "KEY_EXCHANGE",
65 "ID_INITIATOR",
66 "ID_RESPONDER",
67 "CERTIFICATE",
68 "CERTREQ",
69 "AUTH",
70 "NONCE",
71 "NOTIFY",
72 "DELETE",
73 "VENDOR_ID",
74 "TS_INITIATOR",
75 "TS_RESPONDER",
76 "ENCRYPTED",
77 "CONFIGURATION",
78 "EAP",
79 "GSPM");
80 #ifdef ME
81 ENUM_NEXT(payload_type_names, PLV2_ID_PEER, PLV2_ID_PEER, PLV2_GSPM,
82 "ID_PEER");
83 ENUM_NEXT(payload_type_names, PLV1_NAT_D_DRAFT_00_03, PLV1_FRAGMENT, PLV2_ID_PEER,
84 "NAT_D_DRAFT_V1",
85 "NAT_OA_DRAFT_V1",
86 "FRAGMENT");
87 #else
88 ENUM_NEXT(payload_type_names, PLV1_NAT_D_DRAFT_00_03, PLV1_FRAGMENT, PLV2_GSPM,
89 "NAT_D_DRAFT_V1",
90 "NAT_OA_DRAFT_V1",
91 "FRAGMENT");
92 #endif /* ME */
93 ENUM_NEXT(payload_type_names, PL_HEADER, PLV1_ENCRYPTED, PLV1_FRAGMENT,
94 "HEADER",
95 "PROPOSAL_SUBSTRUCTURE",
96 "PROPOSAL_SUBSTRUCTURE_V1",
97 "TRANSFORM_SUBSTRUCTURE",
98 "TRANSFORM_SUBSTRUCTURE_V1",
99 "TRANSFORM_ATTRIBUTE",
100 "TRANSFORM_ATTRIBUTE_V1",
101 "TRAFFIC_SELECTOR_SUBSTRUCTURE",
102 "CONFIGURATION_ATTRIBUTE",
103 "CONFIGURATION_ATTRIBUTE_V1",
104 "ENCRYPTED_V1");
105 ENUM_END(payload_type_names, PLV1_ENCRYPTED);
106
107 /* short forms of payload names */
108 ENUM_BEGIN(payload_type_short_names, PL_NONE, PL_NONE,
109 "--");
110 ENUM_NEXT(payload_type_short_names, PLV1_SECURITY_ASSOCIATION, PLV1_CONFIGURATION, PL_NONE,
111 "SA",
112 "PROP",
113 "TRANS",
114 "KE",
115 "ID",
116 "CERT",
117 "CERTREQ",
118 "HASH",
119 "SIG",
120 "No",
121 "N",
122 "D",
123 "V",
124 "CP");
125 ENUM_NEXT(payload_type_short_names, PLV1_NAT_D, PLV1_NAT_OA, PLV1_CONFIGURATION,
126 "NAT-D",
127 "NAT-OA");
128 ENUM_NEXT(payload_type_short_names, PLV2_SECURITY_ASSOCIATION, PLV2_GSPM, PLV1_NAT_OA,
129 "SA",
130 "KE",
131 "IDi",
132 "IDr",
133 "CERT",
134 "CERTREQ",
135 "AUTH",
136 "No",
137 "N",
138 "D",
139 "V",
140 "TSi",
141 "TSr",
142 "E",
143 "CP",
144 "EAP",
145 "GSPM");
146 #ifdef ME
147 ENUM_NEXT(payload_type_short_names, PLV2_ID_PEER, PLV2_ID_PEER, PLV2_GSPM,
148 "IDp");
149 ENUM_NEXT(payload_type_short_names, PLV1_NAT_D_DRAFT_00_03, PLV1_FRAGMENT, PLV2_ID_PEER,
150 "NAT-D",
151 "NAT-OA",
152 "FRAG");
153 #else
154 ENUM_NEXT(payload_type_short_names, PLV1_NAT_D_DRAFT_00_03, PLV1_FRAGMENT, PLV2_GSPM,
155 "NAT-D",
156 "NAT-OA",
157 "FRAG");
158 #endif /* ME */
159 ENUM_NEXT(payload_type_short_names, PL_HEADER, PLV1_ENCRYPTED, PLV1_FRAGMENT,
160 "HDR",
161 "PROP",
162 "PROP",
163 "TRANS",
164 "TRANS",
165 "TRANSATTR",
166 "TRANSATTR",
167 "TSSUB",
168 "CATTR",
169 "CATTR",
170 "E");
171 ENUM_END(payload_type_short_names, PLV1_ENCRYPTED);
172
173 /*
174 * see header
175 */
176 payload_t *payload_create(payload_type_t type)
177 {
178 switch (type)
179 {
180 case PL_HEADER:
181 return (payload_t*)ike_header_create();
182 case PLV2_SECURITY_ASSOCIATION:
183 case PLV1_SECURITY_ASSOCIATION:
184 return (payload_t*)sa_payload_create(type);
185 case PLV2_PROPOSAL_SUBSTRUCTURE:
186 case PLV1_PROPOSAL_SUBSTRUCTURE:
187 return (payload_t*)proposal_substructure_create(type);
188 case PLV2_TRANSFORM_SUBSTRUCTURE:
189 case PLV1_TRANSFORM_SUBSTRUCTURE:
190 return (payload_t*)transform_substructure_create(type);
191 case PLV2_TRANSFORM_ATTRIBUTE:
192 case PLV1_TRANSFORM_ATTRIBUTE:
193 return (payload_t*)transform_attribute_create(type);
194 case PLV2_NONCE:
195 case PLV1_NONCE:
196 return (payload_t*)nonce_payload_create(type);
197 case PLV2_ID_INITIATOR:
198 case PLV2_ID_RESPONDER:
199 case PLV1_ID:
200 case PLV1_NAT_OA:
201 case PLV1_NAT_OA_DRAFT_00_03:
202 #ifdef ME
203 case PLV2_ID_PEER:
204 #endif /* ME */
205 return (payload_t*)id_payload_create(type);
206 case PLV2_AUTH:
207 return (payload_t*)auth_payload_create();
208 case PLV2_CERTIFICATE:
209 case PLV1_CERTIFICATE:
210 return (payload_t*)cert_payload_create(type);
211 case PLV2_CERTREQ:
212 case PLV1_CERTREQ:
213 return (payload_t*)certreq_payload_create(type);
214 case PLV2_TRAFFIC_SELECTOR_SUBSTRUCTURE:
215 return (payload_t*)traffic_selector_substructure_create();
216 case PLV2_TS_INITIATOR:
217 return (payload_t*)ts_payload_create(TRUE);
218 case PLV2_TS_RESPONDER:
219 return (payload_t*)ts_payload_create(FALSE);
220 case PLV2_KEY_EXCHANGE:
221 case PLV1_KEY_EXCHANGE:
222 return (payload_t*)ke_payload_create(type);
223 case PLV2_NOTIFY:
224 case PLV1_NOTIFY:
225 return (payload_t*)notify_payload_create(type);
226 case PLV2_DELETE:
227 case PLV1_DELETE:
228 return (payload_t*)delete_payload_create(type, 0);
229 case PLV2_VENDOR_ID:
230 case PLV1_VENDOR_ID:
231 return (payload_t*)vendor_id_payload_create(type);
232 case PLV1_HASH:
233 case PLV1_SIGNATURE:
234 case PLV1_NAT_D:
235 case PLV1_NAT_D_DRAFT_00_03:
236 return (payload_t*)hash_payload_create(type);
237 case PLV2_CONFIGURATION:
238 case PLV1_CONFIGURATION:
239 return (payload_t*)cp_payload_create(type);
240 case PLV2_CONFIGURATION_ATTRIBUTE:
241 case PLV1_CONFIGURATION_ATTRIBUTE:
242 return (payload_t*)configuration_attribute_create(type);
243 case PLV2_EAP:
244 return (payload_t*)eap_payload_create();
245 case PLV2_ENCRYPTED:
246 case PLV1_ENCRYPTED:
247 return (payload_t*)encrypted_payload_create(type);
248 case PLV1_FRAGMENT:
249 return (payload_t*)fragment_payload_create();
250 default:
251 return (payload_t*)unknown_payload_create(type);
252 }
253 }
254
255 /**
256 * See header.
257 */
258 bool payload_is_known(payload_type_t type)
259 {
260 if (type == PL_HEADER)
261 {
262 return TRUE;
263 }
264 if (type >= PLV2_SECURITY_ASSOCIATION && type <= PLV2_EAP)
265 {
266 return TRUE;
267 }
268 if (type >= PLV1_SECURITY_ASSOCIATION && type <= PLV1_CONFIGURATION)
269 {
270 return TRUE;
271 }
272 if (type >= PLV1_NAT_D && type <= PLV1_NAT_OA)
273 {
274 return TRUE;
275 }
276 #ifdef ME
277 if (type == PLV2_ID_PEER)
278 {
279 return TRUE;
280 }
281 #endif
282 if (type >= PLV1_NAT_D_DRAFT_00_03 && type <= PLV1_FRAGMENT)
283 {
284 return TRUE;
285 }
286 return FALSE;
287 }
288
289 /**
290 * See header.
291 */
292 void* payload_get_field(payload_t *payload, encoding_type_t type, u_int skip)
293 {
294 encoding_rule_t *rule;
295 int i, count;
296
297 count = payload->get_encoding_rules(payload, &rule);
298 for (i = 0; i < count; i++)
299 {
300 if (rule[i].type == type && skip-- == 0)
301 {
302 return ((char*)payload) + rule[i].offset;
303 }
304 }
305 return NULL;
306 }