diff --git a/examples/snmp-server/Makefile b/examples/snmp-server/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..c2e7b8952dcf472b7c5308be56fb66aa66b62c72
--- /dev/null
+++ b/examples/snmp-server/Makefile
@@ -0,0 +1,10 @@
+CONTIKI_PROJECT = snmp-server 
+all: $(CONTIKI_PROJECT)
+
+MODULES += os/net/app-layer/snmp
+
+MODULES_REL += ./resources
+
+CONTIKI = ../..
+
+include $(CONTIKI)/Makefile.include
diff --git a/examples/snmp-server/project-conf.h b/examples/snmp-server/project-conf.h
new file mode 100644
index 0000000000000000000000000000000000000000..724e89485b19ec1a39881e4e87162fede1d2bf0b
--- /dev/null
+++ b/examples/snmp-server/project-conf.h
@@ -0,0 +1,33 @@
+/*
+ * 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
diff --git a/examples/snmp-server/resources/snmp-SNMP-MIB-2-System.c b/examples/snmp-server/resources/snmp-SNMP-MIB-2-System.c
new file mode 100644
index 0000000000000000000000000000000000000000..f87d2bd2f07c7937279c6ca4e8a99d43dca56183
--- /dev/null
+++ b/examples/snmp-server/resources/snmp-SNMP-MIB-2-System.c
@@ -0,0 +1,124 @@
+/*
+ * 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);
+}
+/*---------------------------------------------------------------------------*/
diff --git a/examples/snmp-server/snmp-server.c b/examples/snmp-server/snmp-server.c
new file mode 100644
index 0000000000000000000000000000000000000000..dbc638f05e5e307d30e2fc7eefe552d340a0c764
--- /dev/null
+++ b/examples/snmp-server/snmp-server.c
@@ -0,0 +1,69 @@
+/*
+ * 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();
+}
+/*---------------------------------------------------------------------------*/
diff --git a/os/contiki-main.c b/os/contiki-main.c
index 43e3017464a74e73a60b443a992a3f484d66042a..dbeb26e521d72a69a1adfd256b052c954824b0a5 100644
--- a/os/contiki-main.c
+++ b/os/contiki-main.c
@@ -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 */
diff --git a/os/net/app-layer/snmp/module-macros.h b/os/net/app-layer/snmp/module-macros.h
new file mode 100644
index 0000000000000000000000000000000000000000..8396775a76e63231d9991910d14ca3d863a3e694
--- /dev/null
+++ b/os/net/app-layer/snmp/module-macros.h
@@ -0,0 +1 @@
+#define BUILD_WITH_SNMP 1
diff --git a/os/net/app-layer/snmp/snmp-api.c b/os/net/app-layer/snmp/snmp-api.c
new file mode 100644
index 0000000000000000000000000000000000000000..50d252df01812b66c38993c74f620efa9e9d5ef2
--- /dev/null
+++ b/os/net/app-layer/snmp/snmp-api.c
@@ -0,0 +1,93 @@
+/*
+ * 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);
+}
diff --git a/os/net/app-layer/snmp/snmp-api.h b/os/net/app-layer/snmp/snmp-api.h
new file mode 100644
index 0000000000000000000000000000000000000000..a82704f946fdaafddf8b7ce4d42de446709c3499
--- /dev/null
+++ b/os/net/app-layer/snmp/snmp-api.h
@@ -0,0 +1,141 @@
+/*
+ * 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_ */
+/** @} */
diff --git a/os/net/app-layer/snmp/snmp-ber.c b/os/net/app-layer/snmp/snmp-ber.c
new file mode 100644
index 0000000000000000000000000000000000000000..f5c520d0cf34affae3abb98e0e08ac5cf0091c8a
--- /dev/null
+++ b/os/net/app-layer/snmp/snmp-ber.c
@@ -0,0 +1,274 @@
+/*
+ * 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;
+}
+/*---------------------------------------------------------------------------*/
diff --git a/os/net/app-layer/snmp/snmp-ber.h b/os/net/app-layer/snmp/snmp-ber.h
new file mode 100644
index 0000000000000000000000000000000000000000..9111276dec6343de912db802dee1ec57187ef387
--- /dev/null
+++ b/os/net/app-layer/snmp/snmp-ber.h
@@ -0,0 +1,202 @@
+/*
+ * 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_ */
+/** @} */
diff --git a/os/net/app-layer/snmp/snmp-conf.h b/os/net/app-layer/snmp/snmp-conf.h
new file mode 100644
index 0000000000000000000000000000000000000000..c8a11ddadfb70115b3a60620904f35c2712aef96
--- /dev/null
+++ b/os/net/app-layer/snmp/snmp-conf.h
@@ -0,0 +1,116 @@
+/*
+ * 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_ */
+/** @} */
diff --git a/os/net/app-layer/snmp/snmp-engine.c b/os/net/app-layer/snmp/snmp-engine.c
new file mode 100644
index 0000000000000000000000000000000000000000..22694046654ab791a67b72a76c05f29bd7290ec7
--- /dev/null
+++ b/os/net/app-layer/snmp/snmp-engine.c
@@ -0,0 +1,254 @@
+/*
+ * 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;
+}
diff --git a/os/net/app-layer/snmp/snmp-engine.h b/os/net/app-layer/snmp/snmp-engine.h
new file mode 100644
index 0000000000000000000000000000000000000000..d6bc7978e138f186dde79009fa2edfbcef717178
--- /dev/null
+++ b/os/net/app-layer/snmp/snmp-engine.h
@@ -0,0 +1,65 @@
+/*
+ * 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_ */
+
+/** @} */
diff --git a/os/net/app-layer/snmp/snmp-message.c b/os/net/app-layer/snmp/snmp-message.c
new file mode 100644
index 0000000000000000000000000000000000000000..dd32743c1733d4a3d6caee372eae6d1e64e2e7ce
--- /dev/null
+++ b/os/net/app-layer/snmp/snmp-message.c
@@ -0,0 +1,280 @@
+/*
+ * 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;
+}
diff --git a/os/net/app-layer/snmp/snmp-message.h b/os/net/app-layer/snmp/snmp-message.h
new file mode 100644
index 0000000000000000000000000000000000000000..26436b9b7c8f0265c796d7f92fbfdc08e773bc91
--- /dev/null
+++ b/os/net/app-layer/snmp/snmp-message.h
@@ -0,0 +1,92 @@
+/*
+ * 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_ */
+
+/** @} */
diff --git a/os/net/app-layer/snmp/snmp-mib.c b/os/net/app-layer/snmp/snmp-mib.c
new file mode 100644
index 0000000000000000000000000000000000000000..fae834af141afe0d5f8c245de7c9f9a53ca5eade
--- /dev/null
+++ b/os/net/app-layer/snmp/snmp-mib.c
@@ -0,0 +1,117 @@
+/*
+ * 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);
+}
diff --git a/os/net/app-layer/snmp/snmp-mib.h b/os/net/app-layer/snmp/snmp-mib.h
new file mode 100644
index 0000000000000000000000000000000000000000..84115156a0eac33416c925d2d4348cdde4a7c50f
--- /dev/null
+++ b/os/net/app-layer/snmp/snmp-mib.h
@@ -0,0 +1,115 @@
+/*
+ * 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_ */
+/** @} */
diff --git a/os/net/app-layer/snmp/snmp-oid.c b/os/net/app-layer/snmp/snmp-oid.c
new file mode 100644
index 0000000000000000000000000000000000000000..29e4a2637c5b50b133c9117d972f6a5f1c605228
--- /dev/null
+++ b/os/net/app-layer/snmp/snmp-oid.c
@@ -0,0 +1,217 @@
+/*
+ * 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  */
diff --git a/os/net/app-layer/snmp/snmp-oid.h b/os/net/app-layer/snmp/snmp-oid.h
new file mode 100644
index 0000000000000000000000000000000000000000..1da2d16d2a9f02abbfa1844372a6e200c6adbbf2
--- /dev/null
+++ b/os/net/app-layer/snmp/snmp-oid.h
@@ -0,0 +1,108 @@
+/*
+ * 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_ */
+/** @} */
diff --git a/os/net/app-layer/snmp/snmp.c b/os/net/app-layer/snmp/snmp.c
new file mode 100644
index 0000000000000000000000000000000000000000..a721129fc5c9eb8381497bce649250af46a92ef6
--- /dev/null
+++ b/os/net/app-layer/snmp/snmp.c
@@ -0,0 +1,115 @@
+/*
+ * 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();
+}
+/*---------------------------------------------------------------------------*/
diff --git a/os/net/app-layer/snmp/snmp.h b/os/net/app-layer/snmp/snmp.h
new file mode 100644
index 0000000000000000000000000000000000000000..f6c4be0667f002bdce94072cfd0c2e424a639c00
--- /dev/null
+++ b/os/net/app-layer/snmp/snmp.h
@@ -0,0 +1,219 @@
+/*
+ * 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 apps
+ * @{
+ *
+ * \defgroup snmp SNMP (Simple Network Management Protocol)
+ * @{
+ *
+ * This is an implementation of the Simple Network Management Protocol
+ */
+
+#ifndef SNMP_H_
+#define SNMP_H_
+
+#include "contiki.h"
+#include "contiki-net.h"
+
+#include "sys/log.h"
+
+#include "snmp-conf.h"
+
+#include <stdlib.h>
+#include <stdint.h>
+
+/**
+ * \defgroup SNMPDefine SNMP Defines
+ * @{
+ */
+
+/**
+ * @brief SNMP Version 1 code
+ */
+#define SNMP_VERSION_1  0
+/**
+ * @brief SNMP Version 2c code
+ */
+#define SNMP_VERSION_2C 1
+
+/**
+ * @brief SNMP No Such Name error code
+ */
+#define SNMP_STATUS_NO_SUCH_NAME 2
+
+/** @} */
+
+/**
+ * \defgroup SNMPStructs SNMP Structs
+ * @{
+ */
+
+/**
+ * @brief The SNMP header struct
+ */
+typedef struct snmp_header_s {
+  /**
+   * @brief SNMP Version
+   */
+  uint32_t version;
+  /**
+   * @brief Struct to wrap the community
+   */
+  struct snmp_msg_community {
+    /**
+     * @brief A pointer to the community
+     *
+     * @remarks This pointer refers to the beginning of the string in the packet
+     */
+    const char *community;
+    /**
+     * @brief The string length
+     *
+     * @remarks Do not use strlen on the community pointer since it is not null terminated
+     */
+    uint32_t length;
+  } community;
+  /**
+   * @brief The PDU type
+   */
+  uint8_t pdu_type;
+  /**
+   * @brief The request ID
+   */
+  uint32_t request_id;
+  /**
+   * @brief Union to hold the error status or the non repeaters
+   *
+   * @remarks A union was used since these values cannot co-exist
+   */
+  union error_status_non_repeaters_u {
+    /**
+     * @brief The error status
+     */
+    uint32_t error_status;
+    /**
+     * @brief The non repeaters
+     */
+    uint32_t non_repeaters;
+  } error_status_non_repeaters;
+  /**
+   * @brief Union to hold the error index or the max repetitions
+   *
+   * @remarks A union was used since these values cannot co-exist
+   */
+  union error_index_max_repetitions_u {
+    /**
+     * @brief The error index
+     */
+    uint32_t error_index;
+    /**
+     * @brief The max repetitions
+     */
+    uint32_t max_repetitions;
+  } error_index_max_repetitions;
+} snmp_header_t;
+
+/**
+ * @brief The varbind struct
+ */
+typedef struct snmp_varbind_s {
+  /**
+   * @brief The OID
+   *
+   * @remarks The length is configurable
+   */
+  uint32_t oid[SNMP_MSG_OID_MAX_LEN];
+  /**
+   * @brief The type in this varbind
+   */
+  uint8_t value_type;
+  /**
+   * @brief A union to represent the value in this varbind
+   *
+   * @remarks A union is used since the varbind can only have one value of one type
+   */
+  union snmp_varbind_val_u {
+    /**
+     * @brief The integer value
+     */
+    uint32_t integer;
+    /**
+     * @brief A struct that contains the string
+     */
+    struct snmp_varbind_string_s {
+      /**
+       * @brief A pointer to the string value from this varbind
+       *
+       * @remarks This pointer points to a string that cannot be changed
+       */
+      const char *string;
+      /**
+       * @brief The string length
+       *
+       * @remarks Do not use strlen on the string since it might not be null terminated
+       */
+      uint32_t length;
+    } string;
+    /**
+     * @brief A pointer to the beggining of a oid array
+     */
+    uint32_t *oid;
+  } value;
+} snmp_varbind_t;
+
+/** @}*/
+
+/**
+ * \defgroup SNMPFunctions SNMP Functions
+ * @{
+ */
+
+/**
+ * @brief Initializes the SNMP engine
+ */
+void
+snmp_init();
+
+/** @}*/
+
+#endif /* SNMP_H_ */
+/** @} */
+/** @} */
diff --git a/os/net/mac/csma/csma.c b/os/net/mac/csma/csma.c
index 40fe4d7b3f4e9a089e25708cabd49d889081f543..3b20d9b988059a2a84c663c4de616c4a8a6d9587 100644
--- a/os/net/mac/csma/csma.c
+++ b/os/net/mac/csma/csma.c
@@ -177,7 +177,9 @@ max_payload(void)
     framer_hdrlen = CSMA_MAC_MAX_HEADER;
   }
 
