2016-12-11 19 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 имеет длину заголовка, который будет установлен 5. Поскольку длина заголовка описана в 4 байтовых словах, фактическая длина заголовка составляет 5 × 4 = 20 байт. Минимальная длина - 20 байт. С учетом сказанного мне любопытно, будут ли битовые поля в этой структуре, заданные для iph_ver и iph_ihl, конкретно 4 и 5, потому что это будет IPv4, а IP-заголовок будет 20 байтов в длину. Однако я не уверен, как их битовые поля будут иметь какой-либо эффект или корреляцию их стоимости. Любые объяснения были бы весьма признательны.

Ссылка на код: http://www.tenouk.com/Module43a.html

+2

Это бит поля. –

+0

@ VladfromMoscow Но не битовые поля определяют размер в битах и ​​только в битах? Они не определяют фактическую ценность этих данных, сколько у нее комнаты. Или мне не хватает чего-то фундаментального в битполах и/или как работа с версией и заголовком работает в заголовках ip? –

+1

Это странно, хотя IHL должен быть 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_hl и ip_v являются 4 бита для битовые. Фактические имена полей не имеют значения, только их позиция в заголовке пакета.

Они определяются в другом порядке, в зависимости от платформы, потому что компилятор по-разному распределяет битполя в зависимости от сущности. Это поведение на самом деле не указано в стандарте C, но похоже, что оно совместимо на разных платформах.

+0

Спасибо большое! Я думаю, чтобы избежать подобных явлений, я собираюсь найти новый учебник. –