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