-  return MIN(max_radio_payload_len, PACKETBUF_SIZE) - framer_hdrlen;
+  return MIN(max_radio_payload_len, PACKETBUF_SIZE)
+    - framer_hdrlen
+    - LLSEC802154_PACKETBUF_MIC_LEN();
 }
 /*---------------------------------------------------------------------------*/
 const struct mac_driver csma_driver = {
diff --git a/os/net/mac/llsec802154.h b/os/net/mac/llsec802154.h
index e808fef7a016a1323d545f487b365a22f04a1297..84e8396e765dd4cd8864366f048402f88561fdcd 100644
--- a/os/net/mac/llsec802154.h
+++ b/os/net/mac/llsec802154.h
@@ -60,8 +60,6 @@
 #define LLSEC802154_ENABLED            0
 #endif /* LLSEC802154_CONF_ENABLED */
 
-#define LLSEC802154_MIC_LEN(sec_lvl)   (2 << (sec_lvl & 3))
-
 #ifdef LLSEC802154_CONF_USES_EXPLICIT_KEYS
 #define LLSEC802154_USES_EXPLICIT_KEYS LLSEC802154_CONF_USES_EXPLICIT_KEYS
 #else /* LLSEC802154_CONF_USES_EXPLICIT_KEYS */
@@ -88,6 +86,14 @@
 #define LLSEC802154_HTONL(n) (((uint32_t)UIP_HTONS(n) << 16) | UIP_HTONS((uint32_t)(n) >> 16))
 #endif /* UIP_CONF_BYTE_ORDER == UIP_LITTLE_ENDIAN */
 
+#define LLSEC802154_MIC_LEN(sec_lvl)   (2 << (sec_lvl & 3))
+
+#if LLSEC802154_USES_AUX_HEADER
+#define LLSEC802154_PACKETBUF_MIC_LEN() LLSEC802154_MIC_LEN(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL))
+#else
+#define LLSEC802154_PACKETBUF_MIC_LEN() 0
+#endif
+
 #endif /* LLSEC802154_H_ */
 
 /** @} */
diff --git a/os/net/mac/tsch/tsch-packet.c b/os/net/mac/tsch/tsch-packet.c
index 133e9a6688af7afa206aa99f47730fa89d8f472a..893aa7e8c76c1bfbcbce261e04b89a24f94d6b4d 100644
--- a/os/net/mac/tsch/tsch-packet.c
+++ b/os/net/mac/tsch/tsch-packet.c
@@ -74,11 +74,11 @@ static struct packetbuf_attr eackbuf_attrs[PACKETBUF_NUM_ATTRS];
 #define IEEE802154_FRAME_PENDING_BIT_OFFSET 4
 
 /*---------------------------------------------------------------------------*/
-static int
+void
 tsch_packet_eackbuf_set_attr(uint8_t type, const packetbuf_attr_t val)
 {
   eackbuf_attrs[type].val = val;
-  return 1;
+  return;
 }
 /*---------------------------------------------------------------------------*/
 /* Return the value of a specified attribute */
@@ -124,14 +124,7 @@ tsch_packet_create_eack(uint8_t *buf, uint16_t buf_len,
 #endif
 
 #if LLSEC802154_ENABLED
-  if(tsch_is_pan_secured) {
-    tsch_packet_eackbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL,
-                                 TSCH_SECURITY_KEY_SEC_LEVEL_ACK);
-    tsch_packet_eackbuf_set_attr(PACKETBUF_ATTR_KEY_ID_MODE,
-                                 FRAME802154_1_BYTE_KEY_ID_MODE);
-    tsch_packet_eackbuf_set_attr(PACKETBUF_ATTR_KEY_INDEX,
-                                 TSCH_SECURITY_KEY_INDEX_ACK);
-  }
+  tsch_security_set_packetbuf_attr(FRAME802154_ACKFRAME);
 #endif /* LLSEC802154_ENABLED */
 
   framer_802154_setup_params(tsch_packet_eackbuf_attr, 0, &params);
@@ -356,14 +349,7 @@ tsch_packet_create_eb(uint8_t *hdr_len, uint8_t *tsch_sync_ie_offset)
   packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, &tsch_eb_address);
 
 #if LLSEC802154_ENABLED
