我正在编写一个简单的数据包处理程序。下面是代码摘录:
void print_ethernet_header(unsigned char* buffer)
{
struct ethhdr *eth = (struct ethhdr *)buffer;
fprintf(logfile , " |-Protocol : %x \n",eth->h_proto);
}这个简单的函数应该将协议类型的十六进制值打印到日志文件中。事实上,它确实打印了值'8‘。但是,在源/usr/include/net/ethernet.h和online (https://en.wikipedia.org/wiki/EtherType)中,我看到IP协议类型被定义为0x0800。所以我实际上希望看到值800 (十六进制)或2048 (12月)被打印到文件中,而不是8。我想这可能与endianess有关,需要从净字节顺序转换为主机,但是在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);我工作的机器是小终端(Ubuntu16.04)。为什么协议类型显示为8?
发布于 2018-04-03 09:23:26
结构定义显示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。
发布于 2021-04-27 11:17:57
如果您尝试打印那个EtherType广告,您没有得到正确的值,那么您的机器就没有以正确的方式解释endianness。解决办法是:
int etherType = ntohs(eth->h_proto);
printf("EtherType: 02%x", etherType);这将准确地给出文档中指定的EtherType。
https://unix.stackexchange.com/questions/435233
复制相似问题