strncmp()和if()不同意......我错过了什么?(原始插座)

Nom*_*ien 0 c raw-sockets strcmp

我正在尝试构建一个在以太网级别上工作的简单echo服务器/客户端(使用原始套接字).服务器端本身工作并显示eth0上的所有传入数据包.客户端工作并在eth0上发送以太网数据包(我用wireshark检查了这个数据包,可以看到数据包输出.)我现在想要制作一个过滤器,只查看我感兴趣的数据包.(这基于目的地/源地址.)

在下面的代码,可能有人请向我解释为什么STRNCMP返回零(指字符串匹配),但还没有了"如果(ethernet_header-> h_dest == MAC)"执行失败(不匹配).变量"mac"和"ethernet_header-> h_dest"都是相同的类型和长度.

一些更多的背景: - 这是Linux 64位完成(Ubuntu的) - 我使用的是同一台机器上发送/接收的eth0 ....我不认为这应该是一个问题吗?

我只是不明白为什么strcmp返回一个匹配,如果没有.我错过了什么?

void ParseEthernetHeader(unsigned char *packet, int len) {
    struct ethhdr *ethernet_header;
 unsigned char mac[ETH_ALEN] = {0x01, 0x55, 0x56, 0x88, 0x32, 0x7c}; 

 if (len > sizeof(struct ethhdr)) {
  ethernet_header = (struct ethhdr *) packet;

  int result = strncmp(ethernet_header->h_dest, mac, ETH_ALEN);
  printf("Result: %d\n", result);

  if(ethernet_header->h_dest == mac) {
   /* First set of 6 bytes are Destination MAC */
   PrintInHex("Destination MAC: ", ethernet_header->h_dest, 6);
   printf("\n");

   /* Second set of 6 bytes are Source MAC */
   PrintInHex("Source MAC: ", ethernet_header->h_source, 6);
   printf("\n");

   /* Last 2 bytes in the Ethernet header are the protocol it carries */
   PrintInHex("Protocol: ", (void *) &ethernet_header->h_proto, 2);
   printf("\n\n");
   printf("Length: %d\n",len);
  }

 } else {
  printf("Packet size too small (length: %d)!\n",len);
 }

}
Run Code Online (Sandbox Code Playgroud)

pax*_*blo 9

既不strncmp也不裸if应该用于比较的MAC地址.

第一种方法在它们可能具有嵌入的零字节的情况下将无法正常工作,这将导致strncmp在它们实际上不存在时表明它们是相等的.那是因为strncmp以下两个值中的一个:

ff ff 00 ff ff ff
ff ff 00 aa aa aa
Run Code Online (Sandbox Code Playgroud)

将是真的(它只检查第一个零字节).

第二个将无法工作,因为您正在比较指针而不是指针指向的内容.如果您有以下内存布局:

0x12345678 (mac) | 0x11111111 |
0x1234567c (eth) | 0x11111111 |
Run Code Online (Sandbox Code Playgroud)

然后比较macethif (mac == eth)会给你false,因为它们是不同的指针,一个在结束78,另一个在7c.

您应该使用,memcmp因为它将比较原始内存字节而不停留在早期零字节:

int result = memcmp (ethernet_header->h_dest, mac, ETH_ALEN);
Run Code Online (Sandbox Code Playgroud)