开放源码的TCPIP协议栈--LwIP

1、BSD TCP/IP协议栈

     BSD栈历史上是其他商业栈的起点,大多数专业TCP/IP栈(VxWorks内嵌的TCP/IP 栈)是BSD栈派生的。这是因为BSD栈在BSD许可协议下提供了这些专业栈的雏形,BSD许用证允许BSD栈以修改或未修改的形式结合这些专业栈的代码而无须向创建者付版税。同时,BSD也是许多TCP/IP协议中的创新(如广域网中饿拥塞控制和避免)的开始点。

2、uC/IP

    uC/IP是由Guy Lancaster编写的一套基于uC/OS且开放源码的TCP/IP协议栈,亦可移植到其它操作系统,是一套完全免费的、可供研究的TCP/IP协议栈,uC/IP大部分源码是从公开源码BSD发布站点和KA9Q(一个基于DOS单任务环境运行的TCP/IP协议栈)移植过来。uC/IP具有如下一些特点:带身份验证和报头压缩支持的PPP协议,优化的单一请求/回复交互过程,支持IP/TCP/UDP协议,可实现的网络功能较为强大,并可裁减。 UCIP协议栈被设计为一个带最小化用户接口及可应用串行链路网络模块。根据采用CPU、编译器和系统所需实现协议的多少,协议栈需要的代码容量空间在 30-60KB之间。http://ucip.sourceforge.net

3、LwIP

     LwIP是瑞士计算机科学院(Swedish Institute of Computer Science)的Adam Dunkels等开发的一套用于嵌入式系统的开放源代码TCP/IP协议栈。LwIP的含义是Light Weight(轻型)IP协议,相对于uip。LwIP可以移植到操作系统上,也可以在无操作系统的情况下独立运行。LwIP TCP/IP实现的重点是在保持TCP协议主要功能的基础上减少对RAM的占用,一般它只需要几十K的RAM和40K左右的ROM就可以运行,这使 LwIP协议栈适合在低端嵌入式系统中使用。LwIP的特性如下:支持多网络接口下的IP转发,支持ICMP协议,包括实验性扩展的的UDP(用户数据报协议),包括阻塞控制,RTT估算和快速恢复和快速转发的TCP(传输控制协议),提供专门的内部回调接口(Raw API)用于提高应用程序性能,并提供了可选择的Berkeley接口API。http://www.sics.se/~adam/lwip/或http://savannah.nongnu.org/projects/lwip/

LwIP 之 源码目录文件详解及移植说明:

https://blog.csdn.net/ZCShouCSDN/article/details/79229728

源码目录文件
目前,网络上多数文章所使用的LwIP版本为1.4.1。最新版本为2.0.3。从1.4.1到2.0.3(貌似从2.0.0开始),LwIP的源码有了一定的变化,甚至于源码的文件结构也不一样,内部的一些实现源文件也被更新和替换了。其源码目录结构如下所示(对于简单的文件以注释的形式给出,核心源码下文会详细说明):

