View Javadoc
1   // NAME
2   //      $RCSfile: SnmpContextv2c.java,v $
3   // DESCRIPTION
4   //      [given below in javadoc format]
5   // DELTA
6   //      $Revision: 3.16 $
7   // CREATED
8   //      $Date: 2009/03/05 12:54:04 $
9   // COPYRIGHT
10  //      Westhawk Ltd
11  // TO DO
12  //
13  
14  /*
15   * Copyright (C) 2001 - 2006 by Westhawk Ltd
16   * <a href="www.westhawk.co.uk">www.westhawk.co.uk</a>
17   *
18   * Permission to use, copy, modify, and distribute this software
19   * for any purpose and without fee is hereby granted, provided
20   * that the above copyright notices appear in all copies and that
21   * both the copyright notice and this permission notice appear in
22   * supporting documentation.
23   * This software is provided "as is" without express or implied
24   * warranty.
25   * author <a href="mailto:snmp@westhawk.co.uk">Tim Panton</a>
26   */
27  
28  package uk.co.westhawk.snmp.stack;
29  
30  /*-
31   * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲
32   * SNMP Java Client
33   * ჻჻჻჻჻჻
34   * Copyright 2023 MetricsHub, Westhawk
35   * ჻჻჻჻჻჻
36   * This program is free software: you can redistribute it and/or modify
37   * it under the terms of the GNU Lesser General Public License as
38   * published by the Free Software Foundation, either version 3 of the
39   * License, or (at your option) any later version.
40   *
41   * This program is distributed in the hope that it will be useful,
42   * but WITHOUT ANY WARRANTY; without even the implied warranty of
43   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
44   * GNU General Lesser Public License for more details.
45   *
46   * You should have received a copy of the GNU General Lesser Public
47   * License along with this program.  If not, see
48   * <http://www.gnu.org/licenses/lgpl-3.0.html>.
49   * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱
50   */
51  
52  import java.net.*;
53  import java.io.*;
54  import java.util.*;
55  import uk.co.westhawk.snmp.event.*;
56  
57  /**
58   * This class contains the SNMP v2c context that is needed by every PDU to
59   * send a SNMP v2c request.
60   *
61   * <p>
62   * <code>destroy()</code> should be called when the context is no longer
63   * used. This is the only way the threads will be stopped and garbage
64   * collected.
65   * </p>
66   *
67   * @see SnmpContextv2cFace
68   * @see SnmpContextv2cPool
69   * @author <a href="mailto:snmp@westhawk.co.uk">Birgit Arkesteijn</a>
70   * @version $Revision: 3.16 $ $Date: 2009/03/05 12:54:04 $
71   */
72  public class SnmpContextv2c extends SnmpContext
73          implements SnmpContextv2cFace, Cloneable {
74      private static final String version_id = "@(#)$Id: SnmpContextv2c.java,v 3.16 2009/03/05 12:54:04 birgita Exp $ Copyright Westhawk Ltd";
75  
76      /**
77       * Constructor.
78       *
79       * @param host The host to which the PDU will be sent
80       * @param port The port where the SNMP server will be
81       * @see AbstractSnmpContext#AbstractSnmpContext(String, int)
82       */
83      public SnmpContextv2c(String host, int port) throws IOException {
84          super(host, port);
85      }
86  
87      /**
88       * Constructor.
89       * Parameter typeSocketA should be either STANDARD_SOCKET, TCP_SOCKET or a
90       * fully qualified classname.
91       *
92       * @param host        The host to which the Pdu will be sent
93       * @param port        The port where the SNMP server will be
94       * @param typeSocketA The local address the server will bind to
95       *
96       * @see AbstractSnmpContext#AbstractSnmpContext(String, int, String)
97       */
98      public SnmpContextv2c(String host, int port, String typeSocketA)
99              throws IOException {
100         super(host, port, typeSocketA);
101     }
102 
103     /**
104      * Constructor.
105      * Parameter typeSocketA should be either STANDARD_SOCKET, TCP_SOCKET or a
106      * fully qualified classname.
107      *
108      * @param host        The host to which the PDU will be sent
109      * @param port        The port where the SNMP server will be
110      * @param bindAddress The local address the server will bind to
111      * @param typeSocketA The type of socket to use.
112      *
113      * @see AbstractSnmpContext#AbstractSnmpContext(String, int, String, String)
114      * @see SnmpContextBasisFace#STANDARD_SOCKET
115      * @see SnmpContextBasisFace#TCP_SOCKET
116      * @since 4_14
117      */
118     public SnmpContextv2c(String host, int port, String bindAddress, String typeSocketA)
119             throws IOException {
120         super(host, port, bindAddress, typeSocketA);
121     }
122 
123     public int getVersion() {
124         return SnmpConstants.SNMP_VERSION_2c;
125     }
126 
127     public byte[] encodePacket(byte msg_type, int rId, int errstat,
128             int errind, Enumeration ve, Object obj)
129             throws IOException, EncodingException {
130         byte[] packet = null;
131         if (isDestroyed == true) {
132             throw new EncodingException("Context can no longer be used, since it is already destroyed");
133         } else {
134             AsnEncoderv2c enc = new AsnEncoderv2c();
135             ByteArrayOutputStream bay = enc.EncodeSNMPv2c(this, msg_type, rId, errstat,
136                     errind, ve);
137 
138             int sz = bay.size();
139             if (sz > maxRecvSize) {
140                 throw new EncodingException("Packet size (" + sz
141                         + ") is > maximum size (" + maxRecvSize + ")");
142             }
143             packet = bay.toByteArray();
144         }
145         return packet;
146     }
147 
148     /**
149      * Processes an incoming SNMP v2c response.
150      */
151     protected void processIncomingResponse(ByteArrayInputStream in)
152             throws DecodingException, IOException {
153         AsnDecoderv2c rpdu = new AsnDecoderv2c();
154         AsnPduSequence pduSeq = rpdu.DecodeSNMPv2c(in, getCommunity());
155         if (pduSeq != null) {
156             // got a message
157             Integer rid = new Integer(pduSeq.getReqId());
158             Pdu answ = getPdu(rid);
159             if (answ != null) {
160                 answ.fillin(pduSeq);
161             } else {
162                 if (AsnObject.debug > 3) {
163                     System.out.println(
164                             getClass().getName() + ".processIncomingResponse(): No Pdu with reqid " + rid.intValue());
165                 }
166             }
167         } else {
168             if (AsnObject.debug > 3) {
169                 System.out.println(getClass().getName() + ".processIncomingResponse(): Error - missing seq input");
170             }
171         }
172     }
173 
174     public Pdu processIncomingPdu(byte[] message)
175             throws DecodingException, IOException {
176         AsnDecoderv2c rpdu = new AsnDecoderv2c();
177         ByteArrayInputStream in = new ByteArrayInputStream(message);
178         AsnPduSequence pduSeq = rpdu.DecodeSNMPv2c(in, getCommunity());
179 
180         Pdu pdu = null;
181         if (pduSeq != null) {
182             byte type = pduSeq.getRespType();
183             switch (type) {
184                 case SnmpConstants.GET_REQ_MSG:
185                     pdu = new GetPdu(this);
186                     break;
187                 case SnmpConstants.GETNEXT_REQ_MSG:
188                     pdu = new GetNextPdu(this);
189                     break;
190                 case SnmpConstants.SET_REQ_MSG:
191                     pdu = new SetPdu(this);
192                     break;
193                 case SnmpConstants.GETBULK_REQ_MSG:
194                     pdu = new GetBulkPdu(this);
195                     break;
196                 case SnmpConstants.INFORM_REQ_MSG:
197                     pdu = new InformPdu(this);
198                     break;
199                 // case SnmpConstants.GET_RSP_MSG:
200                 // A longly response should never be received here.
201                 // They should come in via the processIncomingResponse
202                 // route.
203                 // case SnmpConstants.GET_RPRT_MSG:
204                 // Reports are part of v3 timeliness communication
205                 case SnmpConstants.TRPV2_REQ_MSG:
206                     pdu = new TrapPduv2(this);
207                     break;
208                 default:
209                     if (AsnObject.debug > 3) {
210                         System.out.println(getClass().getName()
211                                 + ".ProcessIncomingPdu(): PDU received with type "
212                                 + pduSeq.getRespTypeString()
213                                 + ". Ignoring it.");
214                     }
215             }
216 
217             if (pdu != null) {
218                 pdu.fillin(pduSeq);
219             }
220         }
221         return pdu;
222     }
223 
224     /**
225      * Returns a clone of this SnmpContextv2c.
226      *
227      * @exception CloneNotSupportedException Thrown when the constructor
228      *                                       generates an IOException
229      */
230     public Object clone() throws CloneNotSupportedException {
231         SnmpContextv2c clContext = null;
232         try {
233             clContext = new SnmpContextv2c(hostname, hostPort, bindAddr, typeSocket);
234             clContext.setCommunity(new String(community));
235         } catch (IOException exc) {
236             throw new CloneNotSupportedException("IOException "
237                     + exc.getMessage());
238         }
239         return clContext;
240     }
241 
242     /**
243      * Returns the hash key. This key is built out of all properties. It
244      * serves as key for a hashtable of (v2c) contexts.
245      *
246      * @since 4_14
247      * @return The hash key
248      */
249     public String getHashKey() {
250         return super.getHashKey();
251     }
252 
253     /**
254      * Returns a string representation of the object.
255      *
256      * @return The string
257      */
258     public String toString() {
259         StringBuffer buffer = new StringBuffer("SnmpContextv2c[");
260         buffer.append("host=").append(hostname);
261         buffer.append(", port=").append(hostPort);
262         buffer.append(", bindAddress=").append(bindAddr);
263         buffer.append(", socketType=").append(typeSocket);
264         buffer.append(", community=").append(community);
265         buffer.append(", #trapListeners=").append(trapSupport.getListenerCount());
266         buffer.append(", #pduListeners=").append(pduSupport.getListenerCount());
267         buffer.append("]");
268         return buffer.toString();
269     }
270 
271 }