Annotation of embedaddon/strongswan/src/libcharon/encoding/payloads/fragment_payload.c, revision 1.1.1.1
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: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>