-  if(tsch_is_pan_secured) {
-    packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL,
-                       TSCH_SECURITY_KEY_SEC_LEVEL_EB);
-    packetbuf_set_attr(PACKETBUF_ATTR_KEY_ID_MODE,
-                       FRAME802154_1_BYTE_KEY_ID_MODE);
-    packetbuf_set_attr(PACKETBUF_ATTR_KEY_INDEX,
-                       TSCH_SECURITY_KEY_INDEX_EB);
-  }
+  tsch_security_set_packetbuf_attr(FRAME802154_BEACONFRAME);
 #endif /* LLSEC802154_ENABLED */
 
   if(NETSTACK_FRAMER.create() < 0) {
diff --git a/os/net/mac/tsch/tsch-packet.h b/os/net/mac/tsch/tsch-packet.h
index cdf7c7bed0111ac6127acaa18a9724d53e06b718..9f110344b717cb38c33dc59a299e1d18b1eea6b1 100644
--- a/os/net/mac/tsch/tsch-packet.h
+++ b/os/net/mac/tsch/tsch-packet.h
@@ -114,6 +114,19 @@ void tsch_packet_set_frame_pending(uint8_t *buf, int buf_size);
  * \return The value of the frame pending bit, 1 or 0
  */
 int tsch_packet_get_frame_pending(uint8_t *buf, int buf_size);
+/**
+ * \brief Set a packet attribute for the current eack. We not use standard
+ * packetbuf for eacks because these are generated from interrupt context.
+ * \param type The attribute identifier
+ * \param val The attribute value
+ */
+void tsch_packet_eackbuf_set_attr(uint8_t type, const packetbuf_attr_t val);
+/**
+ * \brief Return the value of a specified attribute
+ * \param type The attribute identifier
+ * \return The attribute value
+ */
+packetbuf_attr_t tsch_packet_eackbuf_attr(uint8_t type);
 
 #endif /* __TSCH_PACKET_H__ */
 /** @} */
diff --git a/os/net/mac/tsch/tsch-security.c b/os/net/mac/tsch/tsch-security.c
index 12f0de6d51798811b5061f2cfde451209c0d5a84..8d128427043e3c12ad5d887b4dfa1cf35d3376c1 100644
--- a/os/net/mac/tsch/tsch-security.c
+++ b/os/net/mac/tsch/tsch-security.c
@@ -271,4 +271,33 @@ tsch_security_parse_frame(const uint8_t *hdr, int hdrlen, int datalen,
     return 1;
   }
 }
