Por que o valor do tipo de protocolo para o protocolo IP no frame Ethernet é 8?

0

Estou escrevendo um programa de processamento de pacotes simples. Aqui está o trecho do código:

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

Esta função simples deve imprimir para logfile o valor hexadecimal do tipo de protocolo. E, de fato, imprime o valor '8'. No entanto, tanto na fonte /usr/include/net/ethernet.he online ( link ) eu vejo esse tipo de protocolo IP é definido como 0x0800. Então eu realmente esperava ver o valor 800 (em hexadecimal) ou 2048 (em dez) para ser impresso em arquivo, não 8. Eu pensei que talvez isso tenha algo a ver com endianess e uma necessidade de converter de net byte order para host, mas não encontrei nada sobre isso na página man recvfrom (). Aqui está a chamada que preenche a variável de buffer:

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);

A máquina na qual eu trabalho é little-endian (Ubuntu 16.04). Por que o tipo de protocolo mostra 8?

    
por dmytro.poliarush 03.04.2018 / 11:15

1 resposta

5

O definição de estrutura mostra que h_proto é um inteiro de 16 bits big-endian:

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));

Portanto, você precisa processá-lo com ntohs antes de lê-lo. Depois disso, você verá o valor correto, 0x0800.

    
por 03.04.2018 / 11:23