Discussion:
Sending V3 trap to multiple hosts
(too old to reply)
Emilio FG Fuoco
2015-12-14 16:46:39 UTC
Permalink
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.
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<GcpfTrapVariable>& 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= "0x8000000001";
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);
snmp_free_pdu(pdu);
snmp_close(ss);
}
}
} // end for}
Ilya Etingof
2015-12-20 13:08:19 UTC
Permalink
Since there is no SNMP engine ID discovery being performed for SNMPv3 TRAP messages, your Notification
Receiver must have [the authoritative] SNMP engine ID of your Notification Originator explicitly configured
to its LCD. Technically, it’s engineID + username.

In other words, there is no need to have two distinct engine IDs at your trap sender, just set one to a unique and
fixed value, then configure it to your Notification Receivers. The other [very hackerish] way that may also work would
be for your trap sender to temporarily “borrow" SNMP engine IDs of your Notification Receivers [one at a time] and use
them as its own while sending TRAPs. But that’s against SNMP design, so I’d not do that.

More info:

http://www.net-snmp.org/wiki/index.php/TUT:snmptrap_SNMPv3 <http://www.net-snmp.org/wiki/index.php/TUT:snmptrap_SNMPv3>
Post by Emilio FG Fuoco
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.
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<GcpfTrapVariable>& 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= "0x8000000001";
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);
snmp_free_pdu(pdu);
snmp_close(ss);
}
}
} // end for
}
------------------------------------------------------------------------------
_______________________________________________
Net-snmp-users mailing list
https://lists.sourceforge.net/lists/listinfo/net-snmp-users
Ajit Ambekar
2015-12-20 14:05:06 UTC
Permalink
Hi Emilio,
Let me share my experience here.

I have observed that to receive a V3 Trap with net-snmp library, its Engine
ID need to be defined in the snmptrap.conf file of the reciever. Otherwise
the trap is not identified by usm engine.

I am also stuck for a solution where I can recieve SNMPv3 traps without
knowing the EngineID's.

Regards,
Ajit
Post by Ilya Etingof
Since there is no SNMP engine ID discovery being performed for SNMPv3 TRAP
messages, your Notification
Receiver must have [the authoritative] SNMP engine ID of your Notification
Originator explicitly configured
to its LCD. Technically, it’s engineID + username.
In other words, there is no need to have two distinct engine IDs at your
trap sender, just set one to a unique and
fixed value, then configure it to your Notification Receivers. The other
[very hackerish] way that may also work would
be for your trap sender to temporarily “borrow" SNMP engine IDs of your
Notification Receivers [one at a time] and use
them as its own while sending TRAPs. But that’s against SNMP design, so
I’d not do that.
http://www.net-snmp.org/wiki/index.php/TUT:snmptrap_SNMPv3
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.
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<GcpfTrapVariable>& 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= "0x8000000001";
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);
snmp_free_pdu(pdu);
snmp_close(ss);
}
}
} // end for}
------------------------------------------------------------------------------
_______________________________________________
Net-snmp-users mailing list
https://lists.sourceforge.net/lists/listinfo/net-snmp-users
------------------------------------------------------------------------------
_______________________________________________
Net-snmp-users mailing list
https://lists.sourceforge.net/lists/listinfo/net-snmp-users
--
Ambekar Ajit Shivaji
Mumbai.
Loading...