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 *) ðernet_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)
既不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)
然后比较mac与eth同if (mac == eth)会给你false,因为它们是不同的指针,一个在结束78,另一个在7c.
您应该使用,memcmp因为它将比较原始内存字节而不停留在早期零字节:
int result = memcmp (ethernet_header->h_dest, mac, ETH_ALEN);
Run Code Online (Sandbox Code Playgroud)