1: /*
2: * Copyright (C) 2015 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 "generic_attr_bool.h"
17:
18: #include <imcv.h>
19: #include <pa_tnc/pa_tnc_msg.h>
20: #include <bio/bio_writer.h>
21: #include <bio/bio_reader.h>
22: #include <utils/debug.h>
23:
24: typedef struct private_generic_attr_bool_t private_generic_attr_bool_t;
25:
26: /**
27: * Generic PA-TNC attribute containing boolean status value in 32 bit encoding
28: *
29: * 1 2 3
30: * 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
31: * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
32: * | Boolean Value |
33: * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
34: */
35:
36: #define ATTR_BOOL_SIZE 4
37:
38: /**
39: * Private data of an generic_attr_bool_t object.
40: */
41: struct private_generic_attr_bool_t {
42:
43: /**
44: * Public members of generic_attr_bool_t
45: */
46: generic_attr_bool_t public;
47:
48: /**
49: * Vendor-specific attribute type
50: */
51: pen_type_t type;
52:
53: /**
54: * Length of attribute value
55: */
56: size_t length;
57:
58: /**
59: * Attribute value or segment
60: */
61: chunk_t value;
62:
63: /**
64: * Noskip flag
65: */
66: bool noskip_flag;
67:
68: /**
69: * Boolean status value
70: */
71: bool status;
72:
73: /**
74: * Reference count
75: */
76: refcount_t ref;
77: };
78:
79: METHOD(pa_tnc_attr_t, get_type, pen_type_t,
80: private_generic_attr_bool_t *this)
81: {
82: return this->type;
83: }
84:
85: METHOD(pa_tnc_attr_t, get_value, chunk_t,
86: private_generic_attr_bool_t *this)
87: {
88: return this->value;
89: }
90:
91: METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
92: private_generic_attr_bool_t *this)
93: {
94: return this->noskip_flag;
95: }
96:
97: METHOD(pa_tnc_attr_t, set_noskip_flag,void,
98: private_generic_attr_bool_t *this, bool noskip)
99: {
100: this->noskip_flag = noskip;
101: }
102:
103: METHOD(pa_tnc_attr_t, build, void,
104: private_generic_attr_bool_t *this)
105: {
106: bio_writer_t *writer;
107:
108: if (this->value.ptr)
109: {
110: return;
111: }
112: writer = bio_writer_create(ATTR_BOOL_SIZE);
113: writer->write_uint32(writer, this->status);
114:
115: this->value = writer->extract_buf(writer);
116: this->length = this->value.len;
117: writer->destroy(writer);
118: }
119:
120: METHOD(pa_tnc_attr_t, process, status_t,
121: private_generic_attr_bool_t *this, uint32_t *offset)
122: {
123: enum_name_t *pa_attr_names;
124: bio_reader_t *reader;
125: uint32_t status;
126:
127: *offset = 0;
128:
129: if (this->value.len < this->length)
130: {
131: return NEED_MORE;
132: }
133: pa_attr_names = imcv_pa_tnc_attributes->get_names(imcv_pa_tnc_attributes,
134: this->type.vendor_id);
135:
136: if (this->value.len != ATTR_BOOL_SIZE)
137: {
138: DBG1(DBG_TNC, "incorrect attribute size for %N/%N",
139: pen_names, this->type.vendor_id, pa_attr_names, this->type.type);
140: return FAILED;
141: }
142: reader = bio_reader_create(this->value);
143: reader->read_uint32(reader, &status);
144: reader->destroy(reader);
145:
146: if (status > 1)
147: {
148: DBG1(DBG_TNC, "%N/%N attribute contains invalid non-boolean value %u",
149: pen_names, this->type.vendor_id, pa_attr_names, this->type.type,
150: status);
151: return FAILED;
152: }
153: this->status = status;
154:
155: return SUCCESS;
156: }
157:
158: METHOD(pa_tnc_attr_t, add_segment, void,
159: private_generic_attr_bool_t *this, chunk_t segment)
160: {
161: this->value = chunk_cat("mc", this->value, segment);
162: }
163:
164: METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*,
165: private_generic_attr_bool_t *this)
166: {
167: ref_get(&this->ref);
168: return &this->public.pa_tnc_attribute;
169: }
170:
171: METHOD(pa_tnc_attr_t, destroy, void,
172: private_generic_attr_bool_t *this)
173: {
174: if (ref_put(&this->ref))
175: {
176: free(this->value.ptr);
177: free(this);
178: }
179: }
180:
181: METHOD(generic_attr_bool_t, get_status, bool,
182: private_generic_attr_bool_t *this)
183: {
184: return this->status;
185: }
186:
187: /**
188: * Described in header.
189: */
190: pa_tnc_attr_t *generic_attr_bool_create(bool status, pen_type_t type)
191: {
192: private_generic_attr_bool_t *this;
193:
194: INIT(this,
195: .public = {
196: .pa_tnc_attribute = {
197: .get_type = _get_type,
198: .get_value = _get_value,
199: .get_noskip_flag = _get_noskip_flag,
200: .set_noskip_flag = _set_noskip_flag,
201: .build = _build,
202: .process = _process,
203: .add_segment = _add_segment,
204: .get_ref = _get_ref,
205: .destroy = _destroy,
206: },
207: .get_status = _get_status,
208: },
209: .type = type,
210: .status = status,
211: .ref = 1,
212: );
213:
214: return &this->public.pa_tnc_attribute;
215: }
216:
217: /**
218: * Described in header.
219: */
220: pa_tnc_attr_t *generic_attr_bool_create_from_data(size_t length, chunk_t data,
221: pen_type_t type)
222: {
223: private_generic_attr_bool_t *this;
224:
225: INIT(this,
226: .public = {
227: .pa_tnc_attribute = {
228: .get_type = _get_type,
229: .get_value = _get_value,
230: .get_noskip_flag = _get_noskip_flag,
231: .set_noskip_flag = _set_noskip_flag,
232: .build = _build,
233: .process = _process,
234: .add_segment = _add_segment,
235: .get_ref = _get_ref,
236: .destroy = _destroy,
237: },
238: .get_status = _get_status,
239: },
240: .type = type,
241: .length = length,
242: .value = chunk_clone(data),
243: .ref = 1,
244: );
245:
246: return &this->public.pa_tnc_attribute;
247: }
248:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>