2 * Copyright (C) 2013 Andreas Steffen
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_pdp_referral_msg.h"
18 #include <bio/bio_writer.h>
19 #include <bio/bio_reader.h>
20 #include <utils/debug.h>
22 ENUM(pb_tnc_pdp_identifier_type_names
, PB_PDP_ID_FQDN
, PB_PDP_ID_IPV6
,
28 typedef struct private_pb_pdp_referral_msg_t private_pb_pdp_referral_msg_t
;
31 * PB-PDP-Referral message (see section 3.1.1.1 of
32 * TCG TNC PDP Discovery and Validation Specification 1.0
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 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
44 * Section 3.1.1.2.1 FQDN Identifier
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 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
54 * Section 3.1.1.2.2 IPv4 Identifier
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 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
62 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
64 * Section 3.1.1.2.3 IPv6 Identifier
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 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
82 # define PDP_REFERRAL_HEADER_SIZE 8
83 # define PDP_REFERRAL_ID_HEADER_SIZE 4
84 # define PDP_REFERRAL_RESERVED 0x00
85 # define PDP_REFERRAL_PROTOCOL 0x00
88 * Private data of a pb_pdp_referral_msg_t object.
91 struct private_pb_pdp_referral_msg_t
{
93 * Public pb_pdp_referral_msg_t interface.
95 pb_pdp_referral_msg_t
public;
103 * PDP Identifier Type
105 pen_type_t identifier_type
;
108 * PDP Identifier Value
113 * PDP FQDN Identifier
118 * PT protocol the PDP is using
123 * PT port the PDP is using
133 METHOD(pb_tnc_msg_t
, get_type
, pen_type_t
,
134 private_pb_pdp_referral_msg_t
*this)
139 METHOD(pb_tnc_msg_t
, get_encoding
, chunk_t
,
140 private_pb_pdp_referral_msg_t
*this)
142 return this->encoding
;
145 METHOD(pb_tnc_msg_t
, build
, void,
146 private_pb_pdp_referral_msg_t
*this)
148 bio_writer_t
*writer
;
150 if (this->encoding
.ptr
)
154 writer
= bio_writer_create(PDP_REFERRAL_HEADER_SIZE
+ this->identifier
.len
);
155 writer
->write_uint8 (writer
, PDP_REFERRAL_RESERVED
);
156 writer
->write_uint24(writer
, this->identifier_type
.vendor_id
);
157 writer
->write_uint32(writer
, this->identifier_type
.type
);
158 writer
->write_data (writer
, this->identifier
);
160 this->encoding
= writer
->get_buf(writer
);
161 this->encoding
= chunk_clone(this->encoding
);
162 writer
->destroy(writer
);
165 METHOD(pb_tnc_msg_t
, process
, status_t
,
166 private_pb_pdp_referral_msg_t
*this, u_int32_t
*offset
)
168 bio_reader_t
*reader
;
173 /* process message */
174 reader
= bio_reader_create(this->encoding
);
175 reader
->read_uint8 (reader
, &reserved
);
176 reader
->read_uint24(reader
, &this->identifier_type
.vendor_id
);
177 reader
->read_uint32(reader
, &this->identifier_type
.type
);
178 reader
->read_data (reader
, reader
->remaining(reader
), &this->identifier
);
180 this->identifier
= chunk_clone(this->identifier
);
181 reader
->destroy(reader
);
183 if (this->identifier_type
.vendor_id
== PEN_TCG
&&
184 this->identifier_type
.type
== PB_PDP_ID_FQDN
)
186 reader
= bio_reader_create(this->identifier
);
187 *offset
+= PDP_REFERRAL_HEADER_SIZE
;
189 if (this->identifier
.len
<= PDP_REFERRAL_ID_HEADER_SIZE
)
191 reader
->destroy(reader
);
194 reader
->read_uint8 (reader
, &reserved
);
195 reader
->read_uint8 (reader
, &this->protocol
);
196 reader
->read_uint16(reader
, &this->port
);
197 reader
->read_data (reader
, reader
->remaining(reader
), &this->fqdn
);
198 this->fqdn
= chunk_clone(this->fqdn
);
199 reader
->destroy(reader
);
204 METHOD(pb_tnc_msg_t
, destroy
, void,
205 private_pb_pdp_referral_msg_t
*this)
207 free(this->encoding
.ptr
);
208 free(this->identifier
.ptr
);
209 free(this->fqdn
.ptr
);
213 METHOD(pb_pdp_referral_msg_t
, get_identifier_type
, pen_type_t
,
214 private_pb_pdp_referral_msg_t
*this)
216 return this->identifier_type
;
219 METHOD(pb_pdp_referral_msg_t
, get_identifier
, chunk_t
,
220 private_pb_pdp_referral_msg_t
*this)
222 return this->identifier
;
225 METHOD(pb_pdp_referral_msg_t
, get_fqdn
, chunk_t
,
226 private_pb_pdp_referral_msg_t
*this, u_int8_t
*protocol
, u_int16_t
*port
)
230 *protocol
= this->protocol
;
242 pb_tnc_msg_t
* pb_pdp_referral_msg_create(pen_type_t identifier_type
,
245 private_pb_pdp_referral_msg_t
*this;
250 .get_type
= _get_type
,
251 .get_encoding
= _get_encoding
,
256 .get_identifier_type
= _get_identifier_type
,
257 .get_identifier
= _get_identifier
,
259 .type
= { PEN_TCG
, PB_TCG_MSG_PDP_REFERRAL
},
260 .identifier_type
= identifier_type
,
261 .identifier
= chunk_clone(identifier
),
264 return &this->public.pb_interface
;
270 pb_tnc_msg_t
* pb_pdp_referral_msg_create_from_fqdn(chunk_t fqdn
, u_int16_t port
)
273 bio_writer_t
*writer
;
274 pen_type_t type
= { PEN_TCG
, PB_PDP_ID_FQDN
};
276 writer
= bio_writer_create(PDP_REFERRAL_ID_HEADER_SIZE
+ fqdn
.len
);
277 writer
->write_uint8 (writer
, PDP_REFERRAL_RESERVED
);
278 writer
->write_uint8 (writer
, PDP_REFERRAL_PROTOCOL
);
279 writer
->write_uint16(writer
, port
);
280 writer
->write_data (writer
, fqdn
);
282 msg
= pb_pdp_referral_msg_create(type
, writer
->get_buf(writer
));
283 writer
->destroy(writer
);
291 pb_tnc_msg_t
*pb_pdp_referral_msg_create_from_data(chunk_t data
)
293 private_pb_pdp_referral_msg_t
*this;
298 .get_type
= _get_type
,
299 .get_encoding
= _get_encoding
,
304 .get_identifier_type
= _get_identifier_type
,
305 .get_identifier
= _get_identifier
,
306 .get_fqdn
= _get_fqdn
,
308 .type
= { PEN_TCG
, PB_TCG_MSG_PDP_REFERRAL
},
309 .encoding
= chunk_clone(data
),
312 return &this->public.pb_interface
;