+/*---------------------------------------------------------------------------*/
+void
+tsch_security_set_packetbuf_attr(uint8_t frame_type)
+{
+#if LLSEC802154_ENABLED
+  if(tsch_is_pan_secured) {
+    /* Set security level, key id and index */
+    switch(frame_type) {
+      case FRAME802154_ACKFRAME:
+        /* For ACKs, we set attriburtes via tsch_packet_eackbuf_set_attr, as classic
+         * interrupts can not be used from interrupt context. */
+        tsch_packet_eackbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL, TSCH_SECURITY_KEY_SEC_LEVEL_ACK);
+        tsch_packet_eackbuf_set_attr(PACKETBUF_ATTR_KEY_ID_MODE, FRAME802154_1_BYTE_KEY_ID_MODE);
+        tsch_packet_eackbuf_set_attr(PACKETBUF_ATTR_KEY_INDEX, TSCH_SECURITY_KEY_INDEX_ACK);
+        break;
+      case FRAME802154_BEACONFRAME:
+        packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL, TSCH_SECURITY_KEY_SEC_LEVEL_EB);
+        packetbuf_set_attr(PACKETBUF_ATTR_KEY_ID_MODE, FRAME802154_1_BYTE_KEY_ID_MODE);
+        packetbuf_set_attr(PACKETBUF_ATTR_KEY_INDEX, TSCH_SECURITY_KEY_INDEX_EB);
+        break;
+      default:
+        packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL, TSCH_SECURITY_KEY_SEC_LEVEL_OTHER);
+        packetbuf_set_attr(PACKETBUF_ATTR_KEY_ID_MODE, FRAME802154_1_BYTE_KEY_ID_MODE);
+        packetbuf_set_attr(PACKETBUF_ATTR_KEY_INDEX, TSCH_SECURITY_KEY_INDEX_OTHER);
+        break;
+    }
+  }
+#endif /* LLSEC802154_ENABLED */
+}
 /** @} */
