| 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 */  | 
 | 
 | 
 | 
 | 
 | 
package com.sun.jmx.snmp.daemon;  | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
// java import  | 
 | 
 | 
 | 
import java.util.Vector;  | 
 | 
import java.util.Enumeration;  | 
 | 
import java.util.Hashtable;  | 
 | 
import java.util.logging.Level;  | 
 | 
import java.io.InterruptedIOException;  | 
 | 
import java.net.DatagramSocket;  | 
 | 
import java.net.DatagramPacket;  | 
 | 
import java.net.SocketException;  | 
 | 
 | 
 | 
// jmx imports  | 
 | 
 | 
 | 
import javax.management.MBeanServer;  | 
 | 
import javax.management.ObjectName;  | 
 | 
import com.sun.jmx.snmp.SnmpMessage;  | 
 | 
import com.sun.jmx.snmp.SnmpPduFactory;  | 
 | 
import com.sun.jmx.snmp.SnmpPduBulk;  | 
 | 
import com.sun.jmx.snmp.SnmpPduPacket;  | 
 | 
import com.sun.jmx.snmp.SnmpPduRequest;  | 
 | 
import com.sun.jmx.snmp.SnmpPduTrap;  | 
 | 
import com.sun.jmx.snmp.SnmpValue;  | 
 | 
import com.sun.jmx.snmp.SnmpVarBind;  | 
 | 
import com.sun.jmx.snmp.SnmpVarBindList;  | 
 | 
import com.sun.jmx.snmp.SnmpDefinitions;  | 
 | 
import com.sun.jmx.snmp.SnmpStatusException;  | 
 | 
import com.sun.jmx.snmp.SnmpTooBigException;  | 
 | 
import com.sun.jmx.snmp.SnmpDataTypeEnums;  | 
 | 
 | 
 | 
// RI imports  | 
 | 
 | 
 | 
import static com.sun.jmx.defaults.JmxProperties.SNMP_ADAPTOR_LOGGER;  | 
 | 
 | 
 | 
// SNMP runtime import  | 
 | 
 | 
 | 
import com.sun.jmx.snmp.agent.SnmpMibAgent;  | 
 | 
import com.sun.jmx.snmp.agent.SnmpUserDataFactory;  | 
 | 
 | 
 | 
import com.sun.jmx.snmp.InetAddressAcl;  | 
 | 
 | 
 | 
 | 
 | 
