2 * Copyright (C) 2010 Sansar Choinyambuu
3 * HSR Hochschule fuer Technik Rapperswil
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>.
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
16 #include "pb_error_msg.h"
19 #include <tls_writer.h>
20 #include <tls_reader.h>
21 #include <tnc/tnccs/tnccs.h>
22 #include <tnc/pen/pen.h>
24 ENUM(pb_tnc_error_code_names
, PB_ERROR_UNEXPECTED_BATCH_TYPE
,
25 PB_ERROR_VERSION_NOT_SUPPORTED
,
26 "Unexpected Batch Type",
29 "Unsupported Mandatory Message",
30 "Version Not Supported"
33 typedef struct private_pb_error_msg_t private_pb_error_msg_t
;
36 * PB-Error message (see section 4.9 of RFC 5793)
39 * 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
40 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
41 * | Flags | Error Code Vendor ID |
42 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
43 * | Error Code | Reserved |
44 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
45 * | Error Parameters (Variable Length) |
46 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
49 #define ERROR_FLAG_NONE 0x00
50 #define ERROR_FLAG_FATAL (1<<7)
51 #define ERROR_RESERVED 0x0000
52 #define ERROR_HEADER_SIZE 8
55 * Private data of a pb_error_msg_t object.
58 struct private_pb_error_msg_t
{
60 * Public pb_error_msg_t interface.
62 pb_error_msg_t
public;
67 pb_tnc_msg_type_t type
;
75 * PB Error Code Vendor ID
87 u_int32_t error_offset
;
90 * Bad PB-TNC version received
105 METHOD(pb_tnc_msg_t
, get_type
, pb_tnc_msg_type_t
,
106 private_pb_error_msg_t
*this)
111 METHOD(pb_tnc_msg_t
, get_encoding
, chunk_t
,
112 private_pb_error_msg_t
*this)
114 return this->encoding
;
117 METHOD(pb_tnc_msg_t
, build
, void,
118 private_pb_error_msg_t
*this)
120 tls_writer_t
*writer
;
122 /* build message header */
123 writer
= tls_writer_create(ERROR_HEADER_SIZE
);
124 writer
->write_uint8 (writer
, this->fatal
?
125 ERROR_FLAG_FATAL
: ERROR_FLAG_NONE
);
126 writer
->write_uint24(writer
, this->vendor_id
);
127 writer
->write_uint16(writer
, this->error_code
);
128 writer
->write_uint16(writer
, ERROR_RESERVED
);
130 /* build message body */
131 if (this->error_code
== PB_ERROR_VERSION_NOT_SUPPORTED
)
134 writer
->write_uint8(writer
, this->bad_version
);
135 writer
->write_uint8(writer
, PB_TNC_VERSION
); /* Max version */
136 writer
->write_uint8(writer
, PB_TNC_VERSION
); /* Min version */
137 writer
->write_uint8(writer
, 0x00); /* Reserved */
142 writer
->write_uint32(writer
, this->error_offset
);
145 free(this->encoding
.ptr
);
146 this->encoding
= writer
->get_buf(writer
);
147 this->encoding
= chunk_clone(this->encoding
);
148 writer
->destroy(writer
);
151 METHOD(pb_tnc_msg_t
, process
, status_t
,
152 private_pb_error_msg_t
*this, u_int32_t
*offset
)
154 u_int8_t flags
, max_version
, min_version
;
156 tls_reader_t
*reader
;
158 if (this->encoding
.len
< ERROR_HEADER_SIZE
)
160 DBG1(DBG_TNC
,"%N message is shorter than header size of %u bytes",
161 pb_tnc_msg_type_names
, PB_MSG_ERROR
, ERROR_HEADER_SIZE
);
165 /* process message header */
166 reader
= tls_reader_create(this->encoding
);
167 reader
->read_uint8 (reader
, &flags
);
168 reader
->read_uint24(reader
, &this->vendor_id
);
169 reader
->read_uint16(reader
, &this->error_code
);
170 reader
->read_uint16(reader
, &reserved
);
171 this->fatal
= (flags
& ERROR_FLAG_FATAL
) != ERROR_FLAG_NONE
;
173 if (this->vendor_id
== PEN_IETF
&& reader
->remaining(reader
) == 4)
175 if (this->error_code
== PB_ERROR_VERSION_NOT_SUPPORTED
)
177 reader
->read_uint8(reader
, &this->bad_version
);
178 reader
->read_uint8(reader
, &max_version
);
179 reader
->read_uint8(reader
, &min_version
);
183 reader
->read_uint32(reader
, &this->error_offset
);
186 reader
->destroy(reader
);
191 METHOD(pb_tnc_msg_t
, get_ref
, pb_tnc_msg_t
*,
192 private_pb_error_msg_t
*this)
195 return &this->public.pb_interface
;
198 METHOD(pb_tnc_msg_t
, destroy
, void,
199 private_pb_error_msg_t
*this)
201 if (ref_put(&this->ref
))
203 free(this->encoding
.ptr
);
208 METHOD(pb_error_msg_t
, get_fatal_flag
, bool,
209 private_pb_error_msg_t
*this)
214 METHOD(pb_error_msg_t
, get_vendor_id
, u_int32_t
,
215 private_pb_error_msg_t
*this)
217 return this->vendor_id
;
220 METHOD(pb_error_msg_t
, get_error_code
, u_int16_t
,
221 private_pb_error_msg_t
*this)
223 return this->error_code
;
226 METHOD(pb_error_msg_t
, get_offset
, u_int32_t
,
227 private_pb_error_msg_t
*this)
229 return this->error_offset
;
232 METHOD(pb_error_msg_t
, get_bad_version
, u_int8_t
,
233 private_pb_error_msg_t
*this)
235 return this->bad_version
;
238 METHOD(pb_error_msg_t
, set_bad_version
, void,
239 private_pb_error_msg_t
*this, u_int8_t version
)
241 this->bad_version
= version
;
247 pb_tnc_msg_t
* pb_error_msg_create(bool fatal
, u_int32_t vendor_id
,
248 pb_tnc_error_code_t error_code
)
250 private_pb_error_msg_t
*this;
255 .get_type
= _get_type
,
256 .get_encoding
= _get_encoding
,
262 .get_fatal_flag
= _get_fatal_flag
,
263 .get_vendor_id
= _get_vendor_id
,
264 .get_error_code
= _get_error_code
,
265 .get_offset
= _get_offset
,
266 .get_bad_version
= _get_bad_version
,
267 .set_bad_version
= _set_bad_version
,
269 .type
= PB_MSG_ERROR
,
272 .vendor_id
= vendor_id
,
273 .error_code
= error_code
,
276 return &this->public.pb_interface
;
282 pb_tnc_msg_t
* pb_error_msg_create_with_offset(bool fatal
, u_int32_t vendor_id
,
283 pb_tnc_error_code_t error_code
,
284 u_int32_t error_offset
)
286 private_pb_error_msg_t
*this;
291 .get_type
= _get_type
,
292 .get_encoding
= _get_encoding
,
298 .get_fatal_flag
= _get_fatal_flag
,
299 .get_vendor_id
= _get_vendor_id
,
300 .get_error_code
= _get_error_code
,
301 .get_offset
= _get_offset
,
302 .get_bad_version
= _get_bad_version
,
303 .set_bad_version
= _set_bad_version
,
305 .type
= PB_MSG_ERROR
,
308 .vendor_id
= vendor_id
,
309 .error_code
= error_code
,
310 .error_offset
= error_offset
,
313 return &this->public.pb_interface
;
319 pb_tnc_msg_t
*pb_error_msg_create_from_data(chunk_t data
)
321 private_pb_error_msg_t
*this;
326 .get_type
= _get_type
,
327 .get_encoding
= _get_encoding
,
333 .get_fatal_flag
= _get_fatal_flag
,
334 .get_vendor_id
= _get_vendor_id
,
335 .get_error_code
= _get_error_code
,
336 .get_offset
= _get_offset
,
337 .get_bad_version
= _get_bad_version
,
338 .set_bad_version
= _set_bad_version
,
340 .type
= PB_MSG_ERROR
,
342 .encoding
= chunk_clone(data
),
345 return &this->public.pb_interface
;