2009-05-14 7 views
15

Vedere la definizione di TCP in /netinet/tcp.h:Perché un campo a 8 bit ha endianness?

struct tcphdr 
    { 
    u_int16_t th_sport;   /* source port */ 
    u_int16_t th_dport;   /* destination port */ 
    tcp_seq th_seq;    /* sequence number */ 
    tcp_seq th_ack;    /* acknowledgement number */ 
# if __BYTE_ORDER == __LITTLE_ENDIAN 
    u_int8_t th_x2:4;   /* (unused) */ 
    u_int8_t th_off:4;   /* data offset */ 
# endif 
# if __BYTE_ORDER == __BIG_ENDIAN 
    u_int8_t th_off:4;   /* data offset */ 
    u_int8_t th_x2:4;   /* (unused) */ 
# endif 
    u_int8_t th_flags; 
# define TH_FIN  0x01 
# define TH_SYN  0x02 
# define TH_RST  0x04 
# define TH_PUSH  0x08 
# define TH_ACK  0x10 
# define TH_URG  0x20 
    u_int16_t th_win;   /* window */ 
    u_int16_t th_sum;   /* checksum */ 
    u_int16_t th_urp;   /* urgent pointer */ 
}; 

Perché il campo a 8 bit hanno un ordine diverso in endianness? Pensavo che solo i campi a 16 e 32 bit avessero importanza con l'ordine dei byte, e potevi convertire tra endian con ntohs e ntohl, rispettivamente. Quale sarebbe la funzione per la gestione di cose a 8 bit? Se non ce n'è, sembra che un TCP che usa questa intestazione su una piccola macchina endian non funzioni con un TCP su una macchina big endian.

+0

Strano davvero, su quale sistema hai trovato questo file di intestazione? – fbonnet

+0

debian linux. questa versione è inclusa se __USE_BSD è #definito. – Claudiu

risposta

21

Ci sono due tipi di ordine. Uno è l'ordine dei byte, uno è l'ordine dei bitfield. Non esiste un ordine standard sull'ordine bitfield in linguaggio C. Dipende dal compilatore. In genere, l'ordine dei bitfield viene invertito tra big e little endian.

+1

questa sembra la risposta corretta, e ho un vago ricordo di averlo sentito prima, ma non posso in piena coscienza alzarmi senza una citazione ... puoi fornirne uno? – rmeador

+0

questa è l'unica risposta che ha senso per me – Claudiu

+0

non dovrebbe essere __BIG_ENDIAN_BITFIELD/__ LITTLE_ENDIAN_BITFIELD allora? Oppure implicitamente suppongono che l'endianità sia mantenuta uguale tra gli ordini byte e bitfield? – Slava

0

La mia lettura del commento è che i due campi di un byte insieme sono interpretati come un valore a due byte (o erano - sembra che un byte sia inutilizzato in ogni caso). Invece di dichiarare un valore a due byte, dichiarano due valori a un byte, ma invertono l'ordine di dichiarazione a seconda di endianità.

+0

No, è chiaramente intenzione di definire due campi a 4 bit. Vedi per es. http://www.freesoft.org/CIE/Course/Section4/8.htm per il layout dell'intestazione TCP. –

3

È possibile che in questa macchina l'endianess faccia riferimento anche all'ordine dei bit e all'ordine dei byte. This wikipedia article menziona che questo a volte è il caso.

+0

In questa domanda, non ha alcuna relazione con l'ordine dei bit. – kcwu

11

Questo è dipendente dal compilatore e non è portatile. Il modo in cui i campi bit sono ordinati dipende dall'implementazione, sarebbe molto meglio utilizzare un campo a 8 bit e shift/mask per ottenere i sottocampi.

+0

Sembra un piano migliore per me. –

1

La mia comprensione è che il bit ordering e l'endianness sono generalmente due cose diverse. Le strutture con campi bit non sono generalmente portabili su compilatori/architetture. A volte ifdefs può essere usato per supportare diversi ordini di bit. In questo caso l'endianness è davvero irrilevante e dovrebbe essere un ifdef sull'ordinamento dei bit. L'ipotesi che alcune endianess abbiano un certo ordine di bit può essere vera in alcuni casi.

0

Può essere utile sapere che questo codice viene eseguito solo se "# ifdef __FAVOR_BSD". È da /usr/include/netinet/tcp.h

# ifdef __FAVOR_BSD 
typedef u_int32_t tcp_seq; 
/* 
* TCP header. 
* Per RFC 793, September, 1981. 
*/ 
struct tcphdr