KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > snmp4j > agent > mo > snmp > NotificationOriginatorImpl


1 /*_############################################################################
2   _##
3   _## SNMP4J-Agent - NotificationOriginatorImpl.java
4   _##
5   _## Copyright (C) 2005-2007 Frank Fock (SNMP4J.org)
6   _##
7   _## Licensed under the Apache License, Version 2.0 (the "License");
8   _## you may not use this file except in compliance with the License.
9   _## You may obtain a copy of the License at
10   _##
11   _## http://www.apache.org/licenses/LICENSE-2.0
12   _##
13   _## Unless required by applicable law or agreed to in writing, software
14   _## distributed under the License is distributed on an "AS IS" BASIS,
15   _## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   _## See the License for the specific language governing permissions and
17   _## limitations under the License.
18   _##
19   _##########################################################################*/

20
21
22 package org.snmp4j.agent.mo.snmp;
23
24 import java.util.*;
25
26 import org.snmp4j.*;
27 import org.snmp4j.agent.*;
28 import org.snmp4j.agent.mo.*;
29 import org.snmp4j.agent.security.*;
30 import org.snmp4j.event.*;
31 import org.snmp4j.smi.*;
32 import org.snmp4j.log.LogFactory;
33 import org.snmp4j.log.LogAdapter;
34 import org.snmp4j.mp.MessageProcessingModel;
35 import org.snmp4j.agent.mo.snmp.SnmpTargetMIB.SnmpTargetAddrEntryRow;
36 import java.io.IOException JavaDoc;
37 import org.snmp4j.mp.SnmpConstants;
38 import org.snmp4j.agent.mo.snmp.SysUpTime;
39 import java.net.InetAddress JavaDoc;
40
41 /**
42  * The <code>NotificationOriginatorImpl</code> class implements a notification
43  * originator application for SNMP4J.
44  * <p>
45  * See also RFC 3411 for a description of notification originators.
46  * </p>
47  * @author Frank Fock
48  * @version 1.0
49  */

