PB-TNC messages implemented
[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 length
57 */
58 u_int32_t reason_string_length;
59
60 /**
61 * Reason string
62 */
63 chunk_t reason_string;
64
65 /**
66 * Language code length
67 */
68 u_int8_t language_code_length;
69
70 /**
71 * Language code
72 */
73 chunk_t language_code;
74
75 /**
76 * Encoded message
77 */
78 chunk_t encoding;
79 };
80
81 METHOD(pb_tnc_message_t, get_type, pb_tnc_msg_type_t,
82 private_pb_reason_string_message_t *this)
83 {
84 return this->type;
85 }
86
87 METHOD(pb_tnc_message_t, get_encoding, chunk_t,
88 private_pb_reason_string_message_t *this)
89 {
90 return this->encoding;
91 }
92
93 METHOD(pb_tnc_message_t, build, void,
94 private_pb_reason_string_message_t *this)
95 {
96 tls_writer_t *writer;
97
98 /* build message */
99 writer = tls_writer_create(REASON_STRING_HEADER_SIZE);
100 writer->write_uint32(writer, this->reason_string_length);
101 writer->write_data(writer, this->reason_string);
102
103 writer->write_uint8(writer, this->language_code_length);
104 writer->write_data(writer, this->language_code);
105
106 free(this->encoding.ptr);
107 this->encoding = writer->get_buf(writer);
108 this->encoding = chunk_clone(this->encoding);
109 writer->destroy(writer);
110 }
111
112 METHOD(pb_tnc_message_t, process, status_t,
113 private_pb_reason_string_message_t *this)
114 {
115 tls_reader_t *reader;
116
117 if (this->encoding.len < REASON_STRING_HEADER_SIZE)
118 {
119 DBG1(DBG_TNC,"%N message is shorter than header size of %u bytes",
120 pb_tnc_msg_type_names, PB_MSG_REASON_STRING,
121 REASON_STRING_HEADER_SIZE);
122 return FAILED;
123 }
124
125 /* process message */
126 reader = tls_reader_create(this->encoding);
127 reader->read_uint32(reader, &this->reason_string_length);
128 reader->read_data(reader, this->reason_string_length, &this->reason_string);
129
130 reader->read_uint8(reader, &this->language_code_length);
131 reader->read_data(reader, this->language_code_length, &this->language_code);
132
133 reader->destroy(reader);
134 return SUCCESS;
135 }
136
137 METHOD(pb_tnc_message_t, destroy, void,
138 private_pb_reason_string_message_t *this)
139 {
140 free(this->encoding.ptr);
141 free(this->reason_string.ptr);
142 free(this->language_code.ptr);
143 free(this);
144 }
145
146 METHOD(pb_reason_string_message_t, get_reason_string_length, u_int32_t,
147 private_pb_reason_string_message_t *this)
148 {
149 return this->reason_string_length;
150 }
151
152 METHOD(pb_reason_string_message_t, get_reason_string, chunk_t,
153 private_pb_reason_string_message_t *this)
154 {
155 return this->reason_string;
156 }
157
158 METHOD(pb_reason_string_message_t, get_language_code_length, u_int8_t,
159 private_pb_reason_string_message_t *this)
160 {
161 return this->language_code_length;
162 }
163
164 METHOD(pb_reason_string_message_t, get_language_code, chunk_t,
165 private_pb_reason_string_message_t *this)
166 {
167 return this->language_code;
168 }
169
170 /**
171 * See header
172 */
173 pb_tnc_message_t *pb_reason_string_message_create_from_data(chunk_t data)
174 {
175 private_pb_reason_string_message_t *this;
176
177 INIT(this,
178 .public = {
179 .pb_interface = {
180 .get_type = _get_type,
181 .get_encoding = _get_encoding,
182 .build = _build,
183 .process = _process,
184 .destroy = _destroy,
185 },
186 .get_reason_string_length = _get_reason_string_length,
187 .get_reason_string = _get_reason_string,
188 .get_language_code_length = _get_language_code_length,
189 .get_language_code = _get_language_code,
190 },
191 .type = PB_MSG_REASON_STRING,
192 .encoding = chunk_clone(data),
193 );
194
195 return &this->public.pb_interface;
196 }
197
198 /**
199 * See header
200 */
201 pb_tnc_message_t *pb_reason_string_message_create(chunk_t reason_string,
202 chunk_t language_code)
203 {
204 private_pb_reason_string_message_t *this;
205
206 INIT(this,
207 .public = {
208 .pb_interface = {
209 .get_type = _get_type,
210 .get_encoding = _get_encoding,
211 .build = _build,
212 .process = _process,
213 .destroy = _destroy,
214 },
215 .get_reason_string_length = _get_reason_string_length,
216 .get_reason_string = _get_reason_string,
217 .get_language_code_length = _get_language_code_length,
218 .get_language_code = _get_language_code,
219 },
220 .type = PB_MSG_REASON_STRING,
221 .reason_string_length = reason_string.len,
222 .reason_string = reason_string,
223 .language_code_length = language_code.len,
224 .language_code = language_code,
225 );
226
227 return &this->public.pb_interface;
228 }