Return to transform_substructure.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libcharon / encoding / payloads |
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 "transform_substructure.h" 21: 22: #include <encoding/payloads/transform_attribute.h> 23: #include <encoding/payloads/encodings.h> 24: #include <library.h> 25: #include <collections/linked_list.h> 26: #include <daemon.h> 27: 28: typedef struct private_transform_substructure_t private_transform_substructure_t; 29: 30: /** 31: * Private data of an transform_substructure_t object. 32: */ 33: struct private_transform_substructure_t { 34: 35: /** 36: * Public transform_substructure_t interface. 37: */ 38: transform_substructure_t public; 39: 40: /** 41: * Next payload type. 42: */ 43: uint8_t next_payload; 44: 45: /** 46: * Reserved byte 47: */ 48: uint8_t reserved[3]; 49: 50: /** 51: * Length of this payload. 52: */ 53: uint16_t transform_length; 54: 55: /** 56: * Type or number, Type of the transform in IKEv2, number in IKEv2. 57: */ 58: uint8_t transform_ton; 59: 60: /** 61: * Transform ID, as encoded in IKEv1. 62: */ 63: uint8_t transform_id_v1; 64: 65: /** 66: * Transform ID, as encoded in IKEv2. 67: */ 68: uint16_t transform_id_v2; 69: 70: /** 71: * Transforms Attributes are stored in a linked_list_t. 72: */ 73: linked_list_t *attributes; 74: 75: /** 76: * Payload type, PLV2_TRANSFORM_SUBSTRUCTURE or PLV1_TRANSFORM_SUBSTRUCTURE 77: */ 78: payload_type_t type; 79: }; 80: 81: /** 82: * Encoding rules for PLV2_TRANSFORM_SUBSTRUCTURE 83: */ 84: static encoding_rule_t encodings_v2[] = { 85: /* 1 Byte next payload type, stored in the field next_payload */ 86: { U_INT_8, offsetof(private_transform_substructure_t, next_payload) }, 87: /* 1 Reserved Byte */ 88: { RESERVED_BYTE, offsetof(private_transform_substructure_t, reserved[0]) }, 89: /* Length of the whole transform substructure*/ 90: { PAYLOAD_LENGTH, offsetof(private_transform_substructure_t, transform_length)}, 91: /* transform type */ 92: { U_INT_8, offsetof(private_transform_substructure_t, transform_ton) }, 93: /* transform identifier, as used by IKEv1 */ 94: { RESERVED_BYTE, offsetof(private_transform_substructure_t, reserved[1]) }, 95: /* transform identifier, as used by IKEv2 */ 96: { U_INT_16, offsetof(private_transform_substructure_t, transform_id_v2) }, 97: /* Attributes in a transform attribute list */ 98: { PAYLOAD_LIST + PLV2_TRANSFORM_ATTRIBUTE, 99: offsetof(private_transform_substructure_t, attributes) } 100: }; 101: 102: /** 103: * Encoding rules for PLV1_TRANSFORM_SUBSTRUCTURE 104: */ 105: static encoding_rule_t encodings_v1[] = { 106: /* 1 Byte next payload type, stored in the field next_payload */ 107: { U_INT_8, offsetof(private_transform_substructure_t, next_payload) }, 108: /* 1 Reserved Byte */ 109: { RESERVED_BYTE, offsetof(private_transform_substructure_t, reserved[0]) }, 110: /* Length of the whole transform substructure*/ 111: { PAYLOAD_LENGTH, offsetof(private_transform_substructure_t, transform_length)}, 112: /* transform number */ 113: { U_INT_8, offsetof(private_transform_substructure_t, transform_ton)}, 114: /* transform identifier, as used by IKEv1 */ 115: { U_INT_8, offsetof(private_transform_substructure_t, transform_id_v1) }, 116: /* transform identifier, as used by IKEv2 */ 117: { RESERVED_BYTE, offsetof(private_transform_substructure_t, reserved[1]) }, 118: { RESERVED_BYTE, offsetof(private_transform_substructure_t, reserved[2]) }, 119: /* Attributes in a transform attribute list */ 120: { PAYLOAD_LIST + PLV1_TRANSFORM_ATTRIBUTE, 121: offsetof(private_transform_substructure_t, attributes) } 122: }; 123: 124: /* 125: 1 2 3 126: 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 127: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 128: ! 0 (last) or 3 ! RESERVED ! Transform Length ! 129: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 130: ! Tfrm Typ or # ! Tfrm ID IKEv1 ! Transform ID IKEv2 ! 131: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 132: ! ! 133: ~ Transform Attributes ~ 134: ! ! 135: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 136: */ 137: 138: METHOD(payload_t, verify, status_t, 139: private_transform_substructure_t *this) 140: { 141: status_t status = SUCCESS; 142: enumerator_t *enumerator; 143: payload_t *attribute; 144: 145: if (this->next_payload != PL_NONE && this->next_payload != 3) 146: { 147: DBG1(DBG_ENC, "inconsistent next payload"); 148: return FAILED; 149: } 150: 151: enumerator = this->attributes->create_enumerator(this->attributes); 152: while (enumerator->enumerate(enumerator, &attribute)) 153: { 154: status = attribute->verify(attribute); 155: if (status != SUCCESS) 156: { 157: DBG1(DBG_ENC, "TRANSFORM_ATTRIBUTE verification failed"); 158: break; 159: } 160: } 161: enumerator->destroy(enumerator); 162: 163: /* proposal number is checked in SA payload */ 164: return status; 165: } 166: 167: METHOD(payload_t, get_encoding_rules, int, 168: private_transform_substructure_t *this, encoding_rule_t **rules) 169: { 170: if (this->type == PLV2_TRANSFORM_SUBSTRUCTURE) 171: { 172: *rules = encodings_v2; 173: return countof(encodings_v2); 174: } 175: *rules = encodings_v1; 176: return countof(encodings_v1); 177: } 178: 179: METHOD(payload_t, get_header_length, int, 180: private_transform_substructure_t *this) 181: { 182: return 8; 183: } 184: 185: METHOD(payload_t, get_type, payload_type_t, 186: private_transform_substructure_t *this) 187: { 188: return this->type; 189: } 190: 191: METHOD(payload_t, get_next_type, payload_type_t, 192: private_transform_substructure_t *this) 193: { 194: return this->next_payload; 195: } 196: 197: /** 198: * recompute the length of the payload. 199: */ 200: static void compute_length(private_transform_substructure_t *this) 201: { 202: enumerator_t *enumerator; 203: payload_t *attribute; 204: 205: this->transform_length = get_header_length(this); 206: enumerator = this->attributes->create_enumerator(this->attributes); 207: while (enumerator->enumerate(enumerator, &attribute)) 208: { 209: this->transform_length += attribute->get_length(attribute); 210: } 211: enumerator->destroy(enumerator); 212: } 213: 214: METHOD(payload_t, get_length, size_t, 215: private_transform_substructure_t *this) 216: { 217: return this->transform_length; 218: } 219: 220: METHOD(transform_substructure_t, add_transform_attribute, void, 221: private_transform_substructure_t *this, transform_attribute_t *attribute) 222: { 223: this->attributes->insert_last(this->attributes, attribute); 224: compute_length(this); 225: } 226: 227: METHOD(transform_substructure_t, set_is_last_transform, void, 228: private_transform_substructure_t *this, bool is_last) 229: { 230: this->next_payload = is_last ? 0: TRANSFORM_TYPE_VALUE; 231: } 232: 233: METHOD(payload_t, set_next_type, void, 234: private_transform_substructure_t *this,payload_type_t type) 235: { 236: } 237: 238: METHOD(transform_substructure_t, get_transform_type_or_number, uint8_t, 239: private_transform_substructure_t *this) 240: { 241: return this->transform_ton; 242: } 243: 244: METHOD(transform_substructure_t, get_transform_id, uint16_t, 245: private_transform_substructure_t *this) 246: { 247: if (this->type == PLV2_TRANSFORM_SUBSTRUCTURE) 248: { 249: return this->transform_id_v2; 250: } 251: return this->transform_id_v1; 252: } 253: 254: METHOD(transform_substructure_t, create_attribute_enumerator, enumerator_t*, 255: private_transform_substructure_t *this) 256: { 257: return this->attributes->create_enumerator(this->attributes); 258: } 259: 260: METHOD2(payload_t, transform_substructure_t, destroy, void, 261: private_transform_substructure_t *this) 262: { 263: this->attributes->destroy_offset(this->attributes, 264: offsetof(payload_t, destroy)); 265: free(this); 266: } 267: 268: /* 269: * Described in header. 270: */ 271: transform_substructure_t *transform_substructure_create(payload_type_t type) 272: { 273: private_transform_substructure_t *this; 274: 275: INIT(this, 276: .public = { 277: .payload_interface = { 278: .verify = _verify, 279: .get_encoding_rules = _get_encoding_rules, 280: .get_header_length = _get_header_length, 281: .get_length = _get_length, 282: .get_next_type = _get_next_type, 283: .set_next_type = _set_next_type, 284: .get_type = _get_type, 285: .destroy = _destroy, 286: }, 287: .add_transform_attribute = _add_transform_attribute, 288: .set_is_last_transform = _set_is_last_transform, 289: .get_transform_type_or_number = _get_transform_type_or_number, 290: .get_transform_id = _get_transform_id, 291: .create_attribute_enumerator = _create_attribute_enumerator, 292: .destroy = _destroy, 293: }, 294: .next_payload = PL_NONE, 295: .transform_length = get_header_length(this), 296: .attributes = linked_list_create(), 297: .type = type, 298: ); 299: return &this->public; 300: } 301: 302: /* 303: * Described in header 304: */ 305: transform_substructure_t *transform_substructure_create_type(payload_type_t type, 306: uint8_t type_or_number, uint16_t id) 307: { 308: private_transform_substructure_t *this; 309: 310: this = (private_transform_substructure_t*)transform_substructure_create(type); 311: 312: this->transform_ton = type_or_number; 313: if (type == PLV2_TRANSFORM_SUBSTRUCTURE) 314: { 315: this->transform_id_v2 = id; 316: } 317: else 318: { 319: this->transform_id_v1 = id; 320: } 321: return &this->public; 322: } 323: