/** * Sends an generic or enterprise specific trap message. * * @param generic_trap is the trap code * @param eoid points to enterprise object identifier * @param specific_trap used for enterprise traps when generic_trap == 6 * @return ERR_OK when success, ERR_MEM if we're out of memory * * @note the caller is responsible for filling in outvb in the trap_msg * @note the use of the enterpise identifier field * is per RFC1215. * Use .iso.org.dod.internet.mgmt.mib-2.snmp for generic traps * and .iso.org.dod.internet.private.enterprises.yourenterprise * (sysObjectID) for specific traps. */ err_t snmp_send_trap(s8_t generic_trap, struct snmp_obj_id *eoid, s32_t specific_trap) { struct snmp_trap_dst *td; struct netif *dst_if; ip_addr_t dst_ip; struct pbuf *p; u16_t i,tot_len; for (i=0, td = &trap_dst[0]; i<SNMP_TRAP_DESTINATIONS; i++, td++) { if ((td->enable != 0) && !ip_addr_isany(&td->dip)) { /* network order trap destination */ ip_addr_copy(trap_msg.dip, td->dip); /* lookup current source address for this dst */ dst_if = ip_route(&td->dip); ip_addr_copy(dst_ip, dst_if->ip_addr); /* @todo: what about IPv6? */ trap_msg.sip_raw[0] = ip4_addr1(&dst_ip); trap_msg.sip_raw[1] = ip4_addr2(&dst_ip); trap_msg.sip_raw[2] = ip4_addr3(&dst_ip); trap_msg.sip_raw[3] = ip4_addr4(&dst_ip); trap_msg.gen_trap = generic_trap; trap_msg.spc_trap = specific_trap; if (generic_trap == SNMP_GENTRAP_ENTERPRISESPC) { /* enterprise-Specific trap */ trap_msg.enterprise = eoid; } else { /* generic (MIB-II) trap */ snmp_get_snmpgrpid_ptr(&trap_msg.enterprise); } snmp_get_sysuptime(&trap_msg.ts); /* pass 0, calculate length fields */ tot_len = snmp_varbind_list_sum(&trap_msg.outvb); tot_len = snmp_trap_header_sum(&trap_msg, tot_len); /* allocate pbuf(s) */ p = pbuf_alloc(PBUF_TRANSPORT, tot_len, PBUF_POOL); if (p != NULL) { u16_t ofs; /* pass 1, encode packet ino the pbuf(s) */ ofs = snmp_trap_header_enc(&trap_msg, p); snmp_varbind_list_enc(&trap_msg.outvb, p, ofs); snmp_inc_snmpouttraps(); snmp_inc_snmpoutpkts(); /** send to the TRAP destination */ udp_sendto(trap_msg.pcb, p, &trap_msg.dip, SNMP_TRAP_PORT); pbuf_free(p); } else { return ERR_MEM; } } } return ERR_OK; }
/** * Sends an generic or enterprise specific trap message. * * @param generic_trap is the trap code * @param eoid points to enterprise object identifier * @param specific_trap used for enterprise traps when generic_trap == 6 * @return ERR_OK when success, ERR_MEM if we're out of memory * * @note the use of the enterprise identifier field * is per RFC1215. * Use .iso.org.dod.internet.mgmt.mib-2.snmp for generic traps * and .iso.org.dod.internet.private.enterprises.yourenterprise * (sysObjectID) for specific traps. */ static err_t snmp_send_trap(const struct snmp_obj_id *device_enterprise_oid, s32_t generic_trap, s32_t specific_trap) { struct snmp_msg_trap trap_msg; struct snmp_trap_dst *td; struct pbuf *p; u16_t i, tot_len; err_t err = ERR_OK; trap_msg.snmp_version = 0; for (i = 0, td = &trap_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(snmp_traps_handle, &td->dip, &trap_msg.sip)) { if (device_enterprise_oid == NULL) { trap_msg.enterprise = snmp_get_device_enterprise_oid(); } else { trap_msg.enterprise = device_enterprise_oid; } trap_msg.gen_trap = generic_trap; if (generic_trap == SNMP_GENTRAP_ENTERPRISE_SPECIFIC) { trap_msg.spc_trap = specific_trap; } else { trap_msg.spc_trap = 0; } MIB2_COPY_SYSUPTIME_TO(&trap_msg.ts); /* pass 0, calculate length fields */ tot_len = snmp_trap_header_sum(&trap_msg); /* allocate pbuf(s) */ p = pbuf_alloc(PBUF_TRANSPORT, tot_len, PBUF_RAM); if (p != NULL) { struct snmp_pbuf_stream pbuf_stream; snmp_pbuf_stream_init(&pbuf_stream, p, 0, tot_len); /* pass 1, encode packet ino the pbuf(s) */ snmp_trap_header_enc(&trap_msg, &pbuf_stream); snmp_stats.outtraps++; snmp_stats.outpkts++; /** send to the TRAP destination */ snmp_sendto(snmp_traps_handle, p, &td->dip, SNMP_TRAP_PORT); } else { err = ERR_MEM; } } else { /* routing error */ err = ERR_RTE; } } } return err; }
/** * Sends an generic or enterprise specific trap message. * * @param generic_trap is the trap code * @param eoid points to enterprise object identifier * @param specific_trap used for enterprise traps when generic_trap == 6 * @return ERR_OK when success, ERR_MEM if we're out of memory * * @note the caller is responsible for filling in outvb in the trap_msg * @note the use of the enterpise identifier field * is per RFC1215. * Use .iso.org.dod.internet.mgmt.mib-2.snmp for generic traps * and .iso.org.dod.internet.private.enterprises.yourenterprise * (sysObjectID) for specific traps. */ err_t snmp_send_trap(s8_t generic_trap, struct snmp_obj_id *eoid, s32_t specific_trap) { struct snmp_trap_dst *td; struct netif *dst_if; struct ip_addr dst_ip; struct pbuf *p; u16_t i,tot_len; for (i=0, td = &trap_dst[0]; i<SNMP_TRAP_DESTINATIONS; i++, td++) { if ((td->enable != 0) && (td->dip.addr != 0)) { /* network order trap destination */ trap_msg.dip.addr = td->dip.addr; /* lookup current source address for this dst */ dst_if = ip_route(&td->dip); dst_ip.addr = ntohl(dst_if->ip_addr.addr); trap_msg.sip_raw[0] = dst_ip.addr >> 24; trap_msg.sip_raw[1] = dst_ip.addr >> 16; trap_msg.sip_raw[2] = dst_ip.addr >> 8; trap_msg.sip_raw[3] = dst_ip.addr; trap_msg.gen_trap = generic_trap; trap_msg.spc_trap = specific_trap; if (generic_trap == SNMP_GENTRAP_ENTERPRISESPC) { /* enterprise-Specific trap */ trap_msg.enterprise = eoid; } else { /* generic (MIB-II) trap */ snmp_get_snmpgrpid_ptr(&trap_msg.enterprise); } snmp_get_sysuptime(&trap_msg.ts); /* pass 0, calculate length fields */ tot_len = snmp_varbind_list_sum(&trap_msg.outvb); tot_len = snmp_trap_header_sum(&trap_msg, tot_len); /* allocate pbuf(s) */ p = pbuf_alloc(PBUF_TRANSPORT, tot_len, PBUF_POOL); if (p != NULL) { u16_t ofs; /* pass 1, encode packet ino the pbuf(s) */ ofs = snmp_trap_header_enc(&trap_msg, p); snmp_varbind_list_enc(&trap_msg.outvb, p, ofs); snmp_inc_snmpouttraps(); snmp_inc_snmpoutpkts(); /** connect to the TRAP destination */ udp_connect(trap_msg.pcb, &trap_msg.dip, SNMP_TRAP_PORT); udp_send(trap_msg.pcb, p); /** disassociate remote address and port with this pcb */ udp_disconnect(trap_msg.pcb); pbuf_free(p); } else { return ERR_MEM; } } }
/** * Sends an generic or enterprise specific trap message. * * @param generic_trap is the trap code * @param eoid points to enterprise object identifier * @param specific_trap used for enterprise traps when generic_trap == 6 * @return ERR_OK when success, ERR_MEM if we're out of memory * * @note the caller is responsible for filling in outvb in the trap_msg * @note the use of the enterprise identifier field * is per RFC1215. * Use .iso.org.dod.internet.mgmt.mib-2.snmp for generic traps * and .iso.org.dod.internet.private.enterprises.yourenterprise * (sysObjectID) for specific traps. */ err_t snmp_send_trap(s8_t generic_trap, const struct snmp_obj_id *eoid, s32_t specific_trap) { struct snmp_trap_dst *td; struct netif *dst_if; const ip_addr_t* dst_ip; struct pbuf *p; u16_t i,tot_len; err_t err = ERR_OK; for (i = 0, td = &trap_dst[0]; i < SNMP_TRAP_DESTINATIONS; i++, td++) { if ((td->enable != 0) && !ip_addr_isany(&td->dip)) { /* network order trap destination */ ip_addr_copy(trap_msg.dip, td->dip); /* lookup current source address for this dst */ ip_route_get_local_ip(PCB_ISIPV6(trap_msg.pcb), &trap_msg.pcb->local_ip, &td->dip, dst_if, dst_ip); if ((dst_if != NULL) && (dst_ip != NULL)) { trap_msg.sip_raw_len = (IP_IS_V6_VAL(*dst_ip) ? 16 : 4); memcpy(trap_msg.sip_raw, dst_ip, trap_msg.sip_raw_len); trap_msg.gen_trap = generic_trap; trap_msg.spc_trap = specific_trap; if (generic_trap == SNMP_GENTRAP_ENTERPRISESPC) { /* enterprise-Specific trap */ trap_msg.enterprise = eoid; } else { /* generic (MIB-II) trap */ mib2_get_snmpgrpid_ptr(&trap_msg.enterprise); } MIB2_COPY_SYSUPTIME_TO(&trap_msg.ts); /* pass 0, calculate length fields */ tot_len = snmp_varbind_list_sum(&trap_msg.outvb); tot_len = snmp_trap_header_sum(&trap_msg, tot_len); /* allocate pbuf(s) */ p = pbuf_alloc(PBUF_TRANSPORT, tot_len, PBUF_RAM); if (p != NULL) { u16_t ofs; /* pass 1, encode packet ino the pbuf(s) */ ofs = snmp_trap_header_enc(&trap_msg, p); snmp_varbind_list_enc(&trap_msg.outvb, p, ofs); mib2_inc_snmpouttraps(); mib2_inc_snmpoutpkts(); /** send to the TRAP destination */ udp_sendto(trap_msg.pcb, p, &trap_msg.dip, SNMP_TRAP_PORT); pbuf_free(p); } else { err = ERR_MEM; } } else { /* routing error */ err = ERR_RTE; } } } return err; }