1 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 ; 37 import org.snmp4j.mp.SnmpConstants; 38 import org.snmp4j.agent.mo.snmp.SysUpTime; 39 import java.net.InetAddress ; 40 41 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 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 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 130 public Object 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 OctetString community = secName; 150 if (communityMIB != null) { 151 community = communityMIB.getCommunity(secName, null, context); 152 } 153 Address 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 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 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 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 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 |