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>