agent_trap.c
资源名称:snmp.src.rar [点击查看]
上传用户:cxs890
上传日期:2021-05-22
资源大小:347k
文件大小:49k
源码类别:
SNMP编程
开发平台:
C/C++
- /* agent_trap.c: define trap generation routines for mib modules, etc,
- to use */
- #include <config.h>
- #include <assert.h>
- #if HAVE_UNISTD_H
- #include <unistd.h>
- #endif
- #if HAVE_STDLIB_H
- #include <stdlib.h>
- #endif
- #if HAVE_STRING_H
- #include <string.h>
- #else
- #include <strings.h>
- #endif
- #if TIME_WITH_SYS_TIME
- # ifdef WIN32
- # include <sys/timeb.h>
- # else
- # include <time.h>
- # endif
- # include <time.h>
- #else
- # if HAVE_SYS_TIME_H
- # include <sys/time.h>
- # else
- # include <time.h>
- # endif
- #endif
- #ifdef OS_VXWORKS
- #include <sys/times.h>
- #endif
- #if HAVE_SYS_SOCKET_H
- #include <sys/socket.h>
- #elif HAVE_WINSOCK_H
- #include <ip/socket.h>
- #endif
- #if HAVE_NETINET_IN_H
- #include <netinet/in.h>
- #endif
- #include <ip/in.h>
- #include <ip/ip_var.h>
- #include <ip/ip_externs.h>
- #include <ip/inet.h>
- #include <libsys/timer.h>
- #ifdef OS_VXWORKS
- #include "asn1.h"
- #endif
- #include <snmplib/tools.h>
- #include <snmplib/snmpv3.h>
- #include "snmp_api.h"
- #include "snmp_impl.h"
- #include "snmp_client.h"
- #include "snmp.h"
- #include "system.h"
- #include "read_config.h"
- #include "snmp_debug.h"
- #include "system.h"
- #include "config_struct.h"
- #define SET_SNMP_TRAP_QUEUELEN 0
- #define SET_SNMP_TRAP_TIMEOUT 1
- #define SET_SNMP_TRAP_SOURCE 2
- #define SNMP_AUTH_TRAP 0x0001
- #define SNMP_CONFIG_TRAP 0x0002
- #define SNMP_SNMPTYPE_TRAP 0x0004
- extern oid default_enterprise[10];
- extern struct timeval starttime;
- struct trap_pdu_list {
- struct snmp_pdu *pdu;
- struct trap_pdu_list *next;
- };
- struct trap_sink {
- struct snmp_session *sesp;
- struct trap_sink *next;
- struct trap_pdu_list *pduHead;
- int pduCount;
- int pdutype;
- int version;
- unsigned short trapflags;
- };
- struct trap_sink *sinks = NULL;
- extern char *strdup(char*);
- extern void get_trapsrc_ip(unsigned long *ipaddr);
- #define OID_LENGTH(x) (sizeof(x)/sizeof(x[0]))
- #ifndef SNMP_TRAP_PORT
- #define SNMP_TRAP_PORT 162
- #endif
- oid objid_enterprisetrap[] = { EXTENSIBLEMIB, 251 };
- /*oid version_id[] = { EXTENSIBLEMIB, AGENTID, OSTYPE };*/
- oid version_id[] = { EXTENSIBLEMIB, PRODUCEID};
- int enterprisetrap_len = OID_LENGTH( objid_enterprisetrap );
- int version_id_len = OID_LENGTH( version_id );
- #define SNMPV2_TRAPS_PREFIX SNMP_OID_SNMPMODULES,1,1,5
- oid trap_prefix[] = { SNMPV2_TRAPS_PREFIX };
- oid cold_start_oid[] = { SNMPV2_TRAPS_PREFIX, 1 }; /* SNMPv2-MIB */
- oid warm_start_oid[] = { SNMPV2_TRAPS_PREFIX, 2 }; /* SNMPv2-MIB */
- oid link_down_oid[] = { SNMPV2_TRAPS_PREFIX, 3 }; /* IF-MIB */
- oid link_up_oid[] = { SNMPV2_TRAPS_PREFIX, 4 }; /* IF-MIB */
- oid auth_fail_oid[] = { SNMPV2_TRAPS_PREFIX, 5 }; /* SNMPv2-MIB */
- oid egp_xxx_oid[] = { SNMPV2_TRAPS_PREFIX, 99 }; /* ??? */
- #define SNMPV2_TRAP_OBJS_PREFIX SNMP_OID_SNMPMODULES,1,1,4
- oid snmptrap_oid[] = { SNMPV2_TRAP_OBJS_PREFIX, 1, 0 };
- oid snmptrapenterprise_oid[] = { SNMPV2_TRAP_OBJS_PREFIX, 3, 0 };
- oid sysuptime_oid[] = { SNMP_OID_MIB2,1,3,0 };
- int snmptrap_oid_len = OID_LENGTH(snmptrap_oid);
- int snmptrapenterprise_oid_len = OID_LENGTH(snmptrapenterprise_oid);
- int sysuptime_oid_len = OID_LENGTH(sysuptime_oid);
- static void free_trap_session (struct trap_sink *sp);
- #define SNMP_AUTHENTICATED_TRAPS_ENABLED 1
- #define SNMP_AUTHENTICATED_TRAPS_DISABLED 2
- extern void snmp_delete_targetAddr (char *host_name, char *community);
- extern void snmp_add_targetAddr (char *host_name, char *community, int timeout, int retry);
- extern void snmp_add_targetParam (char *host_name, char *community, int model,
- int secModel, char *secName, int secLevel);
- extern void snmp_delete_targetParam (char *host_name, char *community);
- int snmp_enableauthentraps = SNMP_AUTHENTICATED_TRAPS_ENABLED;
- char *snmp_trapcommunity = NULL;
- int verbose;
- /* Prototypes */
- /*
- static int create_v1_trap_session (const char *, u_short, const char *);
- static int create_v2_trap_session (const char *, u_short, const char *);
- static int create_v2_inform_session (const char *, u_short, const char *);
- static void free_trap_session (struct trap_sink *sp);
- static void send_v1_trap (struct snmp_session *, int, int);
- static void send_v2_trap (struct snmp_session *, int, int, int);
- */
- void show_snmp_host (void)
- {
- struct trap_sink *trapsink;
- if (sinks == NULL)
- {
- vty_printf ("Nonen");
- vty_printf_end(1);
- return;
- }
- for(trapsink=sinks;trapsink!=NULL;trapsink=trapsink->next){
- vty_printf("Notification host: %s udp-port: 162 type: ", trapsink->sesp->peername);
- switch (trapsink->pdutype) {
- case SNMP_MSG_TRAP:
- vty_printf("trapn");
- break;
- case SNMP_MSG_TRAP2:
- vty_printf("trap version 2n");
- break;
- case SNMP_MSG_INFORM:
- vty_printf("informn");
- break;
- default:
- assert(0);
- }
- switch (trapsink->version) {
- case SNMP_VERSION_1:
- vty_printf("community: %s security model: v1nn", trapsink->sesp->community);
- break;
- case SNMP_VERSION_2c:
- vty_printf("community: %s security model: v2cnn", trapsink->sesp->community);
- break;
- case SNMP_VERSION_3:
- vty_printf("user: %s security model: USMnn", trapsink->sesp->securityName);
- break;
- default:
- assert(0);
- }
- }
- vty_printf_end(1);
- }
- int deleteTrapSessionNoRem (char *peer, char *community, int version, int pdutype, char *vrfname)
- {
- struct trap_sink *trapsink,*lasttrapsink;
- lasttrapsink=NULL;
- SNMP_DEBUG_ROUTINES("delete_v1_trap_session()");
- if (version == SNMP_VERSION_3) {
- for(trapsink=sinks;trapsink!=NULL;trapsink=trapsink->next){
- if(!strcmp(trapsink->sesp->peername,peer) &&
- !strcmp (trapsink->sesp->securityName, community) &&
- trapsink->pdutype == pdutype &&
- trapsink->version == SNMP_VERSION_3 &&
- !strcmp(trapsink->sesp->vrfname, vrfname)){
- break;
- }
- lasttrapsink=trapsink;
- }
- }else{
- for(trapsink=sinks;trapsink!=NULL;trapsink=trapsink->next){
- if(!strcmp(trapsink->sesp->peername,peer) &&
- !strcmp (trapsink->sesp->community, community) &&
- trapsink->pdutype == pdutype &&
- trapsink->version == version &&
- !strcmp(trapsink->sesp->vrfname, vrfname)){
- break;
- }
- lasttrapsink=trapsink;
- }
- }
- if(trapsink!=NULL){
- if(lasttrapsink){
- lasttrapsink->next=trapsink->next;
- }else{
- sinks=trapsink->next;
- }
- free_trap_session (trapsink);
- return 1;
- }
- return 0;
- }
- int deleteTrapSession(char *peer, char *community, int version, int pdutype, char *vrfname)
- {
- if (deleteTrapSessionNoRem (peer, community, version, pdutype, vrfname))
- {
- snmp_delete_targetAddr (peer, community);
- snmp_delete_targetParam (peer, community);
- #ifdef INCLUDE_SNMPV3
- if (version == SNMP_VERSION_3) {
- snmpv3_dec_remote_engineID_reference(peer, SNMP_TRAP_PORT);
- }
- #endif /* INCLUDE_SNMPV3*/
- return 1;
- }
- return 0;
- }
- /*******************
- *
- * Trap session handling
- *
- *******************/
- int add_trap_session( struct snmp_session *ss, int pdutype, int version )
- {
- struct trap_sink *new_sink =
- (struct trap_sink *) malloc (sizeof (*new_sink));
- if ( new_sink == NULL )
- return 0;
- new_sink->pduHead = NULL;
- new_sink->pduCount = 0;
- new_sink->sesp = ss;
- new_sink->pdutype = pdutype;
- new_sink->version = version;
- new_sink->next = sinks;
- new_sink->trapflags = 0xFFFF;
- sinks = new_sink;
- return 1;
- }
- int createTrapSessionNoAdd (char *sink,char * com,int timeout,int queuelen,unsigned short trapflags, int version, int pdutype, char *vrfname)
- {
- struct snmp_session session, *sesp;
- int return_val = 0;
- struct trap_sink *new_sink;
- memset (&session, 0, sizeof (struct snmp_session));
- session.peername = strdup(sink);
- if (session.peername == NULL)
- return 0;
- session.version = version;
- session.community = strdup (com);
- if (session.community == NULL)
- {
- free (session.peername);
- return 0;
- }
- session.community_len = strlen (com);
- session.remote_port = SNMP_TRAP_PORT;
- session.securityAuthProtoLen = 0;
- session.contextName = NULL;
- session.securityEngineID = NULL;
- session.securityName = NULL;
- session.securityAuthProto = NULL;
- session.securityPrivProto = NULL;
- strcpy(session.vrfname,vrfname);
- sesp = snmp_open (&session);
- if (sesp) {
- sesp->timeout=timeout*1000000L;
- sesp->retries=queuelen;
- new_sink = (struct trap_sink *) malloc (sizeof (struct trap_sink));
- if ( new_sink == NULL )
- {
- snmp_close(sesp);
- return_val = 0;
- }
- else
- {
- return_val = 1;
- new_sink->pduHead = NULL;
- new_sink->pduCount = 0;
- new_sink->sesp = sesp;
- new_sink->pdutype = pdutype;
- new_sink->version = version;
- new_sink->trapflags = trapflags;
- new_sink->next = sinks;
- sinks = new_sink;
- }
- }
- if (session.peername)
- free (session.peername);
- if (session.community)
- free (session.community);
- /* diagnose snmp_open errors with the input struct snmp_session pointer */
- if (!return_val)
- {
- snmp_sess_perror("snmpd: create_trap_session", &session);
- }
- return return_val;
- }
- int createV1TrapSession (char *sink,char * com,unsigned short trapflags, char *vrfname)
- {
- int return_val;
- if ((return_val = createTrapSessionNoAdd (sink, com, snmp_para.timeout, snmp_para.queuelen, trapflags, SNMP_VERSION_1, SNMP_MSG_TRAP,vrfname)))
- {
- snmp_add_targetAddr (sink, com, 1500, 3);
- snmp_add_targetParam (sink, com, SNMP_MP_MODEL_SNMPv1, SNMP_SEC_MODEL_SNMPv1, com,
- SNMP_SEC_LEVEL_NOAUTH);
- }
- return return_val;
- }
- int createV2TrapSession (char *sink,char * com,unsigned short trapflags, int pdutype,char *vrfname)
- {
- int return_val;
- if ((return_val = createTrapSessionNoAdd (sink, com, snmp_para.timeout, snmp_para.queuelen, trapflags, SNMP_VERSION_2c, pdutype,vrfname)))
- {
- snmp_add_targetAddr (sink, com, 1500, 3);
- snmp_add_targetParam (sink, com, SNMP_MP_MODEL_SNMPv2c, SNMP_SEC_MODEL_SNMPv2c, com,
- SNMP_SEC_LEVEL_NOAUTH);
- }
- return return_val;
- }
- #ifdef INCLUDE_SNMPV3
- /*Sunxi added, 26 Feb, 2004*/
- int createV3TrapSession(char *sink,char * user, int authtype, int pdutype, unsigned short trapflags,char*vrfname)
- {
- struct snmp_session session, *sesp;
- char *engineid;
- memset (&session, 0, sizeof (struct snmp_session));
- session.peername = sink;
- session.version = SNMP_VERSION_3;
- session.community = NULL;
- session.community_len = 0;
- /* by yangyuhua 2006-4-7*/
- strcpy(session.vrfname, vrfname);
- session.remote_port = SNMP_TRAP_PORT;
- engineid = snmpv3_get_remote_engineID(sink, SNMP_TRAP_PORT);
- if (engineid != NULL) {
- snmp_memdup(&session.contextEngineID, engineid, SNMP_MAX_ENG_SIZE);
- snmp_memdup(&session.securityEngineID, engineid, SNMP_MAX_ENG_SIZE);
- session.contextEngineIDLen = SNMP_MAX_ENG_SIZE;
- session.securityEngineIDLen = SNMP_MAX_ENG_SIZE;
- } else {
- vty_output("%%Error: No snmpEngineID configured for remote host %s port %dn", sink, SNMP_TRAP_PORT);
- return -1;
- }
- session.securityName = strdup(user);
- session.securityNameLen = strlen(user);
- session.securityModel = SNMP_SEC_MODEL_USM;
- session.securityLevel = authtype;
- session.timeout = snmp_para.timeout * 1000000L;
- session.retries = SNMP_DEFAULT_RETRIES;
- sesp = snmp_open (&session);
- if (sesp) {
- snmp_add_targetAddr (sink, user, 1500, 3);
- snmp_add_targetParam (sink, user, SNMP_MP_MODEL_SNMPv3, SNMP_SEC_MODEL_USM, user, authtype);
- snmpv3_inc_remote_engineID_reference(sink, SNMP_TRAP_PORT);
- return( add_trap_session( sesp, pdutype, SNMP_VERSION_3 ));
- }
- /* diagnose snmp_open errors with the input struct snmp_session pointer */
- snmp_sess_perror("snmpd: createV3TrapSession", &session);
- return 0;
- }
- int destroyV3TrapSession(char *sink, char *user, int pdutype)
- {
- struct trap_sink *trapsink,*lasttrapsink;
- lasttrapsink=NULL;
- SNMP_DEBUG_ROUTINES("destroyV3TrapSession()");
- for(trapsink=sinks;trapsink!=NULL;trapsink=trapsink->next){
- if(!strcmp(trapsink->sesp->peername,sink) &&
- !strcmp (trapsink->sesp->securityName, user) &&
- trapsink->pdutype == pdutype &&
- trapsink->version == SNMP_VERSION_3){
- /*found it !!!*/
- break;
- }
- lasttrapsink=trapsink;
- }
- if(trapsink!=NULL){
- if(lasttrapsink){
- lasttrapsink->next=trapsink->next;
- }else{
- sinks=trapsink->next;
- }
- /*They will be freed in snmp_close --sxf 2k-12-27
- if (trapsink->sesp->peername != NULL)
- sys_mem_free (trapsink->sesp->peername);
- if (trapsink->sesp->community != NULL)
- sys_mem_free (trapsink->sesp->community);
- */
- free_trap_session (trapsink);
- snmp_delete_targetAddr (sink, user);
- snmp_delete_targetParam (sink, user);
- snmpv3_dec_remote_engineID_reference(sink, SNMP_TRAP_PORT);
- return 1;
- }
- return 0;
- }
- int refreshV3TrapSession(char *sink, char *engineID, size_t engineIDLen)
- {
- struct trap_sink *trapsink,*lasttrapsink;
- lasttrapsink=NULL;
- SNMP_DEBUG_ROUTINES("refreshV3TrapSession()");
- for(trapsink=sinks;trapsink!=NULL;trapsink=trapsink->next){
- if(!strcmp(trapsink->sesp->peername,sink) &&
- trapsink->version == SNMP_VERSION_3){
- /*found it !!!*/
- SNMP_FREE(trapsink->sesp->contextEngineID);
- SNMP_FREE(trapsink->sesp->securityEngineID);
- snmp_memdup((u_char**)(&trapsink->sesp->contextEngineID), engineID, SNMP_MAX_ENG_SIZE);
- snmp_memdup((u_char**)(&trapsink->sesp->securityEngineID), engineID, SNMP_MAX_ENG_SIZE);/*by yangyuhua 2005-12-6*/
- trapsink->sesp->contextEngineIDLen = SNMP_MAX_ENG_SIZE;
- trapsink->sesp->securityEngineIDLen = SNMP_MAX_ENG_SIZE;
- }
- lasttrapsink=trapsink;
- }
- return 0;
- }
- /*end add*/
- #endif /*INCLUDE_SNMPV3*/
- int create_trap_session (char *sink, u_short sinkport,
- char *com,
- int version, int pdutype)
- {
- struct snmp_session session, *sesp;
- memset (&session, 0, sizeof (struct snmp_session));
- session.peername = sink;
- session.version = version;
- if (com) {
- session.community = (u_char *)com;
- session.community_len = strlen (com);
- }
- session.remote_port = sinkport;
- sesp = snmp_open (&session);
- if (sesp) {
- return( add_trap_session( sesp, pdutype, version ));
- }
- /* diagnose snmp_open errors with the input struct snmp_session pointer */
- snmp_sess_perror("snmpd: create_trap_session", &session);
- return 0;
- }
- static int create_v1_trap_session (char *sink, u_short sinkport,
- char *com)
- {
- return create_trap_session( sink, sinkport, com,
- SNMP_VERSION_1, SNMP_MSG_TRAP );
- }
- static int create_v2_trap_session (char *sink, u_short sinkport,
- char *com)
- {
- return create_trap_session( sink, sinkport, com,
- SNMP_VERSION_2c, SNMP_MSG_TRAP2 );
- }
- static int create_v2_inform_session (char *sink, u_short sinkport,
- char *com)
- {
- return create_trap_session( sink, sinkport, com,
- SNMP_VERSION_2c, SNMP_MSG_INFORM );
- }
- static void free_trap_session (struct trap_sink *sp)
- {
- snmp_close(sp->sesp);
- free (sp);
- }
- void snmpd_free_trapsinks (void)
- {
- struct trap_sink *sp = sinks;
- while (sp) {
- sinks = sinks->next;
- free_trap_session(sp);
- sp = sinks;
- }
- }
- /*******************
- *
- * Trap handling
- *
- *******************/
- #if 0
- void send_enterprise_trap_vars (int trap,
- int specific,
- oid *enterprise, int enterprise_length,
- struct variable_list *vars)
- {
- struct variable_list uptime_var, snmptrap_var, enterprise_var;
- struct variable_list *v2_vars, *last_var;
- struct snmp_pdu *template_pdu, *pdu=NULL;
- struct timeval now;
- long uptime;
- struct soaddr_in *pduIp;
- struct trap_sink *sink;
- oid temp_oid[MAX_OID_LEN];
- u_long addr;
- /*
- * Initialise SNMPv2 required variables
- */
- gettimeofday(&now, NULL);
- uptime = calculate_time_diff(&now, &starttime);
- memset (&uptime_var, 0, sizeof (struct variable_list));
- snmp_set_var_objid( &uptime_var, sysuptime_oid, OID_LENGTH(sysuptime_oid));
- snmp_set_var_value( &uptime_var, (u_char *)&uptime, sizeof(uptime) );
- uptime_var.type = ASN_TIMETICKS;
- uptime_var.next_variable = &snmptrap_var;
- memset (&snmptrap_var, 0, sizeof (struct variable_list));
- snmp_set_var_objid( &snmptrap_var, snmptrap_oid, OID_LENGTH(snmptrap_oid));
- /* value set later .... */
- snmptrap_var.type = ASN_OBJECT_ID;
- if ( vars )
- snmptrap_var.next_variable = vars;
- else
- snmptrap_var.next_variable = &enterprise_var;
- /* find end of provided varbind list,
- ready to append the enterprise info if necessary */
- last_var = vars;
- while ( last_var && last_var->next_variable )
- last_var = last_var->next_variable;
- memset (&enterprise_var, 0, sizeof (struct variable_list));
- snmp_set_var_objid( &enterprise_var,
- snmptrapenterprise_oid, OID_LENGTH(snmptrapenterprise_oid));
- snmp_set_var_value( &enterprise_var, (u_char *)enterprise, enterprise_length*sizeof(oid));
- enterprise_var.type = ASN_OBJECT_ID;
- enterprise_var.next_variable = NULL;
- v2_vars = &uptime_var;
- /*
- * Create a template PDU, ready for sending
- */
- template_pdu = snmp_pdu_create( SNMP_MSG_TRAP );
- if ( template_pdu == NULL )
- {
- if ( vars ) snmp_free_var(&enterprise_var);
- snmp_free_varbind(v2_vars);
- return;
- }
- template_pdu->trap_type = trap;
- template_pdu->specific_type = specific;
- if ( snmp_clone_mem((void **)&template_pdu->enterprise,
- enterprise, enterprise_length*sizeof(oid))) {
- snmp_free_pdu( template_pdu );
- if ( vars ) snmp_free_varbind(&enterprise_var);
- snmp_free_varbind(v2_vars);
- return;
- }
- template_pdu->enterprise_length = enterprise_length;
- template_pdu->flags |= UCD_MSG_FLAG_FORCE_PDU_COPY;
- pduIp = (struct soaddr_in *)&template_pdu->agent_addr;
- pduIp->sin_family = AF_INET;
- get_trapsrc_ip(&addr);
- if(addr)
- pduIp->sin_addr.s_addr = addr;
- else
- pduIp->sin_addr.s_addr = get_myaddr();
- template_pdu->time = uptime;
- /*
- * Now use the parameters to determine
- * which v2 variables are needed,
- * and what values they should take.
- */
- switch ( trap ) {
- case -1: /*
- * SNMPv2 only
- * Check to see whether the variables provided
- * are sufficient for SNMPv2 notifications
- */
- if (vars && snmp_oid_compare(vars->name, vars->name_length,
- sysuptime_oid, OID_LENGTH(sysuptime_oid)) == 0 )
- v2_vars = vars;
- else
- if (vars && snmp_oid_compare(vars->name, vars->name_length,
- snmptrap_oid, OID_LENGTH(snmptrap_oid)) == 0 )
- uptime_var.next_variable = vars;
- else {
- /* Hmmm... we don't seem to have a value - oops! */
- snmptrap_var.next_variable = vars;
- }
- last_var = NULL; /* Don't need enterprise info */
- break;
- /* "Standard" SNMPv1 traps */
- case SNMP_TRAP_COLDSTART:
- snmp_set_var_value( &snmptrap_var,
- (u_char *)cold_start_oid,
- sizeof(cold_start_oid));
- break;
- case SNMP_TRAP_WARMSTART:
- snmp_set_var_value( &snmptrap_var,
- (u_char *)warm_start_oid,
- sizeof(warm_start_oid));
- break;
- case SNMP_TRAP_LINKDOWN:
- snmp_set_var_value( &snmptrap_var,
- (u_char *)link_down_oid,
- sizeof(link_down_oid));
- break;
- case SNMP_TRAP_LINKUP:
- snmp_set_var_value( &snmptrap_var,
- (u_char *)link_up_oid,
- sizeof(link_up_oid));
- break;
- case SNMP_TRAP_AUTHFAIL:
- if (snmp_enableauthentraps == SNMP_AUTHENTICATED_TRAPS_DISABLED)
- {
- snmp_free_pdu( template_pdu );
- snmp_free_varbind(v2_vars);
- return;
- }
- snmp_set_var_value( &snmptrap_var,
- (u_char *)auth_fail_oid,
- sizeof(auth_fail_oid));
- break;
- case SNMP_TRAP_EGPNEIGHBORLOSS:
- snmp_set_var_value( &snmptrap_var,
- (u_char *)egp_xxx_oid,
- sizeof(egp_xxx_oid));
- break;
- case SNMP_TRAP_ENTERPRISESPECIFIC:
- memcpy( &temp_oid,
- (char *)enterprise,
- (enterprise_length)*sizeof(oid));
- temp_oid[ enterprise_length ] = 0;
- temp_oid[ enterprise_length+1 ] = specific;
- snmp_set_var_value( &snmptrap_var,
- (u_char *)&temp_oid,
- (enterprise_length+2)*sizeof(oid));
- snmptrap_var.next_variable = vars;
- last_var = NULL; /* Don't need version info */
- break;
- }
- /*
- * Now loop through the list of trap sinks,
- * sending an appropriately formatted PDU to each
- */
- for ( sink = sinks ; sink ; sink=sink->next )
- {
- BOOL bContinue;
- if ( sink->version == SNMP_VERSION_1 && trap == -1 )
- continue; /* Skip v1 sinks for v2 only traps */
- bContinue = TRUE;
- switch ( trap )
- {
- case SNMP_TRAP_COLDSTART:
- case SNMP_TRAP_WARMSTART:
- case SNMP_TRAP_LINKDOWN:
- case SNMP_TRAP_LINKUP:
- if(sink->trapflags&SNMP_SNMPTYPE_TRAP)
- bContinue = FALSE;
- break;
- case SNMP_TRAP_AUTHFAIL:
- if(sink->trapflags&SNMP_AUTH_TRAP)
- bContinue = FALSE;
- break;
- default:
- bContinue = FALSE;
- break;
- }
- if (bContinue)
- continue;
- template_pdu->version = sink->version;
- template_pdu->command = sink->pdutype;
- if ( sink->version != SNMP_VERSION_1 )
- {
- template_pdu->variables = v2_vars;
- if ( last_var )
- last_var->next_variable = &enterprise_var;
- }
- else
- template_pdu->variables = vars;
- pdu = snmp_clone_pdu( template_pdu );
- if (pdu == NULL)
- continue;
- if (!addr)
- {
- IP_ADDR dest_addr, src_addr;
- if (sink->sesp->peername != NULL)
- {
- dest_addr = inet_addr (sink->sesp->peername);
- if (ipof_iffordest(dest_addr, &src_addr) == 0) /*success*/
- {
- pduIp = (struct soaddr_in *)&pdu->agent_addr;
- pduIp->sin_family = AF_INET;
- pduIp->sin_addr.s_addr = src_addr;
- }
- }
- }
- pdu->sessid = sink->sesp->sessid; /* AgentX only ? */
- if ( snmp_send( sink->sesp, pdu) == 0 )
- {
- if (sink->sesp->s_snmp_errno == SNMPERR_BAD_SENDTO)
- {
- if (sink->pduCount+1 < snmp_para.queuelen)
- {
- struct trap_pdu_list *pPduList, *pTemp;
- pPduList = (struct trap_pdu_list *) malloc (sizeof (struct trap_pdu_list));
- if (pPduList == NULL)
- {
- snmp_sess_perror ("snmpd: send_trap", sink->sesp);
- snmp_free_pdu( pdu );
- }
- pPduList->pdu = pdu;
- if (sink->pduHead == NULL)
- {
- pPduList->next = NULL;
- sink->pduHead = pPduList;
- }
- else
- {
- for (pTemp = sink->pduHead; pTemp->next != NULL; pTemp = pTemp->next)
- ;
- pTemp->next = pPduList;
- pPduList->next = NULL;
- }
- sink->pduCount++;
- }
- }
- else
- {
- snmp_sess_perror ("snmpd: send_trap", sink->sesp);
- snmp_free_pdu( pdu );
- }
- }
- else
- {
- snmp_increment_statistic(STAT_SNMPOUTTRAPS);
- snmp_increment_statistic(STAT_SNMPOUTPKTS);
- }
- if ( sink->version != SNMP_VERSION_1 && last_var )
- last_var->next_variable = NULL;
- }
- /* Ensure we don't free anything we shouldn't */
- if ( last_var )
- last_var->next_variable = NULL;
- /* template_pdu->variables = NULL;*/
- snmp_free_pdu( template_pdu );
- snmp_free_pdu( pdu );
- }
- #else
- struct variable_list *
- find_varbind_in_list( struct variable_list *vblist,
- oid *name, size_t len)
- {
- struct variable_list *v;
- for (v=vblist; v; v=v->next_variable)
- if (!snmp_oid_compare(v->name, v->name_length,
- name, len))
- return v;
- return NULL;
- }
- static struct variable_list *
- _copy_varlist(struct variable_list *var, /* source varList */
- int errindex, /* index of variable to drop (if any) */
- int copy_count)
- { /* !=0 number variables to copy */
- struct variable_list *newhead, *newvar, *oldvar;
- int ii = 0;
- newhead = NULL;
- oldvar = NULL;
- while (var && (copy_count-- > 0)) {
- /*
- * Drop the specified variable (if applicable)
- */
- if (++ii == errindex) {
- var = var->next_variable;
- continue;
- }
- /*
- * clone the next variable. Cleanup if alloc fails
- */
- newvar = (struct variable_list *)
- malloc(sizeof(struct variable_list));
- if (snmp_clone_var(var, newvar)) {
- if (newvar)
- free((char *) newvar);
- snmp_free_varbind(newhead);
- return 0;
- }
- /*
- * add cloned variable to new list
- */
- if (0 == newhead)
- newhead = newvar;
- if (oldvar)
- oldvar->next_variable = newvar;
- oldvar = newvar;
- var = var->next_variable;
- }
- return newhead;
- }
- struct variable_list *
- snmp_clone_varbind(struct variable_list * varlist)
- {
- return _copy_varlist(varlist, 0, 10000); /* skip none, copy all */
- }
- struct snmp_pdu*
- convert_v2pdu_to_v1( struct snmp_pdu* template_v2pdu )
- {
- struct snmp_pdu *template_v1pdu;
- struct variable_list *first_vb, *vblist;
- struct variable_list *var;
- size_t len;
- /*
- * Make a copy of the v2 Trap PDU
- * before starting to convert this
- * into a v1 Trap PDU.
- */
- template_v1pdu = snmp_clone_pdu( template_v2pdu);
- if (!template_v1pdu) {
- return NULL;
- }
- template_v1pdu->command = SNMP_MSG_TRAP;
- first_vb = template_v1pdu->variables;
- vblist = template_v1pdu->variables;
- /*
- * The first varbind should be the system uptime.
- */
- if (!vblist ||
- snmp_oid_compare(vblist->name, vblist->name_length,
- sysuptime_oid, sysuptime_oid_len)) {
- snmp_free_pdu(template_v1pdu);
- return NULL;
- }
- template_v1pdu->time = *vblist->val.integer;
- vblist = vblist->next_variable;
- /*
- * The second varbind should be the snmpTrapOID.
- */
- if (!vblist ||
- snmp_oid_compare(vblist->name, vblist->name_length,
- snmptrap_oid, snmptrap_oid_len)) {
- snmp_free_pdu(template_v1pdu);
- return NULL;
- }
- /*
- * Set the generic & specific trap types,
- * and the enterprise field from the v2 varbind list.
- * If there's an agentIPAddress varbind, set the agent_addr too
- */
- if (!snmp_oid_compare(vblist->val.objid, OID_LENGTH(trap_prefix),
- trap_prefix, OID_LENGTH(trap_prefix))) {
- /*
- * For 'standard' traps, extract the generic trap type
- * from the snmpTrapOID value, and take the enterprise
- * value from the 'snmpEnterprise' varbind.
- */
- template_v1pdu->trap_type =
- vblist->val.objid[OID_LENGTH(trap_prefix)] - 1;
- template_v1pdu->specific_type = 0;
- var = find_varbind_in_list( vblist,
- snmptrapenterprise_oid,
- snmptrapenterprise_oid_len);
- if (var) {
- snmp_memdup((u_char**)&template_v1pdu->enterprise,
- (const u_char*)var->val.objid, var->val_len);
- template_v1pdu->enterprise_length = var->val_len/sizeof(oid);
- } else {
- template_v1pdu->enterprise = NULL;
- template_v1pdu->enterprise_length = 0; /* XXX ??? */
- }
- } else {
- /*
- * For enterprise-specific traps, split the snmpTrapOID value
- * into enterprise and specific trap
- */
- len = vblist->val_len / sizeof(oid);
- template_v1pdu->trap_type = SNMP_TRAP_ENTERPRISESPECIFIC;
- template_v1pdu->specific_type = vblist->val.objid[len - 1];
- len--;
- if (vblist->val.objid[len-1] == 0)
- len--;
- SNMP_FREE(template_v1pdu->enterprise);
- snmp_memdup((u_char**)&template_v1pdu->enterprise,
- (u_char *)vblist->val.objid, len*sizeof(oid));
- template_v1pdu->enterprise_length = len;
- }
- #if 0
- var = find_varbind_in_list( vblist, agentaddr_oid,
- agentaddr_oid_len);
- if (var) {
- memcpy(template_v1pdu->agent_addr,
- var->val.string, 4);
- }
- #endif
- /*
- * The remainder of the v2 varbind list is kept
- * as the v2 varbind list. Update the PDU and
- * free the two redundant varbinds.
- */
- template_v1pdu->variables = vblist->next_variable;
- vblist->next_variable = NULL;
- snmp_free_varbind( first_vb );
- return template_v1pdu;
- }
- struct snmp_pdu*
- convert_v1pdu_to_v2( struct snmp_pdu* template_v1pdu )
- {
- struct snmp_pdu *template_v2pdu;
- struct variable_list *first_vb;
- struct variable_list *var;
- oid enterprise[MAX_OID_LEN];
- size_t enterprise_len;
- /*
- * Make a copy of the v1 Trap PDU
- * before starting to convert this
- * into a v2 Trap PDU.
- */
- template_v2pdu = snmp_clone_pdu( template_v1pdu);
- if (!template_v2pdu) {
- return NULL;
- }
- template_v2pdu->command = SNMP_MSG_TRAP2;
- first_vb = template_v2pdu->variables;
- /*
- * Insert an snmpTrapOID varbind before the original v1 varbind list
- * either using one of the standard defined trap OIDs,
- * or constructing this from the PDU enterprise & specific trap fields
- */
- if (template_v1pdu->trap_type == SNMP_TRAP_ENTERPRISESPECIFIC) {
- memcpy(enterprise, template_v1pdu->enterprise,
- template_v1pdu->enterprise_length*sizeof(oid));
- enterprise_len = template_v1pdu->enterprise_length;
- enterprise[enterprise_len++] = 0;
- enterprise[enterprise_len++] = template_v1pdu->specific_type;
- } else {
- memcpy(enterprise, cold_start_oid, sizeof(cold_start_oid));
- enterprise[9] = template_v1pdu->trap_type+1;
- enterprise_len = sizeof(cold_start_oid)/sizeof(oid);
- }
- var = NULL;
- if (!snmp_varlist_add_variable( &var,
- snmptrap_oid, snmptrap_oid_len,
- ASN_OBJECT_ID,
- (u_char*)enterprise, enterprise_len*sizeof(oid))) {
- snmp_free_pdu(template_v2pdu);
- return NULL;
- }
- var->next_variable = template_v2pdu->variables;
- template_v2pdu->variables = var;
- /*
- * Insert a sysUptime varbind at the head of the v2 varbind list
- */
- var = NULL;
- if (!snmp_varlist_add_variable( &var,
- sysuptime_oid, sysuptime_oid_len,
- ASN_TIMETICKS,
- (u_char*)&(template_v1pdu->time),
- sizeof(template_v1pdu->time))) {
- snmp_free_pdu(template_v2pdu);
- return NULL;
- }
- var->next_variable = template_v2pdu->variables;
- template_v2pdu->variables = var;
- /*
- * Append the other three conversion varbinds,
- * (snmpTrapAgentAddr, snmpTrapCommunity & snmpTrapEnterprise)
- * if they're not already present.
- * But don't bomb out completely if there are problems.
- */
- #if 0
- var = find_varbind_in_list( template_v2pdu->variables,
- agentaddr_oid, agentaddr_oid_len);
- if (!var && template_v1pdu->agent_addr[0]
- && template_v1pdu->agent_addr[1]
- && template_v1pdu->agent_addr[2]
- && template_v1pdu->agent_addr[3]) {
- if (!snmp_varlist_add_variable( &(template_v2pdu->variables),
- agentaddr_oid, agentaddr_oid_len,
- ASN_IPADDRESS,
- (u_char*)&(template_v1pdu->agent_addr),
- sizeof(template_v1pdu->agent_addr)))
- snmp_log(LOG_WARNING,
- "send_trap: failed to append snmpTrapAddr varbindn");
- }
- var = find_varbind_in_list( template_v2pdu->variables,
- community_oid, community_oid_len);
- if (!var && template_v1pdu->community) {
- if (!snmp_varlist_add_variable( &(template_v2pdu->variables),
- community_oid, community_oid_len,
- ASN_OCTET_STR,
- template_v1pdu->community,
- strlen(template_v1pdu->community)))
- snmp_log(LOG_WARNING,
- "send_trap: failed to append snmpTrapCommunity varbindn");
- }
- #endif
- var = find_varbind_in_list( template_v2pdu->variables,
- snmptrapenterprise_oid,
- snmptrapenterprise_oid_len);
- if (!var &&
- template_v1pdu->trap_type != SNMP_TRAP_ENTERPRISESPECIFIC) {
- if (!snmp_varlist_add_variable( &(template_v2pdu->variables),
- snmptrapenterprise_oid, snmptrapenterprise_oid_len,
- ASN_OBJECT_ID,
- (u_char*)template_v1pdu->enterprise,
- template_v1pdu->enterprise_length*sizeof(oid)))
- snmp_log(LOG_WARNING,
- "send_trap: failed to append snmpEnterprise varbindn");
- }
- return template_v2pdu;
- }
- void
- send_trap_to_sess(struct trap_sink *sink, struct snmp_pdu *template_pdu)
- {
- struct snmp_pdu *pdu;
- struct soaddr_in *pduIp;
- u_long addr;
- if (!sink->sesp || !template_pdu)
- return;
- template_pdu->version = sink->sesp->version;
- template_pdu->command = sink->pdutype;
- if (sink->sesp->version == SNMP_VERSION_1 &&
- (template_pdu->command == SNMP_MSG_TRAP2 ||
- template_pdu->command == SNMP_MSG_INFORM))
- return; /* Skip v1 sinks for v2 only traps */
- pdu = snmp_clone_pdu(template_pdu);
- pduIp = (struct soaddr_in *)&pdu->agent_addr;/*by yangyuhua 2006-8-29*/
- pduIp->sin_family = AF_INET;
- get_trapsrc_ip(&addr);
- if(addr)
- pduIp->sin_addr.s_addr = addr;
- else
- pduIp->sin_addr.s_addr = get_myaddr();
- if (!addr)
- {
- IP_ADDR dest_addr, src_addr;
- if (sink->sesp->peername != NULL)
- {
- dest_addr = inet_addr (sink->sesp->peername);
- if (ipof_iffordest(dest_addr, &src_addr) == 0) /*success*/
- {
- pduIp = (struct soaddr_in *)&pdu->agent_addr;
- pduIp->sin_family = AF_INET;
- pduIp->sin_addr.s_addr = src_addr;
- }
- }
- }
- pdu->sessid = sink->sesp->sessid; /* AgentX only ? */
- if ( snmp_send( sink->sesp, pdu) == 0 )
- {
- if (sink->sesp->s_snmp_errno == SNMPERR_BAD_SENDTO)
- {
- if (sink->pduCount+1 < snmp_para.queuelen)
- {
- struct trap_pdu_list *pPduList, *pTemp;
- pPduList = (struct trap_pdu_list *) malloc (sizeof (struct trap_pdu_list));
- if (pPduList == NULL)
- {
- snmp_sess_perror ("snmpd: send_trap", sink->sesp);
- snmp_free_pdu( pdu );
- }
- pPduList->pdu = pdu;
- if (sink->pduHead == NULL)
- {
- pPduList->next = NULL;
- sink->pduHead = pPduList;
- }
- else
- {
- for (pTemp = sink->pduHead; pTemp->next != NULL; pTemp = pTemp->next)
- ;
- pTemp->next = pPduList;
- pPduList->next = NULL;
- }
- sink->pduCount++;
- }
- }
- else
- {
- snmp_sess_perror ("snmpd: send_trap", sink->sesp);
- snmp_free_pdu( pdu );
- }
- }
- else
- {
- snmp_increment_statistic(STAT_SNMPOUTTRAPS);
- snmp_increment_statistic(STAT_SNMPOUTPKTS);
- }
- }
- void send_enterprise_trap_vars (int trap,
- int specific,
- oid *enterprise, int enterprise_length,
- struct variable_list *vars)
- {
- /* struct variable_list uptime_var, snmptrap_var, enterprise_var;
- oid temp_oid[MAX_OID_LEN];*/
- struct variable_list *trap_vb, *var;
- struct snmp_pdu *template_v1pdu;
- struct snmp_pdu *template_v2pdu;
- struct timeval now;
- long uptime;
- struct trap_sink *sink;
- struct variable_list *vblist = NULL;
- if (vars) {
- vblist = snmp_clone_varbind( vars );
- if (!vblist) {
- snmp_log(LOG_WARNING,
- "send_trap: failed to clone varbind listn");
- return;
- }
- }
- gettimeofday(&now, NULL);
- uptime = calculate_time_diff(&now, &starttime);
- if ( trap == -1 ) {
- /*
- * Construct the SNMPv2-style notification PDU
- */
- if (!vblist) return;
- template_v2pdu = snmp_pdu_create(SNMP_MSG_TRAP2);
- if (!template_v2pdu) {
- snmp_free_varbind(vblist);
- return;
- }
- /*
- * Check the varbind list we've been given.
- * If it starts with a 'sysUptime.0' varbind, then use that.
- * Otherwise, prepend a suitable 'sysUptime.0' varbind.
- */
- if (!snmp_oid_compare( vblist->name, vblist->name_length,
- sysuptime_oid, sysuptime_oid_len )) {
- template_v2pdu->variables = vblist;
- trap_vb = vblist->next_variable;
- } else {
- var = NULL;
- snmp_varlist_add_variable( &var,
- sysuptime_oid, sysuptime_oid_len,
- ASN_TIMETICKS, (u_char*)&uptime, sizeof(uptime));
- if (!var) {
- snmp_free_varbind(vblist);
- snmp_free_pdu(template_v2pdu);
- return ;
- }
- template_v2pdu->variables = var;
- var->next_variable = vblist;
- trap_vb = vblist;
- }
- /*
- * 'trap_vb' should point to the snmpTrapOID.0 varbind,
- * identifying the requested trap. If not then bomb out.
- * If it's a 'standard' trap, then we need to append an
- * snmpEnterprise varbind (if there isn't already one).
- */
- if (!trap_vb ||
- snmp_oid_compare(trap_vb->name, trap_vb->name_length,
- snmptrap_oid, snmptrap_oid_len)) {
- snmp_free_pdu(template_v2pdu);
- return;
- }
- if (!snmp_oid_compare(vblist->val.objid, OID_LENGTH(trap_prefix),
- trap_prefix, OID_LENGTH(trap_prefix))) {/*查看warm_start_oid等有没有定义*/
- var = find_varbind_in_list( template_v2pdu->variables,
- snmptrapenterprise_oid,
- snmptrapenterprise_oid_len);
- if (!var &&
- !snmp_varlist_add_variable( &(template_v2pdu->variables),
- snmptrapenterprise_oid, snmptrapenterprise_oid_len,
- ASN_OBJECT_ID,
- (char*)enterprise, enterprise_length*sizeof(oid))) {
- snmp_free_pdu(template_v2pdu);
- return ;
- }
- }
- /*
- * If everything's OK, convert the v2 template into an SNMPv1 trap PDU.
- */
- template_v1pdu = convert_v2pdu_to_v1( template_v2pdu );
- if (!template_v1pdu) {
- snmp_free_pdu(template_v2pdu);
- return;
- }
- }else {
- /*
- * Construct the SNMPv1 trap PDU....
- */
- template_v1pdu = snmp_pdu_create(SNMP_MSG_TRAP);
- if (!template_v1pdu) {
- snmp_free_varbind(vblist);
- return ;
- }
- template_v1pdu->trap_type = trap;
- template_v1pdu->specific_type = specific;
- template_v1pdu->time = uptime;
- if (snmp_clone_mem((void **) &template_v1pdu->enterprise,
- enterprise, enterprise_length * sizeof(oid))) {
- snmp_free_varbind(vblist);
- snmp_free_pdu(template_v1pdu);
- return;
- }
- template_v1pdu->enterprise_length = enterprise_length;
- template_v1pdu->flags |= UCD_MSG_FLAG_FORCE_PDU_COPY;
- template_v1pdu->variables = vblist;
- /*
- * ... and convert it into an SNMPv2-style notification PDU.
- */
- template_v2pdu = convert_v1pdu_to_v2( template_v1pdu );
- if (!template_v2pdu) {
- snmp_free_pdu(template_v1pdu);
- return ;
- }
- }
- /*
- * Now loop through the list of trap sinks,
- * sending an appropriately formatted PDU to each
- */
- for ( sink = sinks ; sink ; sink=sink->next )
- {
- BOOL bContinue;
- if ( sink->version == SNMP_VERSION_1 && trap == -1 )
- continue; /* Skip v1 sinks for v2 only traps */
- bContinue = TRUE;
- switch ( trap )
- {
- case SNMP_TRAP_COLDSTART:
- case SNMP_TRAP_WARMSTART:
- case SNMP_TRAP_LINKDOWN:
- case SNMP_TRAP_LINKUP:
- if(sink->trapflags&SNMP_SNMPTYPE_TRAP)
- bContinue = FALSE;
- break;
- case SNMP_TRAP_AUTHFAIL:
- if(sink->trapflags&SNMP_AUTH_TRAP)
- bContinue = FALSE;
- break;
- default:
- bContinue = FALSE;
- break;
- }
- if (bContinue)
- continue;
- if (sink->version == SNMP_VERSION_1) {
- send_trap_to_sess(sink, template_v1pdu);
- } else {
- send_trap_to_sess(sink, template_v2pdu);
- }
- }
- /* Ensure we don't free anything we shouldn't */
- snmp_free_pdu( template_v1pdu );
- snmp_free_pdu( template_v2pdu );
- }
- #endif
- void send_trap_vars (int trap,
- int specific,
- struct variable_list *vars)
- {
- if ( trap == SNMP_TRAP_ENTERPRISESPECIFIC )
- send_enterprise_trap_vars( trap, specific, default_enterprise,
- OID_LENGTH(default_enterprise), vars );
- else
- send_enterprise_trap_vars( trap, specific, default_enterprise,
- OID_LENGTH(default_enterprise), vars );
- }
- void send_easy_trap (int trap,
- int specific)
- {
- send_trap_vars( trap, specific, NULL );
- }
- void send_v2trap ( struct variable_list *vars)
- {
- send_trap_vars( -1, -1, vars );
- }
- void
- send_trap_pdu(struct snmp_pdu *pdu)
- {
- send_trap_vars( -1, -1, pdu->variables );
- }
- /*******************
- *
- * Config file handling
- *
- *******************/
- void snmpd_parse_config_authtrap(const char *token,
- char *cptr)
- {
- int i;
- i = atoi(cptr);
- if ( i == 0 ) {
- if ( !strcmp( cptr, "enable" ))
- i = SNMP_AUTHENTICATED_TRAPS_ENABLED;
- else if ( !strcmp( cptr, "disable" ))
- i = SNMP_AUTHENTICATED_TRAPS_DISABLED;
- }
- if (i < 1 || i > 2)
- config_perror("authtrapenable must be 1 or 2");
- else
- snmp_enableauthentraps = i;
- }
- void snmpd_parse_config_trapsink(const char *token,
- char *cptr)
- {
- char tmpbuf[1024];
- char *sp, *cp, *pp = NULL;
- u_short sinkport;
- if (!snmp_trapcommunity) snmp_trapcommunity = strdup("public");
- sp = strtok(cptr, " tn");
- cp = strtok(NULL, " tn");
- if (cp) pp = strtok(NULL, " tn");
- if (cp && pp) {
- sinkport = (u_short) atoi(pp);
- if ((sinkport < 1) || (sinkport > 0xffff)) {
- config_perror("trapsink port out of range");
- sinkport = SNMP_TRAP_PORT;
- }
- } else {
- sinkport = SNMP_TRAP_PORT;
- }
- if (create_v1_trap_session(sp, sinkport,
- cp ? cp : snmp_trapcommunity) == 0) {
- sprintf(tmpbuf,"cannot create trapsink: %s", cptr);
- config_perror(tmpbuf);
- }
- }
- void
- snmpd_parse_config_trap2sink(const char *word, char *cptr)
- {
- char tmpbuf[1024];
- char *sp, *cp, *pp = NULL;
- u_short sinkport;
- if (!snmp_trapcommunity) snmp_trapcommunity = strdup("public");
- sp = strtok(cptr, " tn");
- cp = strtok(NULL, " tn");
- if (cp) pp = strtok(NULL, " tn");
- if (cp && pp) {
- sinkport = (u_short)atoi(pp);
- if ((sinkport < 1) || (sinkport > 0xffff)) {
- config_perror("trapsink port out of range");
- sinkport = SNMP_TRAP_PORT;
- }
- } else {
- sinkport = SNMP_TRAP_PORT;
- }
- if (create_v2_trap_session(sp, sinkport,
- cp ? cp : snmp_trapcommunity) == 0) {
- sprintf(tmpbuf,"cannot create trap2sink: %s", cptr);
- config_perror(tmpbuf);
- }
- }
- void
- snmpd_parse_config_informsink(const char *word, char *cptr)
- {
- char tmpbuf[1024];
- char *sp, *cp, *pp = NULL;
- u_short sinkport;
- if (!snmp_trapcommunity) snmp_trapcommunity = strdup("public");
- sp = strtok(cptr, " tn");
- cp = strtok(NULL, " tn");
- if (cp) pp = strtok(NULL, " tn");
- if (cp && pp) {
- sinkport = (u_short)atoi(pp);
- if ((sinkport < 1) || (sinkport > 0xffff)) {
- config_perror("trapsink port out of range");
- sinkport = SNMP_TRAP_PORT;
- }
- } else {
- sinkport = SNMP_TRAP_PORT;
- }
- if (create_v2_inform_session(sp, sinkport,
- cp ? cp : snmp_trapcommunity) == 0) {
- sprintf(tmpbuf,"cannot create informsink: %s", cptr);
- config_perror(tmpbuf);
- }
- }
- void
- snmpd_parse_config_trapcommunity(const char *word, char *cptr)
- {
- if (snmp_trapcommunity) free(snmp_trapcommunity);
- snmp_trapcommunity = malloc (strlen(cptr)+1);
- copy_word(cptr, snmp_trapcommunity);
- }
- void snmpd_free_trapcommunity (void)
- {
- if (snmp_trapcommunity) {
- free(snmp_trapcommunity);
- snmp_trapcommunity = NULL;
- }
- }
- #define MIB 1, 3, 6, 1, 2, 1
- oid objid_ifIndex[] = {MIB, 2, 2,1,1, 0};
- static oid objid_ifDescr[] = {MIB, 2,2,1, 2, 0};
- static oid objid_ifType[] = {MIB, 2,2,1, 3, 0};
- static oid objid_ifAdminStatus[] = {MIB, 2,2,1, 7, 0};
- static oid objid_ifOpenStatus[] = {MIB, 2,2,1, 8, 0};
- static long ltmp;
- void send_v1_link_trap(int trap_type,int if_index,int if_type,unsigned char *if_desr)
- {
- struct variable_list *vl = NULL;
- int namelen;
- UINT16 iAdminTemp=0;
- namelen=sizeof (objid_ifIndex)/sizeof(oid);
- objid_ifIndex[namelen-1]=if_index;
- ltmp = if_index;
- snmp_varlist_add_variable(&vl, objid_ifIndex, namelen, ASN_INTEGER,
- (char*)<mp, sizeof (long));
- namelen=sizeof (objid_ifDescr)/sizeof(oid);
- objid_ifDescr[namelen-1]=if_index;
- snmp_varlist_add_variable(&vl, objid_ifDescr, namelen, ASN_OCTET_STR,
- (char*)if_desr, strlen (if_desr));
- namelen=sizeof (objid_ifType)/sizeof(oid);
- objid_ifType[namelen-1]=if_index;
- ltmp = if_type;
- snmp_varlist_add_variable(&vl, objid_ifType, namelen, ASN_INTEGER,
- (char*)<mp, sizeof (long));
- interface_omnivorous_callback_getshutdown(if_index, (UINT16 *)&iAdminTemp);
- if (iAdminTemp & 1)
- {
- ltmp = 2;
- }
- else
- {
- ltmp = 1;
- }
- namelen=sizeof (objid_ifAdminStatus)/sizeof(oid);
- objid_ifAdminStatus[namelen-1]=if_index;
- snmp_varlist_add_variable(&vl, objid_ifAdminStatus, namelen, ASN_INTEGER,
- (char*)<mp, sizeof (long));
- switch ( trap_type )
- {
- case SNMP_TRAP_LINKDOWN:
- namelen=sizeof (objid_ifOpenStatus)/sizeof(oid);
- objid_ifOpenStatus[namelen-1]=if_index;
- ltmp = trap_type;
- snmp_varlist_add_variable(&vl, objid_ifOpenStatus, namelen, ASN_INTEGER,
- (char*)<mp, sizeof (long));
- break;
- case SNMP_TRAP_LINKUP:
- namelen=sizeof (objid_ifOpenStatus)/sizeof(oid);
- objid_ifOpenStatus[namelen-1]=if_index;
- ltmp = 1;
- snmp_varlist_add_variable(&vl, objid_ifOpenStatus, namelen, ASN_INTEGER,
- (char*)<mp, sizeof (long));
- break;
- default:
- break;
- }
- send_trap_vars (trap_type, -1, vl);
- snmp_free_varbind (vl);
- }
- void send_link_trap(int version,int trap_type,int if_index,int if_type,unsigned char *if_desr)
- {
- send_v1_link_trap(trap_type,if_index,if_type,if_desr);
- }
- #ifndef OS_VXWORKS
- static ULONG trapTimerID = 0;
- #endif
- static void retry_send_trap(ULONG arg)
- {
- struct trap_sink *sinkPtr;
- struct trap_pdu_list *prevPtr, *curPtr;
- for ( sinkPtr = sinks ; sinkPtr != NULL; sinkPtr=sinkPtr->next )
- {
- prevPtr = NULL;
- for (curPtr = sinkPtr->pduHead; curPtr != NULL; )
- {
- IP_ADDR dest_addr, src_addr;
- struct soaddr_in *pduIp;
- if (sinkPtr->sesp->peername != NULL)
- {
- dest_addr = inet_addr (sinkPtr->sesp->peername);
- if (ipof_iffordest(dest_addr, &src_addr) == 0) /*success*/
- {
- pduIp = (struct soaddr_in *)&(curPtr->pdu->agent_addr);
- pduIp->sin_family = AF_INET;
- pduIp->sin_addr.s_addr = src_addr;
- }
- }
- if (snmp_send( sinkPtr->sesp, curPtr->pdu) != 0)
- {
- if (prevPtr == NULL)
- {
- sinkPtr->pduHead = curPtr->next;
- free (curPtr);
- curPtr = sinkPtr->pduHead;
- }
- else
- {
- prevPtr->next = curPtr->next;
- free (curPtr);
- curPtr = prevPtr->next;
- }
- sinkPtr->pduCount --;
- snmp_increment_statistic(STAT_SNMPOUTTRAPS);
- snmp_increment_statistic(STAT_SNMPOUTPKTS);
- }
- else
- {
- prevPtr = curPtr;
- curPtr = curPtr->next;
- }
- }
- }
- #ifndef OS_VXWORKS
- sys_start_timer(trapTimerID,snmp_para.timeout);
- #endif
- }
- #ifdef OS_VXWORKS
- void snmp_retry_send_trap()
- {
- while (1)
- {
- sys_task_delay(snmp_para.timeout * SYS_CLK_RATE);
- retry_send_trap(0);
- }
- }
- #endif
- void init_trap_retry_timer(void)
- {
- #ifndef OS_VXWORKS
- TIMER_USER_DATA user_data;
- user_data.cb.fun=retry_send_trap;
- user_data.cb.arg=0;
- sys_add_timer(TIMER_CALLBACK_METHOD,&user_data,&trapTimerID);
- sys_start_timer(trapTimerID,snmp_para.timeout);
- #else
- sys_task_spawn("SNMT", SYS_TASK_PRI_NORMAL, T_OP_NOPREEMPT, 16*1024, snmp_retry_send_trap, NULL, 0);
- #endif
- }
- void set_trapsinks(int cmd,long long value)
- {
- struct trap_sink *trapsink;
- SNMP_DEBUG_ROUTINES("set_trapsinks()");
- for(trapsink=sinks;trapsink!=NULL;trapsink=trapsink->next){
- switch(cmd){
- case SET_SNMP_TRAP_QUEUELEN:
- trapsink->sesp->retries=(int)value;
- break;
- case SET_SNMP_TRAP_TIMEOUT:
- trapsink->sesp->timeout=(int)value;
- #ifndef OS_VXWORKS
- sys_stop_timer (trapTimerID);
- sys_start_timer(trapTimerID,snmp_para.timeout);
- #endif
- break;
- case SET_SNMP_TRAP_SOURCE:
- change_session_localaddr(trapsink->sesp,(DEVICE_ETERNAL_ID)value);
- break;
- }
- }
- }