Author: nextgens
Date: 2006-05-07 23:27:20 +0000 (Sun, 07 May 2006)
New Revision: 8646
Added:
trunk/plugins/SNMP/
trunk/plugins/SNMP/SNMP.java
trunk/plugins/SNMP/snmplib/
trunk/plugins/SNMP/snmplib/BERDecoder.java
trunk/plugins/SNMP/snmplib/BEREncoder.java
trunk/plugins/SNMP/snmplib/BadFormatException.java
trunk/plugins/SNMP/snmplib/DataConstantInt.java
trunk/plugins/SNMP/snmplib/DataConstantString.java
trunk/plugins/SNMP/snmplib/DataFetcher.java
trunk/plugins/SNMP/snmplib/DataStatisticsInfo.java
trunk/plugins/SNMP/snmplib/InfoSystem.java
trunk/plugins/SNMP/snmplib/MultiplexedDataFetcher.java
trunk/plugins/SNMP/snmplib/SNMPAgent.java
trunk/plugins/SNMP/snmplib/SNMPBindtoCallback.java
trunk/plugins/SNMP/snmplib/SNMPCounter32.java
trunk/plugins/SNMP/snmplib/SNMPGauge32.java
trunk/plugins/SNMP/snmplib/SNMPInteger32.java
trunk/plugins/SNMP/snmplib/SNMPPortNumberCallback.java
trunk/plugins/SNMP/snmplib/SNMPStarter.java
trunk/plugins/SNMP/snmplib/SNMPTimeTicks.java
trunk/plugins/SNMP/snmplib/SNMPTypeWrapperNum.java
Log:
SNMP: new plugin
Added: trunk/plugins/SNMP/SNMP.java
===================================================================
--- trunk/plugins/SNMP/SNMP.java 2006-05-07 23:24:54 UTC (rev 8645)
+++ trunk/plugins/SNMP/SNMP.java 2006-05-07 23:27:20 UTC (rev 8646)
@@ -0,0 +1,55 @@
+package plugins;
+
+import freenet.config.Config;
+import freenet.config.SubConfig;
+import freenet.pluginmanager.*;
+import freenet.support.Logger;
+import plugins.snmplib.*;
+
+
+public class SNMP implements FredPlugin{
+ boolean goon=true;
+ PluginRespirator pr;
+ private int port;
+ private String bindto;
+
+ public void terminate() {
+ Logger.normal(this,"Stopping SNMP");
+ SNMPAgent.stopSNMPAgent();
+ goon=false;
+ }
+
+ public int getPort(){
+ return port;
+ }
+
+ public String getBindto(){
+ return bindto;
+ }
+
+ public void runPlugin(PluginRespirator pr) {
+ this.pr = pr;
+ SNMPAgent.stopSNMPAgent();
+
+ try{
+ Config c=pr.getNode().config;
+ SubConfig sc=new SubConfig("plugins.snmp",c);
+ sc.register("port", 4000,2, true, "SNMP port number", "SNMP
port number", new SNMPPortNumberCallback());
+ sc.register("bindto", "127.0.0.1", 2, true, "Ip address to bind
to", "Ip address to bind the SNMP server to", new SNMPBindtoCallback());
+
+ bindto=sc.getString("bindto");
+ port=sc.getInt("port");
+
+ SNMPAgent.setSNMPPort(port);
+ System.out.println("Starting SNMP server on "+bindto+":"+port);
+ SNMPStarter.initialize();
+ Logger.normal(this,"Starting SNMP server on "+bindto+":"+port);
+
+ sc.finishedInitialization();
+ while(goon){};
+ }catch (IllegalArgumentException e){
+ Logger.error(this, "Error loading SNMP server");
+ }
+ }
+}
+
Added: trunk/plugins/SNMP/snmplib/BERDecoder.java
===================================================================
--- trunk/plugins/SNMP/snmplib/BERDecoder.java 2006-05-07 23:24:54 UTC (rev
8645)
+++ trunk/plugins/SNMP/snmplib/BERDecoder.java 2006-05-07 23:27:20 UTC (rev
8646)
@@ -0,0 +1,133 @@
+package plugins.snmplib;
+
+import java.util.Stack;
+
+public class BERDecoder {
+ private byte[] buf;
+ private int ptr = 0;
+ private Stack seqStack;
+
+ public BERDecoder(byte[] buf) {
+ this.buf = buf;
+ seqStack = new Stack();
+ }
+
+ public void startSequence() throws BadFormatException {
+ startSequence((byte)0x30);
+ }
+
+ public void startSequence(byte id) throws BadFormatException {
+ if (buf[ptr] != id)
+ throw new BadFormatException("Unknown Sequence
(expected: 0x" +
+ Integer.toHexString(id) + ", got: 0x" +
+ Integer.toHexString(buf[ptr]) + ")");
+ ptr++;
+ int len = readBERInt();
+ seqStack.push(new Integer(ptr + len));
+ seqStack.push(new Integer(len));
+ }
+
+ public void endSequence() throws BadFormatException {
+ int length = ((Integer)seqStack.pop()).intValue();
+ int pos = ((Integer)seqStack.pop()).intValue();
+ if (pos != ptr)
+ throw new BadFormatException("Wrong length of field " +
+ length + ":" + pos + ":" + ptr);
+ }
+
+ public boolean sequenceHasMore() {
+ //int length = ((Integer)seqStack.peek()).intValue();
+ int pos = ((Integer)seqStack.get(seqStack.size()-2)).intValue();
+ return (pos != ptr);
+ }
+
+ public byte peekRaw() {
+ return buf[ptr];
+ }
+
+ public long[] fetchOID() throws BadFormatException {
+ startSequence((byte)0x06);
+ long[] ret = readOID();
+ endSequence();
+ return ret;
+ }
+
+ private long[] readOID() throws BadFormatException {
+ if (buf[ptr] != 0x2b)
+ throw new BadFormatException("Bad start of OID");
+ int inptr = ptr;
+ ptr++;
+ int length = ((Integer)seqStack.peek()).intValue();
+ if (length < 2)
+ return new long[0];
+ long ret[] = new long[length]; // it won't getlonger then this
+ int i;
+ for(i = 0; i < length ; i++) {
+ ret[i] = readBERInt();
+ if ((ptr - inptr) >= length)
+ break;
+ }
+
+ if (i < length) { // Bring out the scissors
+ long ret2[] = (long[])ret.clone();
+ ret = new long[i + 1];
+ for ( ; i >= 0 ; i--)
+ ret[i] = ret2[i];
+ }
+ return ret;
+ }
+
+
+ public byte[] fetchOctetString() throws BadFormatException {
+ startSequence((byte)0x04);
+ byte[] ret = readOctetString();
+ endSequence();
+ return ret;
+ }
+
+ private byte[] readOctetString() {
+ int length = ((Integer)seqStack.peek()).intValue();
+ byte ret[] = new byte[length];
+ for(int i = 0; i < length ; i++) {
+ ret[i] = buf[ptr++];
+ }
+ return ret;
+ }
+
+
+ public void fetchNull() throws BadFormatException {
+ startSequence((byte)0x05);
+ endSequence();
+ }
+
+ public int fetchInt() throws BadFormatException {
+ startSequence((byte)0x02);
+ int ret = readInt();
+ endSequence();
+ return ret;
+ }
+
+ private int readInt() {
+ int length = ((Integer)seqStack.peek()).intValue();
+ int ret = 0;
+ for ( ; length > 0 ; length--) {
+ ret = ret * 256;
+ ret = ret + ((((int)buf[ptr])+256)%256);
+ ptr++;
+ }
+ return ret;
+ }
+
+
+
+ private int readBERInt() {
+ int ret = 0;
+ do {
+ ret = ret * 128;
+ ret = ret + ((((int)buf[ptr])+128)%128);
+ ptr++;
+ } while (buf[ptr-1] < 0);
+ return ret;
+ }
+
+}
Added: trunk/plugins/SNMP/snmplib/BEREncoder.java
===================================================================
--- trunk/plugins/SNMP/snmplib/BEREncoder.java 2006-05-07 23:24:54 UTC (rev
8645)
+++ trunk/plugins/SNMP/snmplib/BEREncoder.java 2006-05-07 23:27:20 UTC (rev
8646)
@@ -0,0 +1,231 @@
+package plugins.snmplib;
+
+import java.util.Stack;
+import java.util.Vector;
+
+public class BEREncoder {
+ private IDVector fields;
+ private Stack fstack;
+
+ public BEREncoder() {
+ this((byte)0x30);
+ }
+
+ public BEREncoder(byte id) {
+ fields = new IDVector(id);
+ fstack = new Stack();
+ fstack.add(fields);
+ }
+
+
+ public int toBytes(byte[] buf) {
+ while (fields.size() > 1)
+ endSequence();
+
+ int len = vecToBytes(fields, buf, 0);
+ byte tmpbt;
+ // Remember.. this function writes backwards first!
+ for (int i = 0 ; i < len/2 ; i++) {
+ tmpbt = buf[i];
+ buf[i] = buf[len - 1 - i];
+ buf[len - 1 - i] = tmpbt;
+ }
+
+ return len;
+ }
+
+ private int vecToBytes(IDVector v, byte[] buf, int offset) {
+ int inoffset = offset;
+ for (int i = v.size() - 1 ; i >= 0 ; i--) {
+ Object o = v.get(i);
+// if (o instanceof Integer) {
+// int dlen = intToBytes(((Integer)o).intValue(),
buf, offset);
+ if (o == null) {
+ buf[offset++] = 0x00;
+ buf[offset++] = 0x05;
+ } else if (o instanceof Long) {
+ int dlen = intToBytes(((Long)o).longValue(),
buf, offset);
+ offset += dlen;
+ offset += intToBERBytes(dlen, buf, offset);
+ buf[offset++] = 0x02;
+ } else if (o instanceof SNMPTypeWrapperNum) {
+ int dlen =
intToBytes(((SNMPTypeWrapperNum)o).getValue(), buf, offset);
+ offset += dlen;
+ offset += intToBERBytes(dlen, buf, offset);
+ buf[offset++] =
((SNMPTypeWrapperNum)o).getTypeID();
+ } else if (o instanceof IDVector) {
+ int dlen = vecToBytes((IDVector)o, buf, offset);
+ offset += dlen;
+ offset += intToBERBytes(dlen, buf, offset);
+ buf[offset++] = ((IDVector)o).getVid();
+ } else if (o instanceof ByteArrWrapper) {
+ byte[] barr = ((ByteArrWrapper)o).arr;
+ for (int j = 0 ; j < barr.length ; j++)
+ buf[offset + j] = barr[barr.length - 1
- j];
+ offset += barr.length;
+ offset += intToBERBytes(barr.length, buf,
offset);
+ buf[offset++] = ((ByteArrWrapper)o).id;
+ }
+// myoffset += intToBytes(v.get(i), buf, myoffset);
+
+ }
+
+ return (offset - inoffset);
+ }
+
+
+ private int intToBytes(long i, byte[] buf, int offset) {
+ // TODO: handle negative numbers also!!!!
+ int inoffset = offset;
+ if (i == 0) {
+ buf[offset++] = 0;
+ } else {
+ for (; i > 0 ; i = i / 256) {
+ buf[offset] = (byte)(i % 256);
+ offset++;
+ }
+ }
+ // make the number unsigned
+ /*
+ * No, we should allow signed numbers
+ * if (buf[offset-1]<0)
+ buf[offset++] = 0;
+ */
+ return (offset - inoffset);
+ }
+
+ private int intToBERBytes(long i, byte[] buf, int offset) {
+ //String bs = Long.toBinaryString(i);
+ //int len = (bs.length()%7);
+ //bs = ("0000000" + bs).substring(len);
+ //char bits[] = bs.toCharArray();
+ //int eatenbits = 0;
+ buf[offset] = 0;
+ int inoffset = offset;
+ //for (int j = bits.length - 1 ; j >= 0 ; j--) {
+ long j = i;
+ //System.out.print("intToBERBytes: " + i + ": ");
+ if (i == 0) {
+ offset++;
+ } else {
+ for ( ; j > 0 ; j = j/128) {
+ buf[offset++] += (byte)(j%128);
+ buf[offset] = (byte)((j > 127)?128:0);
+ //System.out.print("[" + (j%128) + " + " + ((j
> 127)?128:0) + " = " + ((j%128) + ((j > 127)?128:0) ) + "] ");
+ }
+
+ // now; turn it around!
+ if ((offset - inoffset) > 1) {
+ // System.err.println("Started at: " + inoffset +
", ended at: " + offset);
+ for (int p = 0 ; p < (offset - inoffset)/2
;p++) {
+ // System.err.println("stap: " +
(offset-p-1) + " <-> " + (inoffset+p));
+ byte tmp = buf[offset-p-1];
+ buf[offset-p-1] = buf[inoffset+p];
+ buf[inoffset+p] = tmp;
+ }
+ }
+ //System.err.println();
+ /*
+ for (int j = 0 ; j < bits.length ; j++) {
+ if (eatenbits == 7) {
+ buf[offset] += 128;
+ offset++;
+ eatenbits = 0;
+ buf[offset] = 0;
+ }
+
+ buf[offset] |= (bits[j]=='1'?1:0) << (6 - eatenbits);
+ eatenbits++;
+ }
+ offset++;
+ */
+ }
+ return (offset - inoffset);
+ }
+
+
+ public void putSNMPTypeWrapperNum(SNMPTypeWrapperNum o) {
+ addToTop(o.clone());
+ }
+
+ /*public void putInteger(int i) {
+ addToTop(new Integer(i));
+ }*/
+ public void putTimeticks(long i) {
+ addToTop(new SNMPTimeTicks(i));
+ }
+
+ public void putInteger(long i) {
+ addToTop(new Long(i));
+ }
+
+ public void putCounter32(long i) {
+ addToTop(new SNMPCounter32(i));
+ }
+
+ public void putNull() {
+ addToTop(null);
+ }
+
+ public void putOctetString(byte buf[]) {
+ addToTop(new ByteArrWrapper((byte[])buf.clone(), (byte)0x04));
+ }
+
+ public void putOID(long buf[]) {
+ byte bufa[] = new byte[10*buf.length];
+ int offset = 1;
+ bufa[0] = 0x2b;
+ for (int i = 2 ; i < buf.length ; i++) {
+ offset += intToBERBytes(buf[i], bufa, offset);
+ }
+ byte bufb[] = new byte[offset];
+ for (int i = 0 ; i < bufb.length ; i++)
+ bufb[i] = bufa[i];
+
+ addToTop(new ByteArrWrapper(bufb, (byte)0x06));
+ }
+
+ public void startSequence() {
+ startSequence((byte)0x30);
+ }
+
+ public void startSequence(byte id) {
+ IDVector v = new IDVector(id);
+ addToTop(v);
+ fstack.add(v);
+ }
+
+ public void endSequence() {
+ fstack.pop();
+ }
+
+ private void addToTop(Object o) {
+ ((IDVector)fstack.peek()).addElement(o);
+ }
+
+ private class ByteArrWrapper {
+ public byte arr[];
+ public byte id;
+
+ public ByteArrWrapper(byte arr[], byte id) {
+ this.arr = arr;
+ this.id = id;
+ }
+ }
+
+ // unpublic
+ private class IDVector extends Vector {
+ private static final long serialVersionUID =
2689317091785298027L;
+ byte vid = (byte)0x30;
+
+ public IDVector(byte id) {
+ super();
+ vid = id;
+ }
+
+ public byte getVid() {
+ return vid;
+ }
+
+ }
+}
Added: trunk/plugins/SNMP/snmplib/BadFormatException.java
===================================================================
--- trunk/plugins/SNMP/snmplib/BadFormatException.java 2006-05-07 23:24:54 UTC
(rev 8645)
+++ trunk/plugins/SNMP/snmplib/BadFormatException.java 2006-05-07 23:27:20 UTC
(rev 8646)
@@ -0,0 +1,7 @@
+package plugins.snmplib;
+
+public class BadFormatException extends Exception {
+ public BadFormatException(String s) {
+ super(s);
+ }
+}
Added: trunk/plugins/SNMP/snmplib/DataConstantInt.java
===================================================================
--- trunk/plugins/SNMP/snmplib/DataConstantInt.java 2006-05-07 23:24:54 UTC
(rev 8645)
+++ trunk/plugins/SNMP/snmplib/DataConstantInt.java 2006-05-07 23:27:20 UTC
(rev 8646)
@@ -0,0 +1,20 @@
+package plugins.snmplib;
+
+
+public class DataConstantInt implements DataFetcher {
+ private String OID;
+ private int value;
+
+ public DataConstantInt(String oID, int value) {
+ this.OID = oID;
+ this.value = value;
+ }
+
+ public String getSNMPOID() {
+ return OID;
+ }
+
+ public Object getSNMPData() {
+ return new Integer(value);
+ }
+}
Added: trunk/plugins/SNMP/snmplib/DataConstantString.java
===================================================================
--- trunk/plugins/SNMP/snmplib/DataConstantString.java 2006-05-07 23:24:54 UTC
(rev 8645)
+++ trunk/plugins/SNMP/snmplib/DataConstantString.java 2006-05-07 23:27:20 UTC
(rev 8646)
@@ -0,0 +1,19 @@
+package plugins.snmplib;
+
+public class DataConstantString implements DataFetcher {
+ private String OID;
+ private String value;
+
+ public DataConstantString(String oID, String value) {
+ this.OID = oID;
+ this.value = value;
+ }
+
+ public String getSNMPOID() {
+ return OID;
+ }
+
+ public Object getSNMPData() {
+ return value;
+ }
+}
Added: trunk/plugins/SNMP/snmplib/DataFetcher.java
===================================================================
--- trunk/plugins/SNMP/snmplib/DataFetcher.java 2006-05-07 23:24:54 UTC (rev
8645)
+++ trunk/plugins/SNMP/snmplib/DataFetcher.java 2006-05-07 23:27:20 UTC (rev
8646)
@@ -0,0 +1,10 @@
+package plugins.snmplib;
+
+public interface DataFetcher {
+
+ public String getSNMPOID();
+
+ /* Must return an Integer or a String */
+ public Object getSNMPData();
+
+}
Added: trunk/plugins/SNMP/snmplib/DataStatisticsInfo.java
===================================================================
--- trunk/plugins/SNMP/snmplib/DataStatisticsInfo.java 2006-05-07 23:24:54 UTC
(rev 8645)
+++ trunk/plugins/SNMP/snmplib/DataStatisticsInfo.java 2006-05-07 23:27:20 UTC
(rev 8646)
@@ -0,0 +1,35 @@
+package plugins.snmplib;
+
+import freenet.io.comm.IOStatisticCollector;
+
+public class DataStatisticsInfo implements DataFetcher {
+ private String OID;
+ int blocks;
+ boolean in;
+
+ public DataStatisticsInfo(int blocks, boolean in) {
+ this.OID = "1.1." + blocks + "." + (in?"1":"0");
+ //System.err.println("adding: " + this.OID);
+ this.in = in;
+ this.blocks = blocks;
+ }
+
+ public String getSNMPOID() {
+ //System.err.println(" " + this.OID);
+ return OID;
+ }
+
+ public Object getSNMPData() {
+ if (blocks == 0) {
+ long io[] = IOStatisticCollector.getTotalIO();
+ return new SNMPCounter32(io[in?1:0]);
+ }
+ // else sum all fields up to <blocks>
+ int res = 0;
+ int stats[][] = IOStatisticCollector.getTotalStatistics();
+ for (int i = 0 ; i < blocks ; i++)
+ res += stats[i][in?1:0];
+
+ return new Long(res);
+ }
+}
Added: trunk/plugins/SNMP/snmplib/InfoSystem.java
===================================================================
--- trunk/plugins/SNMP/snmplib/InfoSystem.java 2006-05-07 23:24:54 UTC (rev
8645)
+++ trunk/plugins/SNMP/snmplib/InfoSystem.java 2006-05-07 23:27:20 UTC (rev
8646)
@@ -0,0 +1,59 @@
+package plugins.snmplib;
+
+import freenet.node.Version;
+
+public class InfoSystem implements MultiplexedDataFetcher {
+ long created;
+
+ public InfoSystem() {
+ created = System.currentTimeMillis()/10;
+ }
+
+ public String getSNMPOID(int index) {
+ switch (index) {
+
+ case 0: //UCD-SNMP-MIB::memTotalReal.0
+ return ".1.3.6.1.4.1.2021.4.5.0";
+ case 1: //UCD-SNMP-MIB::memAvailReal.0
+ return ".1.3.6.1.4.1.2021.4.6.0";
+ case 2: //SNMPv2-MIB::sysName.0
+ return ".1.3.6.1.2.1.1.5.0";
+ case 3: //SNMPv2-MIB::sysUpTime.0
+ return ".1.3.6.1.2.1.1.3.0";
+
+ case 4: //UCD-SNMP-MIB::memTotalReal.0
+ return ".1.3.6.1.4.1.2021.4.5";
+ case 5: //UCD-SNMP-MIB::memAvailReal.0
+ return ".1.3.6.1.4.1.2021.4.6";
+
+
+ }
+ // default
+ return null;
+ }
+
+ public Object getSNMPData(String oid) {
+ Runtime r = Runtime.getRuntime();
+ //System.err.println("requesting: " + oid);
+ if (oid.equals(".1.3.6.1.2.1.1.3.0")) //SNMPv2-MIB::sysUpTime.0
+ return new SNMPTimeTicks(System.currentTimeMillis()/10
- created);
+ if (oid.equals(".1.3.6.1.4.1.2021.4.5.0"))
//UCD-SNMP-MIB::memTotalReal.0
+ return new SNMPInteger32(r.totalMemory());
+ if (oid.equals(".1.3.6.1.4.1.2021.4.6.0"))
//UCD-SNMP-MIB::memAvailReal.0
+ return new SNMPInteger32(r.freeMemory());
+
+
+ if (oid.equals(".1.3.6.1.2.1.1.5.0")) //SNMPv2-MIB::sysName.0
+ return (Version.nodeName + " " + Version.nodeVersion +
" (" + Version.buildNumber() + ")");
+
+
+ if (oid.equals(".1.3.6.1.4.1.2021.4.5"))
//UCD-SNMP-MIB::memTotalReal.0
+ return new SNMPInteger32(r.totalMemory());
+ if (oid.equals(".1.3.6.1.4.1.2021.4.6"))
//UCD-SNMP-MIB::memAvailReal.0
+ return new SNMPInteger32(r.freeMemory());
+
+ return null;
+ }
+
+
+}
Added: trunk/plugins/SNMP/snmplib/MultiplexedDataFetcher.java
===================================================================
--- trunk/plugins/SNMP/snmplib/MultiplexedDataFetcher.java 2006-05-07
23:24:54 UTC (rev 8645)
+++ trunk/plugins/SNMP/snmplib/MultiplexedDataFetcher.java 2006-05-07
23:27:20 UTC (rev 8646)
@@ -0,0 +1,11 @@
+package plugins.snmplib;
+
+public interface MultiplexedDataFetcher {
+
+ /* Return null when the last OID is reached */
+ public String getSNMPOID(int index);
+
+ /* Must return an Integer or a String */
+ public Object getSNMPData(String oid);
+
+}
Added: trunk/plugins/SNMP/snmplib/SNMPAgent.java
===================================================================
--- trunk/plugins/SNMP/snmplib/SNMPAgent.java 2006-05-07 23:24:54 UTC (rev
8645)
+++ trunk/plugins/SNMP/snmplib/SNMPAgent.java 2006-05-07 23:27:20 UTC (rev
8646)
@@ -0,0 +1,453 @@
+package plugins.snmplib;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+import java.net.InetAddress;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.TreeMap;
+
+public class SNMPAgent implements Runnable {
+ private int port = 4445;
+ private String bindto = "127.0.0.1";
+
+ /**
+ * @param args
+ */
+ public static void main(String[] args) throws IOException {
+ SNMPAgent.getSNMPAgent().addFetcher(new
DataConstantInt("1.1.1", 10));
+ SNMPAgent.getSNMPAgent().addFetcher(new
DataConstantInt("1.1.2", 20));
+ SNMPAgent.getSNMPAgent().addFetcher(new
DataConstantInt("1.1.3", 30));
+ SNMPAgent.getSNMPAgent().addFetcher(new
DataConstantInt("1.1.4", 40));
+ SNMPAgent.getSNMPAgent().addFetcher(new
DataConstantInt("1.1.5", 50));
+ SNMPAgent.getSNMPAgent().addFetcher(new
DataConstantString("1.1.0", "Step by 10"));
+ SNMPAgent.getSNMPAgent().addFetcher(new
DataConstantString("1.2", "Nothing here"));
+ }
+
+ protected DatagramSocket socket = null;
+ protected BufferedReader in = null;
+ protected boolean moreQuotes = true;
+ private TreeMap alldata;
+ private static SNMPAgent _SNMPAgent = null;
+
+ public static void setSNMPPort(int port) {
+ ensureCreated();
+ _SNMPAgent.port = port;
+ restartSNMPAgent();
+ }
+
+ public int getSNMPort(){
+ return port;
+ }
+
+ public static void setSNMPbindto(String adr){
+ ensureCreated();
+ _SNMPAgent.bindto=adr;
+ restartSNMPAgent();
+ }
+
+ public String getSNMPbindto(){
+ return bindto;
+ }
+
+ public static void restartSNMPAgent() {
+ ensureCreated();
+ _SNMPAgent.stopRunning();
+ new Thread(_SNMPAgent, "SNMP-Agent").start();
+ }
+
+ public static void stopSNMPAgent(){
+ ensureCreated();
+ _SNMPAgent.stopRunning();
+ }
+
+ public static SNMPAgent getSNMPAgent() {
+ ensureCreated();
+ return _SNMPAgent;
+ }
+
+ private static void ensureCreated() {
+ if (_SNMPAgent == null)
+ _SNMPAgent = new SNMPAgent();
+ }
+
+ private SNMPAgent() {
+ alldata = new TreeMap();
+ //alldata.put("99.99", null);
+ }
+
+ public void addFetcher(DataFetcher df) {
+ //DataHandler dh = new DataHandler(df);
+ //alldata.put(dh.getStringOID(), dh);
+ alldata.put(df.getSNMPOID().replaceAll("^\\.1\\.3\\.",""), df);
+ //System.err.println("sAdded: " + df.getSNMPOID() + "as" +
df.getSNMPOID().replaceAll("^\\.1\\.3\\.",""));
+ }
+
+ public void addFetcher(MultiplexedDataFetcher df) {
+ String oid;
+ for (int i = 0 ; (oid = df.getSNMPOID(i)) != null ; i++) {
+ alldata.put(oid.replaceAll("^\\.1\\.3\\.",""), df);
+ // System.err.println("mAdded: " + oid + " as: " +
oid.replaceAll("^\\.1\\.3\\.",""));
+ }
+ }
+
+ public void removeFetcher(String OID) {
+ alldata.remove(((OID.startsWith("\\."))?"":".") + OID);
+ }
+
+ public void stopRunning() {
+ try {
+ socket.close();
+ } catch (Throwable e) {
+ // prpbably since not running...
+ }
+ }
+
+ public void run() {
+ try {
+ socket = new DatagramSocket(port,
InetAddress.getByName(bindto));
+ } catch (IOException e) {
+ e.printStackTrace();
+ return ;
+ }
+ // make smaller.... 0484 enough?
+
+ while (socket.isBound()) {
+ byte[] buf = new byte[65536];
+ DatagramPacket packet = new DatagramPacket(buf, buf.length);
+
+ try {
+ socket.receive(packet);
+
+ RequestContainer rc = new RequestContainer();
+ int replylength = 0;
+ //DataHandler dh = null;
+
+ //if (rc != null)
+ // throw new BadFormatException("asdfa");
+
+ BERDecoder question = parseRequestStart(buf, rc);
+
+
+ BEREncoder reply = replyStart(rc);
+
+ int errIndex = 0;
+ int errStatus = 0;
+
+ try {
+ while (question.sequenceHasMore()) {
+ errIndex++;
+ question.startSequence();
+ rc.lOID = question.fetchOID();
+ rc.OID = (rc.lOID.length == 0)?"":"";
+ for (int i = 0; i < rc.lOID.length ; i++)
+ rc.OID += (i==0?"":".") + rc.lOID[i];
+ //System.err.println("Doing: " + rc.OID);
+ question.fetchNull();
+ question.endSequence();
+ replyAddOID(reply, rc);
+ }
+ } catch (NoSuchFieldException e) {
+ errStatus = 0x02; // NO SUCH NAME
+ }
+
+ if (errStatus != 0) {
+ // Need to restart the question
+ question = parseRequestStart(buf, rc);
+
+ // TODO! This does not follow the standard, but works
with SNMPWALK
+ // Or does it? ;o)
+ reply = replyStart(rc, errStatus, errIndex);
+ while (question.sequenceHasMore()) {
+ question.startSequence();
+
+
+ reply.startSequence(); // value
+ reply.putOID(question.fetchOID()); // oid
+ reply.putNull();
+ reply.endSequence();
+
+ question.fetchNull();
+ question.endSequence();
+ }
+ }
+
+ replylength = replyEnd(reply, buf);
+ //rc.pdutype == RequestContainer.PDU_GET_NEXT
+
+ // send the response to the client at "address" and "port"
+ InetAddress address = packet.getAddress();
+ int port = packet.getPort();
+ packet = new DatagramPacket(buf, replylength, address, port);
+ socket.send(packet);
+
+ } catch (IOException e) {
+ e.printStackTrace();
+ break;
+ } catch (BadFormatException e) {
+ System.err.println("Datapacket length: " + packet.getLength());
+ for (int i = 0 ; i < packet.getLength() ; i++) {
+ String num = "000" + Integer.toHexString(buf[i]);
+ num = num.substring(num.length()-2);
+ System.err.print("0x" + num + " ");
+ if ((i+1)%8 == 0)
+ System.err.print(" ");
+ if ((i+1)%16 == 0)
+ System.err.println();
+ }
+ System.err.println();
+ e.printStackTrace();
+ //System.err.println(e.toString());
+ } catch (ArrayIndexOutOfBoundsException e) {
+ e.printStackTrace();
+ // not much to do.. ignore the request and it'll time out
+ }
+ }
+ socket.close();
+ }
+
+ private String getAccualOID(String oid, boolean thisval) throws
NoSuchFieldException {
+ boolean keyfound = false;
+ Iterator it = alldata.keySet().iterator();
+ String key = "";
+ while (it.hasNext() && !keyfound) {
+ key = (String)it.next();
+ if (key.startsWith(oid))
+ keyfound = true;
+ }
+
+
+ if (it.hasNext() && !thisval) {
+ key = key.equals(oid)?(String)it.next():key;
+ } else if (!keyfound ) {
+ throw new NoSuchFieldException("OID not found");
+ }
+
+ return key;
+ }
+
+ private Object getResultFromOID(String oid, boolean thisval) {
+ /*boolean keyfound = false;
+ Iterator it = alldata.keySet().iterator();
+ String key = "";
+ while (it.hasNext() && !keyfound) {
+ key = (String)it.next();
+ if (key.startsWith(oid))
+ keyfound = true;
+ }
+ */
+ // keyfound /\ ( (equal -> hasnext) V (rc.pdutype == rc.PDU_GET_THIS))
+ //System.err.println("("+keyfound+" && (!"+key.equals(rc.OID)+" ||
"+it.hasNext()+"))");
+ /*if (keyfound && (
+ (!key.equals(rc.OID) || it.hasNext())) ||
+ (rc.pdutype == RequestContainer.PDU_GET_THIS) ) {
+ */
+ Object data = null;
+ /*if (keyfound && (
+ (!key.equals(oid) || it.hasNext())) ) {
+ if (it.hasNext() && !thisval)
+ key = key.equals(oid)?(String)it.next():key;
+ */
+ Object df = alldata.get(oid);
+
+ if (df instanceof DataFetcher) {
+ data = ((DataFetcher)df).getSNMPData();
+ } else if (df instanceof MultiplexedDataFetcher) {
+ data = ((MultiplexedDataFetcher)df).getSNMPData(oid);
+ if (data == null)
+ if (!oid.startsWith(".1.3."))
+ data =
((MultiplexedDataFetcher)df).getSNMPData(".1.3."+oid);
+ else
+ data =
((MultiplexedDataFetcher)df).getSNMPData(oid.substring(5));
+
+ } else
+ data = null; //new Integer(0);
+
+ //rc.lOID = splitToLong(key);
+ //replylength = makeIntReply(buf, rc, data);
+ //} else {
+ /*
+ if (rc.lOID.length > 0)
+ rc.lOID[0] = 100;
+ else {
+ rc.lOID = new long[1];
+ rc.lOID[0] = 0;
+ }
+ data = new Integer(1);
+ */
+ // data = null;
+ //replylength = makeIntReply(buf, rc, new Integer(1));
+ //}
+ if (data == null)
+ debug("DNF@"+oid);
+ return data;
+ }
+
+ private void debug(String s) {
+ System.err.println("SNMP-Agent " + (new Date()) + ": " + s);
+ }
+
+ private BEREncoder replyStart(RequestContainer rc) {
+ return replyStart(rc, 0, 0);
+ }
+ private BEREncoder replyStart(RequestContainer rc, int errStatus, int
errIndex) /* throws SnmpTooBigException */ {
+ int replyLength = 0;
+ BEREncoder be = new BEREncoder();
+ be.startSequence(); // whole pkg
+ be.putInteger(0); // version
+ be.putOctetString(rc.community); // community
+ be.startSequence((byte)0xa2); // Response
+ be.putInteger(rc.requestID); // RID
+ be.putInteger(errStatus); // err
+ be.putInteger(errIndex); // err
+ be.startSequence(); // OID:s and their values
+
+ return be;
+ }
+
+ private void replyAddOID(BEREncoder be, RequestContainer rc) throws
NoSuchFieldException {
+ String aOID = getAccualOID(rc.OID, rc.pdutype ==
RequestContainer.PDU_GET_THIS);
+ Object data = getResultFromOID(aOID, rc.pdutype ==
RequestContainer.PDU_GET_THIS);
+ be.startSequence(); // value
+ be.putOID(splitToLong(aOID)); // oid
+ //System.err.println("Will reply with OID: " + rc.OID + " -> " + aOID);
+ if (data instanceof Number)
+ be.putInteger(((Number)data).longValue());
+ else if (data instanceof SNMPTypeWrapperNum)
+ be.putSNMPTypeWrapperNum((SNMPTypeWrapperNum)data);
+// else if (data instanceof SNMPCounter32)
+// be.putCunter32(((SNMPCounter32)data).getValue());
+ else if (data instanceof String) {
+ char[] charr = ((String)data).toCharArray();
+ byte[] byarr = new byte[charr.length];
+ for (int i = 0 ; i < charr.length ; i++)
+ byarr[i] = (byte)charr[i];
+ be.putOctetString(byarr);
+ }
+ be.endSequence();
+ }
+
+ private int replyEnd(BEREncoder be, byte[] buf) /* throws
SnmpTooBigException */ {
+ return be.toBytes(buf);
+ }
+
+
+ // http://www.rane.com/note161.html
+ private BERDecoder parseRequestStart(byte buf[], RequestContainer rc)
throws BadFormatException {
+ int tmpint;
+
+ BERDecoder bd = new BERDecoder(buf);
+ bd.startSequence();
+ if ((tmpint = bd.fetchInt()) != 0)
+ throw new BadFormatException("Wrong version, expected 0, got "
+ + tmpint);
+
+ rc.community = bd.fetchOctetString();
+ if (! rc.setPDU(bd.peekRaw()))
+ throw new BadFormatException("Unknown PDU");
+ bd.startSequence(bd.peekRaw());
+ rc.requestID = bd.fetchInt();
+
+ // TODO: care about errors eventually?
+ bd.fetchInt();
+ bd.fetchInt();
+
+ bd.startSequence();
+ /*
+
+ bd.startSequence();
+ rc.lOID = bd.fetchOID();
+ rc.OID = (rc.lOID.length == 0)?".":"";
+ for (int i = 0; i < rc.lOID.length ; i++)
+ rc.OID += (i==0?"":".") + rc.lOID[i];
+ */
+ return bd;
+ }
+
+ private long[] splitToLong(String list) {
+ if (!list.startsWith(".1.3."))
+ list = ".1.3." + list;
+ list = list.substring(1);
+ String nums[] = list.split("\\.");
+ long ret[] = new long[nums.length];
+ for(int i = 0; i < ret.length ; i++) {
+ ret[i] = Long.parseLong(nums[i]);
+ //System.err.print("," + Long.parseLong(nums[i]));
+ }
+ // System.err.println();
+ return ret;
+ }
+ /*
+ private class DataHandler {
+ //public Integer data;
+ public long lOID[] = null;
+ DataFetcher df;
+
+ public DataHandler(DataFetcher df) {
+ lOID = splitToLong(df.getSNMPOID());
+ this.df = df;
+ }
+
+ private long[] splitToLong(String list) {
+ String nums[] = list.split("\\.");
+ long ret[] = new long[nums.length];
+ for(int i = 0; i < ret.length ; i++)
+ ret[i] = Long.parseLong(nums[i]);
+ return ret;
+ }
+
+ public Object getData() {
+ return df.getSNMPData();
+ }
+
+ public String getStringOID() {
+ String ret = "";
+ for (int i = 0; i < lOID.length ; i++)
+ ret += "." + lOID[i];
+ return ret;
+ }
+ }
+ */
+
+
+
+
+ private class RequestContainer {
+ public long lOID[] = null;
+ public byte community[] = null;
+ public int pdutype = 0;
+ public static final int PDU_GET_NEXT = 2;
+ public static final int PDU_GET_THIS = 1;
+ public int requestID = 0;
+ public String OID = null;
+
+ public boolean setPDU(byte id) {
+ switch(id) {
+ case (byte)0xA0:
+ pdutype = PDU_GET_THIS;
+ break;
+
+ case (byte)0xA1:
+ pdutype = PDU_GET_NEXT;
+ break;
+
+ default:
+ System.err.println("Unknown PDU: 0x" +
Integer.toHexString((id + 256)%256));
+ return false;
+ }
+ return true;
+ }
+
+ public String toString() {
+ return ("Community: " + new String(community) +
+ ", PDU: " + pdutype + ", OID: " + OID);
+ }
+
+ public boolean pduIsGet() {
+ return ((pdutype == RequestContainer.PDU_GET_THIS) ||
+ (pdutype == RequestContainer.PDU_GET_NEXT));
+ }
+ }
+}
Added: trunk/plugins/SNMP/snmplib/SNMPBindtoCallback.java
===================================================================
--- trunk/plugins/SNMP/snmplib/SNMPBindtoCallback.java 2006-05-07 23:24:54 UTC
(rev 8645)
+++ trunk/plugins/SNMP/snmplib/SNMPBindtoCallback.java 2006-05-07 23:27:20 UTC
(rev 8646)
@@ -0,0 +1,22 @@
+package plugins.snmplib;
+
+import freenet.config.InvalidConfigValueException;
+import freenet.config.StringCallback;
+
+public class SNMPBindtoCallback implements StringCallback {
+
+ public SNMPBindtoCallback() {
+ }
+
+ public String get() {
+ String bindto=SNMPAgent.getSNMPAgent().getSNMPbindto();
+ if(bindto!=null) return bindto;
+ return "127.0.0.1";
+ }
+
+ public void set(String val) throws InvalidConfigValueException {
+ if(val != get()) {
+ SNMPAgent.setSNMPbindto(val);
+ }
+ }
+}
\ No newline at end of file
Added: trunk/plugins/SNMP/snmplib/SNMPCounter32.java
===================================================================
--- trunk/plugins/SNMP/snmplib/SNMPCounter32.java 2006-05-07 23:24:54 UTC
(rev 8645)
+++ trunk/plugins/SNMP/snmplib/SNMPCounter32.java 2006-05-07 23:27:20 UTC
(rev 8646)
@@ -0,0 +1,16 @@
+package plugins.snmplib;
+
+public class SNMPCounter32 extends SNMPTypeWrapperNum {
+ public SNMPCounter32() { super(); }
+ public SNMPCounter32(long value) { super(value); }
+
+ public void setValue(long value) {
+ // TODO: make it prettier!
+ this.value = new Long(value).intValue();
+ //System.err.println("Value cut from: " + value + " to " +
this.value);
+ }
+
+ protected void init() {
+ this.typeID = 0x41;
+ }
+}
Added: trunk/plugins/SNMP/snmplib/SNMPGauge32.java
===================================================================
--- trunk/plugins/SNMP/snmplib/SNMPGauge32.java 2006-05-07 23:24:54 UTC (rev
8645)
+++ trunk/plugins/SNMP/snmplib/SNMPGauge32.java 2006-05-07 23:27:20 UTC (rev
8646)
@@ -0,0 +1,16 @@
+package plugins.snmplib;
+
+public class SNMPGauge32 extends SNMPTypeWrapperNum {
+ public SNMPGauge32() { super(); }
+ public SNMPGauge32(long value) { super(value); }
+
+ public void setValue(long value) {
+ // TODO: make it prettier!
+ this.value = new Long(value).intValue();
+ //System.err.println("Value cut from: " + value + " to " +
this.value);
+ }
+
+ protected void init() {
+ this.typeID = 0x42;
+ }
+}
Added: trunk/plugins/SNMP/snmplib/SNMPInteger32.java
===================================================================
--- trunk/plugins/SNMP/snmplib/SNMPInteger32.java 2006-05-07 23:24:54 UTC
(rev 8645)
+++ trunk/plugins/SNMP/snmplib/SNMPInteger32.java 2006-05-07 23:27:20 UTC
(rev 8646)
@@ -0,0 +1,16 @@
+package plugins.snmplib;
+
+public class SNMPInteger32 extends SNMPTypeWrapperNum {
+ public SNMPInteger32() { super(); }
+ public SNMPInteger32(long value) { super(value); }
+
+ public void setValue(long value) {
+ // TODO: make it prettier!
+ this.value = new Long(value).intValue();
+ //System.err.println("Value cut from: " + value + " to " +
this.value);
+ }
+
+ protected void init() {
+ this.typeID = 0x02;
+ }
+}
Added: trunk/plugins/SNMP/snmplib/SNMPPortNumberCallback.java
===================================================================
--- trunk/plugins/SNMP/snmplib/SNMPPortNumberCallback.java 2006-05-07
23:24:54 UTC (rev 8645)
+++ trunk/plugins/SNMP/snmplib/SNMPPortNumberCallback.java 2006-05-07
23:27:20 UTC (rev 8646)
@@ -0,0 +1,21 @@
+package plugins.snmplib;
+
+import plugins.SNMP;
+import freenet.config.IntCallback;
+import freenet.config.InvalidConfigValueException;
+
+public class SNMPPortNumberCallback implements IntCallback {
+
+ public SNMPPortNumberCallback() {
+ }
+
+ public int get() {
+ return SNMPAgent.getSNMPAgent().getSNMPort();
+ }
+
+ public void set(int val) throws InvalidConfigValueException {
+ if(val != get()) {
+ SNMPAgent.setSNMPPort(val);
+ }
+ }
+}
\ No newline at end of file
Added: trunk/plugins/SNMP/snmplib/SNMPStarter.java
===================================================================
--- trunk/plugins/SNMP/snmplib/SNMPStarter.java 2006-05-07 23:24:54 UTC (rev
8645)
+++ trunk/plugins/SNMP/snmplib/SNMPStarter.java 2006-05-07 23:27:20 UTC (rev
8646)
@@ -0,0 +1,32 @@
+package plugins.snmplib;
+
+import freenet.config.Config;
+import freenet.io.comm.IOStatisticCollector;
+import freenet.node.Node;
+
+/**
+ * @author cyberdo
+ *
+ * Creates the SNMP-agent
+ */
+public class SNMPStarter {
+
+ private static boolean has_been_runned = false;
+
+ public static void initialize() {
+ //SNMPAgent.setSNMPPort(port);
+ if (has_been_runned) return;
+ // 0 is toatl I/O
+ for (int i = 0 ; i < IOStatisticCollector.STATISTICS_ENTRIES ;
i++) {
+ SNMPAgent.getSNMPAgent().addFetcher(new
DataStatisticsInfo(i, true));
+ SNMPAgent.getSNMPAgent().addFetcher(new
DataStatisticsInfo(i, false));
+ }
+ SNMPAgent.getSNMPAgent().addFetcher(new InfoSystem());
+
+ has_been_runned = true;
+ }
+
+ public static void maybeCreate(Node node, Config config) {
+ // FIXME any config needed for SNMPStarter?
+ }
+}
Added: trunk/plugins/SNMP/snmplib/SNMPTimeTicks.java
===================================================================
--- trunk/plugins/SNMP/snmplib/SNMPTimeTicks.java 2006-05-07 23:24:54 UTC
(rev 8645)
+++ trunk/plugins/SNMP/snmplib/SNMPTimeTicks.java 2006-05-07 23:27:20 UTC
(rev 8646)
@@ -0,0 +1,24 @@
+package plugins.snmplib;
+
+public class SNMPTimeTicks extends SNMPTypeWrapperNum {
+ public SNMPTimeTicks() { super(); }
+ public SNMPTimeTicks(long value) { super(value); }
+
+ protected void init() {
+ this.typeID = 0x43;
+ }
+
+ public String toString() {
+ long rest = value;
+ long dec = rest%100;
+ rest = rest/100;
+ long sec = rest%60;
+ rest = rest/60;
+ long min = rest%60;
+ rest = rest/60;
+ long hour = rest%24;
+ rest = rest/24;
+ long day = rest;
+ return day + ":" + hour + ":" + min + ":" + sec + "." + dec;
+ }
+}
Added: trunk/plugins/SNMP/snmplib/SNMPTypeWrapperNum.java
===================================================================
--- trunk/plugins/SNMP/snmplib/SNMPTypeWrapperNum.java 2006-05-07 23:24:54 UTC
(rev 8645)
+++ trunk/plugins/SNMP/snmplib/SNMPTypeWrapperNum.java 2006-05-07 23:27:20 UTC
(rev 8646)
@@ -0,0 +1,58 @@
+package plugins.snmplib;
+
+public abstract class SNMPTypeWrapperNum {
+ protected long value;
+ protected byte typeID;
+
+ /**
+ * This methd is used to initialize for instance typeID;
+ */
+ protected abstract void init();
+
+ public SNMPTypeWrapperNum() {
+ this(0);
+ }
+
+ public SNMPTypeWrapperNum(long value) {
+ this.setValue(value);
+ init();
+ }
+
+ //public final byte typeID;
+ //= 0x02;
+ public byte getTypeID() {
+ //System.err.println("Returning " + Integer.toHexString(typeID)
+ " for a " + this.getClass().toString());
+ return typeID;
+ }
+
+ public long getValue() {
+ return value;
+ }
+
+ public void setValue(long value) {
+ this.value = value;
+ }
+
+ public Object clone() {
+ Object ret = null;
+ try {
+ ret = this.getClass().newInstance();
+ ((SNMPTypeWrapperNum)ret).setValue(getValue());
+ } catch (SecurityException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (InstantiationException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (IllegalAccessException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ return ret;
+ }
+
+ public String toString() {
+ return Long.toString(value);
+ }
+
+}