|
1 /* |
|
2 * Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of the License "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: EAP and WLAN authentication protocols. |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 // This is enumeration of EAPOL source code. |
|
20 #if defined(USE_EAP_MINIMUM_RELEASE_TRACES) |
|
21 #undef EAP_FILE_NUMBER_ENUM |
|
22 #define EAP_FILE_NUMBER_ENUM 588 |
|
23 #undef EAP_FILE_NUMBER_DATE |
|
24 #define EAP_FILE_NUMBER_DATE 1127594498 |
|
25 #endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) |
|
26 |
|
27 |
|
28 |
|
29 #include "eap_am_memory.h" |
|
30 #include "eap_diameter_payloads.h" |
|
31 #include "eap_diameter_avp_header.h" |
|
32 #include "abs_eap_am_tools.h" |
|
33 #include "eap_tools.h" |
|
34 #include "eap_array_algorithms.h" |
|
35 |
|
36 |
|
37 EAP_FUNC_EXPORT eap_diameter_variable_data_c::~eap_diameter_variable_data_c() |
|
38 { |
|
39 } |
|
40 |
|
41 EAP_FUNC_EXPORT eap_diameter_variable_data_c::eap_diameter_variable_data_c( |
|
42 abs_eap_am_tools_c * const tools) |
|
43 : m_am_tools(tools) |
|
44 , m_data(tools) |
|
45 , m_payload_code(eap_diameter_avp_code_none) |
|
46 , m_is_mandatory(false) |
|
47 { |
|
48 } |
|
49 |
|
50 EAP_FUNC_EXPORT eap_status_e eap_diameter_variable_data_c::set_buffer( |
|
51 const eap_diameter_avp_code_c current_payload, |
|
52 const bool is_mandatory, |
|
53 const u8_t * const buffer, |
|
54 const u32_t buffer_length, |
|
55 const bool free_buffer, |
|
56 const bool is_writable) |
|
57 { |
|
58 eap_status_e status = m_data.set_buffer( |
|
59 buffer, |
|
60 buffer_length, |
|
61 free_buffer, |
|
62 is_writable); |
|
63 if (status != eap_status_ok) |
|
64 { |
|
65 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
66 return EAP_STATUS_RETURN(m_am_tools, status); |
|
67 } |
|
68 |
|
69 m_payload_code = current_payload; |
|
70 |
|
71 m_is_mandatory = is_mandatory; |
|
72 |
|
73 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
74 return EAP_STATUS_RETURN(m_am_tools, status); |
|
75 } |
|
76 |
|
77 EAP_FUNC_EXPORT eap_status_e eap_diameter_variable_data_c::add_data( |
|
78 const u8_t * const buffer, |
|
79 const u32_t buffer_length) |
|
80 { |
|
81 eap_status_e status = m_data.add_data( |
|
82 buffer, |
|
83 buffer_length); |
|
84 |
|
85 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
86 return EAP_STATUS_RETURN(m_am_tools, status); |
|
87 } |
|
88 |
|
89 EAP_FUNC_EXPORT u32_t eap_diameter_variable_data_c::get_data_length() const |
|
90 { |
|
91 return m_data.get_data_length(); |
|
92 } |
|
93 |
|
94 EAP_FUNC_EXPORT u8_t * eap_diameter_variable_data_c::get_data( |
|
95 const u32_t data_length) const |
|
96 { |
|
97 return m_data.get_data(data_length); |
|
98 } |
|
99 |
|
100 EAP_FUNC_EXPORT eap_variable_data_c * eap_diameter_variable_data_c::get_payload_buffer() |
|
101 { |
|
102 return &m_data; |
|
103 } |
|
104 |
|
105 EAP_FUNC_EXPORT eap_diameter_avp_code_c eap_diameter_variable_data_c::get_payload_code() const |
|
106 { |
|
107 return m_payload_code; |
|
108 } |
|
109 |
|
110 EAP_FUNC_EXPORT bool eap_diameter_variable_data_c::get_is_mandatory() const |
|
111 { |
|
112 return m_is_mandatory; |
|
113 } |
|
114 |
|
115 EAP_FUNC_EXPORT void eap_diameter_variable_data_c::set_payload_code( |
|
116 const eap_diameter_avp_code_c code) |
|
117 { |
|
118 m_payload_code = code; |
|
119 } |
|
120 |
|
121 EAP_FUNC_EXPORT eap_diameter_variable_data_c * eap_diameter_variable_data_c::copy() const |
|
122 { |
|
123 eap_diameter_variable_data_c * new_data = new eap_diameter_variable_data_c(m_am_tools); |
|
124 |
|
125 if (new_data != 0) |
|
126 { |
|
127 eap_status_e status = new_data->get_payload_buffer()->add_data(&m_data); |
|
128 if (status != eap_status_ok) |
|
129 { |
|
130 delete new_data; |
|
131 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
132 (void) EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
133 return 0; |
|
134 } |
|
135 |
|
136 new_data->set_payload_code(get_payload_code()); |
|
137 } |
|
138 |
|
139 return new_data; |
|
140 } |
|
141 |
|
142 EAP_FUNC_EXPORT void eap_diameter_variable_data_c::object_increase_reference_count() |
|
143 { |
|
144 } |
|
145 |
|
146 |
|
147 |
|
148 EAP_FUNC_EXPORT eap_diameter_payloads_c::~eap_diameter_payloads_c() |
|
149 { |
|
150 } |
|
151 |
|
152 #if defined(_WIN32) && !defined(__GNUC__) |
|
153 #pragma warning( disable : 4355 ) // 'this' : used in base member initializer list |
|
154 #endif |
|
155 |
|
156 EAP_FUNC_EXPORT eap_diameter_payloads_c::eap_diameter_payloads_c( |
|
157 abs_eap_am_tools_c * const tools) |
|
158 : m_am_tools(tools) |
|
159 , m_payload_map(tools, this) |
|
160 , m_read_payloads(tools) |
|
161 , m_is_valid(false) |
|
162 { |
|
163 m_is_valid = true; |
|
164 } |
|
165 |
|
166 EAP_FUNC_EXPORT eap_diameter_variable_data_c * eap_diameter_payloads_c::get_payload( |
|
167 const eap_diameter_avp_code_c current_payload) |
|
168 { |
|
169 eap_variable_data_c selector(m_am_tools); |
|
170 |
|
171 eap_status_e status = selector.set_buffer( |
|
172 ¤t_payload, |
|
173 sizeof(current_payload), |
|
174 false, |
|
175 false); |
|
176 if (status != eap_status_ok) |
|
177 { |
|
178 return 0; |
|
179 } |
|
180 |
|
181 eap_diameter_variable_data_c *payload = m_payload_map.get_handler(&selector); |
|
182 |
|
183 return payload; |
|
184 } |
|
185 |
|
186 |
|
187 EAP_FUNC_EXPORT eap_status_e eap_diameter_payloads_c::check_payloads_existense( |
|
188 EAP_TEMPLATE_CONST eap_array_c<eap_diameter_avp_code_c> * const needed_payloads) |
|
189 { |
|
190 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
191 |
|
192 for (u32_t ind = 0ul; ind < needed_payloads->get_object_count(); ind++) |
|
193 { |
|
194 const eap_diameter_avp_code_c * const required_avp_code = needed_payloads->get_object(ind); |
|
195 if (required_avp_code == 0) |
|
196 { |
|
197 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
198 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
199 } |
|
200 |
|
201 if (get_payload(*required_avp_code) == 0) |
|
202 { |
|
203 EAP_TRACE_DEBUG( |
|
204 m_am_tools, |
|
205 TRACE_FLAGS_DEFAULT, |
|
206 (EAPL("not received AVP 0x%08x:0x%08x.\n"), |
|
207 required_avp_code->get_vendor_id(), |
|
208 required_avp_code->get_vendor_code())); |
|
209 |
|
210 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
211 return EAP_STATUS_RETURN(m_am_tools, eap_status_not_found); |
|
212 } |
|
213 } |
|
214 |
|
215 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
216 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
217 } |
|
218 |
|
219 |
|
220 EAP_FUNC_EXPORT eap_status_e eap_diameter_payloads_c::check_mandatory_payloads( |
|
221 EAP_TEMPLATE_CONST eap_array_c<eap_diameter_avp_code_c> * const used_payloads) |
|
222 { |
|
223 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
224 |
|
225 for (u32_t ind = 0ul; ind < m_read_payloads.get_object_count(); ind++) |
|
226 { |
|
227 const eap_diameter_variable_data_c * const read_payload = m_read_payloads.get_object(ind); |
|
228 if (read_payload == 0) |
|
229 { |
|
230 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
231 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
232 } |
|
233 |
|
234 if (read_payload->get_is_mandatory() == true) |
|
235 { |
|
236 eap_diameter_avp_code_c code = read_payload->get_payload_code(); |
|
237 |
|
238 i32_t index = find_simple<eap_diameter_avp_code_c>( |
|
239 used_payloads, |
|
240 &code, |
|
241 m_am_tools); |
|
242 if (index < 0ul) |
|
243 { |
|
244 // ERROR: not used mandatory AVP. |
|
245 EAP_TRACE_ERROR( |
|
246 m_am_tools, |
|
247 TRACE_FLAGS_DIAMETER_ERROR, |
|
248 (EAPL("ERROR: not used mandatory AVP 0x%08x:0x%08x.\n"), |
|
249 code.get_vendor_id(), |
|
250 code.get_vendor_code())); |
|
251 |
|
252 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
253 return EAP_STATUS_RETURN(m_am_tools, eap_status_unsupported_payload); |
|
254 } |
|
255 } |
|
256 } |
|
257 |
|
258 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
259 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
260 } |
|
261 |
|
262 |
|
263 EAP_FUNC_EXPORT eap_status_e eap_diameter_payloads_c::add_payload( |
|
264 const eap_diameter_avp_code_c current_payload, |
|
265 const bool is_mandatory, |
|
266 const u8_t * const data, |
|
267 const u32_t data_length, |
|
268 const bool free_buffer, |
|
269 const bool is_writable, |
|
270 const bool fragments_allowed) |
|
271 { |
|
272 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
273 |
|
274 eap_status_e status(eap_status_process_general_error); |
|
275 |
|
276 eap_diameter_variable_data_c *payload = get_payload( |
|
277 current_payload); |
|
278 if (payload != 0) |
|
279 { |
|
280 if (fragments_allowed == true) |
|
281 { |
|
282 // Add fragment to the end of the existing payload. |
|
283 status = payload->add_data(data, data_length); |
|
284 if (status != eap_status_ok) |
|
285 { |
|
286 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
287 return EAP_STATUS_RETURN(m_am_tools, status); |
|
288 } |
|
289 } |
|
290 else |
|
291 { |
|
292 // Cannot add fragment. |
|
293 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
294 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); |
|
295 } |
|
296 } |
|
297 else |
|
298 { |
|
299 eap_variable_data_c selector(m_am_tools); |
|
300 |
|
301 status = selector.set_buffer( |
|
302 ¤t_payload, |
|
303 sizeof(current_payload), |
|
304 false, |
|
305 false); |
|
306 if (status != eap_status_ok) |
|
307 { |
|
308 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
309 return EAP_STATUS_RETURN(m_am_tools, status); |
|
310 } |
|
311 |
|
312 eap_diameter_variable_data_c *payload = new eap_diameter_variable_data_c( |
|
313 m_am_tools); |
|
314 if (payload == 0) |
|
315 { |
|
316 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
317 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
318 } |
|
319 |
|
320 status = payload->set_buffer( |
|
321 current_payload, |
|
322 is_mandatory, |
|
323 data, |
|
324 data_length, |
|
325 free_buffer, |
|
326 is_writable); |
|
327 if (status != eap_status_ok) |
|
328 { |
|
329 delete payload; |
|
330 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
331 return EAP_STATUS_RETURN(m_am_tools, status); |
|
332 } |
|
333 |
|
334 status = m_payload_map.add_handler(&selector, payload); |
|
335 if (status != eap_status_ok) |
|
336 { |
|
337 delete payload; |
|
338 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
339 return EAP_STATUS_RETURN(m_am_tools, status); |
|
340 } |
|
341 |
|
342 // Note the same payload object is added to m_read_payloads as to m_payload_map. |
|
343 status = m_read_payloads.add_object(payload, false); |
|
344 if (status != eap_status_ok) |
|
345 { |
|
346 // Note we do not delete payload here, because it has been added alredy to m_payload_map. |
|
347 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
348 return EAP_STATUS_RETURN(m_am_tools, status); |
|
349 } |
|
350 } |
|
351 |
|
352 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
353 return EAP_STATUS_RETURN(m_am_tools, status); |
|
354 } |
|
355 |
|
356 |
|
357 EAP_FUNC_EXPORT bool eap_diameter_payloads_c::get_is_valid() const |
|
358 { |
|
359 return m_is_valid; |
|
360 } |
|
361 |
|
362 |
|
363 //-------------------------------------------------- |
|
364 |
|
365 //eap_diameter_payloads_c |
|
366 EAP_FUNC_EXPORT eap_status_e eap_diameter_payloads_c::parse_generic_payload( |
|
367 const eap_diameter_avp_code_c payload_type, |
|
368 const eap_diameter_avp_header_c * const payload) |
|
369 { |
|
370 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
371 |
|
372 EAP_DIAMETER_TRACE_PAYLOAD("Parsing payload", payload); |
|
373 |
|
374 eap_status_e status(eap_status_process_general_error); |
|
375 |
|
376 /* |
|
377 * AVP-header: |
|
378 * 0 1 2 3 |
|
379 * 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 |
|
380 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
|
381 * | AVP Code | |
|
382 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
|
383 * |V|M|r r r r r r| AVP Length | |
|
384 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
|
385 * | Vendor-ID (optional) | |
|
386 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
|
387 * | Data .... |
|
388 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
|
389 */ |
|
390 if (payload->get_length() < payload->get_header_length()) |
|
391 { |
|
392 EAP_TRACE_ERROR( |
|
393 m_am_tools, |
|
394 TRACE_FLAGS_DIAMETER_ERROR, |
|
395 (EAPL("ERROR: eap_diameter_payloads_c::parse_generic_payload(0x%08x): ") |
|
396 EAPL("current payload 0x%08x:0x%08x=%s, required length 0x%08x, packet length too less 0x%08x.\n"), |
|
397 payload, |
|
398 payload_type.get_vendor_id(), |
|
399 payload_type.get_vendor_code(), |
|
400 payload->get_avp_code_string(), |
|
401 payload->get_header_length(), |
|
402 payload->get_length())); |
|
403 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
404 return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); |
|
405 } |
|
406 |
|
407 u32_t data_length = payload->get_data_length(); |
|
408 |
|
409 u8_t * const data |
|
410 = static_cast<u8_t *>(payload->get_data_offset(0ul, data_length)); |
|
411 |
|
412 if (data == 0) |
|
413 { |
|
414 EAP_TRACE_ERROR( |
|
415 m_am_tools, |
|
416 TRACE_FLAGS_DIAMETER_ERROR, |
|
417 (EAPL("ERROR: eap_diameter_payloads_c::parse_generic_payload(0x%08x): ") |
|
418 EAPL("current payload 0x%08x:0x%08x=%s, length 0x%04x, data buffer incorrect.\n"), |
|
419 payload, |
|
420 payload_type.get_vendor_id(), |
|
421 payload_type.get_vendor_code(), |
|
422 payload->get_avp_code_string(), |
|
423 payload->get_data_length())); |
|
424 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
425 return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); |
|
426 } |
|
427 |
|
428 status = add_payload( |
|
429 payload_type, |
|
430 payload->get_avp_flag_mandatory_avp(), |
|
431 data, |
|
432 data_length, |
|
433 false, |
|
434 false, |
|
435 true); // This can be fragmented. |
|
436 |
|
437 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
438 return EAP_STATUS_RETURN(m_am_tools, status); |
|
439 } |
|
440 |
|
441 //-------------------------------------------------- |
|
442 |
|
443 // |
|
444 EAP_FUNC_EXPORT eap_status_e eap_diameter_payloads_c::parse_diameter_payloads( |
|
445 const eap_diameter_avp_header_c * const p_payload, |
|
446 u32_t * const buffer_length) |
|
447 { |
|
448 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
449 |
|
450 eap_diameter_avp_header_c payload( |
|
451 m_am_tools, |
|
452 p_payload->get_header_buffer(*buffer_length), |
|
453 *buffer_length); // Const correctness is gone. |
|
454 |
|
455 eap_diameter_avp_code_c current_payload = payload.get_avp_code(); |
|
456 |
|
457 eap_status_e status = eap_status_header_corrupted; |
|
458 |
|
459 if (payload.get_is_valid() == true |
|
460 && current_payload != eap_diameter_avp_code_none) |
|
461 { |
|
462 if (*buffer_length < payload.get_length()) |
|
463 { |
|
464 EAP_TRACE_ERROR( |
|
465 m_am_tools, |
|
466 TRACE_FLAGS_DIAMETER_ERROR, |
|
467 (EAPL("ERROR: eap_diameter_payloads_c::parse_diameter_payloads(0x%08x): ") |
|
468 EAPL("current payload 0x%08x:0x%08x=%s, data length 0x%04x, buffer length 0x%04x.\n"), |
|
469 payload.get_header_buffer(0ul), |
|
470 current_payload.get_vendor_id(), |
|
471 current_payload.get_vendor_code(), |
|
472 payload.get_avp_code_string(), |
|
473 payload.get_data_length(), |
|
474 *buffer_length)); |
|
475 EAP_TRACE_ERROR( |
|
476 m_am_tools, |
|
477 TRACE_FLAGS_DIAMETER_ERROR, |
|
478 (EAPL("ERROR: eap_diameter_payloads_c::parse_diameter_payloads(): ") |
|
479 EAPL("DIAMETER-payload header is corrupted.\n"))); |
|
480 EAP_TRACE_DATA_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("payload"), |
|
481 payload.get_header_buffer(*buffer_length), |
|
482 *buffer_length)); |
|
483 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
484 return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); |
|
485 } |
|
486 |
|
487 status = parse_generic_payload(current_payload, &payload); |
|
488 if (status != eap_status_ok) |
|
489 { |
|
490 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
491 return EAP_STATUS_RETURN(m_am_tools, status); |
|
492 } |
|
493 |
|
494 u32_t prev_avp_length = payload.get_length() + payload.get_padding_length(); |
|
495 if (*buffer_length < prev_avp_length) |
|
496 { |
|
497 // We do have only the current payload. So not padding is included. |
|
498 prev_avp_length = payload.get_length(); |
|
499 } |
|
500 |
|
501 EAP_ASSERT_ALWAYS(*buffer_length >= prev_avp_length); |
|
502 *buffer_length -= prev_avp_length; |
|
503 |
|
504 while(*buffer_length >= payload.get_header_length() |
|
505 && payload.get_is_valid() == true |
|
506 && payload.get_header_buffer_length() >= payload.get_length()) |
|
507 { |
|
508 payload.set_header_buffer( |
|
509 payload.get_next_header(), |
|
510 payload.get_header_buffer_length() - prev_avp_length); |
|
511 if (payload.get_is_valid() == false) |
|
512 { |
|
513 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
514 return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); |
|
515 } |
|
516 |
|
517 current_payload = payload.get_avp_code(); |
|
518 |
|
519 if (*buffer_length < payload.get_length()) |
|
520 { |
|
521 EAP_TRACE_ERROR( |
|
522 m_am_tools, |
|
523 TRACE_FLAGS_DIAMETER_ERROR, |
|
524 (EAPL("ERROR: eap_diameter_payloads_c::parse_diameter_payloads(0x%08x): ") |
|
525 EAPL("current payload 0x%08x:0x%08x=%s, payload data length 0x%04x, payload length 0x%04x, buffer length 0x%04x.\n"), |
|
526 payload.get_header_buffer(0ul), |
|
527 current_payload.get_vendor_id(), |
|
528 current_payload.get_vendor_code(), |
|
529 payload.get_avp_code_string(), |
|
530 payload.get_data_length(), |
|
531 payload.get_length(), |
|
532 *buffer_length)); |
|
533 EAP_TRACE_ERROR( |
|
534 m_am_tools, |
|
535 TRACE_FLAGS_DIAMETER_ERROR, |
|
536 (EAPL("ERROR: eap_diameter_payloads_c::parse_diameter_payloads(): ") |
|
537 EAPL("DIAMETER-payload header is corrupted.\n"))); |
|
538 EAP_TRACE_DATA_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("payload"), |
|
539 payload.get_header_buffer(*buffer_length), |
|
540 *buffer_length)); |
|
541 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
542 return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); |
|
543 } |
|
544 |
|
545 status = parse_generic_payload(current_payload, &payload); |
|
546 if (status != eap_status_ok) |
|
547 { |
|
548 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
549 return EAP_STATUS_RETURN(m_am_tools, status); |
|
550 } |
|
551 |
|
552 prev_avp_length = payload.get_length() + payload.get_padding_length(); |
|
553 if (*buffer_length < prev_avp_length) |
|
554 { |
|
555 // We do have only the current payload. So not padding is included. |
|
556 prev_avp_length = payload.get_length(); |
|
557 } |
|
558 |
|
559 EAP_ASSERT_ALWAYS(*buffer_length >= prev_avp_length); |
|
560 *buffer_length -= prev_avp_length; |
|
561 } |
|
562 } |
|
563 |
|
564 if (*buffer_length != 0u) |
|
565 { |
|
566 EAP_TRACE_ERROR( |
|
567 m_am_tools, |
|
568 TRACE_FLAGS_DIAMETER_ERROR, |
|
569 (EAPL("ERROR: eap_diameter_payloads_c::parse_diameter_payloads(): ") |
|
570 EAPL("DIAMETER-header is corrupted. Buffer length and payload ") |
|
571 EAPL("length does not match. %lu illegal bytes.\n"), |
|
572 *buffer_length)); |
|
573 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
574 return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); |
|
575 } |
|
576 |
|
577 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
578 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
579 } |
|
580 |
|
581 //-------------------------------------------------- |
|
582 |
|
583 EAP_FUNC_EXPORT eap_status_e eap_diameter_payloads_c::reset() |
|
584 { |
|
585 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
586 |
|
587 eap_status_e status = m_payload_map.reset(); |
|
588 if (status != eap_status_ok) |
|
589 { |
|
590 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
591 return EAP_STATUS_RETURN(m_am_tools, status); |
|
592 } |
|
593 |
|
594 status = m_read_payloads.reset(); |
|
595 if (status != eap_status_ok) |
|
596 { |
|
597 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
598 return EAP_STATUS_RETURN(m_am_tools, status); |
|
599 } |
|
600 |
|
601 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
602 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
603 } |
|
604 |
|
605 //-------------------------------------------------- |
|
606 // End. |