Author: cyberdo
Date: 2006-02-04 02:48:11 +0000 (Sat, 04 Feb 2006)
New Revision: 8003
Added:
trunk/freenet/src/snmplib/SNMPTimeTicks.java
Modified:
trunk/freenet/src/freenet/node/Version.java
trunk/freenet/src/snmplib/BERDecoder.java
trunk/freenet/src/snmplib/BEREncoder.java
trunk/freenet/src/snmplib/InfoSystem.java
trunk/freenet/src/snmplib/SNMPAgent.java
trunk/freenet/src/snmplib/SNMPStarter.java
Log:
433:
SNMP-bug now fixed. Still needs testing, but seems to work as supposed to.
MRTG-problem still not solved, but FRED behaves just as SNMPD, so the problem
might be in MRTG.
Added OID:s: SNMPv2-MIB::sysUpTime.0 (.1.3.6.1.2.1.1.3.0) and
SNMPv2-MIB::sysName.0 (.1.3.6.1.2.1.1.5.0)
sysUpTime is the node's uptime, and sysname is a string like "Fred 0.7 (433)"
Modified: trunk/freenet/src/freenet/node/Version.java
===================================================================
--- trunk/freenet/src/freenet/node/Version.java 2006-02-03 23:46:58 UTC (rev
8002)
+++ trunk/freenet/src/freenet/node/Version.java 2006-02-04 02:48:11 UTC (rev
8003)
@@ -20,7 +20,7 @@
public static final String protocolVersion = "1.0";
/** The build number of the current revision */
- private static final int buildNumber = 432;
+ private static final int buildNumber = 433;
/** Oldest build of Fred we will talk to */
private static final int lastGoodBuild = 403;
Modified: trunk/freenet/src/snmplib/BERDecoder.java
===================================================================
--- trunk/freenet/src/snmplib/BERDecoder.java 2006-02-03 23:46:58 UTC (rev
8002)
+++ trunk/freenet/src/snmplib/BERDecoder.java 2006-02-04 02:48:11 UTC (rev
8003)
@@ -18,7 +18,9 @@
public void startSequence(byte id) throws BadFormatException {
if (buf[ptr] != id)
- throw new BadFormatException("Unknown Sequence");
+ 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));
@@ -33,6 +35,12 @@
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];
}
@@ -87,6 +95,11 @@
}
+ public void fetchNull() throws BadFormatException {
+ startSequence((byte)0x05);
+ endSequence();
+ }
+
public int fetchInt() throws BadFormatException {
startSequence((byte)0x02);
int ret = readInt();
Modified: trunk/freenet/src/snmplib/BEREncoder.java
===================================================================
--- trunk/freenet/src/snmplib/BEREncoder.java 2006-02-03 23:46:58 UTC (rev
8002)
+++ trunk/freenet/src/snmplib/BEREncoder.java 2006-02-04 02:48:11 UTC (rev
8003)
@@ -45,6 +45,11 @@
offset += dlen;
offset += intToBERBytes(dlen, buf, offset);
buf[offset++] = 0x02;
+ } else if (o instanceof SNMPTimeTicks) {
+ int dlen =
intToBytes(((SNMPTimeTicks)o).timeValue(), buf, offset);
+ offset += dlen;
+ offset += intToBERBytes(dlen, buf, offset);
+ buf[offset++] = 0x43;
} else if (o instanceof IDVector) {
int dlen = vecToBytes((IDVector)o, buf, offset);
offset += dlen;
@@ -84,26 +89,51 @@
}
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;
+ //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;
+ 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) ) + "] ");
}
- buf[offset] |= (bits[j]=='1'?1:0) << (6 - eatenbits);
- eatenbits++;
+ // 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++;
+ */
}
- offset++;
return (offset - inoffset);
}
@@ -112,6 +142,9 @@
/*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));
@@ -125,7 +158,7 @@
byte bufa[] = new byte[10*buf.length];
int offset = 1;
bufa[0] = 0x2b;
- for (int i = 0 ; i < buf.length ; i++) {
+ for (int i = 2 ; i < buf.length ; i++) {
offset += intToBERBytes(buf[i], bufa, offset);
}
byte bufb[] = new byte[offset];
Modified: trunk/freenet/src/snmplib/InfoSystem.java
===================================================================
--- trunk/freenet/src/snmplib/InfoSystem.java 2006-02-03 23:46:58 UTC (rev
8002)
+++ trunk/freenet/src/snmplib/InfoSystem.java 2006-02-04 02:48:11 UTC (rev
8003)
@@ -1,20 +1,28 @@
package snmplib;
+import freenet.node.Version;
+
public class InfoSystem implements MultiplexedDataFetcher {
long created;
public InfoSystem() {
- created = System.currentTimeMillis()/1000;
+ created = System.currentTimeMillis()/10;
}
public String getSNMPOID(int index) {
switch (index) {
- case 3: //SNMPv2-MIB::sysUpTime.0
- return ".1.3.6.1.2.1.1.3.0";
+
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";
+
+
+
}
// default
return null;
@@ -23,13 +31,24 @@
public Object getSNMPData(String oid) {
Runtime r = Runtime.getRuntime();
int oidhc = oid.hashCode();
+ //System.err.println("requesting: " + oid);
if (oid.equals(".1.3.6.1.2.1.1.3.0")) //SNMPv2-MIB::sysUpTime.0
- return new Long(System.currentTimeMillis()/1000 -
created);
+ 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 Long(r.totalMemory());
if (oid.equals(".1.3.6.1.4.1.2021.4.6.0"))
//UCD-SNMP-MIB::memAvailReal.0
return new Long(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 Long(r.totalMemory());
+ if (oid.equals(".1.3.6.1.4.1.2021.4.6"))
//UCD-SNMP-MIB::memAvailReal.0
+ return new Long(r.freeMemory());
+
return null;
}
Modified: trunk/freenet/src/snmplib/SNMPAgent.java
===================================================================
--- trunk/freenet/src/snmplib/SNMPAgent.java 2006-02-03 23:46:58 UTC (rev
8002)
+++ trunk/freenet/src/snmplib/SNMPAgent.java 2006-02-04 02:48:11 UTC (rev
8003)
@@ -5,6 +5,7 @@
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
+import java.util.Date;
import java.util.Iterator;
import java.util.TreeMap;
@@ -12,7 +13,7 @@
private int port = 4445;
/**
- * @param args
+ * @param args
*/
public static void main(String[] args) throws IOException {
SNMPAgent.getSNMPAgent().addFetcher(new
DataConstantInt("1.1.1", 10));
@@ -39,7 +40,7 @@
public static void restartSNMPAgent() {
ensureCreated();
_SNMPAgent.stopRunning();
- new Thread(_SNMPAgent).start();
+ new Thread(_SNMPAgent, "SNMP-Agent").start();
}
public static SNMPAgent getSNMPAgent() {
@@ -54,6 +55,8 @@
private SNMPAgent() {
alldata = new TreeMap();
+ //alldata.put("99.99", null);
+ addFetcher(new DataConstantInt("99.99.99.99", 0));
}
public void addFetcher(DataFetcher df) {
@@ -91,68 +94,40 @@
return ;
}
// make smaller.... 0484 enough?
- byte[] buf = new byte[65535];
- DatagramPacket packet = new DatagramPacket(buf, buf.length);
while (socket.isBound()) {
+ byte[] buf = new byte[65536];
+ DatagramPacket packet = new DatagramPacket(buf, buf.length);
+
try {
socket.receive(packet);
RequestContainer rc = new RequestContainer();
-
- parseRequest(buf, rc);
-
int replylength = 0;
- boolean keyfound = false;
//DataHandler dh = null;
+
+ //if (rc != null)
+ // throw new BadFormatException("asdfa");
- Iterator it = alldata.keySet().iterator();
- String key = "";
- if (rc.OID.length() == 0)
- rc.OID = "";
+ BERDecoder question = parseRequestStart(buf, rc);
- while (it.hasNext() && !keyfound) {
- key = (String)it.next();
- //System.err.println("is '"+ rc.OID + "' in: " + key);
- if (key.startsWith(rc.OID))
- keyfound = true;
- }
+
+ BEREncoder reply = replyStart(rc);
- // keyfound /\ (equal -> hasnext)
- //System.err.println("("+keyfound+" &&
(!"+key.equals(rc.OID)+" || "+it.hasNext()+"))");
- if (keyfound && (!key.equals(rc.OID) || it.hasNext())) {
- key = key.equals(rc.OID)?(String)it.next():key;
-
- Object df = alldata.get(key);
- //Object key = null;
- Object data = null;
- //dh = (DataHandler)alldata.get(key);
- //rc.lOID = (long[])dh.lOID.clone();
- if (df instanceof DataFetcher) {
- data = ((DataFetcher)df).getSNMPData();
- } else if (df instanceof MultiplexedDataFetcher) {
- data =
((MultiplexedDataFetcher)df).getSNMPData(key);
- if (data == null)
- data =
((MultiplexedDataFetcher)df).getSNMPData(".1.3."+key);
- } else
- data = new Integer(0);
-
- rc.lOID = splitToLong(key);
- //System.err.println(key);
- //for (int i = 0; i < rc.lOID.length ; i++)
- // System.err.print("." + rc.lOID[i]);
-
-
- 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;
- }
- replylength = makeIntReply(buf, rc, new Integer(1));
+
+ while (question.sequenceHasMore()) {
+ 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);
}
+ replylength = replyEnd(reply, buf);
+ //rc.pdutype == RequestContainer.PDU_GET_NEXT
// send the response to the client at "address" and "port"
InetAddress address = packet.getAddress();
@@ -164,6 +139,17 @@
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) {
@@ -174,7 +160,86 @@
socket.close();
}
- private int makeIntReply(byte buf[], RequestContainer rc, Object data) /*
throws SnmpTooBigException */ {
+ private String getAccualOID(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;
+ }
+
+
+ if (it.hasNext() && !thisval) {
+ key = key.equals(oid)?(String)it.next():key;
+ }
+
+ 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) /* throws
SnmpTooBigException */ {
int replyLength = 0;
BEREncoder be = new BEREncoder();
be.startSequence(); // whole pkg
@@ -184,14 +249,23 @@
be.putInteger(rc.requestID); // RID
be.putInteger(0); // err
be.putInteger(0); // err
+ be.startSequence(); // OID:s and their values
+
+ return be;
+ }
+
+ private void replyAddOID(BEREncoder be, RequestContainer rc) /* throws
SnmpTooBigException */ {
+ 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.startSequence(); // value
- be.putOID(rc.lOID); // oid
-
+ be.putOID(splitToLong(aOID)); // oid
+ //System.err.println("Will reply with OID: " + rc.OID + " -> " + aOID);
if (data instanceof Integer)
be.putInteger(((Integer)data).intValue());
else if (data instanceof Long)
be.putInteger(((Long)data).longValue());
+ else if (data instanceof SNMPTimeTicks)
+ be.putTimeticks(((SNMPTimeTicks)data).timeValue());
else if (data instanceof String) {
char[] charr = ((String)data).toCharArray();
byte[] byarr = new byte[charr.length];
@@ -199,14 +273,16 @@
byarr[i] = (byte)charr[i];
be.putOctetString(byarr);
}
-
- replyLength = be.toBytes(buf);
-
- return replyLength;
+ be.endSequence();
}
+ private int replyEnd(BEREncoder be, byte[] buf) /* throws
SnmpTooBigException */ {
+ return be.toBytes(buf);
+ }
+
+
// http://www.rane.com/note161.html
- private void parseRequest(byte buf[], RequestContainer rc) throws
BadFormatException {
+ private BERDecoder parseRequestStart(byte buf[], RequestContainer rc)
throws BadFormatException {
int tmpint;
BERDecoder bd = new BERDecoder(buf);
@@ -226,19 +302,28 @@
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++)
+ 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;
}
/*
@@ -296,7 +381,7 @@
break;
default:
- //System.err.println("Unknown PDU: 0x" +
Integer.toHexString((id + 256)%256));
+ System.err.println("Unknown PDU: 0x" +
Integer.toHexString((id + 256)%256));
return false;
}
return true;
@@ -306,5 +391,10 @@
return ("Community: " + new String(community) +
", PDU: " + pdutype + ", OID: " + OID);
}
+
+ public boolean pduIsGet() {
+ return ((pdutype == RequestContainer.PDU_GET_THIS) ||
+ (pdutype == RequestContainer.PDU_GET_NEXT));
+ }
}
}
Modified: trunk/freenet/src/snmplib/SNMPStarter.java
===================================================================
--- trunk/freenet/src/snmplib/SNMPStarter.java 2006-02-03 23:46:58 UTC (rev
8002)
+++ trunk/freenet/src/snmplib/SNMPStarter.java 2006-02-04 02:48:11 UTC (rev
8003)
@@ -1,6 +1,5 @@
package snmplib;
-import snmplib.DataStatisticsInfo;
import freenet.io.comm.IOStatisticCollector;
/**
Added: trunk/freenet/src/snmplib/SNMPTimeTicks.java
===================================================================
--- trunk/freenet/src/snmplib/SNMPTimeTicks.java 2006-02-03 23:46:58 UTC
(rev 8002)
+++ trunk/freenet/src/snmplib/SNMPTimeTicks.java 2006-02-04 02:48:11 UTC
(rev 8003)
@@ -0,0 +1,27 @@
+package snmplib;
+
+public class SNMPTimeTicks {
+ private long ticks;
+
+ public SNMPTimeTicks(long ticks) {
+ this.ticks = ticks;
+ }
+
+ public long timeValue() {
+ return ticks;
+ }
+
+ public String toString() {
+ long rest = ticks;
+ long dec = ticks%100;
+ rest = rest/100;
+ long sec = ticks%60;
+ rest = rest/60;
+ long min = ticks%60;
+ rest = rest/60;
+ long hour = ticks%24;
+ rest = rest/24;
+ long day = ticks;
+ return day + ":" + hour + ":" + min + ":" + sec + "." + dec;
+ }
+}