NotificationOriginatorImpl throws java.net.BindException

I am trying to run the sampleAgent that is shipped with Agent API. I am starting the process “-c udp:10.89.234.198/8000” as parameters. i am able to start the process but i see the following exception are coming when it tries sending a notification.
from the logs and code i see that it is trying to send the notification to “127.0.0.1/162”. i dont have any application runnign on that port and i dont see any configuration to customize this so thta i can send notifications to my custom ip addres. please help

exception is:

Sending message to 127.0.0.1/162 with length 71: 30:45:02:01:01:04:06:70:75:62:6c:69:63:a6:38:02:04:50:16:ab:c0:02:01:00:02:01:00:30:2a:30:0f:06:08:2b:06:01:02:01:01:03:00:43:03:00:9e:40:30:17:06:0a:2b:06:01:06:03:01:01:04:01:00:06:09:2b:06:01:06:03:01:01:05:05
java.net.BindException: Cannot assign requested address: Datagram send failed
VACM access requested for context=, securityName=public, securityModel=2, securityLevel=1, viewType=0, OID=1.3.6.1.6.3.1.1.5.5
Found group name ‘v1v2cgroup’ for secName ‘public’ and secModel 2
Got views [DefaultMOMutableRow2PC[index=10.118.49.118.50.99.103.114.111.117.112.0.1.1,values=[1, unrestrictedReadView, unrestrictedWriteView, unrestrictedNotifyView, 3, 1], DefaultMOMutableRow2PC[index=10.118.49.118.50.99.103.114.111.117.112.0.2.1,values=[1, unrestrictedReadView, unrestrictedWriteView, unrestrictedNotifyView, 3, 1]] for group name ‘v1v2cgroup’
Matching against access entry DefaultMOMutableRow2PC[index=10.118.49.118.50.99.103.114.111.117.112.0.1.1,values=[1, unrestrictedReadView, unrestrictedWriteView, unrestrictedNotifyView, 3, 1] with exactContextMatch=true, prefixMatch=false, matchSecModel=false and matchSecLevel=true
Matching against access entry DefaultMOMutableRow2PC[index=10.118.49.118.50.99.103.114.111.117.112.0.2.1,values=[1, unrestrictedReadView, unrestrictedWriteView, unrestrictedNotifyView, 3, 1] with exactContextMatch=true, prefixMatch=false, matchSecModel=true and matchSecLevel=true
Matching view found for group name ‘v1v2cgroup’ is ‘unrestrictedNotifyView’
Access allowed for view ‘unrestrictedNotifyView’ by subtree 1.3.6 for OID 1.3.6.1.6.3.1.1.5.5
Sending message to 127.0.0.1/162 with length 71: 30:45:02:01:01:04:06:70:75:62:6c:69:63:a7:38:02:04:50:16:ab:c1:02:01:00:02:01:00:30:2a:30:0f:06:08:2b:06:01:02:01:01:03:00:43:03:00:9e:41:30:17:06:0a:2b:06:01:06:03:01:01:04:01:00:06:09:2b:06:01:06:03:01:01:05:05
VACM access requested for context=, securityName=SHA256DES, securityModel=3, securityLevel=3, viewType=0, OID=1.3.6.1.6.3.1.1.5.5
Found group name ‘v3group’ for secName ‘SHA256DES’ and secModel 3
at java.net.DualStackPlainDatagramSocketImpl.socketSend(Native Method)
at java.net.DualStackPlainDatagramSocketImpl.send(Unknown Source)
at java.net.DatagramSocket.send(Unknown Source)
at org.snmp4j.transport.DefaultUdpTransportMapping.sendMessage(DefaultUdpTransportMapping.java:117)
at org.snmp4j.transport.UdpTransportMapping.sendMessage(UdpTransportMapping.java:1)
at org.snmp4j.MessageDispatcherImpl.sendMessage(MessageDispatcherImpl.java:203)
at org.snmp4j.MessageDispatcherImpl.sendPdu(MessageDispatcherImpl.java:522)
at org.snmp4j.Snmp.sendMessage(Snmp.java:1088)
at org.snmp4j.Snmp.send(Snmp.java:981)
at org.snmp4j.Snmp.send(Snmp.java:961)
at org.snmp4j.Snmp.send(Snmp.java:926)
at org.snmp4j.agent.mo.snmp.NotificationOriginatorImpl.sendNotification(NotificationOriginatorImpl.java:270)
at org.snmp4j.agent.mo.snmp.NotificationOriginatorImpl.notify(NotificationOriginatorImpl.java:376)
at org.snmp4j.agent.mo.snmp.NotificationOriginatorImpl.notify(NotificationOriginatorImpl.java:140)
at org.snmp4j.agent.NotificationTask.run(NotificationTask.java:68)
at org.snmp4j.util.ThreadPool$TaskManager.run(ThreadPool.java:312)
Failed to send notification: Cannot assign requested address: Datagram send failed

The exception is not caused by the target address. Instead it is the UDP port 8000 which is already used by another process on your system. With UDP a wrong/used target port will never return an error.

You can specify the target addresses in the SNMP-TARGET-MIB in conjunction with the SNMP-NOTIFICATION-MIB.

Hi,
" Instead it is the UDP port 8000 which is already used by another process on your system" - i am confused. 800 is the port where my snmp agent is listening for incoming requests. (i started my application with “-c udp:10.89.234.198/8000”)
when i debug the code i understand that it is trying to send a a packet to “127.0.0.1"162” (not sure from where did it get this target, i dont see any entry with that address in “SampleAgentConfig.properties” as well) using the 8000 port where my Agent is listening for incoming requests. now why it is again trying to bind to 8000 which already in use with itself?
code snippet:
DefaultUdpTransportMapping.sendMessage{
//
if (logger.isDebugEnabled()) {
logger.debug("Sending message to “+targetAddress+” with length “+
message.length+”: "+
new OctetString(message).toHexString());
}
DatagramSocket s = ensureSocket();
s.send(new DatagramPacket(message, message.length, targetSocketAddress));
}

The standard/sample agent will not bind the agent port twice.
Maybe you need to debug your setup?

Hi,
I debugged the code (the sample agent as is without any modifications). Here are my observations,

  • i started the agent with the command line args as "-c udp:hostname.com/8000” so that my sample agent starts listening for SNMP requests on UDP port 8000.

  • when the application is started i see the agent is trying to send coldStart notification (coldStart - 1.3.6.1.6.3.1.1.5.1).
    // code snippet from backtrace
    MessageDispatcherImpl::sendPdu()
    if (transport == null) {
    transport = getTransport(transportAddress);
    }

  • Here it is trying to get the registered transport mappping for UDP which is DefaultUdpTransportMapping.
    using this mapping it is trying to Datagram socket with the the same port 8000 which is already bound to listen the incoming SNMP requests.
    code snippet:
    DefaultUdpTransportMapping::sendMessage()
    {
    //
    DatagramSocket s = ensureSocket(); // here it is creating DatagramSocket (to send the notification to the target ip address) with the same 8000 on which my agent is running.
    s.send(new DatagramPacket(message, message.length, targetSocketAddress));
    //
    }

as the port is already bound to process the incoming SNMP GET/POST requests, it is not able to bind again and getting “java.net.BindException”.

StackTrace:
for MessageDispatcherImpl.getTransport:

Thread [main] (Suspended (breakpoint at line 227 in MessageDispatcherImpl))
owns: Snmp$SyncResponseListener (id=42)
MessageDispatcherImpl.getTransport(Address) line: 227
MessageDispatcherImpl.sendPdu(TransportMapping, Target, PDU, boolean, PduHandleCallback) line: 449
Snmp.sendMessage(PDU, Target, TransportMapping, PduHandleCallback) line: 1088
Snmp.send(PDU, Target, TransportMapping, int) line: 981
Snmp.send(PDU, Target, TransportMapping) line: 961
Snmp.send(PDU, Target) line: 926
NotificationOriginatorImpl.sendNotification(Address, Integer32, Integer32, SnmpTargetMIB$SnmpTargetAddrEntryRow, MOTableRow, OctetString, OID, TimeTicks, VariableBinding[], int, long) line: 270
NotificationOriginatorImpl.notify(OctetString, OID, TimeTicks, VariableBinding[]) line: 376
NotificationOriginatorImpl.notify(OctetString, OID, VariableBinding[]) line: 140
AgentConfigManager.fireLaunchNotifications() line: 400
AgentConfigManager.launch() line: 392
AgentConfigManager.run() line: 248
NetegrityAgent.run() line: 181
NetegrityAgent.main(String[]) line: 346

for sendMessage
com.netegrity.snmp.example.NetegrityAgent at localhost:52777
Thread [main] (Suspended (breakpoint at line 117 in DefaultUdpTransportMapping))
owns: Snmp$SyncResponseListener (id=42)
DefaultUdpTransportMapping.sendMessage(UdpAddress, byte[], TransportStateReference) line: 117
DefaultUdpTransportMapping(UdpTransportMapping).sendMessage(Address, byte[], TransportStateReference) line: 1
MessageDispatcherImpl.sendMessage(TransportMapping, Address, byte[], TransportStateReference) line: 203
MessageDispatcherImpl.sendPdu(TransportMapping, Target, PDU, boolean, PduHandleCallback) line: 522
Snmp.sendMessage(PDU, Target, TransportMapping, PduHandleCallback) line: 1088
Snmp.send(PDU, Target, TransportMapping, int) line: 981
Snmp.send(PDU, Target, TransportMapping) line: 961
Snmp.send(PDU, Target) line: 926
NotificationOriginatorImpl.sendNotification(Address, Integer32, Integer32, SnmpTargetMIB$SnmpTargetAddrEntryRow, MOTableRow, OctetString, OID, TimeTicks, VariableBinding[], int, long) line: 270
NotificationOriginatorImpl.notify(OctetString, OID, TimeTicks, VariableBinding[]) line: 376
NotificationOriginatorImpl.notify(OctetString, OID, VariableBinding[]) line: 140
AgentConfigManager.fireLaunchNotifications() line: 400
AgentConfigManager.launch() line: 392
AgentConfigManager.run() line: 248
NetegrityAgent.run() line: 181
NetegrityAgent.main(String[]) line: 346

For bind exception:
java.net.BindException: Cannot assign requested address: Datagram send failed
at java.net.DualStackPlainDatagramSocketImpl.socketSend(Native Method)
at java.net.DualStackPlainDatagramSocketImpl.send(Unknown Source)
at java.net.DatagramSocket.send(Unknown Source)
at org.snmp4j.transport.DefaultUdpTransportMapping.sendMessage(DefaultUdpTransportMapping.java:117)
at org.snmp4j.transport.UdpTransportMapping.sendMessage(UdpTransportMapping.java:1)
at org.snmp4j.MessageDispatcherImpl.sendMessage(MessageDispatcherImpl.java:203)
at org.snmp4j.MessageDispatcherImpl.sendPdu(MessageDispatcherImpl.java:522)
at org.snmp4j.Snmp.sendMessage(Snmp.java:1088)
at org.snmp4j.Snmp.send(Snmp.java:968)
at org.snmp4j.Snmp.send(Snmp.java:961)
at org.snmp4j.Snmp.send(Snmp.java:926)
at org.snmp4j.agent.mo.snmp.NotificationOriginatorImpl.sendNotification(NotificationOriginatorImpl.java:270)
at org.snmp4j.agent.mo.snmp.NotificationOriginatorImpl.notify(NotificationOriginatorImpl.java:376)
at org.snmp4j.agent.mo.snmp.NotificationOriginatorImpl.notify(NotificationOriginatorImpl.java:140)
at org.snmp4j.agent.AgentConfigManager.fireLaunchNotifications(AgentConfigManager.java:400)
at org.snmp4j.agent.AgentConfigManager.launch(AgentConfigManager.java:392)
at org.snmp4j.agent.AgentConfigManager.run(AgentConfigManager.java:248)
at com.netegrity.snmp.example.NetegrityAgent.run(NetegrityAgent.java:181)
at com.netegrity.snmp.example.NetegrityAgent.main(NetegrityAgent.java:346)
Failed to send notification: Cannot assign requested address: Datagram send failed

can some one please clarify the following?
1.do we need two different ports to start the agent. one for listening the incoming requests and another for sending notifications?
2. in that case do we need to run the application with “-c udp:hostname.com/8000 udp:hostname.com/8001” some thing like this? but from the code i see SNMP4J isalways taking the first one in the transportMappings. (that is why the agent is always trying to bind to the same port to send notifications on which the agent is started)
3. am i missing any configuration?

  1. No, the transport mapping for the incoming requests can be used to send notifications too (this is true for UDP and TCP. For TLS and DTLS that would not be true in all cases. That is why in SNMP4J 3.6.x (3.7.0 is the current release) an additional transport mapping type TransportType.sender
  2. For sending notifications, the first transport mapping registered for the required address class (in your case UDP) is selected.
  3. The trap destinations used by the agent are defined in the agent’s properties files. But the values are encoded in OCTET STRINGS according to the SNMP-TARGET-MIB specification.

The port assignment problem is more likely caused because your command line is wrong. The “-c” option has no value, instead the listen address you specified is taken is its value to store persistent data. Thus, you do not specify and listen port and the defaults apply.

Hi,
“The port assignment problem is more likely caused because your command line is wrong” - sorry it was a copy paste problem. Actually , i run the application with “-c SampleAgent.cfg udp:10.89.234.198/8000”. and i can see the port 8000 is opened also.

“For sending notifications, the first transport mapping registered for the required address class (in your case UDP) is selected” - this is what causing exception in my case. so to send the coldStart notification, as shown and explained in the back trace above, library is trying to create a Datagram Socket with the same port (because there is only one udp transport mapping which is given in the command line) and so it is throwing exception as the port is already bound.

MessageDispatcherImpl.getTransport(Address) line: 227
MessageDispatcherImpl.sendPdu(TransportMapping, Target, PDU, boolean, PduHandleCallback) line: 449
this is where library is trying to get the default UDP transport mapping which is (UDP on port 8000 from command line)

DefaultUdpTransportMapping.sendMessage(UdpAddress, byte[], TransportStateReference) line: 116
this is where it is creating Datagram socket with port 8000 again (using the above mapping).

please let me know if i am missing anything in explaining the issue or if you want more information on my application configuration.

Ok, again: the SNMP4J-Agent code is designed to use only a single transport mapping per address class. Thus it will not create a second instance for the same address class.

Thus, something goes wrong in your configuration. (I know that this isn’t new to you)

Best regards
Frank