Lorcan Smith
/
Enet_SPI
SNMP agent attached to SPI slave
lwip/core/snmp/msg_in.c@0:2a53a4c3238c, 2012-08-13 (annotated)
- Committer:
- lorcansmith
- Date:
- Mon Aug 13 15:07:40 2012 +0000
- Revision:
- 0:2a53a4c3238c
- Child:
- 2:25e12a7fe0aa
v1.1 release includes ioAlarm traps
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
lorcansmith | 0:2a53a4c3238c | 1 | /***************************************************************************** |
lorcansmith | 0:2a53a4c3238c | 2 | * Copyright Field Electronics Ltd |
lorcansmith | 0:2a53a4c3238c | 3 | * File: msg_in.c |
lorcansmith | 0:2a53a4c3238c | 4 | * Reference: 3000-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 */ |