50 public class NotificationOriginatorImpl implements NotificationOriginator {
51
52   private static final LogAdapter logger =
53       LogFactory.getLogger(NotificationOriginatorImpl.class);
54
55   private Snmp session;
56   private VACM vacm;
57   private SnmpTargetMIB targetMIB;
58   private SnmpNotificationMIB notificationMIB;
59   private SnmpCommunityMIB communityMIB;
60   private SysUpTime sysUpTime;
61
62   /**
63    * Creates a notification originator.
64    * @param session
65    * the Snmp instance to be used to send the notifications/informs.
66    * @param vacm
67    * the VACM to be used to check access for notifications.
68    * @param sysUpTime
69    * the sysUpTime instance to be used to determine sysUpTime.0 when
70    * sending notifications without specifically specified sysUpTime.
71    * @param targetMIB
72    * the SnmpTargetMIB containing notification target information.
73    * @param notificationMIB SnmpNotificationMIB
74    */

75   public NotificationOriginatorImpl(Snmp session,
76                                     VACM vacm,
77                                     SysUpTime sysUpTime,
78                                     SnmpTargetMIB targetMIB,
79                                     SnmpNotificationMIB notificationMIB) {
80     this.session = session;
81     this.sysUpTime = sysUpTime;
82     this.vacm = vacm;
83     this.targetMIB = targetMIB;
84     this.notificationMIB = notificationMIB;
85   }
86
87   /**
88    * Creates a notification originator.
89    * @param session
90    * the Snmp instance to be used to send the notifications/informs.
91    * @param vacm
92    * the VACM to be used to check access for notifications.
93    * @param sysUpTime
94    * the sysUpTime instance to be used to determine sysUpTime.0 when
95    * sending notifications without specifically specified sysUpTime.
96    * @param targetMIB
97    * the SnmpTargetMIB containing notification target information.
98    * @param notificationMIB
99    * the SnmpNotificationMIB containing notification filtering information.
100    * @param communityMIB
101    * the community MIB for coexistence information.
102    */

103   public NotificationOriginatorImpl(Snmp session,
104                                     VACM vacm,
105                                     SysUpTime sysUpTime,
106                                     SnmpTargetMIB targetMIB,
107                                     SnmpNotificationMIB notificationMIB,
108                                     SnmpCommunityMIB communityMIB) {
109     this(session, vacm, sysUpTime, targetMIB, notificationMIB);
110     this.communityMIB = communityMIB;
111   }
112
113   /**
114    * Sends notifications (traps) to all appropriate notification targets.
115    *
116    * @param context the context name of the context on whose behalf this
117    * notification has been generated.
118    * @param notificationID the object ID that uniquely identifies this
119    * notification. For SNMPv1 traps, the notification ID has to be build
120    * using the rules provided by RFC 2576.
121    * @param vbs an array of <code>VariableBinding</code> instances
122    * representing the payload of the notification.
123    * @return an array of ResponseEvent instances. Since the
124    * <code>NotificationOriginator</code> determines on behalf of the
125    * SNMP-NOTIFICTON-MIB contents whether a notification is sent as
126    * trap/notification or as inform request, the returned array contains an
127    * element for each addressed target, but only a response PDU for inform
128    * targets.
129    */

130   public Object JavaDoc notify(OctetString context, OID notificationID,
131                        VariableBinding[] vbs) {
132     return notify(context, notificationID, null, vbs);
133   }
134
135   private ResponseEvent sendNotification(MOTableRow addr, MOTableRow paramsRow,
136                                          OctetString context,
137                                          OID notificationID,
138                                          TimeTicks sysUpTime,
139                                          VariableBinding[] vbs,
140                                          int type) {
141     Integer32 mpModel = (Integer32)
142         paramsRow.getValue(SnmpTargetMIB.idxSnmpTargetParamsMPModel);
143     OctetString secName = (OctetString)
144         paramsRow.getValue(SnmpTargetMIB.idxSnmpTargetParamsSecurityName);
145     Integer32 secLevel = (Integer32)
146         paramsRow.getValue(SnmpTargetMIB.idxSnmpTargetParamsSecurityLevel);
147 // Integer32 secModel = (Integer32)
148
// paramsRow.getValue(SnmpTargetMIB.idxSnmpTargetParamsSecurityModel);
149
OctetString community = secName;
150     if (communityMIB != null) {
151        community = communityMIB.getCommunity(secName, null, context);
152     }
153     Address JavaDoc address = ((SnmpTargetAddrEntryRow)addr).getAddress();
154     Target t;
155     PDU pdu;
156     switch (mpModel.getValue()) {
157       case MessageProcessingModel.MPv1: {
158         t = new CommunityTarget(address, community);
159         PDUv1 trap = new PDUv1();
160         pdu = trap;
161         if (sysUpTime != null) {
162           trap.setTimestamp(sysUpTime.getValue());
163         }
164         else {
165           trap.setTimestamp(this.sysUpTime.get().getValue());
166         }
167         int genericID = SnmpConstants.getGenericTrapID(notificationID);
168         if (genericID < 0) {
169           trap.setGenericTrap(6);
170           if ((notificationID.size() > 2) &&
171               (notificationID.get(notificationID.size() - 2) == 0)) {
172             OID enterprise =
173                 new OID(notificationID.getValue(), 0,
174                         notificationID.size() - 2);
175             trap.setEnterprise(enterprise);
176           }
177           else {
178             OID enterprise =
179                 new OID(notificationID.getValue(), 0,
180                         notificationID.size() - 1);
181             trap.setEnterprise(enterprise);
182           }
183           trap.setSpecificTrap(notificationID.last());
184         }
185         else {
186           trap.setGenericTrap(genericID);
187           trap.setEnterprise(new OID(new int[] { 0,0 }));
188         }
189         TransportMapping tm =
190             session.getMessageDispatcher().getTransport(address);
191         if ((tm != null) && (tm.getListenAddress() instanceof IpAddress)) {
192           InetAddress JavaDoc localAddress =
193               ((IpAddress)tm.getListenAddress()).getInetAddress();
194           trap.setAgentAddress(new IpAddress(localAddress));
195         }
196         break;
197       }
198       case MessageProcessingModel.MPv2c: {
199         t = new CommunityTarget(address, community);
200         pdu = new PDU();
201         break;
202       }
203       default: {
204         byte[] authEngineID =
205             (type == SnmpNotificationMIB.SnmpNotifyTypeEnum.inform) ?
206             new byte[0] : session.getLocalEngineID();
207         UserTarget ut =
208             new UserTarget(address, secName, authEngineID, secLevel.getValue());
209         t = ut;
210         ScopedPDU scopedPdu = new ScopedPDU();
211         scopedPdu.setContextName(context);
212         pdu = scopedPdu;
213       }
214     }
215     t.setVersion(mpModel.getValue());
216     Integer32 timeout = (Integer32)
217         addr.getValue(SnmpTargetMIB.idxSnmpTargetAddrTimeout);
218     Integer32 retries = (Integer32)
219         addr.getValue(SnmpTargetMIB.idxSnmpTargetAddrRetryCount);
220     t.setTimeout(timeout.getValue() * 10);
221     t.setRetries(retries.getValue());
222     if (mpModel.getValue() != MessageProcessingModel.MPv1) {
223       if (sysUpTime != null) {
224         pdu.add(new VariableBinding(SnmpConstants.sysUpTime, sysUpTime));
225       }
226       else {
227         pdu.add(new VariableBinding(SnmpConstants.sysUpTime,
228                                     this.sysUpTime.get()));
229       }
230       pdu.add(new VariableBinding(SnmpConstants.snmpTrapOID, notificationID));
231     }
232     pdu.addAll(vbs);
233     pdu.setType((type == SnmpNotificationMIB.SnmpNotifyTypeEnum.inform) ?
234                 PDU.INFORM : (mpModel.getValue() == MessageProcessingModel.MPv1)
235                 ? PDU.V1TRAP : PDU.TRAP);
236     try {
237       ResponseEvent response = session.send(pdu, t);
238       logger.info("Sent notification "+pdu+" to "+t);
239       return response;
240     }
241     catch (IOException JavaDoc iox) {
242       logger.error("Failed to send notification: "+iox.getMessage());
243
244     }
245     return null;
246   }
247
248   private boolean isAccessGranted(MOTableRow addr, MOTableRow paramsRow,
249                                   OctetString context,
250                                   OID notificationID,
251                                   VariableBinding[] vbs) {
252     if (!notificationMIB.passesFilter(paramsRow.getIndex(), notificationID, vbs)) {
253       if (logger.isInfoEnabled()) {
254         logger.info("Notification " + notificationID + " did not pass filter " +
255                     paramsRow.getIndex());
256       }
257       return false;
258     }
259 // Integer32 mpModel = (Integer32)
260
// paramsRow.getValue(SnmpTargetMIB.idxSnmpTargetParamsMPModel);
261
OctetString secName = (OctetString)
262         paramsRow.getValue(SnmpTargetMIB.idxSnmpTargetParamsSecurityName);
263     Integer32 secLevel = (Integer32)
264         paramsRow.getValue(SnmpTargetMIB.idxSnmpTargetParamsSecurityLevel);
265     Integer32 secModel = (Integer32)
266         paramsRow.getValue(SnmpTargetMIB.idxSnmpTargetParamsSecurityModel);
267     int status = vacm.isAccessAllowed(context, secName,
268                                       secModel.getValue(), secLevel.getValue(),
269                                       VACM.VIEW_NOTIFY, notificationID);
270     for (int i=0; (status == VACM.VACM_OK) && (i<vbs.length); i++) {
271       status = vacm.isAccessAllowed(context, secName,
272                                     secModel.getValue(), secLevel.getValue(),
273                                     VACM.VIEW_NOTIFY, vbs[i].getOid());
274     }
275     return (status == VACM.VACM_OK);
276   }
277
278   public Object JavaDoc notify(OctetString context, OID notificationID,
279                        TimeTicks sysUpTime, VariableBinding[] vbs) {
280     if (logger.isInfoEnabled()) {
281       logger.info("Notification " + notificationID + " issued with " +
282                   Arrays.asList(vbs));
283     }
284     List responses = new LinkedList();
285     for (Iterator it = notificationMIB.getNotifyTable().getModel().iterator();
286          it.hasNext(); ) {
287       MOTableRow notifyRow = (MOTableRow) it.next();
288       OctetString tag = (OctetString)
289           notifyRow.getValue(SnmpNotificationMIB.idxSnmpNotifyTag);
290       Integer32 type =
291           (Integer32) notifyRow.getValue(SnmpNotificationMIB.idxSnmpNotifyType);
292       Collection addresses = targetMIB.getTargetAddrRowsForTag(tag);
293       MOTableRowFilter aFilter =
294           new RowStatus.ActiveRowsFilter(SnmpTargetMIB.idxSnmpTargetAddrRowStatus);
295       for (Iterator ait = addresses.iterator(); ait.hasNext(); ) {
296         MOTableRow addr = (MOTableRow) ait.next();
297         if (aFilter.passesFilter(addr)) {
298           OctetString params =
299               (OctetString)addr.getValue(SnmpTargetMIB.idxSnmpTargetAddrParams);
300           MOTableRow paramsRow = targetMIB.getTargetParamsRow(params);
301           if (RowStatus.isRowActive(paramsRow,
302                                     SnmpTargetMIB.idxSnmpTargetParamsRowStatus)) {
303             if (isAccessGranted(addr, paramsRow, context, notificationID, vbs)) {
304               ResponseEvent response =
305                   sendNotification(addr, paramsRow, context,
306                                    notificationID,
307                                    sysUpTime,
308                                    vbs, type.getValue());
309               responses.add(response);
310             }
311             else {
312               if (logger.isWarnEnabled()) {
313                 logger.warn("Access denied by VACM for "+notificationID);
314               }
315             }
316           }
317           else {
318             logger.warn("Found active target address but corrsponding params"+
319                         " are not active");
320           }
321         }
322       }
323     }
324     return (ResponseEvent[]) responses.toArray(new ResponseEvent[0]);
325   }
326 }
327
Popular Tags