1195972f6Sopenharmony_ci/** 2195972f6Sopenharmony_ci * @file 3195972f6Sopenharmony_ci * SNMPv1 traps implementation. 4195972f6Sopenharmony_ci */ 5195972f6Sopenharmony_ci 6195972f6Sopenharmony_ci/* 7195972f6Sopenharmony_ci * Copyright (c) 2001-2004 Swedish Institute of Computer Science. 8195972f6Sopenharmony_ci * All rights reserved. 9195972f6Sopenharmony_ci * 10195972f6Sopenharmony_ci * Redistribution and use in source and binary forms, with or without modification, 11195972f6Sopenharmony_ci * are permitted provided that the following conditions are met: 12195972f6Sopenharmony_ci * 13195972f6Sopenharmony_ci * 1. Redistributions of source code must retain the above copyright notice, 14195972f6Sopenharmony_ci * this list of conditions and the following disclaimer. 15195972f6Sopenharmony_ci * 2. Redistributions in binary form must reproduce the above copyright notice, 16195972f6Sopenharmony_ci * this list of conditions and the following disclaimer in the documentation 17195972f6Sopenharmony_ci * and/or other materials provided with the distribution. 18195972f6Sopenharmony_ci * 3. The name of the author may not be used to endorse or promote products 19195972f6Sopenharmony_ci * derived from this software without specific prior written permission. 20195972f6Sopenharmony_ci * 21195972f6Sopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 22195972f6Sopenharmony_ci * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 23195972f6Sopenharmony_ci * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 24195972f6Sopenharmony_ci * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 25195972f6Sopenharmony_ci * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 26195972f6Sopenharmony_ci * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27195972f6Sopenharmony_ci * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28195972f6Sopenharmony_ci * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 29195972f6Sopenharmony_ci * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 30195972f6Sopenharmony_ci * OF SUCH DAMAGE. 31195972f6Sopenharmony_ci * 32195972f6Sopenharmony_ci * This file is part of the lwIP TCP/IP stack. 33195972f6Sopenharmony_ci * 34195972f6Sopenharmony_ci * Author: Martin Hentschel 35195972f6Sopenharmony_ci * Christiaan Simons <christiaan.simons@axon.tv> 36195972f6Sopenharmony_ci * 37195972f6Sopenharmony_ci */ 38195972f6Sopenharmony_ci 39195972f6Sopenharmony_ci#include "lwip/apps/snmp_opts.h" 40195972f6Sopenharmony_ci 41195972f6Sopenharmony_ci#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ 42195972f6Sopenharmony_ci 43195972f6Sopenharmony_ci#include <string.h> 44195972f6Sopenharmony_ci 45195972f6Sopenharmony_ci#include "lwip/snmp.h" 46195972f6Sopenharmony_ci#include "lwip/sys.h" 47195972f6Sopenharmony_ci#include "lwip/apps/snmp.h" 48195972f6Sopenharmony_ci#include "lwip/apps/snmp_core.h" 49195972f6Sopenharmony_ci#include "lwip/prot/iana.h" 50195972f6Sopenharmony_ci#include "snmp_msg.h" 51195972f6Sopenharmony_ci#include "snmp_asn1.h" 52195972f6Sopenharmony_ci#include "snmp_core_priv.h" 53195972f6Sopenharmony_ci 54195972f6Sopenharmony_cistruct snmp_msg_trap { 55195972f6Sopenharmony_ci /* source enterprise ID (sysObjectID) */ 56195972f6Sopenharmony_ci const struct snmp_obj_id *enterprise; 57195972f6Sopenharmony_ci /* source IP address, raw network order format */ 58195972f6Sopenharmony_ci ip_addr_t sip; 59195972f6Sopenharmony_ci /* generic trap code */ 60195972f6Sopenharmony_ci u32_t gen_trap; 61195972f6Sopenharmony_ci /* specific trap code */ 62195972f6Sopenharmony_ci u32_t spc_trap; 63195972f6Sopenharmony_ci /* timestamp */ 64195972f6Sopenharmony_ci u32_t ts; 65195972f6Sopenharmony_ci /* snmp_version */ 66195972f6Sopenharmony_ci u32_t snmp_version; 67195972f6Sopenharmony_ci 68195972f6Sopenharmony_ci /* output trap lengths used in ASN encoding */ 69195972f6Sopenharmony_ci /* encoding pdu length */ 70195972f6Sopenharmony_ci u16_t pdulen; 71195972f6Sopenharmony_ci /* encoding community length */ 72195972f6Sopenharmony_ci u16_t comlen; 73195972f6Sopenharmony_ci /* encoding sequence length */ 74195972f6Sopenharmony_ci u16_t seqlen; 75195972f6Sopenharmony_ci /* encoding varbinds sequence length */ 76195972f6Sopenharmony_ci u16_t vbseqlen; 77195972f6Sopenharmony_ci}; 78195972f6Sopenharmony_ci 79195972f6Sopenharmony_cistatic u16_t snmp_trap_varbind_sum(struct snmp_msg_trap *trap, struct snmp_varbind *varbinds); 80195972f6Sopenharmony_cistatic u16_t snmp_trap_header_sum(struct snmp_msg_trap *trap, u16_t vb_len); 81195972f6Sopenharmony_cistatic err_t snmp_trap_header_enc(struct snmp_msg_trap *trap, struct snmp_pbuf_stream *pbuf_stream); 82195972f6Sopenharmony_cistatic err_t snmp_trap_varbind_enc(struct snmp_msg_trap *trap, struct snmp_pbuf_stream *pbuf_stream, struct snmp_varbind *varbinds); 83195972f6Sopenharmony_ci 84195972f6Sopenharmony_ci#define BUILD_EXEC(code) \ 85195972f6Sopenharmony_ci if ((code) != ERR_OK) { \ 86195972f6Sopenharmony_ci LWIP_DEBUGF(SNMP_DEBUG, ("SNMP error during creation of outbound trap frame!")); \ 87195972f6Sopenharmony_ci return ERR_ARG; \ 88195972f6Sopenharmony_ci } 89195972f6Sopenharmony_ci 90195972f6Sopenharmony_ci/** Agent community string for sending traps */ 91195972f6Sopenharmony_ciextern const char *snmp_community_trap; 92195972f6Sopenharmony_ci 93195972f6Sopenharmony_civoid *snmp_traps_handle; 94195972f6Sopenharmony_ci 95195972f6Sopenharmony_cistruct snmp_trap_dst { 96195972f6Sopenharmony_ci /* destination IP address in network order */ 97195972f6Sopenharmony_ci ip_addr_t dip; 98195972f6Sopenharmony_ci /* set to 0 when disabled, >0 when enabled */ 99195972f6Sopenharmony_ci u8_t enable; 100195972f6Sopenharmony_ci}; 101195972f6Sopenharmony_cistatic struct snmp_trap_dst trap_dst[SNMP_TRAP_DESTINATIONS]; 102195972f6Sopenharmony_ci 103195972f6Sopenharmony_cistatic u8_t snmp_auth_traps_enabled = 0; 104195972f6Sopenharmony_ci 105195972f6Sopenharmony_ci/** 106195972f6Sopenharmony_ci * @ingroup snmp_traps 107195972f6Sopenharmony_ci * Sets enable switch for this trap destination. 108195972f6Sopenharmony_ci * @param dst_idx index in 0 .. SNMP_TRAP_DESTINATIONS-1 109195972f6Sopenharmony_ci * @param enable switch if 0 destination is disabled >0 enabled. 110195972f6Sopenharmony_ci */ 111195972f6Sopenharmony_civoid 112195972f6Sopenharmony_cisnmp_trap_dst_enable(u8_t dst_idx, u8_t enable) 113195972f6Sopenharmony_ci{ 114195972f6Sopenharmony_ci LWIP_ASSERT_CORE_LOCKED(); 115195972f6Sopenharmony_ci if (dst_idx < SNMP_TRAP_DESTINATIONS) { 116195972f6Sopenharmony_ci trap_dst[dst_idx].enable = enable; 117195972f6Sopenharmony_ci } 118195972f6Sopenharmony_ci} 119195972f6Sopenharmony_ci 120195972f6Sopenharmony_ci/** 121195972f6Sopenharmony_ci * @ingroup snmp_traps 122195972f6Sopenharmony_ci * Sets IPv4 address for this trap destination. 123195972f6Sopenharmony_ci * @param dst_idx index in 0 .. SNMP_TRAP_DESTINATIONS-1 124195972f6Sopenharmony_ci * @param dst IPv4 address in host order. 125195972f6Sopenharmony_ci */ 126195972f6Sopenharmony_civoid 127195972f6Sopenharmony_cisnmp_trap_dst_ip_set(u8_t dst_idx, const ip_addr_t *dst) 128195972f6Sopenharmony_ci{ 129195972f6Sopenharmony_ci LWIP_ASSERT_CORE_LOCKED(); 130195972f6Sopenharmony_ci if (dst_idx < SNMP_TRAP_DESTINATIONS) { 131195972f6Sopenharmony_ci ip_addr_set(&trap_dst[dst_idx].dip, dst); 132195972f6Sopenharmony_ci } 133195972f6Sopenharmony_ci} 134195972f6Sopenharmony_ci 135195972f6Sopenharmony_ci/** 136195972f6Sopenharmony_ci * @ingroup snmp_traps 137195972f6Sopenharmony_ci * Enable/disable authentication traps 138195972f6Sopenharmony_ci */ 139195972f6Sopenharmony_civoid 140195972f6Sopenharmony_cisnmp_set_auth_traps_enabled(u8_t enable) 141195972f6Sopenharmony_ci{ 142195972f6Sopenharmony_ci snmp_auth_traps_enabled = enable; 143195972f6Sopenharmony_ci} 144195972f6Sopenharmony_ci 145195972f6Sopenharmony_ci/** 146195972f6Sopenharmony_ci * @ingroup snmp_traps 147195972f6Sopenharmony_ci * Get authentication traps enabled state 148195972f6Sopenharmony_ci */ 149195972f6Sopenharmony_ciu8_t 150195972f6Sopenharmony_cisnmp_get_auth_traps_enabled(void) 151195972f6Sopenharmony_ci{ 152195972f6Sopenharmony_ci return snmp_auth_traps_enabled; 153195972f6Sopenharmony_ci} 154195972f6Sopenharmony_ci 155195972f6Sopenharmony_ci 156195972f6Sopenharmony_ci/** 157195972f6Sopenharmony_ci * @ingroup snmp_traps 158195972f6Sopenharmony_ci * Sends a generic or enterprise specific trap message. 159195972f6Sopenharmony_ci * 160195972f6Sopenharmony_ci * @param eoid points to enterprise object identifier 161195972f6Sopenharmony_ci * @param generic_trap is the trap code 162195972f6Sopenharmony_ci * @param specific_trap used for enterprise traps when generic_trap == 6 163195972f6Sopenharmony_ci * @param varbinds linked list of varbinds to be sent 164195972f6Sopenharmony_ci * @return ERR_OK when success, ERR_MEM if we're out of memory 165195972f6Sopenharmony_ci * 166195972f6Sopenharmony_ci * @note the use of the enterprise identifier field 167195972f6Sopenharmony_ci * is per RFC1215. 168195972f6Sopenharmony_ci * Use .iso.org.dod.internet.mgmt.mib-2.snmp for generic traps 169195972f6Sopenharmony_ci * and .iso.org.dod.internet.private.enterprises.yourenterprise 170195972f6Sopenharmony_ci * (sysObjectID) for specific traps. 171195972f6Sopenharmony_ci */ 172195972f6Sopenharmony_cierr_t 173195972f6Sopenharmony_cisnmp_send_trap(const struct snmp_obj_id *eoid, s32_t generic_trap, s32_t specific_trap, struct snmp_varbind *varbinds) 174195972f6Sopenharmony_ci{ 175195972f6Sopenharmony_ci struct snmp_msg_trap trap_msg; 176195972f6Sopenharmony_ci struct snmp_trap_dst *td; 177195972f6Sopenharmony_ci struct pbuf *p; 178195972f6Sopenharmony_ci u16_t i, tot_len; 179195972f6Sopenharmony_ci err_t err = ERR_OK; 180195972f6Sopenharmony_ci 181195972f6Sopenharmony_ci LWIP_ASSERT_CORE_LOCKED(); 182195972f6Sopenharmony_ci 183195972f6Sopenharmony_ci trap_msg.snmp_version = 0; 184195972f6Sopenharmony_ci 185195972f6Sopenharmony_ci for (i = 0, td = &trap_dst[0]; i < SNMP_TRAP_DESTINATIONS; i++, td++) { 186195972f6Sopenharmony_ci if ((td->enable != 0) && !ip_addr_isany(&td->dip)) { 187195972f6Sopenharmony_ci /* lookup current source address for this dst */ 188195972f6Sopenharmony_ci if (snmp_get_local_ip_for_dst(snmp_traps_handle, &td->dip, &trap_msg.sip)) { 189195972f6Sopenharmony_ci if (eoid == NULL) { 190195972f6Sopenharmony_ci trap_msg.enterprise = snmp_get_device_enterprise_oid(); 191195972f6Sopenharmony_ci } else { 192195972f6Sopenharmony_ci trap_msg.enterprise = eoid; 193195972f6Sopenharmony_ci } 194195972f6Sopenharmony_ci 195195972f6Sopenharmony_ci trap_msg.gen_trap = generic_trap; 196195972f6Sopenharmony_ci if (generic_trap == SNMP_GENTRAP_ENTERPRISE_SPECIFIC) { 197195972f6Sopenharmony_ci trap_msg.spc_trap = specific_trap; 198195972f6Sopenharmony_ci } else { 199195972f6Sopenharmony_ci trap_msg.spc_trap = 0; 200195972f6Sopenharmony_ci } 201195972f6Sopenharmony_ci 202195972f6Sopenharmony_ci MIB2_COPY_SYSUPTIME_TO(&trap_msg.ts); 203195972f6Sopenharmony_ci 204195972f6Sopenharmony_ci /* pass 0, calculate length fields */ 205195972f6Sopenharmony_ci tot_len = snmp_trap_varbind_sum(&trap_msg, varbinds); 206195972f6Sopenharmony_ci tot_len = snmp_trap_header_sum(&trap_msg, tot_len); 207195972f6Sopenharmony_ci 208195972f6Sopenharmony_ci /* allocate pbuf(s) */ 209195972f6Sopenharmony_ci p = pbuf_alloc(PBUF_TRANSPORT, tot_len, PBUF_RAM); 210195972f6Sopenharmony_ci if (p != NULL) { 211195972f6Sopenharmony_ci struct snmp_pbuf_stream pbuf_stream; 212195972f6Sopenharmony_ci snmp_pbuf_stream_init(&pbuf_stream, p, 0, tot_len); 213195972f6Sopenharmony_ci 214195972f6Sopenharmony_ci /* pass 1, encode packet into the pbuf(s) */ 215195972f6Sopenharmony_ci snmp_trap_header_enc(&trap_msg, &pbuf_stream); 216195972f6Sopenharmony_ci snmp_trap_varbind_enc(&trap_msg, &pbuf_stream, varbinds); 217195972f6Sopenharmony_ci 218195972f6Sopenharmony_ci snmp_stats.outtraps++; 219195972f6Sopenharmony_ci snmp_stats.outpkts++; 220195972f6Sopenharmony_ci 221195972f6Sopenharmony_ci /** send to the TRAP destination */ 222195972f6Sopenharmony_ci snmp_sendto(snmp_traps_handle, p, &td->dip, LWIP_IANA_PORT_SNMP_TRAP); 223195972f6Sopenharmony_ci pbuf_free(p); 224195972f6Sopenharmony_ci } else { 225195972f6Sopenharmony_ci err = ERR_MEM; 226195972f6Sopenharmony_ci } 227195972f6Sopenharmony_ci } else { 228195972f6Sopenharmony_ci /* routing error */ 229195972f6Sopenharmony_ci err = ERR_RTE; 230195972f6Sopenharmony_ci } 231195972f6Sopenharmony_ci } 232195972f6Sopenharmony_ci } 233195972f6Sopenharmony_ci return err; 234195972f6Sopenharmony_ci} 235195972f6Sopenharmony_ci 236195972f6Sopenharmony_ci/** 237195972f6Sopenharmony_ci * @ingroup snmp_traps 238195972f6Sopenharmony_ci * Send generic SNMP trap 239195972f6Sopenharmony_ci */ 240195972f6Sopenharmony_cierr_t 241195972f6Sopenharmony_cisnmp_send_trap_generic(s32_t generic_trap) 242195972f6Sopenharmony_ci{ 243195972f6Sopenharmony_ci static const struct snmp_obj_id oid = { 7, { 1, 3, 6, 1, 2, 1, 11 } }; 244195972f6Sopenharmony_ci return snmp_send_trap(&oid, generic_trap, 0, NULL); 245195972f6Sopenharmony_ci} 246195972f6Sopenharmony_ci 247195972f6Sopenharmony_ci/** 248195972f6Sopenharmony_ci * @ingroup snmp_traps 249195972f6Sopenharmony_ci * Send specific SNMP trap with variable bindings 250195972f6Sopenharmony_ci */ 251195972f6Sopenharmony_cierr_t 252195972f6Sopenharmony_cisnmp_send_trap_specific(s32_t specific_trap, struct snmp_varbind *varbinds) 253195972f6Sopenharmony_ci{ 254195972f6Sopenharmony_ci return snmp_send_trap(NULL, SNMP_GENTRAP_ENTERPRISE_SPECIFIC, specific_trap, varbinds); 255195972f6Sopenharmony_ci} 256195972f6Sopenharmony_ci 257195972f6Sopenharmony_ci/** 258195972f6Sopenharmony_ci * @ingroup snmp_traps 259195972f6Sopenharmony_ci * Send coldstart trap 260195972f6Sopenharmony_ci */ 261195972f6Sopenharmony_civoid 262195972f6Sopenharmony_cisnmp_coldstart_trap(void) 263195972f6Sopenharmony_ci{ 264195972f6Sopenharmony_ci snmp_send_trap_generic(SNMP_GENTRAP_COLDSTART); 265195972f6Sopenharmony_ci} 266195972f6Sopenharmony_ci 267195972f6Sopenharmony_ci/** 268195972f6Sopenharmony_ci * @ingroup snmp_traps 269195972f6Sopenharmony_ci * Send authentication failure trap (used internally by agent) 270195972f6Sopenharmony_ci */ 271195972f6Sopenharmony_civoid 272195972f6Sopenharmony_cisnmp_authfail_trap(void) 273195972f6Sopenharmony_ci{ 274195972f6Sopenharmony_ci if (snmp_auth_traps_enabled != 0) { 275195972f6Sopenharmony_ci snmp_send_trap_generic(SNMP_GENTRAP_AUTH_FAILURE); 276195972f6Sopenharmony_ci } 277195972f6Sopenharmony_ci} 278195972f6Sopenharmony_ci 279195972f6Sopenharmony_cistatic u16_t 280195972f6Sopenharmony_cisnmp_trap_varbind_sum(struct snmp_msg_trap *trap, struct snmp_varbind *varbinds) 281195972f6Sopenharmony_ci{ 282195972f6Sopenharmony_ci struct snmp_varbind *varbind; 283195972f6Sopenharmony_ci u16_t tot_len; 284195972f6Sopenharmony_ci u8_t tot_len_len; 285195972f6Sopenharmony_ci 286195972f6Sopenharmony_ci tot_len = 0; 287195972f6Sopenharmony_ci varbind = varbinds; 288195972f6Sopenharmony_ci while (varbind != NULL) { 289195972f6Sopenharmony_ci struct snmp_varbind_len len; 290195972f6Sopenharmony_ci 291195972f6Sopenharmony_ci if (snmp_varbind_length(varbind, &len) == ERR_OK) { 292195972f6Sopenharmony_ci tot_len += 1 + len.vb_len_len + len.vb_value_len; 293195972f6Sopenharmony_ci } 294195972f6Sopenharmony_ci 295195972f6Sopenharmony_ci varbind = varbind->next; 296195972f6Sopenharmony_ci } 297195972f6Sopenharmony_ci 298195972f6Sopenharmony_ci trap->vbseqlen = tot_len; 299195972f6Sopenharmony_ci snmp_asn1_enc_length_cnt(trap->vbseqlen, &tot_len_len); 300195972f6Sopenharmony_ci tot_len += 1 + tot_len_len; 301195972f6Sopenharmony_ci 302195972f6Sopenharmony_ci return tot_len; 303195972f6Sopenharmony_ci} 304195972f6Sopenharmony_ci 305195972f6Sopenharmony_ci/** 306195972f6Sopenharmony_ci * Sums trap header field lengths from tail to head and 307195972f6Sopenharmony_ci * returns trap_header_lengths for second encoding pass. 308195972f6Sopenharmony_ci * 309195972f6Sopenharmony_ci * @param trap Trap message 310195972f6Sopenharmony_ci * @param vb_len varbind-list length 311195972f6Sopenharmony_ci * @return the required length for encoding the trap header 312195972f6Sopenharmony_ci */ 313195972f6Sopenharmony_cistatic u16_t 314195972f6Sopenharmony_cisnmp_trap_header_sum(struct snmp_msg_trap *trap, u16_t vb_len) 315195972f6Sopenharmony_ci{ 316195972f6Sopenharmony_ci u16_t tot_len; 317195972f6Sopenharmony_ci u16_t len; 318195972f6Sopenharmony_ci u8_t lenlen; 319195972f6Sopenharmony_ci 320195972f6Sopenharmony_ci tot_len = vb_len; 321195972f6Sopenharmony_ci 322195972f6Sopenharmony_ci snmp_asn1_enc_u32t_cnt(trap->ts, &len); 323195972f6Sopenharmony_ci snmp_asn1_enc_length_cnt(len, &lenlen); 324195972f6Sopenharmony_ci tot_len += 1 + len + lenlen; 325195972f6Sopenharmony_ci 326195972f6Sopenharmony_ci snmp_asn1_enc_s32t_cnt(trap->spc_trap, &len); 327195972f6Sopenharmony_ci snmp_asn1_enc_length_cnt(len, &lenlen); 328195972f6Sopenharmony_ci tot_len += 1 + len + lenlen; 329195972f6Sopenharmony_ci 330195972f6Sopenharmony_ci snmp_asn1_enc_s32t_cnt(trap->gen_trap, &len); 331195972f6Sopenharmony_ci snmp_asn1_enc_length_cnt(len, &lenlen); 332195972f6Sopenharmony_ci tot_len += 1 + len + lenlen; 333195972f6Sopenharmony_ci 334195972f6Sopenharmony_ci if (IP_IS_V6_VAL(trap->sip)) { 335195972f6Sopenharmony_ci#if LWIP_IPV6 336195972f6Sopenharmony_ci len = sizeof(ip_2_ip6(&trap->sip)->addr); 337195972f6Sopenharmony_ci#endif 338195972f6Sopenharmony_ci } else { 339195972f6Sopenharmony_ci#if LWIP_IPV4 340195972f6Sopenharmony_ci len = sizeof(ip_2_ip4(&trap->sip)->addr); 341195972f6Sopenharmony_ci#endif 342195972f6Sopenharmony_ci } 343195972f6Sopenharmony_ci snmp_asn1_enc_length_cnt(len, &lenlen); 344195972f6Sopenharmony_ci tot_len += 1 + len + lenlen; 345195972f6Sopenharmony_ci 346195972f6Sopenharmony_ci snmp_asn1_enc_oid_cnt(trap->enterprise->id, trap->enterprise->len, &len); 347195972f6Sopenharmony_ci snmp_asn1_enc_length_cnt(len, &lenlen); 348195972f6Sopenharmony_ci tot_len += 1 + len + lenlen; 349195972f6Sopenharmony_ci 350195972f6Sopenharmony_ci trap->pdulen = tot_len; 351195972f6Sopenharmony_ci snmp_asn1_enc_length_cnt(trap->pdulen, &lenlen); 352195972f6Sopenharmony_ci tot_len += 1 + lenlen; 353195972f6Sopenharmony_ci 354195972f6Sopenharmony_ci trap->comlen = (u16_t)LWIP_MIN(strlen(snmp_community_trap), 0xFFFF); 355195972f6Sopenharmony_ci snmp_asn1_enc_length_cnt(trap->comlen, &lenlen); 356195972f6Sopenharmony_ci tot_len += 1 + lenlen + trap->comlen; 357195972f6Sopenharmony_ci 358195972f6Sopenharmony_ci snmp_asn1_enc_s32t_cnt(trap->snmp_version, &len); 359195972f6Sopenharmony_ci snmp_asn1_enc_length_cnt(len, &lenlen); 360195972f6Sopenharmony_ci tot_len += 1 + len + lenlen; 361195972f6Sopenharmony_ci 362195972f6Sopenharmony_ci trap->seqlen = tot_len; 363195972f6Sopenharmony_ci snmp_asn1_enc_length_cnt(trap->seqlen, &lenlen); 364195972f6Sopenharmony_ci tot_len += 1 + lenlen; 365195972f6Sopenharmony_ci 366195972f6Sopenharmony_ci return tot_len; 367195972f6Sopenharmony_ci} 368195972f6Sopenharmony_ci 369195972f6Sopenharmony_cistatic err_t 370195972f6Sopenharmony_cisnmp_trap_varbind_enc(struct snmp_msg_trap *trap, struct snmp_pbuf_stream *pbuf_stream, struct snmp_varbind *varbinds) 371195972f6Sopenharmony_ci{ 372195972f6Sopenharmony_ci struct snmp_asn1_tlv tlv; 373195972f6Sopenharmony_ci struct snmp_varbind *varbind; 374195972f6Sopenharmony_ci 375195972f6Sopenharmony_ci varbind = varbinds; 376195972f6Sopenharmony_ci 377195972f6Sopenharmony_ci SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_SEQUENCE, 0, trap->vbseqlen); 378195972f6Sopenharmony_ci BUILD_EXEC( snmp_ans1_enc_tlv(pbuf_stream, &tlv) ); 379195972f6Sopenharmony_ci 380195972f6Sopenharmony_ci while (varbind != NULL) { 381195972f6Sopenharmony_ci BUILD_EXEC( snmp_append_outbound_varbind(pbuf_stream, varbind) ); 382195972f6Sopenharmony_ci 383195972f6Sopenharmony_ci varbind = varbind->next; 384195972f6Sopenharmony_ci } 385195972f6Sopenharmony_ci 386195972f6Sopenharmony_ci return ERR_OK; 387195972f6Sopenharmony_ci} 388195972f6Sopenharmony_ci 389195972f6Sopenharmony_ci/** 390195972f6Sopenharmony_ci * Encodes trap header from head to tail. 391195972f6Sopenharmony_ci */ 392195972f6Sopenharmony_cistatic err_t 393195972f6Sopenharmony_cisnmp_trap_header_enc(struct snmp_msg_trap *trap, struct snmp_pbuf_stream *pbuf_stream) 394195972f6Sopenharmony_ci{ 395195972f6Sopenharmony_ci struct snmp_asn1_tlv tlv; 396195972f6Sopenharmony_ci 397195972f6Sopenharmony_ci /* 'Message' sequence */ 398195972f6Sopenharmony_ci SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_SEQUENCE, 0, trap->seqlen); 399195972f6Sopenharmony_ci BUILD_EXEC( snmp_ans1_enc_tlv(pbuf_stream, &tlv) ); 400195972f6Sopenharmony_ci 401195972f6Sopenharmony_ci /* version */ 402195972f6Sopenharmony_ci SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_INTEGER, 0, 0); 403195972f6Sopenharmony_ci snmp_asn1_enc_s32t_cnt(trap->snmp_version, &tlv.value_len); 404195972f6Sopenharmony_ci BUILD_EXEC( snmp_ans1_enc_tlv(pbuf_stream, &tlv) ); 405195972f6Sopenharmony_ci BUILD_EXEC( snmp_asn1_enc_s32t(pbuf_stream, tlv.value_len, trap->snmp_version) ); 406195972f6Sopenharmony_ci 407195972f6Sopenharmony_ci /* community */ 408195972f6Sopenharmony_ci SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 0, trap->comlen); 409195972f6Sopenharmony_ci BUILD_EXEC( snmp_ans1_enc_tlv(pbuf_stream, &tlv) ); 410195972f6Sopenharmony_ci BUILD_EXEC( snmp_asn1_enc_raw(pbuf_stream, (const u8_t *)snmp_community_trap, trap->comlen) ); 411195972f6Sopenharmony_ci 412195972f6Sopenharmony_ci /* 'PDU' sequence */ 413195972f6Sopenharmony_ci SNMP_ASN1_SET_TLV_PARAMS(tlv, (SNMP_ASN1_CLASS_CONTEXT | SNMP_ASN1_CONTENTTYPE_CONSTRUCTED | SNMP_ASN1_CONTEXT_PDU_TRAP), 0, trap->pdulen); 414195972f6Sopenharmony_ci BUILD_EXEC( snmp_ans1_enc_tlv(pbuf_stream, &tlv) ); 415195972f6Sopenharmony_ci 416195972f6Sopenharmony_ci /* object ID */ 417195972f6Sopenharmony_ci SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OBJECT_ID, 0, 0); 418195972f6Sopenharmony_ci snmp_asn1_enc_oid_cnt(trap->enterprise->id, trap->enterprise->len, &tlv.value_len); 419195972f6Sopenharmony_ci BUILD_EXEC( snmp_ans1_enc_tlv(pbuf_stream, &tlv) ); 420195972f6Sopenharmony_ci BUILD_EXEC( snmp_asn1_enc_oid(pbuf_stream, trap->enterprise->id, trap->enterprise->len) ); 421195972f6Sopenharmony_ci 422195972f6Sopenharmony_ci /* IP addr */ 423195972f6Sopenharmony_ci if (IP_IS_V6_VAL(trap->sip)) { 424195972f6Sopenharmony_ci#if LWIP_IPV6 425195972f6Sopenharmony_ci SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_IPADDR, 0, sizeof(ip_2_ip6(&trap->sip)->addr)); 426195972f6Sopenharmony_ci BUILD_EXEC( snmp_ans1_enc_tlv(pbuf_stream, &tlv) ); 427195972f6Sopenharmony_ci BUILD_EXEC( snmp_asn1_enc_raw(pbuf_stream, (const u8_t *)&ip_2_ip6(&trap->sip)->addr, sizeof(ip_2_ip6(&trap->sip)->addr)) ); 428195972f6Sopenharmony_ci#endif 429195972f6Sopenharmony_ci } else { 430195972f6Sopenharmony_ci#if LWIP_IPV4 431195972f6Sopenharmony_ci SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_IPADDR, 0, sizeof(ip_2_ip4(&trap->sip)->addr)); 432195972f6Sopenharmony_ci BUILD_EXEC( snmp_ans1_enc_tlv(pbuf_stream, &tlv) ); 433195972f6Sopenharmony_ci BUILD_EXEC( snmp_asn1_enc_raw(pbuf_stream, (const u8_t *)&ip_2_ip4(&trap->sip)->addr, sizeof(ip_2_ip4(&trap->sip)->addr)) ); 434195972f6Sopenharmony_ci#endif 435195972f6Sopenharmony_ci } 436195972f6Sopenharmony_ci 437195972f6Sopenharmony_ci /* trap length */ 438195972f6Sopenharmony_ci SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_INTEGER, 0, 0); 439195972f6Sopenharmony_ci snmp_asn1_enc_s32t_cnt(trap->gen_trap, &tlv.value_len); 440195972f6Sopenharmony_ci BUILD_EXEC( snmp_ans1_enc_tlv(pbuf_stream, &tlv) ); 441195972f6Sopenharmony_ci BUILD_EXEC( snmp_asn1_enc_s32t(pbuf_stream, tlv.value_len, trap->gen_trap) ); 442195972f6Sopenharmony_ci 443195972f6Sopenharmony_ci /* specific trap */ 444195972f6Sopenharmony_ci SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_INTEGER, 0, 0); 445195972f6Sopenharmony_ci snmp_asn1_enc_s32t_cnt(trap->spc_trap, &tlv.value_len); 446195972f6Sopenharmony_ci BUILD_EXEC( snmp_ans1_enc_tlv(pbuf_stream, &tlv) ); 447195972f6Sopenharmony_ci BUILD_EXEC( snmp_asn1_enc_s32t(pbuf_stream, tlv.value_len, trap->spc_trap) ); 448195972f6Sopenharmony_ci 449195972f6Sopenharmony_ci /* timestamp */ 450195972f6Sopenharmony_ci SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_TIMETICKS, 0, 0); 451195972f6Sopenharmony_ci snmp_asn1_enc_s32t_cnt(trap->ts, &tlv.value_len); 452195972f6Sopenharmony_ci BUILD_EXEC( snmp_ans1_enc_tlv(pbuf_stream, &tlv) ); 453195972f6Sopenharmony_ci BUILD_EXEC( snmp_asn1_enc_s32t(pbuf_stream, tlv.value_len, trap->ts) ); 454195972f6Sopenharmony_ci 455195972f6Sopenharmony_ci return ERR_OK; 456195972f6Sopenharmony_ci} 457195972f6Sopenharmony_ci 458195972f6Sopenharmony_ci#endif /* LWIP_SNMP */ 459