Creating a simple trap receiver using snmp4j is not calling the processPdu method

This is a new fact, you did not mention so far: INFORM request is not a NOTIFICATION.
For INFORM, the command responder ( in this case the Java application) is authoritative.

This is correct. On the „out-of-time-window“ report, the command sender should follow the engine time discovery method to actually get the time and engine boots for the authoritative engine ID. The msgFlags field is 0 which indicates a trap (or response) but you wrote above to send an INFORM request. That does not make any sense.
Please be consistent when asking and trying out things, then we might be able to help.

Please note that the message in the image was sent with securityLevel noAuthNoPriv (field msgAuthenticationParameters is empty). In this case it does not make any sense to fill the engineBoots and engineTime fields, as the receiver cannot trust them.

@jkatz /@AGENTPP
sorry for not mentioning about the progress, Yes i started with trap and it works fine with the notification receiver as Java. I have started to validate the inform request and this where i was facing the problem.

So the inform request sender does try to discover the engine id , engine boot and engine time of the commander responder by firing the get request.

The response of the getrequest (Report) should contain the engineid, engineboot and engine time so that the command sender can synchronize it right? but i am seeing that the engineid, engineboot are blank so the subsequent request are sent with the enginetime and engineboot values as “0” and this fails?


Please advise.

Java Code:
package snmpsimple;
import java.io.IOException;

import org.snmp4j.CommandResponder;
import org.snmp4j.CommandResponderEvent;
import org.snmp4j.MessageDispatcherImpl;
import org.snmp4j.Snmp;
import org.snmp4j.TransportMapping;
import org.snmp4j.log.ConsoleLogAdapter;
import org.snmp4j.log.ConsoleLogFactory;
import org.snmp4j.log.LogFactory;
import org.snmp4j.mp.MPv3;
import org.snmp4j.security.AuthHMAC192SHA256;
import org.snmp4j.security.AuthMD5;
import org.snmp4j.security.AuthSHA;
import org.snmp4j.security.AuthenticationProtocol;
import org.snmp4j.security.PrivAES128;
import org.snmp4j.security.PrivDES;
import org.snmp4j.security.PrivacyProtocol;
import org.snmp4j.security.SecurityProtocols;
import org.snmp4j.security.USM;
import org.snmp4j.security.UsmUser;
import org.snmp4j.smi.Address;
import org.snmp4j.smi.GenericAddress;
import org.snmp4j.smi.OctetString;
import org.snmp4j.smi.TcpAddress;
import org.snmp4j.smi.UdpAddress;
import org.snmp4j.transport.DefaultTcpTransportMapping;
import org.snmp4j.transport.DefaultUdpTransportMapping;
import org.snmp4j.util.MultiThreadedMessageDispatcher;
import org.snmp4j.util.ThreadPool;

