]> git.ipfire.org Git - thirdparty/strongswan.git/blame - src/conftest/hooks/set_reserved.c
Update copyright headers after acquisition by secunet
[thirdparty/strongswan.git] / src / conftest / hooks / set_reserved.c
CommitLineData
446a4537
MW
1/*
2 * Copyright (C) 2010 Martin Willi
19ef2aec
TB
3 *
4 * Copyright (C) secunet Security Networks AG
446a4537
MW
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
15 */
16
17#include "hook.h"
18
b5bbc950 19#include <encoding/payloads/sa_payload.h>
446a4537
MW
20
21typedef struct private_set_reserved_t private_set_reserved_t;
22
23/**
24 * Private data of an set_reserved_t object.
25 */
26struct private_set_reserved_t {
27
28 /**
29 * Implements the hook_t interface.
30 */
31 hook_t hook;
32
33 /**
34 * Alter requests or responses?
35 */
36 bool req;
37
38 /**
39 * ID of message to alter.
40 */
41 int id;
42
43 /**
44 * Hook name
45 */
46 char *name;
47};
48
b5bbc950
MW
49/**
50 * Set reserved bit of a payload
51 */
52static void set_bit(private_set_reserved_t *this, message_t *message,
53 payload_type_t type, u_int nr)
54{
55 enumerator_t *payloads;
56 payload_t *payload;
57 bool *bit;
58
3ecfc83c 59 if (type == PL_HEADER)
b5bbc950
MW
60 {
61 message->set_reserved_header_bit(message, nr);
62 DBG1(DBG_CFG, "setting reserved bit %d of %N",
63 nr, payload_type_short_names, type);
64 }
65 else
66 {
67 payloads = message->create_payload_enumerator(message);
68 while (payloads->enumerate(payloads, &payload))
69 {
70 if (payload->get_type(payload) == type)
71 {
72 bit = payload_get_field(payload, RESERVED_BIT, nr);
73 if (bit)
74 {
75 DBG1(DBG_CFG, "setting reserved bit %d of %N",
76 nr, payload_type_short_names, type);
77 *bit = TRUE;
78 }
79 }
80 }
81 payloads->destroy(payloads);
82 }
83}
84
85/**
86 * Set reserved byte of a payload
87 */
88static void set_byte(private_set_reserved_t *this, message_t *message,
b12c53ce 89 payload_type_t type, u_int nr, uint8_t byteval)
b5bbc950
MW
90{
91 enumerator_t *payloads;
92 payload_t *payload;
b12c53ce 93 uint8_t *byte;
b5bbc950 94
3ecfc83c 95 if (type == PLV2_TRANSFORM_SUBSTRUCTURE || type == PLV2_PROPOSAL_SUBSTRUCTURE)
b5bbc950
MW
96 {
97 enumerator_t *transforms, *proposals;
98 transform_substructure_t *transform;
99 proposal_substructure_t *proposal;
100 sa_payload_t *sa;
101
102 payloads = message->create_payload_enumerator(message);
103 while (payloads->enumerate(payloads, &payload))
104 {
3ecfc83c 105 if (payload->get_type(payload) == PLV2_SECURITY_ASSOCIATION)
b5bbc950
MW
106 {
107 sa = (sa_payload_t*)payload;
108 proposals = sa->create_substructure_enumerator(sa);
109 while (proposals->enumerate(proposals, &proposal))
110 {
3ecfc83c 111 if (type == PLV2_PROPOSAL_SUBSTRUCTURE)
b5bbc950
MW
112 {
113 byte = payload_get_field(&proposal->payload_interface,
114 RESERVED_BYTE, nr);
115 if (byte)
116 {
117 DBG1(DBG_CFG, "setting reserved byte %d of %N to %d",
118 nr, payload_type_short_names, type, byteval);
119 *byte = byteval;
120 }
121 }
3ecfc83c 122 else if (type == PLV2_TRANSFORM_SUBSTRUCTURE)
b5bbc950
MW
123 {
124 transforms = proposal->create_substructure_enumerator(
125 proposal);
126 while (transforms->enumerate(transforms, &transform))
127 {
128 byte = payload_get_field(&transform->payload_interface,
129 RESERVED_BYTE, nr);
130 if (byte)
131 {
132 DBG1(DBG_CFG, "setting reserved byte %d of %N to %d",
133 nr, payload_type_short_names, type, byteval);
134 *byte = byteval;
135 }
136 }
137 transforms->destroy(transforms);
138 }
139 }
140 proposals->destroy(proposals);
141 }
142 }
143 payloads->destroy(payloads);
144 }
145 else
146 {
147 payloads = message->create_payload_enumerator(message);
148 while (payloads->enumerate(payloads, &payload))
149 {
150 if (payload->get_type(payload) == type)
151 {
152 byte = payload_get_field(payload, RESERVED_BYTE, nr);
153 if (byte)
154 {
155 DBG1(DBG_CFG, "setting reserved byte %d of %N to %d",
156 nr, payload_type_short_names, type, byteval);
157 *byte = byteval;
158 }
159 }
160 }
161 payloads->destroy(payloads);
162 }
163}
164
446a4537
MW
165METHOD(listener_t, message, bool,
166 private_set_reserved_t *this, ike_sa_t *ike_sa, message_t *message,
47b8f6ef 167 bool incoming, bool plain)
446a4537 168{
47b8f6ef 169 if (!incoming && plain &&
446a4537
MW
170 message->get_request(message) == this->req &&
171 message->get_message_id(message) == this->id)
172 {
5c95bf7b
MW
173 enumerator_t *bits, *bytes, *types;
174 payload_type_t type;
175 char *nr, *name;
b12c53ce 176 uint8_t byteval;
5c95bf7b
MW
177
178 types = conftest->test->create_section_enumerator(conftest->test,
179 "hooks.%s", this->name);
180 while (types->enumerate(types, &name))
446a4537 181 {
5c95bf7b
MW
182 type = atoi(name);
183 if (!type)
446a4537 184 {
064fe9c9 185 if (!enum_from_name(payload_type_short_names, name, &type))
5c95bf7b
MW
186 {
187 DBG1(DBG_CFG, "invalid payload name '%s'", name);
188 break;
189 }
446a4537 190 }
5c95bf7b
MW
191 nr = conftest->test->get_str(conftest->test,
192 "hooks.%s.%s.bits", "", this->name, name);
193 bits = enumerator_create_token(nr, ",", " ");
194 while (bits->enumerate(bits, &nr))
446a4537 195 {
5c95bf7b 196 set_bit(this, message, type, atoi(nr));
446a4537 197 }
5c95bf7b
MW
198 bits->destroy(bits);
199
200 nr = conftest->test->get_str(conftest->test,
201 "hooks.%s.%s.bytes", "", this->name, name);
202 byteval = conftest->test->get_int(conftest->test,
203 "hooks.%s.%s.byteval", 255, this->name, name);
204 bytes = enumerator_create_token(nr, ",", " ");
205 while (bytes->enumerate(bytes, &nr))
446a4537 206 {
5c95bf7b 207 set_byte(this, message, type, atoi(nr), byteval);
446a4537 208 }
5c95bf7b 209 bytes->destroy(bytes);
446a4537 210 }
5c95bf7b 211 types->destroy(types);
446a4537
MW
212 }
213 return TRUE;
214}
215
216METHOD(hook_t, destroy, void,
217 private_set_reserved_t *this)
218{
219 free(this->name);
220 free(this);
221}
222
223/**
224 * Create the IKE_AUTH fill hook
225 */
226hook_t *set_reserved_hook_create(char *name)
227{
228 private_set_reserved_t *this;
229
230 INIT(this,
231 .hook = {
232 .listener = {
233 .message = _message,
234 },
235 .destroy = _destroy,
236 },
237 .req = conftest->test->get_bool(conftest->test,
238 "hooks.%s.request", TRUE, name),
239 .id = conftest->test->get_int(conftest->test,
240 "hooks.%s.id", 0, name),
241 .name = strdup(name),
242 );
243
244 return &this->hook;
245}