LWIP-2.0.3
│  CHANGELOG    // 版本更新记录,从中可以看到LwIP不同版本的变化
│  COPYING
│  FILES        // 其中说明了其所在目录下的各目录或文件的用途。在不同的目录下会有不同的该文件
│  README
│  UPGRADING    // 版本升级后可能出现不兼容,该文档记录了从老版本升级需要修改的地方。对于升级自己使用的LwIP版本时很有用处。
├─doc
│  │  contrib.txt    // LwIP作为开源软件,如果想要为其做贡献,则需要遵循一定的准则,例如:提交代码的风格、报告Bug等。该文档给出了详细的贡献准则。
│  │  doxygen_docs.zip    // 用doxygen生成的LwIP的配套文档
│  │  FILES            // 其中说明了该目录下的每个文件的用途
│  │  mdns.txt        // MDNS的说明文档
│  │  mqtt_client.txt
│  │  NO_SYS_SampleCode.c
│  │  ppp.txt        // lwIP的PPP接口文档
│  │  rawapi.txt    // 告诉读者怎样使用协议栈的Raw/Callback API进行编程
│  │  savannah.txt    // 说明了如何获取当前的开发源代码
│  │  sys_arch.txt  // 在有操作系统的移植的时候会被使用到,包含了移植说明,规定了移植者需要实现的函数、宏定义等,后面有详细说明。
│  └─doxygen        // doxygen脚本,主要用来维护LwIP的配套文档。对于使用LwIP来说用不到
│      │  generate.bat
│      │  generate.sh
│      │  lwip.Doxyfile
│      │  main_page.h
│      └─output
│              index.html
├─src /* 源码文件部分下面独立详细说明 */
│  │  Filelists.mk
│  │  FILES        // 主要记录了该目录下每个文件、目录的用途
│  ├─api
│  │      api_lib.c
│  │      api_msg.c
│  │      err.c
│  │      netbuf.c
│  │      netdb.c
│  │      netifapi.c
│  │      sockets.c
│  │      tcpip.c
│  ├─apps
│  │  ├─httpd
│  │  │  │  fs.c
│  │  │  │  fsdata.c
│  │  │  │  fsdata.h
│  │  │  │  httpd.c
│  │  │  │  httpd_structs.h
│  │  │  ├─fs
│  │  │  │  │  404.html
│  │  │  │  │  index.html
│  │  │  │  └─img
│  │  │  │          sics.gif
│  │  │  └─makefsdata
│  │  │          makefsdata
│  │  │          makefsdata.c
│  │  │          readme.txt
│  │  ├─lwiperf
│  │  │      lwiperf.c
│  │  ├─mdns
│  │  │      mdns.c
│  │  ├─mqtt
│  │  │      mqtt.c
│  │  ├─netbiosns
│  │  │      netbiosns.c
│  │  ├─snmp
│  │  │      snmpv3.c
│  │  │      snmpv3_dummy.c
│  │  │      snmpv3_mbedtls.c
│  │  │      snmpv3_priv.h
│  │  │      snmp_asn1.c
│  │  │      snmp_asn1.h
│  │  │      snmp_core.c
│  │  │      snmp_core_priv.h
│  │  │      snmp_mib2.c
│  │  │      snmp_mib2_icmp.c
│  │  │      snmp_mib2_interfaces.c
│  │  │      snmp_mib2_ip.c
│  │  │      snmp_mib2_snmp.c
│  │  │      snmp_mib2_system.c
│  │  │      snmp_mib2_tcp.c
│  │  │      snmp_mib2_udp.c
│  │  │      snmp_msg.c
│  │  │      snmp_msg.h
│  │  │      snmp_netconn.c
│  │  │      snmp_pbuf_stream.c
│  │  │      snmp_pbuf_stream.h
│  │  │      snmp_raw.c
│  │  │      snmp_scalar.c
│  │  │      snmp_table.c
│  │  │      snmp_threadsync.c
│  │  │      snmp_traps.c
│  │  ├─sntp
│  │  │      sntp.c
│  │  └─tftp
│  │          tftp_server.c
│  ├─core
│  │  │  def.c
│  │  │  dns.c
│  │  │  inet_chksum.c
│  │  │  init.c
│  │  │  ip.c
│  │  │  mem.c
│  │  │  memp.c
│  │  │  netif.c
│  │  │  pbuf.c
│  │  │  raw.c
│  │  │  stats.c
│  │  │  sys.c
│  │  │  tcp.c
│  │  │  tcp_in.c
│  │  │  tcp_out.c
│  │  │  timeouts.c
│  │  │  udp.c
│  │  ├─ipv4
│  │  │      autoip.c
│  │  │      dhcp.c
│  │  │      etharp.c
│  │  │      icmp.c
│  │  │      igmp.c
│  │  │      ip4.c
│  │  │      ip4_addr.c
│  │  │      ip4_frag.c
│  │  └─ipv6
│  │          dhcp6.c
│  │          ethip6.c
│  │          icmp6.c
│  │          inet6.c
│  │          ip6.c
│  │          ip6_addr.c
│  │          ip6_frag.c
│  │          mld6.c
│  │          nd6.c
│  ├─include
│  │  ├─lwip
│  │  │  │  api.h
│  │  │  │  arch.h
│  │  │  │  autoip.h
│  │  │  │  debug.h
│  │  │  │  def.h
│  │  │  │  dhcp.h
│  │  │  │  dhcp6.h
│  │  │  │  dns.h
│  │  │  │  err.h
│  │  │  │  errno.h
│  │  │  │  etharp.h
│  │  │  │  ethip6.h
│  │  │  │  icmp.h
│  │  │  │  icmp6.h
│  │  │  │  igmp.h
│  │  │  │  inet.h
│  │  │  │  inet_chksum.h
│  │  │  │  init.h
│  │  │  │  ip.h
│  │  │  │  ip4.h
│  │  │  │  ip4_addr.h
│  │  │  │  ip4_frag.h
│  │  │  │  ip6.h
│  │  │  │  ip6_addr.h
│  │  │  │  ip6_frag.h
│  │  │  │  ip_addr.h
│  │  │  │  mem.h
│  │  │  │  memp.h
│  │  │  │  mld6.h
│  │  │  │  nd6.h
│  │  │  │  netbuf.h
│  │  │  │  netdb.h
│  │  │  │  netif.h
│  │  │  │  netifapi.h
│  │  │  │  opt.h
│  │  │  │  pbuf.h
│  │  │  │  raw.h
│  │  │  │  sio.h
│  │  │  │  snmp.h
│  │  │  │  sockets.h
│  │  │  │  stats.h
│  │  │  │  sys.h
│  │  │  │  tcp.h
│  │  │  │  tcpip.h
│  │  │  │  timeouts.h
│  │  │  │  udp.h
│  │  │  ├─apps
│  │  │  │      FILES
│  │  │  │      fs.h
│  │  │  │      httpd.h
│  │  │  │      httpd_opts.h
│  │  │  │      lwiperf.h
│  │  │  │      mdns.h
│  │  │  │      mdns_opts.h
│  │  │  │      mdns_priv.h
│  │  │  │      mqtt.h
│  │  │  │      mqtt_opts.h
│  │  │  │      netbiosns.h
│  │  │  │      netbiosns_opts.h
│  │  │  │      snmp.h
│  │  │  │      snmpv3.h
│  │  │  │      snmp_core.h
│  │  │  │      snmp_mib2.h
│  │  │  │      snmp_opts.h
│  │  │  │      snmp_scalar.h
│  │  │  │      snmp_table.h
│  │  │  │      snmp_threadsync.h
│  │  │  │      sntp.h
│  │  │  │      sntp_opts.h
│  │  │  │      tftp_opts.h
│  │  │  │      tftp_server.h
│  │  │  ├─priv
│  │  │  │      api_msg.h
│  │  │  │      memp_priv.h
│  │  │  │      memp_std.h
│  │  │  │      nd6_priv.h
│  │  │  │      tcpip_priv.h
│  │  │  │      tcp_priv.h
│  │  │  └─prot
│  │  │          autoip.h
│  │  │          dhcp.h
│  │  │          dns.h
│  │  │          etharp.h
│  │  │          ethernet.h
│  │  │          icmp.h
│  │  │          icmp6.h
│  │  │          igmp.h
│  │  │          ip.h
│  │  │          ip4.h
│  │  │          ip6.h
│  │  │          mld6.h
│  │  │          nd6.h
│  │  │          tcp.h
│  │  │          udp.h
│  │  ├─netif
│  │  │  │  etharp.h
│  │  │  │  ethernet.h
│  │  │  │  lowpan6.h
│  │  │  │  lowpan6_opts.h
│  │  │  │  slipif.h
│  │  │  └─ppp
│  │  │      │  ccp.h
│  │  │      │  chap-md5.h
│  │  │      │  chap-new.h
│  │  │      │  chap_ms.h
│  │  │      │  eap.h
│  │  │      │  ecp.h
│  │  │      │  eui64.h
│  │  │      │  fsm.h
│  │  │      │  ipcp.h
│  │  │      │  ipv6cp.h
│  │  │      │  lcp.h
│  │  │      │  magic.h
│  │  │      │  mppe.h
│  │  │      │  ppp.h
│  │  │      │  pppapi.h
│  │  │      │  pppcrypt.h
│  │  │      │  pppdebug.h
│  │  │      │  pppoe.h
│  │  │      │  pppo.h
│  │  │      │  pppos.h
│  │  │      │  ppp_impl.h
│  │  │      │  ppp_opts.h
│  │  │      │  upap.h
│  │  │      │  vj.h
│  │  │      └─polarssl
│  │  │              arc4.h
│  │  │              des.h
│  │  │              md4.h
│  │  │              md5.h
│  │  │              sha1.h
│  │  └─posix
│  │      │  errno.h
│  │      │  netdb.h
│  │      └─sys
│  │              socket.h
│  └─netif
│      │  ethernet.c
│      │  ethernetif.c
│      │  FILES
│      │  lowpan6.c
│      │  slipif.c
│      └─ppp
│          │  auth.c
│          │  ccp.c
│          │  chap-md5.c
│          │  chap-new.c
│          │  chap_ms.c
│          │  demand.c
│          │  eap.c
│          │  ecp.c
│          │  eui64.c
│          │  fsm.c
│          │  ipcp.c
│          │  ipv6cp.c
│          │  lcp.c
│          │  magic.c
│          │  mppe.c
│          │  multilink.c
│          │  ppp.c
│          │  pppapi.c
│          │  pppcrypt.c
│          │  PPPD_FOLLOWUP
│          │  pppoe.c
│          │  pppo.c
│          │  pppos.c
│          │  upap.c
│          │  utils.c
│          │  vj.c
│          └─polarssl
│                  arc4.c
│                  des.c
│                  md4.c
│                  md5.c
│                  README
│                  sha1.c
└─test    // 一些协议栈内核测试程序.在实际使用时一般用不到!可直接删除。
    ├─fuzz
    │  │  config.h
    │  │  fuzz.c
    │  │  lwipopts.h
    │  │  Makefile
    │  │  output_to_pcap.sh
    │  │  README
    │  └─inputs
    │      ├─arp
    │      │      arp_req.bin
    │      ├─icmp
    │      │      icmp_ping.bin
    │      ├─ipv6
    │      │      neighbor_solicitation.bin
    │      │      router_adv.bin
    │      ├─tcp
    │      │      tcp_syn.bin
    │      └─udp
    │              udp_port_5000.bin
    └─unit
        │  lwipopts.h
        │  lwip_check.h
        │  lwip_unittests.c
        ├─core
        │      test_mem.c
        │      test_mem.h
        │      test_pbuf.c
        │      test_pbuf.h
        ├─dhcp
        │      test_dhcp.c
        │      test_dhcp.h
        ├─etharp
        │      test_etharp.c
        │      test_etharp.h
        ├─ip4
        │      test_ip4.c
        │      test_ip4.h
        ├─mdns
        │      test_mdns.c
        │      test_mdns.h
        ├─tcp
        │      tcp_helper.c
        │      tcp_helper.h
        │      test_tcp.c
        │      test_tcp.h
        │      test_tcp_oos.c
        │      test_tcp_oos.h
        └─udp
                test_udp.c
                test_udp.h
