193#if (LWIP_SNMP && (SNMP_TRAP_DESTINATIONS<=0))
194#error "If you want to use SNMP, you have to define SNMP_TRAP_DESTINATIONS>=1 in your lwipopts.h"
196#if (!LWIP_UDP && LWIP_SNMP)
197#error "If you want to use SNMP, you have to define LWIP_UDP=1 in your lwipopts.h"
199#if SNMP_MAX_OBJ_ID_LEN > 255
200#error "SNMP_MAX_OBJ_ID_LEN must fit into an u8_t"
203struct snmp_statistics snmp_stats;
205static const struct snmp_obj_id *snmp_device_enterprise_oid = &snmp_device_enterprise_oid_default;
207const u32_t snmp_zero_dot_zero_values[] = { 0, 0 };
208const struct snmp_obj_id_const_ref snmp_zero_dot_zero = {
LWIP_ARRAYSIZE(snmp_zero_dot_zero_values), snmp_zero_dot_zero_values };
210#if SNMP_LWIP_MIB2 && LWIP_SNMP_V3
214static const struct snmp_mib *
const default_mibs[] = { &
mib2, &snmpframeworkmib, &snmpusmmib };
218static const struct snmp_mib *
const default_mibs[] = { &
mib2 };
221static const struct snmp_mib *
const default_mibs[] = {
NULL };
222static u8_t snmp_num_mibs = 0;
226static struct snmp_mib
const *
const *snmp_mibs = default_mibs;
239snmp_set_mibs(
const struct snmp_mib **mibs,
u8_t num_mibs)
241 LWIP_ASSERT_SNMP_LOCKED();
243 LWIP_ASSERT(
"num_mibs pointer must be != 0", (num_mibs != 0));
245 snmp_num_mibs = num_mibs;
262void snmp_set_device_enterprise_oid(
const struct snmp_obj_id *device_enterprise_oid)
264 LWIP_ASSERT_SNMP_LOCKED();
265 if (device_enterprise_oid ==
NULL) {
266 snmp_device_enterprise_oid = &snmp_device_enterprise_oid_default;
268 snmp_device_enterprise_oid = device_enterprise_oid;
276const struct snmp_obj_id *snmp_get_device_enterprise_oid(
void)
278 LWIP_ASSERT_SNMP_LOCKED();
279 return snmp_device_enterprise_oid;
289snmp_oid_to_ip4(
const u32_t *oid, ip4_addr_t *
ip)
291 if ((oid[0] > 0xFF) ||
295 ip4_addr_copy(*
ip, *IP4_ADDR_ANY4);
299 IP4_ADDR(
ip, oid[0], oid[1], oid[2], oid[3]);
309snmp_ip4_to_oid(
const ip4_addr_t *
ip,
u32_t *oid)
311 oid[0] = ip4_addr1(
ip);
312 oid[1] = ip4_addr2(
ip);
313 oid[2] = ip4_addr3(
ip);
314 oid[3] = ip4_addr4(
ip);
325snmp_oid_to_ip6(
const u32_t *oid, ip6_addr_t *
ip)
327 if ((oid[0] > 0xFF) ||
343 ip6_addr_set_any(
ip);
347 ip->addr[0] = (oid[0] << 24) | (oid[1] << 16) | (oid[2] << 8) | (oid[3] << 0);
348 ip->addr[1] = (oid[4] << 24) | (oid[5] << 16) | (oid[6] << 8) | (oid[7] << 0);
349 ip->addr[2] = (oid[8] << 24) | (oid[9] << 16) | (oid[10] << 8) | (oid[11] << 0);
350 ip->addr[3] = (oid[12] << 24) | (oid[13] << 16) | (oid[14] << 8) | (oid[15] << 0);
360snmp_ip6_to_oid(
const ip6_addr_t *
ip,
u32_t *oid)
362 oid[0] = (
ip->addr[0] & 0xFF000000) >> 24;
363 oid[1] = (
ip->addr[0] & 0x00FF0000) >> 16;
364 oid[2] = (
ip->addr[0] & 0x0000FF00) >> 8;
365 oid[3] = (
ip->addr[0] & 0x000000FF) >> 0;
366 oid[4] = (
ip->addr[1] & 0xFF000000) >> 24;
367 oid[5] = (
ip->addr[1] & 0x00FF0000) >> 16;
368 oid[6] = (
ip->addr[1] & 0x0000FF00) >> 8;
369 oid[7] = (
ip->addr[1] & 0x000000FF) >> 0;
370 oid[8] = (
ip->addr[2] & 0xFF000000) >> 24;
371 oid[9] = (
ip->addr[2] & 0x00FF0000) >> 16;
372 oid[10] = (
ip->addr[2] & 0x0000FF00) >> 8;
373 oid[11] = (
ip->addr[2] & 0x000000FF) >> 0;
374 oid[12] = (
ip->addr[3] & 0xFF000000) >> 24;
375 oid[13] = (
ip->addr[3] & 0x00FF0000) >> 16;
376 oid[14] = (
ip->addr[3] & 0x0000FF00) >> 8;
377 oid[15] = (
ip->addr[3] & 0x000000FF) >> 0;
381#if LWIP_IPV4 || LWIP_IPV6
394 idx = snmp_ip_to_oid(
ip, oid);
427 snmp_ip4_to_oid(ip_2_ip4(
ip), &oid[2]);
463 }
else if (oid[0] == 1) {
476 if (!snmp_oid_to_ip4(&oid[2], ip_2_ip4(
ip))) {
484 }
else if (oid[0] == 2) {
497 if (!snmp_oid_to_ip6(&oid[2],
ip_2_ip6(
ip))) {
524 idx = snmp_oid_to_ip(&oid[0], oid_len,
ip);
530 if (oid_len < (
idx + 1)) {
533 if (oid[
idx] > 0xffff) {
551snmp_oid_assign(
struct snmp_obj_id *
target,
const u32_t *oid,
u8_t oid_len)
569snmp_oid_prefix(
struct snmp_obj_id *
target,
const u32_t *oid,
u8_t oid_len)
597 snmp_oid_append(
target, oid2, oid2_len);
607snmp_oid_append(
struct snmp_obj_id *
target,
const u32_t *oid,
u8_t oid_len)
629 LWIP_ASSERT(
"'oid1' param must not be NULL or 'oid1_len' param be 0!", (
oid1 !=
NULL) || (oid1_len == 0));
630 LWIP_ASSERT(
"'oid2' param must not be NULL or 'oid2_len' param be 0!", (oid2 !=
NULL) || (oid2_len == 0));
632 while ((
level < oid1_len) && (
level < oid2_len)) {
646 if (oid1_len < oid2_len) {
649 if (oid1_len > oid2_len) {
669 return (snmp_oid_compare(
oid1, oid1_len, oid2, oid2_len) == 0) ? 1 : 0;
683static const struct snmp_mib *
684snmp_get_mib_from_oid(
const u32_t *oid,
u8_t oid_len)
686 const u32_t *list_oid;
687 const u32_t *searched_oid;
690 u8_t max_match_len = 0;
691 const struct snmp_mib *matched_mib =
NULL;
699 for (
i = 0;
i < snmp_num_mibs;
i++) {
701 LWIP_ASSERT(
"MIB array not initialized correctly - base OID is NULL", (snmp_mibs[
i]->base_oid !=
NULL));
703 if (oid_len >= snmp_mibs[
i]->base_oid_len) {
704 l = snmp_mibs[
i]->base_oid_len;
705 list_oid = snmp_mibs[
i]->base_oid;
709 if (*list_oid != *searched_oid) {
718 if ((
l == 0) && (snmp_mibs[
i]->base_oid_len > max_match_len)) {
719 max_match_len = snmp_mibs[
i]->base_oid_len;
720 matched_mib = snmp_mibs[
i];
728static const struct snmp_mib *
729snmp_get_next_mib(
const u32_t *oid,
u8_t oid_len)
732 const struct snmp_mib *next_mib =
NULL;
740 for (
i = 0;
i < snmp_num_mibs;
i++) {
741 if (snmp_mibs[
i]->base_oid !=
NULL) {
743 if (snmp_oid_compare(snmp_mibs[
i]->base_oid, snmp_mibs[
i]->base_oid_len, oid, oid_len) > 0) {
744 if ((next_mib ==
NULL) ||
745 (snmp_oid_compare(snmp_mibs[
i]->base_oid, snmp_mibs[
i]->base_oid_len,
746 next_mib->base_oid, next_mib->base_oid_len) < 0)) {
747 next_mib = snmp_mibs[
i];
756static const struct snmp_mib *
759 const struct snmp_mib *next_mib = snmp_get_next_mib(
oid1, oid1_len);
762 LWIP_ASSERT(
"'oid2_len' param must be greater than 0!", (oid2_len > 0));
764 if (next_mib !=
NULL) {
765 if (snmp_oid_compare(next_mib->base_oid, next_mib->base_oid_len, oid2, oid2_len) < 0) {
774snmp_get_node_instance_from_oid(
const u32_t *oid,
u8_t oid_len,
struct snmp_node_instance *node_instance)
777 const struct snmp_mib *mib;
778 const struct snmp_node *mn =
NULL;
780 mib = snmp_get_mib_from_oid(oid, oid_len);
782 u8_t oid_instance_len;
784 mn = snmp_mib_tree_resolve_exact(mib, oid, oid_len, &oid_instance_len);
785 if ((mn !=
NULL) && (mn->node_type != SNMP_NODE_TREE)) {
787 const struct snmp_leaf_node *
leaf_node = (
const struct snmp_leaf_node *)(
const void *)mn;
789 node_instance->node = mn;
790 snmp_oid_assign(&node_instance->instance_oid, oid + (oid_len - oid_instance_len), oid_instance_len);
794 oid_len - oid_instance_len,
798 if (
result == SNMP_ERR_NOERROR) {
799 if (((node_instance->access & SNMP_NODE_INSTANCE_ACCESS_READ) != 0) && (node_instance->get_value ==
NULL)) {
800 LWIP_DEBUGF(
SNMP_DEBUG, (
"SNMP inconsistent access: node is readable but no get_value function is specified\n"));
802 if (((node_instance->access & SNMP_NODE_INSTANCE_ACCESS_WRITE) != 0) && (node_instance->set_value ==
NULL)) {
803 LWIP_DEBUGF(
SNMP_DEBUG, (
"SNMP inconsistent access: node is writable but no set_value and/or set_test function is specified\n"));
814snmp_get_next_node_instance_from_oid(
const u32_t *oid,
u8_t oid_len, snmp_validate_node_instance_method validate_node_instance_method,
void *validate_node_instance_arg,
struct snmp_obj_id *node_oid,
struct snmp_node_instance *node_instance)
816 const struct snmp_mib *mib;
817 const struct snmp_node *mn =
NULL;
819 u8_t start_oid_len = 0;
822 mib = snmp_get_mib_from_oid(oid, oid_len);
825 mib = snmp_get_next_mib(oid, oid_len);
828 start_oid = mib->base_oid;
829 start_oid_len = mib->base_oid_len;
833 start_oid_len = oid_len;
837 while ((mib !=
NULL) && (mn ==
NULL)) {
838 u8_t oid_instance_len;
841 mn = snmp_mib_tree_resolve_exact(mib, start_oid, start_oid_len, &oid_instance_len);
843 snmp_oid_assign(node_oid, start_oid, start_oid_len - oid_instance_len);
844 snmp_oid_assign(&node_instance->instance_oid, start_oid + (start_oid_len - oid_instance_len), oid_instance_len);
847 mn = snmp_mib_tree_resolve_next(mib, start_oid, start_oid_len, node_oid);
848 node_instance->instance_oid.len = 0;
852 node_instance->node = mn;
857 node_instance->asn1_type = 0;
858 node_instance->access = SNMP_NODE_INSTANCE_NOT_ACCESSIBLE;
859 node_instance->get_value =
NULL;
860 node_instance->set_test =
NULL;
861 node_instance->set_value =
NULL;
862 node_instance->release_instance =
NULL;
863 node_instance->reference.ptr =
NULL;
864 node_instance->reference_len = 0;
866 result = ((
const struct snmp_leaf_node *)(
const void *)mn)->get_next_instance(
871 if (
result == SNMP_ERR_NOERROR) {
873 if (((node_instance->access & SNMP_NODE_INSTANCE_ACCESS_READ) != 0) && (node_instance->get_value ==
NULL)) {
874 LWIP_DEBUGF(
SNMP_DEBUG, (
"SNMP inconsistent access: node is readable but no get_value function is specified\n"));
876 if (((node_instance->access & SNMP_NODE_INSTANCE_ACCESS_WRITE) != 0) && (node_instance->set_value ==
NULL)) {
877 LWIP_DEBUGF(
SNMP_DEBUG, (
"SNMP inconsistent access: node is writable but no set_value function is specified\n"));
882 if ((validate_node_instance_method ==
NULL) ||
883 (validate_node_instance_method(node_instance, validate_node_instance_arg) == SNMP_ERR_NOERROR)) {
885 snmp_oid_append(node_oid, node_instance->instance_oid.id, node_instance->instance_oid.len);
889 if (node_instance->release_instance !=
NULL) {
890 node_instance->release_instance(node_instance);
898 if (node_instance->release_instance !=
NULL) {
899 node_instance->release_instance(node_instance);
903 mn = snmp_mib_tree_resolve_next(mib, node_oid->id, node_oid->len, &node_instance->instance_oid);
906 snmp_oid_assign(node_oid, node_instance->instance_oid.id, node_instance->instance_oid.len);
907 node_instance->instance_oid.len = 0;
908 node_instance->node = mn;
921 const struct snmp_mib *intermediate_mib;
922 intermediate_mib = snmp_get_mib_between(start_oid, start_oid_len, node_oid->id, node_oid->len);
924 if (intermediate_mib !=
NULL) {
926 if (node_instance->release_instance !=
NULL) {
927 node_instance->release_instance(node_instance);
931 mib = intermediate_mib;
932 start_oid = mib->base_oid;
933 start_oid_len = mib->base_oid_len;
943 const struct snmp_mib *next_mib;
944 next_mib = snmp_get_next_mib(start_oid, start_oid_len);
947 if ((next_mib !=
NULL) && (next_mib->base_oid_len > mib->base_oid_len) &&
948 (snmp_oid_compare(next_mib->base_oid, mib->base_oid_len, mib->base_oid, mib->base_oid_len) == 0)) {
951 start_oid = mib->base_oid;
952 start_oid_len = mib->base_oid_len;
955 if (mib->base_oid_len > 1) {
956 mib = snmp_get_mib_from_oid(mib->base_oid, mib->base_oid_len - 1);
963 start_oid = mib->base_oid;
964 start_oid_len = mib->base_oid_len;
975 return SNMP_ERR_ENDOFMIBVIEW;
978 return SNMP_ERR_NOERROR;
985const struct snmp_node *
986snmp_mib_tree_resolve_exact(
const struct snmp_mib *mib,
const u32_t *oid,
u8_t oid_len,
u8_t *oid_instance_len)
988 const struct snmp_node *
const *
node = &mib->root_node;
989 u8_t oid_offset = mib->base_oid_len;
991 while ((oid_offset < oid_len) && ((*node)->node_type == SNMP_NODE_TREE)) {
993 u32_t subnode_oid = *(oid + oid_offset);
995 u32_t i = (*(
const struct snmp_tree_node *
const *)
node)->subnode_count;
996 node = (*(
const struct snmp_tree_node *
const *)
node)->subnodes;
997 while ((
i > 0) && ((*node)->oid != subnode_oid)) {
1010 if ((*node)->node_type != SNMP_NODE_TREE) {
1012 *oid_instance_len = oid_len - oid_offset;
1019const struct snmp_node *
1020snmp_mib_tree_resolve_next(
const struct snmp_mib *mib,
const u32_t *oid,
u8_t oid_len,
struct snmp_obj_id *oidret)
1022 u8_t oid_offset = mib->base_oid_len;
1023 const struct snmp_node *
const *
node;
1028 if (mib->root_node->node_type != SNMP_NODE_TREE) {
1034 node_stack[nsi] = (
const struct snmp_tree_node *)(
const void *)mib->root_node;
1035 while (oid_offset < oid_len) {
1037 u32_t i = node_stack[nsi]->subnode_count;
1038 node = node_stack[nsi]->subnodes;
1040 subnode_oid = *(oid + oid_offset);
1042 while ((
i > 0) && ((*node)->oid != subnode_oid)) {
1047 if ((
i == 0) || ((*node)->node_type != SNMP_NODE_TREE)) {
1052 node_stack[nsi] = (
const struct snmp_tree_node *)(
const void *)(*node);
1058 if (oid_offset >= oid_len) {
1062 subnode_oid = *(oid + oid_offset) + 1;
1066 const struct snmp_node *subnode =
NULL;
1069 s32_t i = node_stack[nsi]->subnode_count;
1070 node = node_stack[nsi]->subnodes;
1072 if ((*node)->oid == subnode_oid) {
1075 }
else if (((*node)->oid > subnode_oid) && ((subnode ==
NULL) || ((*node)->oid < subnode->oid))) {
1083 if (subnode ==
NULL) {
1085 subnode_oid = node_stack[nsi]->node.oid + 1;
1088 if (subnode->node_type == SNMP_NODE_TREE) {
1091 node_stack[nsi] = (
const struct snmp_tree_node *)(
const void *)subnode;
1095 snmp_oid_assign(oidret, mib->base_oid, mib->base_oid_len);
1098 oidret->id[oidret->len] = node_stack[
i]->node.oid;
1103 oidret->id[oidret->len] = subnode->oid;
1116snmp_next_oid_init(
struct snmp_next_oid_state *
state,
1117 const u32_t *start_oid,
u8_t start_oid_len,
1118 u32_t *next_oid_buf,
u8_t next_oid_max_len)
1120 state->start_oid = start_oid;
1121 state->start_oid_len = start_oid_len;
1122 state->next_oid = next_oid_buf;
1123 state->next_oid_len = 0;
1124 state->next_oid_max_len = next_oid_max_len;
1125 state->status = SNMP_NEXT_OID_STATUS_NO_MATCH;
1132snmp_next_oid_precheck(
struct snmp_next_oid_state *
state,
const u32_t *oid,
u8_t oid_len)
1134 if (
state->status != SNMP_NEXT_OID_STATUS_BUF_TO_SMALL) {
1135 u8_t start_oid_len = (oid_len <
state->start_oid_len) ? oid_len :
state->start_oid_len;
1138 if (snmp_oid_compare(oid, oid_len,
state->start_oid, start_oid_len) >= 0) {
1140 if ((
state->status == SNMP_NEXT_OID_STATUS_NO_MATCH) ||
1141 (snmp_oid_compare(oid, oid_len,
state->next_oid,
state->next_oid_len) < 0)) {
1155 if (
state->status != SNMP_NEXT_OID_STATUS_BUF_TO_SMALL) {
1157 if (snmp_oid_compare(oid, oid_len,
state->start_oid,
state->start_oid_len) > 0) {
1159 if ((
state->status == SNMP_NEXT_OID_STATUS_NO_MATCH) ||
1160 (snmp_oid_compare(oid, oid_len,
state->next_oid,
state->next_oid_len) < 0)) {
1161 if (oid_len <= state->next_oid_max_len) {
1163 state->next_oid_len = oid_len;
1164 state->status = SNMP_NEXT_OID_STATUS_SUCCESS;
1168 state->status = SNMP_NEXT_OID_STATUS_BUF_TO_SMALL;
1178snmp_oid_in_range(
const u32_t *oid_in,
u8_t oid_len,
const struct snmp_oid_range *oid_ranges,
u8_t oid_ranges_len)
1182 if (oid_len != oid_ranges_len) {
1186 for (
i = 0;
i < oid_ranges_len;
i++) {
1187 if ((oid_in[
i] < oid_ranges[
i].
min) || (oid_in[
i] > oid_ranges[
i].
max)) {
1202 return SNMP_ERR_NOERROR;
1221 u8_t bits_processed = 0;
1224 while (buf_len > 0) {
1227 if (bits_processed >= 32) {
1235 *bit_value |= (1 << bits_processed);
1239 }
while ((bits_processed & 0x07) != 0);
1241 bits_processed += 8;
1252snmp_decode_truthvalue(
const s32_t *asn1_value,
u8_t *bool_value)
1262 if ((asn1_value ==
NULL) || (bool_value ==
NULL)) {
1266 if (*asn1_value == 1) {
1268 }
else if (*asn1_value == 2) {
1294 u8_t min_bytes = (bit_count + 7) >> 3;
1296 while ((buf_len > 0) && (bit_value != 0x00)) {
1300 if (bit_value & 0x01) {
1317 if (
len < min_bytes) {
1321 while ((
len < min_bytes) && (buf_len > 0)) {
1333snmp_encode_truthvalue(
s32_t *asn1_value,
u32_t bool_value)
1343 if (asn1_value ==
NULL) {
1353 return sizeof(
s32_t);
#define LWIP_ARRAYSIZE(x)
static HINSTANCE instance
#define LWIP_DEBUGF(debug, message)
#define LWIP_ASSERT(message, assertion)
GLboolean GLboolean GLboolean b
GLenum GLuint GLenum GLsizei const GLchar * buf
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
#define LWIP_UNUSED_ARG(x)
#define SNMP_DEVICE_ENTERPRISE_OID
#define SNMP_MAX_OBJ_ID_LEN
#define SNMP_DEVICE_ENTERPRISE_OID_LEN
#define IP_SET_TYPE(ipaddr, iptype)
#define IP_IS_ANY_TYPE_VAL(ipaddr)
#define MEMCPY(DST, SRC, BYTES)
#define netif_get_index(netif)