SNMP4J 2.8.6- TCP traps coming from different ips are lost

We have a java application (JDK version 1.8) which uses snm4j(2.8.6) library which consumes SNMPV3 traps which are sent to port 10118 and host interface 0.0.0.0 . but the application is able to read the traps from IP e.g 1.2.3.4:10118 but not from IP 9.8.7.5:10118 and these traps can be seen in tcpdump and all packets are valid. How to make the application listen to all the traps sent to port 10118 (from any host)

You cannot send a UDP message to IPv4 “0.0.0.0”. So what you describe is supposed to fail. (But maybe you meant that the SNMP4J based trap receiver is listening on 0.0.0.0/10118?)

Are the traps sent with noAuthNoPriv security level?

Yes the Java app is a listener and listening at 0.0.0.0:10118 and it is a TCP protocol with authpriv enabled (authentication model is md5 and privacy protocol AES).

need your suggestion here please.

Can you post a code snippet of your trapSender and trapReciever. The application which receives the traps should be able to receive any trap from any host, assuming that the trapSender has the correct target information set for the trapReciever.

And we see below in snmp4j debug logs
RFC3414 §3.2.7.a Not in time window;

import groovy.transform.CompileStatic
import groovy.util.logging.Log4j2
import org.apache.camel.Endpoint
import org.apache.camel.Exchange
import org.apache.camel.Processor
import org.apache.camel.component.snmp.SnmpMessage
import org.apache.camel.support.DefaultConsumer
import org.apache.commons.codec.binary.Hex
import org.apache.log4j.Logger
import org.snmp4j.*
import org.snmp4j.mp.*
import org.snmp4j.security.Priv3DES
import org.snmp4j.security.SecurityModels
import org.snmp4j.security.USM
import org.snmp4j.security.UsmUser
import org.snmp4j.smi.*
import org.snmp4j.transport.DefaultTcpTransportMapping
import org.snmp4j.transport.DefaultUdpTransportMapping