1

在LwIP的源码包中,一共包含三个目录:doc、src、test。分别对应:源码的文档、源码、测试代码。最新版的源码与早期源码在某些目录文件是有区别的。以下主要说明src即:源码部分。

api目录
LwIP提供了两种类型的API: Callback-style APIs和Sequential-style APIs 。其中,Callback-style APIs即为LwIP最底层的接口,被称为Raw API或者Native API;而Sequential-style APIs主要是对底层接口进行了封装,主要包含:Netconn API、NETIF API和Socket API。在实际使用中,使用者可以任选一种API来使用。
api目录下主要包含对底层API(raw API)封装后的高级API的代码。 如果直接使用底层的的Raw API,则不需要该目录下的文件。而封装后的高级别的这两种API实现的原理都是通过引进邮箱和信号量等通信与同步机制,来实现对内核中***Raw API(native API)***函数的封装和调用。要使用这两种类型的API,需要底层操作系统的支持。

Raw API:(有时称为native API)是一个设计用于在没有操作系统时,实现零拷贝发送和接收的事件驱动的API。 这个API也被核心堆栈用于各种协议之间的交互。 这是在没有操作系统的情况下,运行lwIP时唯一可用的API。
因为Callback/Raw API是协议栈提供的三种编程接口中最复杂的一种, 它通过直接与协议栈内 核函数交互以实现编程,所以整个过程比较复杂。源码的doc目录下有一个专门的文档:rawapi.txt说明了具体如何使用Raw API。
**Netconn API:**为普通的、顺序的程序提供了使用lwIP栈的方法。 线程安全,仅从非TCPIP线程调用。 基于网络缓冲区(包含数据包缓冲区(PBUF))的TX / RX处理,以避免复制数据。这与BSD Socket API非常相似。 执行模型基于 打开-读取-写入-关闭 范例。 由于TCP / IP堆栈本质上是事件,所以TCP / IP代码和应用程序必须驻留在不同的执行上下文(线程)中。
**Socket API:**它是建立在Netconn API之上的。其主要是由于BSD Socket API是网络通信的一个实现。线程安全,仅从非TCPIP线程调用。BSD Socket API已经是网络套接字的事实上的抽象标准。目前,所有主流操作系统均实现了BSD Socket API。出于此,LwIP也提供了一套BSD Socket API。但是,标准 socket 库中的部分函数仍无法直接通过封装 Netconn API 来实现,因此 LwIP 中提供的socket 函数并不完整,用户最好不要使用它进行实际应用程序开发。对应文件为posix/sys/socket.h。
以下为每个文件的具体说明:

