struct ip 和 struct iphdr 的区别

Posted

技术标签:

【中文标题】struct ip 和 struct iphdr 的区别【英文标题】:Difference between struct ip and struct iphdr 【发布时间】:2017-08-08 00:20:51 【问题描述】:

我正在尝试了解网络是如何工作的,我正在做一些测试,发送一些包裹......无论如何

我的意思是我找不到"protocol" structure"protocol header" structure 之间的真正区别。

对于 ip 结构,它们的大小都是 20 字节。 但例如:

struct ipstruct iphdr 大小为 20 个字节 struct icmp 大小为 28 个字节 struct icmphdr 大小为 8 个字节

我猜struct icmp 包含struct ip/iphdr?

而且我见过的每个协议都有相同的结构。 struct udp / struct udphdr,

它是否链接到IP_HDRINCL 设置为setsockopt()

所以我的问题是它们之间的真正区别是什么?以及何时使用好的。

ip 和 iphdr 结构:

struct iphdr 
    #if defined(__LITTLE_ENDIAN_BITFIELD)
        __u8    ihl:4,
                version:4;
    #elif defined (__BIG_ENDIAN_BITFIELD)
        __u8    version:4,
                ihl:4;
    #else
        #error  "Please fix <asm/byteorder.h>"
    #endif
         __u8   tos;
         __u16  tot_len;
         __u16  id;
         __u16  frag_off;
         __u8   ttl;
         __u8   protocol;
         __u16  check;
         __u32  saddr;
         __u32  daddr;
         /*The options start here. */
;

以及IP HDR

struct ip 
#if BYTE_ORDER == LITTLE_ENDIAN 
    u_char  ip_hl:4,        /* header length */
        ip_v:4;         /* version */
#endif
#if BYTE_ORDER == BIG_ENDIAN 
    u_char  ip_v:4,         /* version */
        ip_hl:4;        /* header length */
#endif
    u_char  ip_tos;         /* type of service */
    short   ip_len;         /* total length */
    u_short ip_id;          /* identification */
    short   ip_off;         /* fragment offset field */
#define IP_DF 0x4000            /* dont fragment flag */
#define IP_MF 0x2000            /* more fragments flag */
    u_char  ip_ttl;         /* time to live */
    u_char  ip_p;           /* protocol */
    u_short ip_sum;         /* checksum */
    struct  in_addr ip_src,ip_dst;  /* source and dest address */
;

这里是ICMP结构代码:https://www.cymru.com/Documents/ip_icmp.h

【问题讨论】:

为什么两个代码不使用相同的类型名称?请注意,_Bool, int, signed int, unsigned int 以外的位字段类型,如上所示,是实现定义的行为。 chux,我没有创建结构,它们都在 netinet/ip.h 中定义, _minimum IPv4 标头大小为 20 个八位字节,但选项可以使其更大。 ICMP是一种封装成IP载荷的协议,它的头不是IP头。 IP pseudo header google 是你的朋友。 @wildplasser 谢谢!我不知道! 【参考方案1】:

struct ipstruct iphdr是同一个底层结构的两个不同定义,从不同的地方引入。

struct ip 定义在 &lt;netinet/ip.h&gt; 中,这是 UNIX 系统上相当标准的标头。

struct iphdr&lt;linux/ip.h&gt; 中定义。此标头(和结构)是特定于 Linux 的,不会出现在其他操作系统中。

如果您不确定要使用哪一个,请使用struct ip;使用这种结构的代码更有可能移植到非 Linux 系统。


struct icmpstruct icmphdr 情况更糟:

&lt;netinet/icmp.h&gt; 定义两者 struct icmpstruct icmphdr&lt;linux/icmp.h&gt; 还定义了 struct icmphdr,与 &lt;netinet/icmp.h&gt; 的定义具有相似的结构(但通常是不同的字段名称)。

首先:不要包含&lt;linux/icmp.h&gt;,除非您有充分的理由。您不能包含这两个标头——它们会发生冲突——并且大多数软件都需要 netinet 定义。

第二个:struct icmphdr,顾名思义,就是标题。 struct icmp 定义结构化 ICMP 消息的内容,例如目标不可达消息。

【讨论】:

谢谢!那么icmp / icmphdr 呢? 对于struct ip 在 Linux 系统之外的可移植性建议加 1。

以上是关于struct ip 和 struct iphdr 的区别的主要内容,如果未能解决你的问题,请参考以下文章

将 char* 转换为 struct

struct.pack引发“struct.error:required参数不是整数”

如何使用 inet_pton 和 struct ifreq 从 C 程序设置 IP 地址

域名和网络地址结构体---struct hostent

((struct ip *)0)是啥意思???

struct ifreq学习和实例