Annotation of embedaddon/strongswan/src/libimcv/ietf/ietf_attr_product_info.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2011-2014 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 "ietf_attr_product_info.h"
17:
18: #include <pa_tnc/pa_tnc_msg.h>
19: #include <bio/bio_writer.h>
20: #include <bio/bio_reader.h>
21: #include <utils/debug.h>
22:
23: typedef struct private_ietf_attr_product_info_t private_ietf_attr_product_info_t;
24:
25: /**
26: * PA-TNC Product Information type (see section 4.2.2 of RFC 5792)
27: *
28: * 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: * | Product Vendor ID | Product ID |
32: * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
33: * | Product ID | Product Name (Variable Length) |
34: * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
35: */
36:
37: #define PRODUCT_INFO_MIN_SIZE 5
38:
39: /**
40: * Private data of an ietf_attr_product_info_t object.
41: */
42: struct private_ietf_attr_product_info_t {
43:
44: /**
45: * Public members of ietf_attr_product_info_t
46: */
47: ietf_attr_product_info_t public;
48:
49: /**
50: * Vendor-specific attribute type
51: */
52: pen_type_t type;
53:
54: /**
55: * Length of attribute value
56: */
57: size_t length;
58:
59: /**
60: * Attribute value or segment
61: */
62: chunk_t value;
63:
64: /**
65: * Noskip flag
66: */
67: bool noskip_flag;
68:
69: /**
70: * Product vendor ID
71: */
72: pen_t product_vendor_id;
73:
74: /**
75: * Product ID
76: */
77: uint16_t product_id;
78:
79: /**
80: * Product Name
81: */
82: chunk_t product_name;
83:
84: /**
85: * Reference count
86: */
87: refcount_t ref;
88: };
89:
90: METHOD(pa_tnc_attr_t, get_type, pen_type_t,
91: private_ietf_attr_product_info_t *this)
92: {
93: return this->type;
94: }
95:
96: METHOD(pa_tnc_attr_t, get_value, chunk_t,
97: private_ietf_attr_product_info_t *this)
98: {
99: return this->value;
100: }
101:
102: METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
103: private_ietf_attr_product_info_t *this)
104: {
105: return this->noskip_flag;
106: }
107:
108: METHOD(pa_tnc_attr_t, set_noskip_flag,void,
109: private_ietf_attr_product_info_t *this, bool noskip)
110: {
111: this->noskip_flag = noskip;
112: }
113:
114: METHOD(pa_tnc_attr_t, build, void,
115: private_ietf_attr_product_info_t *this)
116: {
117: bio_writer_t *writer;
118:
119: if (this->value.ptr)
120: {
121: return;
122: }
123: writer = bio_writer_create(PRODUCT_INFO_MIN_SIZE);
124: writer->write_uint24(writer, this->product_vendor_id);
125: writer->write_uint16(writer, this->product_id);
126: writer->write_data (writer, this->product_name);
127:
128: this->value = writer->extract_buf(writer);
129: this->length = this->value.len;
130: writer->destroy(writer);
131: }
132:
133: METHOD(pa_tnc_attr_t, process, status_t,
134: private_ietf_attr_product_info_t *this, uint32_t *offset)
135: {
136: bio_reader_t *reader;
137: chunk_t product_name;
138:
139: *offset = 0;
140:
141: if (this->value.len < this->length)
142: {
143: return NEED_MORE;
144: }
145: if (this->value.len < PRODUCT_INFO_MIN_SIZE)
146: {
147: DBG1(DBG_TNC, "insufficient data for IETF product information");
148: return FAILED;
149: }
150: reader = bio_reader_create(this->value);
151: reader->read_uint24(reader, &this->product_vendor_id);
152: reader->read_uint16(reader, &this->product_id);
153: reader->read_data (reader, reader->remaining(reader), &product_name);
154: reader->destroy(reader);
155:
156: if (!this->product_vendor_id && this->product_id)
157: {
158: DBG1(DBG_TNC, "IETF product information vendor ID is 0 "
159: "but product ID is not 0");
160: *offset = 3;
161: return FAILED;
162: }
163: this->product_name = chunk_clone(product_name);
164:
165: return SUCCESS;
166: }
167:
168: METHOD(pa_tnc_attr_t, add_segment, void,
169: private_ietf_attr_product_info_t *this, chunk_t segment)
170: {
171: this->value = chunk_cat("mc", this->value, segment);
172: }
173:
174: METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*,
175: private_ietf_attr_product_info_t *this)
176: {
177: ref_get(&this->ref);
178: return &this->public.pa_tnc_attribute;
179: }
180:
181: METHOD(pa_tnc_attr_t, destroy, void,
182: private_ietf_attr_product_info_t *this)
183: {
184: if (ref_put(&this->ref))
185: {
186: free(this->product_name.ptr);
187: free(this->value.ptr);
188: free(this);
189: }
190: }
191:
192: METHOD(ietf_attr_product_info_t, get_info, chunk_t,
193: private_ietf_attr_product_info_t *this, pen_t *vendor_id, uint16_t *id)
194: {
195: if (vendor_id)
196: {
197: *vendor_id = this->product_vendor_id;
198: }
199: if (id)
200: {
201: *id = this->product_id;
202: }
203: return this->product_name;
204: }
205:
206: /**
207: * Described in header.
208: */
209: pa_tnc_attr_t *ietf_attr_product_info_create(pen_t vendor_id, uint16_t id,
210: chunk_t name)
211: {
212: private_ietf_attr_product_info_t *this;
213:
214: INIT(this,
215: .public = {
216: .pa_tnc_attribute = {
217: .get_type = _get_type,
218: .get_value = _get_value,
219: .get_noskip_flag = _get_noskip_flag,
220: .set_noskip_flag = _set_noskip_flag,
221: .build = _build,
222: .process = _process,
223: .add_segment = _add_segment,
224: .get_ref = _get_ref,
225: .destroy = _destroy,
226: },
227: .get_info = _get_info,
228: },
229: .type = { PEN_IETF, IETF_ATTR_PRODUCT_INFORMATION },
230: .product_vendor_id = vendor_id,
231: .product_id = id,
232: .product_name = chunk_clone(name),
233: .ref = 1,
234: );
235:
236: return &this->public.pa_tnc_attribute;
237: }
238:
239: /**
240: * Described in header.
241: */
242: pa_tnc_attr_t *ietf_attr_product_info_create_from_data(size_t length,
243: chunk_t data)
244: {
245: private_ietf_attr_product_info_t *this;
246:
247: INIT(this,
248: .public = {
249: .pa_tnc_attribute = {
250: .get_type = _get_type,
251: .get_value = _get_value,
252: .get_noskip_flag = _get_noskip_flag,
253: .set_noskip_flag = _set_noskip_flag,
254: .build = _build,
255: .process = _process,
256: .add_segment = _add_segment,
257: .get_ref = _get_ref,
258: .destroy = _destroy,
259: },
260: .get_info = _get_info,
261: },
262: .type = { PEN_IETF, IETF_ATTR_PRODUCT_INFORMATION },
263: .length = length,
264: .value = chunk_clone(data),
265: .ref = 1,
266: );
267:
268: return &this->public.pa_tnc_attribute;
269: }
270:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>