Example #1
0
int oid_cmp(ptr_t* req_oid, ptr_t*  progmem_oid)
{
    #if CONTIKI_TARGET_AVR_RAVEN && ENABLE_PROGMEM
        u16t len = oid_length(progmem_oid);
        return memcmp_P(req_oid->ptr, (PGM_P)pgm_read_word(&progmem_oid->ptr), min(req_oid->len, len));
    #else
        return memcmp(req_oid->ptr, progmem_oid->ptr, min(req_oid->len, progmem_oid->len));
    #endif
}
/*
 * Find an object in the MIB corresponding to the oid in the snmp-get request.
 */
mib_object_t* mib_get(varbind_t* req)
{
    u16t oid_len;
    
    mib_iterator_init();
    while (!mib_iterator_is_end()) {
        oid_len = oid_length(ptr->varbind.oid_ptr);
        if (!GET_NEXT_OID_PTR) {
            // scalar
            if (oid_len == req->oid_ptr->len && !oid_cmp(req->oid_ptr, ptr->varbind.oid_ptr)) {
                break;
            }
            /* check noSuchInstance */
            if (oid_len - 1 <= req->oid_ptr->len + 1 && !oid_cmpn(req->oid_ptr, ptr->varbind.oid_ptr, oid_len - 1)) {
                req->value_type = BER_TYPE_NO_SUCH_INSTANCE;
                snmp_log("noSuchInstance\n");
                return 0;
            }
        }
        if (GET_NEXT_OID_PTR && oid_len < req->oid_ptr->len &&
                !oid_cmp(req->oid_ptr, ptr->varbind.oid_ptr)) {
            // tabular
            break;
        }
        mib_iterator_next();
    }

    if (mib_iterator_is_end()) {
        req->value_type = BER_TYPE_NO_SUCH_OBJECT;
        snmp_log("noSuchObject\n");
        return 0;
    }

    if (ptr->get_fnc_ptr) {
        if ((ptr->get_fnc_ptr)(ptr, &req->oid_ptr->ptr[oid_len], req->oid_ptr->len - oid_len) == -1) {
            req->value_type = BER_TYPE_NO_SUCH_INSTANCE;
            snmp_log("noSuchInstance - get value function\n");
            return 0;
        }
    }

    /* copy the value */
    memcpy(&req->value, &ptr->varbind.value, sizeof(varbind_value_t));
    req->value_type = ptr->varbind.value_type;
    return ptr;
}
Example #3
0
s8t oid_copy(ptr_t* dest, ptr_t* src, u8t malloc_len)
{
    #if CONTIKI_TARGET_AVR_RAVEN && ENABLE_PROGMEM
        dest->len = oid_length(src);
    #else
        dest->len = src->len;
    #endif

    if (!malloc_len) {
        dest->ptr = malloc(dest->len);
    } else {
        dest->ptr = malloc(malloc_len);
    }
    CHECK_PTR(dest->ptr);
    
    #if CONTIKI_TARGET_AVR_RAVEN && ENABLE_PROGMEM
        memcpy_P(dest->ptr, (PGM_P)pgm_read_word(&src->ptr), dest->len);
    #else
        memcpy(dest->ptr, src->ptr, dest->len);
    #endif
    return 0;
}
eap_status_e asn1_der_type_c::debug_object_identifier(eap_variable_data_c * const debug_buffer)
{
	if (debug_buffer == 0)
	{
		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
	}

	eap_status_e status(eap_status_process_general_error);

	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

	status = debug_buffer->set_data_length(debug_buffer->get_buffer_length());
	if (status != eap_status_ok)
	{
		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
		return EAP_STATUS_RETURN(m_am_tools, status);
	}

	const u32_t recursion(m_recursion + 1u);
	const u32_t max_prefix_length(recursion * SIZE_OF_ONE_OCTET_STRING + 1ul);

	if (debug_buffer->get_buffer_length() < (max_prefix_length + 2ul))
	{
		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
	}

	const u32_t max_data_output_length((debug_buffer->get_buffer_length() - (max_prefix_length + 2ul))/2ul);
	const u32_t max_plain_output_length(max_data_output_length);

	u32_t prefix_length(0ul);

	u8_t * const prefix = debug_buffer->get_data();
	if (prefix == 0)
	{
		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
	}

	status = debug_create_prefix(recursion, prefix, max_prefix_length, &prefix_length);
	if (status != eap_status_ok)
	{
		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
		return EAP_STATUS_RETURN(m_am_tools, status);
	}

	u8_t * const data_output = debug_buffer->get_data_offset(max_prefix_length, max_data_output_length);
	if (data_output == 0)
	{
		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
	}
	data_output[max_data_output_length-1ul] = 0;

	u8_t * const plain_output = debug_buffer->get_data_offset(max_prefix_length + max_data_output_length, max_plain_output_length);
	if (plain_output == 0)
	{
		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
	}
	plain_output[max_plain_output_length - 1ul] = 0;

	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

	const u32_t length = get_content_length();
	
	if (length == 0)
	{
		EAP_TRACE_DEBUG(
			m_am_tools,
			TRACE_FLAGS_DEFAULT,
			(EAPL("# ERROR: invalid %s, length=%d\n"),
				get_tag_string(),
				length));

		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
		return EAP_STATUS_RETURN(m_am_tools, eap_status_buffer_too_short);
	}

	const u8_t * const oid_data = get_content();

	if (oid_data == 0)
	{
		EAP_TRACE_DEBUG(
			m_am_tools,
			TRACE_FLAGS_DEFAULT,
			(EAPL("# ERROR: invalid %s, length=%d\n"),
				get_tag_string(),
				length));

		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
		return EAP_STATUS_RETURN(m_am_tools, eap_status_buffer_too_short);
	}

	u32_t offset(0ul);
	u8_t oid_octet = oid_data[offset];
	u32_t oid1 = oid_octet / 40;
	u32_t oid2 = (oid_octet - oid1*40);

	EAP_TRACE_DEBUG(
		m_am_tools,
		TRACE_FLAGS_DEFAULT,
		(EAPL("%s%02x # = %d = 40 * %d + %d => %d.%d\n"),
		prefix,
		oid_octet,
		oid_octet,
		oid1,
		oid2,
		oid1,
		oid2));

	++offset;

	while(offset < length)
	{
		u32_t oid_length(0ul);
		u32_t data_output_offset(0ul);
		u32_t plain_output_offset(0ul);
		u32_t ind(0ul);

		for (ind = offset; ind < length; ++ind)
		{
			u8_t oid_octet = oid_data[ind];
			++oid_length;
			if ((oid_octet & OID_HIGH_BIT) == 0)
			{
				break;
			}
		} // for()

		u32_t power = oid_length - 1ul;
		u32_t oid_value(0ul);

		for (ind = offset; ind < (offset+oid_length); ++ind)
		{
			u8_t oid_octet = oid_data[ind];

			data_output_offset += m_am_tools->snprintf(
				&data_output[data_output_offset],
				max_data_output_length - data_output_offset,
				"%02x \0",
				oid_octet);

			u8_t oid = static_cast<u8_t>(oid_octet & (~OID_HIGH_BIT));

			if (ind > offset)
			{
				plain_output_offset += m_am_tools->snprintf(
					&plain_output[plain_output_offset],
					max_data_output_length - plain_output_offset,
					" + \0");
			}

			if (power > 1ul)
			{
				plain_output_offset += m_am_tools->snprintf(
					&plain_output[plain_output_offset],
					max_data_output_length - plain_output_offset,
					"0x%02x * 128 ^ %d\0",
					oid,
					power);
			}
			else if (power > 0ul)
			{
				plain_output_offset += m_am_tools->snprintf(
					&plain_output[plain_output_offset],
					max_data_output_length - plain_output_offset,
					"0x%02x * 128\0",
					oid);
			}
			else
			{
				plain_output_offset += m_am_tools->snprintf(
					&plain_output[plain_output_offset],
					max_data_output_length - plain_output_offset,
					"0x%02x\0",
					oid);
			}

			oid_value = (oid_value << 7) + oid;

			--power;
		} // for()

		EAP_TRACE_DEBUG(
			m_am_tools,
			TRACE_FLAGS_DEFAULT,
			(EAPL("%s%s # %s = %d\n"),
			prefix,
			data_output,
			plain_output,
			oid_value));

		offset += oid_length;
	}

	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
	return EAP_STATUS_RETURN(m_am_tools, status);
}
/*
 * Find an object in the MIB that is the lexicographical successor of the given one.
 */
