diff --git a/tools/cooja/java/se/sics/cooja/plugins/RadioLogger.java b/tools/cooja/java/se/sics/cooja/plugins/RadioLogger.java index d38142aa9..d0af04e0f 100644 --- a/tools/cooja/java/se/sics/cooja/plugins/RadioLogger.java +++ b/tools/cooja/java/se/sics/cooja/plugins/RadioLogger.java @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: RadioLogger.java,v 1.34 2010/03/17 22:44:20 nifi Exp $ + * $Id: RadioLogger.java,v 1.35 2010/04/06 23:38:18 nifi Exp $ */ package se.sics.cooja.plugins; @@ -266,6 +266,7 @@ public class RadioLogger extends VisPlugin { prepareTooltipString(conn); } verboseBox.setText(conn.tooltip); + verboseBox.setCaretPosition(0); } } }); @@ -427,12 +428,16 @@ public class RadioLogger extends VisPlugin { if (packet.hasMoreData()) { byte[] payload = packet.getPayload(); brief.append(StringUtils.toHex(payload, 4)); + if (verbose.length() > 0) { + verbose.append("
");
+ }
verbose.append("Payload (")
.append(payload.length).append(" bytes)
") .append(StringUtils.hexDump(payload)) .append(""); } - conn.data = (data.length < 10 ? " " : "") + data.length + ": " + brief; + conn.data = (data.length < 100 ? (data.length < 10 ? " " : " ") : "") + + data.length + ": " + brief; if (verbose.length() > 0) { conn.tooltip = verbose.toString(); } @@ -450,16 +455,16 @@ public class RadioLogger extends VisPlugin { PacketAnalyzer analyzer = analyzers.get(i); if (analyzer.matchPacket(packet)) { int res = analyzer.analyzePacket(packet, brief, verbose); + if (packet.hasMoreData() && brief.length() > 0) { + brief.append('|'); + verbose.append("
");
- }
break;
}
}
diff --git a/tools/cooja/java/se/sics/cooja/plugins/analyzers/ICMPv6Analyzer.java b/tools/cooja/java/se/sics/cooja/plugins/analyzers/ICMPv6Analyzer.java
index 358534b29..1260d8c1d 100644
--- a/tools/cooja/java/se/sics/cooja/plugins/analyzers/ICMPv6Analyzer.java
+++ b/tools/cooja/java/se/sics/cooja/plugins/analyzers/ICMPv6Analyzer.java
@@ -1,86 +1,85 @@
-package se.sics.cooja.plugins.analyzers;
-
-public class ICMPv6Analyzer extends PacketAnalyzer {
-
- public static final byte ICMPv6_DISPATCH = 58;
-
- public static final int ECHO_REQUEST = 128;
- public static final int ECHO_REPLY = 129;
- public static final int GROUP_QUERY = 130;
- public static final int GROUP_REPORT = 131;
- public static final int GROUP_REDUCTION = 132;
- public static final int ROUTER_SOLICITATION = 133;
- public static final int ROUTER_ADVERTISEMENT = 134;
- public static final int NEIGHBOR_SOLICITATION = 135;
- public static final int NEIGHBOR_ADVERTISEMENT = 136;
-
- public static final int RPL_CODE_DIS = 1; /* DIS message */
- public static final int RPL_CODE_DIO = 2; /* DIO message */
- public static final int RPL_CODE_DAO = 4;/* DAO message */
-
- public static final int FLAG_ROUTER = 0x80;
- public static final int FLAG_SOLICITED = 0x40;
- public static final int FLAG_OVERRIDE = 0x20;
-
- public static final int ON_LINK = 0x80;
- public static final int AUTOCONFIG = 0x40;
-
- public static final int SOURCE_LINKADDR = 1;
- public static final int TARGET_LINKADDR = 2;
- public static final int PREFIX_INFO = 3;
- public static final int MTU_INFO = 5;
-
- public static final String[] TYPE_NAME = new String[] {
- "ECHO_REQUEST", "ECHO_REPLY",
- "GROUP_QUERY", "GROUP_REPORT", "GROUP_REDUCTION",
- "ROUTER_SOLICITATION", "ROUTER_ADVERTISEMENT",
- "NEIGHBOR_SOLICITATION", "NEIGHBOR_ADVERTISEMENT", "REDIRECT",
- "ROUTER RENUMBER", "NODE INFORMATION QUERY", "NODE INFORMATION RESPONSE"};
-
-
- public int analyzePacket(Packet packet, StringBuffer brief,
- StringBuffer verbose) {
- int type = packet.get(0) & 0xff;
- int code = packet.get(1) & 0xff;
- int checksum = ((packet.get(2) & 0xff) << 8) | packet.get(3) & 0xff;
-
- brief.append("ICMPv6 ");
- if (type >= 128 && (type - 128) < TYPE_NAME.length) {
- brief.append(TYPE_NAME[type - 128]).append(" ");
- brief.append(" " + code);
- verbose.append("Type: " + TYPE_NAME[type - 128]).append("
");
- verbose.append("Code:" + code + "
");
- } else if (type == 155) {
- /* RPL */
- brief.append("RPL ");
- verbose.append("Type: RPL
");
- switch(code) {
- case RPL_CODE_DIS:
- brief.append("DIS ");
- verbose.append("Code: DIS
");
- break;
- case RPL_CODE_DIO:
- brief.append("DIO ");
- verbose.append("Code: DIO
");
- break;
- case RPL_CODE_DAO:
- brief.append("DAO ");
- verbose.append("Code: DAO
");
- break;
- default:
- brief.append(" " + code);
- verbose.append("Code: " + code);
- }
- }
-
- /* remove type, code, crc */
- packet.consumeBytesStart(4);
- return ANALYSIS_OK_FINAL;
- }
-
- @Override
- public boolean matchPacket(Packet packet) {
- return packet.level == NETWORK_LEVEL && packet.lastDispatch == ICMPv6_DISPATCH;
- }
-
-}
+package se.sics.cooja.plugins.analyzers;
+
+public class ICMPv6Analyzer extends PacketAnalyzer {
+
+ public static final byte ICMPv6_DISPATCH = 58;
+
+ public static final int ECHO_REQUEST = 128;
+ public static final int ECHO_REPLY = 129;
+ public static final int GROUP_QUERY = 130;
+ public static final int GROUP_REPORT = 131;
+ public static final int GROUP_REDUCTION = 132;
+ public static final int ROUTER_SOLICITATION = 133;
+ public static final int ROUTER_ADVERTISEMENT = 134;
+ public static final int NEIGHBOR_SOLICITATION = 135;
+ public static final int NEIGHBOR_ADVERTISEMENT = 136;
+
+ public static final int RPL_CODE_DIS = 1; /* DIS message */
+ public static final int RPL_CODE_DIO = 2; /* DIO message */
+ public static final int RPL_CODE_DAO = 4;/* DAO message */
+
+ public static final int FLAG_ROUTER = 0x80;
+ public static final int FLAG_SOLICITED = 0x40;
+ public static final int FLAG_OVERRIDE = 0x20;
+
+ public static final int ON_LINK = 0x80;
+ public static final int AUTOCONFIG = 0x40;
+
+ public static final int SOURCE_LINKADDR = 1;
+ public static final int TARGET_LINKADDR = 2;
+ public static final int PREFIX_INFO = 3;
+ public static final int MTU_INFO = 5;
+
+ public static final String[] TYPE_NAME = new String[] {
+ "ECHO_REQUEST", "ECHO_REPLY",
+ "GROUP_QUERY", "GROUP_REPORT", "GROUP_REDUCTION",
+ "ROUTER_SOLICITATION", "ROUTER_ADVERTISEMENT",
+ "NEIGHBOR_SOLICITATION", "NEIGHBOR_ADVERTISEMENT", "REDIRECT",
+ "ROUTER RENUMBER", "NODE INFORMATION QUERY", "NODE INFORMATION RESPONSE"};
+
+
+ public int analyzePacket(Packet packet, StringBuffer brief,
+ StringBuffer verbose) {
+ int type = packet.get(0) & 0xff;
+ int code = packet.get(1) & 0xff;
+// int checksum = ((packet.get(2) & 0xff) << 8) | packet.get(3) & 0xff;
+
+ brief.append("ICMPv6 ");
+ if (type >= 128 && (type - 128) < TYPE_NAME.length) {
+ brief.append(TYPE_NAME[type - 128]).append(' ').append(code);
+ verbose.append("Type: ").append(TYPE_NAME[type - 128]);
+ verbose.append(" Code:").append(code);
+ } else if (type == 155) {
+ /* RPL */
+ brief.append("RPL ");
+ verbose.append("Type: RPL Code: ");
+ switch(code) {
+ case RPL_CODE_DIS:
+ brief.append("DIS");
+ verbose.append("DIS");
+ break;
+ case RPL_CODE_DIO:
+ brief.append("DIO");
+ verbose.append("DIO");
+ break;
+ case RPL_CODE_DAO:
+ brief.append("DAO");
+ verbose.append("DAO");
+ break;
+ default:
+ brief.append(code);
+ verbose.append(code);
+ }
+ }
+
+ /* remove type, code, crc */
+ packet.consumeBytesStart(4);
+ return ANALYSIS_OK_FINAL;
+ }
+
+ @Override
+ public boolean matchPacket(Packet packet) {
+ return packet.level == NETWORK_LEVEL && packet.lastDispatch == ICMPv6_DISPATCH;
+ }
+
+}
diff --git a/tools/cooja/java/se/sics/cooja/plugins/analyzers/IPHCPacketAnalyzer.java b/tools/cooja/java/se/sics/cooja/plugins/analyzers/IPHCPacketAnalyzer.java
index faa34c109..6e1332146 100644
--- a/tools/cooja/java/se/sics/cooja/plugins/analyzers/IPHCPacketAnalyzer.java
+++ b/tools/cooja/java/se/sics/cooja/plugins/analyzers/IPHCPacketAnalyzer.java
@@ -1,427 +1,427 @@
-package se.sics.cooja.plugins.analyzers;
-
-import se.sics.cooja.util.StringUtils;
-
-public class IPHCPacketAnalyzer extends PacketAnalyzer {
-
- public final static int SICSLOWPAN_UDP_PORT_MIN = 0xF0B0;
- public final static int SICSLOWPAN_UDP_PORT_MAX = 0xF0BF; /* F0B0 + 15 */
-
- public final static int SICSLOWPAN_DISPATCH_IPV6 = 0x41; /* 01000001 = 65 */
- public final static int SICSLOWPAN_DISPATCH_HC1 = 0x42; /* 01000010 = 66 */
- public final static int SICSLOWPAN_DISPATCH_IPHC = 0x60; /* 011xxxxx = ... */
- public final static int SICSLOWPAN_DISPATCH_FRAG1 = 0xc0; /* 1100= 0xxx */
- public final static int SICSLOWPAN_DISPATCH_FRAGN = 0xe0; /* 1110= 0xxx */
-
- /*
- * Values of fields within the IPHC encoding first byte
- * (C stands for compressed and I for inline)
- */
- public final static int SICSLOWPAN_IPHC_TC_C = 0x10;
- public final static int SICSLOWPAN_IPHC_FL_C = 0x08;
- public final static int SICSLOWPAN_IPHC_NH_C = 0x04;
- public final static int SICSLOWPAN_IPHC_TTL_1 = 0x01;
- public final static int SICSLOWPAN_IPHC_TTL_64 = 0x02;
- public final static int SICSLOWPAN_IPHC_TTL_255 = 0x03;
- public final static int SICSLOWPAN_IPHC_TTL_I = 0x00;
-
-
- /* Values of fields within the IPHC encoding second byte */
- public final static int SICSLOWPAN_IPHC_CID = 0x80;
-
- public final static int SICSLOWPAN_IPHC_SAC = 0x40;
- public final static int SICSLOWPAN_IPHC_SAM_00 = 0x00;
- public final static int SICSLOWPAN_IPHC_SAM_01 = 0x10;
- public final static int SICSLOWPAN_IPHC_SAM_10 = 0x20;
- public final static int SICSLOWPAN_IPHC_SAM_11 = 0x30;
-
- public final static int SICSLOWPAN_IPHC_M = 0x08;
- public final static int SICSLOWPAN_IPHC_DAC = 0x04;
- public final static int SICSLOWPAN_IPHC_DAM_00 = 0x00;
- public final static int SICSLOWPAN_IPHC_DAM_01 = 0x01;
- public final static int SICSLOWPAN_IPHC_DAM_10 = 0x02;
- public final static int SICSLOWPAN_IPHC_DAM_11 = 0x03;
-
- private static final int SICSLOWPAN_NDC_UDP_MASK = 0xf8;
- private static final int SICSLOWPAN_NHC_UDP_ID = 0xf0;
- private static final int SICSLOWPAN_NHC_UDP_C = 0xf3;
- private static final int SICSLOWPAN_NHC_UDP_I = 0xf0;
-
- public final static int PROTO_UDP = 17;
- public final static int PROTO_TCP = 6;
- public final static int PROTO_ICMP = 58;
-
-
- public final static byte[] UNSPECIFIED_ADDRESS =
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
-
- private static byte[][] addrContexts = new byte[][] {
- {(byte)0xaa, (byte)0xaa, 0, 0, 0, 0, 0, 0}
- };
-
- private static final int IPHC_DISPATCH = 0x60;
-
- public boolean matchPacket(Packet packet) {
- return (packet.get(0) & 0xe0) == IPHC_DISPATCH;
- }
-
- public int analyzePacket(Packet packet, StringBuffer brief,
- StringBuffer verbose) {
-
- /* if packet has less than 3 bytes it is not interesting ... */
- if (packet.size() < 3) return ANALYSIS_FAILED;
-
- int tf = (packet.get(0) >> 3) & 0x03;
- boolean nhc = (packet.get(0) & SICSLOWPAN_IPHC_NH_C) > 0;
- int hlim = (packet.get(0) & 0x03);
- int cid = (packet.get(1) >> 7) & 0x01;
- int sac = (packet.get(1) >> 6) & 0x01;
- int sam = (packet.get(1) >> 4) & 0x03;
- int m = (packet.get(1) >> 3) & 0x01;
- int dac = (packet.get(1) >> 2) & 0x01;
- int dam = packet.get(1) & 0x03;
- int sci = 0;
- int dci = 0;
-
- brief.append("IPHC");
-
- /* need to decompress while analyzing - add that later... */
-
- verbose.append("IPHC HC-06
");
- verbose.append("tf = " + tf + " nhc = " + nhc + " hlim = " + hlim
- + " cid = " + cid + " sac = " + sac + " sam = " + sam
- + " MCast = " + m + " dac = " + dac + " dam = " + dam + "
");
- if (cid == 1) {
- verbose.append("Contexts: sci=" + (packet.get(2) >> 4) + " dci="
- + (packet.get(2) & 0x0f) + "
");
- sci = packet.get(2) >> 4;
- dci = packet.get(2) & 0x0f;
- }
-
- int hc06_ptr = 2 + cid;
-
- int version = 6;
- int trafficClass = 0;
- int flowLabel = 0;
- int len = 0;
- int proto = 0;
- int ttl = 0;
- byte[] srcAddress = null;
- byte[] destAddress = null;
-
- int srcPort = 0;
- int destPort = 0;
-
- /* Traffic class and flow label */
- if((packet.get(0) & SICSLOWPAN_IPHC_FL_C) == 0) {
- /* Flow label are carried inline */
- if((packet.get(0) & SICSLOWPAN_IPHC_TC_C) == 0) {
- /* Traffic class is carried inline */
- flowLabel = packet.getInt(hc06_ptr + 1, 3);
- int tmp = packet.get(hc06_ptr);
- hc06_ptr += 4;
- /* hc06 format of tc is ECN | DSCP , original is DSCP | ECN */
- trafficClass = ((tmp >> 2) & 0x3f) | (tmp << 6) & (0x80 + 0x40);
- /* ECN rolled down two steps + lowest DSCP bits at top two bits */
- } else {
- /* highest flow label bits + ECN bits */
- int tmp = packet.get(hc06_ptr);
- trafficClass = (tmp >> 6) & 0x0f;
- flowLabel = packet.getInt(hc06_ptr + 1, 2);
- hc06_ptr += 3;
- }
- } else {
- /* Version is always 6! */
- /* Version and flow label are compressed */
- if((packet.get(0) & SICSLOWPAN_IPHC_TC_C) == 0) {
- /* Traffic class is inline */
- trafficClass =((packet.get(hc06_ptr) >> 6) & 0x03);
- trafficClass = (packet.get(hc06_ptr) << 2);
- hc06_ptr += 1;
- }
- }
-
- /* Next Header */
- if((packet.get(0) & SICSLOWPAN_IPHC_NH_C) == 0) {
- /* Next header is carried inline */
- proto = packet.get(hc06_ptr);
- hc06_ptr += 1;
- }
-
- /* Hop limit */
- switch(packet.get(0) & 0x03) {
- case SICSLOWPAN_IPHC_TTL_1:
- ttl = 1;
- break;
- case SICSLOWPAN_IPHC_TTL_64:
- ttl = 2;
- break;
- case SICSLOWPAN_IPHC_TTL_255:
- ttl = 255;
- break;
- case SICSLOWPAN_IPHC_TTL_I:
- ttl = packet.get(hc06_ptr);
- hc06_ptr += 1;
- break;
- }
-
- /* context based compression */
- if((packet.get(1) & SICSLOWPAN_IPHC_SAC) > 0) {
- /* Source address */
- byte[] context = null;
- if((packet.get(1) & SICSLOWPAN_IPHC_SAM_11) != SICSLOWPAN_IPHC_SAM_00) {
- context = addrContexts[sci];
- }
-
- switch(packet.get(1) & SICSLOWPAN_IPHC_SAM_11) {
- case SICSLOWPAN_IPHC_SAM_00:
- /* copy the unspecificed address */
- srcAddress = UNSPECIFIED_ADDRESS;
- break;
- case SICSLOWPAN_IPHC_SAM_01: /* 64 bits */
- /* copy prefix from context */
- srcAddress = new byte[16];
- System.arraycopy(context, 0, srcAddress, 0, 8);
- /* copy IID from packet */
- packet.copy(hc06_ptr, srcAddress, 8, 8);
- hc06_ptr += 8;
- break;
- case SICSLOWPAN_IPHC_SAM_10: /* 16 bits */
- /* unicast address */
- srcAddress = new byte[16];
- System.arraycopy(context, 0, srcAddress, 0, 8);
- /* copy 6 NULL bytes then 2 last bytes of IID */
- packet.copy(hc06_ptr, srcAddress, 14, 2);
- hc06_ptr += 2;
- break;
- case SICSLOWPAN_IPHC_SAM_11: /* 0-bits */
- /* copy prefix from context */
- srcAddress = new byte[16];
- System.arraycopy(context, 0, srcAddress, 0, 8);
- /* infer IID from L2 address */
- System.arraycopy(packet.llsender, 0, srcAddress,
- 16 - packet.llsender.length, packet.llsender.length);
- break;
- }
- /* end context based compression */
- } else {
- /* no compression and link local */
- switch(packet.get(1) & SICSLOWPAN_IPHC_SAM_11) {
- case SICSLOWPAN_IPHC_SAM_00: /* 128 bits */
- /* copy whole address from packet */
- srcAddress = new byte[16];
- packet.copy(hc06_ptr, srcAddress, 0, 16);
- hc06_ptr += 16;
- break;
- case SICSLOWPAN_IPHC_SAM_01: /* 64 bits */
- srcAddress = new byte[16];
- srcAddress[0] = (byte) 0xfe;
- srcAddress[1] = (byte) 0x80;
- /* copy IID from packet */
- packet.copy(hc06_ptr, srcAddress, 8, 8);
- hc06_ptr += 8;
- break;
- case SICSLOWPAN_IPHC_SAM_10: /* 16 bits */
- srcAddress = new byte[16];
- srcAddress[0] = (byte) 0xfe;
- srcAddress[1] = (byte) 0x80;
- packet.copy(hc06_ptr, srcAddress, 14, 2);
- hc06_ptr += 2;
- break;
- case SICSLOWPAN_IPHC_SAM_11: /* 0 bits */
- /* setup link-local address */
- srcAddress = new byte[16];
- srcAddress[0] = (byte) 0xfe;
- srcAddress[1] = (byte) 0x80;
- /* infer IID from L2 address */
- System.arraycopy(packet.llsender, 0, srcAddress,
- 16 - packet.llsender.length, packet.llsender.length);
- break;
- }
- }
-
- /* Destination address */
-
- /* multicast compression */
- if((packet.get(1) & SICSLOWPAN_IPHC_M) != 0) {
- /* context based multicast compression */
- if((packet.get(1) & SICSLOWPAN_IPHC_DAC) != 0) {
- /* TODO: implement this */
- } else {
- /* non-context based multicast compression */
- switch (packet.get(1) & SICSLOWPAN_IPHC_DAM_11) {
- case SICSLOWPAN_IPHC_DAM_00: /* 128 bits */
- /* copy whole address from packet */
- destAddress = new byte[16];
- packet.copy(hc06_ptr, destAddress, 0, 16);
- hc06_ptr += 16;
- break;
- case SICSLOWPAN_IPHC_DAM_01: /* 48 bits FFXX::00XX:XXXX:XXXX */
- destAddress = new byte[16];
- destAddress[0] = (byte) 0xff;
- destAddress[1] = packet.get(hc06_ptr);
- packet.copy(hc06_ptr + 1, destAddress, 11, 5);
- hc06_ptr += 6;
- break;
- case SICSLOWPAN_IPHC_DAM_10: /* 32 bits FFXX::00XX:XXXX */
- destAddress = new byte[16];
- destAddress[0] = (byte) 0xff;
- destAddress[1] = packet.get(hc06_ptr);
- packet.copy(hc06_ptr + 1, destAddress, 13, 3);
- hc06_ptr += 4;
- break;
- case SICSLOWPAN_IPHC_DAM_11: /* 8 bits FF02::00XX */
- destAddress = new byte[16];
- destAddress[0] = (byte) 0xff;
- destAddress[1] = (byte) 0x02;
- destAddress[15] = packet.get(hc06_ptr);
- hc06_ptr++;
- break;
- }
- }
- } else {
- /* no multicast */
- /* Context based */
- if((packet.get(1) & SICSLOWPAN_IPHC_DAC) != 0) {
- byte[] context = addrContexts[dci];
-
- switch (packet.get(1) & SICSLOWPAN_IPHC_DAM_11) {
- case SICSLOWPAN_IPHC_DAM_01: /* 64 bits */
- destAddress = new byte[16];
- System.arraycopy(context, 0, destAddress, 0, 8);
- /* copy IID from packet */
- packet.copy(hc06_ptr, destAddress, 8, 8);
- hc06_ptr += 8;
- break;
- case SICSLOWPAN_IPHC_DAM_10: /* 16 bits */
- /* unicast address */
- destAddress = new byte[16];
- System.arraycopy(context, 0, destAddress, 0, 8);
- /* copy IID from packet */
- packet.copy(hc06_ptr, destAddress, 14, 2);
- hc06_ptr += 2;
- break;
- case SICSLOWPAN_IPHC_DAM_11: /* 0 bits */
- /* unicast address */
- destAddress = new byte[16];
- System.arraycopy(context, 0, destAddress, 0, 8);
- /* infer IID from L2 address */
- System.arraycopy(packet.llreceiver, 0, destAddress,
- 16 - packet.llreceiver.length, packet.llreceiver.length);
- break;
- }
- } else {
- /* not context based => link local M = 0, DAC = 0 - same as SAC */
- switch (packet.get(1) & SICSLOWPAN_IPHC_DAM_11) {
- case SICSLOWPAN_IPHC_DAM_00: /* 128 bits */
- destAddress = new byte[16];
- packet.copy(hc06_ptr, destAddress, 0, 16);
- hc06_ptr += 16;
- break;
- case SICSLOWPAN_IPHC_DAM_01: /* 64 bits */
- destAddress = new byte[16];
- destAddress[0] = (byte) 0xfe;
- destAddress[1] = (byte) 0x80;
- packet.copy(hc06_ptr, destAddress, 8, 8);
- hc06_ptr += 8;
- break;
- case SICSLOWPAN_IPHC_DAM_10: /* 16 bits */
- destAddress = new byte[16];
- destAddress[0] = (byte) 0xfe;
- destAddress[1] = (byte) 0x80;
- packet.copy(hc06_ptr, destAddress, 14, 2);
- hc06_ptr += 2;
- break;
- case SICSLOWPAN_IPHC_DAM_11: /* 0 bits */
- destAddress = new byte[16];
- destAddress[0] = (byte) 0xfe;
- destAddress[1] = (byte) 0x80;
- System.arraycopy(packet.llreceiver, 0, destAddress,
- 16 - packet.llreceiver.length, packet.llreceiver.length);
- break;
- }
- }
- }
-
- /* Next header processing - continued */
- if(nhc) {
- /* TODO: check if this is correct in hc-06 */
- /* The next header is compressed, NHC is following */
- if((packet.get(hc06_ptr) & SICSLOWPAN_NDC_UDP_MASK) == SICSLOWPAN_NHC_UDP_ID) {
- proto = PROTO_UDP;
- switch(packet.get(hc06_ptr)) {
- case (byte) SICSLOWPAN_NHC_UDP_C:
- /* 1 byte for NHC, 1 byte for ports, 2 bytes chksum */
- srcPort = SICSLOWPAN_UDP_PORT_MIN + (packet.get(hc06_ptr + 1) >> 4);
- destPort = SICSLOWPAN_UDP_PORT_MIN + (packet.get(hc06_ptr + 1) & 0x0F);
-// memcpy(&SICSLOWPAN_UDP_BUF->udpchksum, hc06_ptr + 2, 2);
-// PRINTF("IPHC: Uncompressed UDP ports (4): %x, %x\n",
-// SICSLOWPAN_UDP_BUF->srcport, SICSLOWPAN_UDP_BUF->destport);
- hc06_ptr += 4;
- break;
- case (byte) SICSLOWPAN_NHC_UDP_I:
- /* 1 byte for NHC, 4 byte for ports, 2 bytes chksum */
- srcPort = packet.getInt(hc06_ptr + 1, 2);
- destPort = packet.getInt(hc06_ptr + 3, 2);
-// memcpy(&SICSLOWPAN_UDP_BUF->udpchksum, hc06_ptr + 5, 2);
-// PRINTF("IPHC: Uncompressed UDP ports (7): %x, %x\n",
-// SICSLOWPAN_UDP_BUF->srcport, SICSLOWPAN_UDP_BUF->destport);
-
- hc06_ptr += 7;
- break;
- default:
-// PRINTF("sicslowpan uncompress_hdr: error unsupported UDP compression\n");
- return ANALYSIS_FAILED;
- }
- }
- }
-
- packet.pos += hc06_ptr;
-
-// /* IP length field. */
-// if(ip_len == 0) {
-// /* This is not a fragmented packet */
-// SICSLOWPAN_IP_BUF->len[0] = 0;
-// SICSLOWPAN_IP_BUF->len[1] = packetbuf_datalen() - rime_hdr_len + uncomp_hdr_len - UIP_IPH_LEN;
-// } else {
-// /* This is a 1st fragment */
-// SICSLOWPAN_IP_BUF->len[0] = (ip_len - UIP_IPH_LEN) >> 8;
-// SICSLOWPAN_IP_BUF->len[1] = (ip_len - UIP_IPH_LEN) & 0x00FF;
-// }
-
-// /* length field in UDP header */
-// if(SICSLOWPAN_IP_BUF->proto == UIP_PROTO_UDP) {
-// memcpy(&SICSLOWPAN_UDP_BUF->udplen, ipBuf + len[0], 2);
-// }
-
- /*--------------------------------------------- */
-
- String protoStr = "" + proto;
- if (proto == PROTO_ICMP) {
- protoStr = "ICMPv6";
- } else if (proto == PROTO_UDP) protoStr = "UDP";
- else if (proto == PROTO_TCP) protoStr = "TCP";
-
- verbose.append("
IPv6 ").append(protoStr).append("
");
- verbose.append("From ");
- printAddress(verbose, srcAddress);
- verbose.append(" to ");
- printAddress(verbose, destAddress);
-
- packet.lastDispatch = (byte) (proto & 0xff);
- packet.level = NETWORK_LEVEL;
- return ANALYSIS_OK_CONTINUE;
- }
-
- public static void printAddress(StringBuffer out, byte[] address) {
- for (int i = 0; i < 16; i+=2) {
- out.append(StringUtils.toHex((byte) (address[i] & 0xff)) +
- StringUtils.toHex((byte) (address[i + 1] & 0xff)));
- if (i < 14) {
- out.append(":");
- }
- }
- }
-
-
-}
+package se.sics.cooja.plugins.analyzers;
+
+import se.sics.cooja.util.StringUtils;
+
+public class IPHCPacketAnalyzer extends PacketAnalyzer {
+
+ public final static int SICSLOWPAN_UDP_PORT_MIN = 0xF0B0;
+ public final static int SICSLOWPAN_UDP_PORT_MAX = 0xF0BF; /* F0B0 + 15 */
+
+ public final static int SICSLOWPAN_DISPATCH_IPV6 = 0x41; /* 01000001 = 65 */
+ public final static int SICSLOWPAN_DISPATCH_HC1 = 0x42; /* 01000010 = 66 */
+ public final static int SICSLOWPAN_DISPATCH_IPHC = 0x60; /* 011xxxxx = ... */
+ public final static int SICSLOWPAN_DISPATCH_FRAG1 = 0xc0; /* 1100= 0xxx */
+ public final static int SICSLOWPAN_DISPATCH_FRAGN = 0xe0; /* 1110= 0xxx */
+
+ /*
+ * Values of fields within the IPHC encoding first byte
+ * (C stands for compressed and I for inline)
+ */
+ public final static int SICSLOWPAN_IPHC_TC_C = 0x10;
+ public final static int SICSLOWPAN_IPHC_FL_C = 0x08;
+ public final static int SICSLOWPAN_IPHC_NH_C = 0x04;
+ public final static int SICSLOWPAN_IPHC_TTL_1 = 0x01;
+ public final static int SICSLOWPAN_IPHC_TTL_64 = 0x02;
+ public final static int SICSLOWPAN_IPHC_TTL_255 = 0x03;
+ public final static int SICSLOWPAN_IPHC_TTL_I = 0x00;
+
+
+ /* Values of fields within the IPHC encoding second byte */
+ public final static int SICSLOWPAN_IPHC_CID = 0x80;
+
+ public final static int SICSLOWPAN_IPHC_SAC = 0x40;
+ public final static int SICSLOWPAN_IPHC_SAM_00 = 0x00;
+ public final static int SICSLOWPAN_IPHC_SAM_01 = 0x10;
+ public final static int SICSLOWPAN_IPHC_SAM_10 = 0x20;
+ public final static int SICSLOWPAN_IPHC_SAM_11 = 0x30;
+
+ public final static int SICSLOWPAN_IPHC_M = 0x08;
+ public final static int SICSLOWPAN_IPHC_DAC = 0x04;
+ public final static int SICSLOWPAN_IPHC_DAM_00 = 0x00;
+ public final static int SICSLOWPAN_IPHC_DAM_01 = 0x01;
+ public final static int SICSLOWPAN_IPHC_DAM_10 = 0x02;
+ public final static int SICSLOWPAN_IPHC_DAM_11 = 0x03;
+
+ private static final int SICSLOWPAN_NDC_UDP_MASK = 0xf8;
+ private static final int SICSLOWPAN_NHC_UDP_ID = 0xf0;
+ private static final int SICSLOWPAN_NHC_UDP_C = 0xf3;
+ private static final int SICSLOWPAN_NHC_UDP_I = 0xf0;
+
+ public final static int PROTO_UDP = 17;
+ public final static int PROTO_TCP = 6;
+ public final static int PROTO_ICMP = 58;
+
+
+ public final static byte[] UNSPECIFIED_ADDRESS =
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+
+ private static byte[][] addrContexts = new byte[][] {
+ {(byte)0xaa, (byte)0xaa, 0, 0, 0, 0, 0, 0}
+ };
+
+ private static final int IPHC_DISPATCH = 0x60;
+
+ public boolean matchPacket(Packet packet) {
+ return (packet.get(0) & 0xe0) == IPHC_DISPATCH;
+ }
+
+ public int analyzePacket(Packet packet, StringBuffer brief,
+ StringBuffer verbose) {
+
+ /* if packet has less than 3 bytes it is not interesting ... */
+ if (packet.size() < 3) return ANALYSIS_FAILED;
+
+ int tf = (packet.get(0) >> 3) & 0x03;
+ boolean nhc = (packet.get(0) & SICSLOWPAN_IPHC_NH_C) > 0;
+ int hlim = (packet.get(0) & 0x03);
+ int cid = (packet.get(1) >> 7) & 0x01;
+ int sac = (packet.get(1) >> 6) & 0x01;
+ int sam = (packet.get(1) >> 4) & 0x03;
+ int m = (packet.get(1) >> 3) & 0x01;
+ int dac = (packet.get(1) >> 2) & 0x01;
+ int dam = packet.get(1) & 0x03;
+ int sci = 0;
+ int dci = 0;
+
+ brief.append("IPHC");
+
+ /* need to decompress while analyzing - add that later... */
+
+ verbose.append("IPHC HC-06
");
+ verbose.append("tf = " + tf + " nhc = " + nhc + " hlim = " + hlim
+ + " cid = " + cid + " sac = " + sac + " sam = " + sam
+ + " MCast = " + m + " dac = " + dac + " dam = " + dam);
+ if (cid == 1) {
+ verbose.append("
Contexts: sci=" + (packet.get(2) >> 4) + " dci="
+ + (packet.get(2) & 0x0f));
+ sci = packet.get(2) >> 4;
+ dci = packet.get(2) & 0x0f;
+ }
+
+ int hc06_ptr = 2 + cid;
+
+ int version = 6;
+ int trafficClass = 0;
+ int flowLabel = 0;
+ int len = 0;
+ int proto = 0;
+ int ttl = 0;
+ byte[] srcAddress = null;
+ byte[] destAddress = null;
+
+ int srcPort = 0;
+ int destPort = 0;
+
+ /* Traffic class and flow label */
+ if((packet.get(0) & SICSLOWPAN_IPHC_FL_C) == 0) {
+ /* Flow label are carried inline */
+ if((packet.get(0) & SICSLOWPAN_IPHC_TC_C) == 0) {
+ /* Traffic class is carried inline */
+ flowLabel = packet.getInt(hc06_ptr + 1, 3);
+ int tmp = packet.get(hc06_ptr);
+ hc06_ptr += 4;
+ /* hc06 format of tc is ECN | DSCP , original is DSCP | ECN */
+ trafficClass = ((tmp >> 2) & 0x3f) | (tmp << 6) & (0x80 + 0x40);
+ /* ECN rolled down two steps + lowest DSCP bits at top two bits */
+ } else {
+ /* highest flow label bits + ECN bits */
+ int tmp = packet.get(hc06_ptr);
+ trafficClass = (tmp >> 6) & 0x0f;
+ flowLabel = packet.getInt(hc06_ptr + 1, 2);
+ hc06_ptr += 3;
+ }
+ } else {
+ /* Version is always 6! */
+ /* Version and flow label are compressed */
+ if((packet.get(0) & SICSLOWPAN_IPHC_TC_C) == 0) {
+ /* Traffic class is inline */
+ trafficClass =((packet.get(hc06_ptr) >> 6) & 0x03);
+ trafficClass = (packet.get(hc06_ptr) << 2);
+ hc06_ptr += 1;
+ }
+ }
+
+ /* Next Header */
+ if((packet.get(0) & SICSLOWPAN_IPHC_NH_C) == 0) {
+ /* Next header is carried inline */
+ proto = packet.get(hc06_ptr);
+ hc06_ptr += 1;
+ }
+
+ /* Hop limit */
+ switch(packet.get(0) & 0x03) {
+ case SICSLOWPAN_IPHC_TTL_1:
+ ttl = 1;
+ break;
+ case SICSLOWPAN_IPHC_TTL_64:
+ ttl = 2;
+ break;
+ case SICSLOWPAN_IPHC_TTL_255:
+ ttl = 255;
+ break;
+ case SICSLOWPAN_IPHC_TTL_I:
+ ttl = packet.get(hc06_ptr);
+ hc06_ptr += 1;
+ break;
+ }
+
+ /* context based compression */
+ if((packet.get(1) & SICSLOWPAN_IPHC_SAC) > 0) {
+ /* Source address */
+ byte[] context = null;
+ if((packet.get(1) & SICSLOWPAN_IPHC_SAM_11) != SICSLOWPAN_IPHC_SAM_00) {
+ context = addrContexts[sci];
+ }
+
+ switch(packet.get(1) & SICSLOWPAN_IPHC_SAM_11) {
+ case SICSLOWPAN_IPHC_SAM_00:
+ /* copy the unspecificed address */
+ srcAddress = UNSPECIFIED_ADDRESS;
+ break;
+ case SICSLOWPAN_IPHC_SAM_01: /* 64 bits */
+ /* copy prefix from context */
+ srcAddress = new byte[16];
+ System.arraycopy(context, 0, srcAddress, 0, 8);
+ /* copy IID from packet */
+ packet.copy(hc06_ptr, srcAddress, 8, 8);
+ hc06_ptr += 8;
+ break;
+ case SICSLOWPAN_IPHC_SAM_10: /* 16 bits */
+ /* unicast address */
+ srcAddress = new byte[16];
+ System.arraycopy(context, 0, srcAddress, 0, 8);
+ /* copy 6 NULL bytes then 2 last bytes of IID */
+ packet.copy(hc06_ptr, srcAddress, 14, 2);
+ hc06_ptr += 2;
+ break;
+ case SICSLOWPAN_IPHC_SAM_11: /* 0-bits */
+ /* copy prefix from context */
+ srcAddress = new byte[16];
+ System.arraycopy(context, 0, srcAddress, 0, 8);
+ /* infer IID from L2 address */
+ System.arraycopy(packet.llsender, 0, srcAddress,
+ 16 - packet.llsender.length, packet.llsender.length);
+ break;
+ }
+ /* end context based compression */
+ } else {
+ /* no compression and link local */
+ switch(packet.get(1) & SICSLOWPAN_IPHC_SAM_11) {
+ case SICSLOWPAN_IPHC_SAM_00: /* 128 bits */
+ /* copy whole address from packet */
+ srcAddress = new byte[16];
+ packet.copy(hc06_ptr, srcAddress, 0, 16);
+ hc06_ptr += 16;
+ break;
+ case SICSLOWPAN_IPHC_SAM_01: /* 64 bits */
+ srcAddress = new byte[16];
+ srcAddress[0] = (byte) 0xfe;
+ srcAddress[1] = (byte) 0x80;
+ /* copy IID from packet */
+ packet.copy(hc06_ptr, srcAddress, 8, 8);
+ hc06_ptr += 8;
+ break;
+ case SICSLOWPAN_IPHC_SAM_10: /* 16 bits */
+ srcAddress = new byte[16];
+ srcAddress[0] = (byte) 0xfe;
+ srcAddress[1] = (byte) 0x80;
+ packet.copy(hc06_ptr, srcAddress, 14, 2);
+ hc06_ptr += 2;
+ break;
+ case SICSLOWPAN_IPHC_SAM_11: /* 0 bits */
+ /* setup link-local address */
+ srcAddress = new byte[16];
+ srcAddress[0] = (byte) 0xfe;
+ srcAddress[1] = (byte) 0x80;
+ /* infer IID from L2 address */
+ System.arraycopy(packet.llsender, 0, srcAddress,
+ 16 - packet.llsender.length, packet.llsender.length);
+ break;
+ }
+ }
+
+ /* Destination address */
+
+ /* multicast compression */
+ if((packet.get(1) & SICSLOWPAN_IPHC_M) != 0) {
+ /* context based multicast compression */
+ if((packet.get(1) & SICSLOWPAN_IPHC_DAC) != 0) {
+ /* TODO: implement this */
+ } else {
+ /* non-context based multicast compression */
+ switch (packet.get(1) & SICSLOWPAN_IPHC_DAM_11) {
+ case SICSLOWPAN_IPHC_DAM_00: /* 128 bits */
+ /* copy whole address from packet */
+ destAddress = new byte[16];
+ packet.copy(hc06_ptr, destAddress, 0, 16);
+ hc06_ptr += 16;
+ break;
+ case SICSLOWPAN_IPHC_DAM_01: /* 48 bits FFXX::00XX:XXXX:XXXX */
+ destAddress = new byte[16];
+ destAddress[0] = (byte) 0xff;
+ destAddress[1] = packet.get(hc06_ptr);
+ packet.copy(hc06_ptr + 1, destAddress, 11, 5);
+ hc06_ptr += 6;
+ break;
+ case SICSLOWPAN_IPHC_DAM_10: /* 32 bits FFXX::00XX:XXXX */
+ destAddress = new byte[16];
+ destAddress[0] = (byte) 0xff;
+ destAddress[1] = packet.get(hc06_ptr);
+ packet.copy(hc06_ptr + 1, destAddress, 13, 3);
+ hc06_ptr += 4;
+ break;
+ case SICSLOWPAN_IPHC_DAM_11: /* 8 bits FF02::00XX */
+ destAddress = new byte[16];
+ destAddress[0] = (byte) 0xff;
+ destAddress[1] = (byte) 0x02;
+ destAddress[15] = packet.get(hc06_ptr);
+ hc06_ptr++;
+ break;
+ }
+ }
+ } else {
+ /* no multicast */
+ /* Context based */
+ if((packet.get(1) & SICSLOWPAN_IPHC_DAC) != 0) {
+ byte[] context = addrContexts[dci];
+
+ switch (packet.get(1) & SICSLOWPAN_IPHC_DAM_11) {
+ case SICSLOWPAN_IPHC_DAM_01: /* 64 bits */
+ destAddress = new byte[16];
+ System.arraycopy(context, 0, destAddress, 0, 8);
+ /* copy IID from packet */
+ packet.copy(hc06_ptr, destAddress, 8, 8);
+ hc06_ptr += 8;
+ break;
+ case SICSLOWPAN_IPHC_DAM_10: /* 16 bits */
+ /* unicast address */
+ destAddress = new byte[16];
+ System.arraycopy(context, 0, destAddress, 0, 8);
+ /* copy IID from packet */
+ packet.copy(hc06_ptr, destAddress, 14, 2);
+ hc06_ptr += 2;
+ break;
+ case SICSLOWPAN_IPHC_DAM_11: /* 0 bits */
+ /* unicast address */
+ destAddress = new byte[16];
+ System.arraycopy(context, 0, destAddress, 0, 8);
+ /* infer IID from L2 address */
+ System.arraycopy(packet.llreceiver, 0, destAddress,
+ 16 - packet.llreceiver.length, packet.llreceiver.length);
+ break;
+ }
+ } else {
+ /* not context based => link local M = 0, DAC = 0 - same as SAC */
+ switch (packet.get(1) & SICSLOWPAN_IPHC_DAM_11) {
+ case SICSLOWPAN_IPHC_DAM_00: /* 128 bits */
+ destAddress = new byte[16];
+ packet.copy(hc06_ptr, destAddress, 0, 16);
+ hc06_ptr += 16;
+ break;
+ case SICSLOWPAN_IPHC_DAM_01: /* 64 bits */
+ destAddress = new byte[16];
+ destAddress[0] = (byte) 0xfe;
+ destAddress[1] = (byte) 0x80;
+ packet.copy(hc06_ptr, destAddress, 8, 8);
+ hc06_ptr += 8;
+ break;
+ case SICSLOWPAN_IPHC_DAM_10: /* 16 bits */
+ destAddress = new byte[16];
+ destAddress[0] = (byte) 0xfe;
+ destAddress[1] = (byte) 0x80;
+ packet.copy(hc06_ptr, destAddress, 14, 2);
+ hc06_ptr += 2;
+ break;
+ case SICSLOWPAN_IPHC_DAM_11: /* 0 bits */
+ destAddress = new byte[16];
+ destAddress[0] = (byte) 0xfe;
+ destAddress[1] = (byte) 0x80;
+ System.arraycopy(packet.llreceiver, 0, destAddress,
+ 16 - packet.llreceiver.length, packet.llreceiver.length);
+ break;
+ }
+ }
+ }
+
+ /* Next header processing - continued */
+ if(nhc) {
+ /* TODO: check if this is correct in hc-06 */
+ /* The next header is compressed, NHC is following */
+ if((packet.get(hc06_ptr) & SICSLOWPAN_NDC_UDP_MASK) == SICSLOWPAN_NHC_UDP_ID) {
+ proto = PROTO_UDP;
+ switch(packet.get(hc06_ptr)) {
+ case (byte) SICSLOWPAN_NHC_UDP_C:
+ /* 1 byte for NHC, 1 byte for ports, 2 bytes chksum */
+ srcPort = SICSLOWPAN_UDP_PORT_MIN + (packet.get(hc06_ptr + 1) >> 4);
+ destPort = SICSLOWPAN_UDP_PORT_MIN + (packet.get(hc06_ptr + 1) & 0x0F);
+// memcpy(&SICSLOWPAN_UDP_BUF->udpchksum, hc06_ptr + 2, 2);
+// PRINTF("IPHC: Uncompressed UDP ports (4): %x, %x\n",
+// SICSLOWPAN_UDP_BUF->srcport, SICSLOWPAN_UDP_BUF->destport);
+ hc06_ptr += 4;
+ break;
+ case (byte) SICSLOWPAN_NHC_UDP_I:
+ /* 1 byte for NHC, 4 byte for ports, 2 bytes chksum */
+ srcPort = packet.getInt(hc06_ptr + 1, 2);
+ destPort = packet.getInt(hc06_ptr + 3, 2);
+// memcpy(&SICSLOWPAN_UDP_BUF->udpchksum, hc06_ptr + 5, 2);
+// PRINTF("IPHC: Uncompressed UDP ports (7): %x, %x\n",
+// SICSLOWPAN_UDP_BUF->srcport, SICSLOWPAN_UDP_BUF->destport);
+
+ hc06_ptr += 7;
+ break;
+ default:
+// PRINTF("sicslowpan uncompress_hdr: error unsupported UDP compression\n");
+ return ANALYSIS_FAILED;
+ }
+ }
+ }
+
+ packet.pos += hc06_ptr;
+
+// /* IP length field. */
+// if(ip_len == 0) {
+// /* This is not a fragmented packet */
+// SICSLOWPAN_IP_BUF->len[0] = 0;
+// SICSLOWPAN_IP_BUF->len[1] = packetbuf_datalen() - rime_hdr_len + uncomp_hdr_len - UIP_IPH_LEN;
+// } else {
+// /* This is a 1st fragment */
+// SICSLOWPAN_IP_BUF->len[0] = (ip_len - UIP_IPH_LEN) >> 8;
+// SICSLOWPAN_IP_BUF->len[1] = (ip_len - UIP_IPH_LEN) & 0x00FF;
+// }
+
+// /* length field in UDP header */
+// if(SICSLOWPAN_IP_BUF->proto == UIP_PROTO_UDP) {
+// memcpy(&SICSLOWPAN_UDP_BUF->udplen, ipBuf + len[0], 2);
+// }
+
+ /*--------------------------------------------- */
+
+ String protoStr = "" + proto;
+ if (proto == PROTO_ICMP) {
+ protoStr = "ICMPv6";
+ } else if (proto == PROTO_UDP) protoStr = "UDP";
+ else if (proto == PROTO_TCP) protoStr = "TCP";
+
+ verbose.append("
IPv6 ").append(protoStr).append("
");
+ verbose.append("From ");
+ printAddress(verbose, srcAddress);
+ verbose.append(" to ");
+ printAddress(verbose, destAddress);
+
+ packet.lastDispatch = (byte) (proto & 0xff);
+ packet.level = NETWORK_LEVEL;
+ return ANALYSIS_OK_CONTINUE;
+ }
+
+ public static void printAddress(StringBuffer out, byte[] address) {
+ for (int i = 0; i < 16; i+=2) {
+ out.append(StringUtils.toHex((byte) (address[i] & 0xff)) +
+ StringUtils.toHex((byte) (address[i + 1] & 0xff)));
+ if (i < 14) {
+ out.append(":");
+ }
+ }
+ }
+
+
+}