Annotation of embedaddon/strongswan/src/libcharon/encoding/payloads/ike_header.c, revision 1.1
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: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>