Skip to content
Snippets Groups Projects
Unverified Commit 2f506f62 authored by Simon Duquennoy's avatar Simon Duquennoy Committed by GitHub
Browse files

Merge branch 'develop' into bugfix/link-stats

parents b3f3669f 20778a13
Branches
Tags
No related merge requests found
Showing
with 2432 additions and 0 deletions
CONTIKI_PROJECT = snmp-server
all: $(CONTIKI_PROJECT)
MODULES += os/net/app-layer/snmp
MODULES_REL += ./resources
CONTIKI = ../..
include $(CONTIKI)/Makefile.include
/*
* Copyright (C) 2019 Yago Fontoura do Rosario <yago.rosario@hotmail.com.br>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*---------------------------------------------------------------------------*/
#define LOG_CONF_LEVEL_SNMP LOG_LEVEL_DBG
/*
* Copyright (C) 2019 Yago Fontoura do Rosario <yago.rosario@hotmail.com.br>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "snmp-api.h"
/*---------------------------------------------------------------------------*/
static void
sysDescr_handler(snmp_varbind_t *varbind, uint32_t *oid);
MIB_RESOURCE(sysDescr, sysDescr_handler, 1, 3, 6, 1, 2, 1, 1, 1, 0);
static void
sysDescr_handler(snmp_varbind_t *varbind, uint32_t *oid)
{
snmp_api_set_string(varbind, oid, CONTIKI_VERSION_STRING);
}
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
static void
sysObjectID_handler(snmp_varbind_t *varbind, uint32_t *oid);
MIB_RESOURCE(sysObjectID, sysObjectID_handler, 1, 3, 6, 1, 2, 1, 1, 2, 0);
static void
sysObjectID_handler(snmp_varbind_t *varbind, uint32_t *oid)
{
OID(sysObjectID_oid, 1, 3, 6, 1, 4, 1, 54352);
snmp_api_set_oid(varbind, oid, sysObjectID_oid);
}
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
static void
sysUpTime_handler(snmp_varbind_t *varbind, uint32_t *oid);
MIB_RESOURCE(sysUpTime, sysUpTime_handler, 1, 3, 6, 1, 2, 1, 1, 3, 0);
static void
sysUpTime_handler(snmp_varbind_t *varbind, uint32_t *oid)
{
snmp_api_set_time_ticks(varbind, oid, clock_seconds() * 100);
}
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
static void
sysContact_handler(snmp_varbind_t *varbind, uint32_t *oid);
MIB_RESOURCE(sysContact, sysContact_handler, 1, 3, 6, 1, 2, 1, 1, 4, 0);
static void
sysContact_handler(snmp_varbind_t *varbind, uint32_t *oid)
{
snmp_api_set_string(varbind, oid, "Contiki-NG, https://github.com/contiki-ng/contiki-ng");
}
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
static void
sysName_handler(snmp_varbind_t *varbind, uint32_t *oid);
MIB_RESOURCE(sysName, sysName_handler, 1, 3, 6, 1, 2, 1, 1, 5, 0);
static void
sysName_handler(snmp_varbind_t *varbind, uint32_t *oid)
{
snmp_api_set_string(varbind, oid, "Contiki-NG - "CONTIKI_TARGET_STRING);
}
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
static void
sysLocation_handler(snmp_varbind_t *varbind, uint32_t *oid);
MIB_RESOURCE(sysLocation, sysLocation_handler, 1, 3, 6, 1, 2, 1, 1, 6, 0);
static void
sysLocation_handler(snmp_varbind_t *varbind, uint32_t *oid)
{
snmp_api_set_string(varbind, oid, "");
}
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
static void
sysServices_handler(snmp_varbind_t *varbind, uint32_t *oid);
MIB_RESOURCE(sysServices, sysServices_handler, 1, 3, 6, 1, 2, 1, 1, 7, 0);
static void
sysServices_handler(snmp_varbind_t *varbind, uint32_t *oid)
{
snmp_api_set_time_ticks(varbind, oid, clock_seconds() * 100);
}
/*---------------------------------------------------------------------------*/
/*
* Copyright (C) 2019 Yago Fontoura do Rosario <yago.rosario@hotmail.com.br>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*---------------------------------------------------------------------------*/
#include "contiki.h"
#include "snmp-api.h"
/*---------------------------------------------------------------------------*/
PROCESS_NAME(snmp_server_process);
AUTOSTART_PROCESSES(&snmp_server_process);
/*---------------------------------------------------------------------------*/
extern snmp_mib_resource_t
sysDescr,
sysObjectID,
sysUpTime,
sysContact,
sysName,
sysLocation,
sysServices;
/*---------------------------------------------------------------------------*/
PROCESS(snmp_server_process, "SNMP Server");
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(snmp_server_process, ev, data)
{
PROCESS_BEGIN();
snmp_api_add_resource(&sysDescr);
snmp_api_add_resource(&sysObjectID);
snmp_api_add_resource(&sysUpTime);
snmp_api_add_resource(&sysContact);
snmp_api_add_resource(&sysName);
snmp_api_add_resource(&sysLocation);
snmp_api_add_resource(&sysServices);
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
......@@ -50,6 +50,7 @@
#include "net/queuebuf.h"
#include "net/app-layer/coap/coap-engine.h"
#include "net/app-layer/snmp/snmp.h"
#include "services/rpl-border-router/rpl-border-router.h"
#include "services/orchestra/orchestra.h"
#include "services/shell/serial-shell.h"
......@@ -147,6 +148,11 @@ main(void)
LOG_DBG("With CoAP\n");
#endif /* BUILD_WITH_SHELL */
#if BUILD_WITH_SNMP
snmp_init();
LOG_DBG("With SNMP\n");
#endif /* BUILD_WITH_SNMP */
#if BUILD_WITH_SIMPLE_ENERGEST
simple_energest_init();
#endif /* BUILD_WITH_SIMPLE_ENERGEST */
......
......
#define BUILD_WITH_SNMP 1
/*
* Copyright (C) 2019 Yago Fontoura do Rosario <yago.rosario@hotmail.com.br>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*---------------------------------------------------------------------------*/
/**
* \file
* An implementation of the Simple Network Management Protocol (RFC 3411-3418)
* \author
* Yago Fontoura do Rosario <yago.rosario@hotmail.com.br
*/
#include "contiki.h"
#include "snmp-api.h"
#include "snmp-message.h"
#include "snmp-ber.h"
#include "snmp-oid.h"
static void
snmp_api_replace_oid(snmp_varbind_t *varbind, uint32_t *oid)
{
uint8_t i;
i = 0;
while(oid[i] != ((uint32_t)-1)) {
varbind->oid[i] = oid[i];
i++;
}
varbind->oid[i] = ((uint32_t)-1);
}
/*---------------------------------------------------------------------------*/
void
snmp_api_set_string(snmp_varbind_t *varbind, uint32_t *oid, char *string)
{
snmp_api_replace_oid(varbind, oid);
varbind->value_type = BER_DATA_TYPE_OCTET_STRING;
varbind->value.string.string = string;
varbind->value.string.length = strlen(string);
}
/*---------------------------------------------------------------------------*/
void
snmp_api_set_time_ticks(snmp_varbind_t *varbind, uint32_t *oid, uint32_t integer)
{
snmp_api_replace_oid(varbind, oid);
varbind->value_type = SNMP_DATA_TYPE_TIME_TICKS;
varbind->value.integer = integer;
}
/*---------------------------------------------------------------------------*/
void
snmp_api_set_oid(snmp_varbind_t *varbind, uint32_t *oid, uint32_t *ret_oid)
{
snmp_api_replace_oid(varbind, oid);
varbind->value_type = BER_DATA_TYPE_OID;
varbind->value.oid = ret_oid;
}
/*---------------------------------------------------------------------------*/
void
snmp_api_add_resource(snmp_mib_resource_t *new_resource)
{
return snmp_mib_add(new_resource);
}
/*
* Copyright (C) 2019 Yago Fontoura do Rosario <yago.rosario@hotmail.com.br>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*---------------------------------------------------------------------------*/
/**
* \file
* The public API for the Contiki-NG SNMP implementation
* \author
* Yago Fontoura do Rosario <yago.rosario@hotmail.com.br
*/
/**
* \addtogroup snmp
* @{
*/
#ifndef SNMP_API_H_
#define SNMP_API_H_
#include "snmp.h"
#include "snmp-mib.h"
/**
* \defgroup SNMPAPI This is the SNMP Public API
* @{
*
* This group contains all the functions that can be used outside the OS level.
* The function outside this header can be changed without notice
*/
/**
* @brief The MIB resource handler typedef
*
* @param varbind The varbind that is being changed
* @param oid The oid from the resource
*/
typedef void (*snmp_mib_resource_handler_t)(snmp_varbind_t *varbind, uint32_t *oid);
/**
* @brief The MIB Resource struct
*/
typedef struct snmp_mib_resource_s snmp_mib_resource_t;
/**
* @brief Initializes statically an oid with the "null" terminator
*
* @remarks This should be used inside handlers when declaring an oid
*
* @param name A name for the oid
* @param ... The Oid (comma-separeted)
*/
#define OID(name, ...) \
static uint32_t name[] = { __VA_ARGS__, -1 };
/**
* @brief Declare a MIB resource
*
* @param name A name for the MIB resource
* @param handler The handler function for this resource
* @param ... The OID (comma-separated)
*/
#define MIB_RESOURCE(name, handler, ...) \
uint32_t name##_oid[] = { __VA_ARGS__, -1 }; \
snmp_mib_resource_t name = { NULL, name##_oid, handler };
/**
* @brief Function to set a varbind with a string
*
* This function should be used inside a handler to set the varbind correctly
*
* @param varbind The varbind from the handler
* @param oid The oid from the handler
* @param string The string
*/
void
snmp_api_set_string(snmp_varbind_t *varbind, uint32_t *oid, char *string);
/**
* @brief Function to set a varbind with a time tick
*
* This function should be used inside a handler to set the varbind correctly
*
* @param varbind The varbind from the handler
* @param oid The oid from the handler
* @param integer The time tick value
*/
void
snmp_api_set_time_ticks(snmp_varbind_t *varbind, uint32_t *oid, uint32_t integer);
/**
* @brief Function to set a varbind with a oid
*
* This function should be used inside a handler to set the varbind correctly
*
* @param varbind The varbind from the handler
* @param oid The oid from the handler
* @param ret_oid The oid value
*/
void
snmp_api_set_oid(snmp_varbind_t *varbind, uint32_t *oid, uint32_t *ret_oid);
/**
* @brief Function to add a new resource
*
* @param new_resource The resource
*/
void
snmp_api_add_resource(snmp_mib_resource_t *new_resource);
/** @}*/
#endif /* SNMP_API_H_ */
/** @} */
/*
* Copyright (C) 2019 Yago Fontoura do Rosario <yago.rosario@hotmail.com.br>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*---------------------------------------------------------------------------*/
/**
* \file
* An implementation of the Simple Network Management Protocol (RFC 3411-3418)
* \author
* Yago Fontoura do Rosario <yago.rosario@hotmail.com.br
*/
#include "contiki.h"
#include "snmp.h"
#include "snmp-ber.h"
#define LOG_MODULE "SNMP [ber]"
#define LOG_LEVEL LOG_LEVEL_SNMP
/*---------------------------------------------------------------------------*/
unsigned char *
snmp_ber_encode_type(unsigned char *out, uint32_t *out_len, uint8_t type)
{
*out-- = type;
(*out_len)++;
return out;
}
/*---------------------------------------------------------------------------*/
unsigned char *
snmp_ber_encode_length(unsigned char *out, uint32_t *out_len, uint8_t length)
{
*out-- = length;
(*out_len)++;
return out;
}
/*---------------------------------------------------------------------------*/
unsigned char *
snmp_ber_encode_integer(unsigned char *out, uint32_t *out_len, uint32_t number)
{
uint32_t original_out_len;
original_out_len = *out_len;
do {
(*out_len)++;
*out-- = (uint8_t)(number & 0xFF);
number >>= 8;
} while(number);
out = snmp_ber_encode_length(out, out_len, ((*out_len - original_out_len) & 0xFF));
out = snmp_ber_encode_type(out, out_len, BER_DATA_TYPE_INTEGER);
return out;
}
/*---------------------------------------------------------------------------*/
unsigned char *
snmp_ber_encode_unsigned_integer(unsigned char *out, uint32_t *out_len, uint8_t type, uint32_t number)
{
uint32_t original_out_len;
original_out_len = *out_len;
do {
(*out_len)++;
*out-- = (uint8_t)(number & 0xFF);
number >>= 8;
} while(number);
out = snmp_ber_encode_length(out, out_len, ((*out_len - original_out_len) & 0xFF));
out = snmp_ber_encode_type(out, out_len, type);
return out;
}
/*---------------------------------------------------------------------------*/
unsigned char *
snmp_ber_encode_string_len(unsigned char *out, uint32_t *out_len, const char *str, uint32_t length)
{
uint32_t i;
str += length - 1;
for(i = 0; i < length; ++i) {
(*out_len)++;
*out-- = (uint8_t)*str--;
}
out = snmp_ber_encode_length(out, out_len, length);
out = snmp_ber_encode_type(out, out_len, BER_DATA_TYPE_OCTET_STRING);
return out;
}
/*---------------------------------------------------------------------------*/
unsigned char *
snmp_ber_encode_null(unsigned char *out, uint32_t *out_len, uint8_t type)
{
(*out_len)++;
*out-- = 0x00;
out = snmp_ber_encode_type(out, out_len, type);
return out;
}
/*---------------------------------------------------------------------------*/
unsigned char *
snmp_ber_decode_type(unsigned char *buff, uint32_t *buff_len, uint8_t *type)
{
*type = *buff++;
(*buff_len)--;
return buff;
}
/*---------------------------------------------------------------------------*/
unsigned char *
snmp_ber_decode_length(unsigned char *buff, uint32_t *buff_len, uint8_t *length)
{
*length = *buff++;
(*buff_len)--;
return buff;
}
/*---------------------------------------------------------------------------*/
unsigned char *
snmp_ber_decode_integer(unsigned char *buf, uint32_t *buff_len, uint32_t *num)
{
uint8_t i, len, type;
buf = snmp_ber_decode_type(buf, buff_len, &type);
if(type != BER_DATA_TYPE_INTEGER) {
/*
* Sanity check
* Invalid type in buffer
*/
return NULL;
}
buf = snmp_ber_decode_length(buf, buff_len, &len);
if(len > 4) {
/*
* Sanity check
* It will not fit in the uint32_t
*/
return NULL;
}
*num = (uint32_t)(*buf++ & 0xFF);
(*buff_len)--;
for(i = 1; i < len; ++i) {
*num <<= 8;
*num |= (uint8_t)(*buf++ & 0xFF);
(*buff_len)--;
}
return buf;
}
/*---------------------------------------------------------------------------*/
unsigned char *
snmp_ber_decode_unsigned_integer(unsigned char *buf, uint32_t *buff_len, uint8_t expected_type, uint32_t *num)
{
uint8_t i, len, type;
buf = snmp_ber_decode_type(buf, buff_len, &type);
if(type != expected_type) {
/*
* Sanity check
* Invalid type in buffer
*/
return NULL;
}
buf = snmp_ber_decode_length(buf, buff_len, &len);
if(len > 4) {
/*
* Sanity check
* It will not fit in the uint32_t
*/
return NULL;
}
*num = (uint32_t)(*buf++ & 0xFF);
(*buff_len)--;
for(i = 1; i < len; ++i) {
*num <<= 8;
*num |= (uint8_t)(*buf++ & 0xFF);
(*buff_len)--;
}
return buf;
}
/*---------------------------------------------------------------------------*/
unsigned char *
snmp_ber_decode_string_len_buffer(unsigned char *buf, uint32_t *buff_len, const char **str, uint32_t *length)
{
uint8_t type, i, length_bytes;
buf = snmp_ber_decode_type(buf, buff_len, &type);
if(type != BER_DATA_TYPE_OCTET_STRING) {
/*
* Sanity check
* Invalid type in buffer
*/
return NULL;
}
if((*buf & 0x80) == 0) {
*length = (uint32_t)*buf++;
(*buff_len)--;
} else {
length_bytes = (uint8_t)(*buf++ & 0x7F);
(*buff_len)--;
if(length_bytes > 4) {
/*
* Sanity check
* It will not fit in the uint32_t
*/
return NULL;
}
*length = (uint32_t)*buf++;
(*buff_len)--;
for(i = 1; i < length_bytes; ++i) {
*length <<= 8;
*length |= *buf++;
(*buff_len)--;
}
}
*str = (const char *)buf;
*buff_len -= *length;
return buf + *length;
}
/*---------------------------------------------------------------------------*/
unsigned char *
snmp_ber_decode_null(unsigned char *buf, uint32_t *buff_len)
{
buf++;
(*buff_len)--;
buf++;
(*buff_len)--;
return buf;
}
/*---------------------------------------------------------------------------*/
/*
* Copyright (C) 2019 Yago Fontoura do Rosario <yago.rosario@hotmail.com.br>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*---------------------------------------------------------------------------*/
/**
* \file
* An implementation of the Simple Network Management Protocol (RFC 3411-3418)
* \author
* Yago Fontoura do Rosario <yago.rosario@hotmail.com.br
*/
/**
* \addtogroup snmp
* @{
*/
#ifndef SNMP_BER_H_
#define SNMP_BER_H_
#define BER_DATA_TYPE_INTEGER 0x02
#define BER_DATA_TYPE_OCTET_STRING 0x04
#define BER_DATA_TYPE_NULL 0x05
#define BER_DATA_TYPE_OID 0x06
#define BER_DATA_TYPE_SEQUENCE 0x30
/**
* @brief Encodes a type
*
* @param out A pointer to the end of the buffer
* @param out_len A pointer to the buffer length
* @param type A type
*
* @return NULL if error or the next entry in the buffer
*/
unsigned char *
snmp_ber_encode_type(unsigned char *out, uint32_t *out_len, uint8_t type);
/**
* @brief Encodes the length
*
* @param out A pointer to the end of the buffer
* @param out_len A pointer to the buffer length
* @param length A length
*
* @return NULL if error or the next entry in the buffer
*/
unsigned char *
snmp_ber_encode_length(unsigned char *out, uint32_t *out_len, uint8_t length);
/**
* @brief Encodes an integer
*
* @param out A pointer to the end of the buffer
* @param out_len A pointer to the buffer length
* @param integer A integer
*
* @return NULL if error or the next entry in the buffer
*/
unsigned char *
snmp_ber_encode_integer(unsigned char *out, uint32_t *out_len, uint32_t integer);
/**
* @brief Encodes an unsigned integer
*
* @param out A pointer to the end of the buffer
* @param out_len A pointer to the buffer length
* @param type A type that represents an unsigned integer
* @param number A number
*
* @return NULL if error or the next entry in the buffer
*/
unsigned char *
snmp_ber_encode_unsigned_integer(unsigned char *out, uint32_t *out_len, uint8_t type, uint32_t number);
/**
* @brief Encodes a string
*
* @param out A pointer to the end of the buffer
* @param out_len A pointer to the buffer length
* @param str A string
* @param length The string length
*
* @return NULL if error or the next entry in the buffer
*/
unsigned char *
snmp_ber_encode_string_len(unsigned char *out, uint32_t *out_len, const char *str, uint32_t length);
/**
* @brief Encodes a null
*
* @param out A pointer to the end of the buffer
* @param out_len A pointer to the buffer length
* @param type A type
*
* @return NULL if error or the next entry in the buffer
*/
unsigned char *
snmp_ber_encode_null(unsigned char *out, uint32_t *out_len, uint8_t type);
/**
* @brief Decodes a type
*
* @param buff A pointer to the beginning of the buffer
* @param buff_len A pointer to the buffer length
* @param type A pointer to the type
*
* @return NULL if error or the first entry after the oid in the buffer
*/
unsigned char *
snmp_ber_decode_type(unsigned char *buff, uint32_t *buff_len, uint8_t *type);
/**
* @brief Decodes a length
*
* @param buff A pointer to the beginning of the buffer
* @param buff_len A pointer to the buffer length
* @param length A pointer to the length
*
* @return NULL if error or the first entry after the oid in the buffer
*/
unsigned char *
snmp_ber_decode_length(unsigned char *buff, uint32_t *buff_len, uint8_t *length);
/**
* @brief Decodes an integer
*
* @param buff A pointer to the beginning of the buffer
* @param buff_len A pointer to the buffer length
* @param integer A pointer to the integer
*
* @return NULL if error or the first entry after the oid in the buffer
*/
unsigned char *
snmp_ber_decode_integer(unsigned char *buff, uint32_t *buff_len, uint32_t *integer);
/**
* @brief Decodes an unsigned number
*
* @param buff A pointer to the beginning of the buffer
* @param buff_len A pointer to the buffer length
* @param expected_type The expected type that represents an unsingned integer
* @param number A pointer to the number
*
* @return NULL if error or the first entry after the oid in the buffer
*/
unsigned char *
snmp_ber_decode_unsigned_integer(unsigned char *buff, uint32_t *buff_len, uint8_t expected_type, uint32_t *number);
/**
* @brief Decodes a string
*
* @param buff A pointer to the beginning of the buffer
* @param buff_len A pointer to the buffer length
* @param str A pointer to the string
* @param length A pointer to the string length
*
* @return NULL if error or the first entry after the oid in the buffer
*/
unsigned char *
snmp_ber_decode_string_len_buffer(unsigned char *buff, uint32_t *buff_len, const char **str, uint32_t *length);
/**
* @brief Decodes a null
*
* @param buff A pointer to the beginning of the buffer
* @param buff_len A pointer to the buffer length
*
* @return NULL if error or the first entry after the oid in the buffer
*/
unsigned char *
snmp_ber_decode_null(unsigned char *buff, uint32_t *buff_len);
#endif /* SNMP_BER_H_ */
/** @} */
/*
* Copyright (C) 2019 Yago Fontoura do Rosario <yago.rosario@hotmail.com.br>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*---------------------------------------------------------------------------*/
/**
* \file
* SNMP Configurable Macros
* \author
* Yago Fontoura do Rosario <yago.rosario@hotmail.com.br
*/
/**
* \addtogroup snmp
* @{
*/
#ifndef SNMP_CONF_H_
#define SNMP_CONF_H_
/**
* \defgroup SNMPConfs SNMP Configurable Defines
* @{
*/
#ifdef SNMP_CONF_COMMUNITY
/**
* \brief Configurable SNMP Community
*/
#define SNMP_COMMUNITY SNMP_CONF_COMMUNITY
#else
/**
* \brief Default SNMP Community
*/
#define SNMP_COMMUNITY "public"
#endif
#ifdef SNMP_CONF_MSG_OID_MAX_LEN
/**
* \brief Configurable maximum number of IDs in one OID
*/
#define SNMP_MSG_OID_MAX_LEN SNMP_CONF_MSG_OID_MAX_LEN
#else
/**
* \brief Default maximum number of IDs in one OID
*/
#define SNMP_MSG_OID_MAX_LEN 16
#endif
#ifdef SNMP_CONF_MAX_NR_VALUES
/**
* \brief Configurable maximum number of OIDs in one response
*/
#define SNMP_MAX_NR_VALUES SNMP_CONF_MAX_NR_VALUES
#else
/**
* \brief Default maximum number of OIDs in one response
*/
#define SNMP_MAX_NR_VALUES 2
#endif
#ifdef SNMP_CONF_MAX_PACKET_SIZE
/**
* \brief Configurable maximum size of the packet in bytes
*/
#define SNMP_MAX_PACKET_SIZE SNMP_CONF_MAX_PACKET_SIZE
#else
/**
* \brief Default maximum size of the packet in bytes
*/
#define SNMP_MAX_PACKET_SIZE 512
#endif
#ifdef SNMP_CONF_PORT
/**
* \brief Configurable SNMP port
*/
#define SNMP_PORT SNMP_CONF_PORT
#else
/**
* \brief Default SNMP port
*/
#define SNMP_PORT 161
#endif
/*@}*/
#endif /* SNMP_CONF_H_ */
/** @} */
/*
* Copyright (C) 2019 Yago Fontoura do Rosario <yago.rosario@hotmail.com.br>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*---------------------------------------------------------------------------*/
/**
* \file
* An implementation of the Simple Network Management Protocol (RFC 3411-3418)
* \author
* Yago Fontoura do Rosario <yago.rosario@hotmail.com.br
*/
#include "contiki.h"
#include "snmp-engine.h"
#include "snmp-message.h"
#include "snmp-mib.h"
#include "snmp-oid.h"
#define LOG_MODULE "SNMP [engine]"
#define LOG_LEVEL LOG_LEVEL_SNMP
/*---------------------------------------------------------------------------*/
int
snmp_engine_get(snmp_header_t *header, snmp_varbind_t *varbinds, uint32_t varbinds_length)
{
snmp_mib_resource_t *resource;
uint32_t i;
for(i = 0; i < varbinds_length; i++) {
resource = snmp_mib_find(varbinds[i].oid);
if(!resource) {
switch(header->version) {
case SNMP_VERSION_1:
header->error_status_non_repeaters.error_status = SNMP_STATUS_NO_SUCH_NAME;
/*
* Varbinds are 1 indexed
*/
header->error_index_max_repetitions.error_index = i + 1;
break;
case SNMP_VERSION_2C:
(&varbinds[i])->value_type = SNMP_DATA_TYPE_NO_SUCH_INSTANCE;
break;
default:
header->error_status_non_repeaters.error_status = SNMP_STATUS_NO_SUCH_NAME;
header->error_index_max_repetitions.error_index = 0;
}
} else {
resource->handler(&varbinds[i], resource->oid);
}
}
return 0;
}
/*---------------------------------------------------------------------------*/
int
snmp_engine_get_next(snmp_header_t *header, snmp_varbind_t *varbinds, uint32_t varbinds_length)
{
snmp_mib_resource_t *resource;
uint32_t i;
for(i = 0; i < varbinds_length; i++) {
resource = snmp_mib_find_next(varbinds[i].oid);
if(!resource) {
switch(header->version) {
case SNMP_VERSION_1:
header->error_status_non_repeaters.error_status = SNMP_STATUS_NO_SUCH_NAME;
/*
* Varbinds are 1 indexed
*/
header->error_index_max_repetitions.error_index = i + 1;
break;
case SNMP_VERSION_2C:
(&varbinds[i])->value_type = SNMP_DATA_TYPE_END_OF_MIB_VIEW;
break;
default:
header->error_status_non_repeaters.error_status = SNMP_STATUS_NO_SUCH_NAME;
header->error_index_max_repetitions.error_index = 0;
}
} else {
resource->handler(&varbinds[i], resource->oid);
}
}
return 0;
}
/*---------------------------------------------------------------------------*/
int
snmp_engine_get_bulk(snmp_header_t *header, snmp_varbind_t *varbinds, uint32_t *varbinds_length)
{
snmp_mib_resource_t *resource;
uint32_t i, j, original_varbinds_length;
uint32_t oid[SNMP_MAX_NR_VALUES][SNMP_MSG_OID_MAX_LEN];
uint8_t repeater;
/*
* A local copy of the requested oids must be kept since
* the varbinds are modified on the fly
*/
original_varbinds_length = *varbinds_length;
for(i = 0; i < original_varbinds_length; i++) {
snmp_oid_copy(oid[i], varbinds[i].oid);
}
*varbinds_length = 0;
for(i = 0; i < original_varbinds_length; i++) {
if(i >= header->error_status_non_repeaters.non_repeaters) {
break;
}
resource = snmp_mib_find_next(oid[i]);
if(!resource) {
switch(header->version) {
case SNMP_VERSION_1:
header->error_status_non_repeaters.error_status = SNMP_STATUS_NO_SUCH_NAME;
/*
* Varbinds are 1 indexed
*/
header->error_index_max_repetitions.error_index = i + 1;
break;
case SNMP_VERSION_2C:
(&varbinds[i])->value_type = SNMP_DATA_TYPE_END_OF_MIB_VIEW;
break;
default:
header->error_status_non_repeaters.error_status = SNMP_STATUS_NO_SUCH_NAME;
header->error_index_max_repetitions.error_index = 0;
}
} else {
if(*varbinds_length < SNMP_MAX_NR_VALUES) {
resource->handler(&varbinds[*varbinds_length], resource->oid);
(*varbinds_length)++;
}
}
}
for(i = 0; i < header->error_index_max_repetitions.max_repetitions; i++) {
repeater = 0;
for(j = header->error_status_non_repeaters.non_repeaters; j < original_varbinds_length; j++) {
resource = snmp_mib_find_next(oid[j]);
if(!resource) {
switch(header->version) {
case SNMP_VERSION_1:
header->error_status_non_repeaters.error_status = SNMP_STATUS_NO_SUCH_NAME;
/*
* Varbinds are 1 indexed
*/
header->error_index_max_repetitions.error_index = *varbinds_length + 1;
break;
case SNMP_VERSION_2C:
if(*varbinds_length < SNMP_MAX_NR_VALUES) {
(&varbinds[*varbinds_length])->value_type = SNMP_DATA_TYPE_END_OF_MIB_VIEW;
snmp_oid_copy((&varbinds[*varbinds_length])->oid, oid[j]);
(*varbinds_length)++;
}
break;
default:
header->error_status_non_repeaters.error_status = SNMP_STATUS_NO_SUCH_NAME;
header->error_index_max_repetitions.error_index = 0;
}
} else {
if(*varbinds_length < SNMP_MAX_NR_VALUES) {
resource->handler(&varbinds[*varbinds_length], resource->oid);
(*varbinds_length)++;
snmp_oid_copy(oid[j], resource->oid);
repeater++;
}
}
}
if(repeater == 0) {
break;
}
}
return 0;
}
/*---------------------------------------------------------------------------*/
unsigned char *
snmp_engine(unsigned char *buff, uint32_t buff_len, unsigned char *out, uint32_t *out_len)
{
static snmp_header_t header;
static snmp_varbind_t varbinds[SNMP_MAX_NR_VALUES];
static uint32_t varbind_length;
buff = snmp_message_decode(buff, buff_len, &header, varbinds, &varbind_length);
if(buff == NULL) {
return NULL;
}
if(header.version != SNMP_VERSION_1) {
if(strncmp(header.community.community, SNMP_COMMUNITY, header.community.length)) {
LOG_ERR("Request with invalid community\n");
return NULL;
}
}
/*
* Now handle the SNMP requests depending on their type
*/
switch(header.pdu_type) {
case SNMP_DATA_TYPE_PDU_GET_REQUEST:
if(snmp_engine_get(&header, varbinds, varbind_length) == -1) {
return NULL;
}
break;
case SNMP_DATA_TYPE_PDU_GET_NEXT_REQUEST:
if(snmp_engine_get_next(&header, varbinds, varbind_length) == -1) {
return NULL;
}
break;
case SNMP_DATA_TYPE_PDU_GET_BULK:
if(snmp_engine_get_bulk(&header, varbinds, &varbind_length) == -1) {
return NULL;
}
break;
default:
LOG_ERR("Invalid request type");
return NULL;
}
header.pdu_type = SNMP_DATA_TYPE_PDU_GET_RESPONSE;
out = snmp_message_encode(out, out_len, &header, varbinds, varbind_length);
return ++out;
}
/*
* Copyright (C) 2019 Yago Fontoura do Rosario <yago.rosario@hotmail.com.br>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*---------------------------------------------------------------------------*/
/**
* \file
* An implementation of the Simple Network Management Protocol (RFC 3411-3418)
* \author
* Yago Fontoura do Rosario <yago.rosario@hotmail.com.br
*/
/**
* \addtogroup snmp
* @{
*/
#ifndef SNMP_ENGINE_H_
#define SNMP_ENGINE_H_
#include "snmp.h"
/**
* @brief Process the SNMP packet and prepares the response
*
* @param buff A pointer to the beginning of the packet buffer
* @param buff_len The packet length
* @param out A pointer to the end of the response buffer
* @param out_len A pointer to the length of the response buffer
*
* @return NULL in case of fail or the first element in the response buffer
*/
unsigned char *
snmp_engine(unsigned char *buff, uint32_t buff_len, unsigned char *out, uint32_t *out_len);
#endif /* SNMP_ENGINE_H_ */
/** @} */
/*
* Copyright (C) 2019 Yago Fontoura do Rosario <yago.rosario@hotmail.com.br>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*---------------------------------------------------------------------------*/
/**
* \file
* An implementation of the Simple Network Management Protocol (RFC 3411-3418)
* \author
* Yago Fontoura do Rosario <yago.rosario@hotmail.com.br
*/
#include "contiki.h"
#include "snmp-message.h"
#include "snmp-ber.h"
#include "snmp-oid.h"
#define LOG_MODULE "SNMP [message]"
#define LOG_LEVEL LOG_LEVEL_SNMP
unsigned char *
snmp_message_encode(unsigned char *out, uint32_t *out_len, snmp_header_t *header,
snmp_varbind_t *varbinds, uint32_t varbind_num)
{
snmp_varbind_t *varbind;
uint32_t original_out_len, last_out_len;
int8_t i;
original_out_len = *out_len;
for(i = varbind_num - 1; i >= 0; i--) {
varbind = &varbinds[i];
last_out_len = *out_len;
switch(varbind->value_type) {
case BER_DATA_TYPE_INTEGER:
out = snmp_ber_encode_integer(out, out_len, varbind->value.integer);
break;
case SNMP_DATA_TYPE_TIME_TICKS:
out = snmp_ber_encode_unsigned_integer(out, out_len, varbind->value_type, varbind->value.integer);
break;
case BER_DATA_TYPE_OCTET_STRING:
out = snmp_ber_encode_string_len(out, out_len, varbind->value.string.string, varbind->value.string.length);
break;
case BER_DATA_TYPE_OID:
out = snmp_oid_encode_oid(out, out_len, varbind->value.oid);
break;
case BER_DATA_TYPE_NULL:
case SNMP_DATA_TYPE_NO_SUCH_INSTANCE:
case SNMP_DATA_TYPE_END_OF_MIB_VIEW:
out = snmp_ber_encode_null(out, out_len, varbind->value_type);
break;
default:
return NULL;
}
out = snmp_oid_encode_oid(out, out_len, varbind->oid);
out = snmp_ber_encode_length(out, out_len, ((*out_len - last_out_len) & 0xFF));
out = snmp_ber_encode_type(out, out_len, BER_DATA_TYPE_SEQUENCE);
}
out = snmp_ber_encode_length(out, out_len, ((*out_len - original_out_len) & 0xFF));
out = snmp_ber_encode_type(out, out_len, BER_DATA_TYPE_SEQUENCE);
if(header->pdu_type == SNMP_DATA_TYPE_PDU_GET_BULK) {
out = snmp_ber_encode_integer(out, out_len, header->error_index_max_repetitions.max_repetitions);
out = snmp_ber_encode_integer(out, out_len, header->error_status_non_repeaters.non_repeaters);
} else {
out = snmp_ber_encode_integer(out, out_len, header->error_index_max_repetitions.error_index);
out = snmp_ber_encode_integer(out, out_len, header->error_status_non_repeaters.error_status);
}
out = snmp_ber_encode_integer(out, out_len, header->request_id);
out = snmp_ber_encode_length(out, out_len, ((*out_len - original_out_len) & 0xFF));
out = snmp_ber_encode_type(out, out_len, header->pdu_type);
out = snmp_ber_encode_string_len(out, out_len, header->community.community, header->community.length);
out = snmp_ber_encode_integer(out, out_len, header->version);
out = snmp_ber_encode_length(out, out_len, ((*out_len - original_out_len) & 0xFF));
out = snmp_ber_encode_type(out, out_len, BER_DATA_TYPE_SEQUENCE);
return out;
}
uint8_t *
snmp_message_decode(uint8_t *buf, uint32_t buf_len, snmp_header_t *header,
snmp_varbind_t *varbinds, uint32_t *varbind_num)
{
uint8_t type, len;
uint32_t i, oid_len;
buf = snmp_ber_decode_type(buf, &buf_len, &type);
if(buf == NULL) {
LOG_DBG("Could not decode type\n");
return NULL;
}
if(type != BER_DATA_TYPE_SEQUENCE) {
LOG_DBG("Invalid type\n");
return NULL;
}
buf = snmp_ber_decode_length(buf, &buf_len, &len);
if(buf == NULL) {
LOG_DBG("Could not decode length\n");
return NULL;
}
buf = snmp_ber_decode_integer(buf, &buf_len, &header->version);
if(buf == NULL) {
LOG_DBG("Could not decode version\n");
return NULL;
}
buf = snmp_ber_decode_string_len_buffer(buf, &buf_len, &header->community.community, &header->community.length);
if(buf == NULL) {
LOG_DBG("Could not decode community\n");
return NULL;
}
if(header->version != SNMP_VERSION_1 &&
header->version != SNMP_VERSION_2C) {
LOG_DBG("Invalid version\n");
return NULL;
}
buf = snmp_ber_decode_type(buf, &buf_len, &type);
if(buf == NULL) {
LOG_DBG("Could not decode type\n");
return NULL;
}
header->pdu_type = type;
if(header->pdu_type != SNMP_DATA_TYPE_PDU_GET_REQUEST &&
header->pdu_type != SNMP_DATA_TYPE_PDU_GET_NEXT_REQUEST &&
header->pdu_type != SNMP_DATA_TYPE_PDU_GET_RESPONSE &&
header->pdu_type != SNMP_DATA_TYPE_PDU_SET_REQUEST &&
header->pdu_type != SNMP_DATA_TYPE_PDU_GET_BULK) {
LOG_DBG("Invalid pdu type\n");
return NULL;
}
buf = snmp_ber_decode_length(buf, &buf_len, &len);
if(buf == NULL) {
LOG_DBG("Could not decode length\n");
return NULL;
}
buf = snmp_ber_decode_integer(buf, &buf_len, &header->request_id);
if(buf == NULL) {
LOG_DBG("Could not decode request id\n");
return NULL;
}
if(header->pdu_type == SNMP_DATA_TYPE_PDU_GET_BULK) {
buf = snmp_ber_decode_integer(buf, &buf_len, &header->error_status_non_repeaters.non_repeaters);
if(buf == NULL) {
LOG_DBG("Could not decode error status\n");
return NULL;
}
buf = snmp_ber_decode_integer(buf, &buf_len, &header->error_index_max_repetitions.max_repetitions);
if(buf == NULL) {
LOG_DBG("Could not decode error index\n");
return NULL;
}
} else {
buf = snmp_ber_decode_integer(buf, &buf_len, &header->error_status_non_repeaters.error_status);
if(buf == NULL) {
LOG_DBG("Could not decode error status\n");
return NULL;
}
buf = snmp_ber_decode_integer(buf, &buf_len, &header->error_index_max_repetitions.error_index);
if(buf == NULL) {
LOG_DBG("Could not decode error index\n");
return NULL;
}
}
buf = snmp_ber_decode_type(buf, &buf_len, &type);
if(buf == NULL) {
LOG_DBG("Could not decode type\n");
return NULL;
}
if(type != BER_DATA_TYPE_SEQUENCE) {
LOG_DBG("Invalid type\n");
return NULL;
}
buf = snmp_ber_decode_length(buf, &buf_len, &len);
if(buf == NULL) {
LOG_DBG("Could not decode length\n");
return NULL;
}
for(i = 0; buf_len > 0; ++i) {
buf = snmp_ber_decode_type(buf, &buf_len, &type);
if(buf == NULL) {
LOG_DBG("Could not decode type\n");
return NULL;
}
if(type != BER_DATA_TYPE_SEQUENCE) {
LOG_DBG("Invalid (%X) type\n", type);
return NULL;
}
buf = snmp_ber_decode_length(buf, &buf_len, &len);
if(buf == NULL) {
LOG_DBG("Could not decode length\n");
return NULL;
}
buf = snmp_oid_decode_oid(buf, &buf_len, varbinds[i].oid, &oid_len);
if(buf == NULL) {
LOG_DBG("Could not decode oid\n");
return NULL;
}
varbinds[i].value_type = *buf;
switch(varbinds[i].value_type) {
case BER_DATA_TYPE_INTEGER:
buf = snmp_ber_decode_integer(buf, &buf_len, &varbinds[i].value.integer);
break;
case SNMP_DATA_TYPE_TIME_TICKS:
buf = snmp_ber_decode_unsigned_integer(buf, &buf_len, varbinds[i].value_type, &varbinds[i].value.integer);
break;
case BER_DATA_TYPE_OCTET_STRING:
buf = snmp_ber_decode_string_len_buffer(buf, &buf_len, &varbinds[i].value.string.string, &varbinds[i].value.string.length);
break;
case BER_DATA_TYPE_NULL:
buf = snmp_ber_decode_null(buf, &buf_len);
break;
default:
LOG_DBG("Invalid varbind type\n");
return NULL;
}
if(buf == NULL) {
LOG_DBG("Could varbind type\n");
return NULL;
}
}
*varbind_num = i;
return buf;
}
/*
* Copyright (C) 2019 Yago Fontoura do Rosario <yago.rosario@hotmail.com.br>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*---------------------------------------------------------------------------*/
/**
* \file
* An implementation of the Simple Network Management Protocol (RFC 3411-3418)
* \author
* Yago Fontoura do Rosario <yago.rosario@hotmail.com.br
*/
/**
* \addtogroup snmp
* @{
*/
#ifndef SNMP_MESSAGE_H_
#define SNMP_MESSAGE_H_
#include "snmp.h"
#define SNMP_DATA_TYPE_TIME_TICKS 0x43
#define SNMP_DATA_TYPE_NO_SUCH_INSTANCE 0x81
#define SNMP_DATA_TYPE_END_OF_MIB_VIEW 0x82
#define SNMP_DATA_TYPE_PDU_GET_REQUEST 0xA0
#define SNMP_DATA_TYPE_PDU_GET_NEXT_REQUEST 0xA1
#define SNMP_DATA_TYPE_PDU_GET_RESPONSE 0xA2
#define SNMP_DATA_TYPE_PDU_SET_REQUEST 0xA3
#define SNMP_DATA_TYPE_PDU_TRAP 0xA4
#define SNMP_DATA_TYPE_PDU_GET_BULK 0xA5
/**
* @brief Encodes a SNMP message
*
* @param out A pointer to the end of the buffer
* @param out_len A pointer to the buffer length
* @param header The SNMP header struct
* @param varbinds The varbinds array
* @param varbinds_length The number of varbinds
*
* @return
*/
unsigned char *
snmp_message_encode(unsigned char *out, uint32_t *out_len, snmp_header_t *header,
snmp_varbind_t *varbinds, uint32_t varbinds_length);
/**
* @brief
*
* @param buf A pointer to the beginning of the buffer
* @param buf_len A pointer to the buffer length
* @param header The SNMP header struct
* @param varbinds The varbinds array
* @param varbinds_length A pointer to the number of varbinds
*
* @return
*/
uint8_t *
snmp_message_decode(uint8_t *buf, uint32_t buf_len, snmp_header_t *header,
snmp_varbind_t *varbinds, uint32_t *varbinds_length);
#endif /* SNMP_MESSAGE_H_ */
/** @} */
/*
* Copyright (C) 2019 Yago Fontoura do Rosario <yago.rosario@hotmail.com.br>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*---------------------------------------------------------------------------*/
/**
* \file
* An implementation of the Simple Network Management Protocol (RFC 3411-3418)
* \author
* Yago Fontoura do Rosario <yago.rosario@hotmail.com.br
*/
#include "contiki.h"
#include "snmp-mib.h"
#include "snmp-oid.h"
#include "lib/list.h"
#define LOG_MODULE "SNMP [mib]"
#define LOG_LEVEL LOG_LEVEL_SNMP
LIST(snmp_mib);
snmp_mib_resource_t *
snmp_mib_find(uint32_t *oid)
{
snmp_mib_resource_t *resource;
resource = NULL;
for(resource = list_head(snmp_mib);
resource; resource = resource->next) {
if(!snmp_oid_cmp_oid(oid, resource->oid)) {
return resource;
}
}
return NULL;
}
snmp_mib_resource_t *
snmp_mib_find_next(uint32_t *oid)
{
snmp_mib_resource_t *resource;
resource = NULL;
for(resource = list_head(snmp_mib);
resource; resource = resource->next) {
if(snmp_oid_cmp_oid(resource->oid, oid) > 0) {
return resource;
}
}
return NULL;
}
void
snmp_mib_add(snmp_mib_resource_t *new_resource)
{
snmp_mib_resource_t *resource;
for(resource = list_head(snmp_mib);
resource; resource = resource->next) {
if(snmp_oid_cmp_oid(resource->oid, new_resource->oid) > 0) {
break;
}
}
if(resource == NULL) {
list_add(snmp_mib, new_resource);
} else {
list_insert(snmp_mib, new_resource, resource);
}
#if LOG_LEVEL == LOG_LEVEL_DBG
/*
* We print the entire resource table
*/
LOG_DBG("Table after insert.\n");
for(resource = list_head(snmp_mib);
resource; resource = resource->next) {
snmp_oid_print(resource->oid);
}
#endif /* LOG_LEVEL == LOG_LEVEL_DBG */
}
void
snmp_mib_init(void)
{
list_init(snmp_mib);
}
/*
* Copyright (C) 2019 Yago Fontoura do Rosario <yago.rosario@hotmail.com.br>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*---------------------------------------------------------------------------*/
/**
* \file
* An implementation of the Simple Network Management Protocol (RFC 3411-3418)
* \author
* Yago Fontoura do Rosario <yago.rosario@hotmail.com.br
*/
/**
* \addtogroup snmp
* @{
*/
#ifndef SNMP_MIB_H_
#define SNMP_MIB_H_
#include "snmp.h"
/**
* @brief The MIB resource handler typedef
*
* @param varbind The varbind that is being changed
* @param oid The oid from the resource
*/
typedef void (*snmp_mib_resource_handler_t)(snmp_varbind_t *varbind, uint32_t *oid);
/**
* @brief The MIB Resource struct
*/
typedef struct snmp_mib_resource_s {
/**
* @brief A pointer to the next element in the linked list
*
* @remarks This MUST be the first element in the struct
*/
struct snmp_mib_resource_s *next;
/**
* @brief A array that represents the OID
*
* @remarks This array is "null" terminated. In this case the -1 is used.
*/
uint32_t *oid;
/**
* @brief The function handler that is called for this resource
*/
snmp_mib_resource_handler_t handler;
} snmp_mib_resource_t;
/**
* @brief Finds the MIB Resource for this OID
*
* @param oid The OID
*
* @return In case of success a pointer to the resouce or NULL in case of fail
*/
snmp_mib_resource_t *
snmp_mib_find(uint32_t *oid);
/**
* @brief Finds the next MIB Resource after this OID
*
* @param oid The OID
*
* @return In case of success a pointer to the resouce or NULL in case of fail
*/
snmp_mib_resource_t *
snmp_mib_find_next(uint32_t *oid);
/**
* @brief Adds a resource into the linked list
*
* @param resource The resource
*/
void
snmp_mib_add(snmp_mib_resource_t *resource);
/**
* @brief Initialize the MIB resources list
*/
void
snmp_mib_init(void);
#endif /* SNMP_MIB_H_ */
/** @} */
/*
* Copyright (C) 2019 Yago Fontoura do Rosario <yago.rosario@hotmail.com.br>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*---------------------------------------------------------------------------*/
/**
* \file
* An implementation of the Simple Network Management Protocol (RFC 3411-3418)
* \author
* Yago Fontoura do Rosario <yago.rosario@hotmail.com.br
*/
#include "contiki.h"
#include "snmp-oid.h"
#include "snmp-ber.h"
#define LOG_MODULE "SNMP [oid]"
#define LOG_LEVEL LOG_LEVEL_SNMP
/*---------------------------------------------------------------------------*/
int
snmp_oid_cmp_oid(uint32_t *oid1, uint32_t *oid2)
{
uint8_t i;
i = 0;
while(oid1[i] != ((uint32_t)-1) &&
oid2[i] != ((uint32_t)-1)) {
if(oid1[i] != oid2[i]) {
if(oid1[i] < oid2[i]) {
return -1;
}
return 1;
}
i++;
}
if(oid1[i] == ((uint32_t)-1) &&
oid2[i] != ((uint32_t)-1)) {
return -1;
}
if(oid1[i] != ((uint32_t)-1) &&
oid2[i] == ((uint32_t)-1)) {
return 1;
}
return 0;
}
/*---------------------------------------------------------------------------*/
unsigned char *
snmp_oid_encode_oid(unsigned char *out, uint32_t *out_len, uint32_t *oid)
{
uint32_t original_out_len;
uint32_t *oid_start = oid;
uint32_t num;
original_out_len = *out_len;
while(*oid != ((uint32_t)-1)) {
++oid;
}
--oid;
while(oid != oid_start) {
num = *oid;
(*out_len)++;
*out-- = (uint8_t)(num & 0x7F);
num >>= 7;
while(num) {
(*out_len)++;
*out-- = (uint8_t)((num & 0x7F) | 0x80);
num >>= 7;
}
--oid;
}
num = *(out + 1) + 40 * *oid;
(*out_len)--;
out++;
(*out_len)++;
*out-- = (uint8_t)(num & 0x7F);
num >>= 7;
while(num) {
(*out_len)++;
*out-- = (uint8_t)((num & 0x7F) | 0x80);
num >>= 7;
}
out = snmp_ber_encode_length(out, out_len, ((*out_len - original_out_len) & 0xFF));
out = snmp_ber_encode_type(out, out_len, SNMP_DATA_TYPE_OBJECT);
return out;
}
/*---------------------------------------------------------------------------*/
uint8_t *
snmp_oid_decode_oid(uint8_t *buf, uint32_t *buff_len, uint32_t *oid, uint32_t *oid_len)
{
uint32_t *start;
uint8_t *buf_end, type;
uint8_t len;
div_t first;
start = oid;
buf = snmp_ber_decode_type(buf, buff_len, &type);
if(buf == NULL) {
return NULL;
}
if(type != SNMP_DATA_TYPE_OBJECT) {
return NULL;
}
buf = snmp_ber_decode_length(buf, buff_len, &len);
if(buf == NULL) {
return NULL;
}
buf_end = buf + len;
(*buff_len)--;
first = div(*buf++, 40);
*oid++ = (uint32_t)first.quot;
*oid++ = (uint32_t)first.rem;
while(buf != buf_end) {
--(*oid_len);
if(*oid_len == 0) {
return NULL;
}
int i;
*oid = (uint32_t)(*buf & 0x7F);
for(i = 0; i < 4; i++) {
(*buff_len)--;
if((*buf++ & 0x80) == 0) {
break;
}
*oid <<= 7;
*oid |= (*buf & 0x7F);
}
++oid;
}
*oid++ = ((uint32_t)-1);
*oid_len = (uint32_t)(oid - start);
return buf;
}
/*---------------------------------------------------------------------------*/
void
snmp_oid_copy(uint32_t *dst, uint32_t *src)
{
uint8_t i;
i = 0;
while(src[i] != ((uint32_t)-1)) {
dst[i] = src[i];
i++;
}
/*
* Copy the "null" terminator
*/
dst[i] = src[i];
}
/*---------------------------------------------------------------------------*/
#if LOG_LEVEL == LOG_LEVEL_DBG
void
snmp_oid_print(uint32_t *oid)
{
uint8_t i;
i = 0;
LOG_DBG("{");
while(oid[i] != ((uint32_t)-1)) {
LOG_DBG_("%lu", (unsigned long)oid[i]);
i++;
if(oid[i] != ((uint32_t)-1)) {
LOG_DBG_(".");
}
}
LOG_DBG_("}\n");
}
#endif /* LOG_LEVEL == LOG_LEVEL_DBG */
/*
* Copyright (C) 2019 Yago Fontoura do Rosario <yago.rosario@hotmail.com.br>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*---------------------------------------------------------------------------*/
/**
* \file
* An implementation of the Simple Network Management Protocol (RFC 3411-3418)
* \author
* Yago Fontoura do Rosario <yago.rosario@hotmail.com.br
*/
/**
* \addtogroup snmp
* @{
*/
#ifndef SNMP_OID_H_
#define SNMP_OID_H_
#include "snmp.h"
#define SNMP_DATA_TYPE_OBJECT 0x06
/**
* @brief Compares to oids
*
* @param oid1 First Oid
* @param oid2 Second Oid
*
* @return < 0 if oid1 < oid2, > 0 if oid1 > oid2 and 0 if they are equal
*/
int
snmp_oid_cmp_oid(uint32_t *oid1, uint32_t *oid2);
/**
* @brief Encodes a Oid
*
* @param out A pointer to the end of the buffer
* @param out_len A pointer to the buffer length
* @param oid The Oid
*
* @return NULL if error or the next entry in the buffer
*/
unsigned char *
snmp_oid_encode_oid(unsigned char *out, uint32_t *out_len, uint32_t *oid);
/**
* @brief Decodes a Oid
*
* @param buf A pointer to the beginning of the buffer
* @param buf_len A pointer to the buffer length
* @param oid A pointer to the oid array
* @param oid_len A pointer to the oid length
*
* @return NULL if error or the first entry after the oid in the buffer
*/
unsigned char *
snmp_oid_decode_oid(unsigned char *buf, uint32_t *buf_len, uint32_t *oid, uint32_t *oid_len);
/**
* @brief Copies a Oid
*
* @param dst A pointer to the destination array
* @param src A pointer to the source array
*/
void
snmp_oid_copy(uint32_t *dst, uint32_t *src);
#if LOG_LEVEL == LOG_LEVEL_DBG
/**
* @brief Prints a oid
*
* @param oid A oid
*/
void
snmp_oid_print(uint32_t *oid);
#endif /* LOG_LEVEL == LOG_LEVEL_DBG */
#endif /* SNMP_OID_H_ */
/** @} */
/*
* Copyright (C) 2019 Yago Fontoura do Rosario <yago.rosario@hotmail.com.br>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*---------------------------------------------------------------------------*/
/**
* \file
* An implementation of the Simple Network Management Protocol (RFC 3411-3418)
* \author
* Yago Fontoura do Rosario <yago.rosario@hotmail.com.br
*/
#include "contiki.h"
#include "snmp.h"
#include "snmp-mib.h"
#include "snmp-engine.h"
#define LOG_MODULE "SNMP"
#define LOG_LEVEL LOG_LEVEL_SNMP
/*---------------------------------------------------------------------------*/
#define SNMP_SERVER_PORT UIP_HTONS(SNMP_PORT)
PROCESS(snmp_process, "SNMP Process");
static struct uip_udp_conn *snmp_udp_conn = NULL;
/*---------------------------------------------------------------------------*/
static void
snmp_process_data(void)
{
static unsigned char packet[SNMP_MAX_PACKET_SIZE];
unsigned char *packet_end;
static uint32_t packet_len;
packet_end = packet + sizeof(packet) - 1;
packet_len = 0;
LOG_DBG("receiving UDP datagram from [");
LOG_DBG_6ADDR(&UIP_IP_BUF->srcipaddr);
LOG_DBG_("]:%u", uip_ntohs(UIP_UDP_BUF->srcport));
LOG_DBG_(" Length: %u\n", uip_datalen());
/*
* Handle the request
*/
if((packet_end = snmp_engine(uip_appdata, uip_datalen(), packet_end, &packet_len)) == NULL) {
LOG_DBG("Error while handling the request\n");
} else {
LOG_DBG("Sending response\n");
/*
* Send the response
*/
uip_udp_packet_sendto(snmp_udp_conn, packet_end, packet_len, &UIP_IP_BUF->srcipaddr, UIP_UDP_BUF->srcport);
}
}
/*---------------------------------------------------------------------------*/
void
snmp_init()
{
snmp_mib_init();
process_start(&snmp_process, NULL);
}
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(snmp_process, ev, data)
{
PROCESS_BEGIN();
/* new connection with remote host */
snmp_udp_conn = udp_new(NULL, 0, NULL);
udp_bind(snmp_udp_conn, SNMP_SERVER_PORT);
LOG_DBG("Listening on port %u\n", uip_ntohs(snmp_udp_conn->lport));
while(1) {
PROCESS_YIELD();
if(ev == tcpip_event) {
if(uip_newdata()) {
snmp_process_data();
}
}
} /* while (1) */
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment