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; }
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; }