diff --git a/os/net/mac/tsch/tsch-security.h b/os/net/mac/tsch/tsch-security.h
index 4320d3a70adf65182a5aca9c9d69d473bc99e3f2..3777a9e0c56d9abc41c514bc2832741574ead7fa 100644
--- a/os/net/mac/tsch/tsch-security.h
+++ b/os/net/mac/tsch/tsch-security.h
@@ -140,5 +140,11 @@ unsigned int tsch_security_parse_frame(const uint8_t *hdr, int hdrlen,
                                        const linkaddr_t *sender,
                                        struct tsch_asn_t *asn);
 
+/**
+ * \brief Set packetbuf (or eackbuf) attributes depending on a given frame type
+ * \param frame_type The frame type (FRAME802154_BEACONFRAME etc.)
+ */
+void tsch_security_set_packetbuf_attr(uint8_t frame_type);
+
 #endif /* __TSCH_SECURITY_H__ */
 /** @} */
diff --git a/os/net/mac/tsch/tsch.c b/os/net/mac/tsch/tsch.c
index f6f0d4934bc3a18a29a0600d6e5399f9c3fc5f02..3fd02fbefa3bf1f62f0816f1520d03ee7c2457dd 100644
--- a/os/net/mac/tsch/tsch.c
+++ b/os/net/mac/tsch/tsch.c
@@ -1047,12 +1047,7 @@ send_packet(mac_callback_t sent, void *ptr)
   packetbuf_set_attr(PACKETBUF_ATTR_FRAME_TYPE, FRAME802154_DATAFRAME);
 
 #if LLSEC802154_ENABLED
