2009-05-14 20 views
15

Véase la definición de cabecera TCP en /netinet/tcp.h:¿Por qué un campo de 8 bits tiene 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 */ 
}; 

¿Por qué el campo de 8 bits tienen un orden diferente en el orden de bits? Pensé que solo los campos de 16 bits y 32 bits importaban con el orden de bytes, y se podía convertir entre endians con ntohs y ntohl, respectivamente. ¿Cuál sería la función para manejar cosas de 8 bits? Si no hay ninguno, parece que un TCP que usa este encabezado en una pequeña máquina endian no funcionaría con un TCP en una máquina endian grande.

+0

extraño en verdad, en el que el sistema ha encontrado esta archivo de cabecera? – fbonnet

+0

debian linux. esta versión está incluida si __USE_BSD está #defined. – Claudiu

Respuesta

21

Hay dos tipos de orden. Uno es orden de bytes, uno es orden de bitfield. No existe un orden estándar sobre el orden del campo de bits en lenguaje C. Depende del compilador. Normalmente, el orden de los campos de bits se invierte entre los grandes y los pequeños endian.

+1

esto parece ser la respuesta correcta, y tengo un vago recuerdo de haberlo escuchado antes, pero no puedo, con buena conciencia, presentarme sin una cita ... ¿me pueden dar uno? – rmeador

+0

esta es la única respuesta que tiene sentido para mí – Claudiu

+0

¿No debería ser eso __BIG_ENDIAN_BITFIELD/__ LITTLE_ENDIAN_BITFIELD? ¿O implícitamente suponen que la permanencia se mantuvo igual entre los bytes y los bitfield orders? – Slava

0

Mi lectura del comentario es que los dos campos de un byte juntos se interpretan como un valor de dos bytes (o lo fueron - parece que un byte no se usa de todos modos). En lugar de declarar un valor de dos bytes, declaran dos valores de un byte pero invierten el orden de la declaración según endian-ness.

+0

No, claramente tiene la intención de definir dos campos de 4 bits. Ver p. http://www.freesoft.org/CIE/Course/Section4/8.htm para el diseño del encabezado TCP. –

3

Es posible que en esta máquina la endianess también haga referencia al orden de los bits, así como a la orden de los bytes. This wikipedia article menciona que esto es a veces el caso.

+0

En esta pregunta, no tiene relación con el orden de los bits. – kcwu

11

Esto es dependiente del compilador y no portátil. La forma en que se ordenan los campos de bits depende de la implementación, sería mucho mejor usar un campo de 8 bits y un desplazamiento/máscara para obtener los subcampos.

+0

Suena como un mejor plan para mí. –

1

Mi comprensión es que el orden de bits y la permanencia son generalmente dos cosas diferentes. Las estructuras con campos de bits generalmente no son portátiles en compiladores/arquitecturas. En ocasiones, ifdefs se puede usar para admitir diferentes ordenamientos de bits. En este caso, la endianidad es realmente irrelevante y debería ser un ifdef sobre el orden de bits. La suposición de que algunas endiaitudes tienen un cierto orden de bits puede ser cierta en algunos casos.

0

Puede ser útil saber que este código solo se ejecuta si "# ifdef __FAVOR_BSD". Es a partir de /usr/include/netinet/tcp.h

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