藍森林首頁 | 返回主頁 | 本站地圖 | 站內搜索 | 聯繫信箱 |
 您目前的位置:首頁 > 自由軟件 > 技術交流 > 應用編程


    

藍森林 http://www.lslnet.com 2006年6月6日 10:18


如何在FreeBSD下實現獲取MAC地址?謝謝

我用sysctl來獲取MAC地址,但是不能取的MAC地址列表,是怎麼回事?我的代碼如下:
unsigned char *ip2mac(const unsigned long target_ip, unsigned char* target_mac)
{
    int s, mib[6];
    size_t len;
        int i=0;
    char *buf;
    struct rt_msghdr *rtm;
    struct sockaddr_inarp *sin;
    struct sockaddr_dl *sdl;
        int j;

    mib[0] = CTL_NET;
    mib[1] = PF_ROUTE;
    mib[2] = 0;
    mib[3] = AF_INET;
    mib[4] = NET_RT_FLAGS;
    mib[5] = RTF_LLINFO;

    if (sysctl(mib, 6, NULL, &amp;len, NULL, 0) < 0)
        return NULL;
    if ((buf = malloc(len)) == NULL)
        return NULL;
        printf("len = %d\n", len);
    if (sysctl(mib, 6, buf, &amp;len, NULL, 0) < 0)
    {
        free(buf);
        return NULL;
    }
    for(s = 0; s < len; s+= rtm->;rtm_msglen) {
        rtm = (struct rt_msghdr *)(buf + s);
        printf("%d\n", rtm->;rtm_msglen);
        sin = (struct sockaddr_inarp *)(rtm + 1);
        sdl = (struct sockaddr_dl *)((char*)sin+1);
      if (target_ip == sin->;sin_addr.s_addr) {
        memset(target_mac, 0, sizeof(target_mac));
        bcopy((char *)LLADDR(sdl), target_mac, 6);
            free(buf);
            return target_mac;
        }
     }
    free(buf);
    return NULL;
}

如何在FreeBSD下實現獲取MAC地址?謝謝

能夠詳細解釋一下您說的MAC地址列表是什麼意思?
你的程序這一段表示如果取得了與傳入IP匹配的MAC地址,就返回了。
if (target_ip == sin->;sin_addr.s_addr) {
memset(target_mac, 0, sizeof(target_mac));
bcopy((char *)LLADDR(sdl), target_mac, 6);
free(buf);
return target_mac;
}

我對網絡的理解是一個IP只能對應一個MAC地址,但是一個MAC地址可以對應多個IP,如網關。

如何在FreeBSD下實現獲取MAC地址?謝謝

sorry,我寫錯了,我就是想獲得一個MAC地址,但是上面代碼我不能獲得mac地址

如何在FreeBSD下實現獲取MAC地址?謝謝

這是修改後的程序,我在FreeBSD 4.4-RELEASE下編譯運行成功


int ip2mac(u_long target_ip, unsigned char* target_mac){
       
        int s, mib[6];
        size_t len;
        int i=0,j=0;
        char *buf;
        struct rt_msghdr *rtm;
        struct sockaddr_inarp *sin;
        struct sockaddr_dl *sdl;
        u_long tmp_ip;

        mib[0] = CTL_NET;
        mib[1] = PF_ROUTE;
        mib[2] = 0;
        mib[3] = AF_INET;
        mib[4] = NET_RT_FLAGS;
        mib[5] = RTF_LLINFO;

        if(sysctl(mib, 6, NULL, &amp;len, NULL, 0) < 0)return 0;
        if((buf = (char*)malloc(len)) == NULL)return 0;
       
        printf("len = %d\n", len);
        if (sysctl(mib, 6, buf, &amp;len, NULL, 0) < 0){
                free(buf);return 0;
        }
        for(s = 0; s < len; s+= rtm->;rtm_msglen){
                rtm = (struct rt_msghdr *)(buf + s);
                printf("%d\n", rtm->;rtm_msglen);
                sin = (struct sockaddr_inarp *)(rtm + 1);
                //sdl = (struct sockaddr_dl *)((char*)sin+1);
                sdl = (struct sockaddr_dl *)(sin+1);
               
                //printf("%s\n",inet_ntoa(sin->;sin_addr));
                tmp_ip=(u_long)(sin->;sin_addr.s_addr);
                if(target_ip==tmp_ip){
                        memset(target_mac, 0, sizeof(target_mac));
                        //bcopy((char *)LLADDR(sdl), target_mac, 6);
                        //bcopy(target_mac,(char *)LLADDR(sdl),6);
                        strcpy(target_mac,link_ntoa(sdl));
                        free(buf);
                        return 1;
                }
        }
        free(buf);
        return 0;
}


