Perché un campo a 8 bit hanno endianness?
-
21-08-2019 - |
Domanda
Vedere la definizione di TCP in /netinet/tcp.h:
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? Ho pensato che solo i campi a 16 bit ea 32 bit contava con ordine di byte, e si potrebbe convertire tra endians con ntohs e ntohl, rispettivamente. Quale sarebbe la funzione di essere per il trattamento delle cose a 8-bit? Se non c'è nessuno, sembra che un TCP utilizzando questa intestazione su una macchina little endian non avrebbe funzionato con un TCP su una grande macchina endian.
Soluzione
Ci sono due tipi di ordine. Uno è l'ordine dei byte, uno è ordine campo di bit. Non v'è alcun ordine standard sull'ordine campo di bit in linguaggio C. Dipende dal compilatore. In genere, l'ordine dei campi di bit sono invertiti tra grandi e little endian.
Altri suggerimenti
Questo è il compilatore-dipendente e non portabile. Come campi di bit sono ordinate è a carico di attuazione, sarebbe molto meglio qui per utilizzare un campo di 8 bit e spostamento / maschera per ottenere i sottocampi.
E 'possibile che in questa macchina l'endianess si riferisce anche l'ordine dei bit così come l'ordine dei byte. questo articolo di Wikipedia afferma che questo è a volte il caso.
La mia comprensione è che l'ordinazione bit e endianness sono generalmente due cose diverse. Strutture con bit-field non sono generalmente portabile su compilatori / architetture. A volte ifdefs può essere utilizzato per supportare diversi ordinamenti bit. In questo caso l'endianness è davvero irrilevante e dovrebbe essere un ifdef circa l'ordinazione bit. L'ipotesi che alcuni endianesses hanno una certa po 'di ordine può essere vero in alcuni casi.
La mia lettura del commento è che i due campi da un byte insieme vengono interpretati come un valore a due byte (o erano - sembra che un byte è inutilizzato comunque). Piuttosto che dichiarare un valore a due byte, dichiarano due valori di un byte ma invertire l'ordine di dichiarazione seconda endian-ness.
Può essere utile sapere che questo è il codice viene eseguito solo se "# ifdef __FAVOR_BSD". E 'da /usr/include/netinet/tcp.h
# ifdef __FAVOR_BSD
typedef u_int32_t tcp_seq;
/*
* TCP header.
* Per RFC 793, September, 1981.
*/
struct tcphdr