Annotation of embedaddon/strongswan/src/libcharon/encoding/payloads/cp_payload.c, revision 1.1
1.1 ! misho 1: /*
! 2: * Copyright (C) 2005-2010 Martin Willi
! 3: * Copyright (C) 2010 revosec AG
! 4: * Copyright (C) 2005 Jan Hutter
! 5: * HSR 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: #include <stddef.h>
! 19:
! 20: #include "cp_payload.h"
! 21:
! 22: #include <encoding/payloads/encodings.h>
! 23: #include <collections/linked_list.h>
! 24:
! 25: ENUM(config_type_names, CFG_REQUEST, CFG_ACK,
! 26: "CFG_REQUEST",
! 27: "CFG_REPLY",
! 28: "CFG_SET",
! 29: "CFG_ACK",
! 30: );
! 31:
! 32: typedef struct private_cp_payload_t private_cp_payload_t;
! 33:
! 34: /**
! 35: * Private data of an cp_payload_t object.
! 36: */
! 37: struct private_cp_payload_t {
! 38:
! 39: /**
! 40: * Public cp_payload_t interface.
! 41: */
! 42: cp_payload_t public;
! 43:
! 44: /**
! 45: * Next payload type.
! 46: */
! 47: uint8_t next_payload;
! 48:
! 49: /**
! 50: * Critical flag.
! 51: */
! 52: bool critical;
! 53:
! 54: /**
! 55: * Reserved bits
! 56: */
! 57: bool reserved_bit[7];
! 58:
! 59: /**
! 60: * Reserved bytes
! 61: */
! 62: uint8_t reserved_byte[3];
! 63:
! 64: /**
! 65: * Length of this payload.
! 66: */
! 67: uint16_t payload_length;
! 68:
! 69: /**
! 70: * Identifier field, IKEv1 only
! 71: */
! 72: uint16_t identifier;
! 73:
! 74: /**
! 75: * List of attributes, as configuration_attribute_t
! 76: */
! 77: linked_list_t *attributes;
! 78:
! 79: /**
! 80: * Config Type.
! 81: */
! 82: uint8_t cfg_type;
! 83:
! 84: /**
! 85: * PLV2_CONFIGURATION or PLV1_CONFIGURATION
! 86: */
! 87: payload_type_t type;
! 88: };
! 89:
! 90: /**
! 91: * Encoding rules to for an IKEv2 configuration payload
! 92: */
! 93: static encoding_rule_t encodings_v2[] = {
! 94: /* 1 Byte next payload type, stored in the field next_payload */
! 95: { U_INT_8, offsetof(private_cp_payload_t, next_payload) },
! 96: /* the critical bit */
! 97: { FLAG, offsetof(private_cp_payload_t, critical) },
! 98: /* 7 Bit reserved bits */
! 99: { RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[0]) },
! 100: { RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[1]) },
! 101: { RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[2]) },
! 102: { RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[3]) },
! 103: { RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[4]) },
! 104: { RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[5]) },
! 105: { RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[6]) },
! 106: /* Length of the whole CP payload*/
! 107: { PAYLOAD_LENGTH, offsetof(private_cp_payload_t, payload_length) },
! 108: { U_INT_8, offsetof(private_cp_payload_t, cfg_type) },
! 109: /* 3 reserved bytes */
! 110: { RESERVED_BYTE, offsetof(private_cp_payload_t, reserved_byte[0])},
! 111: { RESERVED_BYTE, offsetof(private_cp_payload_t, reserved_byte[1])},
! 112: { RESERVED_BYTE, offsetof(private_cp_payload_t, reserved_byte[2])},
! 113: /* list of configuration attributes in a list */
! 114: { PAYLOAD_LIST + PLV2_CONFIGURATION_ATTRIBUTE,
! 115: offsetof(private_cp_payload_t, attributes) },
! 116: };
! 117:
! 118: /*
! 119: 1 2 3
! 120: 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
! 121: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
! 122: ! Next Payload !C! RESERVED ! Payload Length !
! 123: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
! 124: ! CFG Type ! RESERVED !
! 125: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
! 126: ! !
! 127: ~ Configuration Attributes ~
! 128: ! !
! 129: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
! 130: */
! 131:
! 132: /**
! 133: * Encoding rules to for an IKEv1 configuration payload
! 134: */
! 135: static encoding_rule_t encodings_v1[] = {
! 136: /* 1 Byte next payload type, stored in the field next_payload */
! 137: { U_INT_8, offsetof(private_cp_payload_t, next_payload) },
! 138: /* the critical bit */
! 139: { FLAG, offsetof(private_cp_payload_t, critical) },
! 140: /* 7 Bit reserved bits */
! 141: { RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[0]) },
! 142: { RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[1]) },
! 143: { RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[2]) },
! 144: { RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[3]) },
! 145: { RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[4]) },
! 146: { RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[5]) },
! 147: { RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[6]) },
! 148: /* Length of the whole CP payload*/
! 149: { PAYLOAD_LENGTH, offsetof(private_cp_payload_t, payload_length) },
! 150: { U_INT_8, offsetof(private_cp_payload_t, cfg_type) },
! 151: /* 1 reserved bytes */
! 152: { RESERVED_BYTE, offsetof(private_cp_payload_t, reserved_byte[0])},
! 153: { U_INT_16, offsetof(private_cp_payload_t, identifier)},
! 154: /* list of configuration attributes in a list */
! 155: { PAYLOAD_LIST + PLV1_CONFIGURATION_ATTRIBUTE,
! 156: offsetof(private_cp_payload_t, attributes) },
! 157: };
! 158:
! 159: /*
! 160: 1 2 3
! 161: 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
! 162: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
! 163: ! Next Payload ! RESERVED ! Payload Length !
! 164: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
! 165: ! CFG Type ! RESERVED ! Identifier !
! 166: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
! 167: ! !
! 168: ~ Configuration Attributes ~
! 169: ! !
! 170: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
! 171: */
! 172:
! 173: METHOD(payload_t, verify, status_t,
! 174: private_cp_payload_t *this)
! 175: {
! 176: status_t status = SUCCESS;
! 177: enumerator_t *enumerator;
! 178: payload_t *attribute;
! 179:
! 180: enumerator = this->attributes->create_enumerator(this->attributes);
! 181: while (enumerator->enumerate(enumerator, &attribute))
! 182: {
! 183: status = attribute->verify(attribute);
! 184: if (status != SUCCESS)
! 185: {
! 186: break;
! 187: }
! 188: }
! 189: enumerator->destroy(enumerator);
! 190: return status;
! 191: }
! 192:
! 193: METHOD(payload_t, get_encoding_rules, int,
! 194: private_cp_payload_t *this, encoding_rule_t **rules)
! 195: {
! 196: if (this->type == PLV2_CONFIGURATION)
! 197: {
! 198: *rules = encodings_v2;
! 199: return countof(encodings_v2);
! 200: }
! 201: *rules = encodings_v1;
! 202: return countof(encodings_v1);
! 203: }
! 204:
! 205: METHOD(payload_t, get_header_length, int,
! 206: private_cp_payload_t *this)
! 207: {
! 208: return 8;
! 209: }
! 210:
! 211: METHOD(payload_t, get_type, payload_type_t,
! 212: private_cp_payload_t *this)
! 213: {
! 214: return this->type;
! 215: }
! 216:
! 217: METHOD(payload_t, get_next_type, payload_type_t,
! 218: private_cp_payload_t *this)
! 219: {
! 220: return this->next_payload;
! 221: }
! 222:
! 223: METHOD(payload_t, set_next_type, void,
! 224: private_cp_payload_t *this,payload_type_t type)
! 225: {
! 226: this->next_payload = type;
! 227: }
! 228:
! 229: /**
! 230: * recompute the length of the payload.
! 231: */
! 232: static void compute_length(private_cp_payload_t *this)
! 233: {
! 234: enumerator_t *enumerator;
! 235: payload_t *attribute;
! 236:
! 237: this->payload_length = get_header_length(this);
! 238:
! 239: enumerator = this->attributes->create_enumerator(this->attributes);
! 240: while (enumerator->enumerate(enumerator, &attribute))
! 241: {
! 242: this->payload_length += attribute->get_length(attribute);
! 243: }
! 244: enumerator->destroy(enumerator);
! 245: }
! 246:
! 247: METHOD(payload_t, get_length, size_t,
! 248: private_cp_payload_t *this)
! 249: {
! 250: return this->payload_length;
! 251: }
! 252:
! 253: METHOD(cp_payload_t, create_attribute_enumerator, enumerator_t*,
! 254: private_cp_payload_t *this)
! 255: {
! 256: return this->attributes->create_enumerator(this->attributes);
! 257: }
! 258:
! 259: METHOD(cp_payload_t, add_attribute, void,
! 260: private_cp_payload_t *this, configuration_attribute_t *attribute)
! 261: {
! 262: this->attributes->insert_last(this->attributes, attribute);
! 263: compute_length(this);
! 264: }
! 265:
! 266: METHOD(cp_payload_t, get_config_type, config_type_t,
! 267: private_cp_payload_t *this)
! 268: {
! 269: return this->cfg_type;
! 270: }
! 271:
! 272: METHOD(cp_payload_t, get_identifier, uint16_t,
! 273: private_cp_payload_t *this)
! 274: {
! 275: return this->identifier;
! 276: }
! 277: METHOD(cp_payload_t, set_identifier, void,
! 278: private_cp_payload_t *this, uint16_t identifier)
! 279: {
! 280: this->identifier = identifier;
! 281: }
! 282:
! 283: METHOD2(payload_t, cp_payload_t, destroy, void,
! 284: private_cp_payload_t *this)
! 285: {
! 286: this->attributes->destroy_offset(this->attributes,
! 287: offsetof(configuration_attribute_t, destroy));
! 288: free(this);
! 289: }
! 290:
! 291: /*
! 292: * Described in header.
! 293: */
! 294: cp_payload_t *cp_payload_create_type(payload_type_t type, config_type_t cfg_type)
! 295: {
! 296: private_cp_payload_t *this;
! 297:
! 298: INIT(this,
! 299: .public = {
! 300: .payload_interface = {
! 301: .verify = _verify,
! 302: .get_encoding_rules = _get_encoding_rules,
! 303: .get_header_length = _get_header_length,
! 304: .get_length = _get_length,
! 305: .get_next_type = _get_next_type,
! 306: .set_next_type = _set_next_type,
! 307: .get_type = _get_type,
! 308: .destroy = _destroy,
! 309: },
! 310: .create_attribute_enumerator = _create_attribute_enumerator,
! 311: .add_attribute = _add_attribute,
! 312: .get_type = _get_config_type,
! 313: .get_identifier = _get_identifier,
! 314: .set_identifier = _set_identifier,
! 315: .destroy = _destroy,
! 316: },
! 317: .next_payload = PL_NONE,
! 318: .payload_length = get_header_length(this),
! 319: .attributes = linked_list_create(),
! 320: .cfg_type = cfg_type,
! 321: .type = type,
! 322: );
! 323: return &this->public;
! 324: }
! 325:
! 326: /*
! 327: * Described in header.
! 328: */
! 329: cp_payload_t *cp_payload_create(payload_type_t type)
! 330: {
! 331: return cp_payload_create_type(type, CFG_REQUEST);
! 332: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>