]> git.ipfire.org Git - thirdparty/strongswan.git/blob - src/libtnccs/plugins/tnccs_20/messages/ietf/pb_language_preference_msg.c
Update copyright headers after acquisition by secunet
[thirdparty/strongswan.git] / src / libtnccs / plugins / tnccs_20 / messages / ietf / pb_language_preference_msg.c
1 /*
2 * Copyright (C) 2010 Sansar Choinyambuu
3 *
4 * Copyright (C) secunet Security Networks AG
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
15 */
16
17 #include "pb_language_preference_msg.h"
18
19 #include <bio/bio_writer.h>
20 #include <bio/bio_reader.h>
21 #include <utils/debug.h>
22
23 typedef struct private_pb_language_preference_msg_t private_pb_language_preference_msg_t;
24
25 /**
26 * PB-Language-Preference message (see section 4.10 of RFC 5793)
27 *
28 * 0 1 2 3
29 * 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
30 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
31 * | Language Preference (Variable Length) |
32 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
33 */
34
35 #define PB_LANG_PREFIX "Accept-Language: "
36 #define PB_LANG_PREFIX_LEN strlen(PB_LANG_PREFIX)
37
38 /**
39 * Private data of a pb_language_preference_msg_t object.
40 *
41 */
42 struct private_pb_language_preference_msg_t {
43 /**
44 * Public pb_access_recommendation_msg_t interface.
45 */
46 pb_language_preference_msg_t public;
47
48 /**
49 * PB-TNC message type
50 */
51 pen_type_t type;
52
53 /**
54 * Language preference
55 */
56 chunk_t language_preference;
57
58 /**
59 * Encoded message
60 */
61 chunk_t encoding;
62 };
63
64 METHOD(pb_tnc_msg_t, get_type, pen_type_t,
65 private_pb_language_preference_msg_t *this)
66 {
67 return this->type;
68 }
69
70 METHOD(pb_tnc_msg_t, get_encoding, chunk_t,
71 private_pb_language_preference_msg_t *this)
72 {
73 return this->encoding;
74 }
75
76 METHOD(pb_tnc_msg_t, build, void,
77 private_pb_language_preference_msg_t *this)
78 {
79 if (this->encoding.ptr)
80 {
81 return;
82 }
83 this->encoding = chunk_cat("cc",
84 chunk_create(PB_LANG_PREFIX, PB_LANG_PREFIX_LEN),
85 this->language_preference);
86 }
87
88 METHOD(pb_tnc_msg_t, process, status_t,
89 private_pb_language_preference_msg_t *this, uint32_t *offset)
90 {
91 chunk_t lang;
92
93 if (this->encoding.len >= PB_LANG_PREFIX_LEN &&
94 memeq(this->encoding.ptr, PB_LANG_PREFIX, PB_LANG_PREFIX_LEN))
95 {
96 lang = chunk_skip(this->encoding, PB_LANG_PREFIX_LEN);
97 this->language_preference = lang.len ? chunk_clone(lang) : chunk_empty;
98 }
99 else
100 {
101 DBG1(DBG_TNC, "language preference must be preceded by '%s'",
102 PB_LANG_PREFIX);
103 *offset = 0;
104 return FAILED;
105 }
106
107 if (this->language_preference.len &&
108 this->language_preference.ptr[this->language_preference.len-1] == '\0')
109 {
110 DBG1(DBG_TNC, "language preference must not be null terminated");
111 *offset = PB_LANG_PREFIX_LEN + this->language_preference.len - 1;
112 return FAILED;
113 }
114
115 return SUCCESS;
116 }
117
118 METHOD(pb_tnc_msg_t, destroy, void,
119 private_pb_language_preference_msg_t *this)
120 {
121 free(this->encoding.ptr);
122 free(this->language_preference.ptr);
123 free(this);
124 }
125
126 METHOD(pb_language_preference_msg_t, get_language_preference, chunk_t,
127 private_pb_language_preference_msg_t *this)
128 {
129 return this->language_preference;
130 }
131
132 /**
133 * See header
134 */
135 pb_tnc_msg_t *pb_language_preference_msg_create_from_data(chunk_t data)
136 {
137 private_pb_language_preference_msg_t *this;
138
139 INIT(this,
140 .public = {
141 .pb_interface = {
142 .get_type = _get_type,
143 .get_encoding = _get_encoding,
144 .build = _build,
145 .process = _process,
146 .destroy = _destroy,
147 },
148 .get_language_preference = _get_language_preference,
149 },
150 .type = { PEN_IETF, PB_MSG_LANGUAGE_PREFERENCE },
151 .encoding = chunk_clone(data),
152 );
153
154 return &this->public.pb_interface;
155 }
156
157 /**
158 * See header
159 */
160 pb_tnc_msg_t *pb_language_preference_msg_create(chunk_t language_preference)
161 {
162 private_pb_language_preference_msg_t *this;
163
164 INIT(this,
165 .public = {
166 .pb_interface = {
167 .get_type = _get_type,
168 .get_encoding = _get_encoding,
169 .build = _build,
170 .process = _process,
171 .destroy = _destroy,
172 },
173 .get_language_preference = _get_language_preference,
174 },
175 .type = { PEN_IETF, PB_MSG_LANGUAGE_PREFERENCE },
176 .language_preference = chunk_clone(language_preference),
177 );
178
179 return &this->public.pb_interface;
180 }