-  if(tsch_is_pan_secured) {
-    /* Set security level, key id and index */
-    packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL, TSCH_SECURITY_KEY_SEC_LEVEL_OTHER);
-    packetbuf_set_attr(PACKETBUF_ATTR_KEY_ID_MODE, FRAME802154_1_BYTE_KEY_ID_MODE); /* Use 1-byte key index */
-    packetbuf_set_attr(PACKETBUF_ATTR_KEY_INDEX, TSCH_SECURITY_KEY_INDEX_OTHER);
-  }
+  tsch_security_set_packetbuf_attr(FRAME802154_DATAFRAME);
 #endif /* LLSEC802154_ENABLED */
 
 #if !NETSTACK_CONF_BRIDGE_MODE
@@ -1163,6 +1158,7 @@ turn_off(void)
 static int
 max_payload(void)
 {
+  int framer_hdrlen;
   radio_value_t max_radio_payload_len;
   radio_result_t res;
 
@@ -1174,8 +1170,18 @@ max_payload(void)
     return 0;
   }
 
+  /* Set packetbuf security attributes */
+  tsch_security_set_packetbuf_attr(FRAME802154_DATAFRAME);
+
+  framer_hdrlen = NETSTACK_FRAMER.length();
+  if(framer_hdrlen < 0) {
+    return 0;
+  }
+
   /* Setup security... before. */
