-
Notifications
You must be signed in to change notification settings - Fork 2.6k
A RPL Network on the minimal net platform
This tutorial describes how to create a RPL network on the minimal-net platform. Using this platform makes for easier debugging since you can add printfs without worrying about fitting everything into flash. Also the turnaround time is just a few seconds. And RPL traffic can be monitored via Wireshark without needing a sniffer that captures 6LoWPAN traffic.
Currently this only works with cygwin builds on Windows, where another wpcap tap could easily be added for the RPL fallback interface. *nix builds use a tap0 to connect to the host network, so adding the fallback interface would be more difficult (needing either an additional tap1 or by using pcap as in Windows).
RPL nodes and the RPL border router communicate on a "primary" loopback interface. The ipv6 address of this interface does not matter since all traffic is link local (other than unicast addresses that are forwarded through the border router). The border router additionally interfaces to the host through a "fallback" loopback interface, which must have the same ipv6 prefix as the RPL network. Then unicast packets from the host will enter the border router through the fallback interface and be routed to the nodes through the primary interface. Responses from the end nodes enter the border router through the primary and are routed back to the host through the fallback.
Instead of using a loopback, a hardware interface can be used for the RPL traffic between border router and end nodes. In this case RPL devices attached to the hardware interface can also be accessed through the border router, for example Raven webservers connected via 6LowPAN to the Jackdaw usb stick acting as an RNDIS interface. We will use two loopbacks to start with!
Install two loopbacks as described in Setting up Wireshark on a Loopback Interface. Win7 is assumed from here on; XP users must use netsh commands to accomplish the ipv6 setup. Turn off all protocols other than ip4 and ip6, give them different ip4 and ip6 addresses, and name the interfaces correspondingly. This will make it easier to keep track of which is which! But you can disable the ip4 protocol to keep the numerous ip4 discovery packets out of the wireshark captures.
ipconfig shows the addresses that are assigned:
Windows IP Configuration Ethernet adapter fdfd 10-10-10-10: Connection-specific DNS Suffix . : IPv6 Address. . . . . . . . . . . : fdfd::1 Link-local IPv6 Address . . . . . : fe80::4cff:fe4f:4f50%14 IPv4 Address. . . . . . . . . . . : 10.10.10.10 Subnet Mask . . . . . . . . . . . : 255.255.0.0 Default Gateway . . . . . . . . . : Ethernet adapter bbbb 10-1-10-10: Connection-specific DNS Suffix . : IPv6 Address. . . . . . . . . . . : bbbb::1 Link-local IPv6 Address . . . . . : fe80::4cff:fe4f:4f50%16 IPv4 Address. . . . . . . . . . . : 10.1.10.10 Subnet Mask . . . . . . . . . . . : 255.255.0.0 Default Gateway . . . . . . . . . :
You can turn off ipv4 now, and launch two wiresharks to monitor the traffic on each loopback. The Win7 homegroup service sends a lot of ipv6 packets; stopping the service will get rid of those (it will restart when you reboot). CTL-shift-escape to bring up the task manager, go to services tab and hit services button, and stop the Peer Name Resolution Protocol service.
Get ready to build the RPL border router. It is instructive to turn on the debug prints in /core/net/rpl/rpl-icmp6.c:
//#define DEBUG DEBUG_NONE #define DEBUG DEBUG_FULL
A status.shtml page is available for webserver-ipv6 that shows the addresses, neighbors, and routes. However it is not included in the default build so as not to increase memory requirements for the smaller platforms. To add it to the build, regenerate the httpd-fsdata.c file by running the perl script makefsdata from the /apps/webserver/ directory. If you have perl working in cygwin do
cd ~/contiki/apps/webserver /../../tools/makefsdata Processing directory httpd-fs as root of packed httpd-fs file system Writing to ~/contiki/apps/webserver/httpd-fsdata.c Adding /404.html Adding /files.shtml Adding /footer.html Adding /header.html Adding /index.html Adding /processes.shtml Adding /status.shtml Adding /style.css Adding /tcp.shtml
If perl is instead installed in cmd windows, copy the makefsdata script to the /apps/webserver directory and run it with:
c:\cygwin\home\dak\contiki\apps\webserver>perl makefsdata Processing directory httpd-fs as root of packed httpd-fs file system Writing to C:\cygwin\home\dak\contiki\apps\webserver\httpd-fsdata.c Adding /404.html ...
The default address is passed through the HARD_CODED_ADDRESS define for the border router:
#undef HARD_CODED_ADDRESS #define HARD_CODED_ADDRESS "bbbb::1" //bbbb::ff:fe00:1 is the RPL border router default
Note the actual address is expanded to correspond to a 6 byte ethernet MAC address. This is because the default ethernet MAC address given in uip6.c will also be changed on border router startup:
uip_lladdr_t uip_lladdr = {{0x00,0x06,0x98,0x00,0x02,0x32}};//translates into fe80::206:98ff:fe00:232.Change /platform/minimal-net/contiki-conf.h to
#define UIP_CONF_IPV6_RPL 1 #define RPL_BORDER_ROUTER 1
Now build and launch the border router
cd ~/examples/webserver-ipv6/ make mv webserver6.minimal-net webrouter1 ./webrouter1 usage: <program> <ip addr of interface> <ip addr of fallback> -->I'll try interface address 10.10.10.10 --> and fallback address [bbbb::1]
Notice that won't work if ip4 is turned off the fdfd:: interface. For compatibility with other tutorials the default is 10.10.10.10. So relaunch with the ipv6 address:
./webrouter1 fdfd::1 init_pcap: found interface: MS LoopBack Driver init_pcap: with ipv6 address: [fe80::4cff:fe4f:4f50] init_pcap: with ipv6 address: [fdfd::1] init_pcap: Opened as primary interface set_ethaddr: found adapter: Microsoft Loopback Adapter #2 set_ethaddr: with ipv6 address: : [bbbb::1] set_ethaddr: found adapter: NVIDIA nForce 10/100/1000 Mbps Ethernet set_ethaddr: with ipv6 address: : [2001:4978:1db:0] set_ethaddr: found adapter: Microsoft Loopback Adapter set_ethaddr: with ipv6 address: : [fdfd::1] set_ethaddr: ethernetaddr: 02-00-4C-4F-4F-50 init_pcap: found interface: NVIDIA nForce MCP Networking Adapter Driver init_pcap: with ipv6 address: [fe80::224:8cff:fe62:6c93] init_pcap: with ipv6 address: [2001:4978:1db:0] init_pcap: with ipv6 address: [2001:4978:1db:0] init_pcap: with address: 192.168.1.11 init_pcap: found interface: MS LoopBack Driver init_pcap: with ipv6 address: [fe80::4cff:fe4f:4f50] init_pcap: with ipv6 address: [bbbb::1] init_pcap: Opened as fallback interface Border Router Process started Created a new RPL dag IPV6 Address: [bbbb::ff:fe00:1] IPV6 Address: [fe80::ff:fe00:1]
The bbbb::1 loopback has been opened as the default fallback interface. Now you should see RPL traffic on fdfd:: and pings to the border router on bbbb::
C:\Users\dak>ping bbbb::ff:fe00:1 Pinging bbbb::ff:fe00:1 with 32 bytes of data: Reply from bbbb::ff:fe00:1: time=2ms Reply from bbbb::ff:fe00:1: time<1ms Reply from bbbb::ff:fe00:1: time<1ms
The border router webserver should appear at http://[bbbb::ff:fe00:1]
Clear the RPL_BORDER_ROUTER define and build one or more webserver6 with different addresses. For the RPL node the HARD_CODED_ADDRESS is bbbb::10 by default, but the prefix is ignored since it is obtained from the border router.
#define UIP_CONF_IPV6_RPL 1 #define RPL_BORDER_ROUTER 0 ... #define HARD_CODED_ADDRESS "bbbb::10" //the prefix is ignored for a rpl end node
Rather than change HARD_CODED_ADDRESS in the contiki-conf.h file it can be also be changed in /platform/contiki-main.c. This allows changing addresses without forcing a complete rebuild.
#define HARD_CODED_ADDRESS "bbbb::10" #ifdef HARD_CODED_ADDRESS
Off we go:
make mv webserver6.minimal-net web10 #define HARD_CODED_ADDRESS "bbbb::20" make mv webserver6.minimal-net web20 #define HARD_CODED_ADDRESS "bbbb::30" make mv webserver6.minimal-net web30 ...
Launch each webserver in its own cygwin window:
dak@DIXIE ~/contiki/examples/webserver-ipv6 $ ./web10 fdfd::1 init_pcap: found interface: MS LoopBack Driver init_pcap: with ipv6 address: [fe80::4cff:fe4f:4f50] init_pcap: with ipv6 address: [fdfd::1] set_ethaddr: found adapter: Microsoft Loopback Adapter #2 set_ethaddr: with ipv6 address: : [bbbb::1] set_ethaddr: found adapter: NVIDIA nForce 10/100/1000 Mbps Ethernet set_ethaddr: with ipv6 address: : [2001:4978:1db:0] set_ethaddr: found adapter: Microsoft Loopback Adapter set_ethaddr: with ipv6 address: : [fdfd::1] set_ethaddr: ethernetaddr: 02-00-4C-4F-4F-50 RPL activated IPV6 Addresss: [fe80::ff:fe00:10]
If you have enabled DEBUG_FULL in rpl-icmp6.c you will get informative prints about DAGs, DAOs and DIOs:
Received an RPL control message RPL: Received a DIO from fe80::ff:fe00:1 RPL: Neighbor added to neighbor cache fe80::ff:fe00:1, 00:00:00:00:00:00 RPL: Incoming DIO rank 256 RPL: DIO suboption 2, length: 6 RPL: DAG MC: type 7, flags 8, aggr 0, prec 0, length 2, ETX 0 RPL: DIO suboption 4, length: 14 RPL: DIO Conf:dbl=8, min=12 red=10 maxinc=768 mininc=256 ocp=1 d_l=255 l_u=65535 RPL: DIO suboption 8, length: 30 RPL: Copying prefix information RPL: Sending prefix info in DIO for bbbb:: RPL: Sending a multicast-DIO with rank 1536
Going to the border router webserver status page will show the routes as they form:
Addresses [bbbb::ff:fe00:1] [fe80::ff:fe00:1] [Room for 9 more] Neighbors [bbbb::1] [fe80::ff:fe00:10] [fe80::ff:fe00:20] [Room for 97 more] Routes [bbbb::ff:fe00:10](128 (via [fe80::ff:fe00:10]) [bbbb::ff:fe00:20](128 (via [fe80::ff:fe00:20]) [Room for 98 more]
Almost done! Try pinging an end node and it won't work, windows outputs a neighbor solicitation from bbbb::1 to ff02::1:ff00:10 and gets no neighbor advertisement in response. That is because the end nodes are attached to the fdfd::1 interface. We have to add the neighbors manually so windows will skip the NS and directly output packets to bbbb::ff:fe00:10, so that the border router can forward them to the fdfd:: interface. This is done just as for the Jackdaw RNDIS RPL border router, using the bbbb:: interface number (16 in this case, as shown by ipconfig above):
IPv6 Address. . . . . . . . . . . : bbbb::1 Link-local IPv6 Address . . . . . : fe80::4cff:fe4f:4f50%16
So in an administrative command window, do:
netsh interface ipv6 add neighbor bbbb::ff:fe00:10 33-33-ff-33-44-10 interface=16 netsh interface ipv6 add neighbor bbbb::ff:fe00:20 33-33-ff-33-44-20 interface=16 netsh interface ipv6 add neighbor bbbb::ff:fe00:30 33-33-ff-33-44-30 interface=16
Then the end nodes can be reached for pings and webserver pages.
Pinging bbbb::ff:fe00:10 with 32 bytes of data: Reply from bbbb::ff:fe00:10: time=2ms Reply from bbbb::ff:fe00:10: time=3ms Reply from bbbb::ff:fe00:10: time=3ms
If fdfd::1 is removed from the loopback and assigned to the Jackdaw RNDIS interface then everything works as before except RPL traffic now goes out 6LoWPAN and Raven RPL webservers also become part of the network:
Multihop can also be implemented among the minimal-net nodes by selectively ignoring incoming packets based on their MAC address. In wpcap.c
* To implement multihop, ignore packets to us from specified source macs. For example building the router1 and web20 to ignore each other: */ #if 1 //enable for multihop if (0 || (*(packet+11) ==0x1) //20 ignores router // || (*(packet+11) ==0x10) // || (*(packet+11) ==0x20) //router ignores 20 ) { printf("i%x",*(packet+11)); return 0; } /* If we are not the recipient, ignore packets from other RPL node forwarding */ if (0 // || (*(packet+5) !=0x1) //router1 // || (*(packet+5) !=0x10) || (*(packet+5) !=0x20) //20 ) { printf("r%x",*(packet+11)); return 0; } #endif
Wireshark captures will show all the traffic, the loopback acting as a sniffer that can receive all transmissions. The forwards are interpreted as duplicate packets, so it will be a mess unless you filter streams by mac address! Here is a .pcap files://files/Rpl_intermediate_and_end_node_gets.pcap showing GETs to the intermediate :10 node and the end :20 node.
For example, the below shows packet 8 (forwarded from web10 to web20) as a retransmitted packet 7 {(from router1 to web10):