43 #include "lwip/ip_addr.h"
52 const s32_t snmp_version = 0;
54 const char snmp_publiccommunity[7] =
"public";
59 struct udp_pcb *snmp1_pcb;
61 static void snmp_recv(
void *arg,
struct udp_pcb *pcb,
struct pbuf *p,
ip_addr_t *addr,
u16_t port);
62 static err_t snmp_pdu_header_check(
struct pbuf *p,
u16_t ofs,
u16_t pdu_len,
u16_t *ofs_ret,
struct snmp_msg_pstat *m_stat);
63 static err_t snmp_pdu_dec_varbindlist(
struct pbuf *p,
u16_t ofs,
u16_t *ofs_ret,
struct snmp_msg_pstat *m_stat);
73 struct snmp_msg_pstat *msg_ps;
76 snmp1_pcb = udp_new();
77 if (snmp1_pcb !=
NULL)
79 udp_recv(snmp1_pcb, snmp_recv, (
void *)SNMP_IN_PORT);
82 msg_ps = &msg_input_list[0];
85 msg_ps->state = SNMP_MSG_EMPTY;
86 msg_ps->error_index = 0;
87 msg_ps->error_status = SNMP_ES_NOERROR;
90 trap_msg.pcb = snmp1_pcb;
92 #ifdef SNMP_PRIVATE_MIB_INIT
97 SNMP_PRIVATE_MIB_INIT();
102 snmp_coldstart_trap();
106 snmp_error_response(
struct snmp_msg_pstat *msg_ps,
u8_t error)
108 snmp_varbind_list_free(&msg_ps->outvb);
109 msg_ps->outvb = msg_ps->invb;
110 msg_ps->invb.head =
NULL;
111 msg_ps->invb.tail =
NULL;
112 msg_ps->invb.count = 0;
113 msg_ps->error_status = error;
114 msg_ps->error_index = 1 + msg_ps->vb_idx;
115 snmp_send_response(msg_ps);
116 snmp_varbind_list_free(&msg_ps->outvb);
117 msg_ps->state = SNMP_MSG_EMPTY;
121 snmp_ok_response(
struct snmp_msg_pstat *msg_ps)
125 err_ret = snmp_send_response(msg_ps);
135 snmp_varbind_list_free(&msg_ps->invb);
136 snmp_varbind_list_free(&msg_ps->outvb);
137 msg_ps->state = SNMP_MSG_EMPTY;
147 snmp_msg_get_event(
u8_t request_id,
struct snmp_msg_pstat *msg_ps)
151 if (msg_ps->state == SNMP_MSG_EXTERNAL_GET_OBJDEF)
153 struct mib_external_node *en;
154 struct snmp_name_ptr np;
157 en = msg_ps->ext_mib_node;
158 np = msg_ps->ext_name_ptr;
161 en->get_object_def_a(request_id, np.ident_len, np.ident, &msg_ps->ext_object_def);
162 if ((msg_ps->ext_object_def.instance != MIB_OBJECT_NONE) &&
163 (msg_ps->ext_object_def.access & MIB_ACCESS_READ))
165 msg_ps->state = SNMP_MSG_EXTERNAL_GET_VALUE;
166 en->get_value_q(request_id, &msg_ps->ext_object_def);
170 en->get_object_def_pc(request_id, np.ident_len, np.ident);
172 snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME);
175 else if (msg_ps->state == SNMP_MSG_EXTERNAL_GET_VALUE)
177 struct mib_external_node *en;
178 struct snmp_varbind *vb;
181 en = msg_ps->ext_mib_node;
184 vb = (
struct snmp_varbind *)
memp_malloc(MEMP_SNMP_VARBIND);
192 vb->ident = msg_ps->vb_ptr->ident;
193 vb->ident_len = msg_ps->vb_ptr->ident_len;
195 msg_ps->vb_ptr->ident =
NULL;
196 msg_ps->vb_ptr->ident_len = 0;
198 vb->value_type = msg_ps->ext_object_def.asn_type;
199 LWIP_ASSERT(
"invalid length", msg_ps->ext_object_def.v_len <= 0xff);
200 vb->value_len = (
u8_t)msg_ps->ext_object_def.v_len;
201 if (vb->value_len > 0)
206 if (vb->value !=
NULL)
208 en->get_value_a(request_id, &msg_ps->ext_object_def, vb->value_len, vb->value);
209 snmp_varbind_tail_add(&msg_ps->outvb, vb);
211 msg_ps->state = SNMP_MSG_SEARCH_OBJ;
216 en->get_value_pc(request_id, &msg_ps->ext_object_def);
218 msg_ps->vb_ptr->ident = vb->ident;
219 msg_ps->vb_ptr->ident_len = vb->ident_len;
221 snmp_error_response(msg_ps,SNMP_ES_TOOBIG);
227 en->get_value_a(request_id, &msg_ps->ext_object_def, 0,
NULL);
229 snmp_varbind_tail_add(&msg_ps->outvb, vb);
231 msg_ps->state = SNMP_MSG_SEARCH_OBJ;
237 en->get_value_pc(request_id, &msg_ps->ext_object_def);
239 snmp_error_response(msg_ps,SNMP_ES_TOOBIG);
243 while ((msg_ps->state == SNMP_MSG_SEARCH_OBJ) &&
244 (msg_ps->vb_idx < msg_ps->invb.count))
247 struct snmp_name_ptr np;
249 if (msg_ps->vb_idx == 0)
251 msg_ps->vb_ptr = msg_ps->invb.head;
255 msg_ps->vb_ptr = msg_ps->vb_ptr->next;
258 if (snmp_iso_prefix_tst(msg_ps->vb_ptr->ident_len, msg_ps->vb_ptr->ident))
260 mn = snmp_search_tree((
struct mib_node*)&internet, msg_ps->vb_ptr->ident_len - 4,
261 msg_ps->vb_ptr->ident + 4, &np);
264 if (mn->node_type == MIB_NODE_EX)
267 struct mib_external_node *en = (
struct mib_external_node*)mn;
269 msg_ps->state = SNMP_MSG_EXTERNAL_GET_OBJDEF;
271 msg_ps->ext_mib_node = en;
272 msg_ps->ext_name_ptr = np;
274 en->get_object_def_q(en->addr_inf, request_id, np.ident_len, np.ident);
279 struct obj_def object_def;
281 msg_ps->state = SNMP_MSG_INTERNAL_GET_OBJDEF;
282 mn->get_object_def(np.ident_len, np.ident, &object_def);
283 if ((object_def.instance != MIB_OBJECT_NONE) &&
284 (object_def.access & MIB_ACCESS_READ))
295 struct snmp_varbind *vb;
297 msg_ps->state = SNMP_MSG_INTERNAL_GET_VALUE;
299 vb = (
struct snmp_varbind *)
memp_malloc(MEMP_SNMP_VARBIND);
307 vb->ident = msg_ps->vb_ptr->ident;
308 vb->ident_len = msg_ps->vb_ptr->ident_len;
310 msg_ps->vb_ptr->ident =
NULL;
311 msg_ps->vb_ptr->ident_len = 0;
313 vb->value_type = object_def.asn_type;
314 LWIP_ASSERT(
"invalid length", object_def.v_len <= 0xff);
315 vb->value_len = (
u8_t)object_def.v_len;
316 if (vb->value_len > 0)
318 LWIP_ASSERT(
"SNMP_MAX_OCTET_STRING_LEN is configured too low",
322 if (vb->value !=
NULL)
324 mn->get_value(&object_def, vb->value_len, vb->value);
325 snmp_varbind_tail_add(&msg_ps->outvb, vb);
326 msg_ps->state = SNMP_MSG_SEARCH_OBJ;
332 msg_ps->vb_ptr->ident = vb->ident;
333 msg_ps->vb_ptr->ident_len = vb->ident_len;
335 snmp_error_response(msg_ps,SNMP_ES_TOOBIG);
342 snmp_varbind_tail_add(&msg_ps->outvb, vb);
343 msg_ps->state = SNMP_MSG_SEARCH_OBJ;
350 snmp_error_response(msg_ps,SNMP_ES_TOOBIG);
363 snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME);
366 if ((msg_ps->state == SNMP_MSG_SEARCH_OBJ) &&
367 (msg_ps->vb_idx == msg_ps->invb.count))
369 snmp_ok_response(msg_ps);
380 snmp_msg_getnext_event(
u8_t request_id,
struct snmp_msg_pstat *msg_ps)
384 if (msg_ps->state == SNMP_MSG_EXTERNAL_GET_OBJDEF)
386 struct mib_external_node *en;
389 en = msg_ps->ext_mib_node;
392 en->get_object_def_a(request_id, 1, &msg_ps->ext_oid.id[msg_ps->ext_oid.len - 1], &msg_ps->ext_object_def);
393 if (msg_ps->ext_object_def.instance != MIB_OBJECT_NONE)
395 msg_ps->state = SNMP_MSG_EXTERNAL_GET_VALUE;
396 en->get_value_q(request_id, &msg_ps->ext_object_def);
400 en->get_object_def_pc(request_id, 1, &msg_ps->ext_oid.id[msg_ps->ext_oid.len - 1]);
402 snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME);
405 else if (msg_ps->state == SNMP_MSG_EXTERNAL_GET_VALUE)
407 struct mib_external_node *en;
408 struct snmp_varbind *vb;
411 en = msg_ps->ext_mib_node;
413 LWIP_ASSERT(
"invalid length", msg_ps->ext_object_def.v_len <= 0xff);
414 vb = snmp_varbind_alloc(&msg_ps->ext_oid,
415 msg_ps->ext_object_def.asn_type,
416 (
u8_t)msg_ps->ext_object_def.v_len);
419 en->get_value_a(request_id, &msg_ps->ext_object_def, vb->value_len, vb->value);
420 snmp_varbind_tail_add(&msg_ps->outvb, vb);
421 msg_ps->state = SNMP_MSG_SEARCH_OBJ;
426 en->get_value_pc(request_id, &msg_ps->ext_object_def);
428 snmp_error_response(msg_ps,SNMP_ES_TOOBIG);
432 while ((msg_ps->state == SNMP_MSG_SEARCH_OBJ) &&
433 (msg_ps->vb_idx < msg_ps->invb.count))
436 struct snmp_obj_id oid;
438 if (msg_ps->vb_idx == 0)
440 msg_ps->vb_ptr = msg_ps->invb.head;
444 msg_ps->vb_ptr = msg_ps->vb_ptr->next;
446 if (snmp_iso_prefix_expand(msg_ps->vb_ptr->ident_len, msg_ps->vb_ptr->ident, &oid))
448 if (msg_ps->vb_ptr->ident_len > 3)
451 mn = snmp_expand_tree((
struct mib_node*)&internet,
452 msg_ps->vb_ptr->ident_len - 4,
453 msg_ps->vb_ptr->ident + 4, &oid);
458 mn = snmp_expand_tree((
struct mib_node*)&internet, 0,
NULL, &oid);
467 if (mn->node_type == MIB_NODE_EX)
470 struct mib_external_node *en = (
struct mib_external_node*)mn;
472 msg_ps->state = SNMP_MSG_EXTERNAL_GET_OBJDEF;
474 msg_ps->ext_mib_node = en;
475 msg_ps->ext_oid = oid;
477 en->get_object_def_q(en->addr_inf, request_id, 1, &oid.id[oid.len - 1]);
482 struct obj_def object_def;
483 struct snmp_varbind *vb;
485 msg_ps->state = SNMP_MSG_INTERNAL_GET_OBJDEF;
486 mn->get_object_def(1, &oid.id[oid.len - 1], &object_def);
488 LWIP_ASSERT(
"invalid length", object_def.v_len <= 0xff);
489 vb = snmp_varbind_alloc(&oid, object_def.asn_type, (
u8_t)object_def.v_len);
492 msg_ps->state = SNMP_MSG_INTERNAL_GET_VALUE;
493 mn->get_value(&object_def, object_def.v_len, vb->value);
494 snmp_varbind_tail_add(&msg_ps->outvb, vb);
495 msg_ps->state = SNMP_MSG_SEARCH_OBJ;
501 snmp_error_response(msg_ps,SNMP_ES_TOOBIG);
508 snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME);
511 if ((msg_ps->state == SNMP_MSG_SEARCH_OBJ) &&
512 (msg_ps->vb_idx == msg_ps->invb.count))
514 snmp_ok_response(msg_ps);
525 snmp_msg_set_event(
u8_t request_id,
struct snmp_msg_pstat *msg_ps)
529 if (msg_ps->state == SNMP_MSG_EXTERNAL_GET_OBJDEF)
531 struct mib_external_node *en;
532 struct snmp_name_ptr np;
535 en = msg_ps->ext_mib_node;
536 np = msg_ps->ext_name_ptr;
539 en->get_object_def_a(request_id, np.ident_len, np.ident, &msg_ps->ext_object_def);
540 if (msg_ps->ext_object_def.instance != MIB_OBJECT_NONE)
542 msg_ps->state = SNMP_MSG_EXTERNAL_SET_TEST;
543 en->set_test_q(request_id, &msg_ps->ext_object_def);
547 en->get_object_def_pc(request_id, np.ident_len, np.ident);
549 snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME);
552 else if (msg_ps->state == SNMP_MSG_EXTERNAL_SET_TEST)
554 struct mib_external_node *en;
557 en = msg_ps->ext_mib_node;
559 if (msg_ps->ext_object_def.access & MIB_ACCESS_WRITE)
561 if ((msg_ps->ext_object_def.asn_type == msg_ps->vb_ptr->value_type) &&
562 (en->set_test_a(request_id,&msg_ps->ext_object_def,
563 msg_ps->vb_ptr->value_len,msg_ps->vb_ptr->value) != 0))
565 msg_ps->state = SNMP_MSG_SEARCH_OBJ;
570 en->set_test_pc(request_id,&msg_ps->ext_object_def);
572 snmp_error_response(msg_ps,SNMP_ES_BADVALUE);
577 en->set_test_pc(request_id,&msg_ps->ext_object_def);
579 snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME);
582 else if (msg_ps->state == SNMP_MSG_EXTERNAL_GET_OBJDEF_S)
584 struct mib_external_node *en;
585 struct snmp_name_ptr np;
588 en = msg_ps->ext_mib_node;
589 np = msg_ps->ext_name_ptr;
592 en->get_object_def_a(request_id, np.ident_len, np.ident, &msg_ps->ext_object_def);
593 if (msg_ps->ext_object_def.instance != MIB_OBJECT_NONE)
595 msg_ps->state = SNMP_MSG_EXTERNAL_SET_VALUE;
596 en->set_value_q(request_id, &msg_ps->ext_object_def,
597 msg_ps->vb_ptr->value_len,msg_ps->vb_ptr->value);
601 en->get_object_def_pc(request_id, np.ident_len, np.ident);
603 snmp_error_response(msg_ps,SNMP_ES_GENERROR);
606 else if (msg_ps->state == SNMP_MSG_EXTERNAL_SET_VALUE)
608 struct mib_external_node *en;
611 en = msg_ps->ext_mib_node;
612 en->set_value_a(request_id, &msg_ps->ext_object_def,
613 msg_ps->vb_ptr->value_len, msg_ps->vb_ptr->value);
616 msg_ps->state = SNMP_MSG_INTERNAL_SET_VALUE;
621 while ((msg_ps->state == SNMP_MSG_SEARCH_OBJ) &&
622 (msg_ps->vb_idx < msg_ps->invb.count))
625 struct snmp_name_ptr np;
627 if (msg_ps->vb_idx == 0)
629 msg_ps->vb_ptr = msg_ps->invb.head;
633 msg_ps->vb_ptr = msg_ps->vb_ptr->next;
636 if (snmp_iso_prefix_tst(msg_ps->vb_ptr->ident_len, msg_ps->vb_ptr->ident))
638 mn = snmp_search_tree((
struct mib_node*)&internet, msg_ps->vb_ptr->ident_len - 4,
639 msg_ps->vb_ptr->ident + 4, &np);
642 if (mn->node_type == MIB_NODE_EX)
645 struct mib_external_node *en = (
struct mib_external_node*)mn;
647 msg_ps->state = SNMP_MSG_EXTERNAL_GET_OBJDEF;
649 msg_ps->ext_mib_node = en;
650 msg_ps->ext_name_ptr = np;
652 en->get_object_def_q(en->addr_inf, request_id, np.ident_len, np.ident);
657 struct obj_def object_def;
659 msg_ps->state = SNMP_MSG_INTERNAL_GET_OBJDEF;
660 mn->get_object_def(np.ident_len, np.ident, &object_def);
661 if (object_def.instance != MIB_OBJECT_NONE)
672 msg_ps->state = SNMP_MSG_INTERNAL_SET_TEST;
674 if (object_def.access & MIB_ACCESS_WRITE)
676 if ((object_def.asn_type == msg_ps->vb_ptr->value_type) &&
677 (mn->set_test(&object_def,msg_ps->vb_ptr->value_len,msg_ps->vb_ptr->value) != 0))
679 msg_ps->state = SNMP_MSG_SEARCH_OBJ;
685 snmp_error_response(msg_ps,SNMP_ES_BADVALUE);
691 snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME);
704 snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME);
708 if ((msg_ps->state == SNMP_MSG_SEARCH_OBJ) &&
709 (msg_ps->vb_idx == msg_ps->invb.count))
712 msg_ps->state = SNMP_MSG_INTERNAL_SET_VALUE;
716 while ((msg_ps->state == SNMP_MSG_INTERNAL_SET_VALUE) &&
717 (msg_ps->vb_idx < msg_ps->invb.count))
720 struct snmp_name_ptr np;
722 if (msg_ps->vb_idx == 0)
724 msg_ps->vb_ptr = msg_ps->invb.head;
728 msg_ps->vb_ptr = msg_ps->vb_ptr->next;
731 mn = snmp_search_tree((
struct mib_node*)&internet, msg_ps->vb_ptr->ident_len - 4,
732 msg_ps->vb_ptr->ident + 4, &np);
737 if (mn->node_type == MIB_NODE_EX)
740 struct mib_external_node *en = (
struct mib_external_node*)mn;
742 msg_ps->state = SNMP_MSG_EXTERNAL_GET_OBJDEF_S;
744 msg_ps->ext_mib_node = en;
745 msg_ps->ext_name_ptr = np;
747 en->get_object_def_q(en->addr_inf, request_id, np.ident_len, np.ident);
752 struct obj_def object_def;
754 msg_ps->state = SNMP_MSG_INTERNAL_GET_OBJDEF_S;
755 mn->get_object_def(np.ident_len, np.ident, &object_def);
756 msg_ps->state = SNMP_MSG_INTERNAL_SET_VALUE;
757 mn->set_value(&object_def,msg_ps->vb_ptr->value_len,msg_ps->vb_ptr->value);
762 if ((msg_ps->state == SNMP_MSG_INTERNAL_SET_VALUE) &&
763 (msg_ps->vb_idx == msg_ps->invb.count))
768 msg_ps->outvb = msg_ps->invb;
769 msg_ps->invb.head =
NULL;
770 msg_ps->invb.tail =
NULL;
771 msg_ps->invb.count = 0;
772 snmp_ok_response(msg_ps);
784 snmp_msg_event(
u8_t request_id)
786 struct snmp_msg_pstat *msg_ps;
790 msg_ps = &msg_input_list[request_id];
791 if (msg_ps->rt == SNMP_ASN1_PDU_GET_NEXT_REQ)
793 snmp_msg_getnext_event(request_id, msg_ps);
795 else if (msg_ps->rt == SNMP_ASN1_PDU_GET_REQ)
797 snmp_msg_get_event(request_id, msg_ps);
799 else if(msg_ps->rt == SNMP_ASN1_PDU_SET_REQ)
801 snmp_msg_set_event(request_id, msg_ps);
809 snmp_recv(
void *arg,
struct udp_pcb *pcb,
struct pbuf *p,
ip_addr_t *addr,
u16_t port)
811 struct snmp_msg_pstat *msg_ps;
815 u16_t payload_ofs = 0;
816 u16_t varbind_ofs = 0;
822 msg_ps = &msg_input_list[0];
846 err_ret = snmp_pdu_header_check(p, payload_ofs, payload_len, &varbind_ofs, msg_ps);
849 if ((err_ret !=
ERR_OK) ||
850 ((msg_ps->rt != SNMP_ASN1_PDU_GET_REQ) &&
851 (msg_ps->rt != SNMP_ASN1_PDU_GET_NEXT_REQ) &&
852 (msg_ps->rt != SNMP_ASN1_PDU_SET_REQ)) ||
853 ((msg_ps->error_status != SNMP_ES_NOERROR) ||
854 (msg_ps->error_index != 0)) )
865 err_ret = snmp_pdu_dec_varbindlist(p, varbind_ofs, &varbind_ofs, msg_ps);
868 if ((err_ret !=
ERR_OK) || (msg_ps->invb.count == 0))
877 msg_ps->error_status = SNMP_ES_NOERROR;
878 msg_ps->error_index = 0;
880 msg_ps->state = SNMP_MSG_SEARCH_OBJ;
887 snmp_msg_event(req_idx);
903 snmp_pdu_header_check(
struct pbuf *p,
u16_t ofs,
u16_t pdu_len,
u16_t *ofs_ret,
struct snmp_msg_pstat *m_stat)
912 snmp_asn1_dec_type(p, ofs, &type);
913 derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len);
915 (pdu_len != (1 + len_octets + len)) ||
916 (type != (SNMP_ASN1_UNIV | SNMP_ASN1_CONSTR | SNMP_ASN1_SEQ)))
921 ofs += (1 + len_octets);
922 snmp_asn1_dec_type(p, ofs, &type);
923 derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len);
924 if ((derr !=
ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG)))
930 derr = snmp_asn1_dec_s32t(p, ofs + 1 + len_octets, len, &version);
943 ofs += (1 + len_octets + len);
944 snmp_asn1_dec_type(p, ofs, &type);
945 derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len);
946 if ((derr !=
ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR)))
952 derr = snmp_asn1_dec_raw(p, ofs + 1 + len_octets, len, SNMP_COMMUNITY_STR_LEN, m_stat->community);
959 len = ((len < (SNMP_COMMUNITY_STR_LEN))?(len):(SNMP_COMMUNITY_STR_LEN));
960 m_stat->community[len] = 0;
961 m_stat->com_strlen = (
u8_t)len;
962 if (strncmp(snmp_publiccommunity, (
const char*)m_stat->community, SNMP_COMMUNITY_STR_LEN) != 0)
966 snmp_authfail_trap();
969 ofs += (1 + len_octets + len);
970 snmp_asn1_dec_type(p, ofs, &type);
971 derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len);
979 case (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_GET_REQ):
984 case (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_GET_NEXT_REQ):
989 case (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_GET_RESP):
994 case (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_SET_REQ):
999 case (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_TRAP):
1014 m_stat->rt = type & 0x1F;
1015 ofs += (1 + len_octets);
1016 if (len != (pdu_len - (ofs - ofs_base)))
1022 snmp_asn1_dec_type(p, ofs, &type);
1023 derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len);
1024 if ((derr !=
ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG)))
1030 derr = snmp_asn1_dec_s32t(p, ofs + 1 + len_octets, len, &m_stat->rid);
1037 ofs += (1 + len_octets + len);
1038 snmp_asn1_dec_type(p, ofs, &type);
1039 derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len);
1040 if ((derr !=
ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG)))
1048 derr = snmp_asn1_dec_s32t(p, ofs + 1 + len_octets, len, &m_stat->error_status);
1055 switch (m_stat->error_status)
1057 case SNMP_ES_TOOBIG:
1060 case SNMP_ES_NOSUCHNAME:
1063 case SNMP_ES_BADVALUE:
1066 case SNMP_ES_READONLY:
1069 case SNMP_ES_GENERROR:
1073 ofs += (1 + len_octets + len);
1074 snmp_asn1_dec_type(p, ofs, &type);
1075 derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len);
1076 if ((derr !=
ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG)))
1084 derr = snmp_asn1_dec_s32t(p, ofs + 1 + len_octets, len, &m_stat->error_index);
1091 ofs += (1 + len_octets + len);
1097 snmp_pdu_dec_varbindlist(
struct pbuf *p,
u16_t ofs,
u16_t *ofs_ret,
struct snmp_msg_pstat *m_stat)
1105 snmp_asn1_dec_type(p, ofs, &type);
1106 derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &vb_len);
1108 (type != (SNMP_ASN1_UNIV | SNMP_ASN1_CONSTR | SNMP_ASN1_SEQ)))
1113 ofs += (1 + len_octets);
1116 m_stat->invb.count = 0;
1117 m_stat->invb.head =
NULL;
1118 m_stat->invb.tail =
NULL;
1122 struct snmp_obj_id oid, oid_value;
1123 struct snmp_varbind *vb;
1125 snmp_asn1_dec_type(p, ofs, &type);
1126 derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len);
1128 (type != (SNMP_ASN1_UNIV | SNMP_ASN1_CONSTR | SNMP_ASN1_SEQ)) ||
1129 (len == 0) || (len > vb_len))
1133 snmp_varbind_list_free(&m_stat->invb);
1136 ofs += (1 + len_octets);
1137 vb_len -= (1 + len_octets);
1139 snmp_asn1_dec_type(p, ofs, &type);
1140 derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len);
1141 if ((derr !=
ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID)))
1146 snmp_varbind_list_free(&m_stat->invb);
1149 derr = snmp_asn1_dec_oid(p, ofs + 1 + len_octets, len, &oid);
1155 snmp_varbind_list_free(&m_stat->invb);
1158 ofs += (1 + len_octets + len);
1159 vb_len -= (1 + len_octets + len);
1161 snmp_asn1_dec_type(p, ofs, &type);
1162 derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len);
1168 snmp_varbind_list_free(&m_stat->invb);
1174 case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG):
1175 vb = snmp_varbind_alloc(&oid, type,
sizeof(
s32_t));
1180 derr = snmp_asn1_dec_s32t(p, ofs + 1 + len_octets, len, vptr);
1181 snmp_varbind_tail_add(&m_stat->invb, vb);
1188 case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER):
1189 case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_GAUGE):
1190 case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_TIMETICKS):
1191 vb = snmp_varbind_alloc(&oid, type,
sizeof(
u32_t));
1196 derr = snmp_asn1_dec_u32t(p, ofs + 1 + len_octets, len, vptr);
1197 snmp_varbind_tail_add(&m_stat->invb, vb);
1204 case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR):
1205 case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_OPAQUE):
1207 vb = snmp_varbind_alloc(&oid, type, (
u8_t)len);
1210 derr = snmp_asn1_dec_raw(p, ofs + 1 + len_octets, len, vb->value_len, (
u8_t*)vb->value);
1211 snmp_varbind_tail_add(&m_stat->invb, vb);
1218 case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_NUL):
1219 vb = snmp_varbind_alloc(&oid, type, 0);
1222 snmp_varbind_tail_add(&m_stat->invb, vb);
1230 case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID):
1231 derr = snmp_asn1_dec_oid(p, ofs + 1 + len_octets, len, &oid_value);
1234 vb = snmp_varbind_alloc(&oid, type, oid_value.len *
sizeof(
s32_t));
1237 u8_t i = oid_value.len;
1243 vptr[i] = oid_value.id[i];
1245 snmp_varbind_tail_add(&m_stat->invb, vb);
1254 case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR):
1258 vb = snmp_varbind_alloc(&oid, type, 4);
1261 derr = snmp_asn1_dec_raw(p, ofs + 1 + len_octets, len, vb->value_len, (
u8_t*)vb->value);
1262 snmp_varbind_tail_add(&m_stat->invb, vb);
1282 snmp_varbind_list_free(&m_stat->invb);
1285 ofs += (1 + len_octets + len);
1286 vb_len -= (1 + len_octets + len);
1289 if (m_stat->rt == SNMP_ASN1_PDU_SET_REQ)
1302 struct snmp_varbind*
1303 snmp_varbind_alloc(
struct snmp_obj_id *oid,
u8_t type,
u8_t len)
1305 struct snmp_varbind *vb;
1307 vb = (
struct snmp_varbind *)
memp_malloc(MEMP_SNMP_VARBIND);
1323 if (vb->ident ==
NULL)
1331 vb->ident[i] = oid->id[i];
1339 vb->value_type = type;
1340 vb->value_len = len;
1347 if (vb->value ==
NULL)
1349 if (vb->ident !=
NULL)
1367 snmp_varbind_free(
struct snmp_varbind *vb)
1369 if (vb->value !=
NULL )
1373 if (vb->ident !=
NULL )
1381 snmp_varbind_list_free(
struct snmp_varbind_root *root)
1383 struct snmp_varbind *vb, *prev;
1386 while ( vb !=
NULL )
1389 snmp_varbind_free(vb);
1398 snmp_varbind_tail_add(
struct snmp_varbind_root *root,
struct snmp_varbind *vb)
1400 if (root->count == 0)
1409 root->tail->next = vb;
1410 vb->prev = root->tail;
1416 struct snmp_varbind*
1417 snmp_varbind_tail_remove(
struct snmp_varbind_root *root)
1419 struct snmp_varbind* vb;
1421 if (root->count > 0)
1425 root->tail = vb->prev;
1426 vb->prev->next =
NULL;