2009-07-09 127 views
1

可能重复:
Getting the MAC address of the remote host查找MAC地址

我工作具有客户端 - 服务器架构的模块上。我必须根据MAC address对连接的同级机器进行身份验证。

在安装时,我存储一个加密的有效MAC地址列表。

请注意,我无法控制此同级机器,并且某些第三方应用程序将在此上运行,我无法在此同级机器上安装任何应用程序。

运行时发生套接字连接时,我需要知道连接中使用的IP地址的MAC地址,以便我可以根据以前存储的MAC地址对其进行验证。

是否有任何C /可用C++的API,它可以帮助我得到的IP地址的MAC地址。这台机器通常连接在局域网中,但它可以位于不同的子网上。

我的模块多平台和运行在Windows,Solaris和Linux和类似的同行机器可以在任何操作系统上运行。

+4

如果你花了两分钟搜索“mac地址”,你会发现http://stackoverflow.com/questions/1092463/getting-the-mac-address-of-the-remote-host和其他几个告诉你答案是,当两台机器不在同一个局域网中时,这根本不可能。 – 2009-07-09 15:35:41

+0

我的错误,我错过了这个问题。 大部分时间点的同行都在同一个子网上,但有可能存在不同的子网。 我会经历所提到的问题。 – nurxb01 2009-07-09 15:47:17

+0

其实,我建议你尝试http://stackoverflow.com/search?q=mac%20address&tab=newest。 – 2009-07-09 15:48:26

回答

1

不通过MAC地址进行身份验证。欺骗他们很容易。使用一个HTTP认证库,如Chilkat

8

不幸的是,简单的答案实际上是“不这样做”。

如果您的对等机器位于不同的子网上(因此您和对等体之间的流量正在通过路由器),那么您无法做到您想要的 - 您收到的数据包的MAC地址将是将它们转发给您的路由器的MAC地址,因为这是您要与之通信的链路层设备。只有距离对方机器最近的路由器才能知道对等体的MAC地址是什么 - 并且不会传递此信息。

如果对等机器都在同一个子网,那么进入的数据包将包含在以太网头端的MAC地址,...但在此之前的数据包被发送到您的应用程序这个被扒掉。您的选择几乎局限于您正在监听的网络接口上的数据包捕获以获取整个数据包,或使用系统提供的任何工具来检查本地ARP表。这两个选项都非常依赖于平台!

而且,这两个选项很可能继续不加修改地工作,如果你正在处理的接口不是以太网接口(也许他们PPP链路,或WiFi,或某种形式的虚拟化的时髦接口,.. ),他们也不会使用IPv6。

如果毕竟这样,你仍然确定,请查看libpcap/WinPCap数据包捕获,这是想到的最便携的选项。要检查本地ARP表,Linux,OS X,Solaris和Windows都提供了一个arp命令行实用程序,但语法可能会有所不同。如果一个API可用,我不希望平台之间有任何共同点 - 这种事情没有标准,因为你真的不应该这样做!

1

正如mcandre提到的,这是非常容易欺骗的MAC地址,但还是回答你的问题,我认为,如果你是在同一个局域网上,你可以做到这一点在所有操作系统的通过BSD风格的插座:

这里有一些示例代码this forum post

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <string.h> 
#include <sys/ioctl.h> 
#include <net/if.h> 
#include <arpa/inet.h> 

int main(int argc, char *argv[]) { 
    struct ifreq ifr; 
    int sock, j, k; 
    char *p, addr[32], mask[32], mac[32]; 

    if (argc<2) { 
     fprintf(stderr,"missing argument, example: eth0\n"); 
     return 1; 
    } 

    sock=socket(PF_INET, SOCK_STREAM, 0); 
    if (-1==sock) { 
     perror("socket() "); 
     return 1; 
    } 

    strncpy(ifr.ifr_name,argv[1],sizeof(ifr.ifr_name)-1); 
    ifr.ifr_name[sizeof(ifr.ifr_name)-1]='\0'; 

    if (-1==ioctl(sock, SIOCGIFADDR, &ifr)) { 
     perror("ioctl(SIOCGIFADDR) "); 
     return 1; 
    } 
    p=inet_ntoa(((struct sockaddr_in *)(&ifr.ifr_addr))->sin_addr); 
    strncpy(addr,p,sizeof(addr)-1); 
    addr[sizeof(addr)-1]='\0'; 

    if (-1==ioctl(sock, SIOCGIFNETMASK, &ifr)) { 
     perror("ioctl(SIOCGIFNETMASK) "); 
      return 1; 
     } 
     p=inet_ntoa(((struct sockaddr_in *)(&ifr.ifr_netmask))->sin_addr); 
     strncpy(mask,p,sizeof(mask)-1); 
     mask[sizeof(mask)-1]='\0'; 

     if (-1==ioctl(sock, SIOCGIFHWADDR, &ifr)) { 
     perror("ioctl(SIOCGIFHWADDR) "); 
     return 1; 
    } 
    for (j=0, k=0; j<6; j++) { 
     k+=snprintf(mac+k, sizeof(mac)-k-1, j ? ":%02X" : "%02X", 
      (int)(unsigned int)(unsigned char)ifr.ifr_hwaddr.sa_data[j]); 
    } 
    mac[sizeof(mac)-1]='\0'; 

    printf("\n"); 
    printf("name: %s\n",ifr.ifr_name); 
    printf("address: %s\n",addr); 
    printf("netmask: %s\n",mask); 
    printf("macaddr: %s\n",mac); 
    printf("\n"); 

    close(sock); 
    return 0; 
} 
2

这是不可能的。不保证您的连接对等体甚至有一个MAC地址。对等体完全可以通过拨号(PPP)或其他非以太网接口连接到网络。