[SNMP4J] Counting Invalid Traps

Elise Atkins elise.atkins at tavve.com
Mon Oct 26 14:28:55 CET 2009


I have used SNMP4J for several years and have been very satisfied. 
Recently I did some testing to see what happens when invalid V1 traps 
and snmp requests were received by the snmp4j code. A CounterListner was 
added to the MessageDispatcherImpl and the number of incoming 
traps/requests were accurately counted but the number of invalid traps 
was not. The large majority of traps were silently discarded. After 
looking at the following code snippet from MessageDispatcherImpl and the 
MPv1.java code I concluded that when the MPv1 encountered an error it 
threw an exception that was caught by the catch block near the end of 
the snippet. The packet is then silently discarded unless the 
Snmp4JSettings.forwardRuntimeExceptions is true and the 
TransportMapping  class catches and counts the exception.

I think that a better solution would be to add the following lines the 
catch block:
        CounterEvent event = new CounterEvent(this,
                                              
SnmpConstants.snmpInvalidMsgs);
        fireIncrementCounter(event);

The packet would be then counted as invalid. I did set the 
forwardRuntimeExceptions to true and was able to get a count of the 
invalid packets and all seemed ok until a little later. I also use 
AgentXSubagent to connect to the snmpd service. When that service was 
not running or misconfigured and the subagent could not connect, a 
socket was orphaned and eventually things stopped working because there 
were too many sockets opened. I fixed that by calling close and 
disconnect on the subagent when the connect method failed. But I am now 
worried that having the forwardRuntimeExceptions set to true will cause 
additional problems down the line.

  public void processMessage(TransportMapping sourceTransport,
                             Address incomingAddress,
                             BERInputStream wholeMessage) {
    fireIncrementCounter(new CounterEvent(this, SnmpConstants.snmpInPkts));
    if (!wholeMessage.markSupported()) {
      String txt = "Message stream must support marks";
      logger.error(txt);
      throw new IllegalArgumentException(txt);
    }
    try {
      wholeMessage.mark(16);
      BER.MutableByte type = new BER.MutableByte();
      // decode header but do not check length here, because we do only 
decode
      // the first 16 bytes.
      BER.decodeHeader(wholeMessage, type, false);
      if (type.getValue() != BER.SEQUENCE) {
        logger.error("ASN.1 parse error (message is not a sequence)");
        CounterEvent event = new CounterEvent(this,
                                              
SnmpConstants.snmpInASNParseErrs);
        fireIncrementCounter(event);
      }
      Integer32 version = new Integer32();
      version.decodeBER(wholeMessage);
      MessageProcessingModel mp = 
getMessageProcessingModel(version.getValue());
      if (mp == null) {
        logger.warn("SNMP version "+version+" is not supported");
        CounterEvent event = new CounterEvent(this,
                                              
SnmpConstants.snmpInBadVersions);
        fireIncrementCounter(event);
      }
      else {
        // reset it
        wholeMessage.reset();
        // dispatch it
        dispatchMessage(sourceTransport, mp, incomingAddress, wholeMessage);
      }
    }
    catch (Exception ex) {
      logger.error(ex);
      if (logger.isDebugEnabled()) {
        ex.printStackTrace();
      }
      if (SNMP4JSettings.isFowardRuntimeExceptions()) {
        throw new RuntimeException(ex);
      }
    }
    catch (OutOfMemoryError oex) {
      logger.error(oex);
      if (SNMP4JSettings.isFowardRuntimeExceptions()) {
        throw oex;
      }
    }
  }

Sincerely,
Elise Atkins

-- 
ZoneRanger "Management Through Firewalls" <http://www.tavve.com/?leadlander>




More information about the SNMP4J mailing list