lwip获取ip地址说明
扫描二维码
随时随地手机看文章
Lwip,light weight IP;是由Adam Dunkels 开发的一个小型开源的TCP/IP协议栈;目前已经为全球共同开发的开源协议;支持TCPIP协议族的核心协议;包括:ARP/ICMP/TCP/UDP/IPV4/IPV6/DHCP等;其核心特点是:功能齐全、运行需求的RAM和ROM少;
编程模型所有的功能和性能都可进行裁剪和配置;相关文件为:lwipopts.h
内部实现支持带操作系统和不带操作系统;核心框架是:外部单线程驱动协议栈状态机;底层使用中断进行数据的接收;
其提供三种API :1)RAW API 2)lwip API 3)BSD API。其中BSD API就是大家最熟悉的socket API了。Linux和Windows平台中的socket接口都与此大同小异;
移植将lwip移植到不同的平台主要包括两个部分工作:
1.MAC+PHY层移植,包括初始化、数据的收发;
2.应用层框架移植,如操作系统层的线程创建、定时器、消息邮箱;
平台硬件:STM32F107 PHY芯片:DM9161AEP
软件:UCOS-ii
移植核心点ST公司针对STM32F107 不带操作系统版本的LWIP移植版本,文件名为STM32F107_ETH_LwIP,版本为V1.0.0;由于其版本不再更新且与本软件平台不一致,所以不做参考;
由于STM32F1 STM32F2 STM32F4的以太网驱动都是一致的。所以到ST官网下载stm32cubdf2。其中有LWIP针对FREERTOS的移植;而FREERTOS与UCOS大同小异;所以只要针对其修改应用层框架移植的实现即可;相关代码位于:stm32cubef2STM32Cube_FW_F2_V1.1.0ProjectsSTM322xG_EVALApplicaTIonsLwIPLwIP_UDPTCP_Echo_Server_Netconn_RTOS;
LWIP的代码使用1.4.1版本,可到LWIP官网上下载;也包含在stm32cubef2中;
移植的理论基础来源于lwip 1.4.1源码包中doc文件夹中的文件;同时官方也有移植到各个平台中的示例,文件为:contrib-1.4.1.zip,到官网上下载即可;
1.MAC+PHY移植:
需要修改的文件为:
app_ethernet.c/h
etherneTIf.c/h
同时需要将stm32cubef2驱动库中的stm32f2xx_hal_eth.c/h拷贝过来;
以上文件只需要配置好,保证编译没问题,则MAC+PHY层移植完成;
2.应用层框架移植:
修改1个文件sys_arch.c,位于stm32cubef2STM32Cube_FW_F2_V1.1.0MiddlewaresThird_PartyLwIPsystem;
所有的移植即完成;
实现lwip的DHCP自动获取ip地址 LM3S系列移植lwip自动获取ip的功能:实现过程是:1)在opt.h上使能#define LWIP_ARP 1和#define LWIP_DHCP 1;2)在lwipopts.h上使能#define LWIP_DHCP 1 和 #define DHCP_DOES_ARP_CHECK 1;3)在lwiplib.c上增加#include “lwip/dhcp.h”;4)最后在lwiplib.c上修改staTIc unsigned long g_ulIPMode = IPADDR_USE_DHCP和InitNic函数中的“ lwIPInit(MACAddress,xIpAddr, xNetMask, xGateway,IPADDR_USE_DHCP);”。
调试过程: 一开始用网络数据包分析软件看,发现每隔几秒实验板会发DHCP广播给255.255.255.255,我不知道出现什么问题,后来看DHCP原理才知道,路由器没回应数据包,就觉得路由器不能自动分配ip。我尝试用pc机改成自动获取ip,原来真的不成功。后来发现之前修改路由器使能DHCP功能后没重启路由。重启后,实验板也是先用DHCP广播,接着路由器回应一个ARP数据包给实验板,数据包里有给实验板分配的ip地址。接着实验板发出3次请问有谁是会占用自己将要获得的ip,避免ip地址重复。之后什么数据都没,我还以为没成功获得ip呢,因为在路由器上看不见实验板已经连上,后还我用ping,居然是通的,关闭实验板就ping不通,说明已经获得ip地址了,只是不明白在路由器上为什么不显示连接成功。
DHCP工作原理:根据客户端是否第一次登录网络,DHCP 的工作形式会有所不同。
第一次登录的时候:
寻找 Server
当 DHCP 客户端第一次登录网络的时候,也就是客户发现本机上没有任何 IP 数据设定,它会向网络发出一个 DHCP DISCOVER 封包。因为客户端还不知道自己属于哪一个网络,所以封包的来源地址会为 0.0.0.0 ,而目的地址则为 255.255.255.255 ,然后再附上 DHCP discover 的信息,向网络进行广播。 在 Windows 的预设情形下,DHCP discover 的等待时间预设为 1 秒,也就是当客户端将第一个 DHCP discover 封包送出去之后,在 1 秒之内没有得到响应的话,就会进行第二次 DHCP discover 广播。若一直得不到响应的情况下,客户端一共会有四次 DHCP discover 广播(包括第一次在内),除了第一次会等待 1 秒之外,其余三次的等待时间分别是 9、13、16 秒。如果都没有得到 DHCP 服务器的响应,客户端则会显示错误信息,宣告 DHCP discover 的失败。之后,基于使用者的选择,系统会继续在 5 分钟之后再重复一次 DHCP discover 的过程。
提供IP租用地址
当 DHCP 服务器监听到客户端发出的 DHCP discover 广播后,它会从那些还没有租出的地址范围内,选择最前面的空置 IP ,连同其它 TCP/IP 设定,响应给客户端一个 DHCP OFFER 封包。 由于客户端在开始的时候还没有 IP 地址,所以在其 DHCP discover 封包内会带有其 MAC 地址信息,并且有一个 XID 编号来辨别该封包,DHCP 服务器响应的 DHCP offer 封包则会根据这些资料传递给要求租约的客户。根据服务器端的设定,DHCP offer 封包会包含一个租约期限的信息。
接受IP租约
如果客户端收到网络上多台 DHCP 服务器的响应,只会挑选其中一个 DHCP offer 而已(通常是最先抵达的那个),并且会向网络发送一个DHCP request广播封包,告诉所有 DHCP 服务器它将指定接受哪一台服务器提供的 IP 地址。 同时,客户端还会向网络发送一个 ARP 封包,查询网络上面有没有其它机器使用该 IP 地址;如果发现该 IP 已经被占用,客户端则会送出一个 DHCPDECLIENT 封包给 DHCP 服务器,拒绝接受其 DHCP offer ,并重新发送 DHCP discover 信息。 事实上,并不是所有 DHCP 客户端都会无条件接受 DHCP 服务器的 offer ,尤其这些主机安装有其它 TCP/IP 相关的客户软件。客户端也可以用 DHCP request 向服务器提出 DHCP 选择,而这些选择会以不同的号码填写在 DHCP OpTIon Field 里面。
换一句话说,在 DHCP 服务器上面的设定,未必是客户端全都接受。客户端可以保留自己的一些 TCP/IP 设定,并且主动权永远在客户端这边。
租约确认
当 DHCP 服务器接收到客户端的 DHCP request 之后,会向客户端发出一个 DHCPACK 响应,以确认 IP 租约的正式生效,也就结束了一个完整的 DHCP 工作过程。
DHCP 发放流程第一次登录之后: 一旦 DHCP 客户端成功地从服务器哪里取得 DHCP 租约之后,除非其租约已经失效并且 IP 地址也重新设定回 0.0.0.0 ,否则就无需再发送 DHCP discover 信息了,而会直接使用已经租用到的 IP 地址向之前之 DHCP 服务器发出 DHCP request 信息,DHCP 服务器会尽量让客户端使用原来的 IP 地址,如果没问题的话,直接响应 DHCPack 来确认则可。如果该地址已经失效或已经被其它机器使用了,服务器则会响应一个 DHCPNACK 封包给客户端,要求其重新执行 DHCP discover。 至于 IP 的租约期限却是非常考究的,并非如我们租房子那样简单, 以 NT 为例子:DHCP 客户端除了在开机的时候发出 DHCP request 请求之外,在租约期限一半的时候也会发出 DHCP request ,如果此时得不到 DHCP 服务器的确认的话,客户端还可以继续使用该 IP ;当租约期过了87.5%时,如果客户端仍然无法与当初的DHCP服务器联系上,它将与其它DHCP服务器通信。如果网络上再没有任何DHCP服务器在运行时,该客户端必须停止使用该IP地址,并从发送一个Dhcpdiscover数据包开始,再一次重复整个过程。要是您想退租,可以随时送出 DHCPRELEASE 命令解约,就算您的租约在前一秒钟才获得的。
跨网络的 DHCP 运作 从前面描述的过程中,我们不难发现:DHCP DISCOVER 是以广播方式进行的,其情形只能在同一网络之内进行,因为 router 是不会将广播传送出去的。但如果 DHCP 服务器安设在其它的网络上面呢?由于 DHCP 客户端还没有 IP 环境设定,所以也不知道 Router 地址,而且有些 Router 也不会将 DHCP 广播封包传递出去,因此这情形下 DHCP DISCOVER 是永远没办法抵达 DHCP 服务器那端的,当然也不会发生 OFFER 及其它动作了。要解决这个问题,我们可以用 DHCP Agent (或 DHCP Proxy )主机来接管客户的 DHCP 请求,然后将此请求传递给真正的 DHCP 服务器,然后将服务器的回复传给客户。这里,Proxy 主机必须自己具有路由能力,且能将双方的封包互传对方。 若不使用 Proxy,您也可以在每一个网络之中安装 DHCP 服务器,但这样的话,一来设备成本会增加,而且,管理上面也比较分散。当然喽,如果在一个十分大型的网络中,这样的均衡式架构还是可取的。视您的实际情况而定了。