mib_object_t* mib_get_next(varbind_t* req)
{
    int cmp;
    u16t oid_len;
    
    mib_iterator_init();
    while (!mib_iterator_is_end()) {
        // find the object
        cmp = oid_cmp(req->oid_ptr, ptr->varbind.oid_ptr);
        oid_len = oid_length(ptr->varbind.oid_ptr);

        if (!GET_NEXT_OID_PTR) {
            // handle a scalar object
            if (cmp < 0 || (cmp == 0 && req->oid_ptr->len < oid_len)) {
                #if ENABLE_MIB_TABLE || ENABLE_PROGMEM
                    oid_copy(req->oid_ptr, ptr->varbind.oid_ptr, 0);
                    CHECK_PTR_U(req->oid_ptr->ptr);
                #else
                    req->oid_ptr.len = ptr->varbind.oid_ptr.len;
                    req->oid_ptr.ptr = ptr->varbind.oid_ptr.ptr;
                #endif
                break;
            }
        } else {
            #if ENABLE_MIB_TABLE
            /* handle a tabular object */
            if (cmp < 0 || cmp == 0) {
                ptr_t* table_oid_ptr;
                if ((table_oid_ptr = (ptr->get_next_oid_fnc_ptr)(ptr, (cmp < 0 ? 0 : &req->oid_ptr->ptr[oid_len]),
                        cmp < 0 ? 0 : req->oid_ptr->len - oid_len)) != 0) {
                    /* copy the mib object's oid */
                    oid_copy(req->oid_ptr, ptr->varbind.oid_ptr, oid_len + table_oid_ptr->len);
                    CHECK_PTR_U(req->oid_ptr->ptr);
                    memcpy(&req->oid_ptr->ptr[oid_len], table_oid_ptr->ptr, table_oid_ptr->len);
                    req->oid_ptr->len += table_oid_ptr->len;

                    free(table_oid_ptr->ptr);
                    oid_free(table_oid_ptr);
                    break;                    
                }
            }
            #endif
        }
        mib_iterator_next();
    }

    if (mib_iterator_is_end()) {
        req->value_type = BER_TYPE_END_OF_MIB;
        snmp_log("mib does not contain next object\n");
        return 0;
    }

    if (ptr->get_fnc_ptr) {
        if ((ptr->get_fnc_ptr)(ptr, &req->oid_ptr->ptr[oid_len],
                                    req->oid_ptr->len - oid_len) == -1) {
            snmp_log("can not get the value of the object\n");
            return 0;
        }
    }

    /* copy the value */
    memcpy(&req->value, &ptr->varbind.value, sizeof(varbind_value_t));
    req->value_type = ptr->varbind.value_type;
    return ptr;
}