1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 package uk.co.westhawk.snmp.stack;
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52 import java.io.*;
53 import java.util.*;
54 import uk.co.westhawk.snmp.net.*;
55 import uk.co.westhawk.snmp.event.*;
56 import uk.co.westhawk.snmp.util.*;
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76 public abstract class AbstractSnmpContext extends Object
77 implements SnmpContextBasisFace, Runnable, RawPduListener {
78 private static final String version_id = "@(#)$Id: AbstractSnmpContext.java,v 3.33 2009/03/05 12:48:04 birgita Exp $ Copyright Westhawk Ltd";
79
80 private ContextSocketFace soc;
81 private Transmitter[] transmitters;
82 private Pdu[] pdus;
83 private Thread me;
84 private String basename;
85 private volatile boolean stopRequested;
86
87
88
89 protected String typeSocket;
90 protected String hostname;
91 protected String bindAddr;
92 protected int hostPort;
93 protected int maxRecvSize;
94 protected boolean isDestroyed;
95 protected boolean anyPduExpectingResponse = false;
96 protected RequestPduReceivedSupport pduSupport;
97 protected TrapReceivedSupport trapSupport;
98
99
100
101
102
103
104
105 protected abstract void processIncomingResponse(ByteArrayInputStream in)
106 throws DecodingException, IOException;
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123 public abstract byte[] encodePacket(byte msg_type, int rId, int errstat,
124 int errind, Enumeration ve, Object obj)
125 throws IOException, EncodingException;
126
127
128
129
130
131
132
133 public abstract Pdu processIncomingPdu(byte[] message) throws DecodingException, IOException;
134
135
136
137
138
139 public abstract int getVersion();
140
141
142
143
144
145
146
147
148
149 protected AbstractSnmpContext(String host, int port) throws IOException {
150 this(host, port, null, STANDARD_SOCKET);
151 }
152
153
154
155
156
157
158
159
160
161
162
163
164
165 protected AbstractSnmpContext(String host, int port, String typeSocketA)
166 throws IOException {
167 this(host, port, null, typeSocketA);
168 }
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193 protected AbstractSnmpContext(String host, int port, String bindAddress, String typeSocketA)
194 throws IOException {
195 pdus = new Pdu[MAXPDU];
196 hostname = host;
197 hostPort = port;
198 bindAddr = bindAddress;
199 typeSocket = typeSocketA;
200 transmitters = new Transmitter[MAXPDU];
201 basename = host + "_" + port + "_" + bindAddress;
202 trapSupport = new TrapReceivedSupport(this);
203 pduSupport = new RequestPduReceivedSupport(this);
204
205 isDestroyed = false;
206 stopRequested = false;
207 maxRecvSize = MSS;
208
209 soc = getSocket(typeSocket);
210 if (soc != null) {
211 soc.create(hostname, hostPort, bindAddr);
212 if (AsnObject.debug > 12) {
213 System.out.println(getClass().getName()
214 + ": soc.getLocalSocketAddress() = "
215 + soc.getLocalSocketAddress());
216 System.out.println(getClass().getName()
217 + ": soc.getRemoteSocketAddress() = "
218 + soc.getRemoteSocketAddress());
219 }
220 }
221 }
222
223
224
225
226
227
228
229
230
231 static ContextSocketFace getSocket(String type) throws IOException {
232 ContextSocketFace sf = null;
233 if (type != null) {
234 String className = null;
235 if (type.equals(STANDARD_SOCKET)) {
236 className = "uk.co.westhawk.snmp.net.StandardSocket";
237 } else if (type.equals(TCP_SOCKET)) {
238 className = "uk.co.westhawk.snmp.net.TCPSocket";
239 } else {
240 className = type;
241 }
242
243 try {
244 Class cl = Class.forName(className);
245 Object obj = cl.newInstance();
246 sf = (ContextSocketFace) obj;
247 } catch (ClassNotFoundException exc) {
248 String str = "AbstractSnmpContext.getSocket(): ClassNotFound problem " + exc.getMessage() + ", type="
249 + type;
250 throw (new IOException(str));
251 } catch (InstantiationException exc) {
252 String str = "AbstractSnmpContext.getSocket(): Instantiation problem " + exc.getMessage() + ", type="
253 + type;
254 throw (new IOException(str));
255 } catch (IllegalAccessException exc) {
256 String str = "AbstractSnmpContext.getSocket(): IllegalAccess problem " + exc.getMessage() + ", type="
257 + type;
258 throw (new IOException(str));
259 } catch (ClassCastException exc) {
260 String str = "AbstractSnmpContext.getSocket(): ClassCast problem " + exc.getMessage() + ", type="
261 + type;
262 throw (new IOException(str));
263 }
264
265 if (sf == null) {
266 String str = "AbstractSnmpContext.getSocket(): Cannot create socket " + type;
267 throw (new IOException(str));
268 } else {
269 if (AsnObject.debug > 12) {
270 System.out.println("AbstractSnmpContext.getSocket(): New socket " + sf.getClass().getName());
271 }
272 }
273 }
274 return sf;
275 }
276
277 public String getHost() {
278 return hostname;
279 }
280
281
282
283
284
285
286
287
288
289 public String getHostAddress() {
290 return getSendToHostAddress();
291 }
292
293 public String getSendToHostAddress() {
294 String res = "";
295 if (soc != null) {
296 res = soc.getSendToHostAddress();
297 }
298 return res;
299 }
300
301 public String getReceivedFromHostAddress() {
302 String res = "";
303 if (soc != null) {
304 res = soc.getReceivedFromHostAddress();
305 }
306 return res;
307 }
308
309 public int getPort() {
310 return hostPort;
311 }
312
313 public String getBindAddress() {
314 return bindAddr;
315 }
316
317 public String getTypeSocket() {
318 return typeSocket;
319 }
320
321
322
323
324
325
326
327
328
329
330 public int getMaxRecvSize() {
331 return maxRecvSize;
332 }
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372 public void setMaxRecvSize(int no) {
373 maxRecvSize = no;
374 }
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411 public String getDebugString() {
412 char[] cret = new char[MAXPDU + 1];
413 for (int i = 0; i < MAXPDU; i++) {
414 if (transmitters[i] != null) {
415 if (pdus[i] != null) {
416 cret[i] = (char) ('A' + (pdus[i].getReqId() % 26));
417 } else {
418 cret[i] = '=';
419 }
420 } else {
421 cret[i] = '-';
422 }
423 }
424
425 char res = '0';
426 if (me != null) {
427 res++;
428 if (me.isAlive()) {
429 res++;
430 }
431 }
432 cret[MAXPDU] = res;
433
434 return new String(cret);
435 }
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456 public synchronized void destroy() {
457 if (isDestroyed == false) {
458 stopRequested = true;
459 if (AsnObject.debug > 12) {
460 System.out.println(getClass().getName() + ".destroy(): Closing socket ");
461 }
462 soc.close();
463 isDestroyed = true;
464
465
466
467
468 if (me == null) {
469 freeTransmitters();
470 }
471 }
472 }
473
474 public boolean isDestroyed() {
475 return isDestroyed;
476 }
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497 public synchronized void stop() {
498 stopRequested = true;
499 }
500
501
502
503
504
505
506
507
508
509
510
511
512 public void run() {
513
514 while (!stopRequested) {
515
516 me.yield();
517 try {
518 if (stopRequested) {
519 break;
520 }
521
522 StreamPortItem item = soc.receive(maxRecvSize);
523 ByteArrayInputStream in = item.getStream();
524
525 if (AsnObject.debug > 10) {
526 int nb = in.available();
527 byte[] bu = new byte[nb];
528 in.read(bu);
529 in.reset();
530
531 SnmpUtilities.dumpBytes(getClass().getName()
532 + ".run(): Received from "
533 + item.getHostAddress()
534 + ", from port " + item.getHostPort()
535 + ": ", bu);
536 }
537 processIncomingResponse(in);
538 } catch (IOException exc) {
539 if (exc instanceof InterruptedIOException) {
540 if (AsnObject.debug > 15) {
541 System.out.println(getClass().getName() + ".run(): Idle recv " + exc.getMessage());
542 }
543 } else if (exc instanceof java.net.SocketException) {
544 if (AsnObject.debug > 15) {
545 System.out.println(getClass().getName() + ".run(): SocketException " + exc.getMessage());
546 }
547 } else {
548 if (AsnObject.debug > 0) {
549 System.out.println(getClass().getName() + ".run(): "
550 + exc.getClass().getName() + " " + exc.getMessage());
551 exc.printStackTrace();
552 }
553 }
554 } catch (DecodingException exc) {
555 if (AsnObject.debug > 1) {
556 System.out.println(getClass().getName() + ".run(): DecodingException: " + exc.getMessage());
557 }
558 } catch (Exception exc) {
559 if (AsnObject.debug > 1) {
560 System.out.println(getClass().getName() + ".run(): Exception: " + exc.getMessage());
561 exc.printStackTrace();
562 }
563 } catch (Error err) {
564 if (AsnObject.debug > 1) {
565 System.out.println(getClass().getName() + ".run(): Error: " + err.getMessage());
566 err.printStackTrace();
567 }
568 }
569 }
570
571 freeTransmitters();
572
573 trapSupport.empty();
574 pduSupport.empty();
575
576
577
578
579 ListeningContextPool lcontext = new ListeningContextPool(ListeningContextFace.DEFAULT_TRAP_PORT, bindAddr,
580 typeSocket);
581 lcontext.removeRawPduListenerFromPool(this);
582
583 me = null;
584 soc = null;
585 }
586
587
588
589
590
591
592
593
594 public synchronized void sendPacket(byte[] p) {
595 if (isDestroyed == false) {
596 activate();
597 try {
598 if (AsnObject.debug > 10) {
599 SnmpUtilities.dumpBytes("Sending to "
600 + soc.getSendToHostAddress() + ": ", p);
601 }
602
603
604
605
606 soc.send(p);
607 } catch (IOException exc) {
608 if (AsnObject.debug > 0) {
609 System.out.println(getClass().getName() + ".sendPacket(): "
610 + exc.getClass().getName()
611 + " " + exc.getMessage());
612 exc.printStackTrace();
613 }
614 }
615 }
616 }
617
618 Pdu getPdu(Integer ReqId) {
619 return getPdu(ReqId.intValue());
620 }
621
622 Pdu getPdu(int rid) {
623 Pdu ret = null;
624 for (int i = 0; i < MAXPDU; i++) {
625 if ((pdus[i] != null) && (pdus[i].getReqId() == rid)) {
626 ret = pdus[i];
627 break;
628 }
629 }
630 return ret;
631 }
632
633 public synchronized boolean removePdu(int rid) {
634 boolean ret = false;
635 for (int i = 0; i < MAXPDU; i++) {
636 if ((pdus[i] != null) && (pdus[i].getReqId() == rid)) {
637 pdus[i] = null;
638 ret = true;
639 break;
640 }
641 }
642 return ret;
643 }
644
645 public synchronized boolean addPdu(Pdu p)
646 throws IOException, PduException {
647 boolean done = false;
648 if (isDestroyed == true) {
649 throw new EncodingException("Context can no longer be used, since it is already destroyed");
650 } else {
651
652
653 if (anyPduExpectingResponse == false) {
654 anyPduExpectingResponse = p.isExpectingResponse();
655 }
656 for (int i = 0; i < MAXPDU; i++) {
657 if (pdus[i] == null) {
658 pdus[i] = p;
659 pdus[i].setTrans(getTrans(i));
660 done = true;
661 break;
662 }
663 }
664 }
665 return done;
666 }
667
668 public void addTrapListener(TrapListener l) throws IOException {
669 addTrapListener(l, ListeningContextFace.DEFAULT_TRAP_PORT);
670 }
671
672 public void removeTrapListener(TrapListener l) throws IOException {
673 removeTrapListener(l, ListeningContextFace.DEFAULT_TRAP_PORT);
674 }
675
676 public void addTrapListener(TrapListener l, int port)
677 throws IOException {
678 ListeningContextPool lcontext = new ListeningContextPool(port, bindAddr, typeSocket);
679 addTrapListener(l, lcontext);
680 }
681
682 public void removeTrapListener(TrapListener l, int port)
683 throws IOException {
684 ListeningContextPool lcontext = new ListeningContextPool(port, bindAddr, typeSocket);
685 removeTrapListener(l, lcontext);
686 }
687
688 public void addTrapListener(TrapListener l, ListeningContextPool lcontext)
689 throws IOException {
690 trapSupport.addTrapListener(l);
691 lcontext.addRawPduListener(this);
692 }
693
694 public void removeTrapListener(TrapListener l, ListeningContextPool lcontext)
695 throws IOException {
696 trapSupport.removeTrapListener(l);
697 if (trapSupport.getListenerCount() == 0
698 &&
699 pduSupport.getListenerCount() == 0) {
700 lcontext.removeRawPduListener(this);
701 }
702 }
703
704 public void addRequestPduListener(RequestPduListener l)
705 throws IOException {
706 addRequestPduListener(l, SnmpContextBasisFace.DEFAULT_PORT);
707 }
708
709 public void removeRequestPduListener(RequestPduListener l)
710 throws IOException {
711 removeRequestPduListener(l, SnmpContextBasisFace.DEFAULT_PORT);
712 }
713
714 public void addRequestPduListener(RequestPduListener l, int port) throws IOException {
715 ListeningContextPool lcontext = new ListeningContextPool(port, bindAddr, typeSocket);
716 addRequestPduListener(l, lcontext);
717 }
718
719 public void removeRequestPduListener(RequestPduListener l, int port) throws IOException {
720 ListeningContextPool lcontext = new ListeningContextPool(port, bindAddr, typeSocket);
721 removeRequestPduListener(l, lcontext);
722 }
723
724 public void addRequestPduListener(RequestPduListener l, ListeningContextPool lcontext) throws IOException {
725 pduSupport.addRequestPduListener(l);
726 lcontext.addRawPduListener(this);
727 }
728
729 public void removeRequestPduListener(RequestPduListener l, ListeningContextPool lcontext) throws IOException {
730 pduSupport.removeRequestPduListener(l);
731 if (trapSupport.getListenerCount() == 0
732 &&
733 pduSupport.getListenerCount() == 0) {
734 lcontext.removeRawPduListener(this);
735 }
736 }
737
738
739
740
741
742
743
744
745
746
747
748
749 public void rawPduReceived(RawPduEvent evt) {
750 String hostAddress = evt.getHostAddress();
751 int version = evt.getVersion();
752 if (version == this.getVersion()) {
753 if (hostAddress != null && hostAddress.equals(this.getSendToHostAddress()) == true) {
754 byte[] message = evt.getMessage();
755 Pdu pdu = null;
756 try {
757 pdu = processIncomingPdu(message);
758 if (pdu != null) {
759 evt.consume();
760 int port = evt.getHostPort();
761
762 if (pdu.getMsgType() == SnmpConstants.TRP_REQ_MSG
763 ||
764 pdu.getMsgType() == SnmpConstants.TRPV2_REQ_MSG) {
765 trapSupport.fireTrapReceived(pdu, port);
766 } else {
767 pduSupport.fireRequestPduReceived(pdu, port);
768 }
769 } else {
770
771
772 }
773 } catch (DecodingException exc) {
774 if (AsnObject.debug > 2) {
775 System.out.println(
776 getClass().getName() + ".rawPduReceived(): DecodingException: " + exc.getMessage());
777 }
778 } catch (IOException exc) {
779 if (AsnObject.debug > 0) {
780 System.out.println(getClass().getName() + ".rawPduReceived(): IOException " + exc.getMessage());
781 }
782 }
783
784 } else {
785 if (AsnObject.debug > 5) {
786 System.out.println(getClass().getName() + ".rawPduReceived(): "
787 + "Pdu host (" + hostAddress
788 + "), does not correspond with context host ("
789 + this.getSendToHostAddress() + ")");
790 }
791 }
792 } else {
793 if (AsnObject.debug > 5) {
794 String theirs = SnmpUtilities.getSnmpVersionString(version);
795 String ours = SnmpUtilities.getSnmpVersionString(this.getVersion());
796 System.out.println(getClass().getName() + ".rawPduReceived(): "
797 + "Pdu version " + theirs
798 + ", does not correspond with context version "
799 + ours);
800 }
801 }
802 }
803
804 Transmitter getTrans(int i) {
805 if (transmitters[i] == null) {
806 transmitters[i] = new Transmitter(basename + "_v" + getVersion() + "_Trans" + i);
807 }
808 return transmitters[i];
809 }
810
811
812
813
814
815
816
817
818
819 protected void activate() {
820
821
822
823
824 if (me == null && anyPduExpectingResponse == true) {
825 me = new Thread(this, basename + "_v" + getVersion() + "_Receive");
826 me.setPriority(me.MAX_PRIORITY);
827 me.start();
828 }
829 }
830
831
832
833
834
835
836
837
838
839
840 protected void freeTransmitters() {
841 for (int i = 0; i < MAXPDU; i++) {
842 if (transmitters[i] != null) {
843 transmitters[i].destroy();
844 transmitters[i] = null;
845 }
846 if (pdus[i] != null) {
847 pdus[i] = null;
848 }
849 }
850 }
851
852
853
854
855
856
857
858
859
860 public abstract Object clone() throws CloneNotSupportedException;
861
862
863
864
865
866
867
868 public abstract String getHashKey();
869
870 }