Annotation of embedaddon/strongswan/src/libcharon/encoding/payloads/delete_payload.c, revision 1.1
1.1 ! misho 1: /*
! 2: * Copyright (C) 2015 Tobias Brunner
! 3: * Copyright (C) 2005-2010 Martin Willi
! 4: * Copyright (C) 2010 revosec AG
! 5: * Copyright (C) 2005 Jan Hutter
! 6: * HSR Hochschule fuer Technik Rapperswil
! 7: *
! 8: * This program is free software; you can redistribute it and/or modify it
! 9: * under the terms of the GNU General Public License as published by the
! 10: * Free Software Foundation; either version 2 of the License, or (at your
! 11: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
! 12: *
! 13: * This program is distributed in the hope that it will be useful, but
! 14: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
! 15: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
! 16: * for more details.
! 17: */
! 18:
! 19: #include <stddef.h>
! 20:
! 21: #include "delete_payload.h"
! 22:
! 23:
! 24: typedef struct private_delete_payload_t private_delete_payload_t;
! 25:
! 26: /**
! 27: * Private data of an delete_payload_t object.
! 28: */
! 29: struct private_delete_payload_t {
! 30:
! 31: /**
! 32: * Public delete_payload_t interface.
! 33: */
! 34: delete_payload_t public;
! 35:
! 36: /**
! 37: * Next payload type.
! 38: */
! 39: uint8_t next_payload;
! 40:
! 41: /**
! 42: * Critical flag.
! 43: */
! 44: bool critical;
! 45:
! 46: /**
! 47: * reserved bits
! 48: */
! 49: bool reserved[8];
! 50:
! 51: /**
! 52: * Length of this payload.
! 53: */
! 54: uint16_t payload_length;
! 55:
! 56: /**
! 57: * IKEv1 Domain of Interpretation
! 58: */
! 59: uint32_t doi;
! 60:
! 61: /**
! 62: * Protocol ID.
! 63: */
! 64: uint8_t protocol_id;
! 65:
! 66: /**
! 67: * SPI Size.
! 68: */
! 69: uint8_t spi_size;
! 70:
! 71: /**
! 72: * Number of SPI's.
! 73: */
! 74: uint16_t spi_count;
! 75:
! 76: /**
! 77: * The contained SPI's.
! 78: */
! 79: chunk_t spis;
! 80:
! 81: /**
! 82: * Payload type, PLV2_DELETE or PLV1_DELETE
! 83: */
! 84: payload_type_t type;
! 85: };
! 86:
! 87: /**
! 88: * Encoding rules for an IKEv2 delete payload.
! 89: */
! 90: static encoding_rule_t encodings_v2[] = {
! 91: /* 1 Byte next payload type, stored in the field next_payload */
! 92: { U_INT_8, offsetof(private_delete_payload_t, next_payload) },
! 93: /* the critical bit */
! 94: { FLAG, offsetof(private_delete_payload_t, critical) },
! 95: /* 7 Bit reserved bits */
! 96: { RESERVED_BIT, offsetof(private_delete_payload_t, reserved[0]) },
! 97: { RESERVED_BIT, offsetof(private_delete_payload_t, reserved[1]) },
! 98: { RESERVED_BIT, offsetof(private_delete_payload_t, reserved[2]) },
! 99: { RESERVED_BIT, offsetof(private_delete_payload_t, reserved[3]) },
! 100: { RESERVED_BIT, offsetof(private_delete_payload_t, reserved[4]) },
! 101: { RESERVED_BIT, offsetof(private_delete_payload_t, reserved[5]) },
! 102: { RESERVED_BIT, offsetof(private_delete_payload_t, reserved[6]) },
! 103: /* Length of the whole payload*/
! 104: { PAYLOAD_LENGTH, offsetof(private_delete_payload_t, payload_length) },
! 105: { U_INT_8, offsetof(private_delete_payload_t, protocol_id) },
! 106: { U_INT_8, offsetof(private_delete_payload_t, spi_size) },
! 107: { U_INT_16, offsetof(private_delete_payload_t, spi_count) },
! 108: /* some delete data bytes, length is defined in PAYLOAD_LENGTH */
! 109: { CHUNK_DATA, offsetof(private_delete_payload_t, spis) },
! 110: };
! 111:
! 112: /*
! 113: 1 2 3
! 114: 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
! 115: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
! 116: ! Next Payload !C! RESERVED ! Payload Length !
! 117: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
! 118: ! Protocol ID ! SPI Size ! # of SPIs !
! 119: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
! 120: ! !
! 121: ~ Security Parameter Index(es) (SPI) ~
! 122: ! !
! 123: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
! 124: */
! 125:
! 126: /**
! 127: * Encoding rules for an IKEv1 delete payload.
! 128: */
! 129: static encoding_rule_t encodings_v1[] = {
! 130: /* 1 Byte next payload type, stored in the field next_payload */
! 131: { U_INT_8, offsetof(private_delete_payload_t, next_payload) },
! 132: /* 8 Bit reserved bits */
! 133: { RESERVED_BIT, offsetof(private_delete_payload_t, reserved[0]) },
! 134: { RESERVED_BIT, offsetof(private_delete_payload_t, reserved[1]) },
! 135: { RESERVED_BIT, offsetof(private_delete_payload_t, reserved[2]) },
! 136: { RESERVED_BIT, offsetof(private_delete_payload_t, reserved[3]) },
! 137: { RESERVED_BIT, offsetof(private_delete_payload_t, reserved[4]) },
! 138: { RESERVED_BIT, offsetof(private_delete_payload_t, reserved[5]) },
! 139: { RESERVED_BIT, offsetof(private_delete_payload_t, reserved[6]) },
! 140: { RESERVED_BIT, offsetof(private_delete_payload_t, reserved[7]) },
! 141: /* Length of the whole payload*/
! 142: { PAYLOAD_LENGTH, offsetof(private_delete_payload_t, payload_length) },
! 143: /* Domain of interpretation */
! 144: { U_INT_32, offsetof(private_delete_payload_t, doi) },
! 145: { U_INT_8, offsetof(private_delete_payload_t, protocol_id) },
! 146: { U_INT_8, offsetof(private_delete_payload_t, spi_size) },
! 147: { U_INT_16, offsetof(private_delete_payload_t, spi_count) },
! 148: /* some delete data bytes, length is defined in PAYLOAD_LENGTH */
! 149: { CHUNK_DATA, offsetof(private_delete_payload_t, spis) },
! 150: };
! 151:
! 152: /*
! 153: 1 2 3
! 154: 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
! 155: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
! 156: ! Next Payload !C! RESERVED ! Payload Length !
! 157: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
! 158: ! DOI !
! 159: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
! 160: ! Protocol ID ! SPI Size ! # of SPIs !
! 161: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
! 162: ! !
! 163: ~ Security Parameter Index(es) (SPI) ~
! 164: ! !
! 165: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
! 166: */
! 167:
! 168: METHOD(payload_t, verify, status_t,
! 169: private_delete_payload_t *this)
! 170: {
! 171: switch (this->protocol_id)
! 172: {
! 173: case PROTO_AH:
! 174: case PROTO_ESP:
! 175: if (this->spi_size != 4)
! 176: {
! 177: return FAILED;
! 178: }
! 179: break;
! 180: case PROTO_IKE:
! 181: case 0:
! 182: if (this->type == PLV2_DELETE)
! 183: { /* IKEv2 deletion has no spi assigned! */
! 184: if (this->spi_size != 0)
! 185: {
! 186: return FAILED;
! 187: }
! 188: }
! 189: else
! 190: { /* IKEv1 uses the two concatenated ISAKMP cookies as SPI */
! 191: if (this->spi_size != 16)
! 192: {
! 193: return FAILED;
! 194: }
! 195: }
! 196: break;
! 197: default:
! 198: return FAILED;
! 199: }
! 200: if (this->spis.len != (this->spi_count * this->spi_size))
! 201: {
! 202: return FAILED;
! 203: }
! 204: return SUCCESS;
! 205: }
! 206:
! 207: METHOD(payload_t, get_encoding_rules, int,
! 208: private_delete_payload_t *this, encoding_rule_t **rules)
! 209: {
! 210: if (this->type == PLV2_DELETE)
! 211: {
! 212: *rules = encodings_v2;
! 213: return countof(encodings_v2);
! 214: }
! 215: *rules = encodings_v1;
! 216: return countof(encodings_v1);
! 217: }
! 218:
! 219: METHOD(payload_t, get_header_length, int,
! 220: private_delete_payload_t *this)
! 221: {
! 222: if (this->type == PLV2_DELETE)
! 223: {
! 224: return 8;
! 225: }
! 226: return 12;
! 227: }
! 228:
! 229: METHOD(payload_t, get_payload_type, payload_type_t,
! 230: private_delete_payload_t *this)
! 231: {
! 232: return this->type;
! 233: }
! 234:
! 235: METHOD(payload_t, get_next_type, payload_type_t,
! 236: private_delete_payload_t *this)
! 237: {
! 238: return this->next_payload;
! 239: }
! 240:
! 241: METHOD(payload_t, set_next_type, void,
! 242: private_delete_payload_t *this,payload_type_t type)
! 243: {
! 244: this->next_payload = type;
! 245: }
! 246:
! 247: METHOD(payload_t, get_length, size_t,
! 248: private_delete_payload_t *this)
! 249: {
! 250: return this->payload_length;
! 251: }
! 252:
! 253: METHOD(delete_payload_t, get_protocol_id, protocol_id_t,
! 254: private_delete_payload_t *this)
! 255: {
! 256: return this->protocol_id;
! 257: }
! 258:
! 259: METHOD(delete_payload_t, add_spi, void,
! 260: private_delete_payload_t *this, uint32_t spi)
! 261: {
! 262: switch (this->protocol_id)
! 263: {
! 264: case PROTO_AH:
! 265: case PROTO_ESP:
! 266: this->spi_count++;
! 267: this->payload_length += sizeof(spi);
! 268: this->spis = chunk_cat("mc", this->spis, chunk_from_thing(spi));
! 269: break;
! 270: default:
! 271: break;
! 272: }
! 273: }
! 274:
! 275: METHOD(delete_payload_t, set_ike_spi, void,
! 276: private_delete_payload_t *this, uint64_t spi_i, uint64_t spi_r)
! 277: {
! 278: free(this->spis.ptr);
! 279: this->spis = chunk_cat("cc", chunk_from_thing(spi_i),
! 280: chunk_from_thing(spi_r));
! 281: this->spi_count = 1;
! 282: this->payload_length = get_header_length(this) + this->spi_size;
! 283: }
! 284:
! 285: METHOD(delete_payload_t, get_ike_spi, bool,
! 286: private_delete_payload_t *this, uint64_t *spi_i, uint64_t *spi_r)
! 287: {
! 288: if (this->protocol_id != PROTO_IKE ||
! 289: this->spis.len < 2 * sizeof(uint64_t))
! 290: {
! 291: return FALSE;
! 292: }
! 293: memcpy(spi_i, this->spis.ptr, sizeof(uint64_t));
! 294: memcpy(spi_r, this->spis.ptr + sizeof(uint64_t), sizeof(uint64_t));
! 295: return TRUE;
! 296: }
! 297:
! 298: /**
! 299: * SPI enumerator implementation
! 300: */
! 301: typedef struct {
! 302: /** implements enumerator_t */
! 303: enumerator_t public;
! 304: /** remaining SPIs */
! 305: chunk_t spis;
! 306: } spi_enumerator_t;
! 307:
! 308: METHOD(enumerator_t, spis_enumerate, bool,
! 309: spi_enumerator_t *this, va_list args)
! 310: {
! 311: uint32_t *spi;
! 312:
! 313: VA_ARGS_VGET(args, spi);
! 314:
! 315: if (this->spis.len >= sizeof(*spi))
! 316: {
! 317: memcpy(spi, this->spis.ptr, sizeof(*spi));
! 318: this->spis = chunk_skip(this->spis, sizeof(*spi));
! 319: return TRUE;
! 320: }
! 321: return FALSE;
! 322: }
! 323:
! 324: METHOD(delete_payload_t, create_spi_enumerator, enumerator_t*,
! 325: private_delete_payload_t *this)
! 326: {
! 327: spi_enumerator_t *e;
! 328:
! 329: if (this->spi_size != sizeof(uint32_t))
! 330: {
! 331: return enumerator_create_empty();
! 332: }
! 333: INIT(e,
! 334: .public = {
! 335: .enumerate = enumerator_enumerate_default,
! 336: .venumerate = _spis_enumerate,
! 337: .destroy = (void*)free,
! 338: },
! 339: .spis = this->spis,
! 340: );
! 341: return &e->public;
! 342: }
! 343:
! 344: METHOD2(payload_t, delete_payload_t, destroy, void,
! 345: private_delete_payload_t *this)
! 346: {
! 347: free(this->spis.ptr);
! 348: free(this);
! 349: }
! 350:
! 351: /*
! 352: * Described in header
! 353: */
! 354: delete_payload_t *delete_payload_create(payload_type_t type,
! 355: protocol_id_t protocol_id)
! 356: {
! 357: private_delete_payload_t *this;
! 358:
! 359: INIT(this,
! 360: .public = {
! 361: .payload_interface = {
! 362: .verify = _verify,
! 363: .get_encoding_rules = _get_encoding_rules,
! 364: .get_header_length = _get_header_length,
! 365: .get_length = _get_length,
! 366: .get_next_type = _get_next_type,
! 367: .set_next_type = _set_next_type,
! 368: .get_type = _get_payload_type,
! 369: .destroy = _destroy,
! 370: },
! 371: .get_protocol_id = _get_protocol_id,
! 372: .add_spi = _add_spi,
! 373: .set_ike_spi = _set_ike_spi,
! 374: .get_ike_spi = _get_ike_spi,
! 375: .create_spi_enumerator = _create_spi_enumerator,
! 376: .destroy = _destroy,
! 377: },
! 378: .next_payload = PL_NONE,
! 379: .protocol_id = protocol_id,
! 380: .doi = IKEV1_DOI_IPSEC,
! 381: .type = type,
! 382: );
! 383: this->payload_length = get_header_length(this);
! 384:
! 385: if (protocol_id == PROTO_IKE)
! 386: {
! 387: if (type == PLV1_DELETE)
! 388: {
! 389: this->spi_size = 16;
! 390: }
! 391: }
! 392: else
! 393: {
! 394: this->spi_size = 4;
! 395: }
! 396: return &this->public;
! 397: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>