2 * Copyright (C) 2010 Martin Willi
3 * Copyright (C) 2010 revosec AG
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 #include <encoding/payloads/sa_payload.h>
20 typedef struct private_set_reserved_t private_set_reserved_t
;
23 * Private data of an set_reserved_t object.
25 struct private_set_reserved_t
{
28 * Implements the hook_t interface.
33 * Alter requests or responses?
38 * ID of message to alter.
49 * Set reserved bit of a payload
51 static void set_bit(private_set_reserved_t
*this, message_t
*message
,
52 payload_type_t type
, u_int nr
)
54 enumerator_t
*payloads
;
60 message
->set_reserved_header_bit(message
, nr
);
61 DBG1(DBG_CFG
, "setting reserved bit %d of %N",
62 nr
, payload_type_short_names
, type
);
66 payloads
= message
->create_payload_enumerator(message
);
67 while (payloads
->enumerate(payloads
, &payload
))
69 if (payload
->get_type(payload
) == type
)
71 bit
= payload_get_field(payload
, RESERVED_BIT
, nr
);
74 DBG1(DBG_CFG
, "setting reserved bit %d of %N",
75 nr
, payload_type_short_names
, type
);
80 payloads
->destroy(payloads
);
85 * Set reserved byte of a payload
87 static void set_byte(private_set_reserved_t
*this, message_t
*message
,
88 payload_type_t type
, u_int nr
, u_int8_t byteval
)
90 enumerator_t
*payloads
;
94 if (type
== TRANSFORM_SUBSTRUCTURE
|| type
== PROPOSAL_SUBSTRUCTURE
)
96 enumerator_t
*transforms
, *proposals
;
97 transform_substructure_t
*transform
;
98 proposal_substructure_t
*proposal
;
101 payloads
= message
->create_payload_enumerator(message
);
102 while (payloads
->enumerate(payloads
, &payload
))
104 if (payload
->get_type(payload
) == SECURITY_ASSOCIATION
)
106 sa
= (sa_payload_t
*)payload
;
107 proposals
= sa
->create_substructure_enumerator(sa
);
108 while (proposals
->enumerate(proposals
, &proposal
))
110 if (type
== PROPOSAL_SUBSTRUCTURE
)
112 byte
= payload_get_field(&proposal
->payload_interface
,
116 DBG1(DBG_CFG
, "setting reserved byte %d of %N to %d",
117 nr
, payload_type_short_names
, type
, byteval
);
121 else if (type
== TRANSFORM_SUBSTRUCTURE
)
123 transforms
= proposal
->create_substructure_enumerator(
125 while (transforms
->enumerate(transforms
, &transform
))
127 byte
= payload_get_field(&transform
->payload_interface
,
131 DBG1(DBG_CFG
, "setting reserved byte %d of %N to %d",
132 nr
, payload_type_short_names
, type
, byteval
);
136 transforms
->destroy(transforms
);
139 proposals
->destroy(proposals
);
142 payloads
->destroy(payloads
);
146 payloads
= message
->create_payload_enumerator(message
);
147 while (payloads
->enumerate(payloads
, &payload
))
149 if (payload
->get_type(payload
) == type
)
151 byte
= payload_get_field(payload
, RESERVED_BYTE
, nr
);
154 DBG1(DBG_CFG
, "setting reserved byte %d of %N to %d",
155 nr
, payload_type_short_names
, type
, byteval
);
160 payloads
->destroy(payloads
);
164 METHOD(listener_t
, message
, bool,
165 private_set_reserved_t
*this, ike_sa_t
*ike_sa
, message_t
*message
,
169 message
->get_request(message
) == this->req
&&
170 message
->get_message_id(message
) == this->id
)
172 enumerator_t
*bits
, *bytes
, *types
;
177 types
= conftest
->test
->create_section_enumerator(conftest
->test
,
178 "hooks.%s", this->name
);
179 while (types
->enumerate(types
, &name
))
184 type
= enum_from_name(payload_type_short_names
, name
);
187 DBG1(DBG_CFG
, "invalid payload name '%s'", name
);
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
))
196 set_bit(this, message
, type
, atoi(nr
));
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
))
207 set_byte(this, message
, type
, atoi(nr
), byteval
);
209 bytes
->destroy(bytes
);
211 types
->destroy(types
);
216 METHOD(hook_t
, destroy
, void,
217 private_set_reserved_t
*this)
224 * Create the IKE_AUTH fill hook
226 hook_t
*set_reserved_hook_create(char *name
)
228 private_set_reserved_t
*this;
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
),