| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562 | /* * snmp_trap_pdu2.c * *  Created on: 30.10.2017 *      Author: balbekova */#include "lwip/apps/snmp_opts.h"#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */#include "snmp_msg.h"#include "snmp_asn1.h"#include "snmp_core_priv.h"#include "lwip/ip_addr.h"#include "lwip/stats.h"#if LWIP_SNMP_V3#include "lwip/apps/snmpv3.h"#include "snmpv3_priv.h"#ifdef LWIP_SNMPV3_INCLUDE_ENGINE#include LWIP_SNMPV3_INCLUDE_ENGINE#endif#endif#include <string.h>#define BUILD_EXEC_TRAP(code, retValue) \	if ((code) != ERR_OK) { \		LWIP_DEBUGF(SNMP_DEBUG, ("SNMP error during creation of outbound frame!: " # code)); \		return retValue; \	}#define OF_BUILD_EXEC_TRAP(code) BUILD_EXEC_TRAP(code, ERR_ARG)struct snmp_trap_pduv2_dst{  /* destination IP address in network order */  ip_addr_t dip;  /* set to 0 when disabled, >0 when enabled */  u8_t enable;};static struct snmp_trap_pduv2_dst trap_pduv2_dst[SNMP_TRAP_DESTINATIONS];void* snmp_traps_pdu2_handle;/** * @ingroup snmp_traps * Sets enable switch for this trap destination. * @param dst_idx index in 0 .. SNMP_TRAP_DESTINATIONS-1 * @param enable switch if 0 destination is disabled >0 enabled. */voidsnmp_trap_pduv2_dst_enable(u8_t dst_idx, u8_t enable){  if (dst_idx < SNMP_TRAP_DESTINATIONS) {    trap_pduv2_dst[dst_idx].enable = enable;  }}static err_tsnmp_complete_outbound_frame_trap_pduv2(struct snmp_request *request){  struct snmp_asn1_tlv tlv;  u16_t frame_size;  u8_t outbound_padding = 0;  if (request->version == SNMP_VERSION_1) {    if (request->error_status != SNMP_ERR_NOERROR) {      /* map v2c error codes to v1 compliant error code (according to RFC 2089) */      switch (request->error_status) {        /* mapping of implementation specific "virtual" error codes         * (during processing of frame we already stored them in error_status field,         * so no need to check all varbinds here for those exceptions as suggested by RFC) */        case SNMP_ERR_NOSUCHINSTANCE:        case SNMP_ERR_NOSUCHOBJECT:        case SNMP_ERR_ENDOFMIBVIEW:          request->error_status = SNMP_ERR_NOSUCHNAME;          break;        /* mapping according to RFC */        case SNMP_ERR_WRONGVALUE:        case SNMP_ERR_WRONGENCODING:        case SNMP_ERR_WRONGTYPE:        case SNMP_ERR_WRONGLENGTH:        case SNMP_ERR_INCONSISTENTVALUE:          request->error_status = SNMP_ERR_BADVALUE;          break;        case SNMP_ERR_NOACCESS:        case SNMP_ERR_NOTWRITABLE:        case SNMP_ERR_NOCREATION:        case SNMP_ERR_INCONSISTENTNAME:        case SNMP_ERR_AUTHORIZATIONERROR:          request->error_status = SNMP_ERR_NOSUCHNAME;          break;        case SNMP_ERR_RESOURCEUNAVAILABLE:        case SNMP_ERR_COMMITFAILED:        case SNMP_ERR_UNDOFAILED:        default:          request->error_status = SNMP_ERR_GENERROR;          break;       }    }  } else {    if (request->request_type == SNMP_ASN1_CONTEXT_PDU_SET_REQ) {      /* map error codes to according to RFC 1905 (4.2.5.  The SetRequest-PDU) return 'NotWritable' for unknown OIDs) */      switch (request->error_status) {        case SNMP_ERR_NOSUCHINSTANCE:        case SNMP_ERR_NOSUCHOBJECT:        case SNMP_ERR_ENDOFMIBVIEW:          request->error_status = SNMP_ERR_NOTWRITABLE;          break;        default:          break;      }    }    if (request->error_status >= SNMP_VARBIND_EXCEPTION_OFFSET) {      /* should never occur because v2 frames store exceptions directly inside varbinds and not as frame error_status */      LWIP_DEBUGF(SNMP_DEBUG, ("snmp_complete_outbound_frame() > Found v2 request with varbind exception code stored as error status!\n"));      return ERR_ARG;    }  }  if ((request->error_status != SNMP_ERR_NOERROR) || (request->request_type == SNMP_ASN1_CONTEXT_PDU_SET_REQ)) {    /* all inbound vars are returned in response without any modification for error responses and successful set requests*/    struct snmp_pbuf_stream inbound_stream;    OF_BUILD_EXEC_TRAP( snmp_pbuf_stream_init(&inbound_stream, request->inbound_pbuf, request->inbound_varbind_offset, request->inbound_varbind_len) );    OF_BUILD_EXEC_TRAP( snmp_pbuf_stream_init(&(request->outbound_pbuf_stream), request->outbound_pbuf, request->outbound_varbind_offset, request->outbound_pbuf->tot_len - request->outbound_varbind_offset) );    snmp_pbuf_stream_writeto(&inbound_stream, &(request->outbound_pbuf_stream), 0);  }  frame_size = request->outbound_pbuf_stream.offset;#if LWIP_SNMP_V3 && LWIP_SNMP_V3_CRYPTO  /* Calculate padding for encryption */  if (request->version == SNMP_VERSION_3 && (request->msg_flags & SNMP_V3_PRIV_FLAG)) {    u8_t i;    outbound_padding = (8 - (u8_t)((frame_size - request->outbound_scoped_pdu_seq_offset) & 0x07)) & 0x07;    for (i = 0; i < outbound_padding; i++) {      snmp_pbuf_stream_write(&request->outbound_pbuf_stream, 0);    }  }#endif  /* complete missing length in 'Message' sequence ; 'Message' tlv is located at the beginning (offset 0) */  SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_SEQUENCE, 2, frame_size + outbound_padding - 1 - 2); /* - type - length_len(fixed, see snmp_prepare_outbound_frame()) */  OF_BUILD_EXEC_TRAP( snmp_pbuf_stream_init(&(request->outbound_pbuf_stream), request->outbound_pbuf, 0, request->outbound_pbuf->tot_len) );  OF_BUILD_EXEC_TRAP( snmp_ans1_enc_tlv(&(request->outbound_pbuf_stream), &tlv) );#if LWIP_SNMP_V3  if (request->version == SNMP_VERSION_3) {    /* complete missing length in 'globalData' sequence */    /* - type - length_len(fixed, see snmp_prepare_outbound_frame()) */    SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_SEQUENCE, 1, request->outbound_msg_global_data_end        - request->outbound_msg_global_data_offset - 1 - 1);    OF_BUILD_EXEC_TRAP(snmp_pbuf_stream_seek_abs(&(request->outbound_pbuf_stream), request->outbound_msg_global_data_offset));    OF_BUILD_EXEC_TRAP(snmp_ans1_enc_tlv(&(request->outbound_pbuf_stream), &tlv));    /* complete missing length in 'msgSecurityParameters' sequence */    SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 1, request->outbound_msg_security_parameters_end        - request->outbound_msg_security_parameters_str_offset - 1 - 1);    OF_BUILD_EXEC_TRAP(snmp_pbuf_stream_seek_abs(&(request->outbound_pbuf_stream), request->outbound_msg_security_parameters_str_offset));    OF_BUILD_EXEC_TRAP(snmp_ans1_enc_tlv(&(request->outbound_pbuf_stream), &tlv));    SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_SEQUENCE, 1, request->outbound_msg_security_parameters_end        - request->outbound_msg_security_parameters_seq_offset - 1 - 1);    OF_BUILD_EXEC_TRAP(snmp_pbuf_stream_seek_abs(&(request->outbound_pbuf_stream), request->outbound_msg_security_parameters_seq_offset));    OF_BUILD_EXEC_TRAP(snmp_ans1_enc_tlv(&(request->outbound_pbuf_stream), &tlv));    /* complete missing length in scoped PDU sequence */    SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_SEQUENCE, 3, frame_size - request->outbound_scoped_pdu_seq_offset - 1 - 3);    OF_BUILD_EXEC_TRAP(snmp_pbuf_stream_seek_abs(&(request->outbound_pbuf_stream), request->outbound_scoped_pdu_seq_offset));    OF_BUILD_EXEC_TRAP(snmp_ans1_enc_tlv(&(request->outbound_pbuf_stream), &tlv));  }#endif  /* complete missing length in 'PDU' sequence */  SNMP_ASN1_SET_TLV_PARAMS(tlv, (SNMP_ASN1_CLASS_CONTEXT | SNMP_ASN1_CONTENTTYPE_CONSTRUCTED | SNMP_ASN1_CONTEXT_PDU_GET_NEXT_REQ | SNMP_ASN1_CONTEXT_PDU_GET_RESP | SNMP_ASN1_CONTEXT_PDU_TRAP), 2,      frame_size - request->outbound_pdu_offset - 1 - 2); /* - type - length_len(fixed, see snmp_prepare_outbound_frame()) */  OF_BUILD_EXEC_TRAP( snmp_pbuf_stream_seek_abs(&(request->outbound_pbuf_stream), request->outbound_pdu_offset) );  OF_BUILD_EXEC_TRAP( snmp_ans1_enc_tlv(&(request->outbound_pbuf_stream), &tlv) );  /* process and encode final error status */  if (request->error_status != 0) {    u16_t len;    snmp_asn1_enc_s32t_cnt(request->error_status, &len);    if (len != 1) {      /* error, we only reserved one byte for it */      return ERR_ARG;    }    OF_BUILD_EXEC_TRAP( snmp_pbuf_stream_seek_abs(&(request->outbound_pbuf_stream), request->outbound_error_status_offset) );    OF_BUILD_EXEC_TRAP( snmp_asn1_enc_s32t(&(request->outbound_pbuf_stream), len, request->error_status) );    /* for compatibility to v1, log statistics; in v2 (RFC 1907) these statistics are obsoleted */    switch (request->error_status) {      case SNMP_ERR_TOOBIG:        snmp_stats.outtoobigs++;        break;      case SNMP_ERR_NOSUCHNAME:        snmp_stats.outnosuchnames++;        break;      case SNMP_ERR_BADVALUE:        snmp_stats.outbadvalues++;        break;      case SNMP_ERR_GENERROR:      default:        snmp_stats.outgenerrs++;        break;    }    if (request->error_status == SNMP_ERR_TOOBIG) {      request->error_index = 0; /* defined by RFC 1157 */    } else if (request->error_index == 0) {      /* set index to varbind where error occured (if not already set before, e.g. during GetBulk processing) */      request->error_index = request->inbound_varbind_enumerator.varbind_count;    }  } else {    if (request->request_type == SNMP_ASN1_CONTEXT_PDU_SET_REQ) {      snmp_stats.intotalsetvars += request->inbound_varbind_enumerator.varbind_count;    } else {      snmp_stats.intotalreqvars += request->inbound_varbind_enumerator.varbind_count;    }  }  /* encode final error index*/  if (request->error_index != 0) {    u16_t len;    snmp_asn1_enc_s32t_cnt(request->error_index, &len);    if (len != 1) {      /* error, we only reserved one byte for it */      return ERR_VAL;    }    OF_BUILD_EXEC_TRAP( snmp_pbuf_stream_seek_abs(&(request->outbound_pbuf_stream), request->outbound_error_index_offset) );    OF_BUILD_EXEC_TRAP( snmp_asn1_enc_s32t(&(request->outbound_pbuf_stream), len, request->error_index) );  }  /* complete missing length in 'VarBindList' sequence ; 'VarBindList' tlv is located directly before varbind offset */  SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_SEQUENCE, 1, frame_size - request->outbound_varbind_offset);  OF_BUILD_EXEC_TRAP( snmp_pbuf_stream_seek_abs(&(request->outbound_pbuf_stream), request->outbound_varbind_offset - 1 - 1) ); /* - type - length_len(fixed, see snmp_prepare_outbound_frame()) */  OF_BUILD_EXEC_TRAP( snmp_ans1_enc_tlv(&(request->outbound_pbuf_stream), &tlv) );  /* Authenticate response */#if LWIP_SNMP_V3 && LWIP_SNMP_V3_CRYPTO  /* Encrypt response */  if (request->version == SNMP_VERSION_3 && (request->msg_flags & SNMP_V3_PRIV_FLAG)) {    u8_t key[20];    u8_t algo;    /* complete missing length in PDU sequence */    OF_BUILD_EXEC_TRAP(snmp_pbuf_stream_init(&request->outbound_pbuf_stream, request->outbound_pbuf, 0, request->outbound_pbuf->tot_len));    OF_BUILD_EXEC_TRAP(snmp_pbuf_stream_seek_abs(&(request->outbound_pbuf_stream), request->outbound_scoped_pdu_string_offset));    SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 3, frame_size + outbound_padding        - request->outbound_scoped_pdu_string_offset - 1 - 3);    OF_BUILD_EXEC_TRAP(snmp_ans1_enc_tlv(&(request->outbound_pbuf_stream), &tlv));    OF_BUILD_EXEC_TRAP(snmpv3_get_user((char*)request->msg_user_name, NULL, NULL, &algo, key));    OF_BUILD_EXEC_TRAP(snmpv3_crypt(&request->outbound_pbuf_stream, tlv.value_len, key,        request->msg_privacy_parameters, request->msg_authoritative_engine_boots,        request->msg_authoritative_engine_time, algo, SNMP_V3_PRIV_MODE_ENCRYPT));  }  if (request->version == SNMP_VERSION_3 && (request->msg_flags & SNMP_V3_AUTH_FLAG)) {    u8_t key[20];    u8_t algo;    u8_t hmac[20];    OF_BUILD_EXEC_TRAP(snmpv3_get_user((char*)request->msg_user_name, &algo, key, NULL, NULL));    OF_BUILD_EXEC_TRAP(snmp_pbuf_stream_init(&(request->outbound_pbuf_stream),        request->outbound_pbuf, 0, request->outbound_pbuf->tot_len));    OF_BUILD_EXEC_TRAP(snmpv3_auth(&request->outbound_pbuf_stream, frame_size + outbound_padding, key, algo, hmac));    MEMCPY(request->msg_authentication_parameters, hmac, SNMP_V3_MAX_AUTH_PARAM_LENGTH);    OF_BUILD_EXEC_TRAP(snmp_pbuf_stream_init(&request->outbound_pbuf_stream,                  request->outbound_pbuf, 0, request->outbound_pbuf->tot_len));    OF_BUILD_EXEC_TRAP(snmp_pbuf_stream_seek_abs(&request->outbound_pbuf_stream,                  request->outbound_msg_authentication_parameters_offset));    SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 1, SNMP_V3_MAX_AUTH_PARAM_LENGTH);    OF_BUILD_EXEC_TRAP(snmp_ans1_enc_tlv(&request->outbound_pbuf_stream, &tlv));    OF_BUILD_EXEC_TRAP(snmp_asn1_enc_raw(&request->outbound_pbuf_stream,                  request->msg_authentication_parameters, SNMP_V3_MAX_AUTH_PARAM_LENGTH));  }#endif  pbuf_realloc(request->outbound_pbuf, frame_size + outbound_padding);  snmp_stats.outgetresponses++;  snmp_stats.outpkts++;  return ERR_OK;}/** * @ingroup snmp_traps * Sets IPv4 address for this trap destination. * @param dst_idx index in 0 .. SNMP_TRAP_DESTINATIONS-1 * @param dst IPv4 address in host order. */voidsnmp_trap_pduv2_dst_ip_set(u8_t dst_idx, const ip_addr_t *dst){  if (dst_idx < SNMP_TRAP_DESTINATIONS) {    ip_addr_set(&trap_pduv2_dst[dst_idx].dip, dst);  }}static err_tsnmp_prepare_outbound_frame_trap_pduv2(struct snmp_request *request){  struct snmp_asn1_tlv tlv;  struct snmp_pbuf_stream* pbuf_stream = &(request->outbound_pbuf_stream);  /* try allocating pbuf(s) for maximum response size */  request->outbound_pbuf = pbuf_alloc(PBUF_TRANSPORT, 1472, PBUF_RAM);  if (request->outbound_pbuf == NULL) {    return ERR_MEM;  }  snmp_pbuf_stream_init(pbuf_stream, request->outbound_pbuf, 0, request->outbound_pbuf->tot_len);  /* 'Message' sequence */  SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_SEQUENCE, 2, 0);  OF_BUILD_EXEC_TRAP( snmp_ans1_enc_tlv(pbuf_stream, &tlv) );  /* version */  SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_INTEGER, 0, 0);  snmp_asn1_enc_s32t_cnt(request->version, &tlv.value_len);  OF_BUILD_EXEC_TRAP( snmp_ans1_enc_tlv(pbuf_stream, &tlv) );  OF_BUILD_EXEC_TRAP( snmp_asn1_enc_s32t(pbuf_stream, tlv.value_len, request->version) );#if LWIP_SNMP_V3  if (request->version < SNMP_VERSION_3) {#endif  /* community */  SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 0, request->community_strlen);  OF_BUILD_EXEC_TRAP( snmp_ans1_enc_tlv(pbuf_stream, &tlv) );  OF_BUILD_EXEC_TRAP( snmp_asn1_enc_raw(pbuf_stream, request->community, request->community_strlen) );#if LWIP_SNMP_V3  } else {    const char* id;    /* globalData */    request->outbound_msg_global_data_offset = pbuf_stream->offset;    SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_SEQUENCE, 1, 0);    OF_BUILD_EXEC_TRAP(snmp_ans1_enc_tlv(pbuf_stream, &tlv));    /* msgID */    SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_INTEGER, 0, 1);    snmp_asn1_enc_s32t_cnt(request->msg_id, &tlv.value_len);    OF_BUILD_EXEC_TRAP(snmp_ans1_enc_tlv(pbuf_stream, &tlv));    OF_BUILD_EXEC_TRAP(snmp_asn1_enc_s32t(pbuf_stream, tlv.value_len, request->msg_id));    /* msgMaxSize */    SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_INTEGER, 0, 1);    snmp_asn1_enc_s32t_cnt(request->msg_max_size, &tlv.value_len);    OF_BUILD_EXEC_TRAP(snmp_ans1_enc_tlv(pbuf_stream, &tlv));    OF_BUILD_EXEC_TRAP(snmp_asn1_enc_s32t(pbuf_stream, tlv.value_len, request->msg_max_size));    /* msgFlags */    SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 0, 1);    OF_BUILD_EXEC_TRAP(snmp_ans1_enc_tlv(pbuf_stream, &tlv));    OF_BUILD_EXEC_TRAP(snmp_asn1_enc_raw(pbuf_stream, &request->msg_flags, 1));    /* msgSecurityModel */    SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_INTEGER, 0, 1);    snmp_asn1_enc_s32t_cnt(request->msg_security_model, &tlv.value_len);    OF_BUILD_EXEC_TRAP(snmp_ans1_enc_tlv(pbuf_stream, &tlv));    OF_BUILD_EXEC_TRAP(snmp_asn1_enc_s32t(pbuf_stream, tlv.value_len, request->msg_security_model));    /* end of msgGlobalData */    request->outbound_msg_global_data_end = pbuf_stream->offset;    /* msgSecurityParameters */    request->outbound_msg_security_parameters_str_offset = pbuf_stream->offset;    SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 1, 0);    OF_BUILD_EXEC_TRAP(snmp_ans1_enc_tlv(pbuf_stream, &tlv));    request->outbound_msg_security_parameters_seq_offset = pbuf_stream->offset;    SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_SEQUENCE, 1, 0);    OF_BUILD_EXEC_TRAP(snmp_ans1_enc_tlv(pbuf_stream, &tlv));    /* msgAuthoritativeEngineID */    snmpv3_get_engine_id(&id, &request->msg_authoritative_engine_id_len);    MEMCPY(request->msg_authoritative_engine_id, id, request->msg_authoritative_engine_id_len);    SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 0, request->msg_authoritative_engine_id_len);    OF_BUILD_EXEC_TRAP(snmp_ans1_enc_tlv(pbuf_stream, &tlv));    OF_BUILD_EXEC_TRAP(snmp_asn1_enc_raw(pbuf_stream, request->msg_authoritative_engine_id, request->msg_authoritative_engine_id_len));    request->msg_authoritative_engine_time = snmpv3_get_engine_time();    request->msg_authoritative_engine_boots = snmpv3_get_engine_boots();    /* msgAuthoritativeEngineBoots */    SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_INTEGER, 0, 0);    snmp_asn1_enc_s32t_cnt(request->msg_authoritative_engine_boots, &tlv.value_len);    OF_BUILD_EXEC_TRAP(snmp_ans1_enc_tlv(pbuf_stream, &tlv));    OF_BUILD_EXEC_TRAP(snmp_asn1_enc_s32t(pbuf_stream, tlv.value_len, request->msg_authoritative_engine_boots));    /* msgAuthoritativeEngineTime */    SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_INTEGER, 0, 0);    snmp_asn1_enc_s32t_cnt(request->msg_authoritative_engine_time, &tlv.value_len);    OF_BUILD_EXEC_TRAP(snmp_ans1_enc_tlv(pbuf_stream, &tlv));    OF_BUILD_EXEC_TRAP(snmp_asn1_enc_s32t(pbuf_stream, tlv.value_len, request->msg_authoritative_engine_time));    /* msgUserName */    SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 0, request->msg_user_name_len);    OF_BUILD_EXEC_TRAP(snmp_ans1_enc_tlv(pbuf_stream, &tlv));    OF_BUILD_EXEC_TRAP(snmp_asn1_enc_raw(pbuf_stream, request->msg_user_name, request->msg_user_name_len));#if LWIP_SNMP_V3_CRYPTO    /* msgAuthenticationParameters */    if (request->msg_flags & SNMP_V3_AUTH_FLAG) {      memset(request->msg_authentication_parameters, 0, SNMP_V3_MAX_AUTH_PARAM_LENGTH);      request->outbound_msg_authentication_parameters_offset = pbuf_stream->offset;      SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 1, SNMP_V3_MAX_AUTH_PARAM_LENGTH);      OF_BUILD_EXEC_TRAP(snmp_ans1_enc_tlv(pbuf_stream, &tlv));      OF_BUILD_EXEC_TRAP(snmp_asn1_enc_raw(pbuf_stream, request->msg_authentication_parameters, SNMP_V3_MAX_AUTH_PARAM_LENGTH));    } else#endif    {      SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 0, 0);      OF_BUILD_EXEC_TRAP(snmp_ans1_enc_tlv(pbuf_stream, &tlv));    }#if LWIP_SNMP_V3_CRYPTO    /* msgPrivacyParameters */    if (request->msg_flags & SNMP_V3_PRIV_FLAG) {      snmpv3_build_priv_param(request->msg_privacy_parameters);      SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 0, SNMP_V3_MAX_PRIV_PARAM_LENGTH);      OF_BUILD_EXEC_TRAP(snmp_ans1_enc_tlv(pbuf_stream, &tlv));      OF_BUILD_EXEC_TRAP(snmp_asn1_enc_raw(pbuf_stream, request->msg_privacy_parameters, SNMP_V3_MAX_PRIV_PARAM_LENGTH));    } else#endif    {      SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 0, 0);      OF_BUILD_EXEC_TRAP(snmp_ans1_enc_tlv(pbuf_stream, &tlv) );    }    /* End of msgSecurityParameters, so we can calculate the length of this sequence later */    request->outbound_msg_security_parameters_end = pbuf_stream->offset;#if LWIP_SNMP_V3_CRYPTO    /* For encryption we have to encapsulate the payload in an octet string */    if (request->msg_flags & SNMP_V3_PRIV_FLAG) {      request->outbound_scoped_pdu_string_offset = pbuf_stream->offset;      SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 3, 0);      OF_BUILD_EXEC_TRAP(snmp_ans1_enc_tlv(pbuf_stream, &tlv));    }#endif    /* Scoped PDU     * Encryption context     */    request->outbound_scoped_pdu_seq_offset = pbuf_stream->offset;    SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_SEQUENCE, 3, 0);    OF_BUILD_EXEC_TRAP(snmp_ans1_enc_tlv(pbuf_stream, &tlv));    /* contextEngineID */    snmpv3_get_engine_id(&id, &request->context_engine_id_len);    MEMCPY(request->context_engine_id, id, request->context_engine_id_len);    SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 0, request->context_engine_id_len);    OF_BUILD_EXEC_TRAP(snmp_ans1_enc_tlv(pbuf_stream, &tlv));    OF_BUILD_EXEC_TRAP(snmp_asn1_enc_raw(pbuf_stream, request->context_engine_id, request->context_engine_id_len));    /* contextName */    SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 0, request->context_name_len);    OF_BUILD_EXEC_TRAP(snmp_ans1_enc_tlv(pbuf_stream, &tlv));    OF_BUILD_EXEC_TRAP(snmp_asn1_enc_raw(pbuf_stream, request->context_name, request->context_name_len));  }#endif  /* 'PDU' sequence */  request->outbound_pdu_offset = pbuf_stream->offset;//  SNMP_ASN1_SET_TLV_PARAMS(tlv, (SNMP_ASN1_CLASS_CONTEXT | SNMP_ASN1_CONTENTTYPE_CONSTRUCTED | SNMP_ASN1_CONTEXT_PDU_TRAP), 3, 0);  SNMP_ASN1_SET_TLV_PARAMS(tlv, (SNMP_ASN1_CLASS_CONTEXT | SNMP_ASN1_CONTENTTYPE_CONSTRUCTED | SNMP_ASN1_CONTEXT_PDU_TRAP | SNMP_ASN1_CONTEXT_PDU_GET_NEXT_REQ | SNMP_ASN1_CONTEXT_PDU_GET_RESP), 2, 0);  OF_BUILD_EXEC_TRAP( snmp_ans1_enc_tlv(pbuf_stream, &tlv) );  /* request ID */  SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_INTEGER, 0, 0);  snmp_asn1_enc_s32t_cnt(request->request_id, &tlv.value_len);  OF_BUILD_EXEC_TRAP( snmp_ans1_enc_tlv(pbuf_stream, &tlv) );  OF_BUILD_EXEC_TRAP( snmp_asn1_enc_s32t(pbuf_stream, tlv.value_len, request->request_id) );  /* error status */  SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_INTEGER, 0, 1);  OF_BUILD_EXEC_TRAP( snmp_ans1_enc_tlv(pbuf_stream, &tlv) );  request->outbound_error_status_offset = pbuf_stream->offset;  OF_BUILD_EXEC_TRAP( snmp_pbuf_stream_write(pbuf_stream, 0) );  /* error index */  SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_INTEGER, 0, 1);  OF_BUILD_EXEC_TRAP( snmp_ans1_enc_tlv(pbuf_stream, &tlv) );  request->outbound_error_index_offset = pbuf_stream->offset;  OF_BUILD_EXEC_TRAP( snmp_pbuf_stream_write(pbuf_stream, 0) );  /* 'VarBindList' sequence */  SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_SEQUENCE, 1, 1);  OF_BUILD_EXEC_TRAP( snmp_ans1_enc_tlv(pbuf_stream, &tlv) );  request->outbound_varbind_offset = pbuf_stream->offset;  return ERR_OK;}err_tsnmp_send_trap_pduv2(struct snmp_varbind *varbinds){  err_t err = ERR_OK;  struct snmp_request request;  struct snmp_trap_pduv2_dst *td;  u16_t i;  ip_addr_t sip;  memset(&request, 0, sizeof(request));  request.handle = snmp_traps_handle;  for (i = 0, td = &trap_pduv2_dst[0]; i < SNMP_TRAP_DESTINATIONS; i++, td++) {      if ((td->enable != 0) && !ip_addr_isany(&td->dip)) {        /* lookup current source address for this dst */		if (snmp_get_local_ip_for_dst(request.handle, &td->dip, &sip)) {//request.source_ip			request.source_ip = &td->dip;			request.source_port  = SNMP_TRAP_PORT;			request.version  = SNMP_VERSION_2c;			strcpy((char*)request.community, "public");//snmp_get_community_trap			request.community_strlen = strlen(request.community);			request.request_type = SNMP_ASN1_CONTEXT_PDU_TRAP;			request.request_id = 0x54dc84ac;			err = snmp_prepare_outbound_frame_trap_pduv2(&request);			while (varbinds != NULL) {				err = snmp_append_outbound_varbind(&(request.outbound_pbuf_stream), varbinds);				varbinds = varbinds->next;			}			if (err == ERR_OK) {			  /* we stored the exception in varbind -> go on */			  request.error_status = SNMP_ERR_NOERROR;			} else if (err == ERR_BUF) {			  request.error_status = SNMP_ERR_TOOBIG;			} else {			  request.error_status = SNMP_ERR_GENERROR;			}			if (err == ERR_OK) {				err = snmp_complete_outbound_frame_trap_pduv2(&request);				if (err == ERR_OK) {					err = snmp_sendto(request.handle, request.outbound_pbuf, request.source_ip, request.source_port);					snmp_stats.outtraps++;				  }			}			 if (request.outbound_pbuf != NULL) {			  pbuf_free(request.outbound_pbuf);			}		}      }  }}#endif
 |