2024年4月24日发(作者:夙香莲)
lwip是瑞士计算机科学院的一个开源的TCP/IP协议栈实现.lwIP是TCP/IP协议栈的一个实现。lwIP协议
栈主要关注的是怎么样减少内存的使用河代码的大小,这样就可以让lwIP适用于资源有限的小型平台例如
嵌入式系统。本文我们将主要关于lwip对IP头的数据结构定义。
我们首先看看IP头的RFC描述:
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Version| IHL |Type of Service| Total Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Identification |Flags| Fragment Offset |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Time to Live | Protocol | Header Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source Address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Destination Address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Options | Padding |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
lwip对IP头的数据结构定义为:
PACK_STRUCT_BEGIN
struct ip_hdr {
/* version / header length / type of service */
PACK_STRUCT_FIELD(u16_t _v_hl_tos);
/* total length */
PACK_STRUCT_FIELD(u16_t _len);
/* identification */
PACK_STRUCT_FIELD(u16_t _id);
/* fragment offset field */
PACK_STRUCT_FIELD(u16_t _offset);
#define IP_RF 0x8000 /* reserved fragment flag */
#define IP_DF 0x4000 /* dont fragment flag */
#define IP_MF 0x2000 /* more fragments flag */
#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */
/* time to live / protocol*/
PACK_STRUCT_FIELD(u16_t _ttl_proto);
/* checksum */
PACK_STRUCT_FIELD(u16_t _chksum);
/* source and destination IP addresses */
PACK_STRUCT_FIELD(struct ip_addr src);
PACK_STRUCT_FIELD(struct ip_addr dest);
} PACK_STRUCT_STRUCT;
PACK_STRUCT_END
看到上面的数据结构以后,大家一定觉得十分的迷惑和不解,那么我们就一一为大家解答这些疑问。我
们先看看PACK_STRUCT_BEGIN和PACK_STRUCT_END定义:
#ifndef PACK_STRUCT_BEGIN
#define PACK_STRUCT_BEGIN
#endif /* PACK_STRUCT_BEGIN */
#ifndef PACK_STRUCT_END
#define PACK_STRUCT_END
#endif /* PACK_STRUCT_END */
由上面的定义可以看出,此处定义了PACK_STRUCT_BEGIN和PACK_STRUCT_END两个常量。可
能大多数人看到这里都会觉得奇怪,怎么会这么使用?相信大多数人都明白#ifndef/#define/#endif的作用,
主要用于防止头文件的重复引用。其实,上面两个常量的定义和使用和头文件的重复引用是一样的道理,
只是这里不是防止头文件的重复引用,而是防止数据结构的重复定义。这里之所以定义其实是考虑到移植
性的缘故,我们知道,不同的CPU位数可能不同,读写总线传输的字节数也可能不同,除了这些以外,还
可能在其他方面存在区别;除了硬件差别外,OS也可能存在很多区别。为了便于移植,lwip采用了宏定
义的方式来进行,对于不同的OS或是硬件,更改相关的宏使之适合于特定的系统即可。
上面的数据结构和常用的数据结构定义还有一些不同的地方,为此,我们先看一个常见的数据结构的定
义:
2024年4月24日发(作者:夙香莲)
lwip是瑞士计算机科学院的一个开源的TCP/IP协议栈实现.lwIP是TCP/IP协议栈的一个实现。lwIP协议
栈主要关注的是怎么样减少内存的使用河代码的大小,这样就可以让lwIP适用于资源有限的小型平台例如
嵌入式系统。本文我们将主要关于lwip对IP头的数据结构定义。
我们首先看看IP头的RFC描述:
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Version| IHL |Type of Service| Total Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Identification |Flags| Fragment Offset |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Time to Live | Protocol | Header Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source Address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Destination Address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Options | Padding |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
lwip对IP头的数据结构定义为:
PACK_STRUCT_BEGIN
struct ip_hdr {
/* version / header length / type of service */
PACK_STRUCT_FIELD(u16_t _v_hl_tos);
/* total length */
PACK_STRUCT_FIELD(u16_t _len);
/* identification */
PACK_STRUCT_FIELD(u16_t _id);
/* fragment offset field */
PACK_STRUCT_FIELD(u16_t _offset);
#define IP_RF 0x8000 /* reserved fragment flag */
#define IP_DF 0x4000 /* dont fragment flag */
#define IP_MF 0x2000 /* more fragments flag */
#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */
/* time to live / protocol*/
PACK_STRUCT_FIELD(u16_t _ttl_proto);
/* checksum */
PACK_STRUCT_FIELD(u16_t _chksum);
/* source and destination IP addresses */
PACK_STRUCT_FIELD(struct ip_addr src);
PACK_STRUCT_FIELD(struct ip_addr dest);
} PACK_STRUCT_STRUCT;
PACK_STRUCT_END
看到上面的数据结构以后,大家一定觉得十分的迷惑和不解,那么我们就一一为大家解答这些疑问。我
们先看看PACK_STRUCT_BEGIN和PACK_STRUCT_END定义:
#ifndef PACK_STRUCT_BEGIN
#define PACK_STRUCT_BEGIN
#endif /* PACK_STRUCT_BEGIN */
#ifndef PACK_STRUCT_END
#define PACK_STRUCT_END
#endif /* PACK_STRUCT_END */
由上面的定义可以看出,此处定义了PACK_STRUCT_BEGIN和PACK_STRUCT_END两个常量。可
能大多数人看到这里都会觉得奇怪,怎么会这么使用?相信大多数人都明白#ifndef/#define/#endif的作用,
主要用于防止头文件的重复引用。其实,上面两个常量的定义和使用和头文件的重复引用是一样的道理,
只是这里不是防止头文件的重复引用,而是防止数据结构的重复定义。这里之所以定义其实是考虑到移植
性的缘故,我们知道,不同的CPU位数可能不同,读写总线传输的字节数也可能不同,除了这些以外,还
可能在其他方面存在区别;除了硬件差别外,OS也可能存在很多区别。为了便于移植,lwip采用了宏定
义的方式来进行,对于不同的OS或是硬件,更改相关的宏使之适合于特定的系统即可。
上面的数据结构和常用的数据结构定义还有一些不同的地方,为此,我们先看一个常见的数据结构的定
义: