A version of LWIP, provided for backwards compatibility.

Dependents:   AA_DemoBoard DemoBoard HelloServerDemo DemoBoard_RangeIndicator ... more

Committer:
root@mbed.org
Date:
Tue May 08 15:32:10 2012 +0100
Revision:
0:5e1631496985
initial commit

Who changed what in which revision?

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