0%
LwIP分析#01#在Linux上运行LwIP的第一种方法

我们知道LwIP是给嵌入式设备这种资源有限的设备设计的,我们将其移植到单片机上较为简单。但如果剖析源代码,需要断点或者打印调试信息,每次修改都要重新烧录,那就太麻烦了。所以学习阶段,最好的方法还是可以在Linux上运行,这样就方便多了。

如何让LwIP在Linux上运行,目前我所知有三种方法,对于这几种方法,后续博文一一道来。

方法一的基本原理

该方法的实现代码,请访问下面的github仓库。

https://github.com/haohd/lwip-linux
https://github.com/motadou/lwip-linux (前者如果失效,请访问备份地址)

该实验代码基于LwIP-2.0.2,后面我抽象出了一个测试包,可以方便的基于大多数版本比如最新LwIP-2.2.0运行。


该方法的核心原理是:

  • 使用LwIP提供的开发框架,创建EchoServer服务,监听tcp:6677端口。
  • EchoServer调用libpcap库,设置Linux的网卡为混杂模式。
  • 如同Tcpdump一样,EchoServer开始在该网卡上抓包,抓取数据包(MAC帧)之后,抛给内置的LwIP协议栈处理。
  • 该数据包对LwIP来说就如同真实网卡上传来的数据包一样,然后开始在LwIP协议栈中逐层流转和处理。
  • 注意,特别需要这里! 因为混杂模式,系统抓取了所有数据包,包括监听在22端口上的SSH协议包。 如果LwIP不加以判断的处理,它会发现在LwIP的协议栈上没有应用层监听22端口,从而LwIP会原路返回一个RST包,直接导致你正在使用的仿真终端断联! 所以要完美使用当前这种方法,须在tcp_in.c文件的tcp_input函数中,增加一个滤包逻辑:如果不是发给6677端口的数据包,直接将其丢弃,而不是返回RST包。
  • 过滤数据包之后,LwIP继续处理,将该数据包抛给应用层。然后应用层也使用LwIP提供的开发框架,原路返回数据。
  • 至此完成了整个协议栈的数据流转。

该方法的弊端就是需要修改源码,虽然修改不多,但因其对源码有侵入,所以不作推荐。但它提供了一种运行LwIP的思路供我们参考。

源代码分析

前文所说,该方法是基于LwIP-2.0.2版本修改的,我们看下它对原始代码做了哪些修改。

原始版和定制版的变动汇总:

  • 修改:lwip-2.0.2\src\netif\ethernet.c

  • 修改:lwip-2.0.2\src\include\lwip\opt.h

  • 修改:lwip-2.0.2\src\include\lwip\init.h

  • 修改:lwip-2.0.2\src\core\tcp.c

  • 修改:lwip-2.0.2\src\core\tcp_in.c

  • 新增:lwip-2.0.2\src\arch\cc.h

  • 新增:lwip-2.0.2\src\arch\if.h

  • 新增:lwip-2.0.2\src\arch\netif.h

  • 新增:lwip-2.0.2\src\arch\pcap.h

对ethernet.c、opt.h、init.h、tcp.c的修改,我们完全可以忽略无视。
有效的修改是 tcp_in.c ,对该文件的修改就是前文所说增加的滤包逻辑。cc.h、if.c、netif.c、pcap.c是当前硬件和系统架构的移植文件。

当前github库中的lwip代码,作者已经帮我们修改好了,这里我们看下他是怎么增加的滤包逻辑:

代码很清晰,滤包逻辑就是:不需要的包直接丢弃!!

编译LwIP协议栈

第一步:安装依赖

1
$ sudo apt install libpcap-dev

第二步:下载代码

1
$ git clone git@github.com:haohd/lwip-linux.git

第三步:指定运行模式
修改 lwip-linux/test/linux/lwip.h 文件。

找到文件中:

1
#define  TEST_ID          TCP_CLIENT

将其修改为:

1
#define  TEST_ID          ECHO_SERVER

第四步:编译

1
2
3
$ cd lwip-linux/Debug
$
$ make

如下图所示编译:

编译后,lwip-linux 就是我们需要的可执行程序。

运行LwIP协议栈

第一步:在Linux上使用root权限,启动 lwip-linux 程序,使其开始监听tcp:6677端口。

第二步:在Windows上使用 PuTTY 向 192.168.0.62:6677 端口发起连接。

连接建立之后,我们在 PuTTY 的窗口内,不断的发送数据,正常情况下服务端会接收到数据并接收到LwIP返回的同样的数据。

可见,LwIP目前可以接收到我们从Windows上发送过去的数据,并能正确的处理,然后再将处理结果返回给我们。

参考资料