Example program with HTTPServer and sensor data streaming over TCPSockets, using Donatien Garnier's Net APIs and services code on top of LWIP. Files StreamServer.h and .cpp encapsulate streaming over TCPSockets. Broadcast is done by sendToAll(), and all incoming data is echoed back to the client. Echo code can be replaced with some remote control of the streaming interface. See main() that shows how to periodically send some data to all subscribed clients. To subscribe, a client should open a socket at <mbed_ip> port 123. I used few lines in TCL code to set up a quick sink for the data. HTTP files are served on port 80 concurrently to the streaming.

Dependencies:   mbed

Committer:
iva2k
Date:
Sat Jun 12 06:01:50 2010 +0000
Revision:
0:e614f7875b60

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
iva2k 0:e614f7875b60 1 /**
iva2k 0:e614f7875b60 2 * @file
iva2k 0:e614f7875b60 3 * SNMP output message processing (RFC1157).
iva2k 0:e614f7875b60 4 *
iva2k 0:e614f7875b60 5 * Output responses and traps are build in two passes:
iva2k 0:e614f7875b60 6 *
iva2k 0:e614f7875b60 7 * Pass 0: iterate over the output message backwards to determine encoding lengths
iva2k 0:e614f7875b60 8 * Pass 1: the actual forward encoding of internal form into ASN1
iva2k 0:e614f7875b60 9 *
iva2k 0:e614f7875b60 10 * The single-pass encoding method described by Comer & Stevens
iva2k 0:e614f7875b60 11 * requires extra buffer space and copying for reversal of the packet.
iva2k 0:e614f7875b60 12 * The buffer requirement can be prohibitively large for big payloads
iva2k 0:e614f7875b60 13 * (>= 484) therefore we use the two encoding passes.
iva2k 0:e614f7875b60 14 */
iva2k 0:e614f7875b60 15
iva2k 0:e614f7875b60 16 /*
iva2k 0:e614f7875b60 17 * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands.
iva2k 0:e614f7875b60 18 * All rights reserved.
iva2k 0:e614f7875b60 19 *
iva2k 0:e614f7875b60 20 * Redistribution and use in source and binary forms, with or without modification,
iva2k 0:e614f7875b60 21 * are permitted provided that the following conditions are met:
iva2k 0:e614f7875b60 22 *
iva2k 0:e614f7875b60 23 * 1. Redistributions of source code must retain the above copyright notice,
iva2k 0:e614f7875b60 24 * this list of conditions and the following disclaimer.
iva2k 0:e614f7875b60 25 * 2. Redistributions in binary form must reproduce the above copyright notice,
iva2k 0:e614f7875b60 26 * this list of conditions and the following disclaimer in the documentation
iva2k 0:e614f7875b60 27 * and/or other materials provided with the distribution.
iva2k 0:e614f7875b60 28 * 3. The name of the author may not be used to endorse or promote products
iva2k 0:e614f7875b60 29 * derived from this software without specific prior written permission.
iva2k 0:e614f7875b60 30 *
iva2k 0:e614f7875b60 31 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
iva2k 0:e614f7875b60 32 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
iva2k 0:e614f7875b60 33 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
iva2k 0:e614f7875b60 34 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
iva2k 0:e614f7875b60 35 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
iva2k 0:e614f7875b60 36 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
iva2k 0:e614f7875b60 37 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
iva2k 0:e614f7875b60 38 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
iva2k 0:e614f7875b60 39 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
iva2k 0:e614f7875b60 40 * OF SUCH DAMAGE.
iva2k 0:e614f7875b60 41 *
iva2k 0:e614f7875b60 42 * Author: Christiaan Simons <christiaan.simons@axon.tv>
iva2k 0:e614f7875b60 43 */
iva2k 0:e614f7875b60 44
iva2k 0:e614f7875b60 45 #include "lwip/opt.h"
iva2k 0:e614f7875b60 46
iva2k 0:e614f7875b60 47 #if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */
iva2k 0:e614f7875b60 48
iva2k 0:e614f7875b60 49 #include "lwip/udp.h"
iva2k 0:e614f7875b60 50 #include "lwip/netif.h"
iva2k 0:e614f7875b60 51 #include "lwip/snmp.h"
iva2k 0:e614f7875b60 52 #include "lwip/snmp_asn1.h"
iva2k 0:e614f7875b60 53 #include "lwip/snmp_msg.h"
iva2k 0:e614f7875b60 54
iva2k 0:e614f7875b60 55 struct snmp_trap_dst
iva2k 0:e614f7875b60 56 {
iva2k 0:e614f7875b60 57 /* destination IP address in network order */
iva2k 0:e614f7875b60 58 ip_addr_t dip;
iva2k 0:e614f7875b60 59 /* set to 0 when disabled, >0 when enabled */
iva2k 0:e614f7875b60 60 u8_t enable;
iva2k 0:e614f7875b60 61 };
iva2k 0:e614f7875b60 62 struct snmp_trap_dst trap_dst[SNMP_TRAP_DESTINATIONS];
iva2k 0:e614f7875b60 63
iva2k 0:e614f7875b60 64 /** TRAP message structure */
iva2k 0:e614f7875b60 65 struct snmp_msg_trap trap_msg;
iva2k 0:e614f7875b60 66
iva2k 0:e614f7875b60 67 static u16_t snmp_resp_header_sum(struct snmp_msg_pstat *m_stat, u16_t vb_len);
iva2k 0:e614f7875b60 68 static u16_t snmp_trap_header_sum(struct snmp_msg_trap *m_trap, u16_t vb_len);
iva2k 0:e614f7875b60 69 static u16_t snmp_varbind_list_sum(struct snmp_varbind_root *root);
iva2k 0:e614f7875b60 70
iva2k 0:e614f7875b60 71 static u16_t snmp_resp_header_enc(struct snmp_msg_pstat *m_stat, struct pbuf *p);
iva2k 0:e614f7875b60 72 static u16_t snmp_trap_header_enc(struct snmp_msg_trap *m_trap, struct pbuf *p);
iva2k 0:e614f7875b60 73 static u16_t snmp_varbind_list_enc(struct snmp_varbind_root *root, struct pbuf *p, u16_t ofs);
iva2k 0:e614f7875b60 74
iva2k 0:e614f7875b60 75 /**
iva2k 0:e614f7875b60 76 * Sets enable switch for this trap destination.
iva2k 0:e614f7875b60 77 * @param dst_idx index in 0 .. SNMP_TRAP_DESTINATIONS-1
iva2k 0:e614f7875b60 78 * @param enable switch if 0 destination is disabled >0 enabled.
iva2k 0:e614f7875b60 79 */
iva2k 0:e614f7875b60 80 void
iva2k 0:e614f7875b60 81 snmp_trap_dst_enable(u8_t dst_idx, u8_t enable)
iva2k 0:e614f7875b60 82 {
iva2k 0:e614f7875b60 83 if (dst_idx < SNMP_TRAP_DESTINATIONS)
iva2k 0:e614f7875b60 84 {
iva2k 0:e614f7875b60 85 trap_dst[dst_idx].enable = enable;
iva2k 0:e614f7875b60 86 }
iva2k 0:e614f7875b60 87 }
iva2k 0:e614f7875b60 88
iva2k 0:e614f7875b60 89 /**
iva2k 0:e614f7875b60 90 * Sets IPv4 address for this trap destination.
iva2k 0:e614f7875b60 91 * @param dst_idx index in 0 .. SNMP_TRAP_DESTINATIONS-1
iva2k 0:e614f7875b60 92 * @param dst IPv4 address in host order.
iva2k 0:e614f7875b60 93 */
iva2k 0:e614f7875b60 94 void
iva2k 0:e614f7875b60 95 snmp_trap_dst_ip_set(u8_t dst_idx, ip_addr_t *dst)
iva2k 0:e614f7875b60 96 {
iva2k 0:e614f7875b60 97 if (dst_idx < SNMP_TRAP_DESTINATIONS)
iva2k 0:e614f7875b60 98 {
iva2k 0:e614f7875b60 99 ip_addr_set_hton(&trap_dst[dst_idx].dip, dst);
iva2k 0:e614f7875b60 100 }
iva2k 0:e614f7875b60 101 }
iva2k 0:e614f7875b60 102
iva2k 0:e614f7875b60 103 /**
iva2k 0:e614f7875b60 104 * Sends a 'getresponse' message to the request originator.
iva2k 0:e614f7875b60 105 *
iva2k 0:e614f7875b60 106 * @param m_stat points to the current message request state source
iva2k 0:e614f7875b60 107 * @return ERR_OK when success, ERR_MEM if we're out of memory
iva2k 0:e614f7875b60 108 *
iva2k 0:e614f7875b60 109 * @note the caller is responsible for filling in outvb in the m_stat
iva2k 0:e614f7875b60 110 * and provide error-status and index (except for tooBig errors) ...
iva2k 0:e614f7875b60 111 */
iva2k 0:e614f7875b60 112 err_t
iva2k 0:e614f7875b60 113 snmp_send_response(struct snmp_msg_pstat *m_stat)
iva2k 0:e614f7875b60 114 {
iva2k 0:e614f7875b60 115 struct snmp_varbind_root emptyvb = {NULL, NULL, 0, 0, 0};
iva2k 0:e614f7875b60 116 struct pbuf *p;
iva2k 0:e614f7875b60 117 u16_t tot_len;
iva2k 0:e614f7875b60 118 err_t err;
iva2k 0:e614f7875b60 119
iva2k 0:e614f7875b60 120 /* pass 0, calculate length fields */
iva2k 0:e614f7875b60 121 tot_len = snmp_varbind_list_sum(&m_stat->outvb);
iva2k 0:e614f7875b60 122 tot_len = snmp_resp_header_sum(m_stat, tot_len);
iva2k 0:e614f7875b60 123
iva2k 0:e614f7875b60 124 /* try allocating pbuf(s) for complete response */
iva2k 0:e614f7875b60 125 p = pbuf_alloc(PBUF_TRANSPORT, tot_len, PBUF_POOL);
iva2k 0:e614f7875b60 126 if (p == NULL)
iva2k 0:e614f7875b60 127 {
iva2k 0:e614f7875b60 128 LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_snd_response() tooBig\n"));
iva2k 0:e614f7875b60 129
iva2k 0:e614f7875b60 130 /* can't construct reply, return error-status tooBig */
iva2k 0:e614f7875b60 131 m_stat->error_status = SNMP_ES_TOOBIG;
iva2k 0:e614f7875b60 132 m_stat->error_index = 0;
iva2k 0:e614f7875b60 133 /* pass 0, recalculate lengths, for empty varbind-list */
iva2k 0:e614f7875b60 134 tot_len = snmp_varbind_list_sum(&emptyvb);
iva2k 0:e614f7875b60 135 tot_len = snmp_resp_header_sum(m_stat, tot_len);
iva2k 0:e614f7875b60 136 /* retry allocation once for header and empty varbind-list */
iva2k 0:e614f7875b60 137 p = pbuf_alloc(PBUF_TRANSPORT, tot_len, PBUF_POOL);
iva2k 0:e614f7875b60 138 }
iva2k 0:e614f7875b60 139 if (p != NULL)
iva2k 0:e614f7875b60 140 {
iva2k 0:e614f7875b60 141 /* first pbuf alloc try or retry alloc success */
iva2k 0:e614f7875b60 142 u16_t ofs;
iva2k 0:e614f7875b60 143
iva2k 0:e614f7875b60 144 LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_snd_response() p != NULL\n"));
iva2k 0:e614f7875b60 145
iva2k 0:e614f7875b60 146 /* pass 1, size error, encode packet ino the pbuf(s) */
iva2k 0:e614f7875b60 147 ofs = snmp_resp_header_enc(m_stat, p);
iva2k 0:e614f7875b60 148 if (m_stat->error_status == SNMP_ES_TOOBIG)
iva2k 0:e614f7875b60 149 {
iva2k 0:e614f7875b60 150 snmp_varbind_list_enc(&emptyvb, p, ofs);
iva2k 0:e614f7875b60 151 }
iva2k 0:e614f7875b60 152 else
iva2k 0:e614f7875b60 153 {
iva2k 0:e614f7875b60 154 snmp_varbind_list_enc(&m_stat->outvb, p, ofs);
iva2k 0:e614f7875b60 155 }
iva2k 0:e614f7875b60 156
iva2k 0:e614f7875b60 157 switch (m_stat->error_status)
iva2k 0:e614f7875b60 158 {
iva2k 0:e614f7875b60 159 case SNMP_ES_TOOBIG:
iva2k 0:e614f7875b60 160 snmp_inc_snmpouttoobigs();
iva2k 0:e614f7875b60 161 break;
iva2k 0:e614f7875b60 162 case SNMP_ES_NOSUCHNAME:
iva2k 0:e614f7875b60 163 snmp_inc_snmpoutnosuchnames();
iva2k 0:e614f7875b60 164 break;
iva2k 0:e614f7875b60 165 case SNMP_ES_BADVALUE:
iva2k 0:e614f7875b60 166 snmp_inc_snmpoutbadvalues();
iva2k 0:e614f7875b60 167 break;
iva2k 0:e614f7875b60 168 case SNMP_ES_GENERROR:
iva2k 0:e614f7875b60 169 snmp_inc_snmpoutgenerrs();
iva2k 0:e614f7875b60 170 break;
iva2k 0:e614f7875b60 171 }
iva2k 0:e614f7875b60 172 snmp_inc_snmpoutgetresponses();
iva2k 0:e614f7875b60 173 snmp_inc_snmpoutpkts();
iva2k 0:e614f7875b60 174
iva2k 0:e614f7875b60 175 /** @todo do we need separate rx and tx pcbs for threaded case? */
iva2k 0:e614f7875b60 176 /** connect to the originating source */
iva2k 0:e614f7875b60 177 udp_connect(m_stat->pcb, &m_stat->sip, m_stat->sp);
iva2k 0:e614f7875b60 178 err = udp_send(m_stat->pcb, p);
iva2k 0:e614f7875b60 179 if (err == ERR_MEM)
iva2k 0:e614f7875b60 180 {
iva2k 0:e614f7875b60 181 /** @todo release some memory, retry and return tooBig? tooMuchHassle? */
iva2k 0:e614f7875b60 182 err = ERR_MEM;
iva2k 0:e614f7875b60 183 }
iva2k 0:e614f7875b60 184 else
iva2k 0:e614f7875b60 185 {
iva2k 0:e614f7875b60 186 err = ERR_OK;
iva2k 0:e614f7875b60 187 }
iva2k 0:e614f7875b60 188 /** disassociate remote address and port with this pcb */
iva2k 0:e614f7875b60 189 udp_disconnect(m_stat->pcb);
iva2k 0:e614f7875b60 190
iva2k 0:e614f7875b60 191 pbuf_free(p);
iva2k 0:e614f7875b60 192 LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_snd_response() done\n"));
iva2k 0:e614f7875b60 193 return err;
iva2k 0:e614f7875b60 194 }
iva2k 0:e614f7875b60 195 else
iva2k 0:e614f7875b60 196 {
iva2k 0:e614f7875b60 197 /* first pbuf alloc try or retry alloc failed
iva2k 0:e614f7875b60 198 very low on memory, couldn't return tooBig */
iva2k 0:e614f7875b60 199 return ERR_MEM;
iva2k 0:e614f7875b60 200 }
iva2k 0:e614f7875b60 201 }
iva2k 0:e614f7875b60 202
iva2k 0:e614f7875b60 203
iva2k 0:e614f7875b60 204 /**
iva2k 0:e614f7875b60 205 * Sends an generic or enterprise specific trap message.
iva2k 0:e614f7875b60 206 *
iva2k 0:e614f7875b60 207 * @param generic_trap is the trap code
iva2k 0:e614f7875b60 208 * @param eoid points to enterprise object identifier
iva2k 0:e614f7875b60 209 * @param specific_trap used for enterprise traps when generic_trap == 6
iva2k 0:e614f7875b60 210 * @return ERR_OK when success, ERR_MEM if we're out of memory
iva2k 0:e614f7875b60 211 *
iva2k 0:e614f7875b60 212 * @note the caller is responsible for filling in outvb in the trap_msg
iva2k 0:e614f7875b60 213 * @note the use of the enterpise identifier field
iva2k 0:e614f7875b60 214 * is per RFC1215.
iva2k 0:e614f7875b60 215 * Use .iso.org.dod.internet.mgmt.mib-2.snmp for generic traps
iva2k 0:e614f7875b60 216 * and .iso.org.dod.internet.private.enterprises.yourenterprise
iva2k 0:e614f7875b60 217 * (sysObjectID) for specific traps.
iva2k 0:e614f7875b60 218 */
iva2k 0:e614f7875b60 219 err_t
iva2k 0:e614f7875b60 220 snmp_send_trap(s8_t generic_trap, struct snmp_obj_id *eoid, s32_t specific_trap)
iva2k 0:e614f7875b60 221 {
iva2k 0:e614f7875b60 222 struct snmp_trap_dst *td;
iva2k 0:e614f7875b60 223 struct netif *dst_if;
iva2k 0:e614f7875b60 224 ip_addr_t dst_ip;
iva2k 0:e614f7875b60 225 struct pbuf *p;
iva2k 0:e614f7875b60 226 u16_t i,tot_len;
iva2k 0:e614f7875b60 227
iva2k 0:e614f7875b60 228 for (i=0, td = &trap_dst[0]; i<SNMP_TRAP_DESTINATIONS; i++, td++)
iva2k 0:e614f7875b60 229 {
iva2k 0:e614f7875b60 230 if ((td->enable != 0) && !ip_addr_isany(&td->dip))
iva2k 0:e614f7875b60 231 {
iva2k 0:e614f7875b60 232 /* network order trap destination */
iva2k 0:e614f7875b60 233 ip_addr_copy(trap_msg.dip, td->dip);
iva2k 0:e614f7875b60 234 /* lookup current source address for this dst */
iva2k 0:e614f7875b60 235 dst_if = ip_route(&td->dip);
iva2k 0:e614f7875b60 236 ip_addr_copy(dst_ip, dst_if->ip_addr);
iva2k 0:e614f7875b60 237 /* @todo: what about IPv6? */
iva2k 0:e614f7875b60 238 trap_msg.sip_raw[0] = ip4_addr1(&dst_ip);
iva2k 0:e614f7875b60 239 trap_msg.sip_raw[1] = ip4_addr2(&dst_ip);
iva2k 0:e614f7875b60 240 trap_msg.sip_raw[2] = ip4_addr3(&dst_ip);
iva2k 0:e614f7875b60 241 trap_msg.sip_raw[3] = ip4_addr4(&dst_ip);
iva2k 0:e614f7875b60 242 trap_msg.gen_trap = generic_trap;
iva2k 0:e614f7875b60 243 trap_msg.spc_trap = specific_trap;
iva2k 0:e614f7875b60 244 if (generic_trap == SNMP_GENTRAP_ENTERPRISESPC)
iva2k 0:e614f7875b60 245 {
iva2k 0:e614f7875b60 246 /* enterprise-Specific trap */
iva2k 0:e614f7875b60 247 trap_msg.enterprise = eoid;
iva2k 0:e614f7875b60 248 }
iva2k 0:e614f7875b60 249 else
iva2k 0:e614f7875b60 250 {
iva2k 0:e614f7875b60 251 /* generic (MIB-II) trap */
iva2k 0:e614f7875b60 252 snmp_get_snmpgrpid_ptr(&trap_msg.enterprise);
iva2k 0:e614f7875b60 253 }
iva2k 0:e614f7875b60 254 snmp_get_sysuptime(&trap_msg.ts);
iva2k 0:e614f7875b60 255
iva2k 0:e614f7875b60 256 /* pass 0, calculate length fields */
iva2k 0:e614f7875b60 257 tot_len = snmp_varbind_list_sum(&trap_msg.outvb);
iva2k 0:e614f7875b60 258 tot_len = snmp_trap_header_sum(&trap_msg, tot_len);
iva2k 0:e614f7875b60 259
iva2k 0:e614f7875b60 260 /* allocate pbuf(s) */
iva2k 0:e614f7875b60 261 p = pbuf_alloc(PBUF_TRANSPORT, tot_len, PBUF_POOL);
iva2k 0:e614f7875b60 262 if (p != NULL)
iva2k 0:e614f7875b60 263 {
iva2k 0:e614f7875b60 264 u16_t ofs;
iva2k 0:e614f7875b60 265
iva2k 0:e614f7875b60 266 /* pass 1, encode packet ino the pbuf(s) */
iva2k 0:e614f7875b60 267 ofs = snmp_trap_header_enc(&trap_msg, p);
iva2k 0:e614f7875b60 268 snmp_varbind_list_enc(&trap_msg.outvb, p, ofs);
iva2k 0:e614f7875b60 269
iva2k 0:e614f7875b60 270 snmp_inc_snmpouttraps();
iva2k 0:e614f7875b60 271 snmp_inc_snmpoutpkts();
iva2k 0:e614f7875b60 272
iva2k 0:e614f7875b60 273 /** connect to the TRAP destination */
iva2k 0:e614f7875b60 274 udp_connect(trap_msg.pcb, &trap_msg.dip, SNMP_TRAP_PORT);
iva2k 0:e614f7875b60 275 udp_send(trap_msg.pcb, p);
iva2k 0:e614f7875b60 276 /** disassociate remote address and port with this pcb */
iva2k 0:e614f7875b60 277 udp_disconnect(trap_msg.pcb);
iva2k 0:e614f7875b60 278
iva2k 0:e614f7875b60 279 pbuf_free(p);
iva2k 0:e614f7875b60 280 }
iva2k 0:e614f7875b60 281 else
iva2k 0:e614f7875b60 282 {
iva2k 0:e614f7875b60 283 return ERR_MEM;
iva2k 0:e614f7875b60 284 }
iva2k 0:e614f7875b60 285 }
iva2k 0:e614f7875b60 286 }
iva2k 0:e614f7875b60 287 return ERR_OK;
iva2k 0:e614f7875b60 288 }
iva2k 0:e614f7875b60 289
iva2k 0:e614f7875b60 290 void
iva2k 0:e614f7875b60 291 snmp_coldstart_trap(void)
iva2k 0:e614f7875b60 292 {
iva2k 0:e614f7875b60 293 trap_msg.outvb.head = NULL;
iva2k 0:e614f7875b60 294 trap_msg.outvb.tail = NULL;
iva2k 0:e614f7875b60 295 trap_msg.outvb.count = 0;
iva2k 0:e614f7875b60 296 snmp_send_trap(SNMP_GENTRAP_COLDSTART, NULL, 0);
iva2k 0:e614f7875b60 297 }
iva2k 0:e614f7875b60 298
iva2k 0:e614f7875b60 299 void
iva2k 0:e614f7875b60 300 snmp_authfail_trap(void)
iva2k 0:e614f7875b60 301 {
iva2k 0:e614f7875b60 302 u8_t enable;
iva2k 0:e614f7875b60 303 snmp_get_snmpenableauthentraps(&enable);
iva2k 0:e614f7875b60 304 if (enable == 1)
iva2k 0:e614f7875b60 305 {
iva2k 0:e614f7875b60 306 trap_msg.outvb.head = NULL;
iva2k 0:e614f7875b60 307 trap_msg.outvb.tail = NULL;
iva2k 0:e614f7875b60 308 trap_msg.outvb.count = 0;
iva2k 0:e614f7875b60 309 snmp_send_trap(SNMP_GENTRAP_AUTHFAIL, NULL, 0);
iva2k 0:e614f7875b60 310 }
iva2k 0:e614f7875b60 311 }
iva2k 0:e614f7875b60 312
iva2k 0:e614f7875b60 313 /**
iva2k 0:e614f7875b60 314 * Sums response header field lengths from tail to head and
iva2k 0:e614f7875b60 315 * returns resp_header_lengths for second encoding pass.
iva2k 0:e614f7875b60 316 *
iva2k 0:e614f7875b60 317 * @param vb_len varbind-list length
iva2k 0:e614f7875b60 318 * @param rhl points to returned header lengths
iva2k 0:e614f7875b60 319 * @return the required lenght for encoding the response header
iva2k 0:e614f7875b60 320 */
iva2k 0:e614f7875b60 321 static u16_t
iva2k 0:e614f7875b60 322 snmp_resp_header_sum(struct snmp_msg_pstat *m_stat, u16_t vb_len)
iva2k 0:e614f7875b60 323 {
iva2k 0:e614f7875b60 324 u16_t tot_len;
iva2k 0:e614f7875b60 325 struct snmp_resp_header_lengths *rhl;
iva2k 0:e614f7875b60 326
iva2k 0:e614f7875b60 327 rhl = &m_stat->rhl;
iva2k 0:e614f7875b60 328 tot_len = vb_len;
iva2k 0:e614f7875b60 329 snmp_asn1_enc_s32t_cnt(m_stat->error_index, &rhl->erridxlen);
iva2k 0:e614f7875b60 330 snmp_asn1_enc_length_cnt(rhl->erridxlen, &rhl->erridxlenlen);
iva2k 0:e614f7875b60 331 tot_len += 1 + rhl->erridxlenlen + rhl->erridxlen;
iva2k 0:e614f7875b60 332
iva2k 0:e614f7875b60 333 snmp_asn1_enc_s32t_cnt(m_stat->error_status, &rhl->errstatlen);
iva2k 0:e614f7875b60 334 snmp_asn1_enc_length_cnt(rhl->errstatlen, &rhl->errstatlenlen);
iva2k 0:e614f7875b60 335 tot_len += 1 + rhl->errstatlenlen + rhl->errstatlen;
iva2k 0:e614f7875b60 336
iva2k 0:e614f7875b60 337 snmp_asn1_enc_s32t_cnt(m_stat->rid, &rhl->ridlen);
iva2k 0:e614f7875b60 338 snmp_asn1_enc_length_cnt(rhl->ridlen, &rhl->ridlenlen);
iva2k 0:e614f7875b60 339 tot_len += 1 + rhl->ridlenlen + rhl->ridlen;
iva2k 0:e614f7875b60 340
iva2k 0:e614f7875b60 341 rhl->pdulen = tot_len;
iva2k 0:e614f7875b60 342 snmp_asn1_enc_length_cnt(rhl->pdulen, &rhl->pdulenlen);
iva2k 0:e614f7875b60 343 tot_len += 1 + rhl->pdulenlen;
iva2k 0:e614f7875b60 344
iva2k 0:e614f7875b60 345 rhl->comlen = m_stat->com_strlen;
iva2k 0:e614f7875b60 346 snmp_asn1_enc_length_cnt(rhl->comlen, &rhl->comlenlen);
iva2k 0:e614f7875b60 347 tot_len += 1 + rhl->comlenlen + rhl->comlen;
iva2k 0:e614f7875b60 348
iva2k 0:e614f7875b60 349 snmp_asn1_enc_s32t_cnt(snmp_version, &rhl->verlen);
iva2k 0:e614f7875b60 350 snmp_asn1_enc_length_cnt(rhl->verlen, &rhl->verlenlen);
iva2k 0:e614f7875b60 351 tot_len += 1 + rhl->verlen + rhl->verlenlen;
iva2k 0:e614f7875b60 352
iva2k 0:e614f7875b60 353 rhl->seqlen = tot_len;
iva2k 0:e614f7875b60 354 snmp_asn1_enc_length_cnt(rhl->seqlen, &rhl->seqlenlen);
iva2k 0:e614f7875b60 355 tot_len += 1 + rhl->seqlenlen;
iva2k 0:e614f7875b60 356
iva2k 0:e614f7875b60 357 return tot_len;
iva2k 0:e614f7875b60 358 }
iva2k 0:e614f7875b60 359
iva2k 0:e614f7875b60 360 /**
iva2k 0:e614f7875b60 361 * Sums trap header field lengths from tail to head and
iva2k 0:e614f7875b60 362 * returns trap_header_lengths for second encoding pass.
iva2k 0:e614f7875b60 363 *
iva2k 0:e614f7875b60 364 * @param vb_len varbind-list length
iva2k 0:e614f7875b60 365 * @param thl points to returned header lengths
iva2k 0:e614f7875b60 366 * @return the required lenght for encoding the trap header
iva2k 0:e614f7875b60 367 */
iva2k 0:e614f7875b60 368 static u16_t
iva2k 0:e614f7875b60 369 snmp_trap_header_sum(struct snmp_msg_trap *m_trap, u16_t vb_len)
iva2k 0:e614f7875b60 370 {
iva2k 0:e614f7875b60 371 u16_t tot_len;
iva2k 0:e614f7875b60 372 struct snmp_trap_header_lengths *thl;
iva2k 0:e614f7875b60 373
iva2k 0:e614f7875b60 374 thl = &m_trap->thl;
iva2k 0:e614f7875b60 375 tot_len = vb_len;
iva2k 0:e614f7875b60 376
iva2k 0:e614f7875b60 377 snmp_asn1_enc_u32t_cnt(m_trap->ts, &thl->tslen);
iva2k 0:e614f7875b60 378 snmp_asn1_enc_length_cnt(thl->tslen, &thl->tslenlen);
iva2k 0:e614f7875b60 379 tot_len += 1 + thl->tslen + thl->tslenlen;
iva2k 0:e614f7875b60 380
iva2k 0:e614f7875b60 381 snmp_asn1_enc_s32t_cnt(m_trap->spc_trap, &thl->strplen);
iva2k 0:e614f7875b60 382 snmp_asn1_enc_length_cnt(thl->strplen, &thl->strplenlen);
iva2k 0:e614f7875b60 383 tot_len += 1 + thl->strplen + thl->strplenlen;
iva2k 0:e614f7875b60 384
iva2k 0:e614f7875b60 385 snmp_asn1_enc_s32t_cnt(m_trap->gen_trap, &thl->gtrplen);
iva2k 0:e614f7875b60 386 snmp_asn1_enc_length_cnt(thl->gtrplen, &thl->gtrplenlen);
iva2k 0:e614f7875b60 387 tot_len += 1 + thl->gtrplen + thl->gtrplenlen;
iva2k 0:e614f7875b60 388
iva2k 0:e614f7875b60 389 thl->aaddrlen = 4;
iva2k 0:e614f7875b60 390 snmp_asn1_enc_length_cnt(thl->aaddrlen, &thl->aaddrlenlen);
iva2k 0:e614f7875b60 391 tot_len += 1 + thl->aaddrlen + thl->aaddrlenlen;
iva2k 0:e614f7875b60 392
iva2k 0:e614f7875b60 393 snmp_asn1_enc_oid_cnt(m_trap->enterprise->len, &m_trap->enterprise->id[0], &thl->eidlen);
iva2k 0:e614f7875b60 394 snmp_asn1_enc_length_cnt(thl->eidlen, &thl->eidlenlen);
iva2k 0:e614f7875b60 395 tot_len += 1 + thl->eidlen + thl->eidlenlen;
iva2k 0:e614f7875b60 396
iva2k 0:e614f7875b60 397 thl->pdulen = tot_len;
iva2k 0:e614f7875b60 398 snmp_asn1_enc_length_cnt(thl->pdulen, &thl->pdulenlen);
iva2k 0:e614f7875b60 399 tot_len += 1 + thl->pdulenlen;
iva2k 0:e614f7875b60 400
iva2k 0:e614f7875b60 401 thl->comlen = sizeof(snmp_publiccommunity) - 1;
iva2k 0:e614f7875b60 402 snmp_asn1_enc_length_cnt(thl->comlen, &thl->comlenlen);
iva2k 0:e614f7875b60 403 tot_len += 1 + thl->comlenlen + thl->comlen;
iva2k 0:e614f7875b60 404
iva2k 0:e614f7875b60 405 snmp_asn1_enc_s32t_cnt(snmp_version, &thl->verlen);
iva2k 0:e614f7875b60 406 snmp_asn1_enc_length_cnt(thl->verlen, &thl->verlenlen);
iva2k 0:e614f7875b60 407 tot_len += 1 + thl->verlen + thl->verlenlen;
iva2k 0:e614f7875b60 408
iva2k 0:e614f7875b60 409 thl->seqlen = tot_len;
iva2k 0:e614f7875b60 410 snmp_asn1_enc_length_cnt(thl->seqlen, &thl->seqlenlen);
iva2k 0:e614f7875b60 411 tot_len += 1 + thl->seqlenlen;
iva2k 0:e614f7875b60 412
iva2k 0:e614f7875b60 413 return tot_len;
iva2k 0:e614f7875b60 414 }
iva2k 0:e614f7875b60 415
iva2k 0:e614f7875b60 416 /**
iva2k 0:e614f7875b60 417 * Sums varbind lengths from tail to head and
iva2k 0:e614f7875b60 418 * annotates lengths in varbind for second encoding pass.
iva2k 0:e614f7875b60 419 *
iva2k 0:e614f7875b60 420 * @param root points to the root of the variable binding list
iva2k 0:e614f7875b60 421 * @return the required lenght for encoding the variable bindings
iva2k 0:e614f7875b60 422 */
iva2k 0:e614f7875b60 423 static u16_t
iva2k 0:e614f7875b60 424 snmp_varbind_list_sum(struct snmp_varbind_root *root)
iva2k 0:e614f7875b60 425 {
iva2k 0:e614f7875b60 426 struct snmp_varbind *vb;
iva2k 0:e614f7875b60 427 u32_t *uint_ptr;
iva2k 0:e614f7875b60 428 s32_t *sint_ptr;
iva2k 0:e614f7875b60 429 u16_t tot_len;
iva2k 0:e614f7875b60 430
iva2k 0:e614f7875b60 431 tot_len = 0;
iva2k 0:e614f7875b60 432 vb = root->tail;
iva2k 0:e614f7875b60 433 while ( vb != NULL )
iva2k 0:e614f7875b60 434 {
iva2k 0:e614f7875b60 435 /* encoded value lenght depends on type */
iva2k 0:e614f7875b60 436 switch (vb->value_type)
iva2k 0:e614f7875b60 437 {
iva2k 0:e614f7875b60 438 case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG):
iva2k 0:e614f7875b60 439 sint_ptr = (s32_t*)vb->value;
iva2k 0:e614f7875b60 440 snmp_asn1_enc_s32t_cnt(*sint_ptr, &vb->vlen);
iva2k 0:e614f7875b60 441 break;
iva2k 0:e614f7875b60 442 case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER):
iva2k 0:e614f7875b60 443 case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_GAUGE):
iva2k 0:e614f7875b60 444 case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_TIMETICKS):
iva2k 0:e614f7875b60 445 uint_ptr = (u32_t*)vb->value;
iva2k 0:e614f7875b60 446 snmp_asn1_enc_u32t_cnt(*uint_ptr, &vb->vlen);
iva2k 0:e614f7875b60 447 break;
iva2k 0:e614f7875b60 448 case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR):
iva2k 0:e614f7875b60 449 case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_NUL):
iva2k 0:e614f7875b60 450 case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR):
iva2k 0:e614f7875b60 451 case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_OPAQUE):
iva2k 0:e614f7875b60 452 vb->vlen = vb->value_len;
iva2k 0:e614f7875b60 453 break;
iva2k 0:e614f7875b60 454 case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID):
iva2k 0:e614f7875b60 455 sint_ptr = (s32_t*)vb->value;
iva2k 0:e614f7875b60 456 snmp_asn1_enc_oid_cnt(vb->value_len / sizeof(s32_t), sint_ptr, &vb->vlen);
iva2k 0:e614f7875b60 457 break;
iva2k 0:e614f7875b60 458 default:
iva2k 0:e614f7875b60 459 /* unsupported type */
iva2k 0:e614f7875b60 460 vb->vlen = 0;
iva2k 0:e614f7875b60 461 break;
iva2k 0:e614f7875b60 462 };
iva2k 0:e614f7875b60 463 /* encoding length of value length field */
iva2k 0:e614f7875b60 464 snmp_asn1_enc_length_cnt(vb->vlen, &vb->vlenlen);
iva2k 0:e614f7875b60 465 snmp_asn1_enc_oid_cnt(vb->ident_len, vb->ident, &vb->olen);
iva2k 0:e614f7875b60 466 snmp_asn1_enc_length_cnt(vb->olen, &vb->olenlen);
iva2k 0:e614f7875b60 467
iva2k 0:e614f7875b60 468 vb->seqlen = 1 + vb->vlenlen + vb->vlen;
iva2k 0:e614f7875b60 469 vb->seqlen += 1 + vb->olenlen + vb->olen;
iva2k 0:e614f7875b60 470 snmp_asn1_enc_length_cnt(vb->seqlen, &vb->seqlenlen);
iva2k 0:e614f7875b60 471
iva2k 0:e614f7875b60 472 /* varbind seq */
iva2k 0:e614f7875b60 473 tot_len += 1 + vb->seqlenlen + vb->seqlen;
iva2k 0:e614f7875b60 474
iva2k 0:e614f7875b60 475 vb = vb->prev;
iva2k 0:e614f7875b60 476 }
iva2k 0:e614f7875b60 477
iva2k 0:e614f7875b60 478 /* varbind-list seq */
iva2k 0:e614f7875b60 479 root->seqlen = tot_len;
iva2k 0:e614f7875b60 480 snmp_asn1_enc_length_cnt(root->seqlen, &root->seqlenlen);
iva2k 0:e614f7875b60 481 tot_len += 1 + root->seqlenlen;
iva2k 0:e614f7875b60 482
iva2k 0:e614f7875b60 483 return tot_len;
iva2k 0:e614f7875b60 484 }
iva2k 0:e614f7875b60 485
iva2k 0:e614f7875b60 486 /**
iva2k 0:e614f7875b60 487 * Encodes response header from head to tail.
iva2k 0:e614f7875b60 488 */
iva2k 0:e614f7875b60 489 static u16_t
iva2k 0:e614f7875b60 490 snmp_resp_header_enc(struct snmp_msg_pstat *m_stat, struct pbuf *p)
iva2k 0:e614f7875b60 491 {
iva2k 0:e614f7875b60 492 u16_t ofs;
iva2k 0:e614f7875b60 493
iva2k 0:e614f7875b60 494 ofs = 0;
iva2k 0:e614f7875b60 495 snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_CONSTR | SNMP_ASN1_SEQ));
iva2k 0:e614f7875b60 496 ofs += 1;
iva2k 0:e614f7875b60 497 snmp_asn1_enc_length(p, ofs, m_stat->rhl.seqlen);
iva2k 0:e614f7875b60 498 ofs += m_stat->rhl.seqlenlen;
iva2k 0:e614f7875b60 499
iva2k 0:e614f7875b60 500 snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG));
iva2k 0:e614f7875b60 501 ofs += 1;
iva2k 0:e614f7875b60 502 snmp_asn1_enc_length(p, ofs, m_stat->rhl.verlen);
iva2k 0:e614f7875b60 503 ofs += m_stat->rhl.verlenlen;
iva2k 0:e614f7875b60 504 snmp_asn1_enc_s32t(p, ofs, m_stat->rhl.verlen, snmp_version);
iva2k 0:e614f7875b60 505 ofs += m_stat->rhl.verlen;
iva2k 0:e614f7875b60 506
iva2k 0:e614f7875b60 507 snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR));
iva2k 0:e614f7875b60 508 ofs += 1;
iva2k 0:e614f7875b60 509 snmp_asn1_enc_length(p, ofs, m_stat->rhl.comlen);
iva2k 0:e614f7875b60 510 ofs += m_stat->rhl.comlenlen;
iva2k 0:e614f7875b60 511 snmp_asn1_enc_raw(p, ofs, m_stat->rhl.comlen, m_stat->community);
iva2k 0:e614f7875b60 512 ofs += m_stat->rhl.comlen;
iva2k 0:e614f7875b60 513
iva2k 0:e614f7875b60 514 snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_GET_RESP));
iva2k 0:e614f7875b60 515 ofs += 1;
iva2k 0:e614f7875b60 516 snmp_asn1_enc_length(p, ofs, m_stat->rhl.pdulen);
iva2k 0:e614f7875b60 517 ofs += m_stat->rhl.pdulenlen;
iva2k 0:e614f7875b60 518
iva2k 0:e614f7875b60 519 snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG));
iva2k 0:e614f7875b60 520 ofs += 1;
iva2k 0:e614f7875b60 521 snmp_asn1_enc_length(p, ofs, m_stat->rhl.ridlen);
iva2k 0:e614f7875b60 522 ofs += m_stat->rhl.ridlenlen;
iva2k 0:e614f7875b60 523 snmp_asn1_enc_s32t(p, ofs, m_stat->rhl.ridlen, m_stat->rid);
iva2k 0:e614f7875b60 524 ofs += m_stat->rhl.ridlen;
iva2k 0:e614f7875b60 525
iva2k 0:e614f7875b60 526 snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG));
iva2k 0:e614f7875b60 527 ofs += 1;
iva2k 0:e614f7875b60 528 snmp_asn1_enc_length(p, ofs, m_stat->rhl.errstatlen);
iva2k 0:e614f7875b60 529 ofs += m_stat->rhl.errstatlenlen;
iva2k 0:e614f7875b60 530 snmp_asn1_enc_s32t(p, ofs, m_stat->rhl.errstatlen, m_stat->error_status);
iva2k 0:e614f7875b60 531 ofs += m_stat->rhl.errstatlen;
iva2k 0:e614f7875b60 532
iva2k 0:e614f7875b60 533 snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG));
iva2k 0:e614f7875b60 534 ofs += 1;
iva2k 0:e614f7875b60 535 snmp_asn1_enc_length(p, ofs, m_stat->rhl.erridxlen);
iva2k 0:e614f7875b60 536 ofs += m_stat->rhl.erridxlenlen;
iva2k 0:e614f7875b60 537 snmp_asn1_enc_s32t(p, ofs, m_stat->rhl.erridxlen, m_stat->error_index);
iva2k 0:e614f7875b60 538 ofs += m_stat->rhl.erridxlen;
iva2k 0:e614f7875b60 539
iva2k 0:e614f7875b60 540 return ofs;
iva2k 0:e614f7875b60 541 }
iva2k 0:e614f7875b60 542
iva2k 0:e614f7875b60 543 /**
iva2k 0:e614f7875b60 544 * Encodes trap header from head to tail.
iva2k 0:e614f7875b60 545 */
iva2k 0:e614f7875b60 546 static u16_t
iva2k 0:e614f7875b60 547 snmp_trap_header_enc(struct snmp_msg_trap *m_trap, struct pbuf *p)
iva2k 0:e614f7875b60 548 {
iva2k 0:e614f7875b60 549 u16_t ofs;
iva2k 0:e614f7875b60 550
iva2k 0:e614f7875b60 551 ofs = 0;
iva2k 0:e614f7875b60 552 snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_CONSTR | SNMP_ASN1_SEQ));
iva2k 0:e614f7875b60 553 ofs += 1;
iva2k 0:e614f7875b60 554 snmp_asn1_enc_length(p, ofs, m_trap->thl.seqlen);
iva2k 0:e614f7875b60 555 ofs += m_trap->thl.seqlenlen;
iva2k 0:e614f7875b60 556
iva2k 0:e614f7875b60 557 snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG));
iva2k 0:e614f7875b60 558 ofs += 1;
iva2k 0:e614f7875b60 559 snmp_asn1_enc_length(p, ofs, m_trap->thl.verlen);
iva2k 0:e614f7875b60 560 ofs += m_trap->thl.verlenlen;
iva2k 0:e614f7875b60 561 snmp_asn1_enc_s32t(p, ofs, m_trap->thl.verlen, snmp_version);
iva2k 0:e614f7875b60 562 ofs += m_trap->thl.verlen;
iva2k 0:e614f7875b60 563
iva2k 0:e614f7875b60 564 snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR));
iva2k 0:e614f7875b60 565 ofs += 1;
iva2k 0:e614f7875b60 566 snmp_asn1_enc_length(p, ofs, m_trap->thl.comlen);
iva2k 0:e614f7875b60 567 ofs += m_trap->thl.comlenlen;
iva2k 0:e614f7875b60 568 snmp_asn1_enc_raw(p, ofs, m_trap->thl.comlen, (u8_t *)&snmp_publiccommunity[0]);
iva2k 0:e614f7875b60 569 ofs += m_trap->thl.comlen;
iva2k 0:e614f7875b60 570
iva2k 0:e614f7875b60 571 snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_TRAP));
iva2k 0:e614f7875b60 572 ofs += 1;
iva2k 0:e614f7875b60 573 snmp_asn1_enc_length(p, ofs, m_trap->thl.pdulen);
iva2k 0:e614f7875b60 574 ofs += m_trap->thl.pdulenlen;
iva2k 0:e614f7875b60 575
iva2k 0:e614f7875b60 576 snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID));
iva2k 0:e614f7875b60 577 ofs += 1;
iva2k 0:e614f7875b60 578 snmp_asn1_enc_length(p, ofs, m_trap->thl.eidlen);
iva2k 0:e614f7875b60 579 ofs += m_trap->thl.eidlenlen;
iva2k 0:e614f7875b60 580 snmp_asn1_enc_oid(p, ofs, m_trap->enterprise->len, &m_trap->enterprise->id[0]);
iva2k 0:e614f7875b60 581 ofs += m_trap->thl.eidlen;
iva2k 0:e614f7875b60 582
iva2k 0:e614f7875b60 583 snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR));
iva2k 0:e614f7875b60 584 ofs += 1;
iva2k 0:e614f7875b60 585 snmp_asn1_enc_length(p, ofs, m_trap->thl.aaddrlen);
iva2k 0:e614f7875b60 586 ofs += m_trap->thl.aaddrlenlen;
iva2k 0:e614f7875b60 587 snmp_asn1_enc_raw(p, ofs, m_trap->thl.aaddrlen, &m_trap->sip_raw[0]);
iva2k 0:e614f7875b60 588 ofs += m_trap->thl.aaddrlen;
iva2k 0:e614f7875b60 589
iva2k 0:e614f7875b60 590 snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG));
iva2k 0:e614f7875b60 591 ofs += 1;
iva2k 0:e614f7875b60 592 snmp_asn1_enc_length(p, ofs, m_trap->thl.gtrplen);
iva2k 0:e614f7875b60 593 ofs += m_trap->thl.gtrplenlen;
iva2k 0:e614f7875b60 594 snmp_asn1_enc_u32t(p, ofs, m_trap->thl.gtrplen, m_trap->gen_trap);
iva2k 0:e614f7875b60 595 ofs += m_trap->thl.gtrplen;
iva2k 0:e614f7875b60 596
iva2k 0:e614f7875b60 597 snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG));
iva2k 0:e614f7875b60 598 ofs += 1;
iva2k 0:e614f7875b60 599 snmp_asn1_enc_length(p, ofs, m_trap->thl.strplen);
iva2k 0:e614f7875b60 600 ofs += m_trap->thl.strplenlen;
iva2k 0:e614f7875b60 601 snmp_asn1_enc_u32t(p, ofs, m_trap->thl.strplen, m_trap->spc_trap);
iva2k 0:e614f7875b60 602 ofs += m_trap->thl.strplen;
iva2k 0:e614f7875b60 603
iva2k 0:e614f7875b60 604 snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_TIMETICKS));
iva2k 0:e614f7875b60 605 ofs += 1;
iva2k 0:e614f7875b60 606 snmp_asn1_enc_length(p, ofs, m_trap->thl.tslen);
iva2k 0:e614f7875b60 607 ofs += m_trap->thl.tslenlen;
iva2k 0:e614f7875b60 608 snmp_asn1_enc_u32t(p, ofs, m_trap->thl.tslen, m_trap->ts);
iva2k 0:e614f7875b60 609 ofs += m_trap->thl.tslen;
iva2k 0:e614f7875b60 610
iva2k 0:e614f7875b60 611 return ofs;
iva2k 0:e614f7875b60 612 }
iva2k 0:e614f7875b60 613
iva2k 0:e614f7875b60 614 /**
iva2k 0:e614f7875b60 615 * Encodes varbind list from head to tail.
iva2k 0:e614f7875b60 616 */
iva2k 0:e614f7875b60 617 static u16_t
iva2k 0:e614f7875b60 618 snmp_varbind_list_enc(struct snmp_varbind_root *root, struct pbuf *p, u16_t ofs)
iva2k 0:e614f7875b60 619 {
iva2k 0:e614f7875b60 620 struct snmp_varbind *vb;
iva2k 0:e614f7875b60 621 s32_t *sint_ptr;
iva2k 0:e614f7875b60 622 u32_t *uint_ptr;
iva2k 0:e614f7875b60 623 u8_t *raw_ptr;
iva2k 0:e614f7875b60 624
iva2k 0:e614f7875b60 625 snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_CONSTR | SNMP_ASN1_SEQ));
iva2k 0:e614f7875b60 626 ofs += 1;
iva2k 0:e614f7875b60 627 snmp_asn1_enc_length(p, ofs, root->seqlen);
iva2k 0:e614f7875b60 628 ofs += root->seqlenlen;
iva2k 0:e614f7875b60 629
iva2k 0:e614f7875b60 630 vb = root->head;
iva2k 0:e614f7875b60 631 while ( vb != NULL )
iva2k 0:e614f7875b60 632 {
iva2k 0:e614f7875b60 633 snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_CONSTR | SNMP_ASN1_SEQ));
iva2k 0:e614f7875b60 634 ofs += 1;
iva2k 0:e614f7875b60 635 snmp_asn1_enc_length(p, ofs, vb->seqlen);
iva2k 0:e614f7875b60 636 ofs += vb->seqlenlen;
iva2k 0:e614f7875b60 637
iva2k 0:e614f7875b60 638 snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID));
iva2k 0:e614f7875b60 639 ofs += 1;
iva2k 0:e614f7875b60 640 snmp_asn1_enc_length(p, ofs, vb->olen);
iva2k 0:e614f7875b60 641 ofs += vb->olenlen;
iva2k 0:e614f7875b60 642 snmp_asn1_enc_oid(p, ofs, vb->ident_len, &vb->ident[0]);
iva2k 0:e614f7875b60 643 ofs += vb->olen;
iva2k 0:e614f7875b60 644
iva2k 0:e614f7875b60 645 snmp_asn1_enc_type(p, ofs, vb->value_type);
iva2k 0:e614f7875b60 646 ofs += 1;
iva2k 0:e614f7875b60 647 snmp_asn1_enc_length(p, ofs, vb->vlen);
iva2k 0:e614f7875b60 648 ofs += vb->vlenlen;
iva2k 0:e614f7875b60 649
iva2k 0:e614f7875b60 650 switch (vb->value_type)
iva2k 0:e614f7875b60 651 {
iva2k 0:e614f7875b60 652 case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG):
iva2k 0:e614f7875b60 653 sint_ptr = (s32_t*)vb->value;
iva2k 0:e614f7875b60 654 snmp_asn1_enc_s32t(p, ofs, vb->vlen, *sint_ptr);
iva2k 0:e614f7875b60 655 break;
iva2k 0:e614f7875b60 656 case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER):
iva2k 0:e614f7875b60 657 case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_GAUGE):
iva2k 0:e614f7875b60 658 case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_TIMETICKS):
iva2k 0:e614f7875b60 659 uint_ptr = (u32_t*)vb->value;
iva2k 0:e614f7875b60 660 snmp_asn1_enc_u32t(p, ofs, vb->vlen, *uint_ptr);
iva2k 0:e614f7875b60 661 break;
iva2k 0:e614f7875b60 662 case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR):
iva2k 0:e614f7875b60 663 case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR):
iva2k 0:e614f7875b60 664 case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_OPAQUE):
iva2k 0:e614f7875b60 665 raw_ptr = (u8_t*)vb->value;
iva2k 0:e614f7875b60 666 snmp_asn1_enc_raw(p, ofs, vb->vlen, raw_ptr);
iva2k 0:e614f7875b60 667 break;
iva2k 0:e614f7875b60 668 case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_NUL):
iva2k 0:e614f7875b60 669 break;
iva2k 0:e614f7875b60 670 case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID):
iva2k 0:e614f7875b60 671 sint_ptr = (s32_t*)vb->value;
iva2k 0:e614f7875b60 672 snmp_asn1_enc_oid(p, ofs, vb->value_len / sizeof(s32_t), sint_ptr);
iva2k 0:e614f7875b60 673 break;
iva2k 0:e614f7875b60 674 default:
iva2k 0:e614f7875b60 675 /* unsupported type */
iva2k 0:e614f7875b60 676 break;
iva2k 0:e614f7875b60 677 };
iva2k 0:e614f7875b60 678 ofs += vb->vlen;
iva2k 0:e614f7875b60 679 vb = vb->next;
iva2k 0:e614f7875b60 680 }
iva2k 0:e614f7875b60 681 return ofs;
iva2k 0:e614f7875b60 682 }
iva2k 0:e614f7875b60 683
iva2k 0:e614f7875b60 684 #endif /* LWIP_SNMP */