1. /*
  2. * @(#)file SnmpSubNextRequestHandler.java
  3. * @(#)author Sun Microsystems, Inc.
  4. * @(#)version 4.25
  5. * @(#)date 04/09/15
  6. *
  7. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  8. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  9. *
  10. */
  11. package com.sun.jmx.snmp.daemon;
  12. // java imports
  13. //
  14. import java.util.Vector;
  15. // jmx imports
  16. //
  17. import com.sun.jmx.snmp.SnmpEngine;
  18. import com.sun.jmx.snmp.SnmpPdu;
  19. import com.sun.jmx.snmp.SnmpValue;
  20. import com.sun.jmx.snmp.SnmpVarBind;
  21. import com.sun.jmx.snmp.SnmpVarBindList;
  22. import com.sun.jmx.snmp.SnmpOid;
  23. import com.sun.jmx.snmp.SnmpDefinitions;
  24. import com.sun.jmx.snmp.SnmpStatusException;
  25. // SNMP Runtime import
  26. //
  27. import com.sun.jmx.snmp.agent.SnmpMibAgent;
  28. import com.sun.jmx.snmp.agent.SnmpMibRequest;
  29. import com.sun.jmx.snmp.daemon.SnmpAdaptorServer;
  30. import com.sun.jmx.snmp.internal.SnmpIncomingRequest;
  31. /* NPCTE fix for bugId 4492741, esc 0 */
  32. import com.sun.jmx.snmp.ThreadContext;
  33. /* end of NPCTE fix for bugId 4492741 */
  34. class SnmpSubNextRequestHandler extends SnmpSubRequestHandler {
  35. private SnmpAdaptorServer server = null;
  36. /**
  37. * The constuctor initialize the subrequest with the whole varbind
  38. * list contained in the original request.
  39. */
  40. protected SnmpSubNextRequestHandler(SnmpAdaptorServer server,
  41. SnmpMibAgent agent,
  42. SnmpPdu req) {
  43. super(agent,req);
  44. init(req, server);
  45. }
  46. protected SnmpSubNextRequestHandler(SnmpEngine engine,
  47. SnmpAdaptorServer server,
  48. SnmpIncomingRequest incRequest,
  49. SnmpMibAgent agent,
  50. SnmpPdu req) {
  51. super(engine, incRequest, agent, req);
  52. init(req, server);
  53. if(isDebugOn())
  54. debug("SnmpSubNextRequestHandler", "Constructor :" + this);
  55. }
  56. private void init(SnmpPdu req, SnmpAdaptorServer server) {
  57. this.server = server;
  58. // The translation table is easy in this case ...
  59. //
  60. final int max= translation.length;
  61. final SnmpVarBind[] list= req.varBindList;
  62. final NonSyncVector nonSyncVarBind = ((NonSyncVector)varBind);
  63. for(int i=0; i < max; i++) {
  64. translation[i]= i;
  65. // we need to allocate a new SnmpVarBind. Otherwise the first
  66. // sub request will modify the list...
  67. //
  68. final SnmpVarBind newVarBind =
  69. new SnmpVarBind(list[i].oid, list[i].value);
  70. nonSyncVarBind.addNonSyncElement(newVarBind);
  71. }
  72. }
  73. public void run() {
  74. try {
  75. /* NPCTE fix for bugId 4492741, esc 0, 16-August-2001 */
  76. final ThreadContext oldContext =
  77. ThreadContext.push("SnmpUserData",data);
  78. try {
  79. if (isTraceOn()) {
  80. trace("run", "[" + Thread.currentThread() +
  81. "]:getNext operation on " + agent.getMibName());
  82. }
  83. // Always call with V2. So the merge of the responses will
  84. // be easier.
  85. //
  86. agent.getNext(createMibRequest(varBind, snmpVersionTwo, data));
  87. } finally {
  88. ThreadContext.restore(oldContext);
  89. }
  90. /* end of NPCTE fix for bugId 4492741 */
  91. } catch(SnmpStatusException x) {
  92. errorStatus = x.getStatus() ;
  93. errorIndex= x.getErrorIndex();
  94. if (isDebugOn()) {
  95. debug("run", "[" + Thread.currentThread() +
  96. "]:an Snmp error occured during the operation");
  97. debug("run",x);
  98. }
  99. }
  100. catch(Exception x) {
  101. errorStatus = SnmpDefinitions.snmpRspGenErr ;
  102. if (isTraceOn()) {
  103. trace("run", "[" + Thread.currentThread() +
  104. "]:a generic error occured during the operation");
  105. }
  106. if (isDebugOn()) {
  107. debug("run","Error is: " + x);
  108. debug("run",x);
  109. }
  110. }
  111. if (isTraceOn()) {
  112. trace("run", "[" + Thread.currentThread() +
  113. "]:operation completed");
  114. }
  115. }
  116. /**
  117. * The method updates the varbind list of the subrequest.
  118. */
  119. protected void updateRequest(SnmpVarBind var, int pos) {
  120. if(isDebugOn())
  121. debug("updateRequest", "Copy :" + var);
  122. int size= varBind.size();
  123. translation[size]= pos;
  124. final SnmpVarBind newVarBind =
  125. new SnmpVarBind(var.oid, var.value);
  126. if(isDebugOn())
  127. debug("updateRequest", "Copied :" + newVarBind);
  128. varBind.addElement(newVarBind);
  129. }
  130. /**
  131. * The method updates a given var bind list with the result of a
  132. * previsouly invoked operation.
  133. * Prior to calling the method, one must make sure that the operation was
  134. * successful. As such the method getErrorIndex or getErrorStatus should be
  135. * called.
  136. */
  137. protected void updateResult(SnmpVarBind[] result) {
  138. final int max=varBind.size();
  139. for(int i= 0; i< max ; i++) {
  140. // May be we should control the position ...
  141. //
  142. final int index= translation[i];
  143. final SnmpVarBind elmt=
  144. (SnmpVarBind)((NonSyncVector)varBind).elementAtNonSync(i);
  145. final SnmpVarBind vb= result[index];
  146. if (vb == null) {
  147. result[index]= elmt;
  148. /* NPCTE fix for bugid 4381195 esc 0. <J.C.> < 17-Oct-2000> */
  149. // if ((elmt != null) && (elmt.value == null) &&
  150. // (version == snmpVersionTwo))
  151. // elmt.value = SnmpVarBind.endOfMibView;
  152. /* end of NPCTE fix for bugid 4381195 */
  153. continue;
  154. }
  155. final SnmpValue val= vb.value;
  156. if ((val == null)|| (val == SnmpVarBind.endOfMibView)){
  157. /* NPCTE fix for bugid 4381195 esc 0. <J.C.> < 17-Oct-2000> */
  158. if ((elmt != null) &&
  159. (elmt.value != SnmpVarBind.endOfMibView))
  160. result[index]= elmt;
  161. // else if ((val == null) && (version == snmpVersionTwo))
  162. // vb.value = SnmpVarBind.endOfMibView;
  163. continue;
  164. /* end of NPCTE fix for bugid 4381195 */
  165. }
  166. /* NPCTE fix for bugid 4381195 esc 0. <J.C.> < 17-Oct-2000> */
  167. if (elmt == null) continue;
  168. /* end of NPCTE fix for bugid 4381195 */
  169. if (elmt.value == SnmpVarBind.endOfMibView) continue;
  170. // Now we need to take the smallest oid ...
  171. //
  172. int comp = elmt.oid.compareTo(vb.oid);
  173. if (comp < 0) {
  174. // Take the smallest (lexicographically)
  175. //
  176. result[index]= elmt;
  177. }
  178. else {
  179. if(comp == 0) {
  180. // Must compare agent used for reply
  181. // Take the deeper within the reply
  182. if(isDebugOn()) {
  183. trace("updateResult"," oid overlapping. Oid : " +
  184. elmt.oid + "value :" + elmt.value);
  185. trace("updateResult","Already present varBind : " +
  186. vb);
  187. }
  188. SnmpOid oid = vb.oid;
  189. SnmpMibAgent deeperAgent = server.getAgentMib(oid);
  190. if(isDebugOn())
  191. trace("updateResult","Deeper agent : " + deeperAgent);
  192. if(deeperAgent == agent) {
  193. if(isDebugOn())
  194. trace("updateResult","The current agent is the deeper one. Update the value with the current one");
  195. result[index].value = elmt.value;
  196. }
  197. /*
  198. Vector v = new Vector();
  199. SnmpMibRequest getReq = createMibRequest(v,
  200. version,
  201. null);
  202. SnmpVarBind realValue = new SnmpVarBind(oid);
  203. getReq.addVarBind(realValue);
  204. try {
  205. deeperAgent.get(getReq);
  206. } catch(SnmpStatusException e) {
  207. e.printStackTrace();
  208. }
  209. if(isDebugOn())
  210. trace("updateResult", "Biggest priority value is : " +
  211. realValue.value);
  212. result[index].value = realValue.value;
  213. */
  214. }
  215. }
  216. }
  217. }
  218. protected String makeDebugTag() {
  219. return "SnmpSubNextRequestHandler";
  220. }
  221. }