api_lib.c: 包含 对外提供的 sequential API 函数的实现。函数名均以netconn_开头。主要分为三组API:同时可用于TCP和UDP的API、只能用于TCP的API、只能用于UDP的API。
api_msg.c: 包含sequential API内部自己调用的函数的实现。主要包含API消息的封装和处理函数
err.c: 错误管理模块
netbuf.c: 包含了上层数据包管理函数的实现。应用程序描述待发送数据和已接收数据的基本结构。该结构只是对内核 pbuf 的简单封装,避免了数据的拷贝。缓冲区不能在多个线程之间共享。
netdb.c: 包含与主机名字转换相关的函数,主要在 socket 中被使用到
netifapi.c: 包含了上层网络接口管理函数的实现
sockets.c: 包含了 Socket API 函数的实现
tcpip.c: 包含了上层 API 与协议栈内核交互的函数,它是整个上层 API 功能得以实现的一个枢纽,其实现的功能可以简单理解为:从 API 函数处接收消息,然后将消息递交给内核函数,内核函数根据消息做出相应的处理。
apps目录
使用lwIP低级raw API编写的高层应用程序。

core目录
TCP / IP协议栈的核心部分。主要包含协议实现、内存和缓冲区管理以及底层raw API的实现。它包含了IP、ICMP、IGMP、TCP、UDP 等核 心协议以及建立在它们基础上的DNS、DHCP、SNMP 等上层应用协议。内核源代码可以单独运行,且不需要操作系统的支持。即:直接使用raw API编程。
--------------------- 
作者:ZCShouCSDN 
来源:CSDN 
原文:https://blog.csdn.net/ZCShouCSDN/article/details/79229728 
版权声明:本文为博主原创文章,转载请附上博文链接!

你可能感兴趣的:(科研)