Return to ike_header.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libcharon / encoding / payloads |
1.1 misho 1: /* 2: * Copyright (C) 2007 Tobias Brunner 3: * Copyright (C) 2005-2006 Martin Willi 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: /* offsetof macro */ 19: #include <stddef.h> 20: 21: #include "ike_header.h" 22: 23: #include <encoding/payloads/encodings.h> 24: 25: 26: typedef struct private_ike_header_t private_ike_header_t; 27: 28: /** 29: * Private data of an ike_header_t object. 30: */ 31: struct private_ike_header_t { 32: /** 33: * Public interface. 34: */ 35: ike_header_t public; 36: 37: /** 38: * SPI of the initiator. 39: */ 40: uint64_t initiator_spi; 41: 42: /** 43: * SPI of the responder. 44: */ 45: uint64_t responder_spi; 46: 47: /** 48: * Next payload type. 49: */ 50: uint8_t next_payload; 51: /** 52: * IKE major version. 53: */ 54: uint8_t maj_version; 55: 56: /** 57: * IKE minor version. 58: */ 59: uint8_t min_version; 60: 61: /** 62: * Exchange type . 63: */ 64: uint8_t exchange_type; 65: 66: /** 67: * Flags of the Message. 68: */ 69: struct { 70: /** 71: * Sender is initiator of the associated IKE_SA_INIT-Exchange. 72: */ 73: bool initiator; 74: 75: /** 76: * Is protocol supporting higher version? 77: */ 78: bool version; 79: 80: /** 81: * TRUE, if this is a response, FALSE if its a Request. 82: */ 83: bool response; 84: 85: /** 86: * TRUE, if the packet is encrypted (IKEv1). 87: */ 88: bool encryption; 89: 90: /** 91: * TRUE, if the commit flag is set (IKEv1). 92: */ 93: bool commit; 94: 95: /** 96: * TRUE, if the auth only flag is set (IKEv1). 97: */ 98: bool authonly; 99: } flags; 100: 101: /** 102: * Reserved bits of IKE header 103: */ 104: bool reserved[2]; 105: 106: /** 107: * Associated Message-ID. 108: */ 109: uint32_t message_id; 110: 111: /** 112: * Length of the whole IKEv2-Message (header and all payloads). 113: */ 114: uint32_t length; 115: }; 116: 117: ENUM_BEGIN(exchange_type_names, ID_PROT, TRANSACTION, 118: "ID_PROT", 119: "AUTH_ONLY", 120: "AGGRESSIVE", 121: "INFORMATIONAL_V1", 122: "TRANSACTION"); 123: ENUM_NEXT(exchange_type_names, QUICK_MODE, IKE_SESSION_RESUME, TRANSACTION, 124: "QUICK_MODE", 125: "NEW_GROUP_MODE", 126: "IKE_SA_INIT", 127: "IKE_AUTH", 128: "CREATE_CHILD_SA", 129: "INFORMATIONAL", 130: "IKE_SESSION_RESUME"); 131: #ifdef ME 132: ENUM_NEXT(exchange_type_names, ME_CONNECT, ME_CONNECT, IKE_SESSION_RESUME, 133: "ME_CONNECT"); 134: ENUM_NEXT(exchange_type_names, EXCHANGE_TYPE_UNDEFINED, 135: EXCHANGE_TYPE_UNDEFINED, ME_CONNECT, 136: "EXCHANGE_TYPE_UNDEFINED"); 137: #else 138: ENUM_NEXT(exchange_type_names, EXCHANGE_TYPE_UNDEFINED, 139: EXCHANGE_TYPE_UNDEFINED, IKE_SESSION_RESUME, 140: "EXCHANGE_TYPE_UNDEFINED"); 141: #endif /* ME */ 142: ENUM_END(exchange_type_names, EXCHANGE_TYPE_UNDEFINED); 143: 144: /** 145: * Encoding rules to parse or generate a IKE-Header. 146: * 147: * The defined offsets are the positions in a object of type 148: * ike_header_t. 149: */ 150: static encoding_rule_t encodings[] = { 151: /* 8 Byte SPI, stored in the field initiator_spi */ 152: { IKE_SPI, offsetof(private_ike_header_t, initiator_spi) }, 153: /* 8 Byte SPI, stored in the field responder_spi */ 154: { IKE_SPI, offsetof(private_ike_header_t, responder_spi) }, 155: /* 1 Byte next payload type, stored in the field next_payload */ 156: { U_INT_8, offsetof(private_ike_header_t, next_payload) }, 157: /* 4 Bit major version, stored in the field maj_version */ 158: { U_INT_4, offsetof(private_ike_header_t, maj_version) }, 159: /* 4 Bit minor version, stored in the field min_version */ 160: { U_INT_4, offsetof(private_ike_header_t, min_version) }, 161: /* 8 Bit for the exchange type */ 162: { U_INT_8, offsetof(private_ike_header_t, exchange_type) }, 163: /* 2 Bit reserved bits */ 164: { RESERVED_BIT, offsetof(private_ike_header_t, reserved[0]) }, 165: { RESERVED_BIT, offsetof(private_ike_header_t, reserved[1]) }, 166: /* 6 flags */ 167: { FLAG, offsetof(private_ike_header_t, flags.response) }, 168: { FLAG, offsetof(private_ike_header_t, flags.version) }, 169: { FLAG, offsetof(private_ike_header_t, flags.initiator) }, 170: { FLAG, offsetof(private_ike_header_t, flags.authonly) }, 171: { FLAG, offsetof(private_ike_header_t, flags.commit) }, 172: { FLAG, offsetof(private_ike_header_t, flags.encryption)}, 173: /* 4 Byte message id, stored in the field message_id */ 174: { U_INT_32, offsetof(private_ike_header_t, message_id) }, 175: /* 4 Byte length field, stored in the field length */ 176: { HEADER_LENGTH, offsetof(private_ike_header_t, length) } 177: }; 178: 179: /* 1 2 3 180: 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 181: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 182: ! IKE_SA Initiator's SPI ! 183: ! ! 184: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 185: ! IKE_SA Responder's SPI ! 186: ! ! 187: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 188: ! Next Payload ! MjVer ! MnVer ! Exchange Type ! Flags ! 189: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 190: ! Message ID ! 191: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 192: ! Length ! 193: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 194: */ 195: 196: METHOD(payload_t, verify, status_t, 197: private_ike_header_t *this) 198: { 199: switch (this->exchange_type) 200: { 201: case ID_PROT: 202: case AGGRESSIVE: 203: if (this->message_id != 0) 204: { 205: return FAILED; 206: } 207: /* fall */ 208: case AUTH_ONLY: 209: case INFORMATIONAL_V1: 210: case TRANSACTION: 211: case QUICK_MODE: 212: case NEW_GROUP_MODE: 213: if (this->maj_version == IKEV2_MAJOR_VERSION) 214: { 215: /* IKEv1 exchange type in IKEv2? */ 216: return FAILED; 217: } 218: break; 219: case IKE_SA_INIT: 220: case IKE_AUTH: 221: case CREATE_CHILD_SA: 222: case INFORMATIONAL: 223: case IKE_SESSION_RESUME: 224: #ifdef ME 225: case ME_CONNECT: 226: #endif /* ME */ 227: if (this->maj_version == IKEV1_MAJOR_VERSION) 228: { 229: /* IKEv2 exchange type in IKEv1? */ 230: return FAILED; 231: } 232: break; 233: default: 234: if (this->maj_version == IKEV1_MAJOR_VERSION || 235: this->maj_version == IKEV2_MAJOR_VERSION) 236: { 237: /* unsupported exchange type for known version */ 238: return FAILED; 239: } 240: break; 241: } 242: if (this->initiator_spi == 0) 243: { 244: #ifdef ME 245: if (this->exchange_type != INFORMATIONAL) 246: /* we allow zero spi for INFORMATIONAL exchanges, 247: * to allow connectivity checks */ 248: #endif /* ME */ 249: { 250: return FAILED; 251: } 252: } 253: return SUCCESS; 254: } 255: 256: METHOD(payload_t, get_encoding_rules, int, 257: private_ike_header_t *this, encoding_rule_t **rules) 258: { 259: *rules = encodings; 260: return countof(encodings); 261: } 262: 263: METHOD(payload_t, get_header_length, int, 264: private_ike_header_t *this) 265: { 266: return IKE_HEADER_LENGTH; 267: } 268: 269: METHOD(payload_t, get_type, payload_type_t, 270: private_ike_header_t *this) 271: { 272: return PL_HEADER; 273: } 274: 275: METHOD(payload_t, get_next_type, payload_type_t, 276: private_ike_header_t *this) 277: { 278: return this->next_payload; 279: } 280: 281: METHOD(payload_t, set_next_type, void, 282: private_ike_header_t *this, payload_type_t type) 283: { 284: this->next_payload = type; 285: } 286: 287: METHOD(payload_t, get_length, size_t, 288: private_ike_header_t *this) 289: { 290: return this->length; 291: } 292: 293: METHOD(ike_header_t, get_initiator_spi, uint64_t, 294: private_ike_header_t *this) 295: { 296: return this->initiator_spi; 297: } 298: 299: METHOD(ike_header_t, set_initiator_spi, void, 300: private_ike_header_t *this, uint64_t initiator_spi) 301: { 302: this->initiator_spi = initiator_spi; 303: } 304: 305: METHOD(ike_header_t, get_responder_spi, uint64_t, 306: private_ike_header_t *this) 307: { 308: return this->responder_spi; 309: } 310: 311: METHOD(ike_header_t, set_responder_spi, void, 312: private_ike_header_t *this, uint64_t responder_spi) 313: { 314: this->responder_spi = responder_spi; 315: } 316: 317: METHOD(ike_header_t, get_maj_version, uint8_t, 318: private_ike_header_t *this) 319: { 320: return this->maj_version; 321: } 322: 323: METHOD(ike_header_t, set_maj_version, void, 324: private_ike_header_t *this, uint8_t major) 325: { 326: this->maj_version = major; 327: } 328: 329: METHOD(ike_header_t, get_min_version, uint8_t, 330: private_ike_header_t *this) 331: { 332: return this->min_version; 333: } 334: 335: METHOD(ike_header_t, set_min_version, void, 336: private_ike_header_t *this, uint8_t minor) 337: { 338: this->min_version = minor; 339: } 340: 341: METHOD(ike_header_t, get_response_flag, bool, 342: private_ike_header_t *this) 343: { 344: return this->flags.response; 345: } 346: 347: METHOD(ike_header_t, set_response_flag, void, 348: private_ike_header_t *this, bool response) 349: { 350: this->flags.response = response; 351: } 352: 353: METHOD(ike_header_t, get_version_flag, bool, 354: private_ike_header_t *this) 355: { 356: return this->flags.version; 357: } 358: 359: METHOD(ike_header_t, set_version_flag, void, 360: private_ike_header_t *this, bool version) 361: { 362: this->flags.version = version; 363: } 364: 365: METHOD(ike_header_t, get_initiator_flag, bool, 366: private_ike_header_t *this) 367: { 368: return this->flags.initiator; 369: } 370: 371: METHOD(ike_header_t, set_initiator_flag, void, 372: private_ike_header_t *this, bool initiator) 373: { 374: this->flags.initiator = initiator; 375: } 376: 377: METHOD(ike_header_t, get_encryption_flag, bool, 378: private_ike_header_t *this) 379: { 380: return this->flags.encryption; 381: } 382: 383: METHOD(ike_header_t, set_encryption_flag, void, 384: private_ike_header_t *this, bool encryption) 385: { 386: this->flags.encryption = encryption; 387: } 388: 389: 390: METHOD(ike_header_t, get_commit_flag, bool, 391: private_ike_header_t *this) 392: { 393: return this->flags.commit; 394: } 395: 396: METHOD(ike_header_t, set_commit_flag, void, 397: private_ike_header_t *this, bool commit) 398: { 399: this->flags.commit = commit; 400: } 401: 402: METHOD(ike_header_t, get_authonly_flag, bool, 403: private_ike_header_t *this) 404: { 405: return this->flags.authonly; 406: } 407: 408: METHOD(ike_header_t, set_authonly_flag, void, 409: private_ike_header_t *this, bool authonly) 410: { 411: this->flags.authonly = authonly; 412: } 413: 414: METHOD(ike_header_t, get_exchange_type, uint8_t, 415: private_ike_header_t *this) 416: { 417: return this->exchange_type; 418: } 419: 420: METHOD(ike_header_t, set_exchange_type, void, 421: private_ike_header_t *this, uint8_t exchange_type) 422: { 423: this->exchange_type = exchange_type; 424: } 425: 426: METHOD(ike_header_t, get_message_id, uint32_t, 427: private_ike_header_t *this) 428: { 429: return this->message_id; 430: } 431: 432: METHOD(ike_header_t, set_message_id, void, 433: private_ike_header_t *this, uint32_t message_id) 434: { 435: this->message_id = message_id; 436: } 437: 438: METHOD2(payload_t, ike_header_t, destroy, void, 439: private_ike_header_t *this) 440: { 441: free(this); 442: } 443: 444: /* 445: * Described in header. 446: */ 447: ike_header_t *ike_header_create() 448: { 449: private_ike_header_t *this; 450: 451: INIT(this, 452: .public = { 453: .payload_interface = { 454: .verify = _verify, 455: .get_encoding_rules = _get_encoding_rules, 456: .get_header_length = _get_header_length, 457: .get_length = _get_length, 458: .get_next_type = _get_next_type, 459: .set_next_type = _set_next_type, 460: .get_type = _get_type, 461: .destroy = _destroy, 462: }, 463: .get_initiator_spi = _get_initiator_spi, 464: .set_initiator_spi = _set_initiator_spi, 465: .get_responder_spi = _get_responder_spi, 466: .set_responder_spi = _set_responder_spi, 467: .get_maj_version = _get_maj_version, 468: .set_maj_version = _set_maj_version, 469: .get_min_version = _get_min_version, 470: .set_min_version = _set_min_version, 471: .get_response_flag = _get_response_flag, 472: .set_response_flag = _set_response_flag, 473: .get_version_flag = _get_version_flag, 474: .set_version_flag = _set_version_flag, 475: .get_initiator_flag = _get_initiator_flag, 476: .set_initiator_flag = _set_initiator_flag, 477: .get_encryption_flag = _get_encryption_flag, 478: .set_encryption_flag = _set_encryption_flag, 479: .get_commit_flag = _get_commit_flag, 480: .set_commit_flag = _set_commit_flag, 481: .get_authonly_flag = _get_authonly_flag, 482: .set_authonly_flag = _set_authonly_flag, 483: .get_exchange_type = _get_exchange_type, 484: .set_exchange_type = _set_exchange_type, 485: .get_message_id = _get_message_id, 486: .set_message_id = _set_message_id, 487: .destroy = _destroy, 488: }, 489: .length = IKE_HEADER_LENGTH, 490: .exchange_type = EXCHANGE_TYPE_UNDEFINED, 491: ); 492: 493: return &this->public; 494: } 495: 496: /* 497: * Described in header. 498: */ 499: ike_header_t *ike_header_create_version(int major, int minor) 500: { 501: ike_header_t *this = ike_header_create(); 502: 503: this->set_maj_version(this, major); 504: this->set_min_version(this, minor); 505: if (major == IKEV2_MAJOR_VERSION) 506: { 507: this->set_initiator_flag(this, TRUE); 508: } 509: return this; 510: }