main(int argc,char* argv[]){
       
        unsigned char macstr[256];
        if(argc==1){
                printf("Usage:\tip2mac sourceIP\n");
                return;
        }
        memset(macstr,0,256);
        if(ip2mac(inet_addr(argv[1]),macstr)){
                printf("%s\n",macstr);
        }
        else printf("error\n");
}

如何在FreeBSD下實現獲取MAC地址?謝謝

liupch,謝謝
1、sdl = (struct sockaddr_dl *)((char*)sin+1);這句是不是這樣更好些;如果按你寫的,編譯報告:arithmetic on pointer to an incomplete type。
2、tmp_ip=(u_long)(sin->;sin_addr.s_addr)這句我編譯不過去,提示:dereferencing pointer to incomplete type。
我用的是FreeBSD 4.6-RELEASE,編譯器是gcc version 2.95.3 20010315 (release) [FreeBSD]。
望請指教。謝謝。

如何在FreeBSD下實現獲取MAC地址?謝謝

首先sdl = (struct sockaddr_dl *)((char*)sin+1);就是這句話有問題
因為你首先把sin這個指針轉化成(char*)型,轉化之後再+1,這樣實際上相當於是一個char*的指針加一。而實際的結果應該是sockaddr_inarp 類型的指針加一。

第二個問題我也遇到了,主要是沒有包含正確的頭文件。我一共包含了如下頭文件
#include <sys/types.h>;
#include <sys/socket.h>;
#include <sys/ioctl.h>;
#include <netinet/in.h>;
#include <netinet/if_ether.h>;
#include <sys/sysctl.h>;
#include <sys/types.h>;
#include <net/route.h>;
#include <net/if_dl.h>;
#include <stdio.h>;
#include <string.h>;
#include <fcntl.h>;

我的系統是FreeBSD 4.3-RELEASE
gcc version 2.95.3 [FreeBSD] 20010315 (release)

如何在FreeBSD下實現獲取MAC地址?謝謝

還有一點就是這個程序只能取得本機IP的MAC地址,不能取得其他IP的MAC地址

如何在FreeBSD下實現獲取MAC地址?謝謝

liupch:謝謝,我編譯成功了!

如何在FreeBSD下實現獲取MAC地址?謝謝

如何取得其它機器的ip和mac呢???

如何在FreeBSD下實現獲取MAC地址?謝謝

我這個好像更簡單:(linux 7.2上通過)#include <stdio.h>;
#include <string.h>;
#include <netdb.h>;
#include <arpa/inet.h>;
#include <netinet/in.h>;
#include <sys/types.h>;
#include <sys/socket.h>;
#include <sys/ioctl.h>;
#include <net/if.h>;
#include <net/if_arp.h>;
#include <net/ethernet.h>;
#include <signal.h>;
#include <netinet/ip.h>;

struct in_addr myself,mymask;
int fd_arp;
struct ifreq ifr;

