2016-12-11 37 views
1

我正在学习有关Linux和教程中原始套接字编程我发现此代码巧合:不明确的代码目的?

struct ipheader { 
unsigned char  iph_ihl:5, iph_ver:4; //<--------------These 
unsigned char  iph_tos; 
unsigned short int iph_len; 
unsigned short int iph_ident; 
unsigned char  iph_flag; 
unsigned short int iph_offset; 
unsigned char  iph_ttl; 
unsigned char  iph_protocol; 
unsigned short int iph_chksum; 
unsigned int  iph_sourceip; 
unsigned int  iph_destip; 
}; 

iph_ver持有的IP版本,这将是4,和iph_ihl持有将要设置的报头长度由于标题长度用4字节字描述,所以实际标题长度为5×4 = 20字节。 20个字节是最小长度。这样说我很好奇,如果这个结构中的位字段设置为iph_veriph_ihl,特别是4和5,因为它将是IPv4,并且IP标头的长度将是20个字节。不过,我不确定他们的位域如何在它们的值上产生任何影响或关联。任何解释将不胜感激。

链接代码:http://www.tenouk.com/Module43a.html

+2

它是位域。 –

+0

@VladfromMoscow但是,不要以位为单位来确定大小,只能以位为单位?他们不确定数据的实际价值,只是它有多少空间。或者我错过了有关位域的基本知识和/或版本和标头长度在IP标头中的工作原理? –

+1

虽然这很奇怪,但国际人道法应该是一个4位字段。 – harold

回答

3

从本教程的代码片段其实是不对的!

这里是IP报文头一个正确的定义:

/* 
* Structure of an internet header, naked of options. 
* 
* We declare ip_len and ip_off to be short, rather than u_short 
* pragmatically since otherwise unsigned comparisons can result 
* against negative integers quite easily, and fail in subtle ways. 
*/ 
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 */ 
}; 

正如你所看到的,ip_hlip_v是4位宽位域。字段的实际名称无关紧要,只是它们在数据包标题中的位置。

根据平台的不同,它们的定义顺序不同,因为编译器根据字节顺序不同地分配位域。这一行为实际上并未在C标准中规定,但似乎跨平台一致。

+0

非常感谢!我认为为了避免类似事件,我要找一个新的教程。 –