1 /* 2 * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.jmx.snmp.daemon; 27 28 // java imports 29 // 30 import java.util.logging.Level; 31 import java.util.Vector; 32 33 // jmx imports 34 // 35 import com.sun.jmx.snmp.SnmpEngine; 36 import com.sun.jmx.snmp.SnmpPdu; 37 import com.sun.jmx.snmp.SnmpValue; 38 import com.sun.jmx.snmp.SnmpVarBind; 39 import com.sun.jmx.snmp.SnmpVarBindList; 40 import com.sun.jmx.snmp.SnmpOid; 41 import com.sun.jmx.snmp.SnmpDefinitions; 42 import com.sun.jmx.snmp.SnmpStatusException; 43 // SNMP Runtime import 44 // 45 import static com.sun.jmx.defaults.JmxProperties.SNMP_ADAPTOR_LOGGER; 46 import com.sun.jmx.snmp.agent.SnmpMibAgent; 47 import com.sun.jmx.snmp.agent.SnmpMibRequest; 48 import com.sun.jmx.snmp.daemon.SnmpAdaptorServer; 49 import com.sun.jmx.snmp.internal.SnmpIncomingRequest; 50 51 /* NPCTE fix for bugId 4492741, esc 0 */ 52 import com.sun.jmx.snmp.ThreadContext; 53 /* end of NPCTE fix for bugId 4492741 */ 54 55 class SnmpSubNextRequestHandler extends SnmpSubRequestHandler { 56 private SnmpAdaptorServer server = null; 57 /** 58 * The constructor initialize the subrequest with the whole varbind 59 * list contained in the original request. 60 */ 61 protected SnmpSubNextRequestHandler(SnmpAdaptorServer server, 62 SnmpMibAgent agent, 63 SnmpPdu req) { 64 super(agent,req); 65 init(req, server); 66 } 67 68 protected SnmpSubNextRequestHandler(SnmpEngine engine, 69 SnmpAdaptorServer server, 70 SnmpIncomingRequest incRequest, 71 SnmpMibAgent agent, 72 SnmpPdu req) { 73 super(engine, incRequest, agent, req); 74 init(req, server); 75 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { 76 SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, SnmpSubNextRequestHandler.class.getName(), 77 "SnmpSubNextRequestHandler", "Constructor : " + this); 78 } 79 } 80 81 private void init(SnmpPdu req, SnmpAdaptorServer server) { 82 this.server = server; 83 84 // The translation table is easy in this case ... 85 // 86 final int max= translation.length; 87 final SnmpVarBind[] list= req.varBindList; 88 final NonSyncVector<SnmpVarBind> nonSyncVarBind = 89 ((NonSyncVector<SnmpVarBind>)varBind); 90 for(int i=0; i < max; i++) { 91 translation[i]= i; 92 // we need to allocate a new SnmpVarBind. Otherwise the first 93 // sub request will modify the list... 94 // 95 final SnmpVarBind newVarBind = 96 new SnmpVarBind(list[i].oid, list[i].value); 97 nonSyncVarBind.addNonSyncElement(newVarBind); 98 } 99 } 100 101 public void run() { 102 103 try { 104 /* NPCTE fix for bugId 4492741, esc 0, 16-August-2001 */ 105 final ThreadContext oldContext = 106 ThreadContext.push("SnmpUserData",data); 107 try { 108 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) { 109 SNMP_ADAPTOR_LOGGER.logp(Level.FINER, SnmpSubRequestHandler.class.getName(), 110 "run", "[" + Thread.currentThread() + 111 "]:getNext operation on " + agent.getMibName()); 112 } 113 114 // Always call with V2. So the merge of the responses will 115 // be easier. 116 // 117 agent.getNext(createMibRequest(varBind, snmpVersionTwo, data)); 118 } finally { 119 ThreadContext.restore(oldContext); 120 } 121 /* end of NPCTE fix for bugId 4492741 */ 122 123 124 } catch(SnmpStatusException x) { 125 errorStatus = x.getStatus() ; 126 errorIndex= x.getErrorIndex(); 127 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { 128 SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, SnmpSubRequestHandler.class.getName(), 129 "run", "[" + Thread.currentThread() + 130 "]:an Snmp error occurred during the operation", x); 131 } 132 } 133 catch(Exception x) { 134 errorStatus = SnmpDefinitions.snmpRspGenErr ; 135 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { 136 SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, SnmpSubRequestHandler.class.getName(), 137 "run", "[" + Thread.currentThread() + 138 "]:a generic error occurred during the operation", x); 139 } 140 } 141 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) { 142 SNMP_ADAPTOR_LOGGER.logp(Level.FINER, SnmpSubRequestHandler.class.getName(), 143 "run", "[" + Thread.currentThread() + "]:operation completed"); 144 } 145 } 146 147 /** 148 * The method updates the varbind list of the subrequest. 149 */ 150 protected void updateRequest(SnmpVarBind var, int pos) { 151 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { 152 SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, SnmpSubRequestHandler.class.getName(), 153 "updateRequest", "Copy :" + var); 154 } 155 int size= varBind.size(); 156 translation[size]= pos; 157 final SnmpVarBind newVarBind = 158 new SnmpVarBind(var.oid, var.value); 159 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { 160 SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, SnmpSubRequestHandler.class.getName(), 161 "updateRequest", "Copied :" + newVarBind); 162 } 163 164 varBind.addElement(newVarBind); 165 } 166 /** 167 * The method updates a given var bind list with the result of a 168 * previsouly invoked operation. 169 * Prior to calling the method, one must make sure that the operation was 170 * successful. As such the method getErrorIndex or getErrorStatus should be 171 * called. 172 */ 173 protected void updateResult(SnmpVarBind[] result) { 174 175 final int max=varBind.size(); 176 for(int i= 0; i< max ; i++) { 177 // May be we should control the position ... 178 // 179 final int index= translation[i]; 180 final SnmpVarBind elmt= 181 (SnmpVarBind)((NonSyncVector)varBind).elementAtNonSync(i); 182 183 final SnmpVarBind vb= result[index]; 184 if (vb == null) { 185 result[index]= elmt; 186 /* NPCTE fix for bugid 4381195 esc 0. <J.C.> < 17-Oct-2000> */ 187 // if ((elmt != null) && (elmt.value == null) && 188 // (version == snmpVersionTwo)) 189 // elmt.value = SnmpVarBind.endOfMibView; 190 /* end of NPCTE fix for bugid 4381195 */ 191 continue; 192 } 193 194 final SnmpValue val= vb.value; 195 if ((val == null)|| (val == SnmpVarBind.endOfMibView)){ 196 /* NPCTE fix for bugid 4381195 esc 0. <J.C.> < 17-Oct-2000> */ 197 if ((elmt != null) && 198 (elmt.value != SnmpVarBind.endOfMibView)) 199 result[index]= elmt; 200 // else if ((val == null) && (version == snmpVersionTwo)) 201 // vb.value = SnmpVarBind.endOfMibView; 202 continue; 203 /* end of NPCTE fix for bugid 4381195 */ 204 } 205 206 /* NPCTE fix for bugid 4381195 esc 0. <J.C.> < 17-Oct-2000> */ 207 if (elmt == null) continue; 208 /* end of NPCTE fix for bugid 4381195 */ 209 210 if (elmt.value == SnmpVarBind.endOfMibView) continue; 211 212 213 // Now we need to take the smallest oid ... 214 // 215 int comp = elmt.oid.compareTo(vb.oid); 216 if (comp < 0) { 217 // Take the smallest (lexicographically) 218 // 219 result[index]= elmt; 220 } 221 else { 222 if(comp == 0) { 223 // Must compare agent used for reply 224 // Take the deeper within the reply 225 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) { 226 SNMP_ADAPTOR_LOGGER.logp(Level.FINER, SnmpSubRequestHandler.class.getName(), 227 "updateResult"," oid overlapping. Oid : " + 228 elmt.oid + "value :" + elmt.value); 229 SNMP_ADAPTOR_LOGGER.logp(Level.FINER, SnmpSubRequestHandler.class.getName(), 230 "updateResult","Already present varBind : " + 231 vb); 232 } 233 234 SnmpOid oid = vb.oid; 235 SnmpMibAgent deeperAgent = server.getAgentMib(oid); 236 237 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) { 238 SNMP_ADAPTOR_LOGGER.logp(Level.FINER, SnmpSubRequestHandler.class.getName(), 239 "updateResult","Deeper agent : " + deeperAgent); 240 } 241 if(deeperAgent == agent) { 242 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) { 243 SNMP_ADAPTOR_LOGGER.logp(Level.FINER, SnmpSubRequestHandler.class.getName(), 244 "updateResult","The current agent is the deeper one. Update the value with the current one"); 245 } 246 result[index].value = elmt.value; 247 } 248 249 /* 250 Vector v = new Vector(); 251 SnmpMibRequest getReq = createMibRequest(v, 252 version, 253 null); 254 SnmpVarBind realValue = new SnmpVarBind(oid); 255 getReq.addVarBind(realValue); 256 try { 257 deeperAgent.get(getReq); 258 } catch(SnmpStatusException e) { 259 e.printStackTrace(); 260 } 261 262 if(isDebugOn()) 263 trace("updateResult", "Biggest priority value is : " + 264 realValue.value); 265 266 result[index].value = realValue.value; 267 */ 268 } 269 } 270 } 271 } 272 }