From 15c4cdaa3eb68f80453642343e2511307171a91f Mon Sep 17 00:00:00 2001 From: fros4943 Date: Tue, 20 Oct 2009 09:22:07 +0000 Subject: [PATCH] on non-windows platforms: manually entering simulated gateway arp address + minor updates: introduced network interface wrapper class , extending vis plugin, showing number of bytes forwarded between native and simulated network (not just number of packets) --- .../sics/cooja/plugins/NativeIPGateway.java | 198 +++++++++--------- 1 file changed, 95 insertions(+), 103 deletions(-) diff --git a/tools/cooja/apps/native_gateway/java/se/sics/cooja/plugins/NativeIPGateway.java b/tools/cooja/apps/native_gateway/java/se/sics/cooja/plugins/NativeIPGateway.java index 41e89125c..0e394549d 100644 --- a/tools/cooja/apps/native_gateway/java/se/sics/cooja/plugins/NativeIPGateway.java +++ b/tools/cooja/apps/native_gateway/java/se/sics/cooja/plugins/NativeIPGateway.java @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: NativeIPGateway.java,v 1.9 2009/10/19 17:31:13 fros4943 Exp $ + * $Id: NativeIPGateway.java,v 1.10 2009/10/20 09:22:07 fros4943 Exp $ */ package se.sics.cooja.plugins; @@ -41,6 +41,7 @@ import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.io.File; import java.io.IOException; +import java.util.ArrayList; import java.util.Collection; import java.util.Observable; import java.util.Observer; @@ -52,13 +53,10 @@ import javax.swing.BoxLayout; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JDialog; -import javax.swing.JInternalFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JProgressBar; import javax.swing.JScrollPane; -import javax.swing.event.InternalFrameEvent; -import javax.swing.event.InternalFrameListener; import jpcap.JpcapCaptor; import jpcap.JpcapSender; @@ -72,9 +70,9 @@ import org.jdom.Element; import se.sics.cooja.ClassDescription; import se.sics.cooja.GUI; import se.sics.cooja.Mote; -import se.sics.cooja.Plugin; import se.sics.cooja.PluginType; import se.sics.cooja.Simulation; +import se.sics.cooja.VisPlugin; import se.sics.cooja.GUI.RunnableInEDT; import se.sics.cooja.dialogs.CompileContiki; import se.sics.cooja.dialogs.MessageList; @@ -82,10 +80,9 @@ import se.sics.cooja.interfaces.SerialPort; @ClassDescription("Open Native IP Gateway") @PluginType(PluginType.MOTE_PLUGIN) -public class NativeIPGateway implements Plugin { - private static Logger logger = Logger.getLogger(NativeIPGateway.class); - +public class NativeIPGateway extends VisPlugin { private static final long serialVersionUID = 1L; + private static Logger logger = Logger.getLogger(NativeIPGateway.class); private final static int IP_HEADER_LEN = 20; @@ -97,16 +94,14 @@ public class NativeIPGateway implements Plugin { private final static int LABEL_WIDTH = 170; private final static int LABEL_HEIGHT = 20; - private Object coojaTag = null; /* Used by Cooja for book-keeping */ - private Mote mote; private SerialPort serialPort = null; private boolean registeredGateway = false; - private NetworkInterface[] networkInterfacesAll; + private ArrayList networkInterfacesAll; - private NetworkInterface networkInterface = null; - private NetworkInterface loopbackInterface = null; + private NetworkInterfaceW networkInterface = null; + private NetworkInterfaceW loopbackInterface = null; private Thread captureThread = null; private JpcapCaptor captor = null; private JpcapSender sender = null; @@ -116,8 +111,8 @@ public class NativeIPGateway implements Plugin { private boolean shutdownCaptureThread = false; private int inPkts = 0, outPkts = 0; + private int inBytes = 0, outBytes = 0; - private JInternalFrame pluginGUI = null; private JLabel gatewayLabel = null; private JLabel interfaceLabel = null; private JLabel macLabel = null; @@ -144,6 +139,7 @@ public class NativeIPGateway implements Plugin { private byte[] readSlipBuffer = new byte[READ_SLIP_BUFFER_SIZE]; public NativeIPGateway(Mote mote, Simulation simulation, final GUI gui) { + super("Native IP Gateway (" + mote + ")", gui, false); this.mote = mote; /* Native OS - plugin depends on platform specific commands */ @@ -209,23 +205,30 @@ public class NativeIPGateway implements Plugin { configureLoopbackInterface(); /* Network interfaces list */ - networkInterfacesAll = JpcapCaptor.getDeviceList(); - if (networkInterfacesAll == null || networkInterfacesAll.length == 0) { + NetworkInterface[] intfs = JpcapCaptor.getDeviceList(); + if (intfs == null || intfs.length == 0) { throw new RuntimeException("No network interfaces found"); } + networkInterfacesAll = new ArrayList(); + for (NetworkInterface i: intfs) { + networkInterfacesAll.add(new NetworkInterfaceW(i)); + } + selectNICComboBox = new JComboBox(); - NetworkInterface tunnelInterface = null; - for (NetworkInterface intf : networkInterfacesAll) { - if (!ON_WINDOWS && intf.name.equals("lo")) { + NetworkInterfaceW tunnelInterface = null; + for (NetworkInterfaceW intf : networkInterfacesAll) { + if (!ON_WINDOWS && intf.intf.name.equals("lo")) { loopbackInterface = intf; } - if ((intf.name != null && intf.name.equals("tap0")) || - (intf.description != null && intf.description.contains("VMware Virtual Ethernet Adapter"))) { + if (intf.intf.name != null && intf.intf.name.equals("tap0")) { + tunnelInterface = intf; + } + if (intf.intf.description != null && intf.intf.description.contains("VMware Virtual Ethernet Adapter")) { tunnelInterface = intf; } - selectNICComboBox.addItem(intf.description + " (" + intf.name + ")"); + selectNICComboBox.addItem(intf); } selectNICComboBox.addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent e) { @@ -234,51 +237,20 @@ public class NativeIPGateway implements Plugin { } /* Detect selected network interface */ - String descr = (String) ((JComboBox)e.getSource()).getSelectedItem(); - NetworkInterface selected = null; - for (NetworkInterface networkInterface2 : networkInterfacesAll) { - String label = networkInterface2.description + " (" + networkInterface2.name + ")"; - if (label.equals(descr)) { - selected = networkInterface2; - break; - } - } - if (selected == null) { - logger.fatal("Unknown network interface: " + descr); + NetworkInterfaceW intf = + (NetworkInterfaceW) ((JComboBox)e.getSource()).getSelectedItem(); + if (networkInterface == intf) { + /* Already selected */ return; } /* Activate network interface */ - if (selected == networkInterface) { - return; - } - startCapturingPackets(selected); + startCapturingPackets(intf); } }); /* GUI components */ if (GUI.isVisualized()) { - pluginGUI = new JInternalFrame( - "Native IP Gateway (" + mote + ")", - true, true, true, true); - pluginGUI.addInternalFrameListener(new InternalFrameListener() { - public void internalFrameClosing(InternalFrameEvent e) { - gui.removePlugin(NativeIPGateway.this, true); - } - public void internalFrameClosed(InternalFrameEvent e) { } - public void internalFrameOpened(InternalFrameEvent e) { } - public void internalFrameIconified(InternalFrameEvent e) { } - public void internalFrameDeiconified(InternalFrameEvent e) { } - public void internalFrameActivated(InternalFrameEvent e) { - /* Highlight mote in COOJA */ - if (NativeIPGateway.this.coojaTag != null && coojaTag instanceof Mote) { - gui.signalMoteHighlight((Mote) coojaTag); - } - } - public void internalFrameDeactivated(InternalFrameEvent e) { } - } - ); - JPanel mainPane = new JPanel(); mainPane.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); mainPane.setLayout(new BoxLayout(mainPane, BoxLayout.Y_AXIS)); @@ -289,37 +261,58 @@ public class NativeIPGateway implements Plugin { addComponent(mainPane, "Route to/Capture on: ", selectNICComboBox); addComponent(mainPane, "Auto-register native route: ", autoRegisterRoutes); - addInfo(mainPane, "", ""); + mainPane.add(Box.createVerticalStrut(10)); interfaceLabel = addInfo(mainPane, "Network Interface:", "?"); gatewayLabel = addInfo(mainPane, "Network Gateway:", "?"); macLabel = addInfo(mainPane, "Network MAC: ", "?"); + mainPane.add(Box.createVerticalStrut(10)); inLabel = addInfo(mainPane, "Packets to simulation:", "0"); inLabel.setToolTipText(null); outLabel = addInfo(mainPane, "Packets from simulation:", "0"); outLabel.setToolTipText(null); - pluginGUI.getContentPane().add(BorderLayout.CENTER, + getContentPane().add(BorderLayout.CENTER, new JScrollPane(mainPane, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED)); - pluginGUI.pack(); - pluginGUI.setSize(pluginGUI.getWidth()+10, pluginGUI.getHeight()+10); + pack(); + setSize(getWidth()+10, getHeight()+10); } /* Start capturing network traffic for simulated network */ if (tunnelInterface != null) { startCapturingPackets(tunnelInterface); } else { - startCapturingPackets(networkInterfacesAll[0]); + startCapturingPackets(networkInterfacesAll.get(0)); } } - public JInternalFrame getGUI() { - return pluginGUI; + /** + * Network Interface Wrapper + */ + private class NetworkInterfaceW { + NetworkInterface intf; + public NetworkInterfaceW(NetworkInterface intf) { + this.intf = intf; + } + public String toString() { + if (ON_WINDOWS && intf.name != null && intf.description != null) { + return intf.description + ": " + intf.name; + } else if (intf.name != null && intf.description != null) { + return intf.name + ": " + intf.description; + } + if (intf.name != null) { + return intf.name; + } + if (intf.description != null) { + return intf.description; + } + return "Unknown"; + } } - private void startCapturingPackets(NetworkInterface intf) { + private void startCapturingPackets(NetworkInterfaceW intf) { /* Wait for old capture thread to exit */ if (captureThread != null && captureThread.isAlive()) { @@ -341,7 +334,7 @@ public class NativeIPGateway implements Plugin { /*logger.info("Capture thread started");*/ try { - captor = JpcapCaptor.openDevice(networkInterface, 65535, true, 20); + captor = JpcapCaptor.openDevice(networkInterface.intf, 65535, true, 20); captor.setNonBlockingMode(false); captor.setPacketReadTimeout(20); String[] ipSplit = moteIP.split("\\."); @@ -381,9 +374,9 @@ public class NativeIPGateway implements Plugin { if (sender == null) { if (loopbackInterface != null) { - sender = JpcapSender.openDevice(loopbackInterface); + sender = JpcapSender.openDevice(loopbackInterface.intf); } else { - sender = JpcapSender.openDevice(networkInterface); + sender = JpcapSender.openDevice(networkInterface.intf); } } } catch (IOException e) { @@ -396,7 +389,7 @@ public class NativeIPGateway implements Plugin { } } - System.arraycopy(networkInterface.mac_address, 0, networkInterfaceMAC, 0, 6); + System.arraycopy(networkInterface.intf.mac_address, 0, networkInterfaceMAC, 0, 6); if (autoRegisterRoutes.isSelected()) { updateNativeRoute(); @@ -404,11 +397,11 @@ public class NativeIPGateway implements Plugin { /* Update GUI */ if (GUI.isVisualized()) { - interfaceLabel.setText(networkInterface.description); - interfaceLabel.setToolTipText(networkInterface.description); - if (networkInterface.addresses.length > 0) { - gatewayLabel.setText(networkInterface.addresses[0].address.getHostAddress()); - gatewayLabel.setToolTipText(networkInterface.addresses[0].address.getHostAddress()); + interfaceLabel.setText("" + networkInterface); + interfaceLabel.setToolTipText(networkInterface.intf.description); + if (networkInterface.intf.addresses.length > 0) { + gatewayLabel.setText(networkInterface.intf.addresses[0].address.getHostAddress()); + gatewayLabel.setToolTipText(networkInterface.intf.addresses[0].address.getHostAddress()); } else { gatewayLabel.setText("[no gateway]"); gatewayLabel.setToolTipText(""); @@ -426,7 +419,7 @@ public class NativeIPGateway implements Plugin { ":" + Integer.toHexString(networkInterfaceMAC[4]&0xFF) + ":" + Integer.toHexString(networkInterfaceMAC[5]&0xFF)); - selectNICComboBox.setSelectedItem(networkInterface.description + " (" + networkInterface.name + ")"); + selectNICComboBox.setSelectedItem(networkInterface); } } @@ -662,7 +655,7 @@ public class NativeIPGateway implements Plugin { return; } - if (networkInterface.addresses.length <= 0) { + if (networkInterface.intf.addresses.length <= 0) { return; } @@ -678,8 +671,8 @@ public class NativeIPGateway implements Plugin { /*logger.info("Deleting old route: '" + restoreRoutesCmd + "'");*/ try { logger.info("> " + restoreRoutesCmd); - Process routeProcess = Runtime.getRuntime().exec(restoreRoutesCmd); - routeProcess.waitFor(); + Process process = Runtime.getRuntime().exec(restoreRoutesCmd); + process.waitFor(); } catch (Exception e) { logger.fatal("Error when updating native route: " + e.getMessage(), e); } @@ -693,9 +686,9 @@ public class NativeIPGateway implements Plugin { /*logger.info("Simulation IP net : " + moteNetIP);*/ String gatewayIP = - (0xFF&networkInterface.addresses[0].address.getAddress()[0]) + "." + - (0xFF&networkInterface.addresses[0].address.getAddress()[1]) + "." + - (0xFF&networkInterface.addresses[0].address.getAddress()[2]) + "." + + (0xFF&networkInterface.intf.addresses[0].address.getAddress()[0]) + "." + + (0xFF&networkInterface.intf.addresses[0].address.getAddress()[1]) + "." + + (0xFF&networkInterface.intf.addresses[0].address.getAddress()[2]) + "." + "254"; /* Non-existing gateway - just make the packets go away */ /*logger.info("Gateway IP: " + gatewayIP);*/ @@ -706,8 +699,8 @@ public class NativeIPGateway implements Plugin { logger.info("Registering route to simulated network"); String cmd = "route add " + moteNetIP + " mask " + NETMASK + " " + gatewayIP; logger.info("> " + cmd); - Process routeProcess = Runtime.getRuntime().exec(cmd); - routeProcess.waitFor(); + Process process = Runtime.getRuntime().exec(cmd); + process.waitFor(); restoreRoutesCmd = "route delete " + moteNetIP; } catch (Exception e) { logger.fatal("Error when adding route: " + e.getMessage(), e); @@ -722,9 +715,9 @@ public class NativeIPGateway implements Plugin { /*logger.info("Simulation IP net : " + moteNetIP);*/ String gatewayIP = - (0xFF&networkInterface.addresses[0].address.getAddress()[0]) + "." + - (0xFF&networkInterface.addresses[0].address.getAddress()[1]) + "." + - (0xFF&networkInterface.addresses[0].address.getAddress()[2]) + "." + + (0xFF&networkInterface.intf.addresses[0].address.getAddress()[0]) + "." + + (0xFF&networkInterface.intf.addresses[0].address.getAddress()[1]) + "." + + (0xFF&networkInterface.intf.addresses[0].address.getAddress()[2]) + "." + "2"; /*logger.info("Gateway IP: " + gatewayIP);*/ @@ -742,6 +735,11 @@ public class NativeIPGateway implements Plugin { logger.info("> " + cmd); process = Runtime.getRuntime().exec(cmd); process.waitFor(); + + cmd = "arp -s " + gatewayIP + " -Ds " + networkInterface.intf.name; + logger.info("> " + cmd); + process = Runtime.getRuntime().exec(cmd); + process.waitFor(); } catch (Exception e) { logger.fatal("Error when adding route: " + e.getMessage(), e); } @@ -768,10 +766,11 @@ public class NativeIPGateway implements Plugin { writeAsSlip(packetData, serialPort); inPkts++; + inBytes += packet.len; /* Update GUI */ if (GUI.isVisualized()) { - inLabel.setText("" + inPkts); + inLabel.setText(inPkts + " (" + inBytes + " bytes)"); } } @@ -819,10 +818,11 @@ public class NativeIPGateway implements Plugin { /*logger.info("Sending packet (" + packet.len + " bytes) to native network: " + sender);*/ sender.sendPacket(packet); outPkts++; + outBytes += packet.len; /* Update GUI */ if (GUI.isVisualized()) { - outLabel.setText("" + outPkts); + outLabel.setText(outPkts + " (" + outBytes + " bytes)"); } } @@ -936,8 +936,8 @@ public class NativeIPGateway implements Plugin { for (Element element : configXML) { if (element.getName().equals("network_interface")) { boolean ok = false; - for (NetworkInterface intf: networkInterfacesAll) { - if (intf.name.equals(element.getText())) { + for (NetworkInterfaceW intf: networkInterfacesAll) { + if (intf.intf.name.equals(element.getText())) { startCapturingPackets(intf); ok = true; break; @@ -945,7 +945,7 @@ public class NativeIPGateway implements Plugin { } if (!ok) { logger.warn("Network interface not available: " + element.getText()); - logger.warn("Instead capturing on default network interface: " + networkInterface.name); + logger.warn("Instead capturing on default network interface: " + networkInterface); } } else if (element.getName().equals("register_routes")) { autoRegisterRoutes.setSelected(Boolean.parseBoolean(element.getText())); @@ -962,7 +962,7 @@ public class NativeIPGateway implements Plugin { Element element; element = new Element("network_interface"); - element.setText(networkInterface.name); + element.setText(networkInterface.intf.name); config.add(element); element = new Element("register_routes"); @@ -990,8 +990,8 @@ public class NativeIPGateway implements Plugin { /*logger.info("Deleting old route: '" + restoreRoutesCmd + "'");*/ try { logger.info("> " + restoreRoutesCmd); - Process routeProcess = Runtime.getRuntime().exec(restoreRoutesCmd); - routeProcess.waitFor(); + Process process = Runtime.getRuntime().exec(restoreRoutesCmd); + process.waitFor(); } catch (Exception e) { logger.fatal("Error when deleting route: " + e.getMessage(), e); } @@ -1006,12 +1006,4 @@ public class NativeIPGateway implements Plugin { } } - public void tagWithObject(Object tag) { - this.coojaTag = tag; - } - - public Object getTag() { - return coojaTag; - } - }