added support for icmpv6 analysis / RPL

This commit is contained in:
joxe 2010-03-07 20:44:40 +00:00
parent 577056c452
commit c1ce8721d8
5 changed files with 117 additions and 17 deletions

View file

@ -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.30 2010/03/07 19:53:07 joxe Exp $
* $Id: RadioLogger.java,v 1.31 2010/03/07 20:44:40 joxe Exp $
*/
package se.sics.cooja.plugins;
@ -77,6 +77,7 @@ import se.sics.cooja.Simulation;
import se.sics.cooja.VisPlugin;
import se.sics.cooja.dialogs.TableColumnAdjuster;
import se.sics.cooja.interfaces.Radio;
import se.sics.cooja.plugins.analyzers.ICMPv6Analyzer;
import se.sics.cooja.plugins.analyzers.IEEE802154Analyzer;
import se.sics.cooja.plugins.analyzers.IPHCPacketAnalyzer;
import se.sics.cooja.plugins.analyzers.PacketAnalyzer;
@ -128,6 +129,7 @@ public class RadioLogger extends VisPlugin {
ArrayList<PacketAnalyzer> lowpanAnalyzers = new ArrayList<PacketAnalyzer>();
lowpanAnalyzers.add(new IEEE802154Analyzer());
lowpanAnalyzers.add(new IPHCPacketAnalyzer());
lowpanAnalyzers.add(new ICMPv6Analyzer());
model = new AbstractTableModel() {
private static final long serialVersionUID = 1692207305977527004L;
@ -421,11 +423,17 @@ public class RadioLogger extends VisPlugin {
analyze = false;
for (int i = 0; i < analyzers.size(); i++) {
PacketAnalyzer analyzer = analyzers.get(i);
if (analyzer.matchPacket(packet) && analyzer.analyzePacket(packet, brief, verbose)) {
/* continue another round if more bytes left */
analyze = packet.hasMoreData();
brief.append('|');
verbose.append("<p>");
if (analyzer.matchPacket(packet)) {
int res = analyzer.analyzePacket(packet, brief, verbose);
if (res != analyzer.ANALYSIS_OK_FINAL) {
/* continue another round if more bytes left */
analyze = packet.hasMoreData();
brief.append('|');
verbose.append("<p>");
} else {
/* this was the final - no analyzable payload possible here... */
return brief.length() > 0;
}
break;
}
}

View file

@ -0,0 +1,86 @@
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("<br>");
verbose.append("Code:" + code + "<br>");
} else if (type == 155) {
/* RPL */
brief.append("RPL ");
verbose.append("Type: RPL<br>");
switch(code) {
case RPL_CODE_DIS:
brief.append("DIS ");
verbose.append("Code: DIS<br>");
break;
case RPL_CODE_DIO:
brief.append("DIO ");
verbose.append("Code: DIO<br>");
break;
case RPL_CODE_DAO:
brief.append("DAO ");
verbose.append("Code: DAO<br>");
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;
}
}

View file

@ -42,7 +42,7 @@ public class IEEE802154Analyzer extends PacketAnalyzer {
/* create a 802.15.4 packet of the bytes and "dispatch" to the
* next handler
*/
public boolean analyzePacket(Packet packet, StringBuffer brief, StringBuffer verbose) {
public int analyzePacket(Packet packet, StringBuffer brief, StringBuffer verbose) {
int pos = packet.pos;
int type = packet.data[pos + 0] & 7;
// int security = (packet.data[pos + 0] >> 3) & 1;
@ -134,7 +134,7 @@ public class IEEE802154Analyzer extends PacketAnalyzer {
packet.llsender = sourceAddress;
packet.llreceiver = destAddress;
return true;
return ANALYSIS_OK_CONTINUE;
}
private void printAddress(StringBuffer sb, int type, byte[] addr) {

View file

@ -64,11 +64,11 @@ public class IPHCPacketAnalyzer extends PacketAnalyzer {
return (packet.get(0) & 0xe0) == IPHC_DISPATCH;
}
public boolean analyzePacket(Packet packet, StringBuffer brief,
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 false;
if (packet.size() < 3) return ANALYSIS_FAILED;
int tf = (packet.get(0) >> 3) & 0x03;
int nh = (packet.get(0) >> 2) & 0x01;
@ -375,7 +375,7 @@ public class IPHCPacketAnalyzer extends PacketAnalyzer {
break;
default:
// PRINTF("sicslowpan uncompress_hdr: error unsupported UDP compression\n");
return false;
return ANALYSIS_FAILED;
}
}
}
@ -400,11 +400,10 @@ public class IPHCPacketAnalyzer extends PacketAnalyzer {
/*--------------------------------------------- */
// packet.pos += cid == 1 ? 3 : 2;
String protoStr = "" + proto;
if (proto == PROTO_ICMP) protoStr = "ICMPv6";
else if (proto == PROTO_UDP) protoStr = "UDP";
if (proto == PROTO_ICMP) {
protoStr = "ICMPv6";
} else if (proto == PROTO_UDP) protoStr = "UDP";
else if (proto == PROTO_TCP) protoStr = "TCP";
verbose.append("<br><b>IPv6 ").append(protoStr).append("</b><br>");
@ -413,8 +412,9 @@ public class IPHCPacketAnalyzer extends PacketAnalyzer {
verbose.append(" to ");
printAddress(verbose, destAddress);
packet.lastDispatch = (byte) (proto & 0xff);
packet.level = NETWORK_LEVEL;
return true;
return ANALYSIS_OK_CONTINUE;
}
public static void printAddress(StringBuffer out, byte[] address) {

View file

@ -2,6 +2,10 @@ package se.sics.cooja.plugins.analyzers;
public abstract class PacketAnalyzer {
public static final int ANALYSIS_FAILED = -1;
public static final int ANALYSIS_OK_CONTINUE = 1;
public static final int ANALYSIS_OK_FINAL = 2;
public static final int RADIO_LEVEL = 0;
public static final int MAC_LEVEL = 1;
public static final int NETWORK_LEVEL = 2;
@ -17,6 +21,8 @@ public abstract class PacketAnalyzer {
byte[] llsender;
byte[] llreceiver;
byte lastDispatch = 0;
public Packet(byte[] data, int level) {
this.level = level;
this.data = data;
@ -78,5 +84,5 @@ public abstract class PacketAnalyzer {
public abstract boolean matchPacket(Packet packet);
public abstract boolean analyzePacket(Packet packet, StringBuffer brief, StringBuffer verbose);
public abstract int analyzePacket(Packet packet, StringBuffer brief, StringBuffer verbose);
}