f8c78b6807d84c02d8956bdf6b614ce9532ef94e
[strongswan.git] / src / libtnccs / plugins / tnccs_20 / messages / tcg / pb_pdp_referral_msg.c
1 /*
2 * Copyright (C) 2013 Andreas Steffen
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_pdp_referral_msg.h"
17
18 #include <bio/bio_writer.h>
19 #include <bio/bio_reader.h>
20 #include <utils/debug.h>
21
22 ENUM(pb_tnc_pdp_identifier_type_names, PB_PDP_ID_FQDN, PB_PDP_ID_IPV6,
23 "PDP FQDN ID",
24 "PDP IPv4 ID",
25 "PDP IPv6 ID"
26 );
27
28 typedef struct private_pb_pdp_referral_msg_t private_pb_pdp_referral_msg_t;
29
30 /**
31 * PB-PDP-Referral message (see section 3.1.1.1 of
32 * TCG TNC PDP Discovery and Validation Specification 1.0
33 *
34 * 0 1 2 3
35 * 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
36 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
37 * | Reserved | PDP Identifier Vendor ID |
38 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
39 * | PDP Identifier Type |
40 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
41 * | PDP Identifier (Variable Length) |
42 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
43 *
44 * Section 3.1.1.2.1 FQDN Identifier
45 *
46 * 0 1 2 3
47 * 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
48 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
49 * | Reserved | Protocol | Port Number |
50 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
51 * | FQDN (Variable Length) |
52 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
53 *
54 * Section 3.1.1.2.2 IPv4 Identifier
55 *
56 * 0 1 2 3
57 * 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
58 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59 * | Reserved | Protocol | Port Number |
60 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
61 * | IPv4 Address |
62 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
63 *
64 * Section 3.1.1.2.3 IPv6 Identifier
65 *
66 * 0 1 2 3
67 * 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
68 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
69 * | Reserved | Protocol | Port Number |
70 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
71 * | IPv6 Address (octets 1-4) |
72 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
73 * | IPv6 Address (octets 5-8) |
74 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
75 * | IPv6 Address (octets 9-12) |
76 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
77 * | IPv6 Address (octets 13-16) |
78 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
79 *
80 */
81
82 /**
83 * Private data of a pb_pdp_referral_msg_t object.
84 *
85 */
86 struct private_pb_pdp_referral_msg_t {
87 /**
88 * Public pb_pdp_referral_msg_t interface.
89 */
90 pb_pdp_referral_msg_t public;
91
92 /**
93 * PB-TNC message type
94 */
95 pen_type_t type;
96
97 /**
98 * PDP Identifier Type
99 */
100 pen_type_t identifier_type;
101
102 /**
103 * PDP Identifier Value
104 */
105 chunk_t identifier;
106
107 /**
108 * Encoded message
109 */
110 chunk_t encoding;
111 };
112
113 METHOD(pb_tnc_msg_t, get_type, pen_type_t,
114 private_pb_pdp_referral_msg_t *this)
115 {
116 return this->type;
117 }
118
119 METHOD(pb_tnc_msg_t, get_encoding, chunk_t,
120 private_pb_pdp_referral_msg_t *this)
121 {
122 return this->encoding;
123 }
124
125 METHOD(pb_tnc_msg_t, build, void,
126 private_pb_pdp_referral_msg_t *this)
127 {
128 bio_writer_t *writer;
129
130 if (this->encoding.ptr)
131 {
132 return;
133 }
134 writer = bio_writer_create(64);
135 writer->write_uint32(writer, this->identifier_type.vendor_id);
136 writer->write_uint32(writer, this->identifier_type.type);
137 writer->write_data(writer, this->identifier);
138
139 this->encoding = writer->get_buf(writer);
140 this->encoding = chunk_clone(this->encoding);
141 writer->destroy(writer);
142 }
143
144 METHOD(pb_tnc_msg_t, process, status_t,
145 private_pb_pdp_referral_msg_t *this, u_int32_t *offset)
146 {
147 bio_reader_t *reader;
148 u_int8_t reserved;
149 status_t status = SUCCESS;
150
151 *offset = 0;
152
153 /* process message */
154 reader = bio_reader_create(this->encoding);
155 reader->read_uint8 (reader, &reserved);
156 reader->read_uint24(reader, &this->identifier_type.vendor_id);
157 reader->read_uint32(reader, &this->identifier_type.type);
158 reader->read_data (reader, reader->remaining(reader), &this->identifier);
159
160 this->identifier = chunk_clone(this->identifier);
161 reader->destroy(reader);
162
163 if (this->identifier_type.vendor_id == PEN_TCG)
164 {
165 /* TODO parse PDP Identifier Types */
166 }
167 return status;
168 }
169
170 METHOD(pb_tnc_msg_t, destroy, void,
171 private_pb_pdp_referral_msg_t *this)
172 {
173 free(this->encoding.ptr);
174 free(this->identifier.ptr);
175 free(this);
176 }
177
178 METHOD(pb_pdp_referral_msg_t, get_identifier_type, pen_type_t,
179 private_pb_pdp_referral_msg_t *this)
180 {
181 return this->identifier_type;
182 }
183
184 METHOD(pb_pdp_referral_msg_t, get_identifier, chunk_t,
185 private_pb_pdp_referral_msg_t *this)
186 {
187 return this->identifier;
188 }
189
190 /**
191 * See header
192 */
193 pb_tnc_msg_t* pb_pdp_referral_msg_create(pen_type_t identifier_type,
194 chunk_t identifier)
195 {
196 private_pb_pdp_referral_msg_t *this;
197
198 INIT(this,
199 .public = {
200 .pb_interface = {
201 .get_type = _get_type,
202 .get_encoding = _get_encoding,
203 .build = _build,
204 .process = _process,
205 .destroy = _destroy,
206 },
207 .get_identifier_type = _get_identifier_type,
208 .get_identifier = _get_identifier,
209 },
210 .type = { PEN_TCG, PB_TCG_MSG_PDP_REFERRAL },
211 .identifier_type = identifier_type,
212 .identifier = chunk_clone(identifier),
213 );
214
215 return &this->public.pb_interface;
216 }
217
218 /**
219 * See header
220 */
221 pb_tnc_msg_t *pb_pdp_referral_msg_create_from_data(chunk_t data)
222 {
223 private_pb_pdp_referral_msg_t *this;
224
225 INIT(this,
226 .public = {
227 .pb_interface = {
228 .get_type = _get_type,
229 .get_encoding = _get_encoding,
230 .build = _build,
231 .process = _process,
232 .destroy = _destroy,
233 },
234 .get_identifier_type = _get_identifier_type,
235 .get_identifier = _get_identifier,
236 },
237 .type = { PEN_TCG, PB_TCG_MSG_PDP_REFERRAL },
238 .encoding = chunk_clone(data),
239 );
240
241 return &this->public.pb_interface;
242 }
243