chunk_t msg_info;
/**
- * First 8 bytes of unsupported PA-TNC attribute
+ * Flags of unsupported PA-TNC attribute
*/
- chunk_t attr_info;
+ uint8_t flags;
+
+ /**
+ * Vendor ID and type of unsupported PA-TNC attribute
+ */
+ pen_type_t unsupported_type;
/**
* PA-TNC error offset
*/
- u_int32_t error_offset;
+ uint32_t error_offset;
/**
* Reference count
writer->write_uint16(writer, PA_ERROR_VERSION_RESERVED);
break;
case PA_ERROR_ATTR_TYPE_NOT_SUPPORTED:
- writer->write_data(writer, this->attr_info);
+ writer->write_uint8 (writer, this->flags);
+ writer->write_uint24(writer, this->unsupported_type.vendor_id);
+ writer->write_uint32(writer, this->unsupported_type.type);
break;
default:
break;
}
METHOD(pa_tnc_attr_t, process, status_t,
- private_ietf_attr_pa_tnc_error_t *this, u_int32_t *offset)
+ private_ietf_attr_pa_tnc_error_t *this, uint32_t *offset)
{
bio_reader_t *reader;
- u_int8_t reserved;
+ uint8_t reserved;
+ uint32_t vendor_id, type;
if (this->value.len < PA_ERROR_HEADER_SIZE)
{
}
break;
case PA_ERROR_ATTR_TYPE_NOT_SUPPORTED:
- if (!reader->read_data(reader, PA_ERROR_ATTR_INFO_SIZE,
- &this->attr_info))
+ if (reader->remaining(reader) < PA_ERROR_ATTR_INFO_SIZE)
{
reader->destroy(reader);
DBG1(DBG_TNC, "insufficient data for unsupported attribute "
*offset = PA_ERROR_HEADER_SIZE + PA_ERROR_MSG_INFO_SIZE;
return FAILED;
}
- this->attr_info = chunk_clone(this->attr_info);
+ reader->read_uint8 (reader, &this->flags);
+ reader->read_uint24(reader, &vendor_id);
+ reader->read_uint32(reader, &type);
+ this->unsupported_type = pen_type_create(vendor_id, type);
break;
default:
break;
{
free(this->value.ptr);
free(this->msg_info.ptr);
- free(this->attr_info.ptr);
free(this);
}
}
return this->msg_info;
}
-METHOD(ietf_attr_pa_tnc_error_t, get_attr_info, chunk_t,
- private_ietf_attr_pa_tnc_error_t *this)
+METHOD(ietf_attr_pa_tnc_error_t, get_unsupported_attr, pen_type_t,
+ private_ietf_attr_pa_tnc_error_t *this, uint8_t *flags)
{
- return this->attr_info;
+ if (flags)
+ {
+ *flags = this->flags;
+ }
+ return this->unsupported_type;
}
-METHOD(ietf_attr_pa_tnc_error_t, set_attr_info, void,
- private_ietf_attr_pa_tnc_error_t *this, chunk_t attr_info)
+METHOD(ietf_attr_pa_tnc_error_t, set_unsupported_attr, void,
+ private_ietf_attr_pa_tnc_error_t *this, uint8_t flags, pen_type_t type)
{
- this->attr_info = chunk_clone(attr_info);
+ this->flags = flags;
+ this->unsupported_type = type;
}
-METHOD(ietf_attr_pa_tnc_error_t, get_offset, u_int32_t,
+METHOD(ietf_attr_pa_tnc_error_t, get_offset, uint32_t,
private_ietf_attr_pa_tnc_error_t *this)
{
return this->error_offset;
},
.get_error_code = _get_error_code,
.get_msg_info = _get_msg_info,
- .get_attr_info = _get_attr_info,
- .set_attr_info = _set_attr_info,
+ .get_unsupported_attr = _get_unsupported_attr,
+ .set_unsupported_attr = _set_unsupported_attr,
.get_offset = _get_offset,
},
.type = { PEN_IETF, IETF_ATTR_PA_TNC_ERROR },
*/
pa_tnc_attr_t *ietf_attr_pa_tnc_error_create_with_offset(pen_type_t error_code,
chunk_t msg_info,
- u_int32_t error_offset)
+ uint32_t error_offset)
{
private_ietf_attr_pa_tnc_error_t *this;
chunk_t (*get_msg_info)(ietf_attr_pa_tnc_error_t *this);
/**
- * Get first 8 bytes of unsupported PA-TNC attribute
+ * Get flags, vendor ID and type of unsupported PA-TNC attribute
*
- * @return PA-TNC attribute info
+ * @param flags PA-TNC attribute flags
+ * @return PA-TNC attribute vendor ID and type
*/
- chunk_t (*get_attr_info)(ietf_attr_pa_tnc_error_t *this);
+ pen_type_t (*get_unsupported_attr)(ietf_attr_pa_tnc_error_t *this,
+ uint8_t *flags);
/**
- * Set first 8 bytes of unsupported PA-TNC attribute
+ * Set flags, vendor ID and type of unsupported PA-TNC attribute
*
- * @param attr_info PA-TNC message info
+ * @param flags PA-TNC attribute flags
+ * @param attr_info PA-TNC attribute vendor ID and type
*/
- void (*set_attr_info)(ietf_attr_pa_tnc_error_t *this, chunk_t attr_info);
+ void (*set_unsupported_attr)(ietf_attr_pa_tnc_error_t *this, uint8_t flags,
+ pen_type_t type);
/**
* Get the PA-TNC error offset
*
* @return PA-TNC error offset
*/
- u_int32_t (*get_offset)(ietf_attr_pa_tnc_error_t *this);
+ uint32_t (*get_offset)(ietf_attr_pa_tnc_error_t *this);
};
*/
pa_tnc_attr_t* ietf_attr_pa_tnc_error_create_with_offset(pen_type_t error_code,
chunk_t header,
- u_int32_t error_offset);
+ uint32_t error_offset);
/**
* Creates an ietf_attr_pa_tnc_error_t object from received data
pen_t vendor_id;
uint8_t flags;
uint32_t type, length;
- chunk_t value, attr_info;
+ chunk_t value;
pa_tnc_attr_t *attr;
enum_name_t *pa_attr_names;
ietf_attr_pa_tnc_error_t *error_attr;
+ pen_type_t unsupported_type;
- attr_info = reader->peek(reader);
- attr_info.len = PA_TNC_ATTR_INFO_SIZE;
reader->read_uint8 (reader, &flags);
reader->read_uint24(reader, &vendor_id);
reader->read_uint32(reader, &type);
vendor_id, type, value);
if (!attr)
{
- if (flags & PA_TNC_ATTR_FLAG_NOSKIP)
- {
- DBG1(DBG_TNC, "unsupported PA-TNC attribute with NOSKIP flag");
- error_code = pen_type_create(PEN_IETF,
- PA_ERROR_ATTR_TYPE_NOT_SUPPORTED);
- error = ietf_attr_pa_tnc_error_create(error_code,
- this->encoding);
- error_attr = (ietf_attr_pa_tnc_error_t*)error;
- error_attr->set_attr_info(error_attr, attr_info);
- goto err;
- }
- else
+ if (!(flags & PA_TNC_ATTR_FLAG_NOSKIP))
{
DBG1(DBG_TNC, "skipping unsupported PA-TNC attribute");
offset += length;
continue;
}
+
+ DBG1(DBG_TNC, "unsupported PA-TNC attribute with NOSKIP flag");
+ unsupported_type = pen_type_create(vendor_id, type);
+ error_code = pen_type_create(PEN_IETF,
+ PA_ERROR_ATTR_TYPE_NOT_SUPPORTED);
+ error = ietf_attr_pa_tnc_error_create(error_code, this->encoding);
+ error_attr = (ietf_attr_pa_tnc_error_t*)error;
+ error_attr->set_unsupported_attr(error_attr, flags, unsupported_type);
+ goto err;
}
if (attr->process(attr, &attr_offset) != SUCCESS)
private_pa_tnc_msg_t *this)
{
enumerator_t *enumerator;
+ enum_name_t *pa_attr_names;
pa_tnc_attr_t *attr;
- pen_type_t type;
+ pen_type_t type, unsupported_type;
+ uint8_t flags;
bool fatal_error = FALSE;
enumerator = this->attributes->create_enumerator(this->attributes);
{
ietf_attr_pa_tnc_error_t *error_attr;
pen_type_t error_code;
- chunk_t msg_info, attr_info;
+ chunk_t msg_info;
uint32_t offset;
error_attr = (ietf_attr_pa_tnc_error_t*)attr;
DBG1(DBG_TNC, " occurred at offset of %u bytes", offset);
break;
case PA_ERROR_ATTR_TYPE_NOT_SUPPORTED:
- attr_info = error_attr->get_attr_info(error_attr);
- DBG1(DBG_TNC, " unsupported attribute %#B", &attr_info);
+ unsupported_type =
+ error_attr->get_unsupported_attr(error_attr, &flags);
+ pa_attr_names =
+ imcv_pa_tnc_attributes->get_names(imcv_pa_tnc_attributes,
+ unsupported_type.vendor_id);
+ if (pa_attr_names)
+ {
+ DBG1(DBG_TNC, " unsupported attribute type '%N/%N' "
+ "0x%06x/0x%08x, flags 0x%02x",
+ pen_names, unsupported_type.vendor_id,
+ pa_attr_names, unsupported_type.type,
+ unsupported_type.vendor_id, unsupported_type.type,
+ flags);
+ }
+ else
+ {
+ DBG1(DBG_TNC, " unsupported attribute type '%N' "
+ "0x%06x/0x%08x, flags 0x%02x",
+ pen_names, unsupported_type.vendor_id,
+ unsupported_type.vendor_id, unsupported_type.type,
+ flags);
+ }
break;
default:
break;