이더넷 프레임 8에서 IP 프로토콜의 프로토콜 유형 값이 왜 그렇습니까?

이더넷 프레임 8에서 IP 프로토콜의 프로토콜 유형 값이 왜 그렇습니까?

저는 간단한 패킷 핸들러를 작성하고 있습니다. 다음은 발췌한 코드입니다.

void print_ethernet_header(unsigned char* buffer)
{
        struct ethhdr *eth = (struct ethhdr *)buffer;
        fprintf(logfile , "   |-Protocol  : %x \n",eth->h_proto);
}

이 간단한 함수는 프로토콜 유형의 16진수 값을 로그 파일에 인쇄해야 합니다. 실제로 "8" 값을 인쇄합니다. 그러나 소스 /usr/include/net/ethernet.h 및 라인(https://en.wikipedia.org/wiki/EtherType) IP 프로토콜 유형이 0x0800으로 정의되어 있는 것을 확인했습니다. 따라서 실제로 파일에 8이 아닌 800(16진수) 또는 2048(10진수) 값이 인쇄될 것으로 예상합니다. 나는 이것이 바이트 순서와 관련이 있을 수 있고 네트워크 바이트 순서에서 호스트로 변환해야 한다고 생각했지만, recvfrom() 매뉴얼 페이지에서 이에 대한 정보를 찾지 못했습니다. 다음은 버퍼 변수를 채우는 호출입니다.

sock_raw = socket(AF_PACKET,SOCK_RAW,htons(ETH_P_ALL));
//some code here...
data_size = recvfrom(sock_raw , buffer , bufsize , 0 , (struct sockaddr*)&saddr , (socklen_t*)&saddr_size);

제가 작업 중인 컴퓨터는 리틀 엔디안(Ubuntu 16.04)입니다. 프로토콜 유형이 8로 표시되는 이유는 무엇입니까?

답변1

구조 정의이것이 h_proto빅엔디안 16비트 정수임을 보여줍니다:

struct ethhdr {
        unsigned char   h_dest[ETH_ALEN];       /* destination eth addr */
        unsigned char   h_source[ETH_ALEN];     /* source ether addr    */
        __be16          h_proto;                /* packet type ID field */
} __attribute__((packed));

ntohs따라서 읽기 전에 실제로 처리해야 합니다. 이렇게 하면 올바른 값 0x0800이 표시됩니다.

답변2

EtherType 광고를 인쇄하려고 시도했지만 올바른 값을 얻지 못하면 컴퓨터가 엔디안을 올바른 방식으로 해석하지 않는 것입니다. 해결책은 다음과 같습니다.

 int etherType = ntohs(eth->h_proto);
 printf("EtherType: 02%x", etherType);

그러면 문서에 지정된 EtherType이 제공됩니다.

관련 정보