]>
Commit | Line | Data |
---|---|---|
34852cae JH |
1 | /** |
2 | * @file unknown_payload.c | |
3 | * | |
4 | * @brief Implementation of unknown_payload_t. | |
5 | * | |
6 | */ | |
7 | ||
8 | /* | |
9 | * Copyright (C) 2005 Jan Hutter, Martin Willi | |
10 | * Hochschule fuer Technik Rapperswil | |
11 | * | |
12 | * This program is free software; you can redistribute it and/or modify it | |
13 | * under the terms of the GNU General Public License as published by the | |
14 | * Free Software Foundation; either version 2 of the License, or (at your | |
15 | * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. | |
16 | * | |
17 | * This program is distributed in the hope that it will be useful, but | |
18 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | |
19 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
20 | * for more details. | |
21 | */ | |
22 | ||
23 | #include "unknown_payload.h" | |
24 | ||
25 | #include <utils/allocator.h> | |
26 | ||
27 | ||
28 | typedef struct private_unknown_payload_t private_unknown_payload_t; | |
29 | ||
30 | /** | |
31 | * Private data of an unknown_payload_t object. | |
32 | * | |
33 | */ | |
34 | struct private_unknown_payload_t { | |
35 | /** | |
36 | * Public unknown_payload_t interface. | |
37 | */ | |
38 | unknown_payload_t public; | |
39 | ||
40 | /** | |
41 | * Next payload type. | |
42 | */ | |
43 | u_int8_t next_payload; | |
44 | ||
45 | /** | |
46 | * Critical flag. | |
47 | */ | |
48 | bool critical; | |
49 | ||
50 | /** | |
51 | * Length of this payload. | |
52 | */ | |
53 | u_int16_t payload_length; | |
54 | ||
55 | /** | |
56 | * Type of this payload. | |
57 | */ | |
58 | payload_type_t payload_type; | |
59 | ||
60 | /** | |
61 | * The contained data. | |
62 | */ | |
63 | chunk_t data; | |
64 | }; | |
65 | ||
66 | /** | |
67 | * Encoding rules to parse or generate a EAP payload. | |
68 | * | |
69 | * The defined offsets are the positions in a object of type | |
70 | * private_unknown_payload_t. | |
71 | * | |
72 | */ | |
73 | encoding_rule_t unknown_payload_encodings[] = { | |
74 | /* 1 Byte next payload type, stored in the field next_payload */ | |
75 | { U_INT_8, offsetof(private_unknown_payload_t, next_payload)}, | |
76 | /* the critical bit */ | |
77 | { FLAG, offsetof(private_unknown_payload_t, critical) }, | |
78 | /* 7 Bit reserved bits, nowhere stored */ | |
79 | { RESERVED_BIT, 0 }, | |
80 | { RESERVED_BIT, 0 }, | |
81 | { RESERVED_BIT, 0 }, | |
82 | { RESERVED_BIT, 0 }, | |
83 | { RESERVED_BIT, 0 }, | |
84 | { RESERVED_BIT, 0 }, | |
85 | { RESERVED_BIT, 0 }, | |
86 | /* Length of the whole payload*/ | |
87 | { PAYLOAD_LENGTH, offsetof(private_unknown_payload_t, payload_length)}, | |
88 | /* some unknown data bytes, length is defined in PAYLOAD_LENGTH */ | |
89 | { UNKNOWN_DATA, offsetof(private_unknown_payload_t, data) } | |
90 | }; | |
91 | ||
92 | /* | |
93 | 1 2 3 | |
94 | 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 | |
95 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
96 | ! Next Payload !C! RESERVED ! Payload Length ! | |
97 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
98 | ! ! | |
99 | ~ Data of any type ~ | |
100 | ! ! | |
101 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
102 | */ | |
103 | ||
104 | /** | |
105 | * Implementation of payload_t.verify. | |
106 | */ | |
107 | static status_t verify(private_unknown_payload_t *this) | |
108 | { | |
109 | return SUCCESS; | |
110 | } | |
111 | ||
112 | /** | |
113 | * Implementation of unknown_payload_t.get_encoding_rules. | |
114 | */ | |
115 | static void get_encoding_rules(private_unknown_payload_t *this, encoding_rule_t **rules, size_t *rule_count) | |
116 | { | |
117 | *rules = unknown_payload_encodings; | |
118 | *rule_count = sizeof(unknown_payload_encodings) / sizeof(encoding_rule_t); | |
119 | } | |
120 | ||
121 | /** | |
122 | * Implementation of payload_t.get_type. | |
123 | */ | |
124 | static payload_type_t get_payload_type(private_unknown_payload_t *this) | |
125 | { | |
126 | return UNKNOWN_PAYLOAD; | |
127 | } | |
128 | ||
129 | /** | |
130 | * Implementation of payload_t.get_next_type. | |
131 | */ | |
132 | static payload_type_t get_next_type(private_unknown_payload_t *this) | |
133 | { | |
134 | return (this->next_payload); | |
135 | } | |
136 | ||
137 | /** | |
138 | * Implementation of payload_t.set_next_type. | |
139 | */ | |
140 | static void set_next_type(private_unknown_payload_t *this,payload_type_t type) | |
141 | { | |
142 | this->next_payload = type; | |
143 | } | |
144 | ||
145 | /** | |
146 | * Implementation of unknown_payload_t.set_real_type. | |
147 | */ | |
148 | static void set_real_type(private_unknown_payload_t *this,payload_type_t type) | |
149 | { | |
150 | this->payload_type = type; | |
151 | } | |
152 | ||
153 | /** | |
154 | * Implementation of unknown_payload_t.get_real_type. | |
155 | */ | |
156 | static payload_type_t get_real_type(private_unknown_payload_t *this) | |
157 | { | |
158 | return this->payload_type; | |
159 | } | |
160 | ||
161 | /** | |
162 | * Implementation of payload_t.get_length. | |
163 | */ | |
164 | static size_t get_length(private_unknown_payload_t *this) | |
165 | { | |
166 | return this->payload_length; | |
167 | } | |
168 | ||
169 | /** | |
170 | * Implementation of unknown_payload_t.set_data. | |
171 | */ | |
172 | static void set_data (private_unknown_payload_t *this, chunk_t data) | |
173 | { | |
174 | if (this->data.ptr != NULL) | |
175 | { | |
176 | allocator_free_chunk(&(this->data)); | |
177 | } | |
178 | this->data.ptr = allocator_clone_bytes(data.ptr,data.len); | |
179 | this->data.len = data.len; | |
180 | this->payload_length = DEFAULT_PAYLOAD_HEADER_LENGTH + this->data.len; | |
181 | } | |
182 | ||
183 | /** | |
184 | * Implementation of unknown_payload_t.get_data. | |
185 | */ | |
186 | static chunk_t get_data (private_unknown_payload_t *this) | |
187 | { | |
188 | return (this->data); | |
189 | } | |
190 | ||
191 | /** | |
192 | * Implementation of unknown_payload_t.get_data_clone. | |
193 | */ | |
194 | static chunk_t get_data_clone (private_unknown_payload_t *this) | |
195 | { | |
196 | chunk_t cloned_data; | |
197 | if (this->data.ptr == NULL) | |
198 | { | |
199 | return (this->data); | |
200 | } | |
201 | cloned_data.ptr = allocator_clone_bytes(this->data.ptr,this->data.len); | |
202 | cloned_data.len = this->data.len; | |
203 | return cloned_data; | |
204 | } | |
205 | ||
206 | /** | |
207 | * Implementation of payload_t.destroy and unknown_payload_t.destroy. | |
208 | */ | |
209 | static void destroy(private_unknown_payload_t *this) | |
210 | { | |
211 | if (this->data.ptr != NULL) | |
212 | { | |
213 | allocator_free_chunk(&(this->data)); | |
214 | } | |
215 | ||
216 | allocator_free(this); | |
217 | } | |
218 | ||
219 | /* | |
220 | * Described in header | |
221 | */ | |
222 | unknown_payload_t *unknown_payload_create() | |
223 | { | |
224 | private_unknown_payload_t *this = allocator_alloc_thing(private_unknown_payload_t); | |
225 | ||
226 | /* interface functions */ | |
227 | this->public.payload_interface.verify = (status_t (*) (payload_t *))verify; | |
228 | this->public.payload_interface.get_encoding_rules = (void (*) (payload_t *, encoding_rule_t **, size_t *) ) get_encoding_rules; | |
229 | this->public.payload_interface.get_length = (size_t (*) (payload_t *)) get_length; | |
230 | this->public.payload_interface.get_next_type = (payload_type_t (*) (payload_t *)) get_next_type; | |
231 | this->public.payload_interface.set_next_type = (void (*) (payload_t *,payload_type_t)) set_next_type; | |
232 | this->public.payload_interface.get_type = (payload_type_t (*) (payload_t *)) get_payload_type; | |
233 | this->public.payload_interface.destroy = (void (*) (payload_t *))destroy; | |
234 | ||
235 | /* public functions */ | |
236 | this->public.destroy = (void (*) (unknown_payload_t *)) destroy; | |
237 | this->public.set_real_type = (void (*) (unknown_payload_t *,payload_type_t)) set_real_type; | |
238 | this->public.get_real_type = (payload_type_t (*) (unknown_payload_t *)) get_real_type; | |
239 | this->public.set_data = (void (*) (unknown_payload_t *,chunk_t)) set_data; | |
240 | this->public.get_data_clone = (chunk_t (*) (unknown_payload_t *)) get_data_clone; | |
241 | this->public.get_data = (chunk_t (*) (unknown_payload_t *)) get_data; | |
242 | ||
243 | /* private variables */ | |
244 | this->critical = FALSE; | |
245 | this->next_payload = NO_PAYLOAD; | |
246 | this->payload_type = NO_PAYLOAD; | |
247 | this->payload_length = DEFAULT_PAYLOAD_HEADER_LENGTH; | |
248 | this->data = CHUNK_INITIALIZER; | |
249 | ||
250 | return (&(this->public)); | |
251 | } |