免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 7185 | 回复: 11
打印 上一主题 下一主题

如何在FreeBSD下实现获取MAC地址?谢谢 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2003-01-21 14:37 |只看该作者 |倒序浏览
我用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;
}

论坛徽章:
0
2 [报告]
发表于 2003-01-21 15:52 |只看该作者

如何在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,如网关。

论坛徽章:
0
3 [报告]
发表于 2003-01-21 15:55 |只看该作者

如何在FreeBSD下实现获取MAC地址?谢谢

sorry,我写错了,我就是想获得一个MAC地址,但是上面代码我不能获得mac地址

论坛徽章:
0
4 [报告]
发表于 2003-01-21 17:28 |只看该作者

如何在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";
}

论坛徽章:
0
5 [报告]
发表于 2003-01-21 17:47 |只看该作者

如何在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]。
望请指教。谢谢。

论坛徽章:
0
6 [报告]
发表于 2003-01-21 17:53 |只看该作者

如何在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)

论坛徽章:
0
7 [报告]
发表于 2003-01-21 17:59 |只看该作者

如何在FreeBSD下实现获取MAC地址?谢谢

还有一点就是这个程序只能取得本机IP的MAC地址,不能取得其他IP的MAC地址

论坛徽章:
0
8 [报告]
发表于 2003-01-22 09:14 |只看该作者

如何在FreeBSD下实现获取MAC地址?谢谢

liupch:谢谢,我编译成功了!

论坛徽章:
0
9 [报告]
发表于 2003-05-30 17:12 |只看该作者

如何在FreeBSD下实现获取MAC地址?谢谢

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

论坛徽章:
0
10 [报告]
发表于 2003-05-30 17:15 |只看该作者

如何在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));
}
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP