tcphdr 구조체에서 endian 관련 질문입니다.
struct tcphdr {
__be16 source;
__be16 dest;
__be32 seq;
__be32 ack_seq;
#if defined(__LITTLE_ENDIAN_BITFIELD)
__u16 res1:4,
doff:4,
fin:1,
syn:1,
rst:1,
psh:1,
ack:1,
urg:1,
ece:1,
cwr:1;
#elif defined(__BIG_ENDIAN_BITFIELD)
__u16 doff:4,
res1:4,
cwr:1,
ece:1,
urg:1,
ack:1,
psh:1,
rst:1,
syn:1,
fin:1;
#else
#error "Adjust your defines"
#endif
__be16 window;
__sum16 check;
__be16 urg_ptr;
};
위의 구조체에서 endian 에 따라서 bit 의 순서 또는 byte 의 순서가 달라지는 것 같은데요.
왜 시스템의 endian 에 따라서 구조체의 bit 필드의 순서가 바뀌는지 모르겠습니다.
어차피 네트워크에서 올라온 data 는 big 이든 little 이든 동일한 순서로 되어 있지 않나요?
가령 SYN 00000010 이런식으로 드라이버에서 올라왔다면 big 이나 little 이나 bit 의 순서가
똑같아야 하지 않나요??
메모리상의 위치와 구조체 필드의 위치가 바뀌어야 하는 이유가 있나요?
고수님들의 조언 부탁드립니다.
네트워크로 들어온 데이터야 항상 그 순서이기는
네트워크로 들어온 데이터야 항상 그 순서이기는 합니다만,
그 데이터를 그대로 시스템에서 사용하다가는 난리가 납니다.
endian 이라는게 그렇게 생겨먹은 녀석이죠.
byte order가 다르기 때문에 2바이트 이상의 타입 부터는 원치 않은 결과가 나올 수 있습니다.
0x0102 라는 네트워크 데이터는 빅엔디언에서는 0x0102 그대로, 리틀 엔디언에서는 0x0201로 저장을 해야 실제 십진수 값인
258로 정상적으로 읽어들일 수 있습니다.
가령 리틀 엔디언 시스템에서 아무런 여과없이 그대로 사용한다면 513이라는 십진수로 읽어들일테죠.
이것은 원치 않은 결과일테니 문제가 생길겁니다.
그리하여 보통 host 데이터를 network 데이터로 정렬해주고,
그 역으로 network 데이터를 host 데이터로 정렬해주는 API를 사용합니다.
hostnl, hostns, ntohl, ntohs 이녀석들이죠.
음.. 부족한점이나, 실수한 점은 아래 다른 분들이 ^^;;
-----------------
한글을 사랑합니다.
감사합니다. 하지만 ....
제가 궁금한점은 byte는 그렇다 쳐도 bit 의 순서도 바뀌나요?
저 구조체에서 엔디안에 따라 bit 필드의 순서가 바뀌어서
bit 의 순서도 바뀌는지 궁금합니다.
또한 skb의 데이터를 tcphder 로 캐스팅할 경우 문제는 안생기나요??
답변 주시면 감사하겠습니다.
비스트 순서가 바뀌는 이유는 H/W 의 속도를 위해서입니다.
OS에서 사용하는 데이타를 CPU로 전달해서 사용할때 메모리의 비트를 채우는 순서를 빠르게 하기위해서 설계된 방식입니다.
댓글 달기