class SnmpRequestHandler extends ClientHandler implements SnmpDefinitions { | 
 | 
 | 
 | 
    private transient DatagramSocket       socket = null ;  | 
 | 
    private transient DatagramPacket       packet = null ;  | 
 | 
    private transient Vector<SnmpMibAgent> mibs = null ;  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    private transient Hashtable<SnmpMibAgent, SnmpSubRequestHandler> subs = null;  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    private transient SnmpMibTree root;  | 
 | 
 | 
 | 
    private transient InetAddressAcl      ipacl = null ;  | 
 | 
    private transient SnmpPduFactory      pduFactory = null ;  | 
 | 
    private transient SnmpUserDataFactory userDataFactory = null ;  | 
 | 
    private transient SnmpAdaptorServer adaptor = null;  | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    public SnmpRequestHandler(SnmpAdaptorServer server, int id,  | 
 | 
                              DatagramSocket s, DatagramPacket p,  | 
 | 
                              SnmpMibTree tree, Vector<SnmpMibAgent> m,  | 
 | 
                              InetAddressAcl a,  | 
 | 
                              SnmpPduFactory factory,  | 
 | 
                              SnmpUserDataFactory dataFactory,  | 
 | 
                              MBeanServer f, ObjectName n)  | 
 | 
    { | 
 | 
        super(server, id, f, n);  | 
 | 
 | 
 | 
        // Need a reference on SnmpAdaptorServer for getNext & getBulk,  | 
 | 
        // in case of oid equality (mib overlapping).  | 
 | 
          | 
 | 
        adaptor = server;  | 
 | 
        socket = s;  | 
 | 
        packet = p;  | 
 | 
        root= tree;  | 
 | 
        mibs = new Vector<>(m);  | 
 | 
        subs= new Hashtable<>(mibs.size());  | 
 | 
        ipacl = a;  | 
 | 
        pduFactory = factory ;  | 
 | 
        userDataFactory = dataFactory ;  | 
 | 
        //thread.start();  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    @Override  | 
 | 
    public void doRun() { | 
 | 
 | 
 | 
        // Trace the input packet  | 
 | 
          | 
 | 
        if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) { | 
 | 
            SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag,  | 
 | 
                    "doRun","Packet received:\n" +  | 
 | 
                    SnmpMessage.dumpHexBuffer(packet.getData(), 0, packet.getLength()));  | 
 | 
        }  | 
 | 
 | 
 | 
        // Let's build the response packet  | 
 | 
          | 
 | 
        DatagramPacket respPacket = makeResponsePacket(packet) ;  | 
 | 
 | 
 | 
        // Trace the output packet  | 
 | 
          | 
 | 
        if ((SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) && (respPacket != null)) { | 
 | 
            SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag,  | 
 | 
                    "doRun","Packet to be sent:\n" +  | 
 | 
                    SnmpMessage.dumpHexBuffer(respPacket.getData(), 0, respPacket.getLength()));  | 
 | 
        }  | 
 | 
 | 
 | 
        // Send the response packet if any  | 
 | 
          | 
 | 
        if (respPacket != null) { | 
 | 
            try { | 
 | 
                socket.send(respPacket) ;  | 
 | 
            } catch (SocketException e) { | 
 | 
                if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { | 
 | 
                    if (e.getMessage().equals(InterruptSysCallMsg)) { | 
 | 
                        SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,  | 
 | 
                            "doRun", "interrupted");  | 
 | 
                    } else { | 
 | 
                      SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,  | 
 | 
                            "doRun", "I/O exception", e);  | 
 | 
                    }  | 
 | 
                }  | 
 | 
            } catch(InterruptedIOException e) { | 
 | 
                if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { | 
 | 
                    SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,  | 
 | 
                        "doRun", "interrupted");  | 
 | 
                }  | 
 | 
            } catch(Exception e) { | 
 | 
                if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { | 
 | 
                    SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,  | 
 | 
                        "doRun", "failure when sending response", e);  | 
 | 
                }  | 
 | 
            }  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    private DatagramPacket makeResponsePacket(DatagramPacket reqPacket) { | 
 | 
        DatagramPacket respPacket = null ;  | 
 | 
 | 
 | 
        // Transform the request packet into a request SnmpMessage  | 
 | 
          | 
 | 
        SnmpMessage reqMsg = new SnmpMessage() ;  | 
 | 
        try { | 
 | 
            reqMsg.decodeMessage(reqPacket.getData(), reqPacket.getLength()) ;  | 
 | 
            reqMsg.address = reqPacket.getAddress() ;  | 
 | 
            reqMsg.port = reqPacket.getPort() ;  | 
 | 
        }  | 
 | 
        catch(SnmpStatusException x) { | 
 | 
            if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { | 
 | 
                SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,  | 
 | 
                    "makeResponsePacket", "packet decoding failed", x);  | 
 | 
            }  | 
 | 
            reqMsg = null ;  | 
 | 
            ((SnmpAdaptorServer)adaptorServer).incSnmpInASNParseErrs(1) ;  | 
 | 
        }  | 
 | 
 | 
 | 
        // Make the response SnmpMessage if any  | 
 | 
          | 
 | 
        SnmpMessage respMsg = null ;  | 
 | 
        if (reqMsg != null) { | 
 | 
            respMsg = makeResponseMessage(reqMsg) ;  | 
 | 
        }  | 
 | 
 | 
 | 
        // Try to transform the response SnmpMessage into response packet.  | 
 | 
        // NOTE: we overwrite the request packet.  | 
 | 
          | 
 | 
        if (respMsg != null) { | 
 | 
            try { | 
 | 
                reqPacket.setLength(respMsg.encodeMessage(reqPacket.getData())) ;  | 
 | 
                respPacket = reqPacket ;  | 
 | 
            }  | 
 | 
            catch(SnmpTooBigException x) { | 
 | 
                if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { | 
 | 
                    SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,  | 
 | 
                        "makeResponsePacket", "response message is too big");  | 
 | 
                }  | 
 | 
                try { | 
 | 
                    respMsg = newTooBigMessage(reqMsg) ;  | 
 | 
                    reqPacket.setLength(respMsg.encodeMessage(reqPacket.getData())) ;  | 
 | 
                    respPacket = reqPacket ;  | 
 | 
                }  | 
 | 
                catch(SnmpTooBigException xx) { | 
 | 
                    if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { | 
 | 
                        SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,  | 
 | 
                            "makeResponsePacket", "'too big' is 'too big' !!!");  | 
 | 
                    }  | 
 | 
                    adaptor.incSnmpSilentDrops(1);  | 
 | 
                }  | 
 | 
            }  | 
 | 
        }  | 
 | 
 | 
 | 
        return respPacket ;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    private SnmpMessage makeResponseMessage(SnmpMessage reqMsg) { | 
 | 
        SnmpMessage respMsg = null ;  | 
 | 
 | 
 | 
        // Transform the request message into a request pdu  | 
 | 
          | 
 | 
        SnmpPduPacket reqPdu;  | 
 | 
        Object userData = null;  | 
 | 
        try { | 
 | 
            reqPdu = (SnmpPduPacket)pduFactory.decodeSnmpPdu(reqMsg) ;  | 
 | 
            if (reqPdu != null && userDataFactory != null)  | 
 | 
                userData = userDataFactory.allocateUserData(reqPdu);  | 
 | 
        }  | 
 | 
        catch(SnmpStatusException x) { | 
 | 
            reqPdu = null ;  | 
 | 
            SnmpAdaptorServer snmpServer = (SnmpAdaptorServer)adaptorServer ;  | 
 | 
            snmpServer.incSnmpInASNParseErrs(1) ;  | 
 | 
            if (x.getStatus()== SnmpDefinitions.snmpWrongSnmpVersion)  | 
 | 
                snmpServer.incSnmpInBadVersions(1) ;  | 
 | 
            if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { | 
 | 
                SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,  | 
 | 
                    "makeResponseMessage", "message decoding failed", x);  | 
 | 
            }  | 
 | 
        }  | 
 | 
 | 
 | 
        // Make the response pdu if any  | 
 | 
          | 
 | 
        SnmpPduPacket respPdu = null ;  | 
 | 
        if (reqPdu != null) { | 
 | 
            respPdu = makeResponsePdu(reqPdu,userData) ;  | 
 | 
            try { | 
 | 
                if (userDataFactory != null)  | 
 | 
                    userDataFactory.releaseUserData(userData,respPdu);  | 
 | 
            } catch (SnmpStatusException x) { | 
 | 
                respPdu = null;  | 
 | 
            }  | 
 | 
        }  | 
 | 
 | 
 | 
        // Try to transform the response pdu into a response message if any  | 
 | 
          | 
 | 
        if (respPdu != null) { | 
 | 
            try { | 
 | 
                respMsg = (SnmpMessage)pduFactory.  | 
 | 
                    encodeSnmpPdu(respPdu, packet.getData().length) ;  | 
 | 
            }  | 
 | 
            catch(SnmpStatusException x) { | 
 | 
                respMsg = null ;  | 
 | 
                if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { | 
 | 
                    SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,  | 
 | 
                        "makeResponseMessage", "failure when encoding the response message", x);  | 
 | 
                }  | 
 | 
            }  | 
 | 
            catch(SnmpTooBigException x) { | 
 | 
                if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { | 
 | 
                    SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,  | 
 | 
                        "makeResponseMessage", "response message is too big");  | 
 | 
                }  | 
 | 
 | 
 | 
                try { | 
 | 
                    // if the PDU is too small, why should we try to do  | 
 | 
                    // recovery ?  | 
 | 
                      | 
 | 
                    if (packet.getData().length <=32)  | 
 | 
                        throw x;  | 
 | 
                    int pos= x.getVarBindCount();  | 
 | 
                    if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { | 
 | 
                        SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,  | 
 | 
                            "makeResponseMessage", "fail on element" + pos);  | 
 | 
                    }  | 
 | 
                    int old;  | 
 | 
                    while (true) { | 
 | 
                        try { | 
 | 
                            respPdu = reduceResponsePdu(reqPdu, respPdu, pos) ;  | 
 | 
                            respMsg = (SnmpMessage)pduFactory.  | 
 | 
                                encodeSnmpPdu(respPdu,  | 
 | 
                                              packet.getData().length -32) ;  | 
 | 
                            break;  | 
 | 
                        } catch (SnmpTooBigException xx) { | 
 | 
                            if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { | 
 | 
                                SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,  | 
 | 
                                    "makeResponseMessage", "response message is still too big");  | 
 | 
                            }  | 
 | 
                            old= pos;  | 
 | 
                            pos= xx.getVarBindCount();  | 
 | 
                            if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { | 
 | 
                                SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,  | 
 | 
                                    "makeResponseMessage","fail on element" + pos);  | 
 | 
                            }  | 
 | 
                            if (pos == old) { | 
 | 
                                // we can not go any further in trying to  | 
 | 
                                // reduce the message !  | 
 | 
                                  | 
 | 
                                throw xx;  | 
 | 
                            }  | 
 | 
                        }  | 
 | 
                    }// end of loop  | 
 | 
                } catch(SnmpStatusException xx) { | 
 | 
                    respMsg = null ;  | 
 | 
                    if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { | 
 | 
                        SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,  | 
 | 
                           "makeResponseMessage", "failure when encoding the response message", xx);  | 
 | 
                    }  | 
 | 
                }  | 
 | 
                catch(SnmpTooBigException xx) { | 
 | 
                    try { | 
 | 
                        respPdu = newTooBigPdu(reqPdu) ;  | 
 | 
                        respMsg = (SnmpMessage)pduFactory.  | 
 | 
                            encodeSnmpPdu(respPdu, packet.getData().length) ;  | 
 | 
                    }  | 
 | 
                    catch(SnmpTooBigException xxx) { | 
 | 
                        respMsg = null ;  | 
 | 
                        if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { | 
 | 
                            SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,  | 
 | 
                               "makeResponseMessage", "'too big' is 'too big' !!!");  | 
 | 
                        }  | 
 | 
                        adaptor.incSnmpSilentDrops(1);  | 
 | 
                    }  | 
 | 
                    catch(Exception xxx) { | 
 | 
                        if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { | 
 | 
                            SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,  | 
 | 
                               "makeResponseMessage", "Got unexpected exception", xxx);  | 
 | 
                        }  | 
 | 
                        respMsg = null ;  | 
 | 
                    }  | 
 | 
                }  | 
 | 
                catch(Exception xx) { | 
 | 
                    if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { | 
 | 
                        SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,  | 
 | 
                           "makeResponseMessage", "Got unexpected exception", xx);  | 
 | 
                    }  | 
 | 
                    respMsg = null ;  | 
 | 
                }  | 
 | 
            }  | 
 | 
        }  | 
 | 
        return respMsg ;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    private SnmpPduPacket makeResponsePdu(SnmpPduPacket reqPdu,  | 
 | 
                                          Object userData) { | 
 | 
 | 
 | 
        SnmpAdaptorServer snmpServer = (SnmpAdaptorServer)adaptorServer ;  | 
 | 
        SnmpPduPacket respPdu = null ;  | 
 | 
 | 
 | 
        snmpServer.updateRequestCounters(reqPdu.type) ;  | 
 | 
        if (reqPdu.varBindList != null)  | 
 | 
            snmpServer.updateVarCounters(reqPdu.type,  | 
 | 
                                         reqPdu.varBindList.length) ;  | 
 | 
 | 
 | 
        if (checkPduType(reqPdu)) { | 
 | 
            respPdu = checkAcl(reqPdu) ;  | 
 | 
            if (respPdu == null) {  | 
 | 
                if (mibs.size() < 1) { | 
 | 
                    if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) { | 
 | 
                        SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag,  | 
 | 
                           "makeResponsePdu", "Request " + reqPdu.requestId +  | 
 | 
                           " received but no MIB registered.");  | 
 | 
                    }  | 
 | 
                    return makeNoMibErrorPdu((SnmpPduRequest)reqPdu, userData);  | 
 | 
                }  | 
 | 
                switch(reqPdu.type) { | 
 | 
                case SnmpPduPacket.pduGetRequestPdu:  | 
 | 
                case SnmpPduPacket.pduGetNextRequestPdu:  | 
 | 
                case SnmpPduPacket.pduSetRequestPdu:  | 
 | 
                    respPdu = makeGetSetResponsePdu((SnmpPduRequest)reqPdu,  | 
 | 
                                                    userData) ;  | 
 | 
                    break ;  | 
 | 
 | 
 | 
                case SnmpPduPacket.pduGetBulkRequestPdu:  | 
 | 
                    respPdu = makeGetBulkResponsePdu((SnmpPduBulk)reqPdu,  | 
 | 
                                                     userData) ;  | 
 | 
                    break ;  | 
 | 
                }  | 
 | 
            }  | 
 | 
            else { // reqPdu is rejected by ACLs | 
 | 
                // respPdu contains the error response to be sent.  | 
 | 
                  | 
 | 
                if (!snmpServer.getAuthRespEnabled()) {  | 
 | 
                    respPdu = null ;  | 
 | 
                }  | 
 | 
                if (snmpServer.getAuthTrapEnabled()) {  | 
 | 
                    try { | 
 | 
                        snmpServer.snmpV1Trap(SnmpPduTrap.  | 
 | 
                                              trapAuthenticationFailure, 0,  | 
 | 
                                              new SnmpVarBindList()) ;  | 
 | 
                    }  | 
 | 
                    catch(Exception x) { | 
 | 
                        if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { | 
 | 
                            SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,  | 
 | 
                               "makeResponsePdu", "Failure when sending authentication trap", x);  | 
 | 
                        }  | 
 | 
                    }  | 
 | 
                }  | 
 | 
            }  | 
 | 
        }  | 
 | 
        return respPdu ;  | 
 | 
    }  | 
 | 
 | 
 | 
    //  | 
 | 
    // Generates a response packet, filling the values in the  | 
 | 
    // varbindlist with one of endOfMibView, noSuchObject, noSuchInstance  | 
 | 
    // according to the value of <code>status</code>  | 
 | 
    //  | 
 | 
    // @param statusTag should be one of:  | 
 | 
    //        <li>SnmpDataTypeEnums.errEndOfMibViewTag</li>  | 
 | 
    //        <li>SnmpDataTypeEnums.errNoSuchObjectTag</li>  | 
 | 
    //        <li>SnmpDataTypeEnums.errNoSuchInstanceTag</li>  | 
 | 
      | 
 | 
    SnmpPduPacket makeErrorVarbindPdu(SnmpPduPacket req, int statusTag) { | 
 | 
 | 
 | 
        final SnmpVarBind[] vblist = req.varBindList;  | 
 | 
        final int length = vblist.length;  | 
 | 
 | 
 | 
        switch (statusTag) { | 
 | 
        case SnmpDataTypeEnums.errEndOfMibViewTag:  | 
 | 
            for (int i=0 ; i<length ; i++)  | 
 | 
                vblist[i].value = SnmpVarBind.endOfMibView;  | 
 | 
            break;  | 
 | 
        case SnmpDataTypeEnums.errNoSuchObjectTag:  | 
 | 
            for (int i=0 ; i<length ; i++)  | 
 | 
                vblist[i].value = SnmpVarBind.noSuchObject;  | 
 | 
            break;  | 
 | 
        case SnmpDataTypeEnums.errNoSuchInstanceTag:  | 
 | 
            for (int i=0 ; i<length ; i++)  | 
 | 
                vblist[i].value = SnmpVarBind.noSuchInstance;  | 
 | 
            break;  | 
 | 
        default:  | 
 | 
            return newErrorResponsePdu(req,snmpRspGenErr,1);  | 
 | 
        }  | 
 | 
        return newValidResponsePdu(req,vblist);  | 
 | 
    }  | 
 | 
 | 
 | 
    // Generates an appropriate response when no mib is registered in  | 
 | 
    // the adaptor.  | 
 | 
    //  | 
 | 
    // <li>If the version is V1:</li>  | 
 | 
    // <ul><li>Generates a NoSuchName error V1 response PDU</li></ul>  | 
 | 
    // <li>If the version is V2:</li>  | 
 | 
    // <ul><li>If the request is a GET, fills the varbind list with  | 
 | 
    //         NoSuchObject's</li>  | 
 | 
    //     <li>If the request is a GET-NEXT/GET-BULK, fills the varbind  | 
 | 
    //         list with EndOfMibView's</li>  | 
 | 
    //     <li>If the request is a SET, generates a NoAccess error V2  | 
 | 
    //          response PDU</li>  | 
 | 
    // </ul>  | 
 | 
    //  | 
 | 
      | 
 | 
    SnmpPduPacket makeNoMibErrorPdu(SnmpPduRequest req, Object userData) { | 
 | 
        // There is no agent registered  | 
 | 
          | 
 | 
        if (req.version == SnmpDefinitions.snmpVersionOne) { | 
 | 
              | 
 | 
            return  | 
 | 
                newErrorResponsePdu(req,snmpRspNoSuchName,1);  | 
 | 
        } else if (req.version == SnmpDefinitions.snmpVersionTwo) { | 
 | 
              | 
 | 
            switch (req.type) { | 
 | 
            case pduSetRequestPdu :  | 
 | 
            case pduWalkRequest :  | 
 | 
                  | 
 | 
                return  | 
 | 
                    newErrorResponsePdu(req,snmpRspNoAccess,1);  | 
 | 
            case pduGetRequestPdu :  | 
 | 
                  | 
 | 
                return  | 
 | 
                    makeErrorVarbindPdu(req,SnmpDataTypeEnums.  | 
 | 
                                        errNoSuchObjectTag);  | 
 | 
            case pduGetNextRequestPdu :  | 
 | 
            case pduGetBulkRequestPdu :  | 
 | 
                  | 
 | 
                return  | 
 | 
                    makeErrorVarbindPdu(req,SnmpDataTypeEnums.  | 
 | 
                                        errEndOfMibViewTag);  | 
 | 
            default:  | 
 | 
            }  | 
 | 
        }  | 
 | 
          | 
 | 
        return newErrorResponsePdu(req,snmpRspGenErr,1);  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    private SnmpPduPacket makeGetSetResponsePdu(SnmpPduRequest req,  | 
 | 
                                                Object userData) { | 
 | 
 | 
 | 
        // Create the trhead group specific for handling sub-requests  | 
 | 
        // associated to the current request. Use the invoke id  | 
 | 
        //  | 
 | 
        // Nice idea to use a thread group on a request basis.  | 
 | 
        // However the impact on performance is terrible !  | 
 | 
        // theGroup= new ThreadGroup(thread.getThreadGroup(),  | 
 | 
        //                "request " + String.valueOf(req.requestId));  | 
 | 
 | 
 | 
        // Let's build the varBindList for the response pdu  | 
 | 
        //  | 
 | 
 | 
 | 
        if (req.varBindList == null) { | 
 | 
            // Good ! Let's make a full response pdu.  | 
 | 
              | 
 | 
            return newValidResponsePdu(req, null) ;  | 
 | 
        }  | 
 | 
 | 
 | 
        // First we need to split the request into subrequests  | 
 | 
          | 
 | 
        splitRequest(req);  | 
 | 
        int nbSubRequest= subs.size();  | 
 | 
        if (nbSubRequest == 1)  | 
 | 
            return turboProcessingGetSet(req,userData);  | 
 | 
 | 
 | 
 | 
 | 
        // Execute all the subrequests resulting from the split of the  | 
 | 
        // varbind list.  | 
 | 
          | 
 | 
        SnmpPduPacket result= executeSubRequest(req,userData);  | 
 | 
        if (result != null)  | 
 | 
            // It means that an error occurred. The error is already  | 
 | 
            // formatted by the executeSubRequest  | 
 | 
              | 
 | 
            return result;  | 
 | 
 | 
 | 
        // So far so good. So we need to concatenate all the answers.  | 
 | 
          | 
 | 
        if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) { | 
 | 
            SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag,  | 
 | 
               "makeGetSetResponsePdu",  | 
 | 
               "Build the unified response for request " + req.requestId);  | 
 | 
        }  | 
 | 
        return mergeResponses(req);  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    private SnmpPduPacket executeSubRequest(SnmpPduPacket req,  | 
 | 
                                            Object userData) { | 
 | 
 | 
 | 
        int errorStatus = SnmpDefinitions.snmpRspNoError ;  | 
 | 
 | 
 | 
        int i;  | 
 | 
        // If it's a set request, we must first check any varBind  | 
 | 
          | 
 | 
        if (req.type == pduSetRequestPdu) { | 
 | 
 | 
 | 
            i=0;  | 
 | 
            for(Enumeration<SnmpSubRequestHandler> e= subs.elements(); e.hasMoreElements() ; i++) { | 
 | 
                // Indicate to the sub request that a check must be invoked ...  | 
 | 
                // OK we should have defined out own tag for that !  | 
 | 
                  | 
 | 
                SnmpSubRequestHandler sub= e.nextElement();  | 
 | 
                sub.setUserData(userData);  | 
 | 
                sub.type= pduWalkRequest;  | 
 | 
 | 
 | 
                sub.run();  | 
 | 
 | 
 | 
                sub.type= pduSetRequestPdu;  | 
 | 
 | 
 | 
                if (sub.getErrorStatus() != SnmpDefinitions.snmpRspNoError) { | 
 | 
                    // No point to go any further.  | 
 | 
                      | 
 | 
                    if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { | 
 | 
                        SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,  | 
 | 
                           "executeSubRequest", "an error occurs");  | 
 | 
                    }  | 
 | 
 | 
 | 
                    return newErrorResponsePdu(req, errorStatus,  | 
 | 
                                               sub.getErrorIndex() + 1) ;  | 
 | 
                }  | 
 | 
            }  | 
 | 
        }// end processing check operation for a set PDU.  | 
 | 
 | 
 | 
        // Let's start the sub-requests.  | 
 | 
          | 
 | 
        i=0;  | 
 | 
        for(Enumeration<SnmpSubRequestHandler> e= subs.elements(); e.hasMoreElements() ;i++) { | 
 | 
            SnmpSubRequestHandler sub= e.nextElement();  | 
 | 
          | 
 | 
            sub.setUserData(userData);  | 
 | 
        /* end of NPCTE fix for bugId 4492741 */  | 
 | 
 | 
 | 
            sub.run();  | 
 | 
 | 
 | 
            if (sub.getErrorStatus() != SnmpDefinitions.snmpRspNoError) { | 
 | 
                // No point to go any further.  | 
 | 
                  | 
 | 
                if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { | 
 | 
                    SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,  | 
 | 
                       "executeSubRequest", "an error occurs");  | 
 | 
                }  | 
 | 
 | 
 | 
                return newErrorResponsePdu(req, errorStatus,  | 
 | 
                                           sub.getErrorIndex() + 1) ;  | 
 | 
            }  | 
 | 
        }  | 
 | 
 | 
 | 
        // everything is ok  | 
 | 
          | 
 | 
        return null;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    private SnmpPduPacket turboProcessingGetSet(SnmpPduRequest req,  | 
 | 
                                                Object userData) { | 
 | 
 | 
 | 
        int errorStatus;  | 
 | 
        SnmpSubRequestHandler sub = subs.elements().nextElement();  | 
 | 
        sub.setUserData(userData);  | 
 | 
 | 
 | 
        // Indicate to the sub request that a check must be invoked ...  | 
 | 
        // OK we should have defined out own tag for that !  | 
 | 
          | 
 | 
        if (req.type == SnmpDefinitions.pduSetRequestPdu) { | 
 | 
            sub.type= pduWalkRequest;  | 
 | 
            sub.run();  | 
 | 
            sub.type= pduSetRequestPdu;  | 
 | 
 | 
 | 
            // Check the error status.  | 
 | 
              | 
 | 
            errorStatus= sub.getErrorStatus();  | 
 | 
            if (errorStatus != SnmpDefinitions.snmpRspNoError) { | 
 | 
                // No point to go any further.  | 
 | 
                  | 
 | 
                return newErrorResponsePdu(req, errorStatus,  | 
 | 
                                           sub.getErrorIndex() + 1) ;  | 
 | 
            }  | 
 | 
        }  | 
 | 
 | 
 | 
        // process the operation  | 
 | 
        //  | 
 | 
 | 
 | 
        sub.run();  | 
 | 
        errorStatus= sub.getErrorStatus();  | 
 | 
        if (errorStatus != SnmpDefinitions.snmpRspNoError) { | 
 | 
            // No point to go any further.  | 
 | 
              | 
 | 
            if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { | 
 | 
                SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,  | 
 | 
                   "turboProcessingGetSet", "an error occurs");  | 
 | 
            }  | 
 | 
            int realIndex= sub.getErrorIndex() + 1;  | 
 | 
            return newErrorResponsePdu(req, errorStatus, realIndex) ;  | 
 | 
        }  | 
 | 
 | 
 | 
        // So far so good. So we need to concatenate all the answers.  | 
 | 
        //  | 
 | 
 | 
 | 
        if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) { | 
 | 
            SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag,  | 
 | 
               "turboProcessingGetSet",  "build the unified response for request "  | 
 | 
                + req.requestId);  | 
 | 
        }  | 
 | 
        return mergeResponses(req);  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    private SnmpPduPacket makeGetBulkResponsePdu(SnmpPduBulk req,  | 
 | 
                                                 Object userData) { | 
 | 
 | 
 | 
        SnmpVarBind[] respVarBindList;  | 
 | 
 | 
 | 
          | 
 | 
        int L = req.varBindList.length ;  | 
 | 
        int N = Math.max(Math.min(req.nonRepeaters, L), 0) ;  | 
 | 
        int M = Math.max(req.maxRepetitions, 0) ;  | 
 | 
        int R = L - N ;  | 
 | 
 | 
 | 
        if (req.varBindList == null) { | 
 | 
            // Good ! Let's make a full response pdu.  | 
 | 
              | 
 | 
            return newValidResponsePdu(req, null) ;  | 
 | 
        }  | 
 | 
 | 
 | 
        // Split the request into subrequests.  | 
 | 
          | 
 | 
        splitBulkRequest(req, N, M, R);  | 
 | 
        SnmpPduPacket result= executeSubRequest(req,userData);  | 
 | 
        if (result != null)  | 
 | 
            return result;  | 
 | 
 | 
 | 
        respVarBindList= mergeBulkResponses(N + (M * R));  | 
 | 
 | 
 | 
        // Now we remove useless trailing endOfMibView.  | 
 | 
        //  | 
 | 
        int m2 ;   | 
 | 
        int t = respVarBindList.length ;  | 
 | 
        while ((t > N) && (respVarBindList[t-1].  | 
 | 
                           value.equals(SnmpVarBind.endOfMibView))) { | 
 | 
            t-- ;  | 
 | 
        }  | 
 | 
        if (t == N)  | 
 | 
            m2 = N + R ;  | 
 | 
        else  | 
 | 
            m2 = N + ((t -1 -N) / R + 2) * R ;   | 
 | 
        if (m2 < respVarBindList.length) { | 
 | 
            SnmpVarBind[] truncatedList = new SnmpVarBind[m2] ;  | 
 | 
            for (int i = 0 ; i < m2 ; i++) { | 
 | 
                truncatedList[i] = respVarBindList[i] ;  | 
 | 
            }  | 
 | 
            respVarBindList = truncatedList ;  | 
 | 
        }  | 
 | 
 | 
 | 
        // Good ! Let's make a full response pdu.  | 
 | 
          | 
 | 
        return newValidResponsePdu(req, respVarBindList) ;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    private boolean checkPduType(SnmpPduPacket pdu) { | 
 | 
 | 
 | 
        boolean result;  | 
 | 
 | 
 | 
        switch(pdu.type) { | 
 | 
 | 
 | 
        case SnmpDefinitions.pduGetRequestPdu:  | 
 | 
        case SnmpDefinitions.pduGetNextRequestPdu:  | 
 | 
        case SnmpDefinitions.pduSetRequestPdu:  | 
 | 
        case SnmpDefinitions.pduGetBulkRequestPdu:  | 
 | 
            result = true ;  | 
 | 
            break;  | 
 | 
 | 
 | 
        default:  | 
 | 
            if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { | 
 | 
                SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,  | 
 | 
                   "checkPduType", "cannot respond to this kind of PDU");  | 
 | 
            }  | 
 | 
            result = false ;  | 
 | 
            break;  | 
 | 
        }  | 
 | 
 | 
 | 
        return result ;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    private SnmpPduPacket checkAcl(SnmpPduPacket pdu) { | 
 | 
        SnmpPduPacket response = null ;  | 
 | 
        String community = new String(pdu.community) ;  | 
 | 
 | 
 | 
        // We check the pdu type and create an error response if  | 
 | 
        // the check failed.  | 
 | 
          | 
 | 
        if (ipacl != null) { | 
 | 
            if (pdu.type == SnmpDefinitions.pduSetRequestPdu) { | 
 | 
                if (!ipacl.checkWritePermission(pdu.address, community)) { | 
 | 
                    if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) { | 
 | 
                        SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag,  | 
 | 
                           "checkAcl", "sender is " + pdu.address +  | 
 | 
                              " with " + community +". Sender has no write permission");  | 
 | 
                    }  | 
 | 
                    int err = SnmpSubRequestHandler.  | 
 | 
                        mapErrorStatus(SnmpDefinitions.  | 
 | 
                                       snmpRspAuthorizationError,  | 
 | 
                                       pdu.version, pdu.type);  | 
 | 
                    response = newErrorResponsePdu(pdu, err, 0) ;  | 
 | 
                }  | 
 | 
                else { | 
 | 
                    if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) { | 
 | 
                        SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag,  | 
 | 
                           "checkAcl", "sender is " + pdu.address +  | 
 | 
                              " with " + community +". Sender has write permission");  | 
 | 
                    }  | 
 | 
                }  | 
 | 
            }  | 
 | 
            else { | 
 | 
                if (!ipacl.checkReadPermission(pdu.address, community)) { | 
 | 
                    if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) { | 
 | 
                        SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag,  | 
 | 
                           "checkAcl", "sender is " + pdu.address +  | 
 | 
                              " with " + community +". Sender has no read permission");  | 
 | 
                    }  | 
 | 
                    int err = SnmpSubRequestHandler.  | 
 | 
                        mapErrorStatus(SnmpDefinitions.  | 
 | 
                                       snmpRspAuthorizationError,  | 
 | 
                                       pdu.version, pdu.type);  | 
 | 
                    response = newErrorResponsePdu(pdu,  | 
 | 
                                                   err,  | 
 | 
                                                   0);  | 
 | 
                    SnmpAdaptorServer snmpServer =  | 
 | 
                        (SnmpAdaptorServer)adaptorServer;  | 
 | 
                    snmpServer.updateErrorCounters(SnmpDefinitions.  | 
 | 
                                                   snmpRspNoSuchName);  | 
 | 
                }  | 
 | 
                else { | 
 | 
                    if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) { | 
 | 
                        SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag,  | 
 | 
                           "checkAcl", "sender is " + pdu.address +  | 
 | 
                              " with " + community +". Sender has read permission");  | 
 | 
                    }  | 
 | 
                }  | 
 | 
            }  | 
 | 
        }  | 
 | 
 | 
 | 
        // If the response is not null, this means the pdu is rejected.  | 
 | 
        // So let's update the statistics.  | 
 | 
          | 
 | 
        if (response != null) { | 
 | 
            SnmpAdaptorServer snmpServer = (SnmpAdaptorServer)adaptorServer ;  | 
 | 
            snmpServer.incSnmpInBadCommunityUses(1) ;  | 
 | 
            if (ipacl.checkCommunity(community) == false)  | 
 | 
                snmpServer.incSnmpInBadCommunityNames(1) ;  | 
 | 
        }  | 
 | 
 | 
 | 
        return response ;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    private SnmpPduRequest newValidResponsePdu(SnmpPduPacket reqPdu,  | 
 | 
                                               SnmpVarBind[] varBindList) { | 
 | 
        SnmpPduRequest result = new SnmpPduRequest() ;  | 
 | 
 | 
 | 
        result.address = reqPdu.address ;  | 
 | 
        result.port = reqPdu.port ;  | 
 | 
        result.version = reqPdu.version ;  | 
 | 
        result.community = reqPdu.community ;  | 
 | 
        result.type = SnmpPduRequest.pduGetResponsePdu ;  | 
 | 
        result.requestId = reqPdu.requestId ;  | 
 | 
        result.errorStatus = SnmpDefinitions.snmpRspNoError ;  | 
 | 
        result.errorIndex = 0 ;  | 
 | 
        result.varBindList = varBindList ;  | 
 | 
 | 
 | 
        ((SnmpAdaptorServer)adaptorServer).  | 
 | 
            updateErrorCounters(result.errorStatus) ;  | 
 | 
 | 
 | 
        return result ;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    private SnmpPduRequest newErrorResponsePdu(SnmpPduPacket req,int s,int i) { | 
 | 
        SnmpPduRequest result = newValidResponsePdu(req, null) ;  | 
 | 
        result.errorStatus = s ;  | 
 | 
        result.errorIndex = i ;  | 
 | 
        result.varBindList = req.varBindList ;  | 
 | 
 | 
 | 
        ((SnmpAdaptorServer)adaptorServer).  | 
 | 
            updateErrorCounters(result.errorStatus) ;  | 
 | 
 | 
 | 
        return result ;  | 
 | 
    }  | 
 | 
 | 
 | 
    private SnmpMessage newTooBigMessage(SnmpMessage reqMsg)  | 
 | 
        throws SnmpTooBigException { | 
 | 
        SnmpMessage result = null ;  | 
 | 
        SnmpPduPacket reqPdu;  | 
 | 
 | 
 | 
        try { | 
 | 
            reqPdu = (SnmpPduPacket)pduFactory.decodeSnmpPdu(reqMsg) ;  | 
 | 
            if (reqPdu != null) { | 
 | 
                SnmpPduPacket respPdu = newTooBigPdu(reqPdu) ;  | 
 | 
                result = (SnmpMessage)pduFactory.  | 
 | 
                    encodeSnmpPdu(respPdu, packet.getData().length) ;  | 
 | 
            }  | 
 | 
        }  | 
 | 
        catch(SnmpStatusException x) { | 
 | 
            // This should not occur because decodeIncomingRequest has normally  | 
 | 
              | 
 | 
            if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { | 
 | 
                SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,  | 
 | 
                   "newTooBigMessage", "Internal error", x);  | 
 | 
            }  | 
 | 
            throw new InternalError(x) ;  | 
 | 
        }  | 
 | 
 | 
 | 
        return result ;  | 
 | 
    }  | 
 | 
 | 
 | 
    private SnmpPduPacket newTooBigPdu(SnmpPduPacket req) { | 
 | 
        SnmpPduRequest result =  | 
 | 
            newErrorResponsePdu(req, SnmpDefinitions.snmpRspTooBig, 0) ;  | 
 | 
        result.varBindList = null ;  | 
 | 
        return result ;  | 
 | 
    }  | 
 | 
 | 
 | 
    private SnmpPduPacket reduceResponsePdu(SnmpPduPacket req,  | 
 | 
                                            SnmpPduPacket resp,  | 
 | 
                                            int acceptedVbCount)  | 
 | 
        throws SnmpTooBigException { | 
 | 
 | 
 | 
        // Reduction can be attempted only on bulk response  | 
 | 
          | 
 | 
        if (req.type != SnmpPduPacket.pduGetBulkRequestPdu) { | 
 | 
            if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { | 
 | 
                SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,  | 
 | 
                   "reduceResponsePdu", "cannot remove anything");  | 
 | 
            }  | 
 | 
            throw new SnmpTooBigException(acceptedVbCount) ;  | 
 | 
        }  | 
 | 
 | 
 | 
        // We're going to reduce the varbind list.  | 
 | 
        // First determine which items should be removed.  | 
 | 
        // Next duplicate and replace the existing list by the reduced one.  | 
 | 
        //  | 
 | 
        // acceptedVbCount is the number of varbind which have been  | 
 | 
        // successfully encoded before reaching bufferSize:  | 
 | 
        //   * when it is >= 2, we split the varbindlist at this  | 
 | 
        //     position (-1 to be safe),  | 
 | 
        //   * when it is 1, we only put one (big?) item in the varbindlist  | 
 | 
        //   * when it is 0 (in fact, acceptedVbCount is not available),  | 
 | 
        //     we split the varbindlist by 2.  | 
 | 
          | 
 | 
        int vbCount;  | 
 | 
        if (acceptedVbCount >= 3)  | 
 | 
            vbCount = Math.min(acceptedVbCount - 1, resp.varBindList.length) ;  | 
 | 
        else if (acceptedVbCount == 1)  | 
 | 
            vbCount = 1 ;  | 
 | 
        else   | 
 | 
            vbCount = resp.varBindList.length / 2 ;  | 
 | 
 | 
 | 
        if (vbCount < 1) { | 
 | 
            if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { | 
 | 
                SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,  | 
 | 
                   "reduceResponsePdu", "cannot remove anything");  | 
 | 
            }  | 
 | 
            throw new SnmpTooBigException(acceptedVbCount) ;  | 
 | 
        }  | 
 | 
        else { | 
 | 
            SnmpVarBind[] newVbList = new SnmpVarBind[vbCount] ;  | 
 | 
            for (int i = 0 ; i < vbCount ; i++) { | 
 | 
                newVbList[i] = resp.varBindList[i] ;  | 
 | 
            }  | 
 | 
            if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { | 
 | 
                SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,  | 
 | 
                   "reduceResponsePdu", (resp.varBindList.length - newVbList.length) +  | 
 | 
                    " items have been removed");  | 
 | 
            }  | 
 | 
            resp.varBindList = newVbList ;  | 
 | 
        }  | 
 | 
 | 
 | 
        return resp ;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    private void splitRequest(SnmpPduRequest req) { | 
 | 
 | 
 | 
        int nbAgents= mibs.size();  | 
 | 
        SnmpMibAgent agent = mibs.firstElement();  | 
 | 
        if (nbAgents == 1) { | 
 | 
            // Take all the oids contained in the request and  | 
 | 
              | 
 | 
            subs.put(agent, new SnmpSubRequestHandler(agent, req, true));  | 
 | 
            return;  | 
 | 
        }  | 
 | 
 | 
 | 
        // For the get next operation we are going to send the varbind list  | 
 | 
        // to all agents  | 
 | 
          | 
 | 
        if (req.type == pduGetNextRequestPdu) { | 
 | 
            for(Enumeration<SnmpMibAgent> e= mibs.elements(); e.hasMoreElements(); ) { | 
 | 
                final SnmpMibAgent ag= e.nextElement();  | 
 | 
                subs.put(ag, new SnmpSubNextRequestHandler(adaptor, ag, req));  | 
 | 
            }  | 
 | 
            return;  | 
 | 
        }  | 
 | 
 | 
 | 
        int nbReqs= req.varBindList.length;  | 
 | 
        SnmpVarBind[] vars= req.varBindList;  | 
 | 
        SnmpSubRequestHandler sub;  | 
 | 
        for(int i=0; i < nbReqs; i++) { | 
 | 
            agent= root.getAgentMib(vars[i].oid);  | 
 | 
            sub= subs.get(agent);  | 
 | 
            if (sub == null) { | 
 | 
                // We need to create the sub request handler and update  | 
 | 
                // the hashtable  | 
 | 
                  | 
 | 
                sub= new SnmpSubRequestHandler(agent, req);  | 
 | 
                subs.put(agent, sub);  | 
 | 
            }  | 
 | 
 | 
 | 
            // Update the translation table within the subrequest  | 
 | 
              | 
 | 
            sub.updateRequest(vars[i], i);  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    private void splitBulkRequest(SnmpPduBulk req,  | 
 | 
                                  int nonRepeaters,  | 
 | 
                                  int maxRepetitions,  | 
 | 
                                  int R) { | 
 | 
        // Send the getBulk to all agents  | 
 | 
          | 
 | 
        for(Enumeration<SnmpMibAgent> e= mibs.elements(); e.hasMoreElements(); ) { | 
 | 
            final SnmpMibAgent agent = e.nextElement();  | 
 | 
 | 
 | 
            if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) { | 
 | 
                SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag,  | 
 | 
                   "splitBulkRequest", "Create a sub with : " + agent + " " + nonRepeaters  | 
 | 
                   + " " + maxRepetitions + " " + R);  | 
 | 
            }  | 
 | 
 | 
 | 
            subs.put(agent,  | 
 | 
                     new SnmpSubBulkRequestHandler(adaptor,  | 
 | 
                                                   agent,  | 
 | 
                                                   req,  | 
 | 
                                                   nonRepeaters,  | 
 | 
                                                   maxRepetitions,  | 
 | 
                                                   R));  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
    private SnmpPduPacket mergeResponses(SnmpPduRequest req) { | 
 | 
 | 
 | 
        if (req.type == pduGetNextRequestPdu) { | 
 | 
            return mergeNextResponses(req);  | 
 | 
        }  | 
 | 
 | 
 | 
        SnmpVarBind[] result= req.varBindList;  | 
 | 
 | 
 | 
        // Go through the list of subrequests and concatenate.  | 
 | 
        // Hopefully, by now all the sub-requests should be finished  | 
 | 
          | 
 | 
        for(Enumeration<SnmpSubRequestHandler> e= subs.elements(); e.hasMoreElements();) { | 
 | 
            SnmpSubRequestHandler sub= e.nextElement();  | 
 | 
            sub.updateResult(result);  | 
 | 
        }  | 
 | 
        return newValidResponsePdu(req,result);  | 
 | 
    }  | 
 | 
 | 
 | 
    private SnmpPduPacket mergeNextResponses(SnmpPduRequest req) { | 
 | 
        int max= req.varBindList.length;  | 
 | 
        SnmpVarBind[] result= new SnmpVarBind[max];  | 
 | 
 | 
 | 
        // Go through the list of subrequests and concatenate.  | 
 | 
        // Hopefully, by now all the sub-requests should be finished  | 
 | 
          | 
 | 
        for(Enumeration<SnmpSubRequestHandler> e= subs.elements(); e.hasMoreElements();) { | 
 | 
            SnmpSubRequestHandler sub= e.nextElement();  | 
 | 
            sub.updateResult(result);  | 
 | 
        }  | 
 | 
 | 
 | 
        if (req.version == snmpVersionTwo) { | 
 | 
            return newValidResponsePdu(req,result);  | 
 | 
        }  | 
 | 
 | 
 | 
        // In v1 make sure there is no endOfMibView ...  | 
 | 
          | 
 | 
        for(int i=0; i < max; i++) { | 
 | 
            SnmpValue val= result[i].value;  | 
 | 
            if (val == SnmpVarBind.endOfMibView)  | 
 | 
                return newErrorResponsePdu(req,  | 
 | 
                                   SnmpDefinitions.snmpRspNoSuchName, i+1);  | 
 | 
        }  | 
 | 
 | 
 | 
        // So far so good ...  | 
 | 
          | 
 | 
        return newValidResponsePdu(req,result);  | 
 | 
    }  | 
 | 
 | 
 | 
    private SnmpVarBind[] mergeBulkResponses(int size) { | 
 | 
        // Let's allocate the array for storing the result  | 
 | 
          | 
 | 
        SnmpVarBind[] result= new SnmpVarBind[size];  | 
 | 
        for(int i= size-1; i >=0; --i) { | 
 | 
            result[i]= new SnmpVarBind();  | 
 | 
            result[i].value= SnmpVarBind.endOfMibView;  | 
 | 
        }  | 
 | 
 | 
 | 
        // Go through the list of subrequests and concatenate.  | 
 | 
        // Hopefully, by now all the sub-requests should be finished  | 
 | 
          | 
 | 
        for(Enumeration<SnmpSubRequestHandler> e= subs.elements(); e.hasMoreElements();) { | 
 | 
            SnmpSubRequestHandler sub= e.nextElement();  | 
 | 
            sub.updateResult(result);  | 
 | 
        }  | 
 | 
 | 
 | 
        return result;  | 
 | 
    }  | 
 | 
 | 
 | 
    @Override  | 
 | 
    protected String makeDebugTag() { | 
 | 
        return "SnmpRequestHandler[" + adaptorServer.getProtocol() + ":" +  | 
 | 
            adaptorServer.getPort() + "]";  | 
 | 
    }  | 
 | 
 | 
 | 
    @Override  | 
 | 
    Thread createThread(Runnable r) { | 
 | 
        return null;  | 
 | 
    }  | 
 | 
 | 
 | 
    static final private String InterruptSysCallMsg =  | 
 | 
        "Interrupted system call";  | 
 | 
}  |