ReactOS 0.4.16-dev-814-g656a5dc
snmp_traps.c
Go to the documentation of this file.
1
6/*
7 * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without modification,
11 * are permitted provided that the following conditions are met:
12 *
13 * 1. Redistributions of source code must retain the above copyright notice,
14 * this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright notice,
16 * this list of conditions and the following disclaimer in the documentation
17 * and/or other materials provided with the distribution.
18 * 3. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
22 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
23 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
24 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
26 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
29 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
30 * OF SUCH DAMAGE.
31 *
32 * This file is part of the lwIP TCP/IP stack.
33 *
34 * Author: Martin Hentschel
35 * Christiaan Simons <christiaan.simons@axon.tv>
36 *
37 */
38
39#include "lwip/apps/snmp_opts.h"
40
41#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */
42
43#include <string.h>
44
45#include "lwip/snmp.h"
46#include "lwip/sys.h"
47#include "lwip/apps/snmp.h"
48#include "lwip/apps/snmp_core.h"
49#include "lwip/prot/iana.h"
50#include "snmp_msg.h"
51#include "snmp_asn1.h"
52#include "snmp_core_priv.h"
53
54#define SNMP_IS_INFORM 1
55#define SNMP_IS_TRAP 0
56
57struct snmp_msg_trap
58{
59 /* source enterprise ID (sysObjectID) */
60 const struct snmp_obj_id *enterprise;
61 /* source IP address, raw network order format */
62 ip_addr_t sip;
63 /* generic trap code */
64 u32_t gen_trap;
65 /* specific trap code */
66 u32_t spc_trap;
67 /* timestamp */
68 u32_t ts;
69 /* snmp_version */
70 u32_t snmp_version;
71
72 /* output trap lengths used in ASN encoding */
73 /* encoding pdu length */
74 u16_t pdulen;
75 /* encoding community length */
76 u16_t comlen;
77 /* encoding sequence length */
78 u16_t seqlen;
79 /* encoding varbinds sequence length */
80 u16_t vbseqlen;
81
82 /* error status */
83 s32_t error_status;
84 /* error index */
85 s32_t error_index;
86 /* trap or inform? */
87 u8_t trap_or_inform;
88};
89
90static u16_t snmp_trap_varbind_sum(struct snmp_msg_trap *trap, struct snmp_varbind *varbinds);
91static u16_t snmp_trap_header_sum(struct snmp_msg_trap *trap, u16_t vb_len);
92static err_t snmp_trap_header_enc(struct snmp_msg_trap *trap, struct snmp_pbuf_stream *pbuf_stream);
93static err_t snmp_trap_varbind_enc(struct snmp_msg_trap *trap, struct snmp_pbuf_stream *pbuf_stream, struct snmp_varbind *varbinds);
94static u16_t snmp_trap_header_sum_v1_specific(struct snmp_msg_trap *trap);
95static u16_t snmp_trap_header_sum_v2c_specific(struct snmp_msg_trap *trap);
96static err_t snmp_trap_header_enc_v1_specific(struct snmp_msg_trap *trap, struct snmp_pbuf_stream *pbuf_stream);
97static err_t snmp_trap_header_enc_v2c_specific(struct snmp_msg_trap *trap, struct snmp_pbuf_stream *pbuf_stream);
98static err_t snmp_prepare_trap_oid(struct snmp_obj_id *dest_snmp_trap_oid, const struct snmp_obj_id *eoid, s32_t generic_trap, s32_t specific_trap);
99static void snmp_prepare_necessary_msg_fields(struct snmp_msg_trap *trap_msg, const struct snmp_obj_id *eoid, s32_t generic_trap, s32_t specific_trap, struct snmp_varbind *varbinds);
100static err_t snmp_send_msg(struct snmp_msg_trap *trap_msg, struct snmp_varbind *varbinds, u16_t tot_len, ip_addr_t *dip);
101
102#define BUILD_EXEC(code) \
103 if ((code) != ERR_OK) { \
104 LWIP_DEBUGF(SNMP_DEBUG, ("SNMP error during creation of outbound trap frame!\n")); \
105 return ERR_ARG; \
106 }
107
109extern const char *snmp_community_trap;
110
111void *snmp_traps_handle;
112
117struct snmp_trap_dst
118{
119 /* destination IP address in network order */
120 ip_addr_t dip;
121 /* set to 0 when disabled, >0 when enabled */
122 u8_t enable;
123};
124static struct snmp_trap_dst trap_dst[SNMP_TRAP_DESTINATIONS];
125
126static u8_t snmp_auth_traps_enabled = 0;
127
128/* This is used in functions like snmp_coldstart_trap where user didn't specify which version of trap to use */
129static u8_t snmp_default_trap_version = SNMP_VERSION_1;
130
131/* This is used in trap messages v2c */
132static s32_t req_id = 1;
133
142void
143snmp_trap_dst_enable(u8_t dst_idx, u8_t enable)
144{
145 LWIP_ASSERT_SNMP_LOCKED();
146 if (dst_idx < SNMP_TRAP_DESTINATIONS) {
147 trap_dst[dst_idx].enable = enable;
148 }
149}
150
159void
160snmp_trap_dst_ip_set(u8_t dst_idx, const ip_addr_t *dst)
161{
162 LWIP_ASSERT_SNMP_LOCKED();
163 if (dst_idx < SNMP_TRAP_DESTINATIONS) {
164 ip_addr_set(&trap_dst[dst_idx].dip, dst);
165 }
166}
167
176void
177snmp_set_auth_traps_enabled(u8_t enable)
178{
179 snmp_auth_traps_enabled = enable;
180}
181
188u8_t
189snmp_get_auth_traps_enabled(void)
190{
191 return snmp_auth_traps_enabled;
192}
193
205void
206snmp_set_default_trap_version(u8_t snmp_version)
207{
208 snmp_default_trap_version = snmp_version;
209}
210
220u8_t
221snmp_get_default_trap_version(void)
222{
223 return snmp_default_trap_version;
224}
225
237static err_t
238snmp_prepare_trap_oid(struct snmp_obj_id *dest_snmp_trap_oid, const struct snmp_obj_id *eoid, s32_t generic_trap, s32_t specific_trap)
239{
240 err_t err = ERR_OK;
241 const u32_t snmpTrapOID[] = {1, 3, 6, 1, 6, 3, 1, 1, 5}; /* please see rfc3584 */
242
243 if (generic_trap == SNMP_GENTRAP_ENTERPRISE_SPECIFIC) {
244 if (eoid == NULL) {
245 MEMCPY(dest_snmp_trap_oid, snmp_get_device_enterprise_oid(), sizeof(*dest_snmp_trap_oid));
246 } else {
247 MEMCPY(dest_snmp_trap_oid, eoid, sizeof(*dest_snmp_trap_oid));
248 }
249 if (dest_snmp_trap_oid->len + 2 < SNMP_MAX_OBJ_ID_LEN) {
250 dest_snmp_trap_oid->id[dest_snmp_trap_oid->len++] = 0;
251 dest_snmp_trap_oid->id[dest_snmp_trap_oid->len++] = specific_trap;
252 } else {
253 err = ERR_MEM;
254 }
255 } else if ((generic_trap >= SNMP_GENTRAP_COLDSTART) && (generic_trap < SNMP_GENTRAP_ENTERPRISE_SPECIFIC)) {
256 if (sizeof(dest_snmp_trap_oid->id) >= sizeof(snmpTrapOID)) {
257 MEMCPY(&dest_snmp_trap_oid->id, snmpTrapOID , sizeof(snmpTrapOID));
258 dest_snmp_trap_oid->len = LWIP_ARRAYSIZE(snmpTrapOID);
259 dest_snmp_trap_oid->id[dest_snmp_trap_oid->len++] = specific_trap + 1;
260 } else {
261 err = ERR_MEM;
262 }
263 } else {
264 err = ERR_VAL;
265 }
266 return err;
267}
268
279static void
280snmp_prepare_necessary_msg_fields(struct snmp_msg_trap *trap_msg, const struct snmp_obj_id *eoid, s32_t generic_trap, s32_t specific_trap, struct snmp_varbind *varbinds)
281{
282 if (trap_msg->snmp_version == SNMP_VERSION_1) {
283 trap_msg->enterprise = (eoid == NULL) ? snmp_get_device_enterprise_oid() : eoid;
284 trap_msg->gen_trap = generic_trap;
285 trap_msg->spc_trap = (generic_trap == SNMP_GENTRAP_ENTERPRISE_SPECIFIC) ? specific_trap : 0;
286 MIB2_COPY_SYSUPTIME_TO(&trap_msg->ts);
287 } else if (trap_msg->snmp_version == SNMP_VERSION_2c) {
288 /* Copy sysUpTime into the first varbind */
289 MIB2_COPY_SYSUPTIME_TO((u32_t *)varbinds[0].value);
290 }
291}
292
302static err_t
303snmp_send_msg(struct snmp_msg_trap *trap_msg, struct snmp_varbind *varbinds, u16_t tot_len, ip_addr_t *dip)
304{
305 err_t err = ERR_OK;
306 struct pbuf *p = NULL;
307 /* allocate pbuf(s) */
309 if (p != NULL) {
310 struct snmp_pbuf_stream pbuf_stream;
311 snmp_pbuf_stream_init(&pbuf_stream, p, 0, tot_len);
312
313 /* pass 1, encode packet ino the pbuf(s) */
314 BUILD_EXEC( snmp_trap_header_enc(trap_msg, &pbuf_stream) );
315 BUILD_EXEC( snmp_trap_varbind_enc(trap_msg, &pbuf_stream, varbinds) );
316
317 snmp_stats.outtraps++;
318 snmp_stats.outpkts++;
319
321 err = snmp_sendto(snmp_traps_handle, p, dip, LWIP_IANA_PORT_SNMP_TRAP);
322 pbuf_free(p);
323 } else {
324 err = ERR_MEM;
325 }
326 return err;
327}
328
346static err_t
347snmp_send_trap_or_notification_or_inform_generic(struct snmp_msg_trap *trap_msg, const struct snmp_obj_id *eoid, s32_t generic_trap, s32_t specific_trap, struct snmp_varbind *varbinds)
348{
349 struct snmp_trap_dst *td = NULL;
350 u16_t i = 0;
351 u16_t tot_len = 0;
352 err_t err = ERR_OK;
353 u32_t timestamp = 0;
354 struct snmp_varbind *original_varbinds = varbinds;
355 struct snmp_varbind *original_prev = NULL;
356 struct snmp_varbind snmp_v2_special_varbinds[] = {
357 /* First varbind is used to store sysUpTime */
358 {
359 NULL, /* *next */
360 NULL, /* *prev */
361 { /* oid */
362 8, /* oid len */
363 {1, 3, 6, 1, 2, 1, 1, 3} /* oid for sysUpTime */
364 },
365 SNMP_ASN1_TYPE_TIMETICKS, /* type */
366 sizeof(u32_t), /* value_len */
367 NULL /* value */
368 },
369 /* Second varbind is used to store snmpTrapOID */
370 {
371 NULL, /* *next */
372 NULL, /* *prev */
373 { /* oid */
374 10, /* oid len */
375 {1, 3, 6, 1, 6, 3, 1, 1, 4, 1} /* oid for snmpTrapOID */
376 },
377 SNMP_ASN1_TYPE_OBJECT_ID, /* type */
378 0, /* value_len */
379 NULL /* value */
380 }
381 };
382
383 LWIP_ASSERT_SNMP_LOCKED();
384
385 snmp_v2_special_varbinds[0].next = &snmp_v2_special_varbinds[1];
386 snmp_v2_special_varbinds[1].prev = &snmp_v2_special_varbinds[0];
387
388 snmp_v2_special_varbinds[0].value = &timestamp;
389
390 snmp_v2_special_varbinds[1].next = varbinds;
391
392 /* see rfc3584 */
393 if (trap_msg->snmp_version == SNMP_VERSION_2c) {
394 struct snmp_obj_id snmp_trap_oid = { 0 }; /* used for converting SNMPv1 generic/specific trap parameter to SNMPv2 snmpTrapOID */
395 err = snmp_prepare_trap_oid(&snmp_trap_oid, eoid, generic_trap, specific_trap);
396 if (err == ERR_OK) {
397 snmp_v2_special_varbinds[1].value_len = snmp_trap_oid.len * sizeof(snmp_trap_oid.id[0]);
398 snmp_v2_special_varbinds[1].value = snmp_trap_oid.id;
399 if (varbinds != NULL) {
400 original_prev = varbinds->prev;
401 varbinds->prev = &snmp_v2_special_varbinds[1];
402 }
403 varbinds = snmp_v2_special_varbinds; /* After inserting two varbinds at the beginning of the list, make sure that pointer is pointing to the first element */
404 }
405 }
406
407 for (i = 0, td = &trap_dst[0]; (i < SNMP_TRAP_DESTINATIONS) && (err == ERR_OK); i++, td++) {
408 if ((td->enable != 0) && !ip_addr_isany(&td->dip)) {
409 /* lookup current source address for this dst */
410 if (snmp_get_local_ip_for_dst(snmp_traps_handle, &td->dip, &trap_msg->sip)) {
411 snmp_prepare_necessary_msg_fields(trap_msg, eoid, generic_trap, specific_trap, varbinds);
412
413 /* pass 0, calculate length fields */
414 tot_len = snmp_trap_varbind_sum(trap_msg, varbinds);
415 tot_len = snmp_trap_header_sum(trap_msg, tot_len);
416
417 /* allocate pbuf, fill it and send it */
418 err = snmp_send_msg(trap_msg, varbinds, tot_len, &td->dip);
419 } else {
420 /* routing error */
421 err = ERR_RTE;
422 }
423 }
424 }
425 if ((trap_msg->snmp_version == SNMP_VERSION_2c) && (original_varbinds != NULL)) {
426 original_varbinds->prev = original_prev;
427 }
428 req_id++;
429 return err;
430}
431
448err_t
449snmp_send_trap(const struct snmp_obj_id* oid, s32_t generic_trap, s32_t specific_trap, struct snmp_varbind *varbinds)
450{
451 struct snmp_msg_trap trap_msg = {0};
452 trap_msg.snmp_version = snmp_default_trap_version;
453 trap_msg.trap_or_inform = SNMP_IS_TRAP;
454 return snmp_send_trap_or_notification_or_inform_generic(&trap_msg, oid, generic_trap, specific_trap, varbinds);
455}
456
463err_t
464snmp_send_trap_generic(s32_t generic_trap)
465{
466 err_t err = ERR_OK;
467 struct snmp_msg_trap trap_msg = {0};
468 trap_msg.snmp_version = snmp_default_trap_version;
469 trap_msg.trap_or_inform = SNMP_IS_TRAP;
470
471 if(snmp_default_trap_version == SNMP_VERSION_1) {
472 static const struct snmp_obj_id oid = { 7, { 1, 3, 6, 1, 2, 1, 11 } };
473 err = snmp_send_trap_or_notification_or_inform_generic(&trap_msg, &oid, generic_trap, 0, NULL);
474 } else if (snmp_default_trap_version == SNMP_VERSION_2c) {
475 err = snmp_send_trap_or_notification_or_inform_generic(&trap_msg, NULL, generic_trap, 0, NULL);
476 } else {
477 err = ERR_VAL;
478 }
479 return err;
480}
481
489err_t
490snmp_send_trap_specific(s32_t specific_trap, struct snmp_varbind *varbinds)
491{
492 struct snmp_msg_trap trap_msg = {0};
493 trap_msg.snmp_version = snmp_default_trap_version;
494 trap_msg.trap_or_inform = SNMP_IS_TRAP;
495 return snmp_send_trap_or_notification_or_inform_generic(&trap_msg, NULL, SNMP_GENTRAP_ENTERPRISE_SPECIFIC, specific_trap, varbinds);
496}
497
503void
504snmp_coldstart_trap(void)
505{
506 snmp_send_trap_generic(SNMP_GENTRAP_COLDSTART);
507}
508
514void
515snmp_authfail_trap(void)
516{
517 if (snmp_auth_traps_enabled != 0) {
518 snmp_send_trap_generic(SNMP_GENTRAP_AUTH_FAILURE);
519 }
520}
521
530static u16_t
531snmp_trap_varbind_sum(struct snmp_msg_trap *trap, struct snmp_varbind *varbinds)
532{
533 struct snmp_varbind *varbind;
534 u16_t tot_len;
535 u8_t tot_len_len;
536
537 tot_len = 0;
538 varbind = varbinds;
539 while (varbind != NULL) {
540 struct snmp_varbind_len len;
541
542 if (snmp_varbind_length(varbind, &len) == ERR_OK) {
543 tot_len += 1 + len.vb_len_len + len.vb_value_len;
544 }
545
546 varbind = varbind->next;
547 }
548
549 trap->vbseqlen = tot_len;
550 snmp_asn1_enc_length_cnt(trap->vbseqlen, &tot_len_len);
551 tot_len += 1 + tot_len_len;
552
553 return tot_len;
554}
555
563static u16_t
564snmp_trap_header_sum_v1_specific(struct snmp_msg_trap *trap)
565{
566 u16_t tot_len = 0;
567 u16_t len = 0;
568 u8_t lenlen = 0;
569
570 snmp_asn1_enc_u32t_cnt(trap->ts, &len);
571 snmp_asn1_enc_length_cnt(len, &lenlen);
572 tot_len += 1 + len + lenlen;
573
574 snmp_asn1_enc_s32t_cnt(trap->spc_trap, &len);
575 snmp_asn1_enc_length_cnt(len, &lenlen);
576 tot_len += 1 + len + lenlen;
577
578 snmp_asn1_enc_s32t_cnt(trap->gen_trap, &len);
579 snmp_asn1_enc_length_cnt(len, &lenlen);
580 tot_len += 1 + len + lenlen;
581
582 if (IP_IS_V6_VAL(trap->sip)) {
583#if LWIP_IPV6
584 len = sizeof(ip_2_ip6(&trap->sip)->addr);
585#endif
586 } else {
587#if LWIP_IPV4
588 len = sizeof(ip_2_ip4(&trap->sip)->addr);
589#endif
590 }
591 snmp_asn1_enc_length_cnt(len, &lenlen);
592 tot_len += 1 + len + lenlen;
593
594 snmp_asn1_enc_oid_cnt(trap->enterprise->id, trap->enterprise->len, &len);
595 snmp_asn1_enc_length_cnt(len, &lenlen);
596 tot_len += 1 + len + lenlen;
597
598 return tot_len;
599}
600
608static u16_t
609snmp_trap_header_sum_v2c_specific(struct snmp_msg_trap *trap)
610{
611 u16_t tot_len = 0;
612 u16_t len = 0;
613 u8_t lenlen = 0;
614
615 snmp_asn1_enc_u32t_cnt(req_id, &len);
616 snmp_asn1_enc_length_cnt(len, &lenlen);
617 tot_len += 1 + len + lenlen;
618 snmp_asn1_enc_u32t_cnt(trap->error_status, &len);
619 snmp_asn1_enc_length_cnt(len, &lenlen);
620 tot_len += 1 + len + lenlen;
621 snmp_asn1_enc_u32t_cnt(trap->error_index, &len);
622 snmp_asn1_enc_length_cnt(len, &lenlen);
623 tot_len += 1 + len + lenlen;
624
625 return tot_len;
626}
627
637static u16_t
638snmp_trap_header_sum(struct snmp_msg_trap *trap, u16_t vb_len)
639{
640 u16_t tot_len = vb_len;
641 u16_t len = 0;
642 u8_t lenlen = 0;
643
644 if (trap->snmp_version == SNMP_VERSION_1) {
645 tot_len += snmp_trap_header_sum_v1_specific(trap);
646 } else if (trap->snmp_version == SNMP_VERSION_2c) {
647 tot_len += snmp_trap_header_sum_v2c_specific(trap);
648 }
649 trap->pdulen = tot_len;
650 snmp_asn1_enc_length_cnt(trap->pdulen, &lenlen);
651 tot_len += 1 + lenlen;
652
653 trap->comlen = (u16_t)LWIP_MIN(strlen(snmp_community_trap), 0xFFFF);
654 snmp_asn1_enc_length_cnt(trap->comlen, &lenlen);
655 tot_len += 1 + lenlen + trap->comlen;
656
657 snmp_asn1_enc_s32t_cnt(trap->snmp_version, &len);
658 snmp_asn1_enc_length_cnt(len, &lenlen);
659 tot_len += 1 + len + lenlen;
660
661 trap->seqlen = tot_len;
662 snmp_asn1_enc_length_cnt(trap->seqlen, &lenlen);
663 tot_len += 1 + lenlen;
664
665 return tot_len;
666}
667
676static err_t
677snmp_trap_varbind_enc(struct snmp_msg_trap *trap, struct snmp_pbuf_stream *pbuf_stream, struct snmp_varbind *varbinds)
678{
679 struct snmp_asn1_tlv tlv;
680 struct snmp_varbind *varbind;
681
682 varbind = varbinds;
683
684 SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_SEQUENCE, 0, trap->vbseqlen);
685 BUILD_EXEC( snmp_ans1_enc_tlv(pbuf_stream, &tlv) );
686
687 while (varbind != NULL) {
688 BUILD_EXEC( snmp_append_outbound_varbind(pbuf_stream, varbind) );
689
690 varbind = varbind->next;
691 }
692
693 return ERR_OK;
694}
695
703static err_t
704snmp_trap_header_enc_pdu(struct snmp_msg_trap *trap, struct snmp_pbuf_stream *pbuf_stream)
705{
706 struct snmp_asn1_tlv tlv;
707 /* 'PDU' sequence */
708 if (trap->snmp_version == SNMP_VERSION_1) {
709 /* TRAP V1 */
710 SNMP_ASN1_SET_TLV_PARAMS(tlv, (SNMP_ASN1_CLASS_CONTEXT | SNMP_ASN1_CONTENTTYPE_CONSTRUCTED | SNMP_ASN1_CONTEXT_PDU_TRAP), 0, trap->pdulen);
711 BUILD_EXEC( snmp_ans1_enc_tlv(pbuf_stream, &tlv) );
712 } else if ((trap->snmp_version == SNMP_VERSION_2c) && (trap->trap_or_inform == SNMP_IS_INFORM)) {
713 /* TRAP v2 - INFORM */
714 SNMP_ASN1_SET_TLV_PARAMS(tlv, (SNMP_ASN1_CLASS_CONTEXT | SNMP_ASN1_CONTENTTYPE_CONSTRUCTED | SNMP_ASN1_CONTEXT_PDU_INFORM_REQ), 0, trap->pdulen);
715 BUILD_EXEC( snmp_ans1_enc_tlv(pbuf_stream, &tlv) );
716 } else if (trap->snmp_version == SNMP_VERSION_2c) {
717 /* TRAP v2 - NOTIFICATION*/
718 SNMP_ASN1_SET_TLV_PARAMS(tlv, (SNMP_ASN1_CLASS_CONTEXT | SNMP_ASN1_CONTENTTYPE_CONSTRUCTED | SNMP_ASN1_CONTEXT_PDU_V2_TRAP), 0, trap->pdulen);
719 BUILD_EXEC( snmp_ans1_enc_tlv(pbuf_stream, &tlv) );
720 }
721
722 return ERR_OK;
723}
724
732static err_t
733snmp_trap_header_enc_v1_specific(struct snmp_msg_trap *trap, struct snmp_pbuf_stream *pbuf_stream)
734{
735 struct snmp_asn1_tlv tlv;
736 /* object ID */
737 SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OBJECT_ID, 0, 0);
738 snmp_asn1_enc_oid_cnt(trap->enterprise->id, trap->enterprise->len, &tlv.value_len);
739 BUILD_EXEC( snmp_ans1_enc_tlv(pbuf_stream, &tlv) );
740 BUILD_EXEC( snmp_asn1_enc_oid(pbuf_stream, trap->enterprise->id, trap->enterprise->len) );
741
742 /* IP addr */
743 if (IP_IS_V6_VAL(trap->sip)) {
744#if LWIP_IPV6
745 SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_IPADDR, 0, sizeof(ip_2_ip6(&trap->sip)->addr));
746 BUILD_EXEC( snmp_ans1_enc_tlv(pbuf_stream, &tlv) );
747 BUILD_EXEC( snmp_asn1_enc_raw(pbuf_stream, (const u8_t *)&ip_2_ip6(&trap->sip)->addr, sizeof(ip_2_ip6(&trap->sip)->addr)) );
748#endif
749 } else {
750#if LWIP_IPV4
751 SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_IPADDR, 0, sizeof(ip_2_ip4(&trap->sip)->addr));
752 BUILD_EXEC( snmp_ans1_enc_tlv(pbuf_stream, &tlv) );
753 BUILD_EXEC( snmp_asn1_enc_raw(pbuf_stream, (const u8_t *)&ip_2_ip4(&trap->sip)->addr, sizeof(ip_2_ip4(&trap->sip)->addr)) );
754#endif
755 }
756
757 /* generic trap */
758 SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_INTEGER, 0, 0);
759 snmp_asn1_enc_s32t_cnt(trap->gen_trap, &tlv.value_len);
760 BUILD_EXEC( snmp_ans1_enc_tlv(pbuf_stream, &tlv) );
761 BUILD_EXEC( snmp_asn1_enc_s32t(pbuf_stream, tlv.value_len, trap->gen_trap) );
762
763 /* specific trap */
764 SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_INTEGER, 0, 0);
765 snmp_asn1_enc_s32t_cnt(trap->spc_trap, &tlv.value_len);
766 BUILD_EXEC( snmp_ans1_enc_tlv(pbuf_stream, &tlv) );
767 BUILD_EXEC( snmp_asn1_enc_s32t(pbuf_stream, tlv.value_len, trap->spc_trap) );
768
769 /* timestamp */
770 SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_TIMETICKS, 0, 0);
771 snmp_asn1_enc_s32t_cnt(trap->ts, &tlv.value_len);
772 BUILD_EXEC( snmp_ans1_enc_tlv(pbuf_stream, &tlv) );
773 BUILD_EXEC( snmp_asn1_enc_s32t(pbuf_stream, tlv.value_len, trap->ts) );
774
775 return ERR_OK;
776}
777
786static err_t
787snmp_trap_header_enc_v2c_specific(struct snmp_msg_trap *trap, struct snmp_pbuf_stream *pbuf_stream)
788{
789 struct snmp_asn1_tlv tlv;
790 /* request id */
791 SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_INTEGER, 0, 0);
792 snmp_asn1_enc_s32t_cnt(req_id, &tlv.value_len);
793 BUILD_EXEC( snmp_ans1_enc_tlv(pbuf_stream, &tlv) );
794 BUILD_EXEC( snmp_asn1_enc_s32t(pbuf_stream, tlv.value_len, req_id) );
795
796 /* error status */
797 SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_INTEGER, 0, 0);
798 snmp_asn1_enc_s32t_cnt(trap->error_status, &tlv.value_len);
799 BUILD_EXEC( snmp_ans1_enc_tlv(pbuf_stream, &tlv) );
800 BUILD_EXEC( snmp_asn1_enc_s32t(pbuf_stream, tlv.value_len, trap->error_status) );
801
802 /* error index */
803 SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_INTEGER, 0, 0);
804 snmp_asn1_enc_s32t_cnt(trap->error_index, &tlv.value_len);
805 BUILD_EXEC( snmp_ans1_enc_tlv(pbuf_stream, &tlv) );
806 BUILD_EXEC( snmp_asn1_enc_s32t(pbuf_stream, tlv.value_len, trap->error_index) );
807
808 return ERR_OK;
809}
810
819static err_t
820snmp_trap_header_enc(struct snmp_msg_trap *trap, struct snmp_pbuf_stream *pbuf_stream)
821{
822 struct snmp_asn1_tlv tlv;
823
824 /* 'Message' sequence */
825 SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_SEQUENCE, 0, trap->seqlen);
826 BUILD_EXEC( snmp_ans1_enc_tlv(pbuf_stream, &tlv) );
827
828 /* version */
829 SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_INTEGER, 0, 0);
830 snmp_asn1_enc_s32t_cnt(trap->snmp_version, &tlv.value_len);
831 BUILD_EXEC( snmp_ans1_enc_tlv(pbuf_stream, &tlv) );
832 BUILD_EXEC( snmp_asn1_enc_s32t(pbuf_stream, tlv.value_len, trap->snmp_version) );
833
834 /* community */
835 SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 0, trap->comlen);
836 BUILD_EXEC( snmp_ans1_enc_tlv(pbuf_stream, &tlv) );
837 BUILD_EXEC( snmp_asn1_enc_raw(pbuf_stream, (const u8_t *)snmp_community_trap, trap->comlen) );
838
839 /* PDU */
840 BUILD_EXEC( snmp_trap_header_enc_pdu(trap, pbuf_stream) );
841 if (trap->snmp_version == SNMP_VERSION_1) {
842 /* object ID, IP addr, generic trap, specific trap, timestamp */
843 BUILD_EXEC( snmp_trap_header_enc_v1_specific(trap, pbuf_stream) );
844 } else if (SNMP_VERSION_2c == trap->snmp_version) {
845 /* request id, error status, error index */
846 BUILD_EXEC( snmp_trap_header_enc_v2c_specific(trap, pbuf_stream) );
847 }
848
849 return ERR_OK;
850}
851
860err_t
861snmp_send_inform_specific(s32_t specific_trap, struct snmp_varbind *varbinds, s32_t *ptr_request_id)
862{
863 return snmp_send_inform(NULL, SNMP_GENTRAP_ENTERPRISE_SPECIFIC, specific_trap, varbinds, ptr_request_id);
864}
865
874err_t
875snmp_send_inform_generic(s32_t generic_trap, struct snmp_varbind *varbinds, s32_t *ptr_request_id)
876{
877 return snmp_send_inform(NULL, generic_trap, 0, varbinds, ptr_request_id);
878}
879
890err_t
891snmp_send_inform(const struct snmp_obj_id* oid, s32_t generic_trap, s32_t specific_trap, struct snmp_varbind *varbinds, s32_t *ptr_request_id)
892{
893 struct snmp_msg_trap trap_msg = {0};
894 trap_msg.snmp_version = SNMP_VERSION_2c;
895 trap_msg.trap_or_inform = SNMP_IS_INFORM;
896 *ptr_request_id = req_id;
897 return snmp_send_trap_or_notification_or_inform_generic(&trap_msg, oid, generic_trap, specific_trap, varbinds);
898}
899
900#endif /* LWIP_SNMP */
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define LWIP_ARRAYSIZE(x)
Definition: def.h:69
#define LWIP_MIN(x, y)
Definition: def.h:66
#define NULL
Definition: types.h:112
#define MIB2_COPY_SYSUPTIME_TO(ptrToVal)
Definition: snmp.h:136
#define ERR_MEM
Definition: fontsub.h:52
GLenum GLenum dst
Definition: glext.h:6340
GLfloat GLfloat p
Definition: glext.h:8902
GLboolean enable
Definition: glext.h:11120
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
int32_t s32_t
Definition: arch.h:130
uint32_t u32_t
Definition: arch.h:129
uint8_t u8_t
Definition: arch.h:125
uint16_t u16_t
Definition: arch.h:127
@ LWIP_IANA_PORT_SNMP_TRAP
Definition: iana.h:80
s8_t err_t
Definition: err.h:96
@ ERR_RTE
Definition: err.h:63
@ ERR_OK
Definition: err.h:55
@ ERR_VAL
Definition: err.h:67
struct pbuf * pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
Definition: pbuf.c:224
u8_t pbuf_free(struct pbuf *p)
Definition: pbuf.c:727
@ PBUF_RAM
Definition: pbuf.h:152
@ PBUF_TRANSPORT
Definition: pbuf.h:93
#define SNMP_MAX_OBJ_ID_LEN
Definition: snmp_opts.h:131
#define SNMP_TRAP_DESTINATIONS
Definition: snmp_opts.h:107
#define ip_2_ip6(ipaddr)
Definition: ip_addr.h:356
#define IP_IS_V6_VAL(ipaddr)
Definition: ip_addr.h:348
#define ip_addr_isany(ipaddr)
Definition: ip_addr.h:377
#define ip_addr_set(dest, src)
Definition: ip_addr.h:363
ip6_addr_t ip_addr_t
Definition: ip_addr.h:344
#define MEMCPY(DST, SRC, BYTES)
Definition: macros.h:231
#define err(...)
Definition: pbuf.h:186
u16_t tot_len
Definition: pbuf.h:200
Definition: pdh_main.c:94