SNMP agent attached to SPI slave

Dependencies:   mbed

Committer:
lorcansmith
Date:
Thu Sep 06 12:52:48 2012 +0000
Revision:
2:25e12a7fe0aa
Parent:
0:2a53a4c3238c
Open source version 1.a

Who changed what in which revision?

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