From b9f1b9b205b8e60b9e4ae4188a0db03bb10f02eb Mon Sep 17 00:00:00 2001 From: Fredrik Osterlind Date: Fri, 1 Jun 2012 15:47:22 +0200 Subject: [PATCH] simplified and bugfixed Cooja's IP address interface, added two variables in uip-ds6.c to allow Cooja to extract addresses from memory --- core/net/uip-ds6.c | 7 + .../se/sics/cooja/interfaces/IPAddress.java | 222 ++++++++---------- 2 files changed, 101 insertions(+), 128 deletions(-) diff --git a/core/net/uip-ds6.c b/core/net/uip-ds6.c index 008f7199d..eefbef11b 100644 --- a/core/net/uip-ds6.c +++ b/core/net/uip-ds6.c @@ -42,6 +42,7 @@ */ #include #include +#include #include "lib/random.h" #include "net/uip-nd6.h" #include "net/uip-ds6.h" @@ -78,6 +79,10 @@ uip_ds6_defrt_t uip_ds6_defrt_list[UIP_DS6_DEFRT_NB]; /** \brief Def uip_ds6_prefix_t uip_ds6_prefix_list[UIP_DS6_PREFIX_NB]; /** \brief Prefix list */ uip_ds6_route_t uip_ds6_routing_table[UIP_DS6_ROUTE_NB]; /** \brief Routing table */ +/* Used by Cooja to enable extraction of addresses from memory.*/ +uint8_t uip_ds6_addr_size; +uint8_t uip_ds6_netif_addr_list_offset; + /** @} */ /* "full" (as opposed to pointer) ip address used in this file, */ @@ -106,6 +111,8 @@ uip_ds6_init(void) memset(uip_ds6_prefix_list, 0, sizeof(uip_ds6_prefix_list)); memset(&uip_ds6_if, 0, sizeof(uip_ds6_if)); memset(uip_ds6_routing_table, 0, sizeof(uip_ds6_routing_table)); + uip_ds6_addr_size = sizeof(struct uip_ds6_addr); + uip_ds6_netif_addr_list_offset = offsetof(struct uip_ds6_netif, addr_list); /* Set interface parameters */ uip_ds6_if.link_mtu = UIP_LINK_MTU; diff --git a/tools/cooja/java/se/sics/cooja/interfaces/IPAddress.java b/tools/cooja/java/se/sics/cooja/interfaces/IPAddress.java index 6bf0c6da7..c8a887c99 100644 --- a/tools/cooja/java/se/sics/cooja/interfaces/IPAddress.java +++ b/tools/cooja/java/se/sics/cooja/interfaces/IPAddress.java @@ -25,8 +25,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $Id: IPAddress.java,v 1.11 2010/12/07 10:40:08 fros4943 Exp $ */ package se.sics.cooja.interfaces; @@ -41,13 +39,12 @@ import javax.swing.JPanel; import org.apache.log4j.Logger; import org.jdom.Element; -import se.sics.cooja.AddressMemory; import se.sics.cooja.ClassDescription; import se.sics.cooja.Mote; import se.sics.cooja.MoteInterface; -import se.sics.cooja.MoteTimeEvent; -import se.sics.cooja.Simulation; -import se.sics.cooja.TimeEvent; +import se.sics.cooja.MoteMemory; +import se.sics.cooja.MoteMemory.MemoryEventType; +import se.sics.cooja.MoteMemory.MemoryMonitor; /** * Read-only interface to IPv4 or IPv6 address. @@ -57,61 +54,34 @@ import se.sics.cooja.TimeEvent; @ClassDescription("IP Address") public class IPAddress extends MoteInterface { private static Logger logger = Logger.getLogger(IPAddress.class); - private AddressMemory moteMem; + private final MoteMemory moteMem; - private static final int IPv6_MAX_ADDRESSES = 4; - private int ipv6NetworkInterfaceAddressOffset; - private int ipv6AddressStructSize; - private boolean ipv6IsGlobal = false; - private int ipv6AddressIndex = -1; + private static final int IPv6_MAX_ADDRESSES = 4; + private boolean ipv6IsGlobal = false; + private int ipv6AddressIndex = -1; + + private static final int MONITORED_SIZE = 150; + private MemoryMonitor memMonitor; public IPAddress(final Mote mote) { - moteMem = (AddressMemory) mote.getMemory(); + moteMem = mote.getMemory(); - /* ipV6: Struct sizes and offsets */ - int intLength = moteMem.getIntegerLength(); - int longLength = 4; - ipv6NetworkInterfaceAddressOffset /* net/uip-ds6.h:uip_ds6_netif_t */ = - 4 /* link_mtu */ + - align(1, intLength) /* cur_hop_limit */ + - 4 /* base_reachable_time */ + - 4 /* reachable_time */ + - 4 /* retrans_timer */ + - align(1, intLength) /* maxdadns */; - ipv6AddressStructSize /* net/uip-ds6.h:uip_ds6_addr_t */ = - align(1, 2) /* isused */ + - 16 /* ipaddr, aligned on 16 bits */ + - align(3, intLength) /* state + type + isinfinite */ + - 2*longLength /* vlifetime */ + - 2*longLength /* dadtimer */ + - align(1, intLength) /* dadnscount */; - ipv6AddressStructSize = align(ipv6AddressStructSize, intLength); - - /* Detect startup IP (only zeroes) */ - TimeEvent updateWhenAddressReady = new MoteTimeEvent(mote, 0) { - public void execute(long t) { - if (!isVersion4() && !isVersion6()) { + memMonitor = new MemoryMonitor() { + public void memoryChanged(MoteMemory memory, MemoryEventType type, int address) { + if (type != MemoryEventType.WRITE) { return; } - - String ipString = getIPString(); - ipString = ipString.replace(".", ""); - ipString = ipString.replace(":", ""); - ipString = ipString.replace("0", ""); - if (!ipString.isEmpty()) { - setChanged(); - notifyObservers(); - return; - } - - /* Postpone until IP has been set */ - mote.getSimulation().scheduleEvent( - this, - mote.getSimulation().getSimulationTime() + Simulation.MILLISECOND); - return; + setChanged(); + notifyObservers(); } }; - updateWhenAddressReady.execute(0); + if (isVersion4()) { + moteMem.addMemoryMonitor(moteMem.getVariableAddress("uip_hostaddr"), 4, memMonitor); + } else if (isVersion6()) { + moteMem.addMemoryMonitor(moteMem.getVariableAddress("uip_ds6_netif_addr_list_offset"), 1, memMonitor); + moteMem.addMemoryMonitor(moteMem.getVariableAddress("uip_ds6_addr_size"), 1, memMonitor); + moteMem.addMemoryMonitor(moteMem.getVariableAddress("uip_ds6_if"), MONITORED_SIZE, memMonitor); + } } /** @@ -130,80 +100,77 @@ public class IPAddress extends MoteInterface { ipString += (0xFF & ip[3]); return ipString; } else if (isVersion6()) { - String ipString = getUncompressedIPv6Address(); - if (ipString != null) { - ipString = compressIPv6Address(ipString); - } - return ipString; + String ipString = getUncompressedIPv6Address(); + return compressIPv6Address(ipString); } return null; } public static String compressIPv6Address(String ipString) { - while (ipString.contains(":0000:")) { - ipString = ipString.replaceAll(":0000:", "::"); - } - while (ipString.contains("0000")) { - ipString = ipString.replaceAll("0000", "0"); - } - while (ipString.contains(":::")) { - ipString = ipString.replaceAll(":::", "::"); + if (ipString.contains(":0000:0000:0000:0000:")) { + ipString = ipString.replace(":0000:0000:0000:0000:", "::"); + } else if (ipString.contains(":0000:0000:0000:")) { + ipString = ipString.replace(":0000:0000:0000:", "::"); + } else if (ipString.contains(":0000:0000:")) { + ipString = ipString.replace(":0000:0000:", "::"); + } else if (ipString.contains(":0000:")) { + ipString = ipString.replace(":0000:", "::"); } while (ipString.contains(":0")) { ipString = ipString.replaceAll(":0", ":"); } - if (ipString.endsWith(":")) { - ipString = ipString + "0"; - } return ipString; } public String getUncompressedIPv6Address() { - byte[] ip = null; + byte[] ip = null; - /* TODO No need to copy the entire array! */ - byte[] structData = moteMem.getByteArray("uip_ds6_if", - ipv6NetworkInterfaceAddressOffset+IPv6_MAX_ADDRESSES*ipv6AddressStructSize); + /* IpV6: Struct sizes and offsets */ + int ipv6NetworkInterfaceAddressOffset = moteMem.getByteValueOf("uip_ds6_netif_addr_list_offset"); + int ipv6AddressStructSize = moteMem.getByteValueOf("uip_ds6_addr_size"); + if (ipv6NetworkInterfaceAddressOffset == 0 || ipv6AddressStructSize == 0) { + return ""; + } - ipv6AddressIndex = -1; - for (int addressIndex=0; addressIndex < IPv6_MAX_ADDRESSES; addressIndex++) { - int offset = ipv6NetworkInterfaceAddressOffset+addressIndex*ipv6AddressStructSize; - byte isUsed = structData[offset]; - if (isUsed == 0) { - continue; - } + /* TODO No need to copy the entire array! */ + byte[] structData = moteMem.getByteArray("uip_ds6_if", + ipv6NetworkInterfaceAddressOffset+IPv6_MAX_ADDRESSES*ipv6AddressStructSize); + + ipv6AddressIndex = -1; + for (int addressIndex=0; addressIndex < IPv6_MAX_ADDRESSES; addressIndex++) { + int offset = ipv6NetworkInterfaceAddressOffset+addressIndex*ipv6AddressStructSize; + byte isUsed = structData[offset]; + if (isUsed == 0) { + continue; + } byte[] addressData = new byte[16]; System.arraycopy( - structData, offset+2/* ipaddr offset */, - addressData, 0, 16); - - if (addressData[0] == (byte)0xFE && addressData[1] == (byte)0x80) { - ipv6IsGlobal = false; - } else { - ipv6IsGlobal = true; - } - - ip = addressData; - ipv6AddressIndex = addressIndex; - if (ipv6IsGlobal) { - break; - } - } - if (ip == null) { - ip = new byte[16]; - ipv6AddressIndex = -1; - } + structData, offset+2/* ipaddr offset */, + addressData, 0, 16); - String ipString = ""; - int i=0; - while (i < 14) { - int val = (0xFF&ip[i+1]) + ((0xFF&ip[i])<<8); - ipString += hex16ToString(val) + ":"; - i+=2; + if (addressData[0] == (byte)0xFE && addressData[1] == (byte)0x80) { + ipv6IsGlobal = false; + } else { + ipv6IsGlobal = true; + } + + ip = addressData; + ipv6AddressIndex = addressIndex; + if (ipv6IsGlobal) { + break; + } } - int val = (0xFF&ip[15]) + ((0xFF&ip[14])<<8); - ipString += hex16ToString(val); - return ipString; + if (ip == null) { + ip = new byte[16]; + ipv6AddressIndex = -1; + } + + StringBuilder sb = new StringBuilder(); + for (int i=0; i < 14; i+=2) { + sb.append(String.format("%02x%02x:", 0xFF&ip[i+0], 0xFF&ip[i+1])); + } + sb.append(String.format("%02x%02x", 0xFF&ip[14], 0xFF&ip[15])); + return sb.toString(); } /** @@ -217,7 +184,23 @@ public class IPAddress extends MoteInterface { * @return True if mote has an IPv6 address */ public boolean isVersion6() { - return moteMem.variableExists("uip_ds6_if"); + return + moteMem.variableExists("uip_ds6_netif_addr_list_offset") && + moteMem.variableExists("uip_ds6_addr_size") && + moteMem.variableExists("uip_ds6_if"); + } + + public void removed() { + super.removed(); + if (memMonitor != null) { + if (isVersion4()) { + moteMem.removeMemoryMonitor(moteMem.getVariableAddress("rimeaddr_node_addr"), 4, memMonitor); + } else if (isVersion6()) { + moteMem.removeMemoryMonitor(moteMem.getVariableAddress("uip_ds6_netif_addr_list_offset"), 1, memMonitor); + moteMem.removeMemoryMonitor(moteMem.getVariableAddress("uip_ds6_addr_size"), 1, memMonitor); + moteMem.removeMemoryMonitor(moteMem.getVariableAddress("uip_ds6_if"), MONITORED_SIZE, memMonitor); + } + } } public JPanel getInterfaceVisualizer() { @@ -230,8 +213,8 @@ public class IPAddress extends MoteInterface { if (isVersion4()) { ipLabel.setText("IPv4 address: " + getIPString()); } else if (isVersion6()) { - ipLabel.setText((ipv6IsGlobal?"Global":"Local") + - " IPv6 address(#" + ipv6AddressIndex + "): " + getIPString()); + ipLabel.setText((ipv6IsGlobal?"Global":"Local") + + " IPv6 address(#" + ipv6AddressIndex + "): " + getIPString()); } else { ipLabel.setText("Unknown IP"); } @@ -260,21 +243,4 @@ public class IPAddress extends MoteInterface { public void setConfigXML(Collection configXML, boolean visAvailable) { } - - private static String hex16ToString(int data) { - String s = Integer.toString(data & 0xffff, 16); - if (s.length() < 4) { - s = "0000".substring(0, 4 - s.length()) + s; - } - return s; - } - - private static int align(int bytes, int alignment) { - int size = (bytes/alignment)*alignment; - while (size < bytes) { - size += alignment; - } - return size; - } - }