原始数据包创建导致IP字段的顺序不正确

时间:2014-11-14 21:13:42

标签: c++ c sockets packet endianness

简单地说,当我处理标志和偏移字段时,我遇到了IP协议内的持久性和原始数据包的问题。

我正在尝试使用UDP原始数据包创建自己的数据包。我正在使用带有位域的C样式结构。

我遇到了IP协议的IP标志和Fragment Offset字段的问题。这是因为字节的排序是不同的。我想能够使用 htons()函数来改变位的顺序,但是当我这样做时,我相信我搞砸了。

这是我正在创建的数据包的快速输出。我们感兴趣的是字节6和字节7.(粗体和斜体)。

0 0100 0101 0001 0000 0001 1100 0000 0000 1101 0100 0011 0001 0000 0001 0000 1000

8 0100 0000 0001 0001 0110 0111 1000 1010 0000 0001 0000 0001 0000 0001 0000 0001

16 0000 0011 0000 0011 0000 0011 0000 0011 0000 1000 1010 1110 0001 0001 0101 1100

24 0000 0000 0000 1000 0000 0000 0000 0000

我有以下结构......(记下三个标志的位域和偏移量。

struct IPHeader
{
    unsigned char iph_ihl:4, iph_ver:4;     
    unsigned char iph_tos;                  
    unsigned short int iph_len;             
    unsigned short int iph_ident;           
    unsigned char iph_flag_X:1;                
    unsigned char iph_flag_D:1;
    unsigned char iph_flag_M:1;
    unsigned short int iph_offset:13;         
    unsigned char iph_ttl;                 
    unsigned char iph_protocol;            
    unsigned short int iph_chksum;          
    unsigned int iph_sourceip;              
    unsigned int iph_destip;                
};

在我的代码中,我试图将偏移量设置为1,并设置D标志。 (仅举例)人们会认为我的代码可能是......

ipheader->iph_flag_X = 1;
ipheader->iph_flag_M = 0;
ipheader->iph_flag_D = 0;
ipheader->iph_offset = htons(1);

这导致字节6和7的以下打印输出.... 0000 0001 0000 0001

我希望看到此代码的内容如下...... 1000 0000 0000 0001

第二组byteam尝试使用UDP原始数据包创建自己的数据包。我正在使用带有位域的C样式结构。准确地将X标志集和片段偏移量反映为值1.请记住,片段偏移占用13位,并且三个标志均为1位。

1 个答案:

答案 0 :(得分:0)

位字行为是实现定义的。根据K& R

"fields are assigned left to right on some machines and right to left on others"

因此,您的结构定义必须考虑到这一点。虽然您可能会或可能不会在“Little-Endian”机器上进行开发,但是看看UBUNTU的IP Header定义可能会让您开始使用更便携的课程(并在此过程中解决您的问题):

struct ip
  {
#if __BYTE_ORDER == __LITTLE_ENDIAN
    unsigned int ip_hl:4;               /* header length */
    unsigned int ip_v:4;                /* version */
#endif
#if __BYTE_ORDER == __BIG_ENDIAN
    unsigned int ip_v:4;                /* version */
    unsigned int ip_hl:4;               /* header length */
#endif
    u_int8_t ip_tos;                    /* type of service */
    u_short ip_len;                     /* total length */
    u_short ip_id;                      /* identification */
    u_short ip_off;                     /* fragment offset field */
#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 */
    u_int8_t ip_ttl;                    /* time to live */
    u_int8_t ip_p;                      /* protocol */
    u_short ip_sum;                     /* checksum */
    struct in_addr ip_src, ip_dst;      /* source and dest address */
  };
相关问题