strncmp()和if()不一致…我缺少什么??(原始插座)

strncmp()和if()不一致…我缺少什么??(原始插座),c,strcmp,raw-sockets,C,Strcmp,Raw Sockets,我正在尝试构建一个简单的echo服务器/客户端,它使用原始套接字在以太网级别上工作。 服务器端自行工作并在eth0上显示所有传入的数据包。 客户端在eth0上工作并发送以太网数据包。我与wireshark进行了检查,可以看到数据包发出。 我现在想做一个过滤器,只查看我感兴趣的数据包。这基于目标/源地址 在下面的代码中,是否有人可以向我解释为什么strncmp返回零意味着字符串匹配,但ifethernet\u header->h\u dest==mac无法执行不匹配。 变量mac和ethernet

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

在下面的代码中,是否有人可以向我解释为什么strncmp返回零意味着字符串匹配,但ifethernet\u header->h\u 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);
 }

}
这是什么代码

if(ethernet_header->h_dest == mac)
在C中不进行字符串比较,只进行指针比较,在您的情况下,指针比较始终为false。

ifethernet\u header->h\u dest==mac只比较原始指针值。这意味着它会检查两个字符串是否从相同的内存地址开始。通常,这不是你想要的


要比较两个c字符串的内容,请始终使用strncmp。

不能使用==运算符测试字符串是否相等。这就是strcmp函数首先存在的原因。

不应使用strncmp或裸if来比较MAC地址

第一种方法在它们可能有一个嵌入的零字节的情况下无法正常工作,这会导致strncmp声明它们相等,而实际上它们不相等。这是因为strncmp包含以下两个值:

ff ff 00 ff ff ff
ff ff 00 aa aa aa
它只检查第一个零字节

第二种方法不起作用,因为您正在比较指针,而不是指针指向的内容。如果您具有以下内存布局:

0x12345678 (mac) | 0x11111111 |
0x1234567c (eth) | 0x11111111 |
然后将mac和eth与if mac==eth进行比较,会得到false,因为它们是不同的指针,一个以78结尾,另一个以7c结尾

您应该改用memcmp,因为它将比较原始内存字节,而不会在早期的零字节处停止:

int result = memcmp (ethernet_header->h_dest, mac, ETH_ALEN);
strncmp将指向char的指针作为其前两个参数

strncmp返回零,因为这两个位置的字符串对于ETH_ALEN字符是相同的-这并不意味着ethernet_header->h_dest和mac是相等的。它们是两个不同的指针

输出:

a1 and a2: strcmp gives 0 and they are different  
p1 and p2: strcmp gives 0 and they are equal  
s1 and s2: strcmp gives 0 and they are different
p1和p2相等,因为它们都指向内存中相同的常量字符串。 对于数组,将为堆栈中的每个数组变量分配一个5字节的连续块,并将字符串asdf\0复制到这些位置。 s1和s2是两个不同的指针,指向堆中恰好包含相同值的5字节序列的两个不同块。 在C中,==不能像您所想的那样处理字符串。您必须改用strncmp

换衣服

 if(ethernet_header->h_dest == mac) {


啊,真的!符合事实的符合事实的简单的错误!谢谢大家!请注意,这种使用strcmp(memcmp得到保证)的bug在过去一直是一个安全问题,例如在比较散列值时。
 if(ethernet_header->h_dest == mac) {
if(result == 0) {