LwIP Application Developers Manual3---链路层和网络层协议之ARP,IPV4

1.前言

本文主要讲述链路层和网络层的几种协议:ARP,ipv4

2. ARP

2.1 ARP的主要应用

ARP的主要应用是在与互联网相连的以太网网络层,该层需要一些机制将MAC地址(该地址主要由制造商分发并固定在硬件里)转换成IP地址(该地址主要取决于设备接入的网络)

2.2 从应用的角度来看待ARP

一个支持ARP的网络接口会使 etharp_output 处理所有即将发送的数据包并设置与它相关的netif结构体里面的一个标志来使能“无理由(gratuitous)ARP”(“Writing a device driver”有关于这个的实现)。

一个近期的IP地址和它相关的硬件地址表将被维护。如果有一个即将发送的数据包并没有与之相匹配的硬件地址,那么程序将会执行一次ARP查询来发现其相关的地址。

应用程序员不要直接调用此协议,因为如果程序正常工作,此协议相当于透明的。有一些标志可决定ARP表的大小、以及数据包如何在一个挂起的ARP查询后排队和ARP code是否要需从传入的数据包中绑定MAC-IP地址。

这些标志可以在lwipopts.h选项文件里设置。

 2.3 lwIP支持ARP的历史记录

新的标志 LWIP_ARP,各种优化,更好的ARP排队

1.2.0稳定

2.4 外部参考

3. IPv4

3.1 IPv4特性

IPv4(Internet Protocol version 4)是现在最广泛使用的网络协议。它有如下特性:

  • 尽最大努力的交付(best effort delivery)。

网络设备尽最大的努力让数据包到达目的地,然而并没有延迟或可靠性的保证,只有这样中间节点才会尽他们最大的努力(do their “best”)

  • 没有保证的交付(传送)或重传

目的主机并不会告知发送主机它已经接收到数据包。

  • 数据包到达的次序与发送的次序并不都相同

一旦数据包进入到网路,它们可能会按不同的路由来发送。没有方法能协调数据包按特定的序列到达目的地。

  • 主机可能会接受到重复的数据包

3.2 从应用的角度来看待IPv4

3.2.1 管理地址

IPv4的地址长度是32位比特,且该地址用点十进制计数来表示,如127.0.0.1。

在lwIP的内部,IP地址主要保存在结构体变量ip_addr中。结构体struct ip_addr保存着一个32位的无符号字(其结构如下所示struct ip_addr { u32_t addr;};)。

因此,为了设置一个IP地址,可以参考如下代码:

 #include <lwip/ip_addr.h>

    struct ip_addr local;

    IP4_ADDR(&local,127,0,0,1); // Set local ="127.0.0.1"

3.2.2 作用于struct ip_addr变量的函数或值

一些其它有用的函数和值作用于struct ip_addr变量,如下列表所示:

  •  IP_ADDR_ANY--任何IP地址。

    举例,如果你想要监听一个TCP端口,该端口并没有绑定到一个特定的地址。

  •  ip_addr_set(dest,src)-复制地址
  •  ip_addr_cmp(addr1,addr2)-比较两个地址是否相等
  •  ip_addr1(ipaddr)-IP地址的第一个字节(比如,182.178.3.5->182)
  •  ip_addr2(ipaddr)-IP地址的第二个字节(比如,182.178.3.5->178).
  • ip_addr3(ipaddr)-IP地址的第三个字节。
  • ip_addr4(ipaddr)-IP地址的第四个字节

3.2.3 主机 vs 网络字节顺序

由于小端和大端结构的差异,你一定要清楚结构体里面值的字节顺序(详细请看 Wikipedia:Endianness for explanation)。

网络字节顺序是大端的。你的主机平台的字节顺序也可以是大端模式的,这样从技术上来说你的代码就不需要其它考虑(如转换)。

然而,如果你编译你的代码是在小端模式的处理器上运行(如,Inter,AMDs,ARM,等等),那么你的程序将会出现莫名其妙的行为,难以调试和检测。

因此,一些主机转网络字节顺序的转换函数将会起到作用,如下所示:

  • netval=htonl(hostval)-将32位的主机数据转换成网络数据。
  • netval=htons(hostval)-将16位的主机数据转换成网络数据。
  • hostval=ntohl(netval)-将32位的网络数据转换成主机数据。
  • hostval=ntohs(netval)-将16位的网络数据转换成主机数据

lwIP处理大部分内部Internet协议结构体字节顺序的转换。当你手动设置或比较IP地址或者你为了将数据发送到另一个系统而将数据序列化时,你只要知道字节顺序的区别。

如果你的目的平台与你的平台字节顺序有区别,那么你一定要按照标准进行转换,这样你的16位数据就能和他的16位数据匹配了。

根据IP地址的一般经验来说,“ip_addr->addr是网络字节顺序的,而u32_t someip是主机字节顺序的。”。比如:

  • IN_CLASS 宏检测IP地址是否是A类,该宏操作在32位的主机字节顺序上。
  • IP_ADDR_ANY宏是一个结构体struct ip_addr,而且它的IP地址按网络字节顺序存储的。实际上该宏是指向一个IP地址为0.0.0.0的指针。
  • ip_addr_cmp宏比较2个IP地址的区别,由于比较的网络地址保存在结构体struct ip_addr中,因此该地址也是网络字节顺序的。

举例:一个无效的地址比较如下所示:

复制代码
struct ip_addr ip, otherip; 
        ip.addr = 0x7f000001;   /* BAD: 127.0.0.1 on big-endian, 1.0.0.127 on little-endian */ 
        IP4_ADDR(&ip,127,0,0,1);  /* GOOD: works anywhere */ 
        ip_addr_set(&otherip,&ip); /* GOOD: network-order assigned to network-order */ 
        otherip.addr = ip.addr; /* BAD: Works, but better to use the macro (it checks for NULL) */ 
        if (ip.addr == 0x7f000001) { .... /* BAD: true on big-endian, false on little-endian! */ ... } 
        if (ip.addr == 0x0100007f) { .... /* BAD: true on little-endian, false on big-endian! */ ... } 
        if (ntohl(ip.addr) == 0x7f000001) { .... /* GOOD: Works anywhere */ ... } 
        if (ip_addr_cmp(&ip,&otherip)) { .... /* GOOD: Works anywhere */ ... }
复制代码

3.2.4 分配地址给各接口

一个网络接口只能有一个IP地址。lwIP有3种方法分配合适的IP地址给接口:

 静态IP

netif的IP地址可以被设置在初始化的时候(通过netif_add或者netif_set_addr或者netif_set_ipaddr。详细请看Network interfaces management

DHCP

DHCP是一个可选的协议从一个DHCP服务器来获得IP地址。详细请看DHCP

AUTOIP

 AUTOIP也是一个可选的协议,该协议可以从本地局域网中选取一个IP地址而不用通过服务器。详细请看AUTOIP

3.2.5 分段和重组

3.2.6 lwIP IPV4支持历史

1.2.0版本稳定

3.2.7 外部参考链接

4.参考文献

[1]http://lwip.wikia.com/wiki/Introduction_to_lwIP

[2]lwIP应用开发手册中文翻译

转载于:https://www.cnblogs.com/smartjourneys/p/8204806.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值