fixed pb_reason_string_message_t class
[strongswan.git] / src / libcharon / plugins / tnccs_20 / messages / pb_reason_string_message.c
1 /*
2 * Copyright (C) 2010 Sansar Choinyambuu
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 "pb_reason_string_message.h"
17
18 #include <tls_writer.h>
19 #include <tls_reader.h>
20 #include <debug.h>
21
22 typedef struct private_pb_reason_string_message_t private_pb_reason_string_message_t;
23
24 /**
25 * PB-Language-Preference message (see section 4.11 of RFC 5793)
26 *
27 * 0 1 2 3
28 * 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
29 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
30 * | Reason String Length |
31 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
32 * | Reason String (Variable Length) |
33 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
34 * | Lang Code Len | Reason String Language Code (Variable Length) |
35 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
36 */
37
38 #define REASON_STRING_HEADER_SIZE 5
39
40 /**
41 * Private data of a private_pb_reason_string_message_t object.
42 *
43 */
44 struct private_pb_reason_string_message_t {
45 /**
46 * Public pb_reason_string_message_t interface.
47 */
48 pb_reason_string_message_t public;
49
50 /**
51 * PB-TNC message type
52 */
53 pb_tnc_msg_type_t type;
54
55 /**
56 * Reason string
57 */
58 chunk_t reason_string;
59
60 /**
61 * Language code
62 */
63 chunk_t language_code;
64
65 /**
66 * Encoded message
67 */
68 chunk_t encoding;
69 };
70
71 METHOD(pb_tnc_message_t, get_type, pb_tnc_msg_type_t,
72 private_pb_reason_string_message_t *this)
73 {
74 return this->type;
75 }
76
77 METHOD(pb_tnc_message_t, get_encoding, chunk_t,
78 private_pb_reason_string_message_t *this)
79 {
80 return this->encoding;
81 }
82
83 METHOD(pb_tnc_message_t, build, void,
84 private_pb_reason_string_message_t *this)
85 {
86 tls_writer_t *writer;
87
88 /* build message */
89 writer = tls_writer_create(REASON_STRING_HEADER_SIZE);
90 writer->write_uint32(writer, this->reason_string.len);
91 writer->write_data(writer, this->reason_string);
92
93 writer->write_uint8(writer, this->language_code.len);
94 writer->write_data(writer, this->language_code);
95
96 free(this->encoding.ptr);
97 this->encoding = writer->get_buf(writer);
98 this->encoding = chunk_clone(this->encoding);
99 writer->destroy(writer);
100 }
101
102 METHOD(pb_tnc_message_t, process, status_t,
103 private_pb_reason_string_message_t *this)
104 {
105 tls_reader_t *reader;
106 u_int32_t reason_string_length;
107 u_int8_t language_code_length;
108
109 if (this->encoding.len < REASON_STRING_HEADER_SIZE)
110 {
111 DBG1(DBG_TNC,"%N message is shorter than header size of %u bytes",
112 pb_tnc_msg_type_names, PB_MSG_REASON_STRING,
113 REASON_STRING_HEADER_SIZE);
114 return FAILED;
115 }
116
117 /* process message */
118 reader = tls_reader_create(this->encoding);
119 reader->read_uint32(reader, &reason_string_length);
120 reader->read_data(reader, reason_string_length, &this->reason_string);
121 this->reason_string = chunk_clone(this->reason_string);
122
123 reader->read_uint8(reader, &language_code_length);
124 reader->read_data(reader, language_code_length, &this->language_code);
125 this->language_code = chunk_clone(this->language_code);
126
127 reader->destroy(reader);
128 return SUCCESS;
129 }
130
131 METHOD(pb_tnc_message_t, destroy, void,
132 private_pb_reason_string_message_t *this)
133 {
134 free(this->encoding.ptr);
135 free(this->reason_string.ptr);
136 free(this->language_code.ptr);
137 free(this);
138 }
139
140 METHOD(pb_reason_string_message_t, get_reason_string, chunk_t,
141 private_pb_reason_string_message_t *this)
142 {
143 return this->reason_string;
144 }
145
146 METHOD(pb_reason_string_message_t, get_language_code, chunk_t,
147 private_pb_reason_string_message_t *this)
148 {
149 return this->language_code;
150 }
151
152 /**
153 * See header
154 */
155 pb_tnc_message_t *pb_reason_string_message_create_from_data(chunk_t data)
156 {
157 private_pb_reason_string_message_t *this;
158
159 INIT(this,
160 .public = {
161 .pb_interface = {
162 .get_type = _get_type,
163 .get_encoding = _get_encoding,
164 .build = _build,
165 .process = _process,
166 .destroy = _destroy,
167 },
168 .get_reason_string = _get_reason_string,
169 .get_language_code = _get_language_code,
170 },
171 .type = PB_MSG_REASON_STRING,
172 .encoding = chunk_clone(data),
173 );
174
175 return &this->public.pb_interface;
176 }
177
178 /**
179 * See header
180 */
181 pb_tnc_message_t *pb_reason_string_message_create(chunk_t reason_string,
182 chunk_t language_code)
183 {
184 private_pb_reason_string_message_t *this;
185
186 INIT(this,
187 .public = {
188 .pb_interface = {
189 .get_type = _get_type,
190 .get_encoding = _get_encoding,
191 .build = _build,
192 .process = _process,
193 .destroy = _destroy,
194 },
195 .get_reason_string = _get_reason_string,
196 .get_language_code = _get_language_code,
197 },
198 .type = PB_MSG_REASON_STRING,
199 .reason_string = chunk_clone(reason_string),
200 .language_code = chunk_clone(language_code),
201 );
202
203 return &this->public.pb_interface;
204 }