Annotation of embedaddon/strongswan/src/libcharon/encoding/payloads/transform_attribute.c, revision 1.1
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 <string.h>
! 19: #include <stddef.h>
! 20: #include <stdint.h>
! 21:
! 22: #include "transform_attribute.h"
! 23:
! 24: #include <encoding/payloads/encodings.h>
! 25: #include <library.h>
! 26:
! 27: ENUM(tattr_ph1_names, TATTR_PH1_ENCRYPTION_ALGORITHM, TATTR_PH1_GROUP_ORDER,
! 28: "ENCRYPTION_ALGORITHM",
! 29: "HASH_ALGORITHM",
! 30: "AUTH_METHOD",
! 31: "GROUP",
! 32: "GROUP_TYPE",
! 33: "GROUP_PRIME",
! 34: "GROUP_GENONE",
! 35: "GROUP_GENTWO",
! 36: "GROUP_CURVE_A",
! 37: "GROUP_CURVE_B",
! 38: "LIFE_TYPE",
! 39: "LIFE_DURATION",
! 40: "PRF",
! 41: "KEY_LENGTH",
! 42: "FIELD_SIZE",
! 43: "GROUP_ORDER",
! 44: );
! 45:
! 46: ENUM(tattr_ph2_names, TATTR_PH2_SA_LIFE_TYPE, TATTR_PH2_EXT_SEQ_NUMBER,
! 47: "SA_LIFE_TYPE",
! 48: "SA_LIFE_DURATION",
! 49: "GROUP",
! 50: "ENCAP_MODE",
! 51: "AUTH_ALGORITHM",
! 52: "KEY_LENGTH",
! 53: "KEY_ROUNDS",
! 54: "COMP_DICT_SIZE",
! 55: "COMP_PRIV_ALGORITHM",
! 56: "ECN_TUNNEL",
! 57: "EXT_SEQ_NUMBER",
! 58: );
! 59:
! 60: ENUM(tattr_ikev2_names, TATTR_IKEV2_KEY_LENGTH, TATTR_IKEV2_KEY_LENGTH,
! 61: "KEY_LENGTH",
! 62: );
! 63:
! 64:
! 65: typedef struct private_transform_attribute_t private_transform_attribute_t;
! 66:
! 67: /**
! 68: * Private data of an transform_attribute_t object.
! 69: */
! 70: struct private_transform_attribute_t {
! 71:
! 72: /**
! 73: * Public transform_attribute_t interface.
! 74: */
! 75: transform_attribute_t public;
! 76:
! 77: /**
! 78: * Attribute Format Flag.
! 79: *
! 80: * - TRUE means value is stored in attribute_length_or_value
! 81: * - FALSE means value is stored in attribute_value
! 82: */
! 83: bool attribute_format;
! 84:
! 85: /**
! 86: * Type of the attribute.
! 87: */
! 88: uint16_t attribute_type;
! 89:
! 90: /**
! 91: * Attribute Length if attribute_format is 0, attribute Value otherwise.
! 92: */
! 93: uint16_t attribute_length_or_value;
! 94:
! 95: /**
! 96: * Attribute value as chunk if attribute_format is 0 (FALSE).
! 97: */
! 98: chunk_t attribute_value;
! 99:
! 100: /**
! 101: * Payload type, PLV2_TRANSFORM_ATTRIBUTE or PLV1_TRANSFORM_ATTRIBUTE
! 102: */
! 103: payload_type_t type;
! 104: };
! 105:
! 106: /**
! 107: * Encoding rules for IKEv1/IKEv2 transform attributes
! 108: */
! 109: static encoding_rule_t encodings[] = {
! 110: /* Flag defining the format of this payload */
! 111: { ATTRIBUTE_FORMAT, offsetof(private_transform_attribute_t, attribute_format) },
! 112: /* type of the attribute as 15 bit unsigned integer */
! 113: { ATTRIBUTE_TYPE, offsetof(private_transform_attribute_t, attribute_type) },
! 114: /* Length or value, depending on the attribute format flag */
! 115: { ATTRIBUTE_LENGTH_OR_VALUE,offsetof(private_transform_attribute_t, attribute_length_or_value) },
! 116: /* Value of attribute if attribute format flag is zero */
! 117: { ATTRIBUTE_VALUE, offsetof(private_transform_attribute_t, attribute_value) }
! 118: };
! 119:
! 120: /*
! 121: 1 2 3
! 122: 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
! 123: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
! 124: !A! Attribute Type ! AF=0 Attribute Length !
! 125: !F! ! AF=1 Attribute Value !
! 126: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
! 127: ! AF=0 Attribute Value !
! 128: ! AF=1 Not Transmitted !
! 129: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
! 130: */
! 131:
! 132: METHOD(payload_t, verify, status_t,
! 133: private_transform_attribute_t *this)
! 134: {
! 135: return SUCCESS;
! 136: }
! 137:
! 138: METHOD(payload_t, get_encoding_rules, int,
! 139: private_transform_attribute_t *this, encoding_rule_t **rules)
! 140: {
! 141: *rules = encodings;
! 142: return countof(encodings);
! 143: }
! 144:
! 145: METHOD(payload_t, get_header_length, int,
! 146: private_transform_attribute_t *this)
! 147: {
! 148: return 0;
! 149: }
! 150:
! 151: METHOD(payload_t, get_type, payload_type_t,
! 152: private_transform_attribute_t *this)
! 153: {
! 154: return this->type;
! 155: }
! 156:
! 157: METHOD(payload_t, get_next_type, payload_type_t,
! 158: private_transform_attribute_t *this)
! 159: {
! 160: return PL_NONE;
! 161: }
! 162:
! 163: METHOD(payload_t, set_next_type, void,
! 164: private_transform_attribute_t *this, payload_type_t type)
! 165: {
! 166: }
! 167:
! 168: METHOD(payload_t, get_length, size_t,
! 169: private_transform_attribute_t *this)
! 170: {
! 171: if (this->attribute_format)
! 172: {
! 173: return 4;
! 174: }
! 175: return this->attribute_length_or_value + 4;
! 176: }
! 177:
! 178: METHOD(transform_attribute_t, get_value_chunk, chunk_t,
! 179: private_transform_attribute_t *this)
! 180: {
! 181: if (this->attribute_format)
! 182: {
! 183: return chunk_from_thing(this->attribute_length_or_value);
! 184: }
! 185: return this->attribute_value;
! 186: }
! 187:
! 188: METHOD(transform_attribute_t, get_value, uint64_t,
! 189: private_transform_attribute_t *this)
! 190: {
! 191: uint64_t value = 0;
! 192:
! 193: if (this->attribute_format)
! 194: {
! 195: return this->attribute_length_or_value;
! 196: }
! 197: if (this->attribute_value.len > sizeof(value))
! 198: {
! 199: return UINT64_MAX;
! 200: }
! 201: memcpy(((char*)&value) + sizeof(value) - this->attribute_value.len,
! 202: this->attribute_value.ptr, this->attribute_value.len);
! 203: return untoh64((char*)&value);
! 204: }
! 205:
! 206: METHOD(transform_attribute_t, get_attribute_type, uint16_t,
! 207: private_transform_attribute_t *this)
! 208: {
! 209: return this->attribute_type;
! 210: }
! 211:
! 212: METHOD2(payload_t, transform_attribute_t, destroy, void,
! 213: private_transform_attribute_t *this)
! 214: {
! 215: free(this->attribute_value.ptr);
! 216: free(this);
! 217: }
! 218:
! 219: /*
! 220: * Described in header.
! 221: */
! 222: transform_attribute_t *transform_attribute_create(payload_type_t type)
! 223: {
! 224: private_transform_attribute_t *this;
! 225:
! 226: INIT(this,
! 227: .public = {
! 228: .payload_interface = {
! 229: .verify = _verify,
! 230: .get_encoding_rules = _get_encoding_rules,
! 231: .get_header_length = _get_header_length,
! 232: .get_length = _get_length,
! 233: .get_next_type = _get_next_type,
! 234: .set_next_type = _set_next_type,
! 235: .get_type = _get_type,
! 236: .destroy = _destroy,
! 237: },
! 238: .get_value_chunk = _get_value_chunk,
! 239: .get_value = _get_value,
! 240: .get_attribute_type = _get_attribute_type,
! 241: .destroy = _destroy,
! 242: },
! 243: .attribute_format = FALSE,
! 244: .type = type,
! 245: );
! 246: return &this->public;
! 247: }
! 248:
! 249: /*
! 250: * Described in header.
! 251: */
! 252: transform_attribute_t *transform_attribute_create_value(payload_type_t type,
! 253: transform_attribute_type_t kind, uint64_t value)
! 254: {
! 255: private_transform_attribute_t *this;
! 256:
! 257: this = (private_transform_attribute_t*)transform_attribute_create(type);
! 258:
! 259: this->attribute_type = kind & 0x7FFF;
! 260:
! 261: if (value <= UINT16_MAX)
! 262: {
! 263: this->attribute_length_or_value = value;
! 264: this->attribute_format = TRUE;
! 265: }
! 266: else if (value <= UINT32_MAX)
! 267: {
! 268: uint32_t val32;
! 269:
! 270: val32 = htonl(value);
! 271: this->attribute_value = chunk_clone(chunk_from_thing(val32));
! 272: this->attribute_length_or_value = sizeof(val32);
! 273: }
! 274: else
! 275: {
! 276: htoun64(&value, value);
! 277: this->attribute_value = chunk_clone(chunk_from_thing(value));
! 278: this->attribute_length_or_value = sizeof(value);
! 279: }
! 280: return &this->public;
! 281: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>