set_reserved.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. /*
  2. * Copyright (C) 2010 Martin Willi
  3. * Copyright (C) 2010 revosec AG
  4. *
  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>.
  9. *
  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
  13. * for more details.
  14. */
  15. #include "hook.h"
  16. #include <encoding/payloads/sa_payload.h>
  17. typedef struct private_set_reserved_t private_set_reserved_t;
  18. /**
  19. * Private data of an set_reserved_t object.
  20. */
  21. struct private_set_reserved_t {
  22. /**
  23. * Implements the hook_t interface.
  24. */
  25. hook_t hook;
  26. /**
  27. * Alter requests or responses?
  28. */
  29. bool req;
  30. /**
  31. * ID of message to alter.
  32. */
  33. int id;
  34. /**
  35. * Hook name
  36. */
  37. char *name;
  38. };
  39. /**
  40. * Set reserved bit of a payload
  41. */
  42. static void set_bit(private_set_reserved_t *this, message_t *message,
  43. payload_type_t type, u_int nr)
  44. {
  45. enumerator_t *payloads;
  46. payload_t *payload;
  47. bool *bit;
  48. if (type == PL_HEADER)
  49. {
  50. message->set_reserved_header_bit(message, nr);
  51. DBG1(DBG_CFG, "setting reserved bit %d of %N",
  52. nr, payload_type_short_names, type);
  53. }
  54. else
  55. {
  56. payloads = message->create_payload_enumerator(message);
  57. while (payloads->enumerate(payloads, &payload))
  58. {
  59. if (payload->get_type(payload) == type)
  60. {
  61. bit = payload_get_field(payload, RESERVED_BIT, nr);
  62. if (bit)
  63. {
  64. DBG1(DBG_CFG, "setting reserved bit %d of %N",
  65. nr, payload_type_short_names, type);
  66. *bit = TRUE;
  67. }
  68. }
  69. }
  70. payloads->destroy(payloads);
  71. }
  72. }
  73. /**
  74. * Set reserved byte of a payload
  75. */
  76. static void set_byte(private_set_reserved_t *this, message_t *message,
  77. payload_type_t type, u_int nr, uint8_t byteval)
  78. {
  79. enumerator_t *payloads;
  80. payload_t *payload;
  81. uint8_t *byte;
  82. if (type == PLV2_TRANSFORM_SUBSTRUCTURE || type == PLV2_PROPOSAL_SUBSTRUCTURE)
  83. {
  84. enumerator_t *transforms, *proposals;
  85. transform_substructure_t *transform;
  86. proposal_substructure_t *proposal;
  87. sa_payload_t *sa;
  88. payloads = message->create_payload_enumerator(message);
  89. while (payloads->enumerate(payloads, &payload))
  90. {
  91. if (payload->get_type(payload) == PLV2_SECURITY_ASSOCIATION)
  92. {
  93. sa = (sa_payload_t*)payload;
  94. proposals = sa->create_substructure_enumerator(sa);
  95. while (proposals->enumerate(proposals, &proposal))
  96. {
  97. if (type == PLV2_PROPOSAL_SUBSTRUCTURE)
  98. {
  99. byte = payload_get_field(&proposal->payload_interface,
  100. RESERVED_BYTE, nr);
  101. if (byte)
  102. {
  103. DBG1(DBG_CFG, "setting reserved byte %d of %N to %d",
  104. nr, payload_type_short_names, type, byteval);
  105. *byte = byteval;
  106. }
  107. }
  108. else if (type == PLV2_TRANSFORM_SUBSTRUCTURE)
  109. {
  110. transforms = proposal->create_substructure_enumerator(
  111. proposal);
  112. while (transforms->enumerate(transforms, &transform))
  113. {
  114. byte = payload_get_field(&transform->payload_interface,
  115. RESERVED_BYTE, nr);
  116. if (byte)
  117. {
  118. DBG1(DBG_CFG, "setting reserved byte %d of %N to %d",
  119. nr, payload_type_short_names, type, byteval);
  120. *byte = byteval;
  121. }
  122. }
  123. transforms->destroy(transforms);
  124. }
  125. }
  126. proposals->destroy(proposals);
  127. }
  128. }
  129. payloads->destroy(payloads);
  130. }
  131. else
  132. {
  133. payloads = message->create_payload_enumerator(message);
  134. while (payloads->enumerate(payloads, &payload))
  135. {
  136. if (payload->get_type(payload) == type)
  137. {
  138. byte = payload_get_field(payload, RESERVED_BYTE, nr);
  139. if (byte)
  140. {
  141. DBG1(DBG_CFG, "setting reserved byte %d of %N to %d",
  142. nr, payload_type_short_names, type, byteval);
  143. *byte = byteval;
  144. }
  145. }
  146. }
  147. payloads->destroy(payloads);
  148. }
  149. }
  150. METHOD(listener_t, message, bool,
  151. private_set_reserved_t *this, ike_sa_t *ike_sa, message_t *message,
  152. bool incoming, bool plain)
  153. {
  154. if (!incoming && plain &&
  155. message->get_request(message) == this->req &&
  156. message->get_message_id(message) == this->id)
  157. {
  158. enumerator_t *bits, *bytes, *types;
  159. payload_type_t type;
  160. char *nr, *name;
  161. uint8_t byteval;
  162. types = conftest->test->create_section_enumerator(conftest->test,
  163. "hooks.%s", this->name);
  164. while (types->enumerate(types, &name))
  165. {
  166. type = atoi(name);
  167. if (!type)
  168. {
  169. if (!enum_from_name(payload_type_short_names, name, &type))
  170. {
  171. DBG1(DBG_CFG, "invalid payload name '%s'", name);
  172. break;
  173. }
  174. }
  175. nr = conftest->test->get_str(conftest->test,
  176. "hooks.%s.%s.bits", "", this->name, name);
  177. bits = enumerator_create_token(nr, ",", " ");
  178. while (bits->enumerate(bits, &nr))
  179. {
  180. set_bit(this, message, type, atoi(nr));
  181. }
  182. bits->destroy(bits);
  183. nr = conftest->test->get_str(conftest->test,
  184. "hooks.%s.%s.bytes", "", this->name, name);
  185. byteval = conftest->test->get_int(conftest->test,
  186. "hooks.%s.%s.byteval", 255, this->name, name);
  187. bytes = enumerator_create_token(nr, ",", " ");
  188. while (bytes->enumerate(bytes, &nr))
  189. {
  190. set_byte(this, message, type, atoi(nr), byteval);
  191. }
  192. bytes->destroy(bytes);
  193. }
  194. types->destroy(types);
  195. }
  196. return TRUE;
  197. }
  198. METHOD(hook_t, destroy, void,
  199. private_set_reserved_t *this)
  200. {
  201. free(this->name);
  202. free(this);
  203. }
  204. /**
  205. * Create the IKE_AUTH fill hook
  206. */
  207. hook_t *set_reserved_hook_create(char *name)
  208. {
  209. private_set_reserved_t *this;
  210. INIT(this,
  211. .hook = {
  212. .listener = {
  213. .message = _message,
  214. },
  215. .destroy = _destroy,
  216. },
  217. .req = conftest->test->get_bool(conftest->test,
  218. "hooks.%s.request", TRUE, name),
  219. .id = conftest->test->get_int(conftest->test,
  220. "hooks.%s.id", 0, name),
  221. .name = strdup(name),
  222. );
  223. return &this->hook;
  224. }