In the SNMP protocol adaptor, the task of translating an SnmpMessage object into an SnmpPduPacket object is delegated to an object which implements the SnmpPduFactory interface. This interface defines two methods, one for decoding messages into PDUs and one for encoding PDUs into messages:
decodePdu takes an SnmpMessage and should return a decoded SnmpPduPacket object; if it returns null or raises an exception, the incoming message is assumed to have failed the security check
encodePdu takes an SnmpPduPacket and should return an encoded SnmpMessage to send
In our example, the SnmpPduFactoryImpl class implements the decodePdu method to reject messages if they originate from certain hosts. The list of hosts to refuse is passed to the class constructor at instantiation. The encodePdu method only does the standard BER encoding of outgoing messages.
public class SnmpPduFactoryImpl implements SnmpPduFactory { private String[] hostNames; // HostNames is the array of the host names whose requests will be // refused by the agent public SnmpPduFactoryImpl(String[] hostNames) { this.hostNames = hostNames; } public SnmpPduPacket decodePdu(SnmpMessage msg) throws SnmpStatusException { // Get the sender's hostname String from = msg.address.getHostName(); for (int i = 0; i < hostNames.length; i++) { if (from.equals(hostNames[i])) { java.lang.System.out.println("Pdu rejected from " + from); return null; } } // If the host is accepted, we return the standard BER decoding return msg.decodePdu(); } // No security when sending, just do the standard BER encoding public SnmpMessage encodePdu(SnmpPduPacket pdu, int maxPktSize) throws SnmpStatusException, SnmpTooBigException { SnmpMessage result = new SnmpMessage(); result.encodePdu(pdu, maxPktSize); return result; } } |
Beyond our simple check of the sender's hostname, our example relies on the standard BER encoding and decoding of the SnmpMessage class. Even if you choose to implement encryption, it can still be implemented on top of the standard BER for simplicity. In this case, you only need to encrypt the message's byte array after the standard encoding and decrypt it before the standard decoding.
When you implement the encodePdu, you must ensure that it also handles trap PDUs, by encoding them as they will be expected by the manager application (see "SNMP Manager Security"). For example, trap messages are decoded separately from response messages in applications based on the SNMP manager API.