Source Code Cross Referenced for MPv3.java in  » Net » snmp4j » org » snmp4j » mp » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Net » snmp4j » org.snmp4j.mp 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*_############################################################################
0002:          _##
0003:          _##  SNMP4J - MPv3.java
0004:          _##
0005:          _##  Copyright (C) 2003-2008  Frank Fock and Jochen Katz (SNMP4J.org)
0006:          _##
0007:          _##  Licensed under the Apache License, Version 2.0 (the "License");
0008:          _##  you may not use this file except in compliance with the License.
0009:          _##  You may obtain a copy of the License at
0010:          _##
0011:          _##      http://www.apache.org/licenses/LICENSE-2.0
0012:          _##
0013:          _##  Unless required by applicable law or agreed to in writing, software
0014:          _##  distributed under the License is distributed on an "AS IS" BASIS,
0015:          _##  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0016:          _##  See the License for the specific language governing permissions and
0017:          _##  limitations under the License.
0018:          _##
0019:          _##########################################################################*/
0020:
0021:        package org.snmp4j.mp;
0022:
0023:        import java.io.*;
0024:        import java.net.*;
0025:        import java.nio.ByteBuffer;
0026:        import java.util.*;
0027:
0028:        import org.snmp4j.*;
0029:        import org.snmp4j.asn1.*;
0030:        import org.snmp4j.event.*;
0031:        import org.snmp4j.log.*;
0032:        import org.snmp4j.security.*;
0033:        import org.snmp4j.smi.*;
0034:        import org.snmp4j.util.PDUFactory;
0035:        import org.snmp4j.util.DefaultPDUFactory;
0036:
0037:        /**
0038:         * The <code>MPv3</code> is the message processing model for SNMPv3.
0039:         *
0040:         * @author Frank Fock
0041:         * @version 1.9.1
0042:         */
0043:        public class MPv3 implements  MessageProcessingModel {
0044:
0045:            public static final int ID = MessageProcessingModel.MPv3;
0046:            public static final int MPv3_REPORTABLE_FLAG = 4;
0047:            public static final int MAX_MESSAGE_ID = 2147483647;
0048:
0049:            public static final int MAXLEN_ENGINE_ID = 32;
0050:            public static final int MINLEN_ENGINE_ID = 5;
0051:
0052:            private static final int MAX_HEADER_PAYLOAD_LENGTH =
0053:            // length of msgFlags
0054:            new OctetString("\0").getBERLength() +
0055:            // length of msgID, msgMaxSize, securityModel
0056:                    3 * new Integer32(Integer.MAX_VALUE).getBERLength();
0057:
0058:            private static final int MAX_HEADER_LENGTH = MAX_HEADER_PAYLOAD_LENGTH
0059:                    + BER.getBERLengthOfLength(MAX_HEADER_PAYLOAD_LENGTH) + 1;
0060:
0061:            private SecurityProtocols securityProtocols;
0062:
0063:            private static final LogAdapter logger = LogFactory
0064:                    .getLogger(MPv3.class);
0065:            private SecurityModels securityModels;
0066:
0067:            private Cache cache;
0068:            private Hashtable engineIDs;
0069:            private byte[] localEngineID;
0070:
0071:            private int currentMsgID = new Random().nextInt(MAX_MESSAGE_ID);
0072:
0073:            // Enterprise ID of AGENT++
0074:            private static int enterpriseID = 4976;
0075:
0076:            private CounterSupport counterSupport;
0077:
0078:            transient Vector snmpEngineListeners;
0079:
0080:            protected PDUFactory incomingPDUFactory = new PDUFactory() {
0081:                public PDU createPDU(Target target) {
0082:                    return new ScopedPDU();
0083:                }
0084:            };
0085:
0086:            /**
0087:             * Creates a MPv3 with a default local engine ID.
0088:             */
0089:            public MPv3() {
0090:                this (createLocalEngineID(), null);
0091:            }
0092:
0093:            /**
0094:             * Creates a MPv3 with a supplied local engine ID.
0095:             * @param localEngineID
0096:             *    the local engine ID. Its length must be >= 5 and <= 32.
0097:             */
0098:            public MPv3(byte[] localEngineID) {
0099:                this (localEngineID, null);
0100:                setLocalEngineID(localEngineID);
0101:            }
0102:
0103:            /**
0104:             * Creates a MPv3 with a supplied local engine ID and {@link PDUFactory}
0105:             * for incoming messages.
0106:             * @param localEngineID
0107:             *    the local engine ID. Its length must be >= 5 and <= 32.
0108:             * @param incomingPDUFactory
0109:             *    a {@link PDUFactory}. If <code>null</code> the default factory will be
0110:             *    used which creates {@link ScopedPDU} instances.
0111:             * @since 1.9.1
0112:             */
0113:            public MPv3(byte[] localEngineID, PDUFactory incomingPDUFactory) {
0114:                if (incomingPDUFactory != null) {
0115:                    this .incomingPDUFactory = incomingPDUFactory;
0116:                }
0117:                engineIDs = new Hashtable();
0118:                cache = new Cache();
0119:                securityProtocols = SecurityProtocols.getInstance();
0120:                securityModels = SecurityModels.getInstance();
0121:                counterSupport = CounterSupport.getInstance();
0122:                setLocalEngineID(localEngineID);
0123:            }
0124:
0125:            /**
0126:             * Creates a local engine ID based on the local IP address.
0127:             * @return
0128:             *    a new local engine ID.
0129:             */
0130:            public static byte[] createLocalEngineID() {
0131:                byte[] engineID = new byte[5];
0132:                engineID[0] = (byte) (0x80 | ((enterpriseID >> 24) & 0xFF));
0133:                engineID[1] = (byte) ((enterpriseID >> 16) & 0xFF);
0134:                engineID[2] = (byte) ((enterpriseID >> 8) & 0xFF);
0135:                engineID[3] = (byte) (enterpriseID & 0xFF);
0136:                engineID[4] = 1;
0137:                OctetString os = new OctetString();
0138:                try {
0139:                    os.setValue(InetAddress.getLocalHost().getAddress());
0140:                } catch (UnknownHostException ex) {
0141:                    logger
0142:                            .debug("Local host cannot be determined for creation of local engine ID");
0143:                    engineID[4] = 4;
0144:                    os.setValue("SNMP4J".getBytes());
0145:                }
0146:                OctetString ownEngineID = new OctetString(engineID);
0147:                ownEngineID.append(os);
0148:                return ownEngineID.getValue();
0149:            }
0150:
0151:            /**
0152:             * Creates a local engine ID based on the ID string supplied
0153:             * @param id
0154:             *    an ID string.
0155:             * @return
0156:             *    a new local engine ID.
0157:             */
0158:            public static byte[] createLocalEngineID(OctetString id) {
0159:                byte[] engineID = new byte[5];
0160:                engineID[0] = (byte) (0x80 | ((enterpriseID >> 24) & 0xFF));
0161:                engineID[1] = (byte) ((enterpriseID >> 16) & 0xFF);
0162:                engineID[2] = (byte) ((enterpriseID >> 8) & 0xFF);
0163:                engineID[3] = (byte) (enterpriseID & 0xFF);
0164:                engineID[4] = 4;
0165:                OctetString ownEngineID = new OctetString(engineID);
0166:                ownEngineID.append(id);
0167:                return ownEngineID.getValue();
0168:            }
0169:
0170:            /**
0171:             * Sets the local engine ID. This value must not be changed after message
0172:             * processing has been started.
0173:             * @param engineID
0174:             *    the local engine ID. Its length must be >= 5 and <= 32.
0175:             */
0176:            public void setLocalEngineID(byte[] engineID) {
0177:                if ((engineID == null) || (engineID.length < MINLEN_ENGINE_ID)
0178:                        || (engineID.length > MAXLEN_ENGINE_ID)) {
0179:                    throw new IllegalArgumentException(
0180:                            "Illegal (local) engine ID");
0181:                }
0182:                this .localEngineID = engineID;
0183:            }
0184:
0185:            /**
0186:             * Gets a copy of the local engine ID.
0187:             * @return
0188:             *    a byte array containing the local engine ID.
0189:             */
0190:            public byte[] getLocalEngineID() {
0191:                byte[] retval = new byte[localEngineID.length];
0192:                System.arraycopy(localEngineID, 0, retval, 0,
0193:                        localEngineID.length);
0194:                return retval;
0195:            }
0196:
0197:            /**
0198:             * Creates and initializes the default security protocols.
0199:             * @see SecurityProtocols#addDefaultProtocols()
0200:             */
0201:            public void initDefaults() {
0202:                securityProtocols.addDefaultProtocols();
0203:            }
0204:
0205:            /**
0206:             * Gets an authentication protocol for the supplied ID.
0207:             * @param id
0208:             *    an authentication protocol OID.
0209:             * @return
0210:             *    an <code>AuthenticationProtocol</code> instance if the supplied ID
0211:             *    is supported, otherwise <code>null</code> is returned.
0212:             */
0213:            public AuthenticationProtocol getAuthProtocol(OID id) {
0214:                return securityProtocols.getAuthenticationProtocol(id);
0215:            }
0216:
0217:            /**
0218:             * Gets an privacy protocol for the supplied ID.
0219:             * @param id
0220:             *    an privacy protocol OID.
0221:             * @return
0222:             *    an <code>PrivacyProtocol</code> instance if the supplied ID
0223:             *    is supported, otherwise <code>null</code> is returned.
0224:             */
0225:            public PrivacyProtocol getPrivProtocol(OID id) {
0226:                return securityProtocols.getPrivacyProtocol(id);
0227:            }
0228:
0229:            /**
0230:             * Gets the security model for the supplied ID.
0231:             * @param id
0232:             *    a security model ID.
0233:             * @return
0234:             *    a <code>SecurityModel</code> instance if the supplied ID
0235:             *    is supported, otherwise <code>null</code> is returned.
0236:             */
0237:            public SecurityModel getSecurityModel(int id) {
0238:                return securityModels.getSecurityModel(new Integer32(id));
0239:            }
0240:
0241:            public int getID() {
0242:                return ID;
0243:            }
0244:
0245:            public boolean isProtocolVersionSupported(int version) {
0246:                return (version == SnmpConstants.version3);
0247:            }
0248:
0249:            /**
0250:             * Adds an engine ID (other than the local engine ID) to the internal storage.
0251:             * @param address
0252:             *    the <code>Address</code> of the remote SNMP engine.
0253:             * @param engineID
0254:             *    the engine ID of the remote SNMP engine.
0255:             * @return
0256:             *    <code>true</code> if the engine ID has been added, <code>false</code>
0257:             *    otherwise (if the supplied <code>engineID</code> equals the local one).
0258:             */
0259:            public boolean addEngineID(Address address, OctetString engineID) {
0260:                if (!Arrays.equals(this .localEngineID, engineID.getValue())) {
0261:                    engineIDs.put(address, engineID);
0262:                    if (snmpEngineListeners != null) {
0263:                        fireEngineChanged(new SnmpEngineEvent(this ,
0264:                                SnmpEngineEvent.ADDED_ENGINE_ID, engineID,
0265:                                address));
0266:                    }
0267:                    return true;
0268:                }
0269:                return false;
0270:            }
0271:
0272:            /**
0273:             * Gets the engine ID associated with the supplied address from the local
0274:             * storage and fires the corresponding {@link SnmpEngineEvent}.
0275:             * @param address
0276:             *    the <code>Address</code> of the remote SNMP engine.
0277:             * @return
0278:             *    the engine ID of the remote SNMP engine or <code>null</code> if there
0279:             *    is no entry for <code>address</code> in the local storage.
0280:             */
0281:            public OctetString getEngineID(Address address) {
0282:                return (OctetString) engineIDs.get(address);
0283:            }
0284:
0285:            /**
0286:             * Removes an engine ID association from the local storage and fires the
0287:             * corresponding {@link SnmpEngineEvent}.
0288:             * @param address
0289:             *    the <code>Address</code> of the remote SNMP engine for whose engine ID
0290:             *    is to be removed.
0291:             * @return
0292:             *    the removed engine ID of the remote SNMP engine or <code>null</code> if
0293:             *    there is no entry for <code>address</code> in the local storage.
0294:             */
0295:            public OctetString removeEngineID(Address address) {
0296:                OctetString engineID = (OctetString) engineIDs.remove(address);
0297:                if ((engineID != null) && (snmpEngineListeners != null)) {
0298:                    fireEngineChanged(new SnmpEngineEvent(this ,
0299:                            SnmpEngineEvent.REMOVED_ENGINE_ID, engineID,
0300:                            address));
0301:                }
0302:                return engineID;
0303:            }
0304:
0305:            /**
0306:             * The <code>CacheEntry</code> class holds state reference information
0307:             * for the MPv3 message processing model for a single message.
0308:             * @author Frank Fock
0309:             * @version 1.0
0310:             */
0311:            protected static class CacheEntry extends StateReference {
0312:                int msgID;
0313:                long transactionID;
0314:                byte[] secEngineID;
0315:                SecurityModel secModel;
0316:                byte[] secName;
0317:                int secLevel;
0318:                byte[] contextEngineID;
0319:                byte[] contextName;
0320:                SecurityStateReference secStateReference;
0321:                int errorCode;
0322:
0323:                public CacheEntry(int msgID, long reqID, byte[] secEngineID,
0324:                        SecurityModel secModel, byte[] secName, int secLevel,
0325:                        byte[] contextEngineID, byte[] contextName,
0326:                        SecurityStateReference secStateReference, int errorCode) {
0327:                    this .msgID = msgID;
0328:                    this .transactionID = reqID;
0329:                    this .secEngineID = secEngineID;
0330:                    this .secModel = secModel;
0331:                    this .secName = secName;
0332:                    this .secLevel = secLevel;
0333:                    this .contextEngineID = contextEngineID;
0334:                    this .contextName = contextName;
0335:                    this .secStateReference = secStateReference;
0336:                    this .errorCode = errorCode;
0337:                }
0338:            }
0339:
0340:            /**
0341:             * The <code>Cache</code> stores state reference information for the MPv3.
0342:             * @author Frank Fock
0343:             * @version 1.0
0344:             */
0345:            protected static class Cache {
0346:
0347:                private Map entries = new WeakHashMap(25);
0348:
0349:                /**
0350:                 * Adds a <code>StateReference</code> to the cache.
0351:                 * The <code>PduHandle</code> of the supplied entry will be set to
0352:                 * <code>null</code> while the entry is part of the cache, because the
0353:                 * cache uses a <code>WeakHashMap</code> internally which uses the
0354:                 * <code>PduHandle</code> as key. When
0355:                 * @param entry
0356:                 *    the state reference to add.
0357:                 * @return
0358:                 *    {@link SnmpConstants#SNMP_MP_DOUBLED_MESSAGE} if the entry already
0359:                 *    exists and {@link SnmpConstants#SNMP_MP_OK} on success.
0360:                 */
0361:                public synchronized int addEntry(StateReference entry) {
0362:                    if (logger.isDebugEnabled()) {
0363:                        logger.debug("Adding cache entry: " + entry);
0364:                    }
0365:                    StateReference existing = (StateReference) entries
0366:                            .get(entry.getPduHandle());
0367:                    if (existing != null) {
0368:                        if (existing.equals(entry)) {
0369:                            if (logger.isDebugEnabled()) {
0370:                                logger.debug("Doubled message: " + entry);
0371:                            }
0372:                            return SnmpConstants.SNMP_MP_DOUBLED_MESSAGE;
0373:                        }
0374:                    }
0375:                    // add it
0376:                    PduHandle key = entry.getPduHandle();
0377:                    // because we are using a weak has map for the cache, we need to null out
0378:                    // our key from the entry.
0379:                    entry.setPduHandle(null);
0380:                    entries.put(key, entry);
0381:                    return SnmpConstants.SNMP_MP_OK;
0382:                }
0383:
0384:                /**
0385:                 * Get the first cache entry with specified message ID.
0386:                 * @param msgID
0387:                 *    a message ID.
0388:                 * @return
0389:                 *    a <code>StateReference</code> instance with the given message ID or
0390:                 *    <code>null</code> if such an entry cannot be found.
0391:                 */
0392:                /*
0393:                 public StateReference getEntry(int msgID) {
0394:                 for (Iterator it = entries.iterator(); it.hasNext(); ) {
0395:                 StateReference e = (StateReference) it.next();
0396:                 if (e.getMsgID() == msgID) {
0397:                 return e;
0398:                 }
0399:                 }
0400:                 return null;
0401:                 }
0402:                 */
0403:                /**
0404:                 * Delete the cache entry with the supplied <code>PduHandle</code>.
0405:                 * @param pduHandle
0406:                 *    a pduHandle.
0407:                 * @return
0408:                 *    <code>true</code> if an entry has been deleted, <code>false</code>
0409:                 *    otherwise.
0410:                 */
0411:                public synchronized boolean deleteEntry(PduHandle pduHandle) {
0412:                    StateReference e = (StateReference) entries
0413:                            .remove(pduHandle);
0414:                    return (e != null);
0415:                }
0416:
0417:                /**
0418:                 * Pop the cache entry with the supplied ID from the cache.
0419:                 * @param msgID
0420:                 *    a message ID.
0421:                 * @return
0422:                 *    a <code>CacheEntry</code> instance with the given message ID or
0423:                 *    <code>null</code> if such an entry cannot be found. If a cache entry
0424:                 *   is returned, the same is removed from the cache.
0425:                 */
0426:                public synchronized StateReference popEntry(int msgID) {
0427:                    for (Iterator it = entries.keySet().iterator(); it
0428:                            .hasNext();) {
0429:                        PduHandle key = (PduHandle) it.next();
0430:                        StateReference e = (StateReference) entries.get(key);
0431:                        if ((e != null) && (e.getMsgID() == msgID)) {
0432:                            it.remove();
0433:                            e.setPduHandle(key);
0434:                            if (logger.isDebugEnabled()) {
0435:                                logger.debug("Removed cache entry: " + e);
0436:                            }
0437:                            return e;
0438:                        }
0439:                    }
0440:                    return null;
0441:                }
0442:            }
0443:
0444:            /**
0445:             * The <code>HeaderData</code> represents the message header information
0446:             * of SNMPv3 message.
0447:             * @author Frank Fock
0448:             * @version 1.0
0449:             */
0450:            protected static class HeaderData implements  BERSerializable {
0451:
0452:                public static final byte FLAG_AUTH = 0x01;
0453:                public static final byte FLAG_PRIV = 0x02;
0454:
0455:                Integer32 msgID = new Integer32(0);
0456:                Integer32 msgMaxSize = new Integer32(Integer.MAX_VALUE);
0457:                OctetString msgFlags = new OctetString(new byte[1]);
0458:                Integer32 securityModel = new Integer32(
0459:                        SecurityModel.SECURITY_MODEL_ANY);
0460:
0461:                public void setMsgID(int msgID) {
0462:                    this .msgID.setValue(msgID);
0463:                }
0464:
0465:                public int getMsgID() {
0466:                    return msgID.getValue();
0467:                }
0468:
0469:                public void setMsgMaxSize(int msgMaxSize) {
0470:                    this .msgMaxSize.setValue(msgMaxSize);
0471:                }
0472:
0473:                public int getMsgMaxSize() {
0474:                    return msgMaxSize.getValue();
0475:                }
0476:
0477:                public void setMsgFlags(int flags) {
0478:                    this .msgFlags.getValue()[0] = (byte) flags;
0479:                }
0480:
0481:                public int getMsgFlags() {
0482:                    return msgFlags.getValue()[0] & 0xFF;
0483:                }
0484:
0485:                public void setSecurityModel(int model) {
0486:                    securityModel.setValue(model);
0487:                }
0488:
0489:                public int getSecurityModel() {
0490:                    return securityModel.getValue();
0491:                }
0492:
0493:                public int getBERPayloadLength() {
0494:                    int length = msgID.getBERLength();
0495:                    length += msgMaxSize.getBERLength();
0496:                    length += msgFlags.getBERLength();
0497:                    length += securityModel.getBERLength();
0498:                    return length;
0499:                }
0500:
0501:                public int getBERLength() {
0502:                    int length = getBERPayloadLength();
0503:                    length += BER.getBERLengthOfLength(length) + 1;
0504:                    return length;
0505:                }
0506:
0507:                public void decodeBER(BERInputStream message)
0508:                        throws IOException {
0509:                    BER.MutableByte type = new BER.MutableByte();
0510:                    int length = BER.decodeHeader(message, type);
0511:                    if (type.getValue() != BER.SEQUENCE) {
0512:                        throw new IOException(
0513:                                "Unexpected sequence header type: "
0514:                                        + type.getValue());
0515:                    }
0516:                    msgID.decodeBER(message);
0517:                    msgMaxSize.decodeBER(message);
0518:                    if (msgMaxSize.getValue() < 484) {
0519:                        throw new IOException("Invalid msgMaxSize: "
0520:                                + msgMaxSize);
0521:                    }
0522:                    msgFlags.decodeBER(message);
0523:                    if (msgFlags.length() != 1) {
0524:                        throw new IOException("Message flags length != 1: "
0525:                                + msgFlags.length());
0526:                    }
0527:                    securityModel.decodeBER(message);
0528:                    if (logger.isDebugEnabled()) {
0529:                        logger.debug("SNMPv3 header decoded: msgId=" + msgID
0530:                                + ", msgMaxSize=" + msgMaxSize + ", msgFlags="
0531:                                + msgFlags.toHexString() + ", secModel="
0532:                                + securityModel);
0533:                    }
0534:                    BER.checkSequenceLength(length, this );
0535:                }
0536:
0537:                public void encodeBER(OutputStream outputStream)
0538:                        throws IOException {
0539:                    BER.encodeHeader(outputStream, BER.SEQUENCE,
0540:                            getBERPayloadLength());
0541:                    msgID.encodeBER(outputStream);
0542:                    msgMaxSize.encodeBER(outputStream);
0543:                    msgFlags.encodeBER(outputStream);
0544:                    securityModel.encodeBER(outputStream);
0545:                }
0546:            }
0547:
0548:            /**
0549:             * Gets unique message ID.
0550:             * @return
0551:             *    a message ID >= 1 and <= {@link #MAX_MESSAGE_ID}.
0552:             */
0553:            public synchronized int getNextMessageID() {
0554:                if (currentMsgID >= MAX_MESSAGE_ID) {
0555:                    currentMsgID = 1;
0556:                }
0557:                return currentMsgID++;
0558:            }
0559:
0560:            /**
0561:             * Gets the security protocols supported by this <code>MPv3</code>.
0562:             * @return
0563:             *    return a <code>SecurityProtocols</code>.
0564:             */
0565:            public SecurityProtocols getSecurityProtocols() {
0566:                return securityProtocols;
0567:            }
0568:
0569:            /**
0570:             * Sets the security protocols for this <code>MPv3</code>.
0571:             * @param securityProtocols SecurityProtocols
0572:             */
0573:            public void setSecurityProtocols(SecurityProtocols securityProtocols) {
0574:                this .securityProtocols = securityProtocols;
0575:            }
0576:
0577:            /**
0578:             * Gets the default security model to be used for engine ID discovery.
0579:             * @return
0580:             *    a security model ID.
0581:             * @see USM#getID()
0582:             */
0583:            protected int getDefaultSecurityModel() {
0584:                return SecurityModel.SECURITY_MODEL_USM;
0585:            }
0586:
0587:            public void releaseStateReference(PduHandle pduHandle) {
0588:                cache.deleteEntry(pduHandle);
0589:            }
0590:
0591:            public int prepareOutgoingMessage(Address transportAddress,
0592:                    int maxMessageSize, int messageProcessingModel,
0593:                    int securityModel, byte[] securityName, int securityLevel,
0594:                    PDU pdu, boolean expectResponse, PduHandle sendPduHandle,
0595:                    Address destTransportAddress,
0596:                    BEROutputStream outgoingMessage) throws IOException {
0597:                if (!(pdu instanceof  ScopedPDU)) {
0598:                    throw new IllegalArgumentException(
0599:                            "MPv3 only accepts ScopedPDU instances as pdu parameter");
0600:                }
0601:                ScopedPDU scopedPDU = (ScopedPDU) pdu;
0602:                // lookup engine ID
0603:                byte[] secEngineID = null;
0604:                OctetString securityEngineID = (OctetString) engineIDs
0605:                        .get(transportAddress);
0606:                if (securityEngineID != null) {
0607:                    secEngineID = securityEngineID.getValue();
0608:                    if (scopedPDU.getContextEngineID().length() == 0) {
0609:                        if (logger.isDebugEnabled()) {
0610:                            logger
0611:                                    .debug("Context engine ID of scoped PDU is empty! Setting it to authoritative engine ID: "
0612:                                            + securityEngineID.toHexString());
0613:                        }
0614:                        scopedPDU.setContextEngineID(new OctetString(
0615:                                secEngineID));
0616:                    }
0617:                } else {
0618:                    secEngineID = new byte[0];
0619:                }
0620:
0621:                // determine request type
0622:                if (pdu.isConfirmedPdu()) {
0623:                    if (secEngineID.length == 0) {
0624:                        securityLevel = SecurityLevel.NOAUTH_NOPRIV;
0625:                        securityModel = getDefaultSecurityModel();
0626:                        // do not send any management information
0627:                        scopedPDU = (ScopedPDU) scopedPDU.clone();
0628:                        scopedPDU.clear();
0629:                    }
0630:                } else {
0631:                    if (scopedPDU.getContextEngineID().length() == 0) {
0632:                        if (logger.isDebugEnabled()) {
0633:                            logger
0634:                                    .debug("Context engine ID of unconfirmed scoped PDU is empty! "
0635:                                            + "Setting it to local engine ID");
0636:                        }
0637:                        scopedPDU.setContextEngineID(new OctetString(
0638:                                localEngineID));
0639:                    }
0640:                }
0641:
0642:                // get length of scoped PDU
0643:                int scopedPDULength = pdu.getBERLength();
0644:                BEROutputStream scopedPdu = new BEROutputStream(ByteBuffer
0645:                        .allocate(scopedPDULength));
0646:
0647:                scopedPDU.encodeBER(scopedPdu);
0648:
0649:                HeaderData headerData = new HeaderData();
0650:                int flags = 0;
0651:                switch (securityLevel) {
0652:                case SecurityLevel.NOAUTH_NOPRIV:
0653:                    flags = 0;
0654:                    break;
0655:                case SecurityLevel.AUTH_NOPRIV:
0656:                    flags = 1;
0657:                    break;
0658:                case SecurityLevel.AUTH_PRIV:
0659:                    flags = 3;
0660:                    break;
0661:                }
0662:                if (scopedPDU.isConfirmedPdu()) {
0663:                    flags |= MPv3_REPORTABLE_FLAG;
0664:                } else {
0665:                    secEngineID = localEngineID;
0666:                }
0667:
0668:                int msgID = getNextMessageID();
0669:                headerData.setMsgFlags(flags);
0670:                headerData.setMsgID(msgID);
0671:                headerData.setMsgMaxSize(maxMessageSize);
0672:                headerData.setSecurityModel(securityModel);
0673:
0674:                ByteBuffer globalDataBuffer = ByteBuffer.allocate(headerData
0675:                        .getBERLength());
0676:                BEROutputStream globalDataOutputStream = new BEROutputStream(
0677:                        globalDataBuffer);
0678:                headerData.encodeBER(globalDataOutputStream);
0679:
0680:                BERInputStream scopedPDUInput = new BERInputStream(scopedPdu
0681:                        .rewind());
0682:
0683:                SecurityModel secModel = securityModels
0684:                        .getSecurityModel(new Integer32(securityModel));
0685:                if (secModel == null) {
0686:                    return SnmpConstants.SNMP_MP_UNSUPPORTED_SECURITY_MODEL;
0687:                }
0688:                // output data
0689:                SecurityParameters securityParameters = secModel
0690:                        .newSecurityParametersInstance();
0691:
0692:                int status = secModel.generateRequestMessage(
0693:                        messageProcessingModel, globalDataBuffer.array(),
0694:                        maxMessageSize, securityModel, secEngineID,
0695:                        securityName, securityLevel, scopedPDUInput,
0696:                        securityParameters, outgoingMessage);
0697:                if (status == SnmpConstants.SNMPv3_USM_OK) {
0698:                    if (expectResponse) {
0699:                        cache.addEntry(new StateReference(msgID, flags,
0700:                                maxMessageSize, sendPduHandle,
0701:                                transportAddress, null, secEngineID, secModel,
0702:                                securityName, securityLevel, scopedPDU
0703:                                        .getContextEngineID().getValue(),
0704:                                scopedPDU.getContextName().getValue(), null,
0705:                                status));
0706:                    }
0707:                }
0708:                return status;
0709:            }
0710:
0711:            public int prepareResponseMessage(int messageProcessingModel,
0712:                    int maxMessageSize, int securityModel, byte[] securityName,
0713:                    int securityLevel, PDU pdu, int maxSizeResponseScopedPDU,
0714:                    StateReference stateReference,
0715:                    StatusInformation statusInformation,
0716:                    BEROutputStream outgoingMessage) throws IOException {
0717:                /** Leave entry in cache or remove it? RFC3414 §3.1.a.1 says discard it*/
0718:                StateReference cacheEntry = cache.popEntry(stateReference
0719:                        .getMsgID());
0720:                if (cacheEntry == null) {
0721:                    return SnmpConstants.SNMP_MP_UNKNOWN_MSGID;
0722:                }
0723:
0724:                // get length of scoped PDU
0725:                // get length of scoped PDU
0726:                int scopedPDULength = pdu.getBERLength();
0727:                BEROutputStream scopedPDU;
0728:                // check length
0729:                if (scopedPDULength > maxSizeResponseScopedPDU) {
0730:                    PDU tooBigPDU = new ScopedPDU((ScopedPDU) pdu);
0731:                    tooBigPDU.clear();
0732:                    tooBigPDU.setRequestID(pdu.getRequestID());
0733:                    tooBigPDU.setErrorStatus(SnmpConstants.SNMP_ERROR_TOO_BIG);
0734:                    tooBigPDU.setErrorIndex(0);
0735:                    scopedPDULength = tooBigPDU.getBERLength();
0736:                    scopedPDU = new BEROutputStream(ByteBuffer
0737:                            .allocate(scopedPDULength));
0738:                    tooBigPDU.encodeBER(scopedPDU);
0739:                } else {
0740:                    scopedPDU = new BEROutputStream(ByteBuffer
0741:                            .allocate(scopedPDULength));
0742:                    pdu.encodeBER(scopedPDU);
0743:                }
0744:
0745:                HeaderData headerData = new HeaderData();
0746:                int flags = 0;
0747:                switch (securityLevel) {
0748:                case SecurityLevel.NOAUTH_NOPRIV:
0749:                    flags = 0;
0750:                    break;
0751:                case SecurityLevel.AUTH_NOPRIV:
0752:                    flags = 1;
0753:                    break;
0754:                case SecurityLevel.AUTH_PRIV:
0755:                    flags = 3;
0756:                    break;
0757:                }
0758:                // response message is not reportable
0759:                headerData.setMsgFlags(flags);
0760:                headerData.setMsgID(stateReference.getMsgID());
0761:                headerData.setMsgMaxSize(maxMessageSize);
0762:                headerData.setSecurityModel(securityModel);
0763:
0764:                ByteBuffer globalDataBuffer = ByteBuffer.allocate(headerData
0765:                        .getBERLength());
0766:                BEROutputStream globalDataOutputStream = new BEROutputStream(
0767:                        globalDataBuffer);
0768:                headerData.encodeBER(globalDataOutputStream);
0769:
0770:                OctetString securityEngineID;
0771:                switch (pdu.getType()) {
0772:                case PDU.RESPONSE:
0773:                case PDU.TRAP:
0774:                case PDU.REPORT:
0775:                case PDU.V1TRAP:
0776:                    securityEngineID = new OctetString(localEngineID);
0777:                    break;
0778:                default:
0779:                    securityEngineID = new OctetString(cacheEntry
0780:                            .getSecurityEngineID());
0781:                }
0782:
0783:                BERInputStream scopedPDUInput = new BERInputStream(scopedPDU
0784:                        .rewind());
0785:
0786:                SecurityModel secModel = securityModels
0787:                        .getSecurityModel(new Integer32(securityModel));
0788:                // output data
0789:                SecurityParameters securityParameters = secModel
0790:                        .newSecurityParametersInstance();
0791:
0792:                int status = secModel.generateResponseMessage(getID(),
0793:                        globalDataBuffer.array(), maxMessageSize,
0794:                        securityModel, securityEngineID.getValue(),
0795:                        securityName, securityLevel, scopedPDUInput, cacheEntry
0796:                                .getSecurityStateReference(),
0797:                        securityParameters, outgoingMessage);
0798:                return status;
0799:            }
0800:
0801:            /**
0802:             * Sends a report message.
0803:             * @param messageDispatcher
0804:             *    Send the message on behalf the supplied MessageDispatcher instance.
0805:             * @param pdu ScopedPDU
0806:             *    If <code>null</code>, then contextEngineID, contextName, and requestID
0807:             *    of the report generated will be zero length and zero respective.
0808:             *    Otherwise these values are extracted from the PDU.
0809:             * @param securityLevel
0810:             *    The security level to use when sending this report.
0811:             * @param securityModel
0812:             *    The security model to use when sending this report.
0813:             * @param securityName
0814:             *    The security name to use when sending this report.
0815:             * @param maxSizeResponseScopedPDU
0816:             *    the maximum size of of the report message (will be most likely ignored
0817:             *    because a report should always fit in 484  bytes).
0818:             * @param payload
0819:             *    the variable binding to include in the report message.
0820:             * @param stateReference
0821:             *    the state reference associated with the original message.
0822:             * @return
0823:             *    an SNMP MPv3 error code or 0 if the report has been send successfully.
0824:             */
0825:            public int sendReport(MessageDispatcher messageDispatcher,
0826:                    ScopedPDU pdu, int securityLevel, int securityModel,
0827:                    OctetString securityName, int maxSizeResponseScopedPDU,
0828:                    StateReference stateReference, VariableBinding payload) {
0829:                ScopedPDU reportPDU = new ScopedPDU();
0830:                reportPDU.setType(PDU.REPORT);
0831:                if (pdu != null) {
0832:                    reportPDU.setContextEngineID(pdu.getContextEngineID());
0833:                    reportPDU.setContextName(pdu.getContextName());
0834:                    reportPDU.setRequestID(pdu.getRequestID());
0835:                }
0836:                reportPDU.add(payload);
0837:                StatusInformation statusInformation = new StatusInformation();
0838:                try {
0839:                    int status = messageDispatcher.returnResponsePdu(getID(),
0840:                            securityModel, securityName.getValue(),
0841:                            securityLevel, reportPDU, maxSizeResponseScopedPDU,
0842:                            stateReference, statusInformation);
0843:                    if (status != SnmpConstants.SNMP_ERROR_SUCCESS) {
0844:                        logger.warn("Error while sending report: " + status);
0845:                        return SnmpConstants.SNMP_MP_ERROR;
0846:                    }
0847:                } catch (MessageException mex) {
0848:                    logger.error("Error while sending report: "
0849:                            + mex.getMessage());
0850:                    return SnmpConstants.SNMP_MP_ERROR;
0851:                }
0852:                return SnmpConstants.SNMP_MP_OK;
0853:            }
0854:
0855:            public int prepareDataElements(MessageDispatcher messageDispatcher,
0856:                    Address transportAddress, BERInputStream wholeMsg,
0857:                    Integer32 messageProcessingModel, Integer32 securityModel,
0858:                    OctetString securityName, Integer32 securityLevel,
0859:                    MutablePDU pdu, PduHandle sendPduHandle,
0860:                    Integer32 maxSizeResponseScopedPDU,
0861:                    StatusInformation statusInformation,
0862:                    MutableStateReference mutableStateReference) {
0863:                try {
0864:                    StateReference stateReference = new StateReference();
0865:                    // check if there is transport mapping information
0866:                    if (mutableStateReference.getStateReference() != null) {
0867:                        stateReference
0868:                                .setTransportMapping(mutableStateReference
0869:                                        .getStateReference()
0870:                                        .getTransportMapping());
0871:                    }
0872:                    messageProcessingModel.setValue(MPv3);
0873:                    wholeMsg.mark(16);
0874:
0875:                    BER.MutableByte type = new BER.MutableByte();
0876:                    int length = BER.decodeHeader(wholeMsg, type);
0877:                    if (type.getValue() != BER.SEQUENCE) {
0878:                        return SnmpConstants.SNMP_MP_PARSE_ERROR;
0879:                    }
0880:                    long lengthOfLength = wholeMsg.getPosition();
0881:                    wholeMsg.reset();
0882:                    wholeMsg.mark(length);
0883:                    if (wholeMsg.skip(lengthOfLength) != lengthOfLength) {
0884:                        return SnmpConstants.SNMP_MP_PARSE_ERROR;
0885:                    }
0886:
0887:                    Integer32 snmpVersion = new Integer32();
0888:                    snmpVersion.decodeBER(wholeMsg);
0889:                    if (snmpVersion.getValue() != SnmpConstants.version3) {
0890:                        // internal error -> should not happen
0891:                        throw new RuntimeException(
0892:                                "Internal error unexpected snmp version read");
0893:                    }
0894:                    // decode SNMPv3 header
0895:                    HeaderData header = new HeaderData();
0896:                    header.decodeBER(wholeMsg);
0897:                    securityModel.setValue(header.getSecurityModel());
0898:
0899:                    stateReference.setMsgID(header.getMsgID());
0900:                    stateReference.setMsgFlags(header.getMsgFlags());
0901:                    stateReference.setAddress(transportAddress);
0902:
0903:                    mutableStateReference.setStateReference(stateReference);
0904:
0905:                    // the usm has to recalculate this value
0906:                    maxSizeResponseScopedPDU.setValue(header.msgMaxSize
0907:                            .getValue()
0908:                            - MAX_HEADER_LENGTH);
0909:
0910:                    ScopedPDU scopedPdu = new ScopedPDU();
0911:                    pdu.setPdu(scopedPdu);
0912:
0913:                    SecurityModel secModel = securityModels
0914:                            .getSecurityModel(securityModel);
0915:                    if (secModel == null) {
0916:                        logger
0917:                                .error("RFC3412 §7.2.4 - Unsupported security model: "
0918:                                        + securityModel);
0919:                        CounterEvent event = new CounterEvent(this ,
0920:                                SnmpConstants.snmpUnknownSecurityModels);
0921:                        fireIncrementCounter(event);
0922:                        return SnmpConstants.SNMP_MP_UNSUPPORTED_SECURITY_MODEL;
0923:                    }
0924:
0925:                    // determine security level
0926:                    switch (header.getMsgFlags() & 0x03) {
0927:                    case 3: {
0928:                        securityLevel.setValue(SecurityLevel.AUTH_PRIV);
0929:                        break;
0930:                    }
0931:                    case 0: {
0932:                        securityLevel.setValue(SecurityLevel.NOAUTH_NOPRIV);
0933:                        break;
0934:                    }
0935:                    case 1: {
0936:                        securityLevel.setValue(SecurityLevel.AUTH_NOPRIV);
0937:                        break;
0938:                    }
0939:                    default: {
0940:                        securityLevel.setValue(SecurityLevel.NOAUTH_NOPRIV);
0941:                        logger
0942:                                .debug("RFC3412 §7.2.5 - Invalid message (illegal msgFlags)");
0943:                        CounterEvent event = new CounterEvent(this ,
0944:                                SnmpConstants.snmpInvalidMsgs);
0945:                        fireIncrementCounter(event);
0946:                        // do not send back report
0947:                        return SnmpConstants.SNMP_MP_INVALID_MESSAGE;
0948:                    }
0949:                    }
0950:
0951:                    int secParametersPosition = (int) wholeMsg.getPosition();
0952:                    // get security parameters
0953:                    SecurityParameters secParameters = secModel
0954:                            .newSecurityParametersInstance();
0955:                    secParameters.decodeBER(wholeMsg);
0956:                    secParameters
0957:                            .setSecurityParametersPosition(secParametersPosition);
0958:
0959:                    // reportable flag
0960:                    boolean reportableFlag = ((header.getMsgFlags() & 0x04) > 0);
0961:
0962:                    OctetString securityEngineID = new OctetString();
0963:                    // create a new security state reference
0964:                    SecurityStateReference secStateReference = secModel
0965:                            .newSecurityStateReference();
0966:                    // create output stream for scoped PDU
0967:                    // may be optimized by an output stream that maps directly into the
0968:                    // original input
0969:                    wholeMsg.reset();
0970:
0971:                    BEROutputStream scopedPDU = new BEROutputStream();
0972:                    int status = secModel.processIncomingMsg(snmpVersion
0973:                            .getValue(), header.getMsgMaxSize()
0974:                            - MAX_HEADER_LENGTH, secParameters, secModel,
0975:                            securityLevel.getValue(),
0976:                            wholeMsg,
0977:                            // output parameters
0978:                            securityEngineID, securityName, scopedPDU,
0979:                            maxSizeResponseScopedPDU, secStateReference,
0980:                            statusInformation);
0981:                    wholeMsg.close();
0982:                    if (status == SnmpConstants.SNMPv3_USM_OK) {
0983:                        try {
0984:                            BERInputStream scopedPduStream = new BERInputStream(
0985:                                    scopedPDU.rewind());
0986:                            scopedPdu.decodeBER(scopedPduStream);
0987:                            sendPduHandle.setTransactionID(scopedPdu
0988:                                    .getRequestID().getValue());
0989:
0990:                            // add the engine ID to the local cache.
0991:                            addEngineID(transportAddress, securityEngineID);
0992:                        } catch (IOException iox) {
0993:                            logger.warn("ASN.1 parse error: "
0994:                                    + iox.getMessage());
0995:                            if (logger.isDebugEnabled()) {
0996:                                iox.printStackTrace();
0997:                            }
0998:                            CounterEvent event = new CounterEvent(this ,
0999:                                    SnmpConstants.snmpInASNParseErrs);
1000:                            fireIncrementCounter(event);
1001:                            return SnmpConstants.SNMP_MP_PARSE_ERROR;
1002:                        }
1003:                        if (((scopedPdu.getContextEngineID() == null) || (scopedPdu
1004:                                .getContextEngineID().length() == 0))
1005:                                && ((scopedPdu.getType() != PDU.RESPONSE) && (scopedPdu
1006:                                        .getType() != PDU.REPORT))) {
1007:                            CounterEvent event = new CounterEvent(this ,
1008:                                    SnmpConstants.snmpUnknownPDUHandlers);
1009:                            fireIncrementCounter(event);
1010:                            VariableBinding errorIndication = new VariableBinding(
1011:                                    event.getOid(), event.getCurrentValue());
1012:                            statusInformation
1013:                                    .setErrorIndication(errorIndication);
1014:                            status = SnmpConstants.SNMP_MP_UNKNOWN_PDU_HANDLERS;
1015:                        }
1016:                    }
1017:
1018:                    if (status != SnmpConstants.SNMPv3_USM_OK) {
1019:                        if ((reportableFlag)
1020:                                && (statusInformation.getErrorIndication() != null)) {
1021:                            // RFC3412 §7.2.6.a - generate a report
1022:                            try {
1023:                                if (scopedPDU.getBuffer() != null) {
1024:                                    BERInputStream scopedPduStream = new BERInputStream(
1025:                                            scopedPDU.rewind());
1026:                                    scopedPdu.decodeBER(scopedPduStream);
1027:                                } else { // incoming message could not be decoded
1028:                                    scopedPdu = null;
1029:                                }
1030:                            } catch (IOException iox) {
1031:                                logger.warn(iox);
1032:                                scopedPdu = null;
1033:                            }
1034:
1035:                            StateReference cacheEntry = new StateReference(
1036:                                    header.getMsgID(), header.getMsgFlags(),
1037:                                    maxSizeResponseScopedPDU.getValue(),
1038:                                    sendPduHandle, transportAddress, null,
1039:                                    securityEngineID.getValue(), secModel,
1040:                                    securityName.getValue(), securityLevel
1041:                                            .getValue(),
1042:                                    (scopedPdu == null) ? new byte[0]
1043:                                            : scopedPdu.getContextEngineID()
1044:                                                    .getValue(),
1045:                                    (scopedPdu == null) ? new byte[0]
1046:                                            : scopedPdu.getContextName()
1047:                                                    .getValue(),
1048:                                    secStateReference, status);
1049:                            cache.addEntry(cacheEntry);
1050:
1051:                            int reportStatus = sendReport(messageDispatcher,
1052:                                    scopedPdu, statusInformation
1053:                                            .getSecurityLevel().getValue(),
1054:                                    secModel.getID(), securityName,
1055:                                    maxSizeResponseScopedPDU.getValue(),
1056:                                    stateReference, statusInformation
1057:                                            .getErrorIndication());
1058:                            if (reportStatus != SnmpConstants.SNMP_MP_OK) {
1059:                                logger
1060:                                        .warn("Sending report failed with error code: "
1061:                                                + reportStatus);
1062:                            }
1063:                        }
1064:                        return SnmpConstants.SNMP_MP_USM_ERROR;
1065:                    }
1066:
1067:                    stateReference.setAddress(transportAddress);
1068:                    stateReference.setSecurityName(securityName.getValue());
1069:                    stateReference.setContextEngineID(scopedPdu
1070:                            .getContextEngineID().getValue());
1071:                    stateReference.setContextName(scopedPdu.getContextName()
1072:                            .getValue());
1073:                    stateReference
1074:                            .setMaxSizeResponseScopedPDU(maxSizeResponseScopedPDU
1075:                                    .getValue());
1076:                    stateReference.setMsgID(header.getMsgID());
1077:                    stateReference.setMsgFlags(header.getMsgFlags());
1078:                    stateReference.setSecurityEngineID(securityEngineID
1079:                            .getValue());
1080:                    stateReference.setSecurityLevel(securityLevel.getValue());
1081:                    stateReference.setSecurityModel(secModel);
1082:                    stateReference.setSecurityStateReference(secStateReference);
1083:                    stateReference.setPduHandle(sendPduHandle);
1084:
1085:                    if ((scopedPdu.getType() == PDU.RESPONSE)
1086:                            || (scopedPdu.getType() == PDU.REPORT)) {
1087:                        StateReference cacheEntry = cache.popEntry(header
1088:                                .getMsgID());
1089:                        if (cacheEntry != null) {
1090:                            if (logger.isDebugEnabled()) {
1091:                                logger
1092:                                        .debug("RFC3412 §7.2.10 - Received PDU (msgID="
1093:                                                + header.getMsgID()
1094:                                                + ") is a response or "
1095:                                                + "an internal class message. PduHandle.transactionID = "
1096:                                                + cacheEntry.getPduHandle()
1097:                                                        .getTransactionID());
1098:                            }
1099:                            sendPduHandle.copyFrom(cacheEntry.getPduHandle());
1100:
1101:                            if (scopedPdu.getType() == PDU.REPORT) {
1102:
1103:                                statusInformation.setContextEngineID(scopedPdu
1104:                                        .getContextEngineID().getValue());
1105:                                statusInformation.setContextName(scopedPdu
1106:                                        .getContextName().getValue());
1107:                                statusInformation
1108:                                        .setSecurityLevel(securityLevel);
1109:
1110:                                if (((cacheEntry.getSecurityEngineID().length != 0) && (!securityEngineID
1111:                                        .equals(cacheEntry
1112:                                                .getSecurityEngineID())))
1113:                                        || (secModel.getID() != cacheEntry
1114:                                                .getSecurityModel().getID())
1115:                                        || ((!securityName.equals(cacheEntry
1116:                                                .getSecurityName()) && (securityName
1117:                                                .length() != 0)))) {
1118:                                    if (logger.isDebugEnabled()) {
1119:                                        logger
1120:                                                .debug("RFC 3412 §7.2.11 - Received report message does not match sent message");
1121:                                    }
1122:                                    //cache.deleteEntry(cacheEntry.getPduHandle());
1123:                                    mutableStateReference
1124:                                            .setStateReference(null);
1125:                                    return SnmpConstants.SNMP_MP_MATCH_ERROR;
1126:                                }
1127:                                if (!addEngineID(cacheEntry.getAddress(),
1128:                                        securityEngineID)) {
1129:                                    if (logger.isWarnEnabled()) {
1130:                                        logger
1131:                                                .warn("Engine ID '"
1132:                                                        + securityEngineID
1133:                                                        + "' could not be added to engine ID cache for "
1134:                                                        + "target address '"
1135:                                                        + cacheEntry
1136:                                                                .getAddress()
1137:                                                        + "' because engine ID matches local engine ID");
1138:                                    }
1139:                                }
1140:                                //cache.deleteEntry(cacheEntry.getPduHandle());
1141:                                mutableStateReference.setStateReference(null);
1142:                                logger.debug("MPv3 finished");
1143:                                return SnmpConstants.SNMP_MP_OK;
1144:                            }
1145:                            if (scopedPdu.getType() == PDU.RESPONSE) {
1146:                                if (((!securityEngineID.equals(cacheEntry
1147:                                        .getSecurityEngineID())) && (cacheEntry
1148:                                        .getSecurityEngineID().length != 0))
1149:                                        || (secModel.getID() != cacheEntry
1150:                                                .getSecurityModel().getID())
1151:                                        || (!securityName.equals(cacheEntry
1152:                                                .getSecurityName()))
1153:                                        || (securityLevel.getValue() != cacheEntry
1154:                                                .getSecurityLevel())
1155:                                        || ((!scopedPdu
1156:                                                .getContextEngineID()
1157:                                                .equals(
1158:                                                        cacheEntry
1159:                                                                .getContextEngineID())) && (cacheEntry
1160:                                                .getContextEngineID().length != 0))
1161:                                        || ((!scopedPdu
1162:                                                .getContextName()
1163:                                                .equals(
1164:                                                        cacheEntry
1165:                                                                .getContextName()) && (cacheEntry
1166:                                                .getContextName().length != 0)))) {
1167:                                    logger
1168:                                            .debug("RFC 3412 §7.2.12.b - Received response message does not match sent message");
1169:                                    //cache.deleteEntry(cacheEntry.getPduHandle());
1170:                                    mutableStateReference
1171:                                            .setStateReference(null);
1172:                                    return SnmpConstants.SNMP_MP_MATCH_ERROR;
1173:                                }
1174:                                //cache.deleteEntry(cacheEntry.getPduHandle());
1175:                                mutableStateReference.setStateReference(null);
1176:                                logger.debug("MPv3 finished");
1177:                                return SnmpConstants.SNMP_MP_OK;
1178:                            }
1179:                        } else {
1180:                            if (logger.isDebugEnabled()) {
1181:                                logger
1182:                                        .debug("RFC3412 §7.2.10 - Received PDU (msgID="
1183:                                                + header.getMsgID()
1184:                                                + ") is a response or "
1185:                                                + "internal class message, but cached "
1186:                                                + "information for the msgID could not be found");
1187:                            }
1188:                            return SnmpConstants.SNMP_MP_UNKNOWN_MSGID;
1189:                        }
1190:                    } else {
1191:                        logger
1192:                                .debug("RFC3412 §7.2.10 - Received PDU is NOT a response or "
1193:                                        + "internal class message -> unchanged PduHandle = "
1194:                                        + sendPduHandle);
1195:                    }
1196:                    switch (scopedPdu.getType()) {
1197:                    case PDU.GET:
1198:                    case PDU.GETBULK:
1199:                    case PDU.GETNEXT:
1200:                    case PDU.INFORM:
1201:                    case PDU.SET: {
1202:                        if (securityEngineID.length() == 0) {
1203:                            logger
1204:                                    .debug("Received confirmed message with 0 length security engine ID");
1205:                        } else if (!securityEngineID.equals(localEngineID)) {
1206:                            if (logger.isDebugEnabled()) {
1207:                                logger
1208:                                        .debug("RFC 3412 §7.2.13.a - Security engine ID "
1209:                                                + securityEngineID
1210:                                                        .toHexString()
1211:                                                + " does not match local engine ID "
1212:                                                + new OctetString(localEngineID)
1213:                                                        .toHexString());
1214:                            }
1215:                            mutableStateReference.setStateReference(null);
1216:                            return SnmpConstants.SNMP_MP_INVALID_ENGINEID;
1217:                        }
1218:                        int cacheStatus = cache.addEntry(stateReference);
1219:                        if (cacheStatus == SnmpConstants.SNMP_MP_DOUBLED_MESSAGE) {
1220:                            mutableStateReference.setStateReference(null);
1221:                        }
1222:                        return SnmpConstants.SNMP_MP_OK;
1223:                    }
1224:                    case PDU.TRAP:
1225:                    case PDU.V1TRAP: {
1226:                        mutableStateReference.setStateReference(null);
1227:                        return SnmpConstants.SNMP_MP_OK;
1228:                    }
1229:                    }
1230:                    // this line should not be reached
1231:                    return SnmpConstants.SNMP_MP_ERROR;
1232:                } catch (IOException iox) {
1233:                    logger.warn("MPv3 parse error: " + iox.getMessage());
1234:                    if (logger.isDebugEnabled()) {
1235:                        iox.printStackTrace();
1236:                    }
1237:                    return SnmpConstants.SNMP_MP_PARSE_ERROR;
1238:                }
1239:            }
1240:
1241:            /**
1242:             * Sets the security models supported by this MPv3.
1243:             * @param securityModels
1244:             *    a <code>SecurityModels</code> instance.
1245:             */
1246:            public void setSecurityModels(SecurityModels securityModels) {
1247:                this .securityModels = securityModels;
1248:            }
1249:
1250:            /**
1251:             * Gets the security models supported by this MPv3.
1252:             * @return
1253:             *   a <code>SecurityModels</code> instance.
1254:             */
1255:            public SecurityModels getSecurityModels() {
1256:                return securityModels;
1257:            }
1258:
1259:            /**
1260:             * Gets the enterprise ID used for creating the local engine ID.
1261:             * @return
1262:             *    an enterprise ID as registered by the IANA (see http://www.iana.org).
1263:             */
1264:            public static int getEnterpriseID() {
1265:                return enterpriseID;
1266:            }
1267:
1268:            /**
1269:             * Sets the IANA enterprise ID to be used for creating local engine ID by
1270:             * {@link #createLocalEngineID()}.
1271:             * @param newEnterpriseID
1272:             *    an enterprise ID as registered by the IANA (see http://www.iana.org).
1273:             */
1274:            public static void setEnterpriseID(int newEnterpriseID) {
1275:                enterpriseID = newEnterpriseID;
1276:            }
1277:
1278:            /**
1279:             * Fire a counter incrementation event.
1280:             * @param e CounterEvent
1281:             */
1282:            protected void fireIncrementCounter(CounterEvent e) {
1283:                counterSupport.fireIncrementCounter(e);
1284:            }
1285:
1286:            /**
1287:             * Gets the counter support instance that can be used to register for
1288:             * counter incremnetation events.
1289:             * @return
1290:             *    a <code>CounterSupport</code> instance that is used to fire
1291:             *    {@link CounterEvent}.
1292:             */
1293:            public CounterSupport getCounterSupport() {
1294:                return counterSupport;
1295:            }
1296:
1297:            /**
1298:             * Sets the counter support instance. By default, the singleton instance
1299:             * provided by the {@link CounterSupport} instance is used.
1300:             * @param counterSupport
1301:             *    a <code>CounterSupport</code> subclass instance.
1302:             */
1303:            public void setCounterSupport(CounterSupport counterSupport) {
1304:                if (counterSupport == null) {
1305:                    throw new NullPointerException();
1306:                }
1307:                this .counterSupport = counterSupport;
1308:            }
1309:
1310:            /**
1311:             * Adds a SNMP engine listener that needs to be informed about changes to
1312:             * the engine ID cache.
1313:             * @param l
1314:             *    a <code>SnmpEngineListener</code> instance.
1315:             * @since 1.6
1316:             */
1317:            public synchronized void addSnmpEngineListener(SnmpEngineListener l) {
1318:                if (snmpEngineListeners == null) {
1319:                    snmpEngineListeners = new Vector();
1320:                }
1321:                snmpEngineListeners.add(l);
1322:            }
1323:
1324:            /**
1325:             * Removes a SNMP engine listener.
1326:             * @param l
1327:             *    a <code>SnmpEngineListener</code> instance.
1328:             * @since 1.6
1329:             */
1330:            public synchronized void removeSnmpEngineListener(
1331:                    SnmpEngineListener l) {
1332:                if (snmpEngineListeners != null) {
1333:                    snmpEngineListeners.remove(l);
1334:                }
1335:            }
1336:
1337:            /**
1338:             * Creates a PDU class that is used to parse incoming SNMP messages.
1339:             * @param target
1340:             *    the <code>target</code> parameter must be ignored.
1341:             * @return
1342:             *    a {@link ScopedPDU} instance by default.
1343:             * @since 1.9.1
1344:             */
1345:            public PDU createPDU(Target target) {
1346:                return new ScopedPDU();
1347:            }
1348:
1349:            /**
1350:             * Fires a SNMP engine event the registered listeners.
1351:             * @param engineEvent
1352:             *    the <code>SnmpEngineEvent</code> instance to fire.
1353:             * @since 1.6
1354:             */
1355:            protected void fireEngineChanged(SnmpEngineEvent engineEvent) {
1356:                if (snmpEngineListeners != null) {
1357:                    Vector listeners = snmpEngineListeners;
1358:                    int count = listeners.size();
1359:                    for (int i = 0; i < count; i++) {
1360:                        ((SnmpEngineListener) listeners.elementAt(i))
1361:                                .engineChanged(engineEvent);
1362:                    }
1363:                }
1364:            }
1365:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.