Some news about my issue: it seems something related to engine ID.
If I'm going to send the same V3 trap to two peers I have to define two
unique engine IDs (one for each remote peer) in my trap sender.
If I use the same engine ID only the first trap sending works.
Someone could confirm this?
Thanks.
On Sun, Dec 6, 2015 at 9:37 AM, Emilio FG Fuoco
wrote:
> Hi,
>
> following my code used in order to send the same V3 trap to multiple hosts.
>
> Now, this is en example scenario: Host #1 with wrong V3 credentials Host
> #2 with correct V3 credentials
>
> V3 trap not sent to host #1 => OK because I've wrong credentials V3 trap
> *not* sent to host #2 => NOK because I've correct credentials
>
> Why? It seems SNMP session related to host #2 "inherits" something from
> host #1 session.
>
> Thanks for your help.
>
>
> void MyClass::sendV3Trap(string p_notificationDescriptor, const
> vector& p_trapVariables)
>{
> // SNMP system OID of trap
> oid objid_snmptrap[]= { 1, 3, 6, 1, 6, 3, 1, 1, 4, 1, 0 };
> // for each configured remote hosts
> for (...)
> {
> netsnmp_session session;
> char* p_posix = strdup("POSIXLY_CORRECT=1");
> putenv(p_posix);
> // inits the SNMP session
> snmp_sess_init(&session);
> // SNMP version
> session.version = SNMP_VERSION_3;
> // manages the security name
> session.securityName= "snmpuser";
> session.securityNameLen= strlen("snmpuser");
> // security level is Auth-Priv
> session.securityLevel= SNMP_SEC_LEVEL_AUTHPRIV;
> // manages auth protocol (for example MD5)
> session.securityAuthProto= usmHMACMD5AuthProtocol;
> session.securityAuthProtoLen= USM_AUTH_PROTO_MD5_LEN;
> // manages priv protocol (for example DES)
> session.securityPrivProto= usmDESPrivProtocol;
> session.securityPrivProtoLen= USM_PRIV_PROTO_DES_LEN;
> // manages auth password
> char* Apsz= "authPassword";
> // manages priv password
> char* Xpsz= "privPassword";
> //
> init_snmp("gcpf_trap_sender");
> // makes master key from pass phrases
> session.securityAuthKeyLen= USM_AUTH_KU_LEN;
> if (SNMPERR_SUCCESS!= generate_Ku(session.securityAuthProto,
> session.securityAuthProtoLen, (u_char*)Apsz, strlen(Apsz),
> session.securityAuthKey, &session.securityAuthKeyLen))
> printf("Error generating a key (Ku) from the supplied
> authentication pass phrase");
> session.securityPrivKeyLen= USM_PRIV_KU_LEN;
> if (SNMPERR_SUCCESS!= generate_Ku(session.securityAuthProto,
> session.securityAuthProtoLen, (u_char*)Xpsz, strlen(Xpsz),
> session.securityPrivKey, &session.securityPrivKeyLen))
> printf("Error generating a key (Ku) from the supplied privacy
> pass phrase");
> // peer name (IP address and port of the remote host)
> session.peername= ...;
> // socket and callbacks
> SOCK_STARTUP;
> session.callback = NULL;
> session.callback_magic = NULL;
> // setup the local engineID which may be for either or both of the
> // contextEngineID and/or the securityEngineID
> setup_engineID(NULL, NULL);
> // use our internal engineID as the context
> session.contextEngineID=
> snmpv3_generate_engineID(&session.contextEngineIDLen);
> // sets the engine ID
> size_t ebuf_len= 32;
> size_t eout_len= 0;
> u_char* ebuf= (u_char*)malloc(ebuf_len);
> char* optarg= "0x81";
> if (!snmp_hex_to_binary(&ebuf, &ebuf_len, &eout_len, 1, optarg))
> printf("Bad engine ID value specified in the config file");
> if ((eout_len < 5) || (eout_len > 32))
> printf("Invalid engine ID value specified in the config file");
> session.securityEngineID = ebuf;
> session.securityEngineIDLen = eout_len;
> //
> session.engineBoots= 1;
> //
> session.engineTime= get_uptime();
> netsnmp_session* ss= snmp_add(&session,
> netsnmp_transport_open_client("snmptrap", session.peername), NULL, NULL);
> if (NULL== ss)
> printf("Error snmp_add");
> else
> {
> netsnmp_pdu* pdu= snmp_pdu_create(SNMP_MSG_TRAP2);
> pdu->trap_type = SNMP_TRAP_ENTERPRISESPECIFIC;
> if (!pdu)
> printf("Failed to create notification PDU");
> else
> {
> // for each variable of the trap
> for (...)
> snmp_add_var(pdu, it->m_trapVariableOid,
> sizeof(it->m_trapVariableOid) / sizeof(oid), it->m_trapVariableType,
> it->m_trapVariableValue.c_str());
> snmp_add_var(pdu, objid_snmptrap, sizeof(objid_snmptrap) /
> sizeof(oid), 'o', p_notificationDescriptor.c_str());
> send_trap_to_sess (ss, pdu);
>