Return to cp_payload.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 "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: }