Agent++ listen address for sending traps ipv6 bug

There is a define in agent++.h header - USE_LISTEN_ADDRESS_FOR_SENDING_TRAPS.
snmp_request.cpp, method Snmpx *SnmpRequest::get_new_snmp(Snmpx* snmp, int &status). If USE_LISTEN_ADDRESS_FOR_SENDING_TRAPS is not defined (0.0.0.0 or [::] listen address is more suitable for me, so I’ve undefined it), Snmpx will be created with ipv4 0.0.0.0 listen address regardless of sending address type (ipv4 or ipv6), so sending traps to ipv6 is not possible.
My workaround looks like this:

Snmpx *SnmpRequest::get_new_snmp(Snmpx* snmp, int &status)
{
    Snmpx *snmpx;

    status = SNMP_CLASS_ERROR;

#ifdef USE_LISTEN_ADDRESS_FOR_SENDING_TRAPS
    if (snmp)
    {
	UdpAddress addr = snmp->get_listen_address();
	addr.set_port(0);
	snmpx = new Snmpx(status, addr);
    }
    else
    {
	LOG_BEGIN(loggerModuleName, WARNING_LOG | 1);
	LOG("SnmpRequestV3: Binding to all interfaces");
	LOG_END;
	snmpx = new Snmpx(status, 0);
    }
#else
    if (snmp)
	{
		if (snmp->get_listen_address().get_ip_version() == IpAddress::version_ipv4)
		    snmpx = new Snmpx(status, "0.0.0.0");
		else
		    snmpx = new Snmpx(status, "::");
	}
	else
        snmpx = new Snmpx(status, 0);
#endif
    return snmpx;
}

What do you think about it? Is there a better solution?

Hi,

thanks for your report. The next release of agent++ will have a slightly different patch. I added the optional bind_ipv6 parameter from Snmp constructor to the Snmpx constructor, so the result of the IPv6 comparison can be passed to the Snmpx constructor.

Kind regards,
Jochen

Hi,
I appreciate that.
About ipv6 related bugs, please pay attention to SnmpSocket Snmpx::get_session_fds(). Regardless of which address is used, ipv4 or ipv6, the method returns a descriptor for ipv4, which is incorrect if ipv6 is used.

Thanks again for this new report.

The obvious fix is a new function SnmpSocket get_session_fds_ipv6() { return iv_snmp_session_ipv6; }, but maybe I should rethink the whole thing with two listening sockets:

  • If IPv6 is disabled, no IPv6 hosts can be reached, so there is no need for a second socket
  • If IPv6 is enabled, the user has the choice:
    • If no IPv6 hosts have to be accessed, an IPv4 listen address can be used
    • If IPv6 communication is needed, an IPv6 listen address can be used
    • If IPv6 and IPv4 is needed, use “::” as listen address and it is possible to use this socket for IPv4 and IPv6

I think the last point was not working on all systems, so the second socket was used.