Official mbed lwIP library (version 1.4.0)

Dependents:   LwIPNetworking NetServicesMin EthernetInterface EthernetInterface_RSF ... more

Legacy Networking Libraries

This is an mbed 2 networking library. For mbed OS 5, lwip has been integrated with built-in networking interfaces. The networking libraries have been revised to better support additional network stacks and thread safety here.

This library is based on the code of lwIP v1.4.0

Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
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. The name of the author may not be used to endorse or promote products
   derived from this software without specific prior written permission. 

THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
Committer:
mbed_official
Date:
Mon Mar 14 16:15:36 2016 +0000
Revision:
20:08f08bfc3f3d
Parent:
0:51ac1d130fd4
Synchronized with git revision fec574a5ed6db26aca1b13992ff271bf527d4a0d

Full URL: https://github.com/mbedmicro/mbed/commit/fec574a5ed6db26aca1b13992ff271bf527d4a0d/

Increased allocated netbufs to handle DTLS handshakes

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 0:51ac1d130fd4 1 /**
mbed_official 0:51ac1d130fd4 2 * @file
mbed_official 0:51ac1d130fd4 3 * SNMP input message processing (RFC1157).
mbed_official 0:51ac1d130fd4 4 */
mbed_official 0:51ac1d130fd4 5
mbed_official 0:51ac1d130fd4 6 /*
mbed_official 0:51ac1d130fd4 7 * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands.
mbed_official 0:51ac1d130fd4 8 * All rights reserved.
mbed_official 0:51ac1d130fd4 9 *
mbed_official 0:51ac1d130fd4 10 * Redistribution and use in source and binary forms, with or without modification,
mbed_official 0:51ac1d130fd4 11 * are permitted provided that the following conditions are met:
mbed_official 0:51ac1d130fd4 12 *
mbed_official 0:51ac1d130fd4 13 * 1. Redistributions of source code must retain the above copyright notice,
mbed_official 0:51ac1d130fd4 14 * this list of conditions and the following disclaimer.
mbed_official 0:51ac1d130fd4 15 * 2. Redistributions in binary form must reproduce the above copyright notice,
mbed_official 0:51ac1d130fd4 16 * this list of conditions and the following disclaimer in the documentation
mbed_official 0:51ac1d130fd4 17 * and/or other materials provided with the distribution.
mbed_official 0:51ac1d130fd4 18 * 3. The name of the author may not be used to endorse or promote products
mbed_official 0:51ac1d130fd4 19 * derived from this software without specific prior written permission.
mbed_official 0:51ac1d130fd4 20 *
mbed_official 0:51ac1d130fd4 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
mbed_official 0:51ac1d130fd4 22 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
mbed_official 0:51ac1d130fd4 23 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
mbed_official 0:51ac1d130fd4 24 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
mbed_official 0:51ac1d130fd4 25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
mbed_official 0:51ac1d130fd4 26 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
mbed_official 0:51ac1d130fd4 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
mbed_official 0:51ac1d130fd4 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
mbed_official 0:51ac1d130fd4 29 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
mbed_official 0:51ac1d130fd4 30 * OF SUCH DAMAGE.
mbed_official 0:51ac1d130fd4 31 *
mbed_official 0:51ac1d130fd4 32 * Author: Christiaan Simons <christiaan.simons@axon.tv>
mbed_official 0:51ac1d130fd4 33 */
mbed_official 0:51ac1d130fd4 34
mbed_official 0:51ac1d130fd4 35 #include "lwip/opt.h"
mbed_official 0:51ac1d130fd4 36
mbed_official 0:51ac1d130fd4 37 #if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */
mbed_official 0:51ac1d130fd4 38
mbed_official 0:51ac1d130fd4 39 #include "lwip/snmp.h"
mbed_official 0:51ac1d130fd4 40 #include "lwip/snmp_asn1.h"
mbed_official 0:51ac1d130fd4 41 #include "lwip/snmp_msg.h"
mbed_official 0:51ac1d130fd4 42 #include "lwip/snmp_structs.h"
mbed_official 0:51ac1d130fd4 43 #include "lwip/ip_addr.h"
mbed_official 0:51ac1d130fd4 44 #include "lwip/memp.h"
mbed_official 0:51ac1d130fd4 45 #include "lwip/udp.h"
mbed_official 0:51ac1d130fd4 46 #include "lwip/stats.h"
mbed_official 0:51ac1d130fd4 47
mbed_official 0:51ac1d130fd4 48 #include <string.h>
mbed_official 0:51ac1d130fd4 49
mbed_official 0:51ac1d130fd4 50 /* public (non-static) constants */
mbed_official 0:51ac1d130fd4 51 /** SNMP v1 == 0 */
mbed_official 0:51ac1d130fd4 52 const s32_t snmp_version = 0;
mbed_official 0:51ac1d130fd4 53 /** default SNMP community string */
mbed_official 0:51ac1d130fd4 54 const char snmp_publiccommunity[7] = "public";
mbed_official 0:51ac1d130fd4 55
mbed_official 0:51ac1d130fd4 56 /* statically allocated buffers for SNMP_CONCURRENT_REQUESTS */
mbed_official 0:51ac1d130fd4 57 struct snmp_msg_pstat msg_input_list[SNMP_CONCURRENT_REQUESTS];
mbed_official 0:51ac1d130fd4 58 /* UDP Protocol Control Block */
mbed_official 0:51ac1d130fd4 59 struct udp_pcb *snmp1_pcb;
mbed_official 0:51ac1d130fd4 60
mbed_official 0:51ac1d130fd4 61 static void snmp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *addr, u16_t port);
mbed_official 0:51ac1d130fd4 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);
mbed_official 0:51ac1d130fd4 63 static err_t snmp_pdu_dec_varbindlist(struct pbuf *p, u16_t ofs, u16_t *ofs_ret, struct snmp_msg_pstat *m_stat);
mbed_official 0:51ac1d130fd4 64
mbed_official 0:51ac1d130fd4 65
mbed_official 0:51ac1d130fd4 66 /**
mbed_official 0:51ac1d130fd4 67 * Starts SNMP Agent.
mbed_official 0:51ac1d130fd4 68 * Allocates UDP pcb and binds it to IP_ADDR_ANY port 161.
mbed_official 0:51ac1d130fd4 69 */
mbed_official 0:51ac1d130fd4 70 void
mbed_official 0:51ac1d130fd4 71 snmp_init(void)
mbed_official 0:51ac1d130fd4 72 {
mbed_official 0:51ac1d130fd4 73 struct snmp_msg_pstat *msg_ps;
mbed_official 0:51ac1d130fd4 74 u8_t i;
mbed_official 0:51ac1d130fd4 75
mbed_official 0:51ac1d130fd4 76 snmp1_pcb = udp_new();
mbed_official 0:51ac1d130fd4 77 if (snmp1_pcb != NULL)
mbed_official 0:51ac1d130fd4 78 {
mbed_official 0:51ac1d130fd4 79 udp_recv(snmp1_pcb, snmp_recv, (void *)SNMP_IN_PORT);
mbed_official 0:51ac1d130fd4 80 udp_bind(snmp1_pcb, IP_ADDR_ANY, SNMP_IN_PORT);
mbed_official 0:51ac1d130fd4 81 }
mbed_official 0:51ac1d130fd4 82 msg_ps = &msg_input_list[0];
mbed_official 0:51ac1d130fd4 83 for (i=0; i<SNMP_CONCURRENT_REQUESTS; i++)
mbed_official 0:51ac1d130fd4 84 {
mbed_official 0:51ac1d130fd4 85 msg_ps->state = SNMP_MSG_EMPTY;
mbed_official 0:51ac1d130fd4 86 msg_ps->error_index = 0;
mbed_official 0:51ac1d130fd4 87 msg_ps->error_status = SNMP_ES_NOERROR;
mbed_official 0:51ac1d130fd4 88 msg_ps++;
mbed_official 0:51ac1d130fd4 89 }
mbed_official 0:51ac1d130fd4 90 trap_msg.pcb = snmp1_pcb;
mbed_official 0:51ac1d130fd4 91
mbed_official 0:51ac1d130fd4 92 #ifdef SNMP_PRIVATE_MIB_INIT
mbed_official 0:51ac1d130fd4 93 /* If defined, rhis must be a function-like define to initialize the
mbed_official 0:51ac1d130fd4 94 * private MIB after the stack has been initialized.
mbed_official 0:51ac1d130fd4 95 * The private MIB can also be initialized in tcpip_callback (or after
mbed_official 0:51ac1d130fd4 96 * the stack is initialized), this define is only for convenience. */
mbed_official 0:51ac1d130fd4 97 SNMP_PRIVATE_MIB_INIT();
mbed_official 0:51ac1d130fd4 98 #endif /* SNMP_PRIVATE_MIB_INIT */
mbed_official 0:51ac1d130fd4 99
mbed_official 0:51ac1d130fd4 100 /* The coldstart trap will only be output
mbed_official 0:51ac1d130fd4 101 if our outgoing interface is up & configured */
mbed_official 0:51ac1d130fd4 102 snmp_coldstart_trap();
mbed_official 0:51ac1d130fd4 103 }
mbed_official 0:51ac1d130fd4 104
mbed_official 0:51ac1d130fd4 105 static void
mbed_official 0:51ac1d130fd4 106 snmp_error_response(struct snmp_msg_pstat *msg_ps, u8_t error)
mbed_official 0:51ac1d130fd4 107 {
mbed_official 0:51ac1d130fd4 108 snmp_varbind_list_free(&msg_ps->outvb);
mbed_official 0:51ac1d130fd4 109 msg_ps->outvb = msg_ps->invb;
mbed_official 0:51ac1d130fd4 110 msg_ps->invb.head = NULL;
mbed_official 0:51ac1d130fd4 111 msg_ps->invb.tail = NULL;
mbed_official 0:51ac1d130fd4 112 msg_ps->invb.count = 0;
mbed_official 0:51ac1d130fd4 113 msg_ps->error_status = error;
mbed_official 0:51ac1d130fd4 114 msg_ps->error_index = 1 + msg_ps->vb_idx;
mbed_official 0:51ac1d130fd4 115 snmp_send_response(msg_ps);
mbed_official 0:51ac1d130fd4 116 snmp_varbind_list_free(&msg_ps->outvb);
mbed_official 0:51ac1d130fd4 117 msg_ps->state = SNMP_MSG_EMPTY;
mbed_official 0:51ac1d130fd4 118 }
mbed_official 0:51ac1d130fd4 119
mbed_official 0:51ac1d130fd4 120 static void
mbed_official 0:51ac1d130fd4 121 snmp_ok_response(struct snmp_msg_pstat *msg_ps)
mbed_official 0:51ac1d130fd4 122 {
mbed_official 0:51ac1d130fd4 123 err_t err_ret;
mbed_official 0:51ac1d130fd4 124
mbed_official 0:51ac1d130fd4 125 err_ret = snmp_send_response(msg_ps);
mbed_official 0:51ac1d130fd4 126 if (err_ret == ERR_MEM)
mbed_official 0:51ac1d130fd4 127 {
mbed_official 0:51ac1d130fd4 128 /* serious memory problem, can't return tooBig */
mbed_official 0:51ac1d130fd4 129 }
mbed_official 0:51ac1d130fd4 130 else
mbed_official 0:51ac1d130fd4 131 {
mbed_official 0:51ac1d130fd4 132 LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_event = %"S32_F"\n",msg_ps->error_status));
mbed_official 0:51ac1d130fd4 133 }
mbed_official 0:51ac1d130fd4 134 /* free varbinds (if available) */
mbed_official 0:51ac1d130fd4 135 snmp_varbind_list_free(&msg_ps->invb);
mbed_official 0:51ac1d130fd4 136 snmp_varbind_list_free(&msg_ps->outvb);
mbed_official 0:51ac1d130fd4 137 msg_ps->state = SNMP_MSG_EMPTY;
mbed_official 0:51ac1d130fd4 138 }
mbed_official 0:51ac1d130fd4 139
mbed_official 0:51ac1d130fd4 140 /**
mbed_official 0:51ac1d130fd4 141 * Service an internal or external event for SNMP GET.
mbed_official 0:51ac1d130fd4 142 *
mbed_official 0:51ac1d130fd4 143 * @param request_id identifies requests from 0 to (SNMP_CONCURRENT_REQUESTS-1)
mbed_official 0:51ac1d130fd4 144 * @param msg_ps points to the assosicated message process state
mbed_official 0:51ac1d130fd4 145 */
mbed_official 0:51ac1d130fd4 146 static void
mbed_official 0:51ac1d130fd4 147 snmp_msg_get_event(u8_t request_id, struct snmp_msg_pstat *msg_ps)
mbed_official 0:51ac1d130fd4 148 {
mbed_official 0:51ac1d130fd4 149 LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_get_event: msg_ps->state==%"U16_F"\n",(u16_t)msg_ps->state));
mbed_official 0:51ac1d130fd4 150
mbed_official 0:51ac1d130fd4 151 if (msg_ps->state == SNMP_MSG_EXTERNAL_GET_OBJDEF)
mbed_official 0:51ac1d130fd4 152 {
mbed_official 0:51ac1d130fd4 153 struct mib_external_node *en;
mbed_official 0:51ac1d130fd4 154 struct snmp_name_ptr np;
mbed_official 0:51ac1d130fd4 155
mbed_official 0:51ac1d130fd4 156 /* get_object_def() answer*/
mbed_official 0:51ac1d130fd4 157 en = msg_ps->ext_mib_node;
mbed_official 0:51ac1d130fd4 158 np = msg_ps->ext_name_ptr;
mbed_official 0:51ac1d130fd4 159
mbed_official 0:51ac1d130fd4 160 /* translate answer into a known lifeform */
mbed_official 0:51ac1d130fd4 161 en->get_object_def_a(request_id, np.ident_len, np.ident, &msg_ps->ext_object_def);
mbed_official 0:51ac1d130fd4 162 if ((msg_ps->ext_object_def.instance != MIB_OBJECT_NONE) &&
mbed_official 0:51ac1d130fd4 163 (msg_ps->ext_object_def.access & MIB_ACCESS_READ))
mbed_official 0:51ac1d130fd4 164 {
mbed_official 0:51ac1d130fd4 165 msg_ps->state = SNMP_MSG_EXTERNAL_GET_VALUE;
mbed_official 0:51ac1d130fd4 166 en->get_value_q(request_id, &msg_ps->ext_object_def);
mbed_official 0:51ac1d130fd4 167 }
mbed_official 0:51ac1d130fd4 168 else
mbed_official 0:51ac1d130fd4 169 {
mbed_official 0:51ac1d130fd4 170 en->get_object_def_pc(request_id, np.ident_len, np.ident);
mbed_official 0:51ac1d130fd4 171 /* search failed, object id points to unknown object (nosuchname) */
mbed_official 0:51ac1d130fd4 172 snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME);
mbed_official 0:51ac1d130fd4 173 }
mbed_official 0:51ac1d130fd4 174 }
mbed_official 0:51ac1d130fd4 175 else if (msg_ps->state == SNMP_MSG_EXTERNAL_GET_VALUE)
mbed_official 0:51ac1d130fd4 176 {
mbed_official 0:51ac1d130fd4 177 struct mib_external_node *en;
mbed_official 0:51ac1d130fd4 178 struct snmp_varbind *vb;
mbed_official 0:51ac1d130fd4 179
mbed_official 0:51ac1d130fd4 180 /* get_value() answer */
mbed_official 0:51ac1d130fd4 181 en = msg_ps->ext_mib_node;
mbed_official 0:51ac1d130fd4 182
mbed_official 0:51ac1d130fd4 183 /* allocate output varbind */
mbed_official 0:51ac1d130fd4 184 vb = (struct snmp_varbind *)memp_malloc(MEMP_SNMP_VARBIND);
mbed_official 0:51ac1d130fd4 185 LWIP_ASSERT("vb != NULL",vb != NULL);
mbed_official 0:51ac1d130fd4 186 if (vb != NULL)
mbed_official 0:51ac1d130fd4 187 {
mbed_official 0:51ac1d130fd4 188 vb->next = NULL;
mbed_official 0:51ac1d130fd4 189 vb->prev = NULL;
mbed_official 0:51ac1d130fd4 190
mbed_official 0:51ac1d130fd4 191 /* move name from invb to outvb */
mbed_official 0:51ac1d130fd4 192 vb->ident = msg_ps->vb_ptr->ident;
mbed_official 0:51ac1d130fd4 193 vb->ident_len = msg_ps->vb_ptr->ident_len;
mbed_official 0:51ac1d130fd4 194 /* ensure this memory is refereced once only */
mbed_official 0:51ac1d130fd4 195 msg_ps->vb_ptr->ident = NULL;
mbed_official 0:51ac1d130fd4 196 msg_ps->vb_ptr->ident_len = 0;
mbed_official 0:51ac1d130fd4 197
mbed_official 0:51ac1d130fd4 198 vb->value_type = msg_ps->ext_object_def.asn_type;
mbed_official 0:51ac1d130fd4 199 LWIP_ASSERT("invalid length", msg_ps->ext_object_def.v_len <= 0xff);
mbed_official 0:51ac1d130fd4 200 vb->value_len = (u8_t)msg_ps->ext_object_def.v_len;
mbed_official 0:51ac1d130fd4 201 if (vb->value_len > 0)
mbed_official 0:51ac1d130fd4 202 {
mbed_official 0:51ac1d130fd4 203 LWIP_ASSERT("SNMP_MAX_OCTET_STRING_LEN is configured too low", vb->value_len <= SNMP_MAX_VALUE_SIZE);
mbed_official 0:51ac1d130fd4 204 vb->value = memp_malloc(MEMP_SNMP_VALUE);
mbed_official 0:51ac1d130fd4 205 LWIP_ASSERT("vb->value != NULL",vb->value != NULL);
mbed_official 0:51ac1d130fd4 206 if (vb->value != NULL)
mbed_official 0:51ac1d130fd4 207 {
mbed_official 0:51ac1d130fd4 208 en->get_value_a(request_id, &msg_ps->ext_object_def, vb->value_len, vb->value);
mbed_official 0:51ac1d130fd4 209 snmp_varbind_tail_add(&msg_ps->outvb, vb);
mbed_official 0:51ac1d130fd4 210 /* search again (if vb_idx < msg_ps->invb.count) */
mbed_official 0:51ac1d130fd4 211 msg_ps->state = SNMP_MSG_SEARCH_OBJ;
mbed_official 0:51ac1d130fd4 212 msg_ps->vb_idx += 1;
mbed_official 0:51ac1d130fd4 213 }
mbed_official 0:51ac1d130fd4 214 else
mbed_official 0:51ac1d130fd4 215 {
mbed_official 0:51ac1d130fd4 216 en->get_value_pc(request_id, &msg_ps->ext_object_def);
mbed_official 0:51ac1d130fd4 217 LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_event: no variable space\n"));
mbed_official 0:51ac1d130fd4 218 msg_ps->vb_ptr->ident = vb->ident;
mbed_official 0:51ac1d130fd4 219 msg_ps->vb_ptr->ident_len = vb->ident_len;
mbed_official 0:51ac1d130fd4 220 memp_free(MEMP_SNMP_VARBIND, vb);
mbed_official 0:51ac1d130fd4 221 snmp_error_response(msg_ps,SNMP_ES_TOOBIG);
mbed_official 0:51ac1d130fd4 222 }
mbed_official 0:51ac1d130fd4 223 }
mbed_official 0:51ac1d130fd4 224 else
mbed_official 0:51ac1d130fd4 225 {
mbed_official 0:51ac1d130fd4 226 /* vb->value_len == 0, empty value (e.g. empty string) */
mbed_official 0:51ac1d130fd4 227 en->get_value_a(request_id, &msg_ps->ext_object_def, 0, NULL);
mbed_official 0:51ac1d130fd4 228 vb->value = NULL;
mbed_official 0:51ac1d130fd4 229 snmp_varbind_tail_add(&msg_ps->outvb, vb);
mbed_official 0:51ac1d130fd4 230 /* search again (if vb_idx < msg_ps->invb.count) */
mbed_official 0:51ac1d130fd4 231 msg_ps->state = SNMP_MSG_SEARCH_OBJ;
mbed_official 0:51ac1d130fd4 232 msg_ps->vb_idx += 1;
mbed_official 0:51ac1d130fd4 233 }
mbed_official 0:51ac1d130fd4 234 }
mbed_official 0:51ac1d130fd4 235 else
mbed_official 0:51ac1d130fd4 236 {
mbed_official 0:51ac1d130fd4 237 en->get_value_pc(request_id, &msg_ps->ext_object_def);
mbed_official 0:51ac1d130fd4 238 LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_event: no outvb space\n"));
mbed_official 0:51ac1d130fd4 239 snmp_error_response(msg_ps,SNMP_ES_TOOBIG);
mbed_official 0:51ac1d130fd4 240 }
mbed_official 0:51ac1d130fd4 241 }
mbed_official 0:51ac1d130fd4 242
mbed_official 0:51ac1d130fd4 243 while ((msg_ps->state == SNMP_MSG_SEARCH_OBJ) &&
mbed_official 0:51ac1d130fd4 244 (msg_ps->vb_idx < msg_ps->invb.count))
mbed_official 0:51ac1d130fd4 245 {
mbed_official 0:51ac1d130fd4 246 struct mib_node *mn;
mbed_official 0:51ac1d130fd4 247 struct snmp_name_ptr np;
mbed_official 0:51ac1d130fd4 248
mbed_official 0:51ac1d130fd4 249 if (msg_ps->vb_idx == 0)
mbed_official 0:51ac1d130fd4 250 {
mbed_official 0:51ac1d130fd4 251 msg_ps->vb_ptr = msg_ps->invb.head;
mbed_official 0:51ac1d130fd4 252 }
mbed_official 0:51ac1d130fd4 253 else
mbed_official 0:51ac1d130fd4 254 {
mbed_official 0:51ac1d130fd4 255 msg_ps->vb_ptr = msg_ps->vb_ptr->next;
mbed_official 0:51ac1d130fd4 256 }
mbed_official 0:51ac1d130fd4 257 /** test object identifier for .iso.org.dod.internet prefix */
mbed_official 0:51ac1d130fd4 258 if (snmp_iso_prefix_tst(msg_ps->vb_ptr->ident_len, msg_ps->vb_ptr->ident))
mbed_official 0:51ac1d130fd4 259 {
mbed_official 0:51ac1d130fd4 260 mn = snmp_search_tree((struct mib_node*)&internet, msg_ps->vb_ptr->ident_len - 4,
mbed_official 0:51ac1d130fd4 261 msg_ps->vb_ptr->ident + 4, &np);
mbed_official 0:51ac1d130fd4 262 if (mn != NULL)
mbed_official 0:51ac1d130fd4 263 {
mbed_official 0:51ac1d130fd4 264 if (mn->node_type == MIB_NODE_EX)
mbed_official 0:51ac1d130fd4 265 {
mbed_official 0:51ac1d130fd4 266 /* external object */
mbed_official 0:51ac1d130fd4 267 struct mib_external_node *en = (struct mib_external_node*)mn;
mbed_official 0:51ac1d130fd4 268
mbed_official 0:51ac1d130fd4 269 msg_ps->state = SNMP_MSG_EXTERNAL_GET_OBJDEF;
mbed_official 0:51ac1d130fd4 270 /* save en && args in msg_ps!! */
mbed_official 0:51ac1d130fd4 271 msg_ps->ext_mib_node = en;
mbed_official 0:51ac1d130fd4 272 msg_ps->ext_name_ptr = np;
mbed_official 0:51ac1d130fd4 273
mbed_official 0:51ac1d130fd4 274 en->get_object_def_q(en->addr_inf, request_id, np.ident_len, np.ident);
mbed_official 0:51ac1d130fd4 275 }
mbed_official 0:51ac1d130fd4 276 else
mbed_official 0:51ac1d130fd4 277 {
mbed_official 0:51ac1d130fd4 278 /* internal object */
mbed_official 0:51ac1d130fd4 279 struct obj_def object_def;
mbed_official 0:51ac1d130fd4 280
mbed_official 0:51ac1d130fd4 281 msg_ps->state = SNMP_MSG_INTERNAL_GET_OBJDEF;
mbed_official 0:51ac1d130fd4 282 mn->get_object_def(np.ident_len, np.ident, &object_def);
mbed_official 0:51ac1d130fd4 283 if ((object_def.instance != MIB_OBJECT_NONE) &&
mbed_official 0:51ac1d130fd4 284 (object_def.access & MIB_ACCESS_READ))
mbed_official 0:51ac1d130fd4 285 {
mbed_official 0:51ac1d130fd4 286 mn = mn;
mbed_official 0:51ac1d130fd4 287 }
mbed_official 0:51ac1d130fd4 288 else
mbed_official 0:51ac1d130fd4 289 {
mbed_official 0:51ac1d130fd4 290 /* search failed, object id points to unknown object (nosuchname) */
mbed_official 0:51ac1d130fd4 291 mn = NULL;
mbed_official 0:51ac1d130fd4 292 }
mbed_official 0:51ac1d130fd4 293 if (mn != NULL)
mbed_official 0:51ac1d130fd4 294 {
mbed_official 0:51ac1d130fd4 295 struct snmp_varbind *vb;
mbed_official 0:51ac1d130fd4 296
mbed_official 0:51ac1d130fd4 297 msg_ps->state = SNMP_MSG_INTERNAL_GET_VALUE;
mbed_official 0:51ac1d130fd4 298 /* allocate output varbind */
mbed_official 0:51ac1d130fd4 299 vb = (struct snmp_varbind *)memp_malloc(MEMP_SNMP_VARBIND);
mbed_official 0:51ac1d130fd4 300 LWIP_ASSERT("vb != NULL",vb != NULL);
mbed_official 0:51ac1d130fd4 301 if (vb != NULL)
mbed_official 0:51ac1d130fd4 302 {
mbed_official 0:51ac1d130fd4 303 vb->next = NULL;
mbed_official 0:51ac1d130fd4 304 vb->prev = NULL;
mbed_official 0:51ac1d130fd4 305
mbed_official 0:51ac1d130fd4 306 /* move name from invb to outvb */
mbed_official 0:51ac1d130fd4 307 vb->ident = msg_ps->vb_ptr->ident;
mbed_official 0:51ac1d130fd4 308 vb->ident_len = msg_ps->vb_ptr->ident_len;
mbed_official 0:51ac1d130fd4 309 /* ensure this memory is refereced once only */
mbed_official 0:51ac1d130fd4 310 msg_ps->vb_ptr->ident = NULL;
mbed_official 0:51ac1d130fd4 311 msg_ps->vb_ptr->ident_len = 0;
mbed_official 0:51ac1d130fd4 312
mbed_official 0:51ac1d130fd4 313 vb->value_type = object_def.asn_type;
mbed_official 0:51ac1d130fd4 314 LWIP_ASSERT("invalid length", object_def.v_len <= 0xff);
mbed_official 0:51ac1d130fd4 315 vb->value_len = (u8_t)object_def.v_len;
mbed_official 0:51ac1d130fd4 316 if (vb->value_len > 0)
mbed_official 0:51ac1d130fd4 317 {
mbed_official 0:51ac1d130fd4 318 LWIP_ASSERT("SNMP_MAX_OCTET_STRING_LEN is configured too low",
mbed_official 0:51ac1d130fd4 319 vb->value_len <= SNMP_MAX_VALUE_SIZE);
mbed_official 0:51ac1d130fd4 320 vb->value = memp_malloc(MEMP_SNMP_VALUE);
mbed_official 0:51ac1d130fd4 321 LWIP_ASSERT("vb->value != NULL",vb->value != NULL);
mbed_official 0:51ac1d130fd4 322 if (vb->value != NULL)
mbed_official 0:51ac1d130fd4 323 {
mbed_official 0:51ac1d130fd4 324 mn->get_value(&object_def, vb->value_len, vb->value);
mbed_official 0:51ac1d130fd4 325 snmp_varbind_tail_add(&msg_ps->outvb, vb);
mbed_official 0:51ac1d130fd4 326 msg_ps->state = SNMP_MSG_SEARCH_OBJ;
mbed_official 0:51ac1d130fd4 327 msg_ps->vb_idx += 1;
mbed_official 0:51ac1d130fd4 328 }
mbed_official 0:51ac1d130fd4 329 else
mbed_official 0:51ac1d130fd4 330 {
mbed_official 0:51ac1d130fd4 331 LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_event: couldn't allocate variable space\n"));
mbed_official 0:51ac1d130fd4 332 msg_ps->vb_ptr->ident = vb->ident;
mbed_official 0:51ac1d130fd4 333 msg_ps->vb_ptr->ident_len = vb->ident_len;
mbed_official 0:51ac1d130fd4 334 memp_free(MEMP_SNMP_VARBIND, vb);
mbed_official 0:51ac1d130fd4 335 snmp_error_response(msg_ps,SNMP_ES_TOOBIG);
mbed_official 0:51ac1d130fd4 336 }
mbed_official 0:51ac1d130fd4 337 }
mbed_official 0:51ac1d130fd4 338 else
mbed_official 0:51ac1d130fd4 339 {
mbed_official 0:51ac1d130fd4 340 /* vb->value_len == 0, empty value (e.g. empty string) */
mbed_official 0:51ac1d130fd4 341 vb->value = NULL;
mbed_official 0:51ac1d130fd4 342 snmp_varbind_tail_add(&msg_ps->outvb, vb);
mbed_official 0:51ac1d130fd4 343 msg_ps->state = SNMP_MSG_SEARCH_OBJ;
mbed_official 0:51ac1d130fd4 344 msg_ps->vb_idx += 1;
mbed_official 0:51ac1d130fd4 345 }
mbed_official 0:51ac1d130fd4 346 }
mbed_official 0:51ac1d130fd4 347 else
mbed_official 0:51ac1d130fd4 348 {
mbed_official 0:51ac1d130fd4 349 LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_event: couldn't allocate outvb space\n"));
mbed_official 0:51ac1d130fd4 350 snmp_error_response(msg_ps,SNMP_ES_TOOBIG);
mbed_official 0:51ac1d130fd4 351 }
mbed_official 0:51ac1d130fd4 352 }
mbed_official 0:51ac1d130fd4 353 }
mbed_official 0:51ac1d130fd4 354 }
mbed_official 0:51ac1d130fd4 355 }
mbed_official 0:51ac1d130fd4 356 else
mbed_official 0:51ac1d130fd4 357 {
mbed_official 0:51ac1d130fd4 358 mn = NULL;
mbed_official 0:51ac1d130fd4 359 }
mbed_official 0:51ac1d130fd4 360 if (mn == NULL)
mbed_official 0:51ac1d130fd4 361 {
mbed_official 0:51ac1d130fd4 362 /* mn == NULL, noSuchName */
mbed_official 0:51ac1d130fd4 363 snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME);
mbed_official 0:51ac1d130fd4 364 }
mbed_official 0:51ac1d130fd4 365 }
mbed_official 0:51ac1d130fd4 366 if ((msg_ps->state == SNMP_MSG_SEARCH_OBJ) &&
mbed_official 0:51ac1d130fd4 367 (msg_ps->vb_idx == msg_ps->invb.count))
mbed_official 0:51ac1d130fd4 368 {
mbed_official 0:51ac1d130fd4 369 snmp_ok_response(msg_ps);
mbed_official 0:51ac1d130fd4 370 }
mbed_official 0:51ac1d130fd4 371 }
mbed_official 0:51ac1d130fd4 372
mbed_official 0:51ac1d130fd4 373 /**
mbed_official 0:51ac1d130fd4 374 * Service an internal or external event for SNMP GETNEXT.
mbed_official 0:51ac1d130fd4 375 *
mbed_official 0:51ac1d130fd4 376 * @param request_id identifies requests from 0 to (SNMP_CONCURRENT_REQUESTS-1)
mbed_official 0:51ac1d130fd4 377 * @param msg_ps points to the assosicated message process state
mbed_official 0:51ac1d130fd4 378 */
mbed_official 0:51ac1d130fd4 379 static void
mbed_official 0:51ac1d130fd4 380 snmp_msg_getnext_event(u8_t request_id, struct snmp_msg_pstat *msg_ps)
mbed_official 0:51ac1d130fd4 381 {
mbed_official 0:51ac1d130fd4 382 LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_getnext_event: msg_ps->state==%"U16_F"\n",(u16_t)msg_ps->state));
mbed_official 0:51ac1d130fd4 383
mbed_official 0:51ac1d130fd4 384 if (msg_ps->state == SNMP_MSG_EXTERNAL_GET_OBJDEF)
mbed_official 0:51ac1d130fd4 385 {
mbed_official 0:51ac1d130fd4 386 struct mib_external_node *en;
mbed_official 0:51ac1d130fd4 387
mbed_official 0:51ac1d130fd4 388 /* get_object_def() answer*/
mbed_official 0:51ac1d130fd4 389 en = msg_ps->ext_mib_node;
mbed_official 0:51ac1d130fd4 390
mbed_official 0:51ac1d130fd4 391 /* translate answer into a known lifeform */
mbed_official 0:51ac1d130fd4 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);
mbed_official 0:51ac1d130fd4 393 if (msg_ps->ext_object_def.instance != MIB_OBJECT_NONE)
mbed_official 0:51ac1d130fd4 394 {
mbed_official 0:51ac1d130fd4 395 msg_ps->state = SNMP_MSG_EXTERNAL_GET_VALUE;
mbed_official 0:51ac1d130fd4 396 en->get_value_q(request_id, &msg_ps->ext_object_def);
mbed_official 0:51ac1d130fd4 397 }
mbed_official 0:51ac1d130fd4 398 else
mbed_official 0:51ac1d130fd4 399 {
mbed_official 0:51ac1d130fd4 400 en->get_object_def_pc(request_id, 1, &msg_ps->ext_oid.id[msg_ps->ext_oid.len - 1]);
mbed_official 0:51ac1d130fd4 401 /* search failed, object id points to unknown object (nosuchname) */
mbed_official 0:51ac1d130fd4 402 snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME);
mbed_official 0:51ac1d130fd4 403 }
mbed_official 0:51ac1d130fd4 404 }
mbed_official 0:51ac1d130fd4 405 else if (msg_ps->state == SNMP_MSG_EXTERNAL_GET_VALUE)
mbed_official 0:51ac1d130fd4 406 {
mbed_official 0:51ac1d130fd4 407 struct mib_external_node *en;
mbed_official 0:51ac1d130fd4 408 struct snmp_varbind *vb;
mbed_official 0:51ac1d130fd4 409
mbed_official 0:51ac1d130fd4 410 /* get_value() answer */
mbed_official 0:51ac1d130fd4 411 en = msg_ps->ext_mib_node;
mbed_official 0:51ac1d130fd4 412
mbed_official 0:51ac1d130fd4 413 LWIP_ASSERT("invalid length", msg_ps->ext_object_def.v_len <= 0xff);
mbed_official 0:51ac1d130fd4 414 vb = snmp_varbind_alloc(&msg_ps->ext_oid,
mbed_official 0:51ac1d130fd4 415 msg_ps->ext_object_def.asn_type,
mbed_official 0:51ac1d130fd4 416 (u8_t)msg_ps->ext_object_def.v_len);
mbed_official 0:51ac1d130fd4 417 if (vb != NULL)
mbed_official 0:51ac1d130fd4 418 {
mbed_official 0:51ac1d130fd4 419 en->get_value_a(request_id, &msg_ps->ext_object_def, vb->value_len, vb->value);
mbed_official 0:51ac1d130fd4 420 snmp_varbind_tail_add(&msg_ps->outvb, vb);
mbed_official 0:51ac1d130fd4 421 msg_ps->state = SNMP_MSG_SEARCH_OBJ;
mbed_official 0:51ac1d130fd4 422 msg_ps->vb_idx += 1;
mbed_official 0:51ac1d130fd4 423 }
mbed_official 0:51ac1d130fd4 424 else
mbed_official 0:51ac1d130fd4 425 {
mbed_official 0:51ac1d130fd4 426 en->get_value_pc(request_id, &msg_ps->ext_object_def);
mbed_official 0:51ac1d130fd4 427 LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_getnext_event: couldn't allocate outvb space\n"));
mbed_official 0:51ac1d130fd4 428 snmp_error_response(msg_ps,SNMP_ES_TOOBIG);
mbed_official 0:51ac1d130fd4 429 }
mbed_official 0:51ac1d130fd4 430 }
mbed_official 0:51ac1d130fd4 431
mbed_official 0:51ac1d130fd4 432 while ((msg_ps->state == SNMP_MSG_SEARCH_OBJ) &&
mbed_official 0:51ac1d130fd4 433 (msg_ps->vb_idx < msg_ps->invb.count))
mbed_official 0:51ac1d130fd4 434 {
mbed_official 0:51ac1d130fd4 435 struct mib_node *mn;
mbed_official 0:51ac1d130fd4 436 struct snmp_obj_id oid;
mbed_official 0:51ac1d130fd4 437
mbed_official 0:51ac1d130fd4 438 if (msg_ps->vb_idx == 0)
mbed_official 0:51ac1d130fd4 439 {
mbed_official 0:51ac1d130fd4 440 msg_ps->vb_ptr = msg_ps->invb.head;
mbed_official 0:51ac1d130fd4 441 }
mbed_official 0:51ac1d130fd4 442 else
mbed_official 0:51ac1d130fd4 443 {
mbed_official 0:51ac1d130fd4 444 msg_ps->vb_ptr = msg_ps->vb_ptr->next;
mbed_official 0:51ac1d130fd4 445 }
mbed_official 0:51ac1d130fd4 446 if (snmp_iso_prefix_expand(msg_ps->vb_ptr->ident_len, msg_ps->vb_ptr->ident, &oid))
mbed_official 0:51ac1d130fd4 447 {
mbed_official 0:51ac1d130fd4 448 if (msg_ps->vb_ptr->ident_len > 3)
mbed_official 0:51ac1d130fd4 449 {
mbed_official 0:51ac1d130fd4 450 /* can offset ident_len and ident */
mbed_official 0:51ac1d130fd4 451 mn = snmp_expand_tree((struct mib_node*)&internet,
mbed_official 0:51ac1d130fd4 452 msg_ps->vb_ptr->ident_len - 4,
mbed_official 0:51ac1d130fd4 453 msg_ps->vb_ptr->ident + 4, &oid);
mbed_official 0:51ac1d130fd4 454 }
mbed_official 0:51ac1d130fd4 455 else
mbed_official 0:51ac1d130fd4 456 {
mbed_official 0:51ac1d130fd4 457 /* can't offset ident_len -4, ident + 4 */
mbed_official 0:51ac1d130fd4 458 mn = snmp_expand_tree((struct mib_node*)&internet, 0, NULL, &oid);
mbed_official 0:51ac1d130fd4 459 }
mbed_official 0:51ac1d130fd4 460 }
mbed_official 0:51ac1d130fd4 461 else
mbed_official 0:51ac1d130fd4 462 {
mbed_official 0:51ac1d130fd4 463 mn = NULL;
mbed_official 0:51ac1d130fd4 464 }
mbed_official 0:51ac1d130fd4 465 if (mn != NULL)
mbed_official 0:51ac1d130fd4 466 {
mbed_official 0:51ac1d130fd4 467 if (mn->node_type == MIB_NODE_EX)
mbed_official 0:51ac1d130fd4 468 {
mbed_official 0:51ac1d130fd4 469 /* external object */
mbed_official 0:51ac1d130fd4 470 struct mib_external_node *en = (struct mib_external_node*)mn;
mbed_official 0:51ac1d130fd4 471
mbed_official 0:51ac1d130fd4 472 msg_ps->state = SNMP_MSG_EXTERNAL_GET_OBJDEF;
mbed_official 0:51ac1d130fd4 473 /* save en && args in msg_ps!! */
mbed_official 0:51ac1d130fd4 474 msg_ps->ext_mib_node = en;
mbed_official 0:51ac1d130fd4 475 msg_ps->ext_oid = oid;
mbed_official 0:51ac1d130fd4 476
mbed_official 0:51ac1d130fd4 477 en->get_object_def_q(en->addr_inf, request_id, 1, &oid.id[oid.len - 1]);
mbed_official 0:51ac1d130fd4 478 }
mbed_official 0:51ac1d130fd4 479 else
mbed_official 0:51ac1d130fd4 480 {
mbed_official 0:51ac1d130fd4 481 /* internal object */
mbed_official 0:51ac1d130fd4 482 struct obj_def object_def;
mbed_official 0:51ac1d130fd4 483 struct snmp_varbind *vb;
mbed_official 0:51ac1d130fd4 484
mbed_official 0:51ac1d130fd4 485 msg_ps->state = SNMP_MSG_INTERNAL_GET_OBJDEF;
mbed_official 0:51ac1d130fd4 486 mn->get_object_def(1, &oid.id[oid.len - 1], &object_def);
mbed_official 0:51ac1d130fd4 487
mbed_official 0:51ac1d130fd4 488 LWIP_ASSERT("invalid length", object_def.v_len <= 0xff);
mbed_official 0:51ac1d130fd4 489 vb = snmp_varbind_alloc(&oid, object_def.asn_type, (u8_t)object_def.v_len);
mbed_official 0:51ac1d130fd4 490 if (vb != NULL)
mbed_official 0:51ac1d130fd4 491 {
mbed_official 0:51ac1d130fd4 492 msg_ps->state = SNMP_MSG_INTERNAL_GET_VALUE;
mbed_official 0:51ac1d130fd4 493 mn->get_value(&object_def, object_def.v_len, vb->value);
mbed_official 0:51ac1d130fd4 494 snmp_varbind_tail_add(&msg_ps->outvb, vb);
mbed_official 0:51ac1d130fd4 495 msg_ps->state = SNMP_MSG_SEARCH_OBJ;
mbed_official 0:51ac1d130fd4 496 msg_ps->vb_idx += 1;
mbed_official 0:51ac1d130fd4 497 }
mbed_official 0:51ac1d130fd4 498 else
mbed_official 0:51ac1d130fd4 499 {
mbed_official 0:51ac1d130fd4 500 LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_recv couldn't allocate outvb space\n"));
mbed_official 0:51ac1d130fd4 501 snmp_error_response(msg_ps,SNMP_ES_TOOBIG);
mbed_official 0:51ac1d130fd4 502 }
mbed_official 0:51ac1d130fd4 503 }
mbed_official 0:51ac1d130fd4 504 }
mbed_official 0:51ac1d130fd4 505 if (mn == NULL)
mbed_official 0:51ac1d130fd4 506 {
mbed_official 0:51ac1d130fd4 507 /* mn == NULL, noSuchName */
mbed_official 0:51ac1d130fd4 508 snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME);
mbed_official 0:51ac1d130fd4 509 }
mbed_official 0:51ac1d130fd4 510 }
mbed_official 0:51ac1d130fd4 511 if ((msg_ps->state == SNMP_MSG_SEARCH_OBJ) &&
mbed_official 0:51ac1d130fd4 512 (msg_ps->vb_idx == msg_ps->invb.count))
mbed_official 0:51ac1d130fd4 513 {
mbed_official 0:51ac1d130fd4 514 snmp_ok_response(msg_ps);
mbed_official 0:51ac1d130fd4 515 }
mbed_official 0:51ac1d130fd4 516 }
mbed_official 0:51ac1d130fd4 517
mbed_official 0:51ac1d130fd4 518 /**
mbed_official 0:51ac1d130fd4 519 * Service an internal or external event for SNMP SET.
mbed_official 0:51ac1d130fd4 520 *
mbed_official 0:51ac1d130fd4 521 * @param request_id identifies requests from 0 to (SNMP_CONCURRENT_REQUESTS-1)
mbed_official 0:51ac1d130fd4 522 * @param msg_ps points to the assosicated message process state
mbed_official 0:51ac1d130fd4 523 */
mbed_official 0:51ac1d130fd4 524 static void
mbed_official 0:51ac1d130fd4 525 snmp_msg_set_event(u8_t request_id, struct snmp_msg_pstat *msg_ps)
mbed_official 0:51ac1d130fd4 526 {
mbed_official 0:51ac1d130fd4 527 LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_set_event: msg_ps->state==%"U16_F"\n",(u16_t)msg_ps->state));
mbed_official 0:51ac1d130fd4 528
mbed_official 0:51ac1d130fd4 529 if (msg_ps->state == SNMP_MSG_EXTERNAL_GET_OBJDEF)
mbed_official 0:51ac1d130fd4 530 {
mbed_official 0:51ac1d130fd4 531 struct mib_external_node *en;
mbed_official 0:51ac1d130fd4 532 struct snmp_name_ptr np;
mbed_official 0:51ac1d130fd4 533
mbed_official 0:51ac1d130fd4 534 /* get_object_def() answer*/
mbed_official 0:51ac1d130fd4 535 en = msg_ps->ext_mib_node;
mbed_official 0:51ac1d130fd4 536 np = msg_ps->ext_name_ptr;
mbed_official 0:51ac1d130fd4 537
mbed_official 0:51ac1d130fd4 538 /* translate answer into a known lifeform */
mbed_official 0:51ac1d130fd4 539 en->get_object_def_a(request_id, np.ident_len, np.ident, &msg_ps->ext_object_def);
mbed_official 0:51ac1d130fd4 540 if (msg_ps->ext_object_def.instance != MIB_OBJECT_NONE)
mbed_official 0:51ac1d130fd4 541 {
mbed_official 0:51ac1d130fd4 542 msg_ps->state = SNMP_MSG_EXTERNAL_SET_TEST;
mbed_official 0:51ac1d130fd4 543 en->set_test_q(request_id, &msg_ps->ext_object_def);
mbed_official 0:51ac1d130fd4 544 }
mbed_official 0:51ac1d130fd4 545 else
mbed_official 0:51ac1d130fd4 546 {
mbed_official 0:51ac1d130fd4 547 en->get_object_def_pc(request_id, np.ident_len, np.ident);
mbed_official 0:51ac1d130fd4 548 /* search failed, object id points to unknown object (nosuchname) */
mbed_official 0:51ac1d130fd4 549 snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME);
mbed_official 0:51ac1d130fd4 550 }
mbed_official 0:51ac1d130fd4 551 }
mbed_official 0:51ac1d130fd4 552 else if (msg_ps->state == SNMP_MSG_EXTERNAL_SET_TEST)
mbed_official 0:51ac1d130fd4 553 {
mbed_official 0:51ac1d130fd4 554 struct mib_external_node *en;
mbed_official 0:51ac1d130fd4 555
mbed_official 0:51ac1d130fd4 556 /* set_test() answer*/
mbed_official 0:51ac1d130fd4 557 en = msg_ps->ext_mib_node;
mbed_official 0:51ac1d130fd4 558
mbed_official 0:51ac1d130fd4 559 if (msg_ps->ext_object_def.access & MIB_ACCESS_WRITE)
mbed_official 0:51ac1d130fd4 560 {
mbed_official 0:51ac1d130fd4 561 if ((msg_ps->ext_object_def.asn_type == msg_ps->vb_ptr->value_type) &&
mbed_official 0:51ac1d130fd4 562 (en->set_test_a(request_id,&msg_ps->ext_object_def,
mbed_official 0:51ac1d130fd4 563 msg_ps->vb_ptr->value_len,msg_ps->vb_ptr->value) != 0))
mbed_official 0:51ac1d130fd4 564 {
mbed_official 0:51ac1d130fd4 565 msg_ps->state = SNMP_MSG_SEARCH_OBJ;
mbed_official 0:51ac1d130fd4 566 msg_ps->vb_idx += 1;
mbed_official 0:51ac1d130fd4 567 }
mbed_official 0:51ac1d130fd4 568 else
mbed_official 0:51ac1d130fd4 569 {
mbed_official 0:51ac1d130fd4 570 en->set_test_pc(request_id,&msg_ps->ext_object_def);
mbed_official 0:51ac1d130fd4 571 /* bad value */
mbed_official 0:51ac1d130fd4 572 snmp_error_response(msg_ps,SNMP_ES_BADVALUE);
mbed_official 0:51ac1d130fd4 573 }
mbed_official 0:51ac1d130fd4 574 }
mbed_official 0:51ac1d130fd4 575 else
mbed_official 0:51ac1d130fd4 576 {
mbed_official 0:51ac1d130fd4 577 en->set_test_pc(request_id,&msg_ps->ext_object_def);
mbed_official 0:51ac1d130fd4 578 /* object not available for set */
mbed_official 0:51ac1d130fd4 579 snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME);
mbed_official 0:51ac1d130fd4 580 }
mbed_official 0:51ac1d130fd4 581 }
mbed_official 0:51ac1d130fd4 582 else if (msg_ps->state == SNMP_MSG_EXTERNAL_GET_OBJDEF_S)
mbed_official 0:51ac1d130fd4 583 {
mbed_official 0:51ac1d130fd4 584 struct mib_external_node *en;
mbed_official 0:51ac1d130fd4 585 struct snmp_name_ptr np;
mbed_official 0:51ac1d130fd4 586
mbed_official 0:51ac1d130fd4 587 /* get_object_def() answer*/
mbed_official 0:51ac1d130fd4 588 en = msg_ps->ext_mib_node;
mbed_official 0:51ac1d130fd4 589 np = msg_ps->ext_name_ptr;
mbed_official 0:51ac1d130fd4 590
mbed_official 0:51ac1d130fd4 591 /* translate answer into a known lifeform */
mbed_official 0:51ac1d130fd4 592 en->get_object_def_a(request_id, np.ident_len, np.ident, &msg_ps->ext_object_def);
mbed_official 0:51ac1d130fd4 593 if (msg_ps->ext_object_def.instance != MIB_OBJECT_NONE)
mbed_official 0:51ac1d130fd4 594 {
mbed_official 0:51ac1d130fd4 595 msg_ps->state = SNMP_MSG_EXTERNAL_SET_VALUE;
mbed_official 0:51ac1d130fd4 596 en->set_value_q(request_id, &msg_ps->ext_object_def,
mbed_official 0:51ac1d130fd4 597 msg_ps->vb_ptr->value_len,msg_ps->vb_ptr->value);
mbed_official 0:51ac1d130fd4 598 }
mbed_official 0:51ac1d130fd4 599 else
mbed_official 0:51ac1d130fd4 600 {
mbed_official 0:51ac1d130fd4 601 en->get_object_def_pc(request_id, np.ident_len, np.ident);
mbed_official 0:51ac1d130fd4 602 /* set_value failed, object has disappeared for some odd reason?? */
mbed_official 0:51ac1d130fd4 603 snmp_error_response(msg_ps,SNMP_ES_GENERROR);
mbed_official 0:51ac1d130fd4 604 }
mbed_official 0:51ac1d130fd4 605 }
mbed_official 0:51ac1d130fd4 606 else if (msg_ps->state == SNMP_MSG_EXTERNAL_SET_VALUE)
mbed_official 0:51ac1d130fd4 607 {
mbed_official 0:51ac1d130fd4 608 struct mib_external_node *en;
mbed_official 0:51ac1d130fd4 609
mbed_official 0:51ac1d130fd4 610 /** set_value_a() */
mbed_official 0:51ac1d130fd4 611 en = msg_ps->ext_mib_node;
mbed_official 0:51ac1d130fd4 612 en->set_value_a(request_id, &msg_ps->ext_object_def,
mbed_official 0:51ac1d130fd4 613 msg_ps->vb_ptr->value_len, msg_ps->vb_ptr->value);
mbed_official 0:51ac1d130fd4 614
mbed_official 0:51ac1d130fd4 615 /** @todo use set_value_pc() if toobig */
mbed_official 0:51ac1d130fd4 616 msg_ps->state = SNMP_MSG_INTERNAL_SET_VALUE;
mbed_official 0:51ac1d130fd4 617 msg_ps->vb_idx += 1;
mbed_official 0:51ac1d130fd4 618 }
mbed_official 0:51ac1d130fd4 619
mbed_official 0:51ac1d130fd4 620 /* test all values before setting */
mbed_official 0:51ac1d130fd4 621 while ((msg_ps->state == SNMP_MSG_SEARCH_OBJ) &&
mbed_official 0:51ac1d130fd4 622 (msg_ps->vb_idx < msg_ps->invb.count))
mbed_official 0:51ac1d130fd4 623 {
mbed_official 0:51ac1d130fd4 624 struct mib_node *mn;
mbed_official 0:51ac1d130fd4 625 struct snmp_name_ptr np;
mbed_official 0:51ac1d130fd4 626
mbed_official 0:51ac1d130fd4 627 if (msg_ps->vb_idx == 0)
mbed_official 0:51ac1d130fd4 628 {
mbed_official 0:51ac1d130fd4 629 msg_ps->vb_ptr = msg_ps->invb.head;
mbed_official 0:51ac1d130fd4 630 }
mbed_official 0:51ac1d130fd4 631 else
mbed_official 0:51ac1d130fd4 632 {
mbed_official 0:51ac1d130fd4 633 msg_ps->vb_ptr = msg_ps->vb_ptr->next;
mbed_official 0:51ac1d130fd4 634 }
mbed_official 0:51ac1d130fd4 635 /** test object identifier for .iso.org.dod.internet prefix */
mbed_official 0:51ac1d130fd4 636 if (snmp_iso_prefix_tst(msg_ps->vb_ptr->ident_len, msg_ps->vb_ptr->ident))
mbed_official 0:51ac1d130fd4 637 {
mbed_official 0:51ac1d130fd4 638 mn = snmp_search_tree((struct mib_node*)&internet, msg_ps->vb_ptr->ident_len - 4,
mbed_official 0:51ac1d130fd4 639 msg_ps->vb_ptr->ident + 4, &np);
mbed_official 0:51ac1d130fd4 640 if (mn != NULL)
mbed_official 0:51ac1d130fd4 641 {
mbed_official 0:51ac1d130fd4 642 if (mn->node_type == MIB_NODE_EX)
mbed_official 0:51ac1d130fd4 643 {
mbed_official 0:51ac1d130fd4 644 /* external object */
mbed_official 0:51ac1d130fd4 645 struct mib_external_node *en = (struct mib_external_node*)mn;
mbed_official 0:51ac1d130fd4 646
mbed_official 0:51ac1d130fd4 647 msg_ps->state = SNMP_MSG_EXTERNAL_GET_OBJDEF;
mbed_official 0:51ac1d130fd4 648 /* save en && args in msg_ps!! */
mbed_official 0:51ac1d130fd4 649 msg_ps->ext_mib_node = en;
mbed_official 0:51ac1d130fd4 650 msg_ps->ext_name_ptr = np;
mbed_official 0:51ac1d130fd4 651
mbed_official 0:51ac1d130fd4 652 en->get_object_def_q(en->addr_inf, request_id, np.ident_len, np.ident);
mbed_official 0:51ac1d130fd4 653 }
mbed_official 0:51ac1d130fd4 654 else
mbed_official 0:51ac1d130fd4 655 {
mbed_official 0:51ac1d130fd4 656 /* internal object */
mbed_official 0:51ac1d130fd4 657 struct obj_def object_def;
mbed_official 0:51ac1d130fd4 658
mbed_official 0:51ac1d130fd4 659 msg_ps->state = SNMP_MSG_INTERNAL_GET_OBJDEF;
mbed_official 0:51ac1d130fd4 660 mn->get_object_def(np.ident_len, np.ident, &object_def);
mbed_official 0:51ac1d130fd4 661 if (object_def.instance != MIB_OBJECT_NONE)
mbed_official 0:51ac1d130fd4 662 {
mbed_official 0:51ac1d130fd4 663 mn = mn;
mbed_official 0:51ac1d130fd4 664 }
mbed_official 0:51ac1d130fd4 665 else
mbed_official 0:51ac1d130fd4 666 {
mbed_official 0:51ac1d130fd4 667 /* search failed, object id points to unknown object (nosuchname) */
mbed_official 0:51ac1d130fd4 668 mn = NULL;
mbed_official 0:51ac1d130fd4 669 }
mbed_official 0:51ac1d130fd4 670 if (mn != NULL)
mbed_official 0:51ac1d130fd4 671 {
mbed_official 0:51ac1d130fd4 672 msg_ps->state = SNMP_MSG_INTERNAL_SET_TEST;
mbed_official 0:51ac1d130fd4 673
mbed_official 0:51ac1d130fd4 674 if (object_def.access & MIB_ACCESS_WRITE)
mbed_official 0:51ac1d130fd4 675 {
mbed_official 0:51ac1d130fd4 676 if ((object_def.asn_type == msg_ps->vb_ptr->value_type) &&
mbed_official 0:51ac1d130fd4 677 (mn->set_test(&object_def,msg_ps->vb_ptr->value_len,msg_ps->vb_ptr->value) != 0))
mbed_official 0:51ac1d130fd4 678 {
mbed_official 0:51ac1d130fd4 679 msg_ps->state = SNMP_MSG_SEARCH_OBJ;
mbed_official 0:51ac1d130fd4 680 msg_ps->vb_idx += 1;
mbed_official 0:51ac1d130fd4 681 }
mbed_official 0:51ac1d130fd4 682 else
mbed_official 0:51ac1d130fd4 683 {
mbed_official 0:51ac1d130fd4 684 /* bad value */
mbed_official 0:51ac1d130fd4 685 snmp_error_response(msg_ps,SNMP_ES_BADVALUE);
mbed_official 0:51ac1d130fd4 686 }
mbed_official 0:51ac1d130fd4 687 }
mbed_official 0:51ac1d130fd4 688 else
mbed_official 0:51ac1d130fd4 689 {
mbed_official 0:51ac1d130fd4 690 /* object not available for set */
mbed_official 0:51ac1d130fd4 691 snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME);
mbed_official 0:51ac1d130fd4 692 }
mbed_official 0:51ac1d130fd4 693 }
mbed_official 0:51ac1d130fd4 694 }
mbed_official 0:51ac1d130fd4 695 }
mbed_official 0:51ac1d130fd4 696 }
mbed_official 0:51ac1d130fd4 697 else
mbed_official 0:51ac1d130fd4 698 {
mbed_official 0:51ac1d130fd4 699 mn = NULL;
mbed_official 0:51ac1d130fd4 700 }
mbed_official 0:51ac1d130fd4 701 if (mn == NULL)
mbed_official 0:51ac1d130fd4 702 {
mbed_official 0:51ac1d130fd4 703 /* mn == NULL, noSuchName */
mbed_official 0:51ac1d130fd4 704 snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME);
mbed_official 0:51ac1d130fd4 705 }
mbed_official 0:51ac1d130fd4 706 }
mbed_official 0:51ac1d130fd4 707
mbed_official 0:51ac1d130fd4 708 if ((msg_ps->state == SNMP_MSG_SEARCH_OBJ) &&
mbed_official 0:51ac1d130fd4 709 (msg_ps->vb_idx == msg_ps->invb.count))
mbed_official 0:51ac1d130fd4 710 {
mbed_official 0:51ac1d130fd4 711 msg_ps->vb_idx = 0;
mbed_official 0:51ac1d130fd4 712 msg_ps->state = SNMP_MSG_INTERNAL_SET_VALUE;
mbed_official 0:51ac1d130fd4 713 }
mbed_official 0:51ac1d130fd4 714
mbed_official 0:51ac1d130fd4 715 /* set all values "atomically" (be as "atomic" as possible) */
mbed_official 0:51ac1d130fd4 716 while ((msg_ps->state == SNMP_MSG_INTERNAL_SET_VALUE) &&
mbed_official 0:51ac1d130fd4 717 (msg_ps->vb_idx < msg_ps->invb.count))
mbed_official 0:51ac1d130fd4 718 {
mbed_official 0:51ac1d130fd4 719 struct mib_node *mn;
mbed_official 0:51ac1d130fd4 720 struct snmp_name_ptr np;
mbed_official 0:51ac1d130fd4 721
mbed_official 0:51ac1d130fd4 722 if (msg_ps->vb_idx == 0)
mbed_official 0:51ac1d130fd4 723 {
mbed_official 0:51ac1d130fd4 724 msg_ps->vb_ptr = msg_ps->invb.head;
mbed_official 0:51ac1d130fd4 725 }
mbed_official 0:51ac1d130fd4 726 else
mbed_official 0:51ac1d130fd4 727 {
mbed_official 0:51ac1d130fd4 728 msg_ps->vb_ptr = msg_ps->vb_ptr->next;
mbed_official 0:51ac1d130fd4 729 }
mbed_official 0:51ac1d130fd4 730 /* skip iso prefix test, was done previously while settesting() */
mbed_official 0:51ac1d130fd4 731 mn = snmp_search_tree((struct mib_node*)&internet, msg_ps->vb_ptr->ident_len - 4,
mbed_official 0:51ac1d130fd4 732 msg_ps->vb_ptr->ident + 4, &np);
mbed_official 0:51ac1d130fd4 733 /* check if object is still available
mbed_official 0:51ac1d130fd4 734 (e.g. external hot-plug thingy present?) */
mbed_official 0:51ac1d130fd4 735 if (mn != NULL)
mbed_official 0:51ac1d130fd4 736 {
mbed_official 0:51ac1d130fd4 737 if (mn->node_type == MIB_NODE_EX)
mbed_official 0:51ac1d130fd4 738 {
mbed_official 0:51ac1d130fd4 739 /* external object */
mbed_official 0:51ac1d130fd4 740 struct mib_external_node *en = (struct mib_external_node*)mn;
mbed_official 0:51ac1d130fd4 741
mbed_official 0:51ac1d130fd4 742 msg_ps->state = SNMP_MSG_EXTERNAL_GET_OBJDEF_S;
mbed_official 0:51ac1d130fd4 743 /* save en && args in msg_ps!! */
mbed_official 0:51ac1d130fd4 744 msg_ps->ext_mib_node = en;
mbed_official 0:51ac1d130fd4 745 msg_ps->ext_name_ptr = np;
mbed_official 0:51ac1d130fd4 746
mbed_official 0:51ac1d130fd4 747 en->get_object_def_q(en->addr_inf, request_id, np.ident_len, np.ident);
mbed_official 0:51ac1d130fd4 748 }
mbed_official 0:51ac1d130fd4 749 else
mbed_official 0:51ac1d130fd4 750 {
mbed_official 0:51ac1d130fd4 751 /* internal object */
mbed_official 0:51ac1d130fd4 752 struct obj_def object_def;
mbed_official 0:51ac1d130fd4 753
mbed_official 0:51ac1d130fd4 754 msg_ps->state = SNMP_MSG_INTERNAL_GET_OBJDEF_S;
mbed_official 0:51ac1d130fd4 755 mn->get_object_def(np.ident_len, np.ident, &object_def);
mbed_official 0:51ac1d130fd4 756 msg_ps->state = SNMP_MSG_INTERNAL_SET_VALUE;
mbed_official 0:51ac1d130fd4 757 mn->set_value(&object_def,msg_ps->vb_ptr->value_len,msg_ps->vb_ptr->value);
mbed_official 0:51ac1d130fd4 758 msg_ps->vb_idx += 1;
mbed_official 0:51ac1d130fd4 759 }
mbed_official 0:51ac1d130fd4 760 }
mbed_official 0:51ac1d130fd4 761 }
mbed_official 0:51ac1d130fd4 762 if ((msg_ps->state == SNMP_MSG_INTERNAL_SET_VALUE) &&
mbed_official 0:51ac1d130fd4 763 (msg_ps->vb_idx == msg_ps->invb.count))
mbed_official 0:51ac1d130fd4 764 {
mbed_official 0:51ac1d130fd4 765 /* simply echo the input if we can set it
mbed_official 0:51ac1d130fd4 766 @todo do we need to return the actual value?
mbed_official 0:51ac1d130fd4 767 e.g. if value is silently modified or behaves sticky? */
mbed_official 0:51ac1d130fd4 768 msg_ps->outvb = msg_ps->invb;
mbed_official 0:51ac1d130fd4 769 msg_ps->invb.head = NULL;
mbed_official 0:51ac1d130fd4 770 msg_ps->invb.tail = NULL;
mbed_official 0:51ac1d130fd4 771 msg_ps->invb.count = 0;
mbed_official 0:51ac1d130fd4 772 snmp_ok_response(msg_ps);
mbed_official 0:51ac1d130fd4 773 }
mbed_official 0:51ac1d130fd4 774 }
mbed_official 0:51ac1d130fd4 775
mbed_official 0:51ac1d130fd4 776
mbed_official 0:51ac1d130fd4 777 /**
mbed_official 0:51ac1d130fd4 778 * Handle one internal or external event.
mbed_official 0:51ac1d130fd4 779 * Called for one async event. (recv external/private answer)
mbed_official 0:51ac1d130fd4 780 *
mbed_official 0:51ac1d130fd4 781 * @param request_id identifies requests from 0 to (SNMP_CONCURRENT_REQUESTS-1)
mbed_official 0:51ac1d130fd4 782 */
mbed_official 0:51ac1d130fd4 783 void
mbed_official 0:51ac1d130fd4 784 snmp_msg_event(u8_t request_id)
mbed_official 0:51ac1d130fd4 785 {
mbed_official 0:51ac1d130fd4 786 struct snmp_msg_pstat *msg_ps;
mbed_official 0:51ac1d130fd4 787
mbed_official 0:51ac1d130fd4 788 if (request_id < SNMP_CONCURRENT_REQUESTS)
mbed_official 0:51ac1d130fd4 789 {
mbed_official 0:51ac1d130fd4 790 msg_ps = &msg_input_list[request_id];
mbed_official 0:51ac1d130fd4 791 if (msg_ps->rt == SNMP_ASN1_PDU_GET_NEXT_REQ)
mbed_official 0:51ac1d130fd4 792 {
mbed_official 0:51ac1d130fd4 793 snmp_msg_getnext_event(request_id, msg_ps);
mbed_official 0:51ac1d130fd4 794 }
mbed_official 0:51ac1d130fd4 795 else if (msg_ps->rt == SNMP_ASN1_PDU_GET_REQ)
mbed_official 0:51ac1d130fd4 796 {
mbed_official 0:51ac1d130fd4 797 snmp_msg_get_event(request_id, msg_ps);
mbed_official 0:51ac1d130fd4 798 }
mbed_official 0:51ac1d130fd4 799 else if(msg_ps->rt == SNMP_ASN1_PDU_SET_REQ)
mbed_official 0:51ac1d130fd4 800 {
mbed_official 0:51ac1d130fd4 801 snmp_msg_set_event(request_id, msg_ps);
mbed_official 0:51ac1d130fd4 802 }
mbed_official 0:51ac1d130fd4 803 }
mbed_official 0:51ac1d130fd4 804 }
mbed_official 0:51ac1d130fd4 805
mbed_official 0:51ac1d130fd4 806
mbed_official 0:51ac1d130fd4 807 /* lwIP UDP receive callback function */
mbed_official 0:51ac1d130fd4 808 static void
mbed_official 0:51ac1d130fd4 809 snmp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *addr, u16_t port)
mbed_official 0:51ac1d130fd4 810 {
mbed_official 0:51ac1d130fd4 811 struct snmp_msg_pstat *msg_ps;
mbed_official 0:51ac1d130fd4 812 u8_t req_idx;
mbed_official 0:51ac1d130fd4 813 err_t err_ret;
mbed_official 0:51ac1d130fd4 814 u16_t payload_len = p->tot_len;
mbed_official 0:51ac1d130fd4 815 u16_t payload_ofs = 0;
mbed_official 0:51ac1d130fd4 816 u16_t varbind_ofs = 0;
mbed_official 0:51ac1d130fd4 817
mbed_official 0:51ac1d130fd4 818 /* suppress unused argument warning */
mbed_official 0:51ac1d130fd4 819 LWIP_UNUSED_ARG(arg);
mbed_official 0:51ac1d130fd4 820
mbed_official 0:51ac1d130fd4 821 /* traverse input message process list, look for SNMP_MSG_EMPTY */
mbed_official 0:51ac1d130fd4 822 msg_ps = &msg_input_list[0];
mbed_official 0:51ac1d130fd4 823 req_idx = 0;
mbed_official 0:51ac1d130fd4 824 while ((req_idx < SNMP_CONCURRENT_REQUESTS) && (msg_ps->state != SNMP_MSG_EMPTY))
mbed_official 0:51ac1d130fd4 825 {
mbed_official 0:51ac1d130fd4 826 req_idx++;
mbed_official 0:51ac1d130fd4 827 msg_ps++;
mbed_official 0:51ac1d130fd4 828 }
mbed_official 0:51ac1d130fd4 829 if (req_idx == SNMP_CONCURRENT_REQUESTS)
mbed_official 0:51ac1d130fd4 830 {
mbed_official 0:51ac1d130fd4 831 /* exceeding number of concurrent requests */
mbed_official 0:51ac1d130fd4 832 pbuf_free(p);
mbed_official 0:51ac1d130fd4 833 return;
mbed_official 0:51ac1d130fd4 834 }
mbed_official 0:51ac1d130fd4 835
mbed_official 0:51ac1d130fd4 836 /* accepting request */
mbed_official 0:51ac1d130fd4 837 snmp_inc_snmpinpkts();
mbed_official 0:51ac1d130fd4 838 /* record used 'protocol control block' */
mbed_official 0:51ac1d130fd4 839 msg_ps->pcb = pcb;
mbed_official 0:51ac1d130fd4 840 /* source address (network order) */
mbed_official 0:51ac1d130fd4 841 msg_ps->sip = *addr;
mbed_official 0:51ac1d130fd4 842 /* source port (host order (lwIP oddity)) */
mbed_official 0:51ac1d130fd4 843 msg_ps->sp = port;
mbed_official 0:51ac1d130fd4 844
mbed_official 0:51ac1d130fd4 845 /* check total length, version, community, pdu type */
mbed_official 0:51ac1d130fd4 846 err_ret = snmp_pdu_header_check(p, payload_ofs, payload_len, &varbind_ofs, msg_ps);
mbed_official 0:51ac1d130fd4 847 /* Only accept requests and requests without error (be robust) */
mbed_official 0:51ac1d130fd4 848 /* Reject response and trap headers or error requests as input! */
mbed_official 0:51ac1d130fd4 849 if ((err_ret != ERR_OK) ||
mbed_official 0:51ac1d130fd4 850 ((msg_ps->rt != SNMP_ASN1_PDU_GET_REQ) &&
mbed_official 0:51ac1d130fd4 851 (msg_ps->rt != SNMP_ASN1_PDU_GET_NEXT_REQ) &&
mbed_official 0:51ac1d130fd4 852 (msg_ps->rt != SNMP_ASN1_PDU_SET_REQ)) ||
mbed_official 0:51ac1d130fd4 853 ((msg_ps->error_status != SNMP_ES_NOERROR) ||
mbed_official 0:51ac1d130fd4 854 (msg_ps->error_index != 0)) )
mbed_official 0:51ac1d130fd4 855 {
mbed_official 0:51ac1d130fd4 856 /* header check failed drop request silently, do not return error! */
mbed_official 0:51ac1d130fd4 857 pbuf_free(p);
mbed_official 0:51ac1d130fd4 858 LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_pdu_header_check() failed\n"));
mbed_official 0:51ac1d130fd4 859 return;
mbed_official 0:51ac1d130fd4 860 }
mbed_official 0:51ac1d130fd4 861 LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_recv ok, community %s\n", msg_ps->community));
mbed_official 0:51ac1d130fd4 862
mbed_official 0:51ac1d130fd4 863 /* Builds a list of variable bindings. Copy the varbinds from the pbuf
mbed_official 0:51ac1d130fd4 864 chain to glue them when these are divided over two or more pbuf's. */
mbed_official 0:51ac1d130fd4 865 err_ret = snmp_pdu_dec_varbindlist(p, varbind_ofs, &varbind_ofs, msg_ps);
mbed_official 0:51ac1d130fd4 866 /* we've decoded the incoming message, release input msg now */
mbed_official 0:51ac1d130fd4 867 pbuf_free(p);
mbed_official 0:51ac1d130fd4 868 if ((err_ret != ERR_OK) || (msg_ps->invb.count == 0))
mbed_official 0:51ac1d130fd4 869 {
mbed_official 0:51ac1d130fd4 870 /* varbind-list decode failed, or varbind list empty.
mbed_official 0:51ac1d130fd4 871 drop request silently, do not return error!
mbed_official 0:51ac1d130fd4 872 (errors are only returned for a specific varbind failure) */
mbed_official 0:51ac1d130fd4 873 LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_pdu_dec_varbindlist() failed\n"));
mbed_official 0:51ac1d130fd4 874 return;
mbed_official 0:51ac1d130fd4 875 }
mbed_official 0:51ac1d130fd4 876
mbed_official 0:51ac1d130fd4 877 msg_ps->error_status = SNMP_ES_NOERROR;
mbed_official 0:51ac1d130fd4 878 msg_ps->error_index = 0;
mbed_official 0:51ac1d130fd4 879 /* find object for each variable binding */
mbed_official 0:51ac1d130fd4 880 msg_ps->state = SNMP_MSG_SEARCH_OBJ;
mbed_official 0:51ac1d130fd4 881 /* first variable binding from list to inspect */
mbed_official 0:51ac1d130fd4 882 msg_ps->vb_idx = 0;
mbed_official 0:51ac1d130fd4 883
mbed_official 0:51ac1d130fd4 884 LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_recv varbind cnt=%"U16_F"\n",(u16_t)msg_ps->invb.count));
mbed_official 0:51ac1d130fd4 885
mbed_official 0:51ac1d130fd4 886 /* handle input event and as much objects as possible in one go */
mbed_official 0:51ac1d130fd4 887 snmp_msg_event(req_idx);
mbed_official 0:51ac1d130fd4 888 }
mbed_official 0:51ac1d130fd4 889
mbed_official 0:51ac1d130fd4 890 /**
mbed_official 0:51ac1d130fd4 891 * Checks and decodes incoming SNMP message header, logs header errors.
mbed_official 0:51ac1d130fd4 892 *
mbed_official 0:51ac1d130fd4 893 * @param p points to pbuf chain of SNMP message (UDP payload)
mbed_official 0:51ac1d130fd4 894 * @param ofs points to first octet of SNMP message
mbed_official 0:51ac1d130fd4 895 * @param pdu_len the length of the UDP payload
mbed_official 0:51ac1d130fd4 896 * @param ofs_ret returns the ofset of the variable bindings
mbed_official 0:51ac1d130fd4 897 * @param m_stat points to the current message request state return
mbed_official 0:51ac1d130fd4 898 * @return
mbed_official 0:51ac1d130fd4 899 * - ERR_OK SNMP header is sane and accepted
mbed_official 0:51ac1d130fd4 900 * - ERR_ARG SNMP header is either malformed or rejected
mbed_official 0:51ac1d130fd4 901 */
mbed_official 0:51ac1d130fd4 902 static err_t
mbed_official 0:51ac1d130fd4 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)
mbed_official 0:51ac1d130fd4 904 {
mbed_official 0:51ac1d130fd4 905 err_t derr;
mbed_official 0:51ac1d130fd4 906 u16_t len, ofs_base;
mbed_official 0:51ac1d130fd4 907 u8_t len_octets;
mbed_official 0:51ac1d130fd4 908 u8_t type;
mbed_official 0:51ac1d130fd4 909 s32_t version;
mbed_official 0:51ac1d130fd4 910
mbed_official 0:51ac1d130fd4 911 ofs_base = ofs;
mbed_official 0:51ac1d130fd4 912 snmp_asn1_dec_type(p, ofs, &type);
mbed_official 0:51ac1d130fd4 913 derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len);
mbed_official 0:51ac1d130fd4 914 if ((derr != ERR_OK) ||
mbed_official 0:51ac1d130fd4 915 (pdu_len != (1 + len_octets + len)) ||
mbed_official 0:51ac1d130fd4 916 (type != (SNMP_ASN1_UNIV | SNMP_ASN1_CONSTR | SNMP_ASN1_SEQ)))
mbed_official 0:51ac1d130fd4 917 {
mbed_official 0:51ac1d130fd4 918 snmp_inc_snmpinasnparseerrs();
mbed_official 0:51ac1d130fd4 919 return ERR_ARG;
mbed_official 0:51ac1d130fd4 920 }
mbed_official 0:51ac1d130fd4 921 ofs += (1 + len_octets);
mbed_official 0:51ac1d130fd4 922 snmp_asn1_dec_type(p, ofs, &type);
mbed_official 0:51ac1d130fd4 923 derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len);
mbed_official 0:51ac1d130fd4 924 if ((derr != ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG)))
mbed_official 0:51ac1d130fd4 925 {
mbed_official 0:51ac1d130fd4 926 /* can't decode or no integer (version) */
mbed_official 0:51ac1d130fd4 927 snmp_inc_snmpinasnparseerrs();
mbed_official 0:51ac1d130fd4 928 return ERR_ARG;
mbed_official 0:51ac1d130fd4 929 }
mbed_official 0:51ac1d130fd4 930 derr = snmp_asn1_dec_s32t(p, ofs + 1 + len_octets, len, &version);
mbed_official 0:51ac1d130fd4 931 if (derr != ERR_OK)
mbed_official 0:51ac1d130fd4 932 {
mbed_official 0:51ac1d130fd4 933 /* can't decode */
mbed_official 0:51ac1d130fd4 934 snmp_inc_snmpinasnparseerrs();
mbed_official 0:51ac1d130fd4 935 return ERR_ARG;
mbed_official 0:51ac1d130fd4 936 }
mbed_official 0:51ac1d130fd4 937 if (version != 0)
mbed_official 0:51ac1d130fd4 938 {
mbed_official 0:51ac1d130fd4 939 /* not version 1 */
mbed_official 0:51ac1d130fd4 940 snmp_inc_snmpinbadversions();
mbed_official 0:51ac1d130fd4 941 return ERR_ARG;
mbed_official 0:51ac1d130fd4 942 }
mbed_official 0:51ac1d130fd4 943 ofs += (1 + len_octets + len);
mbed_official 0:51ac1d130fd4 944 snmp_asn1_dec_type(p, ofs, &type);
mbed_official 0:51ac1d130fd4 945 derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len);
mbed_official 0:51ac1d130fd4 946 if ((derr != ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR)))
mbed_official 0:51ac1d130fd4 947 {
mbed_official 0:51ac1d130fd4 948 /* can't decode or no octet string (community) */
mbed_official 0:51ac1d130fd4 949 snmp_inc_snmpinasnparseerrs();
mbed_official 0:51ac1d130fd4 950 return ERR_ARG;
mbed_official 0:51ac1d130fd4 951 }
mbed_official 0:51ac1d130fd4 952 derr = snmp_asn1_dec_raw(p, ofs + 1 + len_octets, len, SNMP_COMMUNITY_STR_LEN, m_stat->community);
mbed_official 0:51ac1d130fd4 953 if (derr != ERR_OK)
mbed_official 0:51ac1d130fd4 954 {
mbed_official 0:51ac1d130fd4 955 snmp_inc_snmpinasnparseerrs();
mbed_official 0:51ac1d130fd4 956 return ERR_ARG;
mbed_official 0:51ac1d130fd4 957 }
mbed_official 0:51ac1d130fd4 958 /* add zero terminator */
mbed_official 0:51ac1d130fd4 959 len = ((len < (SNMP_COMMUNITY_STR_LEN))?(len):(SNMP_COMMUNITY_STR_LEN));
mbed_official 0:51ac1d130fd4 960 m_stat->community[len] = 0;
mbed_official 0:51ac1d130fd4 961 m_stat->com_strlen = (u8_t)len;
mbed_official 0:51ac1d130fd4 962 if (strncmp(snmp_publiccommunity, (const char*)m_stat->community, SNMP_COMMUNITY_STR_LEN) != 0)
mbed_official 0:51ac1d130fd4 963 {
mbed_official 0:51ac1d130fd4 964 /** @todo: move this if we need to check more names */
mbed_official 0:51ac1d130fd4 965 snmp_inc_snmpinbadcommunitynames();
mbed_official 0:51ac1d130fd4 966 snmp_authfail_trap();
mbed_official 0:51ac1d130fd4 967 return ERR_ARG;
mbed_official 0:51ac1d130fd4 968 }
mbed_official 0:51ac1d130fd4 969 ofs += (1 + len_octets + len);
mbed_official 0:51ac1d130fd4 970 snmp_asn1_dec_type(p, ofs, &type);
mbed_official 0:51ac1d130fd4 971 derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len);
mbed_official 0:51ac1d130fd4 972 if (derr != ERR_OK)
mbed_official 0:51ac1d130fd4 973 {
mbed_official 0:51ac1d130fd4 974 snmp_inc_snmpinasnparseerrs();
mbed_official 0:51ac1d130fd4 975 return ERR_ARG;
mbed_official 0:51ac1d130fd4 976 }
mbed_official 0:51ac1d130fd4 977 switch(type)
mbed_official 0:51ac1d130fd4 978 {
mbed_official 0:51ac1d130fd4 979 case (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_GET_REQ):
mbed_official 0:51ac1d130fd4 980 /* GetRequest PDU */
mbed_official 0:51ac1d130fd4 981 snmp_inc_snmpingetrequests();
mbed_official 0:51ac1d130fd4 982 derr = ERR_OK;
mbed_official 0:51ac1d130fd4 983 break;
mbed_official 0:51ac1d130fd4 984 case (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_GET_NEXT_REQ):
mbed_official 0:51ac1d130fd4 985 /* GetNextRequest PDU */
mbed_official 0:51ac1d130fd4 986 snmp_inc_snmpingetnexts();
mbed_official 0:51ac1d130fd4 987 derr = ERR_OK;
mbed_official 0:51ac1d130fd4 988 break;
mbed_official 0:51ac1d130fd4 989 case (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_GET_RESP):
mbed_official 0:51ac1d130fd4 990 /* GetResponse PDU */
mbed_official 0:51ac1d130fd4 991 snmp_inc_snmpingetresponses();
mbed_official 0:51ac1d130fd4 992 derr = ERR_ARG;
mbed_official 0:51ac1d130fd4 993 break;
mbed_official 0:51ac1d130fd4 994 case (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_SET_REQ):
mbed_official 0:51ac1d130fd4 995 /* SetRequest PDU */
mbed_official 0:51ac1d130fd4 996 snmp_inc_snmpinsetrequests();
mbed_official 0:51ac1d130fd4 997 derr = ERR_OK;
mbed_official 0:51ac1d130fd4 998 break;
mbed_official 0:51ac1d130fd4 999 case (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_TRAP):
mbed_official 0:51ac1d130fd4 1000 /* Trap PDU */
mbed_official 0:51ac1d130fd4 1001 snmp_inc_snmpintraps();
mbed_official 0:51ac1d130fd4 1002 derr = ERR_ARG;
mbed_official 0:51ac1d130fd4 1003 break;
mbed_official 0:51ac1d130fd4 1004 default:
mbed_official 0:51ac1d130fd4 1005 snmp_inc_snmpinasnparseerrs();
mbed_official 0:51ac1d130fd4 1006 derr = ERR_ARG;
mbed_official 0:51ac1d130fd4 1007 break;
mbed_official 0:51ac1d130fd4 1008 }
mbed_official 0:51ac1d130fd4 1009 if (derr != ERR_OK)
mbed_official 0:51ac1d130fd4 1010 {
mbed_official 0:51ac1d130fd4 1011 /* unsupported input PDU for this agent (no parse error) */
mbed_official 0:51ac1d130fd4 1012 return ERR_ARG;
mbed_official 0:51ac1d130fd4 1013 }
mbed_official 0:51ac1d130fd4 1014 m_stat->rt = type & 0x1F;
mbed_official 0:51ac1d130fd4 1015 ofs += (1 + len_octets);
mbed_official 0:51ac1d130fd4 1016 if (len != (pdu_len - (ofs - ofs_base)))
mbed_official 0:51ac1d130fd4 1017 {
mbed_official 0:51ac1d130fd4 1018 /* decoded PDU length does not equal actual payload length */
mbed_official 0:51ac1d130fd4 1019 snmp_inc_snmpinasnparseerrs();
mbed_official 0:51ac1d130fd4 1020 return ERR_ARG;
mbed_official 0:51ac1d130fd4 1021 }
mbed_official 0:51ac1d130fd4 1022 snmp_asn1_dec_type(p, ofs, &type);
mbed_official 0:51ac1d130fd4 1023 derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len);
mbed_official 0:51ac1d130fd4 1024 if ((derr != ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG)))
mbed_official 0:51ac1d130fd4 1025 {
mbed_official 0:51ac1d130fd4 1026 /* can't decode or no integer (request ID) */
mbed_official 0:51ac1d130fd4 1027 snmp_inc_snmpinasnparseerrs();
mbed_official 0:51ac1d130fd4 1028 return ERR_ARG;
mbed_official 0:51ac1d130fd4 1029 }
mbed_official 0:51ac1d130fd4 1030 derr = snmp_asn1_dec_s32t(p, ofs + 1 + len_octets, len, &m_stat->rid);
mbed_official 0:51ac1d130fd4 1031 if (derr != ERR_OK)
mbed_official 0:51ac1d130fd4 1032 {
mbed_official 0:51ac1d130fd4 1033 /* can't decode */
mbed_official 0:51ac1d130fd4 1034 snmp_inc_snmpinasnparseerrs();
mbed_official 0:51ac1d130fd4 1035 return ERR_ARG;
mbed_official 0:51ac1d130fd4 1036 }
mbed_official 0:51ac1d130fd4 1037 ofs += (1 + len_octets + len);
mbed_official 0:51ac1d130fd4 1038 snmp_asn1_dec_type(p, ofs, &type);
mbed_official 0:51ac1d130fd4 1039 derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len);
mbed_official 0:51ac1d130fd4 1040 if ((derr != ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG)))
mbed_official 0:51ac1d130fd4 1041 {
mbed_official 0:51ac1d130fd4 1042 /* can't decode or no integer (error-status) */
mbed_official 0:51ac1d130fd4 1043 snmp_inc_snmpinasnparseerrs();
mbed_official 0:51ac1d130fd4 1044 return ERR_ARG;
mbed_official 0:51ac1d130fd4 1045 }
mbed_official 0:51ac1d130fd4 1046 /* must be noError (0) for incoming requests.
mbed_official 0:51ac1d130fd4 1047 log errors for mib-2 completeness and for debug purposes */
mbed_official 0:51ac1d130fd4 1048 derr = snmp_asn1_dec_s32t(p, ofs + 1 + len_octets, len, &m_stat->error_status);
mbed_official 0:51ac1d130fd4 1049 if (derr != ERR_OK)
mbed_official 0:51ac1d130fd4 1050 {
mbed_official 0:51ac1d130fd4 1051 /* can't decode */
mbed_official 0:51ac1d130fd4 1052 snmp_inc_snmpinasnparseerrs();
mbed_official 0:51ac1d130fd4 1053 return ERR_ARG;
mbed_official 0:51ac1d130fd4 1054 }
mbed_official 0:51ac1d130fd4 1055 switch (m_stat->error_status)
mbed_official 0:51ac1d130fd4 1056 {
mbed_official 0:51ac1d130fd4 1057 case SNMP_ES_TOOBIG:
mbed_official 0:51ac1d130fd4 1058 snmp_inc_snmpintoobigs();
mbed_official 0:51ac1d130fd4 1059 break;
mbed_official 0:51ac1d130fd4 1060 case SNMP_ES_NOSUCHNAME:
mbed_official 0:51ac1d130fd4 1061 snmp_inc_snmpinnosuchnames();
mbed_official 0:51ac1d130fd4 1062 break;
mbed_official 0:51ac1d130fd4 1063 case SNMP_ES_BADVALUE:
mbed_official 0:51ac1d130fd4 1064 snmp_inc_snmpinbadvalues();
mbed_official 0:51ac1d130fd4 1065 break;
mbed_official 0:51ac1d130fd4 1066 case SNMP_ES_READONLY:
mbed_official 0:51ac1d130fd4 1067 snmp_inc_snmpinreadonlys();
mbed_official 0:51ac1d130fd4 1068 break;
mbed_official 0:51ac1d130fd4 1069 case SNMP_ES_GENERROR:
mbed_official 0:51ac1d130fd4 1070 snmp_inc_snmpingenerrs();
mbed_official 0:51ac1d130fd4 1071 break;
mbed_official 0:51ac1d130fd4 1072 }
mbed_official 0:51ac1d130fd4 1073 ofs += (1 + len_octets + len);
mbed_official 0:51ac1d130fd4 1074 snmp_asn1_dec_type(p, ofs, &type);
mbed_official 0:51ac1d130fd4 1075 derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len);
mbed_official 0:51ac1d130fd4 1076 if ((derr != ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG)))
mbed_official 0:51ac1d130fd4 1077 {
mbed_official 0:51ac1d130fd4 1078 /* can't decode or no integer (error-index) */
mbed_official 0:51ac1d130fd4 1079 snmp_inc_snmpinasnparseerrs();
mbed_official 0:51ac1d130fd4 1080 return ERR_ARG;
mbed_official 0:51ac1d130fd4 1081 }
mbed_official 0:51ac1d130fd4 1082 /* must be 0 for incoming requests.
mbed_official 0:51ac1d130fd4 1083 decode anyway to catch bad integers (and dirty tricks) */
mbed_official 0:51ac1d130fd4 1084 derr = snmp_asn1_dec_s32t(p, ofs + 1 + len_octets, len, &m_stat->error_index);
mbed_official 0:51ac1d130fd4 1085 if (derr != ERR_OK)
mbed_official 0:51ac1d130fd4 1086 {
mbed_official 0:51ac1d130fd4 1087 /* can't decode */
mbed_official 0:51ac1d130fd4 1088 snmp_inc_snmpinasnparseerrs();
mbed_official 0:51ac1d130fd4 1089 return ERR_ARG;
mbed_official 0:51ac1d130fd4 1090 }
mbed_official 0:51ac1d130fd4 1091 ofs += (1 + len_octets + len);
mbed_official 0:51ac1d130fd4 1092 *ofs_ret = ofs;
mbed_official 0:51ac1d130fd4 1093 return ERR_OK;
mbed_official 0:51ac1d130fd4 1094 }
mbed_official 0:51ac1d130fd4 1095
mbed_official 0:51ac1d130fd4 1096 static err_t
mbed_official 0:51ac1d130fd4 1097 snmp_pdu_dec_varbindlist(struct pbuf *p, u16_t ofs, u16_t *ofs_ret, struct snmp_msg_pstat *m_stat)
mbed_official 0:51ac1d130fd4 1098 {
mbed_official 0:51ac1d130fd4 1099 err_t derr;
mbed_official 0:51ac1d130fd4 1100 u16_t len, vb_len;
mbed_official 0:51ac1d130fd4 1101 u8_t len_octets;
mbed_official 0:51ac1d130fd4 1102 u8_t type;
mbed_official 0:51ac1d130fd4 1103
mbed_official 0:51ac1d130fd4 1104 /* variable binding list */
mbed_official 0:51ac1d130fd4 1105 snmp_asn1_dec_type(p, ofs, &type);
mbed_official 0:51ac1d130fd4 1106 derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &vb_len);
mbed_official 0:51ac1d130fd4 1107 if ((derr != ERR_OK) ||
mbed_official 0:51ac1d130fd4 1108 (type != (SNMP_ASN1_UNIV | SNMP_ASN1_CONSTR | SNMP_ASN1_SEQ)))
mbed_official 0:51ac1d130fd4 1109 {
mbed_official 0:51ac1d130fd4 1110 snmp_inc_snmpinasnparseerrs();
mbed_official 0:51ac1d130fd4 1111 return ERR_ARG;
mbed_official 0:51ac1d130fd4 1112 }
mbed_official 0:51ac1d130fd4 1113 ofs += (1 + len_octets);
mbed_official 0:51ac1d130fd4 1114
mbed_official 0:51ac1d130fd4 1115 /* start with empty list */
mbed_official 0:51ac1d130fd4 1116 m_stat->invb.count = 0;
mbed_official 0:51ac1d130fd4 1117 m_stat->invb.head = NULL;
mbed_official 0:51ac1d130fd4 1118 m_stat->invb.tail = NULL;
mbed_official 0:51ac1d130fd4 1119
mbed_official 0:51ac1d130fd4 1120 while (vb_len > 0)
mbed_official 0:51ac1d130fd4 1121 {
mbed_official 0:51ac1d130fd4 1122 struct snmp_obj_id oid, oid_value;
mbed_official 0:51ac1d130fd4 1123 struct snmp_varbind *vb;
mbed_official 0:51ac1d130fd4 1124
mbed_official 0:51ac1d130fd4 1125 snmp_asn1_dec_type(p, ofs, &type);
mbed_official 0:51ac1d130fd4 1126 derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len);
mbed_official 0:51ac1d130fd4 1127 if ((derr != ERR_OK) ||
mbed_official 0:51ac1d130fd4 1128 (type != (SNMP_ASN1_UNIV | SNMP_ASN1_CONSTR | SNMP_ASN1_SEQ)) ||
mbed_official 0:51ac1d130fd4 1129 (len == 0) || (len > vb_len))
mbed_official 0:51ac1d130fd4 1130 {
mbed_official 0:51ac1d130fd4 1131 snmp_inc_snmpinasnparseerrs();
mbed_official 0:51ac1d130fd4 1132 /* free varbinds (if available) */
mbed_official 0:51ac1d130fd4 1133 snmp_varbind_list_free(&m_stat->invb);
mbed_official 0:51ac1d130fd4 1134 return ERR_ARG;
mbed_official 0:51ac1d130fd4 1135 }
mbed_official 0:51ac1d130fd4 1136 ofs += (1 + len_octets);
mbed_official 0:51ac1d130fd4 1137 vb_len -= (1 + len_octets);
mbed_official 0:51ac1d130fd4 1138
mbed_official 0:51ac1d130fd4 1139 snmp_asn1_dec_type(p, ofs, &type);
mbed_official 0:51ac1d130fd4 1140 derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len);
mbed_official 0:51ac1d130fd4 1141 if ((derr != ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID)))
mbed_official 0:51ac1d130fd4 1142 {
mbed_official 0:51ac1d130fd4 1143 /* can't decode object name length */
mbed_official 0:51ac1d130fd4 1144 snmp_inc_snmpinasnparseerrs();
mbed_official 0:51ac1d130fd4 1145 /* free varbinds (if available) */
mbed_official 0:51ac1d130fd4 1146 snmp_varbind_list_free(&m_stat->invb);
mbed_official 0:51ac1d130fd4 1147 return ERR_ARG;
mbed_official 0:51ac1d130fd4 1148 }
mbed_official 0:51ac1d130fd4 1149 derr = snmp_asn1_dec_oid(p, ofs + 1 + len_octets, len, &oid);
mbed_official 0:51ac1d130fd4 1150 if (derr != ERR_OK)
mbed_official 0:51ac1d130fd4 1151 {
mbed_official 0:51ac1d130fd4 1152 /* can't decode object name */
mbed_official 0:51ac1d130fd4 1153 snmp_inc_snmpinasnparseerrs();
mbed_official 0:51ac1d130fd4 1154 /* free varbinds (if available) */
mbed_official 0:51ac1d130fd4 1155 snmp_varbind_list_free(&m_stat->invb);
mbed_official 0:51ac1d130fd4 1156 return ERR_ARG;
mbed_official 0:51ac1d130fd4 1157 }
mbed_official 0:51ac1d130fd4 1158 ofs += (1 + len_octets + len);
mbed_official 0:51ac1d130fd4 1159 vb_len -= (1 + len_octets + len);
mbed_official 0:51ac1d130fd4 1160
mbed_official 0:51ac1d130fd4 1161 snmp_asn1_dec_type(p, ofs, &type);
mbed_official 0:51ac1d130fd4 1162 derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len);
mbed_official 0:51ac1d130fd4 1163 if (derr != ERR_OK)
mbed_official 0:51ac1d130fd4 1164 {
mbed_official 0:51ac1d130fd4 1165 /* can't decode object value length */
mbed_official 0:51ac1d130fd4 1166 snmp_inc_snmpinasnparseerrs();
mbed_official 0:51ac1d130fd4 1167 /* free varbinds (if available) */
mbed_official 0:51ac1d130fd4 1168 snmp_varbind_list_free(&m_stat->invb);
mbed_official 0:51ac1d130fd4 1169 return ERR_ARG;
mbed_official 0:51ac1d130fd4 1170 }
mbed_official 0:51ac1d130fd4 1171
mbed_official 0:51ac1d130fd4 1172 switch (type)
mbed_official 0:51ac1d130fd4 1173 {
mbed_official 0:51ac1d130fd4 1174 case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG):
mbed_official 0:51ac1d130fd4 1175 vb = snmp_varbind_alloc(&oid, type, sizeof(s32_t));
mbed_official 0:51ac1d130fd4 1176 if (vb != NULL)
mbed_official 0:51ac1d130fd4 1177 {
mbed_official 0:51ac1d130fd4 1178 s32_t *vptr = (s32_t*)vb->value;
mbed_official 0:51ac1d130fd4 1179
mbed_official 0:51ac1d130fd4 1180 derr = snmp_asn1_dec_s32t(p, ofs + 1 + len_octets, len, vptr);
mbed_official 0:51ac1d130fd4 1181 snmp_varbind_tail_add(&m_stat->invb, vb);
mbed_official 0:51ac1d130fd4 1182 }
mbed_official 0:51ac1d130fd4 1183 else
mbed_official 0:51ac1d130fd4 1184 {
mbed_official 0:51ac1d130fd4 1185 derr = ERR_ARG;
mbed_official 0:51ac1d130fd4 1186 }
mbed_official 0:51ac1d130fd4 1187 break;
mbed_official 0:51ac1d130fd4 1188 case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER):
mbed_official 0:51ac1d130fd4 1189 case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_GAUGE):
mbed_official 0:51ac1d130fd4 1190 case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_TIMETICKS):
mbed_official 0:51ac1d130fd4 1191 vb = snmp_varbind_alloc(&oid, type, sizeof(u32_t));
mbed_official 0:51ac1d130fd4 1192 if (vb != NULL)
mbed_official 0:51ac1d130fd4 1193 {
mbed_official 0:51ac1d130fd4 1194 u32_t *vptr = (u32_t*)vb->value;
mbed_official 0:51ac1d130fd4 1195
mbed_official 0:51ac1d130fd4 1196 derr = snmp_asn1_dec_u32t(p, ofs + 1 + len_octets, len, vptr);
mbed_official 0:51ac1d130fd4 1197 snmp_varbind_tail_add(&m_stat->invb, vb);
mbed_official 0:51ac1d130fd4 1198 }
mbed_official 0:51ac1d130fd4 1199 else
mbed_official 0:51ac1d130fd4 1200 {
mbed_official 0:51ac1d130fd4 1201 derr = ERR_ARG;
mbed_official 0:51ac1d130fd4 1202 }
mbed_official 0:51ac1d130fd4 1203 break;
mbed_official 0:51ac1d130fd4 1204 case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR):
mbed_official 0:51ac1d130fd4 1205 case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_OPAQUE):
mbed_official 0:51ac1d130fd4 1206 LWIP_ASSERT("invalid length", len <= 0xff);
mbed_official 0:51ac1d130fd4 1207 vb = snmp_varbind_alloc(&oid, type, (u8_t)len);
mbed_official 0:51ac1d130fd4 1208 if (vb != NULL)
mbed_official 0:51ac1d130fd4 1209 {
mbed_official 0:51ac1d130fd4 1210 derr = snmp_asn1_dec_raw(p, ofs + 1 + len_octets, len, vb->value_len, (u8_t*)vb->value);
mbed_official 0:51ac1d130fd4 1211 snmp_varbind_tail_add(&m_stat->invb, vb);
mbed_official 0:51ac1d130fd4 1212 }
mbed_official 0:51ac1d130fd4 1213 else
mbed_official 0:51ac1d130fd4 1214 {
mbed_official 0:51ac1d130fd4 1215 derr = ERR_ARG;
mbed_official 0:51ac1d130fd4 1216 }
mbed_official 0:51ac1d130fd4 1217 break;
mbed_official 0:51ac1d130fd4 1218 case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_NUL):
mbed_official 0:51ac1d130fd4 1219 vb = snmp_varbind_alloc(&oid, type, 0);
mbed_official 0:51ac1d130fd4 1220 if (vb != NULL)
mbed_official 0:51ac1d130fd4 1221 {
mbed_official 0:51ac1d130fd4 1222 snmp_varbind_tail_add(&m_stat->invb, vb);
mbed_official 0:51ac1d130fd4 1223 derr = ERR_OK;
mbed_official 0:51ac1d130fd4 1224 }
mbed_official 0:51ac1d130fd4 1225 else
mbed_official 0:51ac1d130fd4 1226 {
mbed_official 0:51ac1d130fd4 1227 derr = ERR_ARG;
mbed_official 0:51ac1d130fd4 1228 }
mbed_official 0:51ac1d130fd4 1229 break;
mbed_official 0:51ac1d130fd4 1230 case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID):
mbed_official 0:51ac1d130fd4 1231 derr = snmp_asn1_dec_oid(p, ofs + 1 + len_octets, len, &oid_value);
mbed_official 0:51ac1d130fd4 1232 if (derr == ERR_OK)
mbed_official 0:51ac1d130fd4 1233 {
mbed_official 0:51ac1d130fd4 1234 vb = snmp_varbind_alloc(&oid, type, oid_value.len * sizeof(s32_t));
mbed_official 0:51ac1d130fd4 1235 if (vb != NULL)
mbed_official 0:51ac1d130fd4 1236 {
mbed_official 0:51ac1d130fd4 1237 u8_t i = oid_value.len;
mbed_official 0:51ac1d130fd4 1238 s32_t *vptr = (s32_t*)vb->value;
mbed_official 0:51ac1d130fd4 1239
mbed_official 0:51ac1d130fd4 1240 while(i > 0)
mbed_official 0:51ac1d130fd4 1241 {
mbed_official 0:51ac1d130fd4 1242 i--;
mbed_official 0:51ac1d130fd4 1243 vptr[i] = oid_value.id[i];
mbed_official 0:51ac1d130fd4 1244 }
mbed_official 0:51ac1d130fd4 1245 snmp_varbind_tail_add(&m_stat->invb, vb);
mbed_official 0:51ac1d130fd4 1246 derr = ERR_OK;
mbed_official 0:51ac1d130fd4 1247 }
mbed_official 0:51ac1d130fd4 1248 else
mbed_official 0:51ac1d130fd4 1249 {
mbed_official 0:51ac1d130fd4 1250 derr = ERR_ARG;
mbed_official 0:51ac1d130fd4 1251 }
mbed_official 0:51ac1d130fd4 1252 }
mbed_official 0:51ac1d130fd4 1253 break;
mbed_official 0:51ac1d130fd4 1254 case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR):
mbed_official 0:51ac1d130fd4 1255 if (len == 4)
mbed_official 0:51ac1d130fd4 1256 {
mbed_official 0:51ac1d130fd4 1257 /* must be exactly 4 octets! */
mbed_official 0:51ac1d130fd4 1258 vb = snmp_varbind_alloc(&oid, type, 4);
mbed_official 0:51ac1d130fd4 1259 if (vb != NULL)
mbed_official 0:51ac1d130fd4 1260 {
mbed_official 0:51ac1d130fd4 1261 derr = snmp_asn1_dec_raw(p, ofs + 1 + len_octets, len, vb->value_len, (u8_t*)vb->value);
mbed_official 0:51ac1d130fd4 1262 snmp_varbind_tail_add(&m_stat->invb, vb);
mbed_official 0:51ac1d130fd4 1263 }
mbed_official 0:51ac1d130fd4 1264 else
mbed_official 0:51ac1d130fd4 1265 {
mbed_official 0:51ac1d130fd4 1266 derr = ERR_ARG;
mbed_official 0:51ac1d130fd4 1267 }
mbed_official 0:51ac1d130fd4 1268 }
mbed_official 0:51ac1d130fd4 1269 else
mbed_official 0:51ac1d130fd4 1270 {
mbed_official 0:51ac1d130fd4 1271 derr = ERR_ARG;
mbed_official 0:51ac1d130fd4 1272 }
mbed_official 0:51ac1d130fd4 1273 break;
mbed_official 0:51ac1d130fd4 1274 default:
mbed_official 0:51ac1d130fd4 1275 derr = ERR_ARG;
mbed_official 0:51ac1d130fd4 1276 break;
mbed_official 0:51ac1d130fd4 1277 }
mbed_official 0:51ac1d130fd4 1278 if (derr != ERR_OK)
mbed_official 0:51ac1d130fd4 1279 {
mbed_official 0:51ac1d130fd4 1280 snmp_inc_snmpinasnparseerrs();
mbed_official 0:51ac1d130fd4 1281 /* free varbinds (if available) */
mbed_official 0:51ac1d130fd4 1282 snmp_varbind_list_free(&m_stat->invb);
mbed_official 0:51ac1d130fd4 1283 return ERR_ARG;
mbed_official 0:51ac1d130fd4 1284 }
mbed_official 0:51ac1d130fd4 1285 ofs += (1 + len_octets + len);
mbed_official 0:51ac1d130fd4 1286 vb_len -= (1 + len_octets + len);
mbed_official 0:51ac1d130fd4 1287 }
mbed_official 0:51ac1d130fd4 1288
mbed_official 0:51ac1d130fd4 1289 if (m_stat->rt == SNMP_ASN1_PDU_SET_REQ)
mbed_official 0:51ac1d130fd4 1290 {
mbed_official 0:51ac1d130fd4 1291 snmp_add_snmpintotalsetvars(m_stat->invb.count);
mbed_official 0:51ac1d130fd4 1292 }
mbed_official 0:51ac1d130fd4 1293 else
mbed_official 0:51ac1d130fd4 1294 {
mbed_official 0:51ac1d130fd4 1295 snmp_add_snmpintotalreqvars(m_stat->invb.count);
mbed_official 0:51ac1d130fd4 1296 }
mbed_official 0:51ac1d130fd4 1297
mbed_official 0:51ac1d130fd4 1298 *ofs_ret = ofs;
mbed_official 0:51ac1d130fd4 1299 return ERR_OK;
mbed_official 0:51ac1d130fd4 1300 }
mbed_official 0:51ac1d130fd4 1301
mbed_official 0:51ac1d130fd4 1302 struct snmp_varbind*
mbed_official 0:51ac1d130fd4 1303 snmp_varbind_alloc(struct snmp_obj_id *oid, u8_t type, u8_t len)
mbed_official 0:51ac1d130fd4 1304 {
mbed_official 0:51ac1d130fd4 1305 struct snmp_varbind *vb;
mbed_official 0:51ac1d130fd4 1306
mbed_official 0:51ac1d130fd4 1307 vb = (struct snmp_varbind *)memp_malloc(MEMP_SNMP_VARBIND);
mbed_official 0:51ac1d130fd4 1308 LWIP_ASSERT("vb != NULL",vb != NULL);
mbed_official 0:51ac1d130fd4 1309 if (vb != NULL)
mbed_official 0:51ac1d130fd4 1310 {
mbed_official 0:51ac1d130fd4 1311 u8_t i;
mbed_official 0:51ac1d130fd4 1312
mbed_official 0:51ac1d130fd4 1313 vb->next = NULL;
mbed_official 0:51ac1d130fd4 1314 vb->prev = NULL;
mbed_official 0:51ac1d130fd4 1315 i = oid->len;
mbed_official 0:51ac1d130fd4 1316 vb->ident_len = i;
mbed_official 0:51ac1d130fd4 1317 if (i > 0)
mbed_official 0:51ac1d130fd4 1318 {
mbed_official 0:51ac1d130fd4 1319 LWIP_ASSERT("SNMP_MAX_TREE_DEPTH is configured too low", i <= SNMP_MAX_TREE_DEPTH);
mbed_official 0:51ac1d130fd4 1320 /* allocate array of s32_t for our object identifier */
mbed_official 0:51ac1d130fd4 1321 vb->ident = (s32_t*)memp_malloc(MEMP_SNMP_VALUE);
mbed_official 0:51ac1d130fd4 1322 LWIP_ASSERT("vb->ident != NULL",vb->ident != NULL);
mbed_official 0:51ac1d130fd4 1323 if (vb->ident == NULL)
mbed_official 0:51ac1d130fd4 1324 {
mbed_official 0:51ac1d130fd4 1325 memp_free(MEMP_SNMP_VARBIND, vb);
mbed_official 0:51ac1d130fd4 1326 return NULL;
mbed_official 0:51ac1d130fd4 1327 }
mbed_official 0:51ac1d130fd4 1328 while(i > 0)
mbed_official 0:51ac1d130fd4 1329 {
mbed_official 0:51ac1d130fd4 1330 i--;
mbed_official 0:51ac1d130fd4 1331 vb->ident[i] = oid->id[i];
mbed_official 0:51ac1d130fd4 1332 }
mbed_official 0:51ac1d130fd4 1333 }
mbed_official 0:51ac1d130fd4 1334 else
mbed_official 0:51ac1d130fd4 1335 {
mbed_official 0:51ac1d130fd4 1336 /* i == 0, pass zero length object identifier */
mbed_official 0:51ac1d130fd4 1337 vb->ident = NULL;
mbed_official 0:51ac1d130fd4 1338 }
mbed_official 0:51ac1d130fd4 1339 vb->value_type = type;
mbed_official 0:51ac1d130fd4 1340 vb->value_len = len;
mbed_official 0:51ac1d130fd4 1341 if (len > 0)
mbed_official 0:51ac1d130fd4 1342 {
mbed_official 0:51ac1d130fd4 1343 LWIP_ASSERT("SNMP_MAX_OCTET_STRING_LEN is configured too low", vb->value_len <= SNMP_MAX_VALUE_SIZE);
mbed_official 0:51ac1d130fd4 1344 /* allocate raw bytes for our object value */
mbed_official 0:51ac1d130fd4 1345 vb->value = memp_malloc(MEMP_SNMP_VALUE);
mbed_official 0:51ac1d130fd4 1346 LWIP_ASSERT("vb->value != NULL",vb->value != NULL);
mbed_official 0:51ac1d130fd4 1347 if (vb->value == NULL)
mbed_official 0:51ac1d130fd4 1348 {
mbed_official 0:51ac1d130fd4 1349 if (vb->ident != NULL)
mbed_official 0:51ac1d130fd4 1350 {
mbed_official 0:51ac1d130fd4 1351 memp_free(MEMP_SNMP_VALUE, vb->ident);
mbed_official 0:51ac1d130fd4 1352 }
mbed_official 0:51ac1d130fd4 1353 memp_free(MEMP_SNMP_VARBIND, vb);
mbed_official 0:51ac1d130fd4 1354 return NULL;
mbed_official 0:51ac1d130fd4 1355 }
mbed_official 0:51ac1d130fd4 1356 }
mbed_official 0:51ac1d130fd4 1357 else
mbed_official 0:51ac1d130fd4 1358 {
mbed_official 0:51ac1d130fd4 1359 /* ASN1_NUL type, or zero length ASN1_OC_STR */
mbed_official 0:51ac1d130fd4 1360 vb->value = NULL;
mbed_official 0:51ac1d130fd4 1361 }
mbed_official 0:51ac1d130fd4 1362 }
mbed_official 0:51ac1d130fd4 1363 return vb;
mbed_official 0:51ac1d130fd4 1364 }
mbed_official 0:51ac1d130fd4 1365
mbed_official 0:51ac1d130fd4 1366 void
mbed_official 0:51ac1d130fd4 1367 snmp_varbind_free(struct snmp_varbind *vb)
mbed_official 0:51ac1d130fd4 1368 {
mbed_official 0:51ac1d130fd4 1369 if (vb->value != NULL )
mbed_official 0:51ac1d130fd4 1370 {
mbed_official 0:51ac1d130fd4 1371 memp_free(MEMP_SNMP_VALUE, vb->value);
mbed_official 0:51ac1d130fd4 1372 }
mbed_official 0:51ac1d130fd4 1373 if (vb->ident != NULL )
mbed_official 0:51ac1d130fd4 1374 {
mbed_official 0:51ac1d130fd4 1375 memp_free(MEMP_SNMP_VALUE, vb->ident);
mbed_official 0:51ac1d130fd4 1376 }
mbed_official 0:51ac1d130fd4 1377 memp_free(MEMP_SNMP_VARBIND, vb);
mbed_official 0:51ac1d130fd4 1378 }
mbed_official 0:51ac1d130fd4 1379
mbed_official 0:51ac1d130fd4 1380 void
mbed_official 0:51ac1d130fd4 1381 snmp_varbind_list_free(struct snmp_varbind_root *root)
mbed_official 0:51ac1d130fd4 1382 {
mbed_official 0:51ac1d130fd4 1383 struct snmp_varbind *vb, *prev;
mbed_official 0:51ac1d130fd4 1384
mbed_official 0:51ac1d130fd4 1385 vb = root->tail;
mbed_official 0:51ac1d130fd4 1386 while ( vb != NULL )
mbed_official 0:51ac1d130fd4 1387 {
mbed_official 0:51ac1d130fd4 1388 prev = vb->prev;
mbed_official 0:51ac1d130fd4 1389 snmp_varbind_free(vb);
mbed_official 0:51ac1d130fd4 1390 vb = prev;
mbed_official 0:51ac1d130fd4 1391 }
mbed_official 0:51ac1d130fd4 1392 root->count = 0;
mbed_official 0:51ac1d130fd4 1393 root->head = NULL;
mbed_official 0:51ac1d130fd4 1394 root->tail = NULL;
mbed_official 0:51ac1d130fd4 1395 }
mbed_official 0:51ac1d130fd4 1396
mbed_official 0:51ac1d130fd4 1397 void
mbed_official 0:51ac1d130fd4 1398 snmp_varbind_tail_add(struct snmp_varbind_root *root, struct snmp_varbind *vb)
mbed_official 0:51ac1d130fd4 1399 {
mbed_official 0:51ac1d130fd4 1400 if (root->count == 0)
mbed_official 0:51ac1d130fd4 1401 {
mbed_official 0:51ac1d130fd4 1402 /* add first varbind to list */
mbed_official 0:51ac1d130fd4 1403 root->head = vb;
mbed_official 0:51ac1d130fd4 1404 root->tail = vb;
mbed_official 0:51ac1d130fd4 1405 }
mbed_official 0:51ac1d130fd4 1406 else
mbed_official 0:51ac1d130fd4 1407 {
mbed_official 0:51ac1d130fd4 1408 /* add nth varbind to list tail */
mbed_official 0:51ac1d130fd4 1409 root->tail->next = vb;
mbed_official 0:51ac1d130fd4 1410 vb->prev = root->tail;
mbed_official 0:51ac1d130fd4 1411 root->tail = vb;
mbed_official 0:51ac1d130fd4 1412 }
mbed_official 0:51ac1d130fd4 1413 root->count += 1;
mbed_official 0:51ac1d130fd4 1414 }
mbed_official 0:51ac1d130fd4 1415
mbed_official 0:51ac1d130fd4 1416 struct snmp_varbind*
mbed_official 0:51ac1d130fd4 1417 snmp_varbind_tail_remove(struct snmp_varbind_root *root)
mbed_official 0:51ac1d130fd4 1418 {
mbed_official 0:51ac1d130fd4 1419 struct snmp_varbind* vb;
mbed_official 0:51ac1d130fd4 1420
mbed_official 0:51ac1d130fd4 1421 if (root->count > 0)
mbed_official 0:51ac1d130fd4 1422 {
mbed_official 0:51ac1d130fd4 1423 /* remove tail varbind */
mbed_official 0:51ac1d130fd4 1424 vb = root->tail;
mbed_official 0:51ac1d130fd4 1425 root->tail = vb->prev;
mbed_official 0:51ac1d130fd4 1426 vb->prev->next = NULL;
mbed_official 0:51ac1d130fd4 1427 root->count -= 1;
mbed_official 0:51ac1d130fd4 1428 }
mbed_official 0:51ac1d130fd4 1429 else
mbed_official 0:51ac1d130fd4 1430 {
mbed_official 0:51ac1d130fd4 1431 /* nothing to remove */
mbed_official 0:51ac1d130fd4 1432 vb = NULL;
mbed_official 0:51ac1d130fd4 1433 }
mbed_official 0:51ac1d130fd4 1434 return vb;
mbed_official 0:51ac1d130fd4 1435 }
mbed_official 0:51ac1d130fd4 1436
mbed_official 0:51ac1d130fd4 1437 #endif /* LWIP_SNMP */