main(int argc,char* argv[]) {
  char device[32];
  struct sockaddr from,to;
  int fromlen;
  struct sockaddr_in *sin_ptr;
  u_char *ptr;
  int n;
  strcpy(device,"lo");
  if((fd_arp=socket(AF_INET,SOCK_PACKET,htons(0x0806)))<0) {
    perror("arp socket error");
    exit(-1);
  }
  
  strcpy(ifr.ifr_name,device);
  if(ioctl(fd_arp,SIOCGIFADDR,&ifr)<0) {
    perror("ioctl SIOCGIFADDR error");
    exit(-1);
  }
  sin_ptr=(struct sockaddr_in *)&ifr.ifr_addr;
  myself=sin_ptr->;sin_addr;

  // get network mask
  if(ioctl(fd_arp,SIOCGIFNETMASK,&ifr)<0) {
    perror("ioctl SIOCGIFNETMASK error");
    exit(-1);
  }
  sin_ptr=(struct sockaddr_in *)&ifr.ifr_addr;
  mymask=sin_ptr->;sin_addr;

  // get mac address
  if(ioctl(fd_arp,SIOCGIFHWADDR,&ifr)<0) {
    perror("ioctl SIOCGIFHWADDR error");
    exit(-1);
  }
  ptr=(u_char *)&ifr.ifr_ifru.ifru_hwaddr.sa_data[0];
  printf("\nrequest mac %02x:%02x:%02x:%02x:%02x:%02x,",*ptr,*(ptr+1),*(ptr+2),*(ptr+3),*(ptr+4),*(ptr+5));
  printf("\nrequest netmask %s",inet_ntoa(mymask));
  printf("\nrequest IP %s\n",inet_ntoa(myself));
}

如何在FreeBSD下實現獲取MAC地址?謝謝

我這個好像更簡單:(linux 7.2上通過)#include <stdio.h>;
#include <string.h>;
#include <netdb.h>;
#include <arpa/inet.h>;
#include <netinet/in.h>;
#include <sys/types.h>;
#include <sys/socket.h>;
#include <sys/ioctl.h>;
#include <net/if.h>;
#include <net/if_arp.h>;
#include <net/ethernet.h>;
#include <signal.h>;
#include <netinet/ip.h>;

struct in_addr myself,mymask;
int fd_arp;
struct ifreq ifr;

main(int argc,char* argv[]) {
  char device[32];
  struct sockaddr from,to;
  int fromlen;
  struct sockaddr_in *sin_ptr;
  u_char *ptr;
  int n;
  strcpy(device,"lo");
  if((fd_arp=socket(AF_INET,SOCK_PACKET,htons(0x0806)))<0) {
    perror("arp socket error");
    exit(-1);
  }
  
  strcpy(ifr.ifr_name,device);
  if(ioctl(fd_arp,SIOCGIFADDR,&ifr)<0) {
    perror("ioctl SIOCGIFADDR error");
    exit(-1);
  }
  sin_ptr=(struct sockaddr_in *)&ifr.ifr_addr;
  myself=sin_ptr->;sin_addr;

  // get network mask
  if(ioctl(fd_arp,SIOCGIFNETMASK,&ifr)<0) {
    perror("ioctl SIOCGIFNETMASK error");
    exit(-1);
  }
  sin_ptr=(struct sockaddr_in *)&ifr.ifr_addr;
  mymask=sin_ptr->;sin_addr;

  // get mac address
  if(ioctl(fd_arp,SIOCGIFHWADDR,&ifr)<0) {
    perror("ioctl SIOCGIFHWADDR error");
    exit(-1);
  }
  ptr=(u_char *)&ifr.ifr_ifru.ifru_hwaddr.sa_data[0];
  printf("\nrequest mac %02x:%02x:%02x:%02x:%02x:%02x,",*ptr,*(ptr+1),*(ptr+2),*(ptr+3),*(ptr+4),*(ptr+5));
  printf("\nrequest netmask %s",inet_ntoa(mymask));
  printf("\nrequest IP %s\n",inet_ntoa(myself));
}

如何在FreeBSD下實現獲取MAC地址?謝謝

好東東!!!!



Copyright © 1999-2000 LSLNET.COM. All rights reserved. 藍森林網站 版權所有。 E-mail : webmaster@lslnet.com