@Log4j2
@CompileStatic
class SnmpTrapConsumer extends DefaultConsumer implements CommandResponder {

static final Logger TRANSPORTLOG =  Logger.getLogger('transport.trap.consumer')

SnmpEndpoint endpoint
private Address listenGenericAddress
private Snmp snmp
private TransportMapping<? extends Address> transport

SnmpTrapConsumer(Endpoint endpoint, Processor processor) {
    super(endpoint, processor)
    this.endpoint = (SnmpEndpoint) endpoint
}

@Override
@SuppressWarnings('MethodSize')
protected void doStart() throws Exception {
    super.doStart()

    // load connection data only if the endpoint is enabled
    if (log.isInfoEnabled()) {
        log.info('Starting trap consumer on {}', this.endpoint.getAddress())
    }

    this.listenGenericAddress = GenericAddress.parse(this.endpoint.getAddress())

    // either tcp or udp
    if (endpoint.getProtocol() == 'tcp') {
        this.transport = new DefaultTcpTransportMapping((TcpAddress) this.listenGenericAddress)
    } else if (endpoint.getProtocol() == 'udp') {
        this.transport = new DefaultUdpTransportMapping((UdpAddress) this.listenGenericAddress)
    } else {
        throw new IllegalArgumentException('Unknown protocol: ' + endpoint.getProtocol())
    }

    MessageDispatcher dispatcher = new MessageDispatcherImpl()
    switch (endpoint.snmpVersion) {
        case SnmpConstants.version2c:
            dispatcher.addMessageProcessingModel(new MPv2c())
            break
        case SnmpConstants.version3:
            dispatcher.addMessageProcessingModel(new MPv3())
            break
        default:
            throw new IllegalArgumentException('Unsupported SNMP version ' + endpoint.snmpVersion)
    }
    this.snmp = new Snmp(dispatcher, transport)

    if (endpoint.snmpVersion == SnmpConstants.version3) {
        configureUSM()
        byte[] byteEngineID
        if (endpoint.localEngineName != null) {
            byteEngineID = MPv3.createLocalEngineID(new OctetString(endpoint.localEngineName))
            this.snmp.setLocalEngine(byteEngineID, 0, 0)
        }
        log.info('The local snmp entity engine id is : {}',
                Hex.encodeHexString(this.snmp.getLocalEngineID()))
    }

    this.snmp.addCommandResponder(this)

    // listen to the transport
    if (log.isDebugEnabled()) {
        log.debug('Starting trap consumer on {} using {} protocol',
                endpoint.getAddress(), endpoint.getProtocol())
    }
    this.transport.listen()
    if (log.isInfoEnabled()) {
        log.info('Started trap consumer on {} using {} protocol',
                endpoint.getAddress(), endpoint.getProtocol())
    }
}

/**
 * Generate and set USM upon configuration
 * @throws Exception if illegal parameters configured
 */
private void configureUSM() throws Exception {
    UsmUser user = SnmpHelper.createUsmUser(endpoint.securityLevel,
            ['userName' : endpoint.userName,
            'authProtocol' : endpoint.authenticationProtocol,
            'authPassphrase' : endpoint.authenticationPassphrase,
            'privProtocol' : endpoint.privacyProtocol,
            'privPassphrase' : endpoint.privacyPassphrase,])
    if (user) {
        USM usm = new USM()
        SecurityModels.getInstance().addSecurityModel(usm)
        //by default, SNMP4j did not add Priv3DES protocol support
        if (endpoint.privacyProtocol?.toUpperCase() == SnmpPrivacyProtocolType.TRIDES.toString() &&
            snmp.getUSM().getSecurityProtocols().getPrivacyProtocol(Priv3DES.ID) == null) {
            snmp.getUSM().getSecurityProtocols().addPrivacyProtocol(new Priv3DES())
        }
        this.snmp.getUSM().addUser(new OctetString(endpoint.userName), user)
    }
}

@Override
protected void doStop() throws Exception {
    // stop listening to the transport
    if (this.transport != null && this.transport.isListening()) {
        if (log.isDebugEnabled()) {
            log.debug('Stopping trap consumer on {}', this.endpoint.getAddress())
        }
        this.transport.close()
        log.info('Stopped trap consumer on {}', this.endpoint.getAddress())
    }

    super.doStop()
}

@Override
void processPdu(CommandResponderEvent event) {
    PDU pdu = event.getPDU()
    TRANSPORTLOG.trace("Received trap event for ${this.endpoint.getAddress()} : ${pdu}")
    // check PDU not null
    if (pdu != null) {
        // check for INFORM
        // code take from the book "Essential SNMP"
        if (pdu.getType() != PDU.TRAP && pdu.getType() != PDU.V1TRAP && pdu.getType() != PDU.REPORT
                && pdu.getType() != PDU.RESPONSE) {
            // first response the inform-message and then process the
            // message
            pdu.setErrorIndex(0)
            pdu.setErrorStatus(0)
            pdu.setType(PDU.RESPONSE)
            StatusInformation statusInformation = new StatusInformation()
            StateReference ref = event.getStateReference()
            try {
                event.getMessageDispatcher().returnResponsePdu(event.getMessageProcessingModel(),
                        event.getSecurityModel(),
                        event.getSecurityName(),
                        event.getSecurityLevel(), pdu,
                        event.getMaxSizeResponsePDU(), ref,
                        statusInformation)
                if (log.isDebugEnabled()) {
                    log.debug('response to INFORM sent')
                }
            } catch (MessageException ex) {
                getExceptionHandler().handleException(ex)
            }
        }
        processPDU(pdu, event)
    } else {
        log.debug('Received invalid trap PDU')
    }
}

void processPDU(PDU pdu, CommandResponderEvent event) {
    Exchange exchange = createExchange(pdu, event)
    try {
        getProcessor().process(exchange)
    } catch (Exception e) {
        exchange.setException(e)
    }
    if (exchange.getException() != null) {
        getExceptionHandler().handleException(exchange.getException())
    }
    releaseExchange(exchange, false)
}

/**
 * creates an exchange for the given message
 *
 * @param  pdu   the pdu
 * @param  event a snmp4j CommandResponderEvent
 * @return       an exchange
 */
Exchange createExchange(PDU pdu, CommandResponderEvent event) {
    Exchange exchange = createExchange(false)
    exchange.setIn(new SnmpMessage(getEndpoint().getCamelContext(), pdu, event))
    return exchange
}

}

That means most likely that SNMP engine IDs are not unique in your environment, which is a strong requirement by the SNMPv3 standard!

This code is dangerous / an error, because after the first restart of this SNMPv3 entity the peer entity will have a different time notion than this entity and any >= auth level communication will and has to fail until the time data of the peer entity has been (manually) reset - by a restart, for example.

Instead store engineBootCounter persistently using the EngineBootsCounterFile (SNMP4J 3.8.2)

The engineIDs are unique.

it is only set if localEngineName is available, can we set localEngineName==null and try ?

No, you need to properly set engine ID and engine boots counter on each startup of the engine. That does not seem to be the case.
If you are sure, that engine IDs are unique (I cannot see that from the code and doubt that the code that you posted will ensure that), then the problem is caused by the wrongly set engine boots counter. Please check the description of the engineBoots object:

snmpEngineBoots OBJECT-TYPE
        SYNTAX  INTEGER (1..2147483647)
        MAX-ACCESS read-only
        STATUS  current
        DESCRIPTION
                "The number of times that the SNMP engine has
                (re-)initialized itself since snmpEngineID
                was last configured."
        -- 1.3.6.1.6.3.10.2.1.2
        ::= { snmpEngine 2 }