Return to ts_payload.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libcharon / encoding / payloads |
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 <stddef.h> 19: 20: #include "ts_payload.h" 21: 22: #include <encoding/payloads/encodings.h> 23: #include <collections/linked_list.h> 24: 25: typedef struct private_ts_payload_t private_ts_payload_t; 26: 27: /** 28: * Private data of an ts_payload_t object. 29: */ 30: struct private_ts_payload_t { 31: 32: /** 33: * Public ts_payload_t interface. 34: */ 35: ts_payload_t public; 36: 37: /** 38: * TRUE if this TS payload is of type TSi, FALSE for TSr. 39: */ 40: bool is_initiator; 41: 42: /** 43: * Next payload type. 44: */ 45: uint8_t next_payload; 46: 47: /** 48: * Critical flag. 49: */ 50: bool critical; 51: 52: /** 53: * reserved bits 54: */ 55: bool reserved_bit[7]; 56: 57: /** 58: * reserved bytes 59: */ 60: bool reserved_byte[3]; 61: 62: /** 63: * Length of this payload. 64: */ 65: uint16_t payload_length; 66: 67: /** 68: * Number of traffic selectors 69: */ 70: uint8_t ts_num; 71: 72: /** 73: * Contains the traffic selectors of type traffic_selector_substructure_t. 74: */ 75: linked_list_t *substrs; 76: }; 77: 78: /** 79: * Encoding rules to parse or generate a TS payload 80: * 81: * The defined offsets are the positions in a object of type 82: * private_ts_payload_t. 83: */ 84: static encoding_rule_t encodings[] = { 85: /* 1 Byte next payload type, stored in the field next_payload */ 86: { U_INT_8, offsetof(private_ts_payload_t, next_payload) }, 87: /* the critical bit */ 88: { FLAG, offsetof(private_ts_payload_t, critical) }, 89: /* 7 Bit reserved bits */ 90: { RESERVED_BIT, offsetof(private_ts_payload_t, reserved_bit[0]) }, 91: { RESERVED_BIT, offsetof(private_ts_payload_t, reserved_bit[1]) }, 92: { RESERVED_BIT, offsetof(private_ts_payload_t, reserved_bit[2]) }, 93: { RESERVED_BIT, offsetof(private_ts_payload_t, reserved_bit[3]) }, 94: { RESERVED_BIT, offsetof(private_ts_payload_t, reserved_bit[4]) }, 95: { RESERVED_BIT, offsetof(private_ts_payload_t, reserved_bit[5]) }, 96: { RESERVED_BIT, offsetof(private_ts_payload_t, reserved_bit[6]) }, 97: /* Length of the whole payload*/ 98: { PAYLOAD_LENGTH, offsetof(private_ts_payload_t, payload_length) }, 99: /* 1 Byte TS type*/ 100: { U_INT_8, offsetof(private_ts_payload_t, ts_num) }, 101: /* 3 reserved bytes */ 102: { RESERVED_BYTE, offsetof(private_ts_payload_t, reserved_byte[0])}, 103: { RESERVED_BYTE, offsetof(private_ts_payload_t, reserved_byte[1])}, 104: { RESERVED_BYTE, offsetof(private_ts_payload_t, reserved_byte[2])}, 105: /* wrapped list of traffic selectors substructures */ 106: { PAYLOAD_LIST + PLV2_TRAFFIC_SELECTOR_SUBSTRUCTURE, 107: offsetof(private_ts_payload_t, substrs) }, 108: }; 109: 110: /* 111: 1 2 3 112: 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 113: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 114: ! Next Payload !C! RESERVED ! Payload Length ! 115: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 116: ! Number of TSs ! RESERVED ! 117: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 118: ! ! 119: ~ <Traffic Selectors> ~ 120: ! ! 121: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 122: */ 123: 124: METHOD(payload_t, verify, status_t, 125: private_ts_payload_t *this) 126: { 127: enumerator_t *enumerator; 128: payload_t *substr; 129: status_t status = SUCCESS; 130: 131: if (this->ts_num != this->substrs->get_count(this->substrs)) 132: { 133: return FAILED; 134: } 135: enumerator = this->substrs->create_enumerator(this->substrs); 136: while (enumerator->enumerate(enumerator, &substr)) 137: { 138: status = substr->verify(substr); 139: if (status != SUCCESS) 140: { 141: break; 142: } 143: } 144: enumerator->destroy(enumerator); 145: 146: return status; 147: } 148: 149: METHOD(payload_t, get_encoding_rules, int, 150: private_ts_payload_t *this, encoding_rule_t **rules) 151: { 152: *rules = encodings; 153: return countof(encodings); 154: } 155: 156: METHOD(payload_t, get_header_length, int, 157: private_ts_payload_t *this) 158: { 159: return 8; 160: } 161: 162: METHOD(payload_t, get_type, payload_type_t, 163: private_ts_payload_t *this) 164: { 165: if (this->is_initiator) 166: { 167: return PLV2_TS_INITIATOR; 168: } 169: return PLV2_TS_RESPONDER; 170: } 171: 172: METHOD(payload_t, get_next_type, payload_type_t, 173: private_ts_payload_t *this) 174: { 175: return this->next_payload; 176: } 177: 178: METHOD(payload_t, set_next_type, void, 179: private_ts_payload_t *this,payload_type_t type) 180: { 181: this->next_payload = type; 182: } 183: 184: /** 185: * recompute the length of the payload. 186: */ 187: static void compute_length(private_ts_payload_t *this) 188: { 189: enumerator_t *enumerator; 190: payload_t *subst; 191: 192: this->payload_length = get_header_length(this); 193: this->ts_num = 0; 194: enumerator = this->substrs->create_enumerator(this->substrs); 195: while (enumerator->enumerate(enumerator, &subst)) 196: { 197: this->payload_length += subst->get_length(subst); 198: this->ts_num++; 199: } 200: enumerator->destroy(enumerator); 201: } 202: 203: METHOD(payload_t, get_length, size_t, 204: private_ts_payload_t *this) 205: { 206: return this->payload_length; 207: } 208: 209: METHOD(ts_payload_t, get_initiator, bool, 210: private_ts_payload_t *this) 211: { 212: return this->is_initiator; 213: } 214: 215: METHOD(ts_payload_t, set_initiator, void, 216: private_ts_payload_t *this,bool is_initiator) 217: { 218: this->is_initiator = is_initiator; 219: } 220: 221: METHOD(ts_payload_t, get_traffic_selectors, linked_list_t*, 222: private_ts_payload_t *this) 223: { 224: traffic_selector_t *ts; 225: enumerator_t *enumerator; 226: traffic_selector_substructure_t *subst; 227: linked_list_t *list; 228: 229: list = linked_list_create(); 230: enumerator = this->substrs->create_enumerator(this->substrs); 231: while (enumerator->enumerate(enumerator, &subst)) 232: { 233: ts = subst->get_traffic_selector(subst); 234: list->insert_last(list, ts); 235: } 236: enumerator->destroy(enumerator); 237: 238: return list; 239: } 240: 241: METHOD2(payload_t, ts_payload_t, destroy, void, 242: private_ts_payload_t *this) 243: { 244: this->substrs->destroy_offset(this->substrs, offsetof(payload_t, destroy)); 245: free(this); 246: } 247: 248: /* 249: * Described in header 250: */ 251: ts_payload_t *ts_payload_create(bool is_initiator) 252: { 253: private_ts_payload_t *this; 254: 255: INIT(this, 256: .public = { 257: .payload_interface = { 258: .verify = _verify, 259: .get_encoding_rules = _get_encoding_rules, 260: .get_header_length = _get_header_length, 261: .get_length = _get_length, 262: .get_next_type = _get_next_type, 263: .set_next_type = _set_next_type, 264: .get_type = _get_type, 265: .destroy = _destroy, 266: }, 267: .get_initiator = _get_initiator, 268: .set_initiator = _set_initiator, 269: .get_traffic_selectors = _get_traffic_selectors, 270: .destroy = _destroy, 271: }, 272: .next_payload = PL_NONE, 273: .payload_length = get_header_length(this), 274: .is_initiator = is_initiator, 275: .substrs = linked_list_create(), 276: ); 277: return &this->public; 278: } 279: 280: /* 281: * Described in header 282: */ 283: ts_payload_t *ts_payload_create_from_traffic_selectors(bool is_initiator, 284: linked_list_t *traffic_selectors) 285: { 286: enumerator_t *enumerator; 287: traffic_selector_t *ts; 288: traffic_selector_substructure_t *subst; 289: private_ts_payload_t *this; 290: 291: this = (private_ts_payload_t*)ts_payload_create(is_initiator); 292: 293: enumerator = traffic_selectors->create_enumerator(traffic_selectors); 294: while (enumerator->enumerate(enumerator, &ts)) 295: { 296: subst = traffic_selector_substructure_create_from_traffic_selector(ts); 297: this->substrs->insert_last(this->substrs, subst); 298: } 299: enumerator->destroy(enumerator); 300: compute_length(this); 301: 302: return &this->public; 303: }