Return to fragment_payload.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libcharon / encoding / payloads |
1.1 misho 1: /* 2: * Copyright (C) 2012 Tobias Brunner 3: * HSR Hochschule fuer Technik Rapperswil 4: * 5: * This program is free software; you can redistribute it and/or modify it 6: * under the terms of the GNU General Public License as published by the 7: * Free Software Foundation; either version 2 of the License, or (at your 8: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. 9: * 10: * This program is distributed in the hope that it will be useful, but 11: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 12: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13: * for more details. 14: */ 15: 16: #include "fragment_payload.h" 17: 18: #include <encoding/payloads/encodings.h> 19: 20: /** Flag that is set in case the given fragment is the last for the message */ 21: #define LAST_FRAGMENT 0x01 22: 23: typedef struct private_fragment_payload_t private_fragment_payload_t; 24: 25: /** 26: * Private data of an fragment_payload_t object. 27: */ 28: struct private_fragment_payload_t { 29: 30: /** 31: * Public fragment_payload_t interface. 32: */ 33: fragment_payload_t public; 34: 35: /** 36: * Next payload type. 37: */ 38: uint8_t next_payload; 39: 40: /** 41: * Reserved byte 42: */ 43: uint8_t reserved; 44: 45: /** 46: * Length of this payload. 47: */ 48: uint16_t payload_length; 49: 50: /** 51: * Fragment ID. 52: */ 53: uint16_t fragment_id; 54: 55: /** 56: * Fragment number. 57: */ 58: uint8_t fragment_number; 59: 60: /** 61: * Flags 62: */ 63: uint8_t flags; 64: 65: /** 66: * The contained fragment data. 67: */ 68: chunk_t data; 69: }; 70: 71: /** 72: * Encoding rules for an IKEv1 fragment payload 73: */ 74: static encoding_rule_t encodings[] = { 75: /* 1 Byte next payload type, stored in the field next_payload */ 76: { U_INT_8, offsetof(private_fragment_payload_t, next_payload) }, 77: { RESERVED_BYTE, offsetof(private_fragment_payload_t, reserved) }, 78: /* Length of the whole payload*/ 79: { PAYLOAD_LENGTH, offsetof(private_fragment_payload_t, payload_length) }, 80: { U_INT_16, offsetof(private_fragment_payload_t, fragment_id) }, 81: { U_INT_8, offsetof(private_fragment_payload_t, fragment_number) }, 82: { U_INT_8, offsetof(private_fragment_payload_t, flags) }, 83: /* Fragment data is of variable size */ 84: { CHUNK_DATA, offsetof(private_fragment_payload_t, data) }, 85: }; 86: 87: /* 88: 1 2 3 89: 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 90: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 91: ! Next Payload ! RESERVED ! Payload Length ! 92: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 93: ! Fragment ID ! Fragment Num ! Flags ! 94: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 95: ! ! 96: ~ Fragment Data ~ 97: ! ! 98: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 99: */ 100: 101: METHOD(payload_t, verify, status_t, 102: private_fragment_payload_t *this) 103: { 104: if (this->fragment_number == 0) 105: { 106: return FAILED; 107: } 108: return SUCCESS; 109: } 110: 111: METHOD(payload_t, get_encoding_rules, int, 112: private_fragment_payload_t *this, encoding_rule_t **rules) 113: { 114: *rules = encodings; 115: return countof(encodings); 116: } 117: 118: METHOD(payload_t, get_header_length, int, 119: private_fragment_payload_t *this) 120: { 121: return 8; 122: } 123: 124: METHOD(payload_t, get_type, payload_type_t, 125: private_fragment_payload_t *this) 126: { 127: return PLV1_FRAGMENT; 128: } 129: 130: METHOD(payload_t, get_next_type, payload_type_t, 131: private_fragment_payload_t *this) 132: { 133: return this->next_payload; 134: } 135: 136: METHOD(payload_t, set_next_type, void, 137: private_fragment_payload_t *this, payload_type_t type) 138: { 139: this->next_payload = type; 140: } 141: 142: METHOD(payload_t, get_length, size_t, 143: private_fragment_payload_t *this) 144: { 145: return this->payload_length; 146: } 147: 148: METHOD(fragment_payload_t, get_id, uint16_t, 149: private_fragment_payload_t *this) 150: { 151: return this->fragment_id; 152: } 153: 154: METHOD(fragment_payload_t, get_number, uint8_t, 155: private_fragment_payload_t *this) 156: { 157: return this->fragment_number; 158: } 159: 160: METHOD(fragment_payload_t, is_last, bool, 161: private_fragment_payload_t *this) 162: { 163: return (this->flags & LAST_FRAGMENT) == LAST_FRAGMENT; 164: } 165: 166: METHOD(fragment_payload_t, get_data, chunk_t, 167: private_fragment_payload_t *this) 168: { 169: return this->data; 170: } 171: 172: METHOD2(payload_t, fragment_payload_t, destroy, void, 173: private_fragment_payload_t *this) 174: { 175: free(this->data.ptr); 176: free(this); 177: } 178: 179: /* 180: * Described in header 181: */ 182: fragment_payload_t *fragment_payload_create() 183: { 184: private_fragment_payload_t *this; 185: 186: INIT(this, 187: .public = { 188: .payload_interface = { 189: .verify = _verify, 190: .get_encoding_rules = _get_encoding_rules, 191: .get_header_length = _get_header_length, 192: .get_length = _get_length, 193: .get_next_type = _get_next_type, 194: .set_next_type = _set_next_type, 195: .get_type = _get_type, 196: .destroy = _destroy, 197: }, 198: .get_id = _get_id, 199: .get_number = _get_number, 200: .is_last = _is_last, 201: .get_data = _get_data, 202: .destroy = _destroy, 203: }, 204: .next_payload = PL_NONE, 205: ); 206: this->payload_length = get_header_length(this); 207: return &this->public; 208: } 209: 210: /* 211: * Described in header 212: */ 213: fragment_payload_t *fragment_payload_create_from_data(uint8_t num, bool last, 214: chunk_t data) 215: { 216: private_fragment_payload_t *this; 217: 218: this = (private_fragment_payload_t*)fragment_payload_create(); 219: this->fragment_id = 1; 220: this->fragment_number = num; 221: this->flags |= (last ? LAST_FRAGMENT : 0); 222: this->data = chunk_clone(data); 223: this->payload_length = get_header_length(this) + data.len; 224: return &this->public; 225: }