public class SnmpTrapReceiver {

static {
    LogFactory.setLogFactory(new ConsoleLogFactory());
    ConsoleLogAdapter.setDebugEnabled(true);
}

// static {
// LogFactory.setLogFactory(new LogFactory());
// LogFactory.getLogFactory().getRootLogger().setLogLevel(LogLevel.ALL);
// }

private static final String SNMP_PORT = System.getenv("SNMP_PORT");
private static final String SNMP_AUTH_PROTOCOL = System.getenv("SNMP_AUTH_PROTOCOL");
private static final String SNMP_PRIVACY_PROTOCOL = System.getenv("SNMP_PRIVACY_PROTOCOL");
private static final String SNMP_AUTH_PHRASE = System.getenv("SNMP_AUTH_PHRASE");
private static final String SNMP_PRIVACY_PHRASE = System.getenv("SNMP_PRIVACY_PHRASE");
private static final String SNMP_PROTOCOL = System.getenv("SNMP_PROTOCOL");
private static final String SNMP_USER=System.getenv("SNMP_USER");
private static final String NOTIFICATION_PORT = System.getenv("NOTIFICATION_PORT");
//private static final String SNMP_ENGINE_ID=System.getenv("SNMP_ENGINE_ID");
//private static final String LOCAL_ENGINE_ID="80:00:1f:88:80:e7:65:f3:78:82:63:bd:67:00:00:00:00";
private static final String LOCAL_ENGINE_ID=System.getenv("SNMP_ENGINE_ID");

private static final String INFORM_LOCAL_ENGINE_ID="80:00:1f:88:80:e7:65:f3:78:82:63:bd:57:00:00:00:00";


public static void main(String[] args) {
    try {
    	
    	System.out.println(SNMP_PORT);
    	System.out.println(SNMP_AUTH_PROTOCOL);
    	System.out.println("Trap user:"+SNMP_USER);
    	System.out.println("Inform user:"+"informuser");
    	System.out.println("Trap engineid:"+LOCAL_ENGINE_ID);
    	System.out.println("Inform engineid:"+INFORM_LOCAL_ENGINE_ID);        	
    	System.out.println("::"+SNMP_AUTH_PHRASE+"::");
    	System.out.println("::"+SNMP_PRIVACY_PHRASE+"::");
    	
    	//MPv3.createLocalEngineID()
    	Address listenAddress, notificationAddress;
    	ThreadPool threadPool = ThreadPool.create("Trap", 2);
    	MultiThreadedMessageDispatcher dispatcher =
    	        new MultiThreadedMessageDispatcher(threadPool,
    	                                           new MessageDispatcherImpl());
        // Create transport mapping
        TransportMapping<?> transport;
        if ("TCP".equalsIgnoreCase(SNMP_PROTOCOL)) {
        	listenAddress = GenericAddress.parse("tcp:0.0.0.0/"+SNMP_PORT);
        	notificationAddress = GenericAddress.parse("tcp:0.0.0.0/"+NOTIFICATION_PORT);
            transport = new DefaultTcpTransportMapping((TcpAddress)listenAddress);
        } else {
        	listenAddress = GenericAddress.parse("udp:0.0.0.0/"+SNMP_PORT);
            transport = new DefaultUdpTransportMapping((UdpAddress)listenAddress);
            notificationAddress = GenericAddress.parse("udp:0.0.0.0/"+NOTIFICATION_PORT);
        }
        transport.listen();
        
        SecurityProtocols securityProtocols = SecurityProtocols.getInstance();
        securityProtocols.addDefaultProtocols();
        
        AuthenticationProtocol authProtocol = getAuthProtocol(SNMP_AUTH_PROTOCOL);
        PrivacyProtocol privProtocol = getPrivProtocol(SNMP_PRIVACY_PROTOCOL);
        
        System.out.println("auth:"+ new OctetString(SNMP_AUTH_PHRASE).getValue());
        System.out.println("priv:"+ new OctetString(SNMP_PRIVACY_PHRASE).getValue());

        byte[] authLocalKey = securityProtocols.passwordToKey(authProtocol.getID(), new OctetString(SNMP_AUTH_PHRASE), LOCAL_ENGINE_ID.getBytes());
        byte[] privLocalKey = securityProtocols.passwordToKey(authProtocol.getID(), new OctetString(SNMP_PRIVACY_PHRASE), LOCAL_ENGINE_ID.getBytes());
        System.out.println(authLocalKey);
        System.out.println(privLocalKey);
        if (authProtocol != null) {
        	System.out.println(authProtocol);
		    securityProtocols.addAuthenticationProtocol(authProtocol);
		}
		if (privProtocol != null) {
		    securityProtocols.addPrivacyProtocol(privProtocol);
		}
	
        UsmUser  user = new UsmUser (new OctetString(SNMP_USER),
                authProtocol.getID(),
                new OctetString(SNMP_AUTH_PHRASE),
                privProtocol.getID(),
                new OctetString(SNMP_PRIVACY_PHRASE));
        
        System.out.println("USM user:"+user.toString());
        
        
        USM usm = new USM(securityProtocols,
        		OctetString.fromHexString(INFORM_LOCAL_ENGINE_ID), 0);
        
       
        usm.setEngineDiscoveryEnabled(true);
        usm.addUser(new OctetString(SNMP_USER),OctetString.fromHexString(LOCAL_ENGINE_ID),user);
        
        UsmUser  user1 = new UsmUser (new OctetString("informuser"),
                authProtocol.getID(),
                new OctetString(SNMP_AUTH_PHRASE),
                privProtocol.getID(),
                new OctetString(SNMP_PRIVACY_PHRASE));
        
        System.out.println("USM user:"+user1.toString());
        
        usm.addUser(user1);
        
       
        //SecurityModels.getInstance().addSecurityModel(usm);

        //snmp.setLocalEngine(engineID, 0, 0);
        MPv3 mpv3=  new MPv3(usm);
        
        //mpv3.getSecurityModels().addSecurityModel(usm);
        dispatcher.addMessageProcessingModel(mpv3);
      
        // Create SNMP object
        Snmp snmp = new Snmp(dispatcher,transport); 
        
       
        //snmp.addCommandResponder(new TrapListener());
        snmp.addNotificationListener(notificationAddress, new TrapListener());
        snmp.addCommandResponder(new CommandListener());
        snmp.discoverAuthoritativeEngineID(listenAddress, 5000);

        snmp.listen();
        // Set up security protocols
          System.out.println("Listening for SNMP traps on port " + SNMP_PORT + " using " + SNMP_PROTOCOL);

        // Keep the application running
        while (true) {
            Thread.sleep(1000);
        }
    } catch (IOException | InterruptedException e) {
        e.printStackTrace();
    }
}

private static AuthenticationProtocol getAuthProtocol(String protocol) {
    switch (protocol.toUpperCase()) {
        case "SHA":
            return new AuthSHA();
        case "MD5":
            return new AuthMD5();
        case "SHA256":
        	return new AuthHMAC192SHA256();
     
        default:
            System.err.println("Unsupported authentication protocol: " + protocol);
            return null;
    }
}

private static PrivacyProtocol getPrivProtocol(String protocol) {
    switch (protocol.toUpperCase()) {
        case "AES":
            return new PrivAES128();
        case "DES":
            return new PrivDES();
        default:
            System.err.println("Unsupported privacy protocol: " + protocol);
            return null;
    }
}


static class TrapListener implements CommandResponder {
	@Override
	public void processPdu(CommandResponderEvent arg0) {
		System.out.println("Received SNMP Trap:" +arg0.getPDU());
		
	}
}

static class CommandListener implements CommandResponder {
	@Override
	public void processPdu(CommandResponderEvent arg0) {
		System.out.println("Received SNMP Trap:" +arg0.getPDU());
		
	}
}

}

As written before, the INFORM sender needs to discover the engine Time with the correct authoritative engine ID.
See RFC 3414 section 3.1 §5:

  1. The securityEngineID is encoded as an OCTET STRING into the
    msgAuthoritativeEngineID field of the securityParameters. Note
    that an empty (zero length) securityEngineID is OK for a Request
    message, because that will cause the remote (authoritative) SNMP
    engine to return a Report PDU with the proper securityEngineID
    included in the msgAuthoritativeEngineID in the securityParameters
    of that returned Report PDU.

You should use/evaluate SNMP4J 3.9.2 if you want to test SNMP4J. Using the very old 2.x branch will not help you.

This report is sent with security level noAuthNoPriv and therefore engineBoots and engineTime are set to zero. But as the engineID is set, the command generator can then send a second request with securityLevel authNoPriv or authPriv (and zero values for engineBoots and engineTime). This request will trigger a notInTimeWindow report (with the same securityLevel as the request) that will have the correct values for engineBoots and engineTime.

Thanks you so much @AGENTPP and @jacket for your help. I really appreciate for helping me …