Author: cyberdo
Date: 2006-01-31 21:11:38 +0000 (Tue, 31 Jan 2006)
New Revision: 7974
Added:
trunk/freenet/src/freenet/io/comm/IOStatisticCollector.java
trunk/freenet/src/snmplib/
trunk/freenet/src/snmplib/BERDecoder.java
trunk/freenet/src/snmplib/BEREncoder.java
trunk/freenet/src/snmplib/BadFormatException.java
trunk/freenet/src/snmplib/DataConstantInt.java
trunk/freenet/src/snmplib/DataConstantString.java
trunk/freenet/src/snmplib/DataFetcher.java
trunk/freenet/src/snmplib/DataStatisticsInfo.java
trunk/freenet/src/snmplib/SNMPAgent.java
trunk/freenet/src/snmplib/SNMPStarter.java
Modified:
trunk/freenet/src/freenet/io/comm/UdpSocketManager.java
trunk/freenet/src/freenet/node/Node.java
Log:
Basic, undocumented, SNMP-support. Most useful OIDs:
.1.3.1.1.0.0 Total outgoing bytes
.1.3.1.1.0.1 Total incoming bytes
Added: trunk/freenet/src/freenet/io/comm/IOStatisticCollector.java
===================================================================
--- trunk/freenet/src/freenet/io/comm/IOStatisticCollector.java 2006-01-31
18:30:45 UTC (rev 7973)
+++ trunk/freenet/src/freenet/io/comm/IOStatisticCollector.java 2006-01-31
21:11:38 UTC (rev 7974)
@@ -0,0 +1,226 @@
+package freenet.io.comm;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+
+import snmplib.SNMPStarter;
+
+public class IOStatisticCollector {
+ public static final int STATISTICS_ENTRIES = 10;
+ public static final int STATISTICS_DURATION_S = 30;
+ public static final int STATISTICS_DURATION =
1000*STATISTICS_DURATION_S;
+ private long lastrotate=0;
+
+ private static IOStatisticCollector _currentSC = null;
+ private long totalbytesin = 0;
+ private long totalbytesout = 0;
+ private HashMap targets = null;
+
+ private IOStatisticCollector() {
+ // Only I should be able to create myself
+ _currentSC = this;
+ targets = new HashMap();
+ // TODO: only for testing!!!!
+ // This should only happen once
+ //SNMPAgent.create();
+ SNMPStarter.initialize();
+ }
+
+ private static IOStatisticCollector getSC() {
+ if (_currentSC == null) {
+ _currentSC = new IOStatisticCollector();
+ }
+ return _currentSC;
+ }
+
+ public static void addInfo(String key, int inbytes, int outbytes) {
+ try {
+ IOStatisticCollector sc = getSC();
+ synchronized (sc) {
+ sc._addInfo(key, inbytes, outbytes);
+ }
+ } catch (Throwable t) {
+ t.printStackTrace();
+ }
+ }
+
+ private void _addInfo(String key, int inbytes, int outbytes) {
+ rotate();
+ StatisticEntry entry = (StatisticEntry)targets.get(key);
+ if (entry == null) {
+ entry = new StatisticEntry();
+ targets.put(key, entry);
+ }
+ entry.addData(inbytes, outbytes);
+ totalbytesout += outbytes;
+ totalbytesin += outbytes;
+ }
+
+ public static void dumpInfo() {
+ IOStatisticCollector sc = getSC();
+ synchronized (sc) {
+ sc._dumpInfo();
+ }
+ }
+
+ public static long[] getTotalIO() {
+ IOStatisticCollector sc = getSC();
+ synchronized (sc) {
+ return sc._getTotalIO();
+ }
+ }
+
+ private long[] _getTotalIO() {
+ long ret[] = new long[2];
+ ret[0] = totalbytesout;
+ ret[1] = totalbytesin;
+ return ret;
+ }
+
+ public static int[][] getTotalStatistics() {
+ IOStatisticCollector sc = getSC();
+ synchronized (sc) {
+ return sc._getTotalStatistics();
+ }
+ }
+
+ private int[][] _getTotalStatistics() {
+ //String[] keys = (String[])targets.keySet().toArray();
+ int ret[][] = new int[STATISTICS_ENTRIES][2];
+ for (int i = 0 ; i < STATISTICS_ENTRIES ; i++) {
+ ret[i][0] = ret[i][1] = 0;
+ }
+
+ Iterator it = targets.keySet().iterator();
+ while (it.hasNext()) {
+ String key = (String)it.next();
+ int inres[] =
((StatisticEntry)targets.get(key)).getRecieved();
+ int outres[] =
((StatisticEntry)targets.get(key)).getSent();
+ for (int i = 0 ; i < STATISTICS_ENTRIES ; i++) {
+ ret[i][1] += inres[i];
+ ret[i][0] += outres[i];
+ }
+ }
+
+ return ret;
+ }
+
+ private void _dumpInfo() {
+ rotate();
+ //DateFormat df = DateFormat.getDateInstance(DateFormat.LONG,
Locale.FRANCE);
+ //System.err.println(DateFormat.getDateInstance().format(new
Date()));
+ System.err.println(new Date());
+ Iterator it = targets.keySet().iterator();
+ final double divby = STATISTICS_DURATION_S*1024;
+ while (it.hasNext()) {
+ String key = (String)it.next();
+ int inres[] =
((StatisticEntry)targets.get(key)).getRecieved();
+ int outres[] =
((StatisticEntry)targets.get(key)).getSent();
+ System.err.print((key + " ").substring(0,22) +
": ");
+ int tin = 0;
+ int tout = 0;
+
+ for (int i = 0 ; i < inres.length ; i++) {
+ // in/out in 102.4 bytes (hecto-bytes)
+ tin += inres[i];
+ tout += outres[i];
+
+ int in = (int) (((double)tin*10.0) /
(divby*(double)(i+1)));
+ int out =(int) (((double)tout*10.0)
/(divby*(double)(i+1)));
+
+ System.err.print("i:" + (in/10) + "." +
(in%10));
+ System.err.print(" o:" + (out/10) + "." +
(out%10));
+ System.err.print(" \t");
+ }
+ System.err.println();
+ }
+ System.err.println();
+ }
+
+ private void rotate() {
+ long now = System.currentTimeMillis();
+ if ((now - lastrotate) >= STATISTICS_DURATION) {
+ Object[] keys = targets.keySet().toArray();
+ for(int i = 0 ; i < keys.length ; i++) {
+ Object key = keys[i];
+ if
(((StatisticEntry)(targets.get(key))).rotate() == false)
+ targets.remove(key);
+ }
+ lastrotate = now;
+ // FIXME: debugging
+ //_dumpInfo();
+ }
+ }
+
+
+/*
+ * to thead each update.... heavy stuff
+ private class StatisticUpdater implements Runnable {
+ private IOStatisticCollector sc;
+ private String key;
+ private int inbytes;
+ private int outbytes;
+
+ public StatisticUpdater(IOStatisticCollector sc, String key,
+ int inbytes, int outbytes) {
+ this.sc = sc;
+ this.key = key;
+ this.inbytes = inbytes;
+ this.outbytes = outbytes;
+ new Thread(this).run();
+ }
+
+ public void run() {
+
+ }
+ }
+ */
+
+
+
+ private class StatisticEntry {
+ private int recieved[];
+ private int sent[];
+
+ public StatisticEntry() {
+ // Create a new array and clear it
+ recieved = new
int[IOStatisticCollector.STATISTICS_ENTRIES+1];
+ sent = new
int[IOStatisticCollector.STATISTICS_ENTRIES+1];
+ for (int i = 0 ; i < recieved.length ; i++) {
+ recieved[i] = sent[i] = 0;
+ }
+ }
+
+ public void addData(int inbytes, int outbytes) {
+ recieved[0] += inbytes;
+ sent[0] += outbytes;
+ }
+
+ public boolean rotate() {
+ boolean hasdata = false;
+ for (int i = recieved.length - 1 ; i > 0 ; i--) {
+ recieved[i] = recieved[i-1];
+ sent[i] = sent[i-1];
+ hasdata |= (recieved[i] > 0) || (sent[i] > 0);
+ }
+ recieved[0] = sent[0] = 0;
+ return hasdata;
+ }
+
+ public int[] getRecieved() {
+ int retint[] = new
int[IOStatisticCollector.STATISTICS_ENTRIES];
+ for(int i = 1 ; i <
IOStatisticCollector.STATISTICS_ENTRIES + 1 ; i++)
+ retint[i-1] = recieved[i];
+ return retint;
+ }
+
+ public int[] getSent() {
+ int retint[] = new
int[IOStatisticCollector.STATISTICS_ENTRIES];
+ for(int i = 1 ; i <
IOStatisticCollector.STATISTICS_ENTRIES + 1; i++)
+ retint[i-1] = sent[i];
+ return retint;
+ }
+
+ }
+}
Modified: trunk/freenet/src/freenet/io/comm/UdpSocketManager.java
===================================================================
--- trunk/freenet/src/freenet/io/comm/UdpSocketManager.java 2006-01-31
18:30:45 UTC (rev 7973)
+++ trunk/freenet/src/freenet/io/comm/UdpSocketManager.java 2006-01-31
21:11:38 UTC (rev 7974)
@@ -208,6 +208,9 @@
DatagramPacket packet = new DatagramPacket(new byte[1500],
1500);
try {
_sock.receive(packet);
+ // TODO: keep?
+ IOStatisticCollector.addInfo(packet.getAddress() + ":"
+ packet.getPort(),
+ packet.getLength(), 0);
} catch (SocketTimeoutException e1) {
packet = null;
} catch (IOException e2) {
@@ -470,6 +473,10 @@
DatagramPacket packet = new DatagramPacket(blockToSend,
blockToSend.length);
packet.setAddress(destination.getAddress());
packet.setPort(destination.getPort());
+
+ // TODO: keep?
+ IOStatisticCollector.addInfo(packet.getAddress() + ":" +
packet.getPort(),
+ 0, packet.getLength());
try {
_sock.send(packet);
} catch (IOException e) {
Modified: trunk/freenet/src/freenet/node/Node.java
===================================================================
--- trunk/freenet/src/freenet/node/Node.java 2006-01-31 18:30:45 UTC (rev
7973)
+++ trunk/freenet/src/freenet/node/Node.java 2006-01-31 21:11:38 UTC (rev
7974)
@@ -24,6 +24,9 @@
import java.util.HashSet;
import java.util.Iterator;
+import snmplib.SNMPAgent;
+import snmplib.SNMPStarter;
+
import freenet.client.ArchiveManager;
import freenet.client.HighLevelSimpleClient;
import freenet.client.HighLevelSimpleClientImpl;
@@ -342,6 +345,9 @@
System.out.println("Starting fproxy on port "+(port+2000));
new FCPServer(port+3000, n);
System.out.println("Starting FCP server on port "+(port+3000));
+ SNMPAgent.setSNMPPort(port+4000);
+ System.out.println("Starting SNMP server on port "+(port+4000));
+ SNMPStarter.initialize();
//server.register(fproxy, "/SSK@", false);
//server.register(fproxy, "/KSK@", false);
}
Added: trunk/freenet/src/snmplib/BERDecoder.java
===================================================================
--- trunk/freenet/src/snmplib/BERDecoder.java 2006-01-31 18:30:45 UTC (rev
7973)
+++ trunk/freenet/src/snmplib/BERDecoder.java 2006-01-31 21:11:38 UTC (rev
7974)
@@ -0,0 +1,120 @@
+package 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");
+ 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 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 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/freenet/src/snmplib/BEREncoder.java
===================================================================
--- trunk/freenet/src/snmplib/BEREncoder.java 2006-01-31 18:30:45 UTC (rev
7973)
+++ trunk/freenet/src/snmplib/BEREncoder.java 2006-01-31 21:11:38 UTC (rev
7974)
@@ -0,0 +1,171 @@
+package 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);
+ offset += dlen;
+ offset += intToBERBytes(dlen, buf, offset);
+ buf[offset++] = 0x02;
+ } 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(int i, byte[] buf, int offset) {
+ int inoffset = offset;
+ if (i == 0) {
+ buf[offset++] = 0;
+ } else {
+ for (; i > 0 ; i = i / 256) {
+ buf[offset] = (byte)(i % 256);
+ offset++;
+ }
+ }
+ 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--) {
+ 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 putInteger(int i) {
+ addToTop(new Integer(i));
+ }
+
+ 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 = 0 ; 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/freenet/src/snmplib/BadFormatException.java
===================================================================
--- trunk/freenet/src/snmplib/BadFormatException.java 2006-01-31 18:30:45 UTC
(rev 7973)
+++ trunk/freenet/src/snmplib/BadFormatException.java 2006-01-31 21:11:38 UTC
(rev 7974)
@@ -0,0 +1,7 @@
+package snmplib;
+
+public class BadFormatException extends Exception {
+ public BadFormatException(String s) {
+ super(s);
+ }
+}
Added: trunk/freenet/src/snmplib/DataConstantInt.java
===================================================================
--- trunk/freenet/src/snmplib/DataConstantInt.java 2006-01-31 18:30:45 UTC
(rev 7973)
+++ trunk/freenet/src/snmplib/DataConstantInt.java 2006-01-31 21:11:38 UTC
(rev 7974)
@@ -0,0 +1,19 @@
+package 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/freenet/src/snmplib/DataConstantString.java
===================================================================
--- trunk/freenet/src/snmplib/DataConstantString.java 2006-01-31 18:30:45 UTC
(rev 7973)
+++ trunk/freenet/src/snmplib/DataConstantString.java 2006-01-31 21:11:38 UTC
(rev 7974)
@@ -0,0 +1,19 @@
+package 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/freenet/src/snmplib/DataFetcher.java
===================================================================
--- trunk/freenet/src/snmplib/DataFetcher.java 2006-01-31 18:30:45 UTC (rev
7973)
+++ trunk/freenet/src/snmplib/DataFetcher.java 2006-01-31 21:11:38 UTC (rev
7974)
@@ -0,0 +1,10 @@
+package snmplib;
+
+public interface DataFetcher {
+
+ public String getSNMPOID();
+
+ /* Must return an Integer or a String */
+ public Object getSNMPData();
+
+}
Added: trunk/freenet/src/snmplib/DataStatisticsInfo.java
===================================================================
--- trunk/freenet/src/snmplib/DataStatisticsInfo.java 2006-01-31 18:30:45 UTC
(rev 7973)
+++ trunk/freenet/src/snmplib/DataStatisticsInfo.java 2006-01-31 21:11:38 UTC
(rev 7974)
@@ -0,0 +1,35 @@
+package 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 Integer((int)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 Integer(res);
+ }
+}
Added: trunk/freenet/src/snmplib/SNMPAgent.java
===================================================================
--- trunk/freenet/src/snmplib/SNMPAgent.java 2006-01-31 18:30:45 UTC (rev
7973)
+++ trunk/freenet/src/snmplib/SNMPAgent.java 2006-01-31 21:11:38 UTC (rev
7974)
@@ -0,0 +1,266 @@
+package snmplib;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+import java.net.InetAddress;
+import java.util.Iterator;
+import java.util.TreeMap;
+
+public class SNMPAgent implements Runnable {
+ private int port = 4445;
+
+ /**
+ * @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 static void restartSNMPAgent() {
+ ensureCreated();
+ _SNMPAgent.stopRunning();
+ new Thread(_SNMPAgent).start();
+ }
+
+ public static SNMPAgent getSNMPAgent() {
+ ensureCreated();
+ return _SNMPAgent;
+ }
+
+ private static void ensureCreated() {
+ if (_SNMPAgent == null)
+ _SNMPAgent = new SNMPAgent();
+ }
+
+ private SNMPAgent() {
+ alldata = new TreeMap();
+ }
+
+ public void addFetcher(DataFetcher df) {
+ DataHandler dh = new DataHandler(df);
+ alldata.put(dh.getStringOID(), dh);
+ }
+
+ 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("localhost"));
+ } catch (IOException e) {
+ e.printStackTrace();
+ return ;
+ }
+ // make smaller.... 0484 enough?
+ byte[] buf = new byte[65535];
+ DatagramPacket packet = new DatagramPacket(buf, buf.length);
+
+ while (socket.isBound()) {
+ try {
+ socket.receive(packet);
+
+ RequestContainer rc = new RequestContainer();
+
+ parseRequest(buf, rc);
+
+ int replylength = 0;
+ boolean keyfound = false;
+ DataHandler dh = null;
+
+ Iterator it = alldata.keySet().iterator();
+ String key = "";
+ if (rc.OID.length() == 0)
+ rc.OID = ".";
+
+ while (it.hasNext() && !keyfound) {
+ key = (String)it.next();
+ if (key.startsWith(rc.OID))
+ keyfound = true;
+ }
+
+ // keyfound /\ (equal -> hasnext)
+ if (keyfound && (!key.equals(rc.OID) || it.hasNext())) {
+ key = key.equals(rc.OID)?(String)it.next():key;
+
+ dh = (DataHandler)alldata.get(key);
+ rc.lOID = (long[])dh.lOID.clone();
+
+ replylength = makeIntReply(buf, rc, dh.getData());
+ } else {
+ rc.lOID[0] = 100;
+ replylength = makeIntReply(buf, rc, new Integer(1));
+ }
+
+ // 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(e.toString());
+ } catch (ArrayIndexOutOfBoundsException e) {
+ e.printStackTrace();
+ // not much to do.. ignore the request and it'll time out
+ }
+ }
+ socket.close();
+ }
+
+ private int makeIntReply(byte buf[], RequestContainer rc, Object data) /*
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(0); // err
+ be.putInteger(0); // err
+ be.startSequence(); // value
+ be.startSequence(); // value
+ be.putOID(rc.lOID); // oid
+
+ if (data instanceof Integer)
+ be.putInteger(((Integer)data).intValue());
+ 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);
+ }
+
+ replyLength = be.toBytes(buf);
+
+ return replyLength;
+ }
+
+ // http://www.rane.com/note161.html
+ private void parseRequest(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 += "." + rc.lOID[i];
+
+ }
+
+
+ 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);
+ }
+ }
+}
Added: trunk/freenet/src/snmplib/SNMPStarter.java
===================================================================
--- trunk/freenet/src/snmplib/SNMPStarter.java 2006-01-31 18:30:45 UTC (rev
7973)
+++ trunk/freenet/src/snmplib/SNMPStarter.java 2006-01-31 21:11:38 UTC (rev
7974)
@@ -0,0 +1,26 @@
+package snmplib;
+
+import snmplib.DataStatisticsInfo;
+import freenet.io.comm.IOStatisticCollector;
+
+/**
+ * @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));
+ }
+
+ has_been_runned = true;
+ }
+}