该博文讲的还是很不错的:
在OpenWrt上实现6lowpan边缘路由器
在OpenWrt上实现6lowpan边缘路由器
【转自网友“不忘初心”,原网站延迟较严重,就直接贴过来了】
一些概念:
- 1、OpenWrt是一个功能强大的开源路由器linux系统。用户可以很方便的对其进行定制,优化。在国内外已经建立起了一个很活跃的生态圈。据说国内很火的极路由就是基于OpenWrt系统制作的。 https://openwrt.org/。
- 2、6lowpan是当前无线传感器网络研究的热门领域,通过对IPv6数据包头进行压缩、解压缩,以及在IP层从添加适用于无线自组网的路由协议RPL。实现了在无线传感器网络中也能直接使用IPv6协议。目前支持6lowpan协议比较好的开源系统有contiki-os和tinyos。在本文中使用的是contki-os。
- 3、边缘路由器是啥概念? 边缘路由器是指将局域网汇接到广域互联网的一种路由设备。具体可参见百度百科:边缘路由器。在本文中实现的是将跑OpenWrt的路由器增加对6lowpan的支持,使其成为6lowpan网络的边缘路由器,最终实现传感器网络节点能够直接通过IPv6访问到互联网。本文仅从应用上说明应该如何做,对于原理性的东西不做深入分析,感兴趣的读者需要自行查找相关知识。
硬件列表:
- 1、TP-link的路由器,型号为703N。
图上看到的黑色天线是后来DIY上去的。硬件也改为8M的FLASH和64M的RAM。我安装(刷机)的是OpenWrt官方编译的固件点此下载。由于我需要安装Python,8M的FLASH还是不够,因此我通过USB hub连接了一个U盘,把需要安装的软件都装在U盘上了。
- 运行contiki系统的USB小板。
这个小板上面的两个芯片分别是CC2530无线单片机、CP210x USB转串口芯片。小板上预留了下载口,方便用户升级调试程序。同时提供了一个复位按键和两个用户按键。另外我们也为这个小板提供的抓包固件,可以用于捕获分析802.15.4的空中数据包,这个功能以后会另外介绍。
开始折腾:
1、制作无线传感器网络的根节点固件
首先到contiki官方下载最新稳定版源码,我下载的是2.7版本。官方代码是在linux下开发编译的,这里我将其代码移植到IAR for 8051编译器下,移植到IAR下有个好处就是可以直接仿真调试。contiki支持多个cpu平台,我使用的cc2530平台。移植完成后添加border-router.c 和 slip-bridge.c 文件。为当前工程添加边缘路由器功能支持,添加完成后,该节点将成为6lowpan网络中的根节点,接管其他所有无线传感器网络中向外部请求的IP数据包,并通过串口方式传递给外部处理器(我们这里是OpenWrt系统)。嫌移植麻烦或者不熟悉的朋友建议下载contiki官方提供好的虚拟机(ubuntu)镜像(下载),然后参考官方提供的编译方法在linux系统下编译CC2530目标平台的代码,同样可以生成相同功能的固件。
将程序烧写至USB小板。此时将小板连接至电脑USB口,并打开串口调试助手(57600 8n1),应该可以看到如下信息了:
节点开始不停的打印 “?P” 用来向上级cpu请求网络地址的前缀信息。
2 、为OpenWrt增加IPv6支持和6lowpan支持
先路由器连接上网络,把USB无线小板也连接到路由器上
通过ssh登录到路由:
我们通过opkg 安装所需的软件包:
opkg update
opkkg install kmod-usb-serial-cp210x kmod-ipv6 kmod-tun tunslip6
安装完毕应该就能在 /dev/ 目录下看到ttyUSB0这个设备了,说明USB小板已经成功被系统识别为串口了。
以上安装的 tunslip6 程序,就是用来打通6lowpan无线传感器网络与真实广域网的桥梁。运行时,该程序创建一个虚拟网卡tun0,并打开串口利用slip协议与USB小板通信。说到这里,其实也很容易理解了,tunslip6做的事情实际上很简单: tun0 ip packet<—–>serial data packet。把从根节点发过来的数据包进行解包,写入到tun网卡。如果tun网卡接收到了外界的数据包,则把该数据包发送到串口上。 tunslip6的源码。
以上是简单的原理分析。在shell上运行如下命令:
tunslip6 aaaa::1/64 -s /dev/ttyUSB0 -B 57600
指定网络前缀及串口、波特率。成功运行后,USB小板会自动被分配到aaaa::/64的网络地址前缀。结合小板的64位mac地址形成小板的全球唯一128位IPv6地址。此时shell被tunslip6占用了,不能继续输入。打开另一个终端,输入ifconfig,查看tun网卡是否成功生成:
tun0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
inet6 addr: aaaa::1/64 Scope:Global
UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:2 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:500
RX bytes:0 (0.0 B) TX bytes:152 (152.0 B)
已经成功了! 由于小板的mac地址固化成0×0000000000000001了。结合刚才已经设置的aaaa::/64前缀,则小板的IPv6地址应该是 aaaa::200:0:0:1 这里多了一个2是IPv6协议规定的,暂不管他,知道地址就行了。ping一下吧!
可以看到,已经能ping通这个节点了。当然,因为根节点已经建立了无线网络了,如果这时候加入一个新的节点,也是能够在OpenWrt上直接ping通的。
3、继续改进
以上的tunslip6程序实际上不太好:1、不能指定信道及其他无线传感网的网络参数,2、运行中遇到错误会立即退出,更好的实现应该是做成daemon形式在后台运行,遇到错误自动继续尝试重启服务,尽最大可能保证系统的稳定。 鉴于以上几点缺点,我写了个简单的Python脚本,对tunslip6进行了简单的处理。规避了以上提到的 2的缺点,至于指定信道等参数的功能,以后在增加吧。该脚本是把自身变成系统的daemon进程,并调用tunslip6这个应用,监测其是否因为错误退出,若退出则继续调用,直到成功。
如果以上脚本设置为开机启动,那么边缘路由器的功能就能系统启动而驱动了。
最后一个问题:无线网里的设备怎么访问外部的ipv6网络?
要让无线节点也能直接访问互联网,其实仅仅按照前面的方法搭建起边缘路由器是不够的,有细心的读者会发现我设置tunslip6的时候用的前缀是aaaa:: 其实这个前缀是我随便填的,因为我这里的网络没有ipv6的环境,无法在路由上获得ipv6地址。因此我的路由没有访问ipv6网络的能力,6lowpan网络也就更不可能访问到了。如果有ipv6网络支持,并且通过网络管理员获得了一个全球唯一可识别的地址前缀,那么把这个前缀设置给tunslip6应该就可以使无线传感网的节点获得访问互联网的能力了。