diff --git a/tools/cooja/java/org/contikios/cooja/plugins/RadioLogger.java b/tools/cooja/java/org/contikios/cooja/plugins/RadioLogger.java index f73a4af8c..2205f1c68 100644 --- a/tools/cooja/java/org/contikios/cooja/plugins/RadioLogger.java +++ b/tools/cooja/java/org/contikios/cooja/plugins/RadioLogger.java @@ -27,7 +27,6 @@ * SUCH DAMAGE. * */ - package org.contikios.cooja.plugins; import java.awt.BorderLayout; @@ -111,6 +110,7 @@ import org.contikios.cooja.util.StringUtils; @ClassDescription("Radio messages") @PluginType(PluginType.SIM_PLUGIN) public class RadioLogger extends VisPlugin { + private static Logger logger = Logger.getLogger(RadioLogger.class); private static final long serialVersionUID = -6927091711697081353L; @@ -141,7 +141,7 @@ public class RadioLogger extends VisPlugin { private Observer radioMediumObserver; private AbstractTableModel model; - private HashMap analyzerMap = new HashMap(); + private HashMap analyzerMap = new HashMap(); private String analyzerName = null; private ArrayList analyzers = null; private IEEE802154Analyzer analyzerWithPcap; @@ -290,14 +290,13 @@ public class RadioLogger extends VisPlugin { /* TODO This entry may represent several hidden connections */ RadioConnectionLog conn = connections.get(modelRowIndex); if (modelColumnIndex == COLUMN_TIME) { - return - "" + - "Start time (us): " + conn.startTime + - "
" + - "End time (us): " + conn.endTime + - "

" + - "Duration (us): " + (conn.endTime - conn.startTime) + - ""; + return "" + + "Start time (us): " + conn.startTime + + "
" + + "End time (us): " + conn.endTime + + "

" + + "Duration (us): " + (conn.endTime - conn.startTime) + + ""; } else if (modelColumnIndex == COLUMN_FROM) { return conn.connection.getSource().getMote().toString(); } else if (modelColumnIndex == COLUMN_TO) { @@ -337,7 +336,7 @@ public class RadioLogger extends VisPlugin { } formatTimeString = !formatTimeString; dataTable.getColumnModel().getColumn(COLUMN_TIME).setHeaderValue( - dataTable.getModel().getColumnName(COLUMN_TIME)); + dataTable.getModel().getColumnName(COLUMN_TIME)); repaint(); } }); @@ -346,16 +345,16 @@ public class RadioLogger extends VisPlugin { public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_SPACE) { showInAllAction.actionPerformed(null); - } else if (e.getKeyCode() == KeyEvent.VK_F && - (e.getModifiers() & KeyEvent.CTRL_MASK) != 0) { - searchField.setVisible(true); - searchField.requestFocus(); - searchField.selectAll(); - revalidate(); + } else if (e.getKeyCode() == KeyEvent.VK_F + && (e.getModifiers() & KeyEvent.CTRL_MASK) != 0) { + searchField.setVisible(true); + searchField.requestFocus(); + searchField.selectAll(); + revalidate(); } else if (e.getKeyCode() == KeyEvent.VK_ESCAPE) { - searchField.setVisible(false); - dataTable.requestFocus(); - revalidate(); + searchField.setVisible(false); + dataTable.requestFocus(); + revalidate(); } } }); @@ -367,21 +366,21 @@ public class RadioLogger extends VisPlugin { dataTable.setRowSorter(logFilter); dataTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() { - public void valueChanged(ListSelectionEvent e) { - int row = dataTable.getSelectedRow(); - if (row < 0) { - return; - } - int modelRowIndex = dataTable.convertRowIndexToModel(row); - if (modelRowIndex >= 0) { - RadioConnectionLog conn = connections.get(modelRowIndex); - if (conn.tooltip == null) { - prepareTooltipString(conn); - } - verboseBox.setText(conn.tooltip); - verboseBox.setCaretPosition(0); - } + public void valueChanged(ListSelectionEvent e) { + int row = dataTable.getSelectedRow(); + if (row < 0) { + return; } + int modelRowIndex = dataTable.convertRowIndexToModel(row); + if (modelRowIndex >= 0) { + RadioConnectionLog conn = connections.get(modelRowIndex); + if (conn.tooltip == null) { + prepareTooltipString(conn); + } + verboseBox.setText(conn.tooltip); + verboseBox.setCaretPosition(0); + } + } }); // Set data column width greedy dataTable.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN); @@ -407,7 +406,6 @@ public class RadioLogger extends VisPlugin { fileMenu.add(new JMenuItem(saveAction)); - JPopupMenu popupMenu = new JPopupMenu(); JMenu focusMenu = new JMenu("Show in"); @@ -418,7 +416,6 @@ public class RadioLogger extends VisPlugin { popupMenu.add(focusMenu); //a group of radio button menu items - ButtonGroup group = new ButtonGroup(); JRadioButtonMenuItem rbMenuItem = new JRadioButtonMenuItem( createAnalyzerAction("No Analyzer", "none", null, true)); @@ -426,7 +423,7 @@ public class RadioLogger extends VisPlugin { analyzerMenu.add(rbMenuItem); rbMenuItem = new JRadioButtonMenuItem(createAnalyzerAction( - "6LoWPAN Analyzer", "6lowpan", lowpanAnalyzers, false)); + "6LoWPAN Analyzer", "6lowpan", lowpanAnalyzers, false)); group.add(rbMenuItem); analyzerMenu.add(rbMenuItem); @@ -436,20 +433,20 @@ public class RadioLogger extends VisPlugin { analyzerMenu.add(rbMenuItem); /* Load additional analyzers specified by projects (cooja.config) */ - String[] projectAnalyzerSuites = - gui.getProjectConfig().getStringArrayValue(RadioLogger.class, "ANALYZERS"); + String[] projectAnalyzerSuites + = gui.getProjectConfig().getStringArrayValue(RadioLogger.class, "ANALYZERS"); if (projectAnalyzerSuites != null) { for (String suiteName: projectAnalyzerSuites) { if (suiteName == null || suiteName.trim().isEmpty()) { continue; } - Class suiteClass = - gui.tryLoadClass(RadioLogger.this, RadioLoggerAnalyzerSuite.class, suiteName); + Class suiteClass + = gui.tryLoadClass(RadioLogger.this, RadioLoggerAnalyzerSuite.class, suiteName); try { RadioLoggerAnalyzerSuite suite = suiteClass.newInstance(); ArrayList suiteAnalyzers = suite.getAnalyzers(); rbMenuItem = new JRadioButtonMenuItem(createAnalyzerAction( - suite.getDescription(), suiteName, suiteAnalyzers, false)); + suite.getDescription(), suiteName, suiteAnalyzers, false)); group.add(rbMenuItem); analyzerMenu.add(rbMenuItem); logger.debug("Loaded radio logger analyzers: " + suite.getDescription()); @@ -473,20 +470,20 @@ public class RadioLogger extends VisPlugin { searchField.setVisible(false); searchField.addKeyListener(new KeyAdapter() { public void keyPressed(KeyEvent e) { - if (e.getKeyCode() == KeyEvent.VK_ENTER) { - searchSelectNext( - searchField.getText(), - (e.getModifiers() & KeyEvent.SHIFT_MASK) != 0); - } else if (e.getKeyCode() == KeyEvent.VK_ESCAPE) { - searchField.setVisible(false); - dataTable.requestFocus(); - revalidate(); + if (e.getKeyCode() == KeyEvent.VK_ENTER) { + searchSelectNext( + searchField.getText(), + (e.getModifiers() & KeyEvent.SHIFT_MASK) != 0); + } else if (e.getKeyCode() == KeyEvent.VK_ESCAPE) { + searchField.setVisible(false); + dataTable.requestFocus(); + revalidate(); } } }); splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, - new JScrollPane(dataTable), new JScrollPane(verboseBox)); + new JScrollPane(dataTable), new JScrollPane(verboseBox)); splitPane.setOneTouchExpandable(true); splitPane.setDividerLocation(150); add(BorderLayout.NORTH, searchField); @@ -528,8 +525,8 @@ public class RadioLogger extends VisPlugin { setTitle("Radio messages: showing " + dataTable.getRowCount() + "/" + connections.size() + " packets"); } }); - } - }); + } + }); setSize(500, 300); try { @@ -543,41 +540,41 @@ public class RadioLogger extends VisPlugin { super.startPlugin(); rebuildAllEntries(); } - - private void searchSelectNext(String text, boolean reverse) { - if (text.isEmpty()) { - return; - } - int row = dataTable.getSelectedRow(); + + private void searchSelectNext(String text, boolean reverse) { + if (text.isEmpty()) { + return; + } + int row = dataTable.getSelectedRow(); if (row < 0) { - row = 0; + row = 0; } if (!reverse) { - row++; + row++; } else { - row--; + row--; } int rows = dataTable.getModel().getRowCount(); - for (int i=0; i < rows; i++) { - int r; - if (!reverse) { - r = (row + i + rows)%rows; - } else { - r = (row - i + rows)%rows; - } - String val = (String) dataTable.getModel().getValueAt(r, COLUMN_DATA); - if (!val.contains(text)) { - continue; - } - dataTable.setRowSelectionInterval(r,r); - dataTable.scrollRectToVisible(dataTable.getCellRect(r, COLUMN_DATA, true)); - searchField.setBackground(Color.WHITE); - return; + for (int i = 0; i < rows; i++) { + int r; + if (!reverse) { + r = (row + i + rows) % rows; + } else { + r = (row - i + rows) % rows; + } + String val = (String) dataTable.getModel().getValueAt(r, COLUMN_DATA); + if (!val.contains(text)) { + continue; + } + dataTable.setRowSelectionInterval(r, r); + dataTable.scrollRectToVisible(dataTable.getCellRect(r, COLUMN_DATA, true)); + searchField.setBackground(Color.WHITE); + return; } - searchField.setBackground(Color.RED); - } + searchField.setBackground(Color.RED); + } /** * Selects a logged radio packet close to the given time. @@ -590,29 +587,29 @@ public class RadioLogger extends VisPlugin { if (dataTable.getRowCount() == 0) { return; } - for (int ai=0; ai < model.getRowCount(); ai++) { + for (int ai = 0; ai < model.getRowCount(); ai++) { int index = dataTable.convertRowIndexToModel(ai); if (connections.get(index).endTime < time) { continue; } - + dataTable.scrollRectToVisible(dataTable.getCellRect(ai, 0, true)); dataTable.setRowSelectionInterval(ai, ai); return; } - dataTable.scrollRectToVisible(dataTable.getCellRect(dataTable.getRowCount()-1, 0, true)); - dataTable.setRowSelectionInterval(dataTable.getRowCount()-1, dataTable.getRowCount()-1); + dataTable.scrollRectToVisible(dataTable.getCellRect(dataTable.getRowCount() - 1, 0, true)); + dataTable.setRowSelectionInterval(dataTable.getRowCount() - 1, dataTable.getRowCount() - 1); } }); } private void applyFilter() { - for(RadioConnectionLog conn: connections) { + for (RadioConnectionLog conn: connections) { conn.data = null; conn.tooltip = null; conn.hides = 0; conn.hiddenBy = null; - } + } try { logFilter.setRowFilter(null); @@ -623,18 +620,18 @@ public class RadioLogger extends VisPlugin { byte[] currentData = current.packet.getPacketData(); if (!showDuplicates && row > 0) { - RadioConnectionLog previous = connections.get(row-1); + RadioConnectionLog previous = connections.get(row - 1); byte[] previousData = previous.packet.getPacketData(); - if (!showDuplicates && - Arrays.equals(previousData, currentData) && - previous.connection.getSource() == current.connection.getSource() && - Arrays.equals(previous.connection.getAllDestinations(), current.connection.getAllDestinations())) { - if (connections.get(row-1).hiddenBy == null) { - connections.get(row-1).hides++; - connections.get(row).hiddenBy = connections.get(row-1); + if (!showDuplicates + && Arrays.equals(previousData, currentData) + && previous.connection.getSource() == current.connection.getSource() + && Arrays.equals(previous.connection.getAllDestinations(), current.connection.getAllDestinations())) { + if (connections.get(row - 1).hiddenBy == null) { + connections.get(row - 1).hides++; + connections.get(row).hiddenBy = connections.get(row - 1); } else { - connections.get(row-1).hiddenBy.hides++; - connections.get(row).hiddenBy = connections.get(row-1).hiddenBy; + connections.get(row - 1).hiddenBy.hides++; + connections.get(row).hiddenBy = connections.get(row - 1).hiddenBy; } return false; } @@ -661,7 +658,7 @@ public class RadioLogger extends VisPlugin { if (conn.packet == null) { data = null; } else if (conn.packet instanceof ConvertedRadioPacket) { - data = ((ConvertedRadioPacket)conn.packet).getOriginalPacketData(); + data = ((ConvertedRadioPacket) conn.packet).getOriginalPacketData(); } else { data = conn.packet.getPacketData(); } @@ -677,56 +674,56 @@ public class RadioLogger extends VisPlugin { PacketAnalyzer.Packet packet = new PacketAnalyzer.Packet(data, PacketAnalyzer.MAC_LEVEL); if (analyzePacket(packet, brief, verbose)) { - 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 < 100 ? (data.length < 10 ? " " : " ") : "") - + data.length + ": " + brief; + if (packet.hasMoreData()) { + byte[] payload = packet.getPayload(); + brief.append(StringUtils.toHex(payload, 4)); if (verbose.length() > 0) { - conn.tooltip = verbose.toString(); + verbose.append("

"); } + verbose.append("Payload (") + .append(payload.length).append(" bytes)

")
+                .append(StringUtils.hexDump(payload))
+                .append("
"); + } + conn.data = (data.length < 100 ? (data.length < 10 ? " " : " ") : "") + + data.length + ": " + brief; + if (verbose.length() > 0) { + conn.tooltip = verbose.toString(); + } } else { - conn.data = data.length + ": 0x" + StringUtils.toHex(data, 4); + conn.data = data.length + ": 0x" + StringUtils.toHex(data, 4); } } private boolean analyzePacket(PacketAnalyzer.Packet packet, StringBuffer brief, StringBuffer verbose) { - if (analyzers == null) return false; - try { - boolean analyze = true; - while (analyze) { - analyze = false; - for (int i = 0; i < analyzers.size(); i++) { - 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("
"); - } - if (res != PacketAnalyzer.ANALYSIS_OK_CONTINUE) { - /* this was the final or the analysis failed - no analyzable payload possible here... */ - return brief.length() > 0; - } - /* continue another round if more bytes left */ - analyze = packet.hasMoreData(); - break; - } + if (analyzers == null) return false; + try { + boolean analyze = true; + while (analyze) { + analyze = false; + for (int i = 0; i < analyzers.size(); i++) { + 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("
"); + } + if (res != PacketAnalyzer.ANALYSIS_OK_CONTINUE) { + /* this was the final or the analysis failed - no analyzable payload possible here... */ + return brief.length() > 0; + } + /* continue another round if more bytes left */ + analyze = packet.hasMoreData(); + break; } + } } - } catch (Exception e) { - logger.debug("Error when analyzing packet: " + e.getMessage(), e); - return false; - } - return brief.length() > 0; + } catch (Exception e) { + logger.debug("Error when analyzing packet: " + e.getMessage(), e); + return false; + } + return brief.length() > 0; } private void prepareTooltipString(RadioConnectionLog conn) { @@ -737,29 +734,29 @@ public class RadioLogger extends VisPlugin { } if (packet instanceof ConvertedRadioPacket && packet.getPacketData().length > 0) { - byte[] original = ((ConvertedRadioPacket)packet).getOriginalPacketData(); - byte[] converted = ((ConvertedRadioPacket)packet).getPacketData(); - conn.tooltip = "" + - "Packet data (" + original.length + " bytes)
" + - "
" + StringUtils.hexDump(original) + "
" + - "
" + - "Cross-level packet data (" + converted.length + " bytes)
" + - "
" + StringUtils.hexDump(converted) + "
" + - "
"; + byte[] original = ((ConvertedRadioPacket) packet).getOriginalPacketData(); + byte[] converted = ((ConvertedRadioPacket) packet).getPacketData(); + conn.tooltip = "" + + "Packet data (" + original.length + " bytes)
" + + "
" + StringUtils.hexDump(original) + "
" + + "
" + + "Cross-level packet data (" + converted.length + " bytes)
" + + "
" + StringUtils.hexDump(converted) + "
" + + "
"; } else if (packet instanceof ConvertedRadioPacket) { - byte[] original = ((ConvertedRadioPacket)packet).getOriginalPacketData(); - conn.tooltip = "" + - "Packet data (" + original.length + " bytes)
" + - "
" + StringUtils.hexDump(original) + "
" + - "
" + - "No cross-level conversion available
" + - "
"; + byte[] original = ((ConvertedRadioPacket) packet).getOriginalPacketData(); + conn.tooltip = "" + + "Packet data (" + original.length + " bytes)
" + + "
" + StringUtils.hexDump(original) + "
" + + "
" + + "No cross-level conversion available
" + + "
"; } else { byte[] data = packet.getPacketData(); - conn.tooltip = "" + - "Packet data (" + data.length + " bytes)
" + - "
" + StringUtils.hexDump(data) + "
" + - "
"; + conn.tooltip = "" + + "Packet data (" + data.length + " bytes)
" + + "
" + StringUtils.hexDump(data) + "
" + + "
"; } } @@ -784,7 +781,7 @@ public class RadioLogger extends VisPlugin { element = new Element("showdups"); element.addContent(Boolean.toString(showDuplicates)); config.add(element); - + element = new Element("hidenodests"); element.addContent(Boolean.toString(hideNoDestinationPackets)); config.add(element); @@ -796,7 +793,7 @@ public class RadioLogger extends VisPlugin { } if (aliases != null) { - for (Object key: aliases.keySet()) { + for (Object key : aliases.keySet()) { element = new Element("alias"); element.setAttribute("payload", (String) key); element.setAttribute("alias", (String) aliases.get(key)); @@ -853,11 +850,12 @@ public class RadioLogger extends VisPlugin { } private class RadioConnectionLog { + long startTime; long endTime; RadioConnection connection; RadioPacket packet; - + RadioConnectionLog hiddenBy = null; int hides = 0; @@ -865,14 +863,13 @@ public class RadioLogger extends VisPlugin { String tooltip = null; public String toString() { - if (data == null) { - RadioLogger.this.prepareDataString(this); - } - return - Long.toString(startTime / Simulation.MILLISECOND) + "\t" + - connection.getSource().getMote().getID() + "\t" + - getDestString(this) + "\t" + - data; + if (data == null) { + RadioLogger.this.prepareDataString(this); + } + return Long.toString(startTime / Simulation.MILLISECOND) + "\t" + + connection.getSource().getMote().getID() + "\t" + + getDestString(this) + "\t" + + data; } } @@ -888,13 +885,13 @@ public class RadioLogger extends VisPlugin { for (Radio dest: dests) { sb.append(dest.getMote().getID()).append(','); } - sb.setLength(sb.length()-1); + sb.setLength(sb.length() - 1); return sb.toString(); } private void rebuildAllEntries() { applyFilter(); - + if (connections.size() > 0) { model.fireTableRowsUpdated(0, connections.size() - 1); } @@ -903,23 +900,23 @@ public class RadioLogger extends VisPlugin { setTitle("Radio messages: showing " + dataTable.getRowCount() + "/" + connections.size() + " packets"); simulation.getCooja().getDesktopPane().repaint(); } - - private Action createAnalyzerAction(String name, final String actionName, - final ArrayList analyzerList, boolean selected) { - Action action = new AbstractAction(name) { - private static final long serialVersionUID = -608913700422638454L; - public void actionPerformed(ActionEvent event) { - if (analyzers != analyzerList) { - analyzers = analyzerList; - analyzerName = actionName; - rebuildAllEntries(); - } + private Action createAnalyzerAction(String name, final String actionName, + final ArrayList analyzerList, boolean selected) { + Action action = new AbstractAction(name) { + private static final long serialVersionUID = -608913700422638454L; + + public void actionPerformed(ActionEvent event) { + if (analyzers != analyzerList) { + analyzers = analyzerList; + analyzerName = actionName; + rebuildAllEntries(); } - }; - action.putValue(Action.SELECTED_KEY, selected ? Boolean.TRUE : Boolean.FALSE); - analyzerMap.put(actionName, action); - return action; + } + }; + action.putValue(Action.SELECTED_KEY, selected ? Boolean.TRUE : Boolean.FALSE); + analyzerMap.put(actionName, action); + return action; } private Action clearAction = new AbstractAction("Clear") { @@ -961,7 +958,7 @@ public class RadioLogger extends VisPlugin { Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); StringBuilder sb = new StringBuilder(); - for(int i=0; i < connections.size(); i++) { + for (int i = 0; i < connections.size(); i++) { sb.append(connections.get(i).toString() + "\n"); } @@ -984,12 +981,12 @@ public class RadioLogger extends VisPlugin { if (saveFile.exists()) { String s1 = "Overwrite"; String s2 = "Cancel"; - Object[] options = { s1, s2 }; + Object[] options = {s1, s2}; int n = JOptionPane.showOptionDialog( - Cooja.getTopParentContainer(), - "A file with the same name already exists.\nDo you want to remove it?", - "Overwrite existing file?", JOptionPane.YES_NO_OPTION, - JOptionPane.QUESTION_MESSAGE, null, options, s1); + Cooja.getTopParentContainer(), + "A file with the same name already exists.\nDo you want to remove it?", + "Overwrite existing file?", JOptionPane.YES_NO_OPTION, + JOptionPane.QUESTION_MESSAGE, null, options, s1); if (n != JOptionPane.YES_OPTION) { return; } @@ -1002,7 +999,7 @@ public class RadioLogger extends VisPlugin { try { PrintWriter outStream = new PrintWriter(new FileWriter(saveFile)); - for(int i=0; i < connections.size(); i++) { + for (int i = 0; i < connections.size(); i++) { outStream.print(connections.get(i).toString() + "\n"); } outStream.close(); @@ -1016,6 +1013,7 @@ public class RadioLogger extends VisPlugin { private Action timeLineAction = new AbstractAction("Timeline") { private static final long serialVersionUID = -4035633464748224192L; + public void actionPerformed(ActionEvent e) { int selectedRow = dataTable.getSelectedRow(); if (selectedRow < 0) return; @@ -1026,12 +1024,12 @@ public class RadioLogger extends VisPlugin { Plugin[] plugins = simulation.getCooja().getStartedPlugins(); for (Plugin p: plugins) { - if (!(p instanceof TimeLine)) { - continue; - } + if (!(p instanceof TimeLine)) { + continue; + } /* Select simulation time */ - TimeLine plugin = (TimeLine) p; + TimeLine plugin = (TimeLine) p; plugin.trySelectTime(time); } } @@ -1039,6 +1037,7 @@ public class RadioLogger extends VisPlugin { private Action logListenerAction = new AbstractAction("Mote output") { private static final long serialVersionUID = 1985006491187878651L; + public void actionPerformed(ActionEvent e) { int selectedRow = dataTable.getSelectedRow(); if (selectedRow < 0) return; @@ -1049,12 +1048,12 @@ public class RadioLogger extends VisPlugin { Plugin[] plugins = simulation.getCooja().getStartedPlugins(); for (Plugin p: plugins) { - if (!(p instanceof LogListener)) { - continue; - } + if (!(p instanceof LogListener)) { + continue; + } /* Select simulation time */ - LogListener plugin = (LogListener) p; + LogListener plugin = (LogListener) p; plugin.trySelectTime(time); } } @@ -1062,9 +1061,11 @@ public class RadioLogger extends VisPlugin { private Action showInAllAction = new AbstractAction("Timeline and mote output") { private static final long serialVersionUID = -3888292108886138128L; + { - putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0, true)); + putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0, true)); } + public void actionPerformed(ActionEvent e) { timeLineAction.actionPerformed(null); logListenerAction.actionPerformed(null); @@ -1087,15 +1088,15 @@ public class RadioLogger extends VisPlugin { } String alias = (String) JOptionPane.showInputDialog( - Cooja.getTopParentContainer(), - "Enter alias for all packets with identical payload.\n" + - "An empty string removes the current alias.\n\n" + - connections.get(selectedRow).data + "\n", - "Create packet payload alias", - JOptionPane.QUESTION_MESSAGE, - null, - null, - current); + Cooja.getTopParentContainer(), + "Enter alias for all packets with identical payload.\n" + + "An empty string removes the current alias.\n\n" + + connections.get(selectedRow).data + "\n", + "Create packet payload alias", + JOptionPane.QUESTION_MESSAGE, + null, + null, + current); if (alias == null) { /* Cancelled */ return; @@ -1141,16 +1142,16 @@ public class RadioLogger extends VisPlugin { }; public String getConnectionsString() { - StringBuilder sb = new StringBuilder(); - RadioConnectionLog[] cs = connections.toArray(new RadioConnectionLog[0]); - for(RadioConnectionLog c: cs) { + StringBuilder sb = new StringBuilder(); + RadioConnectionLog[] cs = connections.toArray(new RadioConnectionLog[0]); + for (RadioConnectionLog c : cs) { sb.append(c.toString() + "\n"); } return sb.toString(); - }; + } public void saveConnectionsToFile(String fileName) { StringUtils.saveToFile(new File(fileName), getConnectionsString()); - }; + } } diff --git a/tools/cooja/java/org/contikios/cooja/plugins/analyzers/ICMPv6Analyzer.java b/tools/cooja/java/org/contikios/cooja/plugins/analyzers/ICMPv6Analyzer.java index a8ea5e8b0..f1e3b0aa0 100644 --- a/tools/cooja/java/org/contikios/cooja/plugins/analyzers/ICMPv6Analyzer.java +++ b/tools/cooja/java/org/contikios/cooja/plugins/analyzers/ICMPv6Analyzer.java @@ -2,99 +2,101 @@ package org.contikios.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 byte ICMPv6_DISPATCH = 58; - public static final int RPL_CODE_DIS = 0; /* DIS message */ - public static final int RPL_CODE_DIO = 1; /* DIO message */ - public static final int RPL_CODE_DAO = 2;/* DAO message */ - public static final int RPL_CODE_DAO_ACK = 3;/* DAO ACK 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 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 ON_LINK = 0x80; - public static final int AUTOCONFIG = 0x40; + public static final int RPL_CODE_DIS = 0; /* DIS message */ + public static final int RPL_CODE_DIO = 1; /* DIO message */ + public static final int RPL_CODE_DAO = 2;/* DAO message */ + public static final int RPL_CODE_DAO_ACK = 3;/* DAO ACK message */ - 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 static final int FLAG_ROUTER = 0x80; + public static final int FLAG_SOLICITED = 0x40; + public static final int FLAG_OVERRIDE = 0x20; - - public int analyzePacket(Packet packet, StringBuffer brief, - StringBuffer verbose) { - int type = packet.get(0) & 0xff; - int code = packet.get(1) & 0xff; + 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
"); - - int instanceID = packet.get(4) & 0xff; - int version = packet.get(5) & 0xff; - int rank = ((packet.get(6) & 0xff) << 8) + (packet.get(7) & 0xff); - int mop = (packet.get(8) >> 3) & 0x07; - int dtsn = packet.get(9); - - verbose.append(" InstanceID: " + instanceID + " Version: " + version + - " Rank:" + rank + " MOP: " + mop + " DTSN: " + dtsn); - packet.consumeBytesStart(8); + 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; - case RPL_CODE_DAO_ACK: - brief.append("DAO ACK"); - verbose.append("DAO ACK"); - break; - default: - brief.append(code); - verbose.append(code); - } - } + int instanceID = packet.get(4) & 0xff; + int version = packet.get(5) & 0xff; + int rank = ((packet.get(6) & 0xff) << 8) + (packet.get(7) & 0xff); + int mop = (packet.get(8) >> 3) & 0x07; + int dtsn = packet.get(9); - /* remove type, code, crc */ - packet.consumeBytesStart(4); - return ANALYSIS_OK_FINAL; + verbose.append(" InstanceID: " + instanceID + + " Version: " + version + + " Rank:" + rank + + " MOP: " + mop + + " DTSN: " + dtsn); + packet.consumeBytesStart(8); + + break; + case RPL_CODE_DAO: + brief.append("DAO"); + verbose.append("DAO"); + break; + case RPL_CODE_DAO_ACK: + brief.append("DAO ACK"); + verbose.append("DAO ACK"); + break; + default: + brief.append(code); + verbose.append(code); + } } - @Override - public boolean matchPacket(Packet packet) { - return packet.level == APPLICATION_LEVEL && packet.lastDispatch == ICMPv6_DISPATCH; - } + /* remove type, code, crc */ + packet.consumeBytesStart(4); + return ANALYSIS_OK_FINAL; + } + + @Override + public boolean matchPacket(Packet packet) { + return packet.level == APPLICATION_LEVEL && packet.lastDispatch == ICMPv6_DISPATCH; + } } diff --git a/tools/cooja/java/org/contikios/cooja/plugins/analyzers/IEEE802154Analyzer.java b/tools/cooja/java/org/contikios/cooja/plugins/analyzers/IEEE802154Analyzer.java index d15903d51..4175a2be4 100644 --- a/tools/cooja/java/org/contikios/cooja/plugins/analyzers/IEEE802154Analyzer.java +++ b/tools/cooja/java/org/contikios/cooja/plugins/analyzers/IEEE802154Analyzer.java @@ -7,175 +7,174 @@ import org.contikios.cooja.util.StringUtils; public class IEEE802154Analyzer extends PacketAnalyzer { - /* TODO: fix this to be correct */ - public static final int NO_ADDRESS = 0; - public static final int RSV_ADDRESS = 1; - public static final int SHORT_ADDRESS = 2; - public static final int LONG_ADDRESS = 3; + /* TODO: fix this to be correct */ + public static final int NO_ADDRESS = 0; + public static final int RSV_ADDRESS = 1; + public static final int SHORT_ADDRESS = 2; + public static final int LONG_ADDRESS = 3; - public static final int BEACONFRAME = 0x00; - public static final int DATAFRAME = 0x01; - public static final int ACKFRAME = 0x02; - public static final int CMDFRAME = 0x03; + public static final int BEACONFRAME = 0x00; + public static final int DATAFRAME = 0x01; + public static final int ACKFRAME = 0x02; + public static final int CMDFRAME = 0x03; // private static final byte[] BROADCAST_ADDR = {(byte)0xff, (byte)0xff}; - - private static final String[] typeS = {"-", "D", "A"}; - private static final String[] typeVerbose = {"BEACON", "DATA", "ACK"}; - private PcapExporter pcapExporter; + private static final String[] typeS = {"-", "D", "A"}; + private static final String[] typeVerbose = {"BEACON", "DATA", "ACK"}; + private PcapExporter pcapExporter; // private int defaultAddressMode = LONG_ADDRESS; // private byte seqNo = 0; - // private int myPanID = 0xabcd; - - public IEEE802154Analyzer(boolean pcap) { - if (pcap) try { - pcapExporter = new PcapExporter(); - } catch (IOException e) { - e.printStackTrace(); - } + public IEEE802154Analyzer(boolean pcap) { + if (pcap) { + try { + pcapExporter = new PcapExporter(); + } catch (IOException e) { + e.printStackTrace(); + } } + } - public void setPcapFile(File pcapFile) { - if (pcapExporter != null) { - try { - pcapExporter.openPcap(pcapFile); - } catch (IOException e) { - System.err.println("Could not open pcap file"); - e.printStackTrace(); - } + public void setPcapFile(File pcapFile) { + if (pcapExporter != null) { + try { + pcapExporter.openPcap(pcapFile); + } catch (IOException e) { + System.err.println("Could not open pcap file"); + e.printStackTrace(); + } + } + } + + public boolean matchPacket(Packet packet) { + return packet.level == MAC_LEVEL; + } + + /* this protocol always have network level packets as payload */ + public int nextLevel(byte[] packet, int level) { + return NETWORK_LEVEL; + } + /* create a 802.15.4 packet of the bytes and "dispatch" to the + * next handler + */ + + public int analyzePacket(Packet packet, StringBuffer brief, StringBuffer verbose) { + + if (pcapExporter != null) { + try { + pcapExporter.exportPacketData(packet.getPayload()); + } catch (IOException e) { + System.err.println("Could not export PCap data"); + e.printStackTrace(); } } - public boolean matchPacket(Packet packet) { - return packet.level == MAC_LEVEL; - } - - /* this protocol always have network level packets as payload */ - public int nextLevel(byte[] packet, int level) { - return NETWORK_LEVEL; - } - /* create a 802.15.4 packet of the bytes and "dispatch" to the - * next handler - */ - public int analyzePacket(Packet packet, StringBuffer brief, StringBuffer verbose) { - - if (pcapExporter != null) { - try { - pcapExporter.exportPacketData(packet.getPayload()); - } catch (IOException e) { - System.err.println("Could not export PCap data"); - e.printStackTrace(); - } - } - - int pos = packet.pos; - int type = packet.data[pos + 0] & 7; + int pos = packet.pos; + int type = packet.data[pos + 0] & 7; // int security = (packet.data[pos + 0] >> 3) & 1; // int pending = (packet.data[pos + 0] >> 4) & 1; // int ackRequired = (packet.data[pos + 0] >> 5) & 1; - int panCompression = (packet.data[pos + 0]>> 6) & 1; - int destAddrMode = (packet.data[pos + 1] >> 2) & 3; + int panCompression = (packet.data[pos + 0] >> 6) & 1; + int destAddrMode = (packet.data[pos + 1] >> 2) & 3; // int frameVersion = (packet.data[pos + 1] >> 4) & 3; - int srcAddrMode = (packet.data[pos + 1] >> 6) & 3; - int seqNumber = packet.data[pos + 2] & 0xff; - int destPanID = 0; - int srcPanID = 0; - byte[] sourceAddress = null; - byte[] destAddress = null; + int srcAddrMode = (packet.data[pos + 1] >> 6) & 3; + int seqNumber = packet.data[pos + 2] & 0xff; + int destPanID = 0; + int srcPanID = 0; + byte[] sourceAddress = null; + byte[] destAddress = null; - pos += 3; + pos += 3; - if (destAddrMode > 0) { - destPanID = (packet.data[pos] & 0xff) + ((packet.data[pos + 1] & 0xff) << 8); - pos += 2; - if (destAddrMode == SHORT_ADDRESS) { - destAddress = new byte[2]; - destAddress[1] = packet.data[pos]; - destAddress[0] = packet.data[pos + 1]; - pos += 2; - } else if (destAddrMode == LONG_ADDRESS) { - destAddress = new byte[8]; - for (int i = 0; i < 8; i++) { - destAddress[i] = packet.data[pos + 7 - i]; - } - pos += 8; - } + if (destAddrMode > 0) { + destPanID = (packet.data[pos] & 0xff) + ((packet.data[pos + 1] & 0xff) << 8); + pos += 2; + if (destAddrMode == SHORT_ADDRESS) { + destAddress = new byte[2]; + destAddress[1] = packet.data[pos]; + destAddress[0] = packet.data[pos + 1]; + pos += 2; + } else if (destAddrMode == LONG_ADDRESS) { + destAddress = new byte[8]; + for (int i = 0; i < 8; i++) { + destAddress[i] = packet.data[pos + 7 - i]; } + pos += 8; + } + } - if (srcAddrMode > 0) { - if (panCompression == 0){ - srcPanID = (packet.data[pos] & 0xff) + ((packet.data[pos + 1] & 0xff) << 8); - pos += 2; - } else { - srcPanID = destPanID; - } - if (srcAddrMode == SHORT_ADDRESS) { - sourceAddress = new byte[2]; - sourceAddress[1] = packet.data[pos]; - sourceAddress[0] = packet.data[pos + 1]; - pos += 2; - } else if (srcAddrMode == LONG_ADDRESS) { - sourceAddress = new byte[8]; - for (int i = 0; i < 8; i++) { - sourceAddress[i] = packet.data[pos + 7 - i]; - } - pos += 8; - } + if (srcAddrMode > 0) { + if (panCompression == 0) { + srcPanID = (packet.data[pos] & 0xff) + ((packet.data[pos + 1] & 0xff) << 8); + pos += 2; + } else { + srcPanID = destPanID; + } + if (srcAddrMode == SHORT_ADDRESS) { + sourceAddress = new byte[2]; + sourceAddress[1] = packet.data[pos]; + sourceAddress[0] = packet.data[pos + 1]; + pos += 2; + } else if (srcAddrMode == LONG_ADDRESS) { + sourceAddress = new byte[8]; + for (int i = 0; i < 8; i++) { + sourceAddress[i] = packet.data[pos + 7 - i]; } + pos += 8; + } + } // int payloadLen = packet.data.length - pos; + brief.append("15.4 "); + brief.append(type < typeS.length ? typeS[type] : "?").append(' '); - brief.append("15.4 "); - brief.append(type < typeS.length ? typeS[type] : "?").append(' '); + verbose.append("IEEE 802.15.4 ") + .append(type < typeVerbose.length ? typeVerbose[type] : "?") + .append(' ').append(seqNumber); + if (type != ACKFRAME) { + printAddress(brief, srcAddrMode, sourceAddress); + brief.append(' '); + printAddress(brief, destAddrMode, destAddress); - verbose.append("IEEE 802.15.4 ") - .append(type < typeVerbose.length ? typeVerbose[type] : "?") - .append(' ').append(seqNumber); - if (type != ACKFRAME) { - printAddress(brief, srcAddrMode, sourceAddress); - brief.append(' '); - printAddress(brief, destAddrMode, destAddress); - - verbose.append("
From "); - if (srcPanID != 0) { - verbose.append(StringUtils.toHex((byte)(srcPanID >> 8))) - .append(StringUtils.toHex((byte)(srcPanID & 0xff))) + verbose.append("

From "); + if (srcPanID != 0) { + verbose.append(StringUtils.toHex((byte) (srcPanID >> 8))) + .append(StringUtils.toHex((byte) (srcPanID & 0xff))) .append('/'); - } - printAddress(verbose, srcAddrMode, sourceAddress); - verbose.append(" to "); - if (destPanID != 0) { - verbose.append(StringUtils.toHex((byte)(destPanID >> 8))) - .append(StringUtils.toHex((byte)(destPanID & 0xff))) + } + printAddress(verbose, srcAddrMode, sourceAddress); + verbose.append(" to "); + if (destPanID != 0) { + verbose.append(StringUtils.toHex((byte) (destPanID >> 8))) + .append(StringUtils.toHex((byte) (destPanID & 0xff))) .append('/'); - } - printAddress(verbose, destAddrMode, destAddress); - } else { - /* got ack - no more to do ... */ - return ANALYSIS_OK_FINAL; - } - - /* update packet */ - packet.pos = pos; - packet.level = NETWORK_LEVEL; - /* remove CRC from the packet */ - packet.consumeBytesEnd(2); - - packet.llsender = sourceAddress; - packet.llreceiver = destAddress; - return ANALYSIS_OK_CONTINUE; + } + printAddress(verbose, destAddrMode, destAddress); + } else { + /* got ack - no more to do ... */ + return ANALYSIS_OK_FINAL; } - private void printAddress(StringBuffer sb, int type, byte[] addr) { - if (type == SHORT_ADDRESS) { - sb.append(StringUtils.toHex(addr)); - } else if (type == LONG_ADDRESS) { - sb.append(StringUtils.toHex(addr[0]) + StringUtils.toHex(addr[1]) + ":" + - StringUtils.toHex(addr[2]) + StringUtils.toHex(addr[3]) + ":" + - StringUtils.toHex(addr[4]) + StringUtils.toHex(addr[5]) + ":" + - StringUtils.toHex(addr[6]) + StringUtils.toHex(addr[7])); - } + /* update packet */ + packet.pos = pos; + packet.level = NETWORK_LEVEL; + /* remove CRC from the packet */ + packet.consumeBytesEnd(2); + + packet.llsender = sourceAddress; + packet.llreceiver = destAddress; + return ANALYSIS_OK_CONTINUE; + } + + private void printAddress(StringBuffer sb, int type, byte[] addr) { + if (type == SHORT_ADDRESS) { + sb.append(StringUtils.toHex(addr)); + } else if (type == LONG_ADDRESS) { + sb.append(StringUtils.toHex(addr[0]) + StringUtils.toHex(addr[1]) + ":" + + StringUtils.toHex(addr[2]) + StringUtils.toHex(addr[3]) + ":" + + StringUtils.toHex(addr[4]) + StringUtils.toHex(addr[5]) + ":" + + StringUtils.toHex(addr[6]) + StringUtils.toHex(addr[7])); } + } } diff --git a/tools/cooja/java/org/contikios/cooja/plugins/analyzers/IPHCPacketAnalyzer.java b/tools/cooja/java/org/contikios/cooja/plugins/analyzers/IPHCPacketAnalyzer.java index 0860b98cc..9b77a6ed7 100644 --- a/tools/cooja/java/org/contikios/cooja/plugins/analyzers/IPHCPacketAnalyzer.java +++ b/tools/cooja/java/org/contikios/cooja/plugins/analyzers/IPHCPacketAnalyzer.java @@ -4,365 +4,379 @@ import org.contikios.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_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 */ + 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_FL_C = 0x10; - public final static int SICSLOWPAN_IPHC_TC_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 first byte + * (C stands for compressed and I for inline) + */ + public final static int SICSLOWPAN_IPHC_FL_C = 0x10; + public final static int SICSLOWPAN_IPHC_TC_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; + /* 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_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; + 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 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; - private static byte[][] addrContexts = new byte[][] { - {(byte)0xaa, (byte)0xaa, 0, 0, 0, 0, 0, 0} - }; + public final static int PROTO_UDP = 17; + public final static int PROTO_TCP = 6; + public final static int PROTO_ICMP = 58; - private static final int IPHC_DISPATCH = 0x60; + public final static byte[] UNSPECIFIED_ADDRESS + = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - /* packet must be on network level && have a IPHC dispatch */ - public boolean matchPacket(Packet packet) { - return packet.level == NETWORK_LEVEL && (packet.get(0) & 0xe0) == IPHC_DISPATCH; + private static byte[][] addrContexts = new byte[][]{ + {(byte) 0xaa, (byte) 0xaa, 0, 0, 0, 0, 0, 0} + }; + + private static final int IPHC_DISPATCH = 0x60; + + /* packet must be on network level && have a IPHC dispatch */ + public boolean matchPacket(Packet packet) { + return packet.level == NETWORK_LEVEL && (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; + + String error = null; + + 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; } - public int analyzePacket(Packet packet, StringBuffer brief, - StringBuffer verbose) { + int hc06_ptr = 2 + cid; - /* 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; + int version = 6; + int trafficClass = 0; + int flowLabel = 0; + int len = 0; + int proto = 0; + int ttl = 0; + byte[] srcAddress = new byte[16]; + byte[] destAddress = new byte[16]; - String error = null; - - brief.append("IPHC"); + int srcPort = 0; + int destPort = 0; - /* 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 = new byte[16]; - byte[] destAddress = new byte[16]; - - int srcPort = 0; - int destPort = 0; - - - try { - /* 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; - } + try { + /* 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 { - /* 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; - } + /* 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; } - - /* Next Header */ - if((packet.get(0) & SICSLOWPAN_IPHC_NH_C) == 0) { - /* Next header is carried inline */ - proto = packet.get(hc06_ptr); - hc06_ptr += 1; + } 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; } + } - /* Hop limit */ - switch(packet.get(0) & 0x03) { + /* 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; + ttl = 1; + break; case SICSLOWPAN_IPHC_TTL_64: - ttl = 2; - break; + ttl = 2; + break; case SICSLOWPAN_IPHC_TTL_255: - ttl = 255; - break; + ttl = 255; + break; case SICSLOWPAN_IPHC_TTL_I: - ttl = packet.get(hc06_ptr); - hc06_ptr += 1; + 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 */ + + 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 */ + + 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 */ + + 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 */ - /* 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]; - } + packet.copy(hc06_ptr, srcAddress, 0, 16); + hc06_ptr += 16; + break; + case SICSLOWPAN_IPHC_SAM_01: /* 64 bits */ - 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 */ - 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 */ - 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 */ - 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 */ - packet.copy(hc06_ptr, srcAddress, 0, 16); - hc06_ptr += 16; - break; - case SICSLOWPAN_IPHC_SAM_01: /* 64 bits */ - 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[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[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; - } + 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[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[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 */ + /* 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 */ - packet.copy(hc06_ptr, destAddress, 0, 16); - hc06_ptr += 16; - break; - case SICSLOWPAN_IPHC_DAM_01: /* 48 bits FFXX::00XX:XXXX:XXXX */ - 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[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[0] = (byte) 0xff; - destAddress[1] = (byte) 0x02; - destAddress[15] = packet.get(hc06_ptr); - hc06_ptr++; - break; - } - } + /* 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 { - /* no multicast */ - /* Context based */ - if((packet.get(1) & SICSLOWPAN_IPHC_DAC) != 0) { - byte[] context = addrContexts[dci]; + /* 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 */ - switch (packet.get(1) & SICSLOWPAN_IPHC_DAM_11) { - case SICSLOWPAN_IPHC_DAM_01: /* 64 bits */ - 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 */ - 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 */ - 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 */ - packet.copy(hc06_ptr, destAddress, 0, 16); - hc06_ptr += 16; - break; - case SICSLOWPAN_IPHC_DAM_01: /* 64 bits */ - 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[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[0] = (byte) 0xfe; - destAddress[1] = (byte) 0x80; - System.arraycopy(packet.llreceiver, 0, destAddress, - 16 - packet.llreceiver.length, packet.llreceiver.length); - break; - } - } + packet.copy(hc06_ptr, destAddress, 0, 16); + hc06_ptr += 16; + break; + case SICSLOWPAN_IPHC_DAM_01: /* 48 bits FFXX::00XX:XXXX:XXXX */ + + 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[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[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]; - /* 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); + switch (packet.get(1) & SICSLOWPAN_IPHC_DAM_11) { + case SICSLOWPAN_IPHC_DAM_01: /* 64 bits */ + + 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 */ + + 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 */ + + 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 */ + + packet.copy(hc06_ptr, destAddress, 0, 16); + hc06_ptr += 16; + break; + case SICSLOWPAN_IPHC_DAM_01: /* 64 bits */ + + 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[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[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); + 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: + hc06_ptr += 7; + break; + default: // PRINTF("sicslowpan uncompress_hdr: error unsupported UDP compression\n"); - return ANALYSIS_FAILED; - } - } + return ANALYSIS_FAILED; + } } - + } // /* IP length field. */ // if(ip_len == 0) { @@ -374,54 +388,54 @@ public class IPHCPacketAnalyzer extends PacketAnalyzer { // 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); // } - /*--------------------------------------------- */ + /*--------------------------------------------- */ + } catch (Exception e) { + // some kind of unexpected error... + error = " error during IPHC parsing: " + e.getMessage(); + } + packet.pos += hc06_ptr; - } catch (Exception e) { - // some kind of unexpected error... - error = " error during IPHC parsing: " + e.getMessage(); - } - packet.pos += hc06_ptr; - - 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(" TC = " + trafficClass + - " FL: " + flowLabel + "
"); - verbose.append("From "); - printAddress(verbose, srcAddress); - verbose.append(" to "); - printAddress(verbose, destAddress); - if (error != null) verbose.append(" " + error); - - packet.lastDispatch = (byte) (proto & 0xff); - if (proto == PROTO_UDP || proto == PROTO_ICMP || - proto == PROTO_TCP) { - packet.level = APPLICATION_LEVEL; - return ANALYSIS_OK_CONTINUE; - } else { - packet.level = NETWORK_LEVEL; - return ANALYSIS_OK_CONTINUE; - } + String protoStr = "" + proto; + if (proto == PROTO_ICMP) { + protoStr = "ICMPv6"; + } else if (proto == PROTO_UDP) { + protoStr = "UDP"; + } else if (proto == PROTO_TCP) { + protoStr = "TCP"; } - 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(":"); - } - } - } + verbose.append("
IPv6 ").append(protoStr) + .append(" TC = " + trafficClass + + " FL: " + flowLabel + "
"); + verbose.append("From "); + printAddress(verbose, srcAddress); + verbose.append(" to "); + printAddress(verbose, destAddress); + if (error != null) verbose.append(" " + error); - + packet.lastDispatch = (byte) (proto & 0xff); + if (proto == PROTO_UDP || proto == PROTO_ICMP + || proto == PROTO_TCP) { + packet.level = APPLICATION_LEVEL; + return ANALYSIS_OK_CONTINUE; + } else { + 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(":"); + } + } + } } diff --git a/tools/cooja/java/org/contikios/cooja/plugins/analyzers/IPv6PacketAnalyzer.java b/tools/cooja/java/org/contikios/cooja/plugins/analyzers/IPv6PacketAnalyzer.java index 4ca371c8d..421014418 100644 --- a/tools/cooja/java/org/contikios/cooja/plugins/analyzers/IPv6PacketAnalyzer.java +++ b/tools/cooja/java/org/contikios/cooja/plugins/analyzers/IPv6PacketAnalyzer.java @@ -4,78 +4,77 @@ import org.contikios.cooja.util.StringUtils; public class IPv6PacketAnalyzer extends PacketAnalyzer { - - 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}; + public final static int PROTO_UDP = 17; + public final static int PROTO_TCP = 6; + public final static int PROTO_ICMP = 58; - private static final int IPV6_DISPATCH = 0x41; + public final static byte[] UNSPECIFIED_ADDRESS + = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - public boolean matchPacket(Packet packet) { - return packet.level == NETWORK_LEVEL && packet.get(0) == IPV6_DISPATCH; + private static final int IPV6_DISPATCH = 0x41; + + public boolean matchPacket(Packet packet) { + return packet.level == NETWORK_LEVEL && packet.get(0) == IPV6_DISPATCH; + } + + public int analyzePacket(Packet packet, StringBuffer brief, + StringBuffer verbose) { + + /* if packet has less than 40 bytes it is not interesting ... */ + if (packet.size() < 40) return ANALYSIS_FAILED; + + brief.append("IPv6"); + + /* need to decompress while analyzing - add that later... */ + verbose.append("IPv6
"); + + int pos = 1; + + int version = 6; + int trafficClass = 0; + int flowLabel = 0; + int len = packet.getInt(pos + 4, 2); + int proto = packet.getInt(pos + 6, 1); + int ttl = packet.getInt(pos + 7, 1); + byte[] srcAddress = new byte[16]; + byte[] destAddress = new byte[16]; + + packet.copy(pos + 8, srcAddress, 0, 16); + packet.copy(pos + 24, destAddress, 0, 16); + + String protoStr = "" + proto; + if (proto == PROTO_ICMP) { + protoStr = "ICMPv6"; + } else if (proto == PROTO_UDP) { + protoStr = "UDP"; + } else if (proto == PROTO_TCP) { + protoStr = "TCP"; } - public int analyzePacket(Packet packet, StringBuffer brief, - StringBuffer verbose) { + /* consume dispatch + IP header */ + packet.pos += 41; - /* if packet has less than 40 bytes it is not interesting ... */ - if (packet.size() < 40) return ANALYSIS_FAILED; - + verbose.append("
IPv6 ").append(protoStr) + .append(" TC = " + trafficClass + + " FL: " + flowLabel + "
"); + verbose.append("From "); + printAddress(verbose, srcAddress); + verbose.append(" to "); + printAddress(verbose, destAddress); - brief.append("IPv6"); + packet.lastDispatch = (byte) (proto & 0xff); + packet.level = APPLICATION_LEVEL; + return ANALYSIS_OK_CONTINUE; + } - /* need to decompress while analyzing - add that later... */ - - verbose.append("IPv6
"); - - int pos = 1; - - int version = 6; - int trafficClass = 0; - int flowLabel = 0; - int len = packet.getInt(pos + 4, 2); - int proto = packet.getInt(pos + 6, 1); - int ttl = packet.getInt(pos + 7, 1); - byte[] srcAddress = new byte[16]; - byte[] destAddress = new byte[16]; - - packet.copy(pos + 8, srcAddress, 0, 16); - packet.copy(pos + 24, destAddress, 0, 16); - - String protoStr = "" + proto; - if (proto == PROTO_ICMP) { - protoStr = "ICMPv6"; - } else if (proto == PROTO_UDP) protoStr = "UDP"; - else if (proto == PROTO_TCP) protoStr = "TCP"; - - /* consume dispatch + IP header */ - packet.pos += 41; - - verbose.append("
IPv6 ").append(protoStr).append(" TC = " + trafficClass + - " FL: " + flowLabel + "
"); - verbose.append("From "); - printAddress(verbose, srcAddress); - verbose.append(" to "); - printAddress(verbose, destAddress); - - packet.lastDispatch = (byte) (proto & 0xff); - packet.level = APPLICATION_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(":"); - } - } + 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(":"); } + } + } - } diff --git a/tools/cooja/java/org/contikios/cooja/plugins/analyzers/PacketAnalyzer.java b/tools/cooja/java/org/contikios/cooja/plugins/analyzers/PacketAnalyzer.java index 45d656863..73549cce3 100644 --- a/tools/cooja/java/org/contikios/cooja/plugins/analyzers/PacketAnalyzer.java +++ b/tools/cooja/java/org/contikios/cooja/plugins/analyzers/PacketAnalyzer.java @@ -2,88 +2,86 @@ package org.contikios.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; - public static final int APPLICATION_LEVEL = 3; - - public static class Packet { - byte[] data; - int pos; - int level; - /* size = length - consumed bytes at tail */ - int size; - - /* L2 addresseses */ - byte[] llsender; - byte[] llreceiver; + public static final int ANALYSIS_FAILED = -1; + public static final int ANALYSIS_OK_CONTINUE = 1; + public static final int ANALYSIS_OK_FINAL = 2; - byte lastDispatch = 0; - - public Packet(byte[] data, int level) { - this.level = level; - this.data = data; - this.size = data.length; - } + public static final int RADIO_LEVEL = 0; + public static final int MAC_LEVEL = 1; + public static final int NETWORK_LEVEL = 2; + public static final int APPLICATION_LEVEL = 3; + public static class Packet { - public void consumeBytesStart(int bytes) { - pos += bytes; - } + byte[] data; + int pos; + int level; + /* size = length - consumed bytes at tail */ + int size; - public void consumeBytesEnd(int bytes) { - size -= bytes; - } - - - public boolean hasMoreData() { - return size > pos; - } - - public int size() { - return size - pos; - } - - public byte get(int index) { - if (index >= size) return 0; - return data[pos + index]; - } + /* L2 addresseses */ + byte[] llsender; + byte[] llreceiver; - public int getInt(int index, int size) { - int value = 0; - for (int i = 0; i < size; i++) { - value = (value << 8) + get(index + i); - } - return value; - } + byte lastDispatch = 0; - - public byte[] getPayload() { - byte[] pload = new byte[size - pos]; - System.arraycopy(data, pos, pload, 0, pload.length); - return pload; - } + public Packet(byte[] data, int level) { + this.level = level; + this.data = data; + this.size = data.length; + } - public void copy(int srcpos, byte[] arr, int pos, int len) { - for (int i = 0; i < len; i++) { - arr[pos + i] = get(srcpos + i); - } - } + public void consumeBytesStart(int bytes) { + pos += bytes; + } - public byte[] getLLSender() { - return llsender; - } + public void consumeBytesEnd(int bytes) { + size -= bytes; + } - public byte[] getLLReceiver() { - return llreceiver; - } - }; - - public abstract boolean matchPacket(Packet packet); - - public abstract int analyzePacket(Packet packet, StringBuffer brief, StringBuffer verbose); -} \ No newline at end of file + public boolean hasMoreData() { + return size > pos; + } + + public int size() { + return size - pos; + } + + public byte get(int index) { + if (index >= size) return 0; + return data[pos + index]; + } + + public int getInt(int index, int size) { + int value = 0; + for (int i = 0; i < size; i++) { + value = (value << 8) + get(index + i); + } + return value; + } + + public byte[] getPayload() { + byte[] pload = new byte[size - pos]; + System.arraycopy(data, pos, pload, 0, pload.length); + return pload; + } + + public void copy(int srcpos, byte[] arr, int pos, int len) { + for (int i = 0; i < len; i++) { + arr[pos + i] = get(srcpos + i); + } + } + + public byte[] getLLSender() { + return llsender; + } + + public byte[] getLLReceiver() { + return llreceiver; + } + }; + + public abstract boolean matchPacket(Packet packet); + + public abstract int analyzePacket(Packet packet, StringBuffer brief, StringBuffer verbose); +} diff --git a/tools/cooja/java/org/contikios/cooja/plugins/analyzers/PcapExporter.java b/tools/cooja/java/org/contikios/cooja/plugins/analyzers/PcapExporter.java index d0fa0624f..64bf5069c 100644 --- a/tools/cooja/java/org/contikios/cooja/plugins/analyzers/PcapExporter.java +++ b/tools/cooja/java/org/contikios/cooja/plugins/analyzers/PcapExporter.java @@ -9,55 +9,55 @@ import java.io.File; public class PcapExporter { - DataOutputStream out; - - public PcapExporter() throws IOException { - } - - public void openPcap(File pcapFile) throws IOException { - if ( out != null ) { - closePcap(); - } - if ( pcapFile == null ) { - /* pcap file not specified, use default file name */ - pcapFile = new File("radiolog-" + System.currentTimeMillis() + ".pcap"); - } - out = new DataOutputStream(new FileOutputStream(pcapFile)); - /* pcap header */ - out.writeInt(0xa1b2c3d4); - out.writeShort(0x0002); - out.writeShort(0x0004); - out.writeInt(0); - out.writeInt(0); - out.writeInt(4096); - out.writeInt(195); /* 195 for LINKTYPE_IEEE802_15_4 */ - out.flush(); - System.out.println("Opened pcap file " + pcapFile); - } - public void closePcap() throws IOException { - out.close(); - out = null; - } + DataOutputStream out; - public void exportPacketData(byte[] data) throws IOException { - if (out == null) { - /* pcap file never set, open default */ - openPcap(null); - } - try { - /* pcap packet header */ - out.writeInt((int) (System.currentTimeMillis() / 1000)); - out.writeInt((int) ((System.currentTimeMillis() % 1000) * 1000)); - out.writeInt(data.length); - out.writeInt(data.length); - /* and the data */ - out.write(data); - out.flush(); - } catch (Exception e) { - e.printStackTrace(); - } + public PcapExporter() throws IOException { + } + + public void openPcap(File pcapFile) throws IOException { + if (out != null) { + closePcap(); } - - - + if (pcapFile == null) { + /* pcap file not specified, use default file name */ + pcapFile = new File("radiolog-" + System.currentTimeMillis() + ".pcap"); + } + out = new DataOutputStream(new FileOutputStream(pcapFile)); + /* pcap header */ + out.writeInt(0xa1b2c3d4); + out.writeShort(0x0002); + out.writeShort(0x0004); + out.writeInt(0); + out.writeInt(0); + out.writeInt(4096); + out.writeInt(195); /* 195 for LINKTYPE_IEEE802_15_4 */ + + out.flush(); + System.out.println("Opened pcap file " + pcapFile); + } + + public void closePcap() throws IOException { + out.close(); + out = null; + } + + public void exportPacketData(byte[] data) throws IOException { + if (out == null) { + /* pcap file never set, open default */ + openPcap(null); + } + try { + /* pcap packet header */ + out.writeInt((int) (System.currentTimeMillis() / 1000)); + out.writeInt((int) ((System.currentTimeMillis() % 1000) * 1000)); + out.writeInt(data.length); + out.writeInt(data.length); + /* and the data */ + out.write(data); + out.flush(); + } catch (Exception e) { + e.printStackTrace(); + } + } + }