-  return MIN(max_radio_payload_len, TSCH_PACKET_MAX_LEN) -  NETSTACK_FRAMER.length();
+  return MIN(max_radio_payload_len, TSCH_PACKET_MAX_LEN)
+    - framer_hdrlen
+    - LLSEC802154_PACKETBUF_MIC_LEN();
 }
 /*---------------------------------------------------------------------------*/
 const struct mac_driver tschmac_driver = {
diff --git a/os/sys/log-conf.h b/os/sys/log-conf.h
index 17d8562cc114e75dccff5a77fc4bc0c7ab67863c..f886e78681738d626639639a5509461e4dfb2f67 100644
--- a/os/sys/log-conf.h
+++ b/os/sys/log-conf.h
@@ -138,6 +138,10 @@
 #define LOG_CONF_LEVEL_COAP                        LOG_LEVEL_NONE
 #endif /* LOG_CONF_LEVEL_COAP */
 
+#ifndef LOG_CONF_LEVEL_SNMP
+#define LOG_CONF_LEVEL_SNMP                        LOG_LEVEL_NONE
+#endif /* LOG_CONF_LEVEL_COAP */
+
 #ifndef LOG_CONF_LEVEL_LWM2M
 #define LOG_CONF_LEVEL_LWM2M                       LOG_LEVEL_NONE
 #endif /* LOG_CONF_LEVEL_LWM2M */
diff --git a/os/sys/log.c b/os/sys/log.c
index abb960b980cb4535fbc84825d5ea8a9edb33612c..41d0ea734abb8eb283f601d21d873c57f8fd786e 100644
--- a/os/sys/log.c
+++ b/os/sys/log.c
@@ -62,6 +62,7 @@ int curr_log_level_mac = LOG_CONF_LEVEL_MAC;
 int curr_log_level_framer = LOG_CONF_LEVEL_FRAMER;
 int curr_log_level_6top = LOG_CONF_LEVEL_6TOP;
 int curr_log_level_coap = LOG_CONF_LEVEL_COAP;
+int curr_log_level_snmp = LOG_CONF_LEVEL_SNMP;
 int curr_log_level_lwm2m = LOG_CONF_LEVEL_LWM2M;
 int curr_log_level_main = LOG_CONF_LEVEL_MAIN;
 
@@ -75,6 +76,7 @@ struct log_module all_modules[] = {
   {"framer", &curr_log_level_framer, LOG_CONF_LEVEL_FRAMER},
   {"6top", &curr_log_level_6top, LOG_CONF_LEVEL_6TOP},
   {"coap", &curr_log_level_coap, LOG_CONF_LEVEL_COAP},
+  {"snmp", &curr_log_level_snmp, LOG_CONF_LEVEL_SNMP},
   {"lwm2m", &curr_log_level_lwm2m, LOG_CONF_LEVEL_LWM2M},
   {"main", &curr_log_level_main, LOG_CONF_LEVEL_MAIN},
   {NULL, NULL, 0},
diff --git a/os/sys/log.h b/os/sys/log.h
index 0f5f840d2e702fd9f6a26edc1ff1ee0b497e5062..a01df9e9149c9662b2b16cb3519e167934cec0e1 100644
--- a/os/sys/log.h
+++ b/os/sys/log.h
@@ -82,6 +82,7 @@ extern int curr_log_level_mac;
 extern int curr_log_level_framer;
 extern int curr_log_level_6top;
 extern int curr_log_level_coap;
+extern int curr_log_level_snmp;
 extern int curr_log_level_lwm2m;
 extern int curr_log_level_main;
 
@@ -96,6 +97,7 @@ extern struct log_module all_modules[];
 #define LOG_LEVEL_FRAMER                      MIN((LOG_CONF_LEVEL_FRAMER), curr_log_level_framer)
 #define LOG_LEVEL_6TOP                        MIN((LOG_CONF_LEVEL_6TOP), curr_log_level_6top)
 #define LOG_LEVEL_COAP                        MIN((LOG_CONF_LEVEL_COAP), curr_log_level_coap)
+#define LOG_LEVEL_SNMP                        MIN((LOG_CONF_LEVEL_SNMP), curr_log_level_snmp)
 #define LOG_LEVEL_LWM2M                       MIN((LOG_CONF_LEVEL_LWM2M), curr_log_level_lwm2m)
 #define LOG_LEVEL_MAIN                        MIN((LOG_CONF_LEVEL_MAIN), curr_log_level_main)
 
diff --git a/tests/01-compile-base/Makefile b/tests/01-compile-base/Makefile
index 51e68f9a258cea9c22e13e3e05a7cabdd6ce348b..e7592e824f18353ae4d68135409bcbc50c5686f5 100644
--- a/tests/01-compile-base/Makefile
+++ b/tests/01-compile-base/Makefile
@@ -32,6 +32,7 @@ coap/coap-example-client/native \
 coap/coap-example-server/native \
 coap/coap-plugtest-server/native \
 sensniff/z1 \
+snmp-server/sky \
 
 TOOLS=
 
diff --git a/tests/02-compile-arm-ports-01/Makefile b/tests/02-compile-arm-ports-01/Makefile
index 43e008c8e8a581b70e0b34177b2e9b471841b622..f94d758e6bcd419d46a47ee0c6656a029b36e9c9 100644
--- a/tests/02-compile-arm-ports-01/Makefile
+++ b/tests/02-compile-arm-ports-01/Makefile
@@ -98,7 +98,8 @@ platform-specific/nrf52dk/mqtt-demo/nrf52dk \
 platform-specific/nrf52dk/blink-hello/nrf52dk \
 platform-specific/nrf52dk/timer-test/nrf52dk \
 libs/data-structures/nrf52dk \
-libs/logging/nrf52dk
+libs/logging/nrf52dk \
+snmp-server/cc2538dk \
 
 TOOLS=
 
diff --git a/tests/08-native-runs/06-snmp-server.sh b/tests/08-native-runs/06-snmp-server.sh
new file mode 100644
index 0000000000000000000000000000000000000000..6a6e12f381aed123ad44c90e5d2aea16ea34bbfa
--- /dev/null
+++ b/tests/08-native-runs/06-snmp-server.sh
@@ -0,0 +1,48 @@
+#!/bin/bash
+source ../utils.sh
+
+# Contiki directory
+CONTIKI=$1
+# Test basename
+BASENAME=$(basename $0 .sh)
+
+IPADDR=fd00::302:304:506:708
+
+# Starting Contiki-NG native node
+echo "Starting native node"
+make -C $CONTIKI/examples/snmp-server > make.log 2> make.err
+sudo $CONTIKI/examples/snmp-server/snmp-server.native > node.log 2> node.err &
+CPID=$!
+sleep 2
+
+# Do Walk
+echo "WALK!"
+snmpwalk -t 4 -v 2c -c public udp6:[$IPADDR]:161 1 | tee $BASENAME.log
+# Fetch snmpwalk status code (not $? because this is piped)
+STATUS=${PIPESTATUS[0]}
+
+echo "Closing native node"
+sleep 2
+kill_bg $CPID
+
+if [ $STATUS -eq 0 ] ; then
+  cp $BASENAME.log $BASENAME.testlog
+  printf "%-32s TEST OK\n" "$BASENAME" | tee $BASENAME.testlog;
+else
+  echo "==== make.log ====" ; cat make.log;
+  echo "==== make.err ====" ; cat make.err;
+  echo "==== node.log ====" ; cat node.log;
+  echo "==== node.err ====" ; cat node.err;
+  echo "==== $BASENAME.log ====" ; cat $BASENAME.log;
+
+  printf "%-32s TEST FAIL\n" "$BASENAME" | tee $BASENAME.testlog;
+fi
+
+rm make.log
+rm make.err
+rm node.log
+rm node.err
+
+# We do not want Make to stop -> Return 0
+# The Makefile will check if a log contains FAIL at the end
+exit 0
diff --git a/tools/docker/Dockerfile b/tools/docker/Dockerfile
index 56775dc7405f7e5633c45c2c9658a60ffd4f0a4a..89cb36c552ed7b7ad2a8a15083fff70391c74d37 100644
--- a/tools/docker/Dockerfile
+++ b/tools/docker/Dockerfile
@@ -31,6 +31,9 @@ RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E03280
     unzip \
     valgrind \
     wget \
+    smitools \
+    snmp \
+    snmp-mibs-downloader \
     > /dev/null \
   && apt-get -qq clean
 
diff --git a/tools/viewconf/viewconf.c b/tools/viewconf/viewconf.c
index 1237061ca7ab992f1f8ab976b8b437139944c620..53a38cf6f3cbd94c1e870d26c0897a5978226770 100644
--- a/tools/viewconf/viewconf.c
+++ b/tools/viewconf/viewconf.c
@@ -149,5 +149,6 @@
 ##### "LOG_CONF_LEVEL_FRAMER": _________________ == LOG_CONF_LEVEL_FRAMER
 ##### "LOG_CONF_LEVEL_6TOP": ___________________ == LOG_CONF_LEVEL_6TOP
 ##### "LOG_CONF_LEVEL_COAP": ___________________ == LOG_CONF_LEVEL_COAP
+##### "LOG_CONF_LEVEL_SNMP": ___________________ == LOG_CONF_LEVEL_SNMP
 ##### "LOG_CONF_LEVEL_LWM2M": __________________ == LOG_CONF_LEVEL_LWM2M
 ##### "LOG_CONF_LEVEL_MAIN": ___________________ == LOG_CONF_LEVEL_MAIN