Return to traffic_selector_substructure.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 "traffic_selector_substructure.h" 19: 20: #include <encoding/payloads/encodings.h> 21: #include <collections/linked_list.h> 22: 23: typedef struct private_traffic_selector_substructure_t private_traffic_selector_substructure_t; 24: 25: /** 26: * Private data of an traffic_selector_substructure_t object. 27: */ 28: struct private_traffic_selector_substructure_t { 29: 30: /** 31: * Public traffic_selector_substructure_t interface. 32: */ 33: traffic_selector_substructure_t public; 34: 35: /** 36: * Type of traffic selector. 37: */ 38: uint8_t ts_type; 39: 40: /** 41: * IP Protocol ID. 42: */ 43: uint8_t ip_protocol_id; 44: 45: /** 46: * Length of this payload. 47: */ 48: uint16_t payload_length; 49: 50: /** 51: * Start port number. 52: */ 53: uint16_t start_port; 54: 55: /** 56: * End port number. 57: */ 58: uint16_t end_port; 59: 60: /** 61: * Starting address. 62: */ 63: chunk_t starting_address; 64: 65: /** 66: * Ending address. 67: */ 68: chunk_t ending_address; 69: }; 70: 71: /** 72: * Encoding rules to parse or generate a TS payload 73: * 74: * The defined offsets are the positions in a object of type 75: * private_traffic_selector_substructure_t. 76: */ 77: static encoding_rule_t encodings[] = { 78: /* 1 Byte next ts type*/ 79: { TS_TYPE, offsetof(private_traffic_selector_substructure_t, ts_type) }, 80: /* 1 Byte IP protocol id*/ 81: { U_INT_8, offsetof(private_traffic_selector_substructure_t, ip_protocol_id) }, 82: /* Length of the whole payload*/ 83: { PAYLOAD_LENGTH,offsetof(private_traffic_selector_substructure_t, payload_length) }, 84: /* 2 Byte start port*/ 85: { U_INT_16, offsetof(private_traffic_selector_substructure_t, start_port) }, 86: /* 2 Byte end port*/ 87: { U_INT_16, offsetof(private_traffic_selector_substructure_t, end_port) }, 88: /* starting address is either 4 or 16 byte */ 89: { ADDRESS, offsetof(private_traffic_selector_substructure_t, starting_address) }, 90: /* ending address is either 4 or 16 byte */ 91: { ADDRESS, offsetof(private_traffic_selector_substructure_t, ending_address) } 92: }; 93: 94: /* 95: 1 2 3 96: 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 97: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 98: ! TS Type !IP Protocol ID*| Selector Length | 99: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 100: | Start Port* | End Port* | 101: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 102: ! ! 103: ~ Starting Address* ~ 104: ! ! 105: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 106: ! ! 107: ~ Ending Address* ~ 108: ! ! 109: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 110: */ 111: 112: METHOD(payload_t, verify, status_t, 113: private_traffic_selector_substructure_t *this) 114: { 115: if (this->start_port > this->end_port) 116: { 117: /* OPAQUE ports are the only exception */ 118: if (this->start_port != 0xffff && this->end_port != 0) 119: { 120: return FAILED; 121: } 122: } 123: switch (this->ts_type) 124: { 125: case TS_IPV4_ADDR_RANGE: 126: { 127: if ((this->starting_address.len != 4) || 128: (this->ending_address.len != 4)) 129: { 130: /* ipv4 address must be 4 bytes long */ 131: return FAILED; 132: } 133: break; 134: } 135: case TS_IPV6_ADDR_RANGE: 136: { 137: if ((this->starting_address.len != 16) || 138: (this->ending_address.len != 16)) 139: { 140: /* ipv6 address must be 16 bytes long */ 141: return FAILED; 142: } 143: break; 144: } 145: default: 146: { 147: /* not supported ts type */ 148: return FAILED; 149: } 150: } 151: 152: return SUCCESS; 153: } 154: 155: METHOD(payload_t, get_encoding_rules, int, 156: private_traffic_selector_substructure_t *this, encoding_rule_t **rules) 157: { 158: *rules = encodings; 159: return countof(encodings); 160: } 161: 162: METHOD(payload_t, get_header_length, int, 163: private_traffic_selector_substructure_t *this) 164: { 165: return 8; 166: } 167: 168: METHOD(payload_t, get_type, payload_type_t, 169: private_traffic_selector_substructure_t *this) 170: { 171: return PLV2_TRAFFIC_SELECTOR_SUBSTRUCTURE; 172: } 173: 174: METHOD(payload_t, get_next_type, payload_type_t, 175: private_traffic_selector_substructure_t *this) 176: { 177: return PL_NONE; 178: } 179: 180: METHOD(payload_t, set_next_type, void, 181: private_traffic_selector_substructure_t *this,payload_type_t type) 182: { 183: } 184: 185: METHOD(payload_t, get_length, size_t, 186: private_traffic_selector_substructure_t *this) 187: { 188: return this->payload_length; 189: } 190: 191: METHOD(traffic_selector_substructure_t, get_traffic_selector, traffic_selector_t*, 192: private_traffic_selector_substructure_t *this) 193: { 194: return traffic_selector_create_from_bytes( 195: this->ip_protocol_id, this->ts_type, 196: this->starting_address, this->start_port, 197: this->ending_address, this->end_port); 198: } 199: 200: METHOD2(payload_t, traffic_selector_substructure_t, destroy, void, 201: private_traffic_selector_substructure_t *this) 202: { 203: free(this->starting_address.ptr); 204: free(this->ending_address.ptr); 205: free(this); 206: } 207: 208: /* 209: * Described in header 210: */ 211: traffic_selector_substructure_t *traffic_selector_substructure_create() 212: { 213: private_traffic_selector_substructure_t *this; 214: 215: INIT(this, 216: .public = { 217: .payload_interface = { 218: .verify = _verify, 219: .get_encoding_rules = _get_encoding_rules, 220: .get_header_length = _get_header_length, 221: .get_length = _get_length, 222: .get_next_type = _get_next_type, 223: .set_next_type = _set_next_type, 224: .get_type = _get_type, 225: .destroy = _destroy, 226: }, 227: .get_traffic_selector = _get_traffic_selector, 228: .destroy = _destroy, 229: }, 230: .payload_length = get_header_length(this), 231: /* must be set to be valid */ 232: .ts_type = TS_IPV4_ADDR_RANGE, 233: ); 234: return &this->public; 235: } 236: 237: /* 238: * Described in header 239: */ 240: traffic_selector_substructure_t *traffic_selector_substructure_create_from_traffic_selector( 241: traffic_selector_t *ts) 242: { 243: private_traffic_selector_substructure_t *this; 244: 245: this = (private_traffic_selector_substructure_t*)traffic_selector_substructure_create(); 246: this->ts_type = ts->get_type(ts); 247: this->ip_protocol_id = ts->get_protocol(ts); 248: this->start_port = ts->get_from_port(ts); 249: this->end_port = ts->get_to_port(ts); 250: this->starting_address = chunk_clone(ts->get_from_address(ts)); 251: this->ending_address = chunk_clone(ts->get_to_address(ts)); 252: this->payload_length = get_header_length(this) + 253: this->ending_address.len + this->starting_address.len; 254: 255: return &this->public; 256: }