unknown-payload: Use a new private payload type and make original type available
[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/encrypted_fragment_payload.h>
33 #include <encoding/payloads/ts_payload.h>
34 #include <encoding/payloads/delete_payload.h>
35 #include <encoding/payloads/vendor_id_payload.h>
36 #include <encoding/payloads/cp_payload.h>
37 #include <encoding/payloads/configuration_attribute.h>
38 #include <encoding/payloads/eap_payload.h>
39 #include <encoding/payloads/hash_payload.h>
40 #include <encoding/payloads/fragment_payload.h>
41 #include <encoding/payloads/unknown_payload.h>
42
43 ENUM_BEGIN(payload_type_names, PL_NONE, PL_NONE,
44 "PL_NONE");
45 ENUM_NEXT(payload_type_names, PLV1_SECURITY_ASSOCIATION, PLV1_CONFIGURATION, PL_NONE,
46 "SECURITY_ASSOCIATION_V1",
47 "PROPOSAL_V1",
48 "TRANSFORM_V1",
49 "KEY_EXCHANGE_V1",
50 "ID_V1",
51 "CERTIFICATE_V1",
52 "CERTREQ_V1",
53 "HASH_V1",
54 "SIGNATURE_V1",
55 "NONCE_V1",
56 "NOTIFY_V1",
57 "DELETE_V1",
58 "VENDOR_ID_V1",
59 "CONFIGURATION_V1");
60 ENUM_NEXT(payload_type_names, PLV1_NAT_D, PLV1_NAT_OA, PLV1_CONFIGURATION,
61 "NAT_D_V1",
62 "NAT_OA_V1");
63 ENUM_NEXT(payload_type_names, PLV2_SECURITY_ASSOCIATION, PLV2_FRAGMENT, PLV1_NAT_OA,
64 "SECURITY_ASSOCIATION",
65 "KEY_EXCHANGE",
66 "ID_INITIATOR",
67 "ID_RESPONDER",
68 "CERTIFICATE",
69 "CERTREQ",
70 "AUTH",
71 "NONCE",
72 "NOTIFY",
73 "DELETE",
74 "VENDOR_ID",
75 "TS_INITIATOR",
76 "TS_RESPONDER",
77 "ENCRYPTED",
78 "CONFIGURATION",
79 "EAP",
80 "GSPM",
81 "GROUP_ID",
82 "GROUP_SECURITY_ASSOCIATION",
83 "KEY_DOWNLOAD",
84 "ENCRYPTED_FRAGMENT");
85 #ifdef ME
86 ENUM_NEXT(payload_type_names, PLV2_ID_PEER, PLV2_ID_PEER, PLV2_FRAGMENT,
87 "ID_PEER");
88 ENUM_NEXT(payload_type_names, PLV1_NAT_D_DRAFT_00_03, PLV1_FRAGMENT, PLV2_ID_PEER,
89 "NAT_D_DRAFT_V1",
90 "NAT_OA_DRAFT_V1",
91 "FRAGMENT");
92 #else
93 ENUM_NEXT(payload_type_names, PLV1_NAT_D_DRAFT_00_03, PLV1_FRAGMENT, PLV2_FRAGMENT,
94 "NAT_D_DRAFT_V1",
95 "NAT_OA_DRAFT_V1",
96 "FRAGMENT");
97 #endif /* ME */
98 ENUM_NEXT(payload_type_names, PL_HEADER, PLV1_ENCRYPTED, PLV1_FRAGMENT,
99 "HEADER",
100 "UNKNOWN",
101 "PROPOSAL_SUBSTRUCTURE",
102 "PROPOSAL_SUBSTRUCTURE_V1",
103 "TRANSFORM_SUBSTRUCTURE",
104 "TRANSFORM_SUBSTRUCTURE_V1",
105 "TRANSFORM_ATTRIBUTE",
106 "TRANSFORM_ATTRIBUTE_V1",
107 "TRAFFIC_SELECTOR_SUBSTRUCTURE",
108 "CONFIGURATION_ATTRIBUTE",
109 "CONFIGURATION_ATTRIBUTE_V1",
110 "ENCRYPTED_V1");
111 ENUM_END(payload_type_names, PLV1_ENCRYPTED);
112
113 /* short forms of payload names */
114 ENUM_BEGIN(payload_type_short_names, PL_NONE, PL_NONE,
115 "--");
116 ENUM_NEXT(payload_type_short_names, PLV1_SECURITY_ASSOCIATION, PLV1_CONFIGURATION, PL_NONE,
117 "SA",
118 "PROP",
119 "TRANS",
120 "KE",
121 "ID",
122 "CERT",
123 "CERTREQ",
124 "HASH",
125 "SIG",
126 "No",
127 "N",
128 "D",
129 "V",
130 "CP");
131 ENUM_NEXT(payload_type_short_names, PLV1_NAT_D, PLV1_NAT_OA, PLV1_CONFIGURATION,
132 "NAT-D",
133 "NAT-OA");
134 ENUM_NEXT(payload_type_short_names, PLV2_SECURITY_ASSOCIATION, PLV2_FRAGMENT, PLV1_NAT_OA,
135 "SA",
136 "KE",
137 "IDi",
138 "IDr",
139 "CERT",
140 "CERTREQ",
141 "AUTH",
142 "No",
143 "N",
144 "D",
145 "V",
146 "TSi",
147 "TSr",
148 "E",
149 "CP",
150 "EAP",
151 "GSPM",
152 "IDg",
153 "GSA",
154 "KD",
155 "EF");
156 #ifdef ME
157 ENUM_NEXT(payload_type_short_names, PLV2_ID_PEER, PLV2_ID_PEER, PLV2_FRAGMENT,
158 "IDp");
159 ENUM_NEXT(payload_type_short_names, PLV1_NAT_D_DRAFT_00_03, PLV1_FRAGMENT, PLV2_ID_PEER,
160 "NAT-D",
161 "NAT-OA",
162 "FRAG");
163 #else
164 ENUM_NEXT(payload_type_short_names, PLV1_NAT_D_DRAFT_00_03, PLV1_FRAGMENT, PLV2_FRAGMENT,
165 "NAT-D",
166 "NAT-OA",
167 "FRAG");
168 #endif /* ME */
169 ENUM_NEXT(payload_type_short_names, PL_HEADER, PLV1_ENCRYPTED, PLV1_FRAGMENT,
170 "HDR",
171 "UNKN",
172 "PROP",
173 "PROP",
174 "TRANS",
175 "TRANS",
176 "TRANSATTR",
177 "TRANSATTR",
178 "TSSUB",
179 "CATTR",
180 "CATTR",
181 "E");
182 ENUM_END(payload_type_short_names, PLV1_ENCRYPTED);
183
184 /*
185 * see header
186 */
187 payload_t *payload_create(payload_type_t type)
188 {
189 switch (type)
190 {
191 case PL_HEADER:
192 return (payload_t*)ike_header_create();
193 case PLV2_SECURITY_ASSOCIATION:
194 case PLV1_SECURITY_ASSOCIATION:
195 return (payload_t*)sa_payload_create(type);
196 case PLV2_PROPOSAL_SUBSTRUCTURE:
197 case PLV1_PROPOSAL_SUBSTRUCTURE:
198 return (payload_t*)proposal_substructure_create(type);
199 case PLV2_TRANSFORM_SUBSTRUCTURE:
200 case PLV1_TRANSFORM_SUBSTRUCTURE:
201 return (payload_t*)transform_substructure_create(type);
202 case PLV2_TRANSFORM_ATTRIBUTE:
203 case PLV1_TRANSFORM_ATTRIBUTE:
204 return (payload_t*)transform_attribute_create(type);
205 case PLV2_NONCE:
206 case PLV1_NONCE:
207 return (payload_t*)nonce_payload_create(type);
208 case PLV2_ID_INITIATOR:
209 case PLV2_ID_RESPONDER:
210 case PLV1_ID:
211 case PLV1_NAT_OA:
212 case PLV1_NAT_OA_DRAFT_00_03:
213 #ifdef ME
214 case PLV2_ID_PEER:
215 #endif /* ME */
216 return (payload_t*)id_payload_create(type);
217 case PLV2_AUTH:
218 return (payload_t*)auth_payload_create();
219 case PLV2_CERTIFICATE:
220 case PLV1_CERTIFICATE:
221 return (payload_t*)cert_payload_create(type);
222 case PLV2_CERTREQ:
223 case PLV1_CERTREQ:
224 return (payload_t*)certreq_payload_create(type);
225 case PLV2_TRAFFIC_SELECTOR_SUBSTRUCTURE:
226 return (payload_t*)traffic_selector_substructure_create();
227 case PLV2_TS_INITIATOR:
228 return (payload_t*)ts_payload_create(TRUE);
229 case PLV2_TS_RESPONDER:
230 return (payload_t*)ts_payload_create(FALSE);
231 case PLV2_KEY_EXCHANGE:
232 case PLV1_KEY_EXCHANGE:
233 return (payload_t*)ke_payload_create(type);
234 case PLV2_NOTIFY:
235 case PLV1_NOTIFY:
236 return (payload_t*)notify_payload_create(type);
237 case PLV2_DELETE:
238 case PLV1_DELETE:
239 return (payload_t*)delete_payload_create(type, 0);
240 case PLV2_VENDOR_ID:
241 case PLV1_VENDOR_ID:
242 return (payload_t*)vendor_id_payload_create(type);
243 case PLV1_HASH:
244 case PLV1_SIGNATURE:
245 case PLV1_NAT_D:
246 case PLV1_NAT_D_DRAFT_00_03:
247 return (payload_t*)hash_payload_create(type);
248 case PLV2_CONFIGURATION:
249 case PLV1_CONFIGURATION:
250 return (payload_t*)cp_payload_create(type);
251 case PLV2_CONFIGURATION_ATTRIBUTE:
252 case PLV1_CONFIGURATION_ATTRIBUTE:
253 return (payload_t*)configuration_attribute_create(type);
254 case PLV2_EAP:
255 return (payload_t*)eap_payload_create();
256 case PLV2_ENCRYPTED:
257 case PLV1_ENCRYPTED:
258 return (payload_t*)encrypted_payload_create(type);
259 case PLV1_FRAGMENT:
260 return (payload_t*)fragment_payload_create();
261 case PLV2_FRAGMENT:
262 return (payload_t*)encrypted_fragment_payload_create();
263 default:
264 return (payload_t*)unknown_payload_create(type);
265 }
266 }
267
268 /**
269 * See header.
270 */
271 bool payload_is_known(payload_type_t type, u_int8_t maj_ver)
272 {
273 if (type >= PL_HEADER)
274 {
275 return TRUE;
276 }
277 switch (maj_ver)
278 {
279 case 0:
280 case IKEV1_MAJOR_VERSION:
281 if (type >= PLV1_SECURITY_ASSOCIATION && type <= PLV1_CONFIGURATION)
282 {
283 return TRUE;
284 }
285 if (type >= PLV1_NAT_D && type <= PLV1_NAT_OA)
286 {
287 return TRUE;
288 }
289 if (type >= PLV1_NAT_D_DRAFT_00_03 && type <= PLV1_FRAGMENT)
290 {
291 return TRUE;
292 }
293 if (maj_ver)
294 {
295 break;
296 }
297 /* fall-through */
298 case IKEV2_MAJOR_VERSION:
299 if (type >= PLV2_SECURITY_ASSOCIATION && type <= PLV2_EAP)
300 {
301 return TRUE;
302 }
303 if (type == PLV2_FRAGMENT)
304 {
305 return TRUE;
306 }
307 #ifdef ME
308 if (type == PLV2_ID_PEER)
309 {
310 return TRUE;
311 }
312 #endif
313 break;
314 default:
315 break;
316 }
317 return FALSE;
318 }
319
320 /**
321 * See header.
322 */
323 void* payload_get_field(payload_t *payload, encoding_type_t type, u_int skip)
324 {
325 encoding_rule_t *rule;
326 int i, count;
327
328 count = payload->get_encoding_rules(payload, &rule);
329 for (i = 0; i < count; i++)
330 {
331 if (rule[i].type == type && skip-- == 0)
332 {
333 return ((char*)payload) + rule[i].offset;
334 }
335 }
336 return NULL;
337 }