这段代码为打印出本地网卡的mac地址,但是,没成功,为什

#include<stdlib.h>
#include<stdio.h>
#include<pcap.h>

struct ethernet_head
{
 unsigned char dest_mac[6]; //目标主机MAC 地址
 unsigned char source_mac[6]; //源端MAC 地址
 unsigned short eh_type; //以太网类型
};
struct arp_head
{
 unsigned short hardware_type; //硬件类型:以太网接口类型为1
 unsigned short protocol_type; //协议类型:IP 协议类型为0X0800
 unsigned char add_len; //硬件地址长度:MAC 地址长度为6B
 unsigned char pro_len; //协议地址长度:IP 地址长度为4B
 unsigned short option; //操作:ARP 请求为1,ARP 应答为2
 unsigned char sour_addr[6]; //源MAC 地址:发送方的MAC 地址
 unsigned long sour_ip; //源IP 地址:发送方的IP 地址
 unsigned char dest_addr[6]; //目的MAC 地址:ARP 请求中该字段没有意义;ARP响应中为接收方的MAC 地址
 unsigned long dest_ip; //目的IP 地址:ARP 请求中为请求解析的IP 地址;ARP响应中为接收方的IP 地址
 unsigned char padding[18];
};
struct arp_packet //最终arp 包结构
{
 ethernet_head eth; //以太网头部
 arp_head arp; //arp 数据包头部
};
int main()
{

 unsigned char* GetSelfMac(char* pDevName, unsigned long chLocalIP);
 int i=0;
 pcap_if_t *alldevs;  //指向设备链表首部的指针
 pcap_if_t *d;
 pcap_addr_t *a;
 unsigned char* mac;
 unsigned long chLocalIp;
 char errbuf[PCAP_ERRBUF_SIZE]; //错误信息缓冲区
 //获得本机的设备列表
 if(pcap_findalldevs_ex(PCAP_SRC_IF_STRING,NULL,&alldevs,errbuf) == -1)
 {
  printf("PCAP出错/n");
 }
 //显示接口列表
 for(d= alldevs; d != NULL; d= d->next)
 {
  printf("%d. %s", ++i, d->name);
        if (d->description)
            printf(" (%s)/n", d->description);
        else
            printf(" (No description available)/n");
  for(a=d->addresses; a!=NULL; a=a->next)
  {  
  if (a->addr->sa_family==AF_INET) //判断该地址是否IP地址
  {
   chLocalIp=((struct sockaddr_in *)a->addr)->sin_addr.s_addr;
   printf("%ld/n",chLocalIp); //利用a->addr获取IP地址
  }
  }
  mac=GetSelfMac(d->name,chLocalIp);
  printf("%s",mac);
 }
 return 0;
 

unsigned char* GetSelfMac(char* pDevName, unsigned long chLocalIP)//设备名和本机IP作为参数
{
 unsigned char* BuildArpRequestPacket(unsigned char* source_mac_add, unsigned long source_ip_add, unsigned long dest_ip_add);
 //获得自己的MAC
 pcap_t* pAdaptHandle;//打开网卡适配器时用
 char errbuf[PCAP_ERRBUF_SIZE + 1];
 if((pAdaptHandle = pcap_open_live(pDevName, 60, 1, 100, errbuf)) == NULL)//arp请求包60字节
 { 
  //MessageBox(NULL, "无法打开适配器,可能与之不兼容!", "Note", MB_OK);
  return NULL;
 }
 struct pcap_pkthdr *header;
 const u_char *pkt_data;
 int res;
 int GetMacSignal=1;
 unsigned short arp_op;   //
 static unsigned char arp_sha[6];
 unsigned long arp_spa = 0;
 unsigned long arp_tpa = 0;
 unsigned char source_mac[6] = {0,0,0,0,0,0};
 unsigned char* arp_packet_for_self;
 arp_packet_for_self = BuildArpRequestPacket(source_mac,chLocalIP,chLocalIP);
 while(GetMacSignal)
 {
  pcap_sendpacket(pAdaptHandle, arp_packet_for_self, 60);
  Sleep(10);          
  res = pcap_next_ex(pAdaptHandle, &header, &pkt_data);
  if(res == 0)
  {
   continue;
  }
  memcpy(&arp_op, pkt_data + 20, 2);  //arp类型
  memcpy(arp_sha, pkt_data + 22, 6);  //源mac
  memcpy(&arp_spa, pkt_data + 28, 4); //源IP
  memcpy(&arp_tpa, pkt_data + 38, 4); //目的IP
  if(arp_op == 2 && arp_spa == chLocalIP && arp_tpa == chLocalIP)
  {   GetMacSignal = 0;   

pcap_close(pAdaptHandle);
   return arp_sha;//返回源mac,就是本地的mac
  }
  Sleep(100);                  //若不成功再等100ms再发,让网卡歇歇:) 20061025
 }
 pcap_close(pAdaptHandle);
 return arp_sha;
}


unsigned char* BuildArpRequestPacket(unsigned char* source_mac_add, unsigned long source_ip_add, unsigned long dest_ip_add)
{
 int i;
 //这是arp请求包,目的mac不用填,重点是arpPackStru.arp.option、源mac、源IP和目的IP,
 //这三项通过参数传递进来构造请求包
 arp_packet arpPackStru;
 for(i=0;i<6;i++) arpPackStru.eth.dest_mac[i]=0xff;
 //for(i=0;i<6;i++) arpPackStru.eth.source_mac[i]=    ;    //
 arpPackStru.eth.eh_type=htons(0x0806);
 arpPackStru.arp.hardware_type=htons(0x0001);
 arpPackStru.arp.protocol_type=htons(0x0800);
 arpPackStru.arp.add_len=0x06;
 arpPackStru.arp.pro_len=0x04;
 arpPackStru.arp.option=0x01;   //请求
 memcpy(arpPackStru.arp.sour_addr,source_mac_add,6);   //自己的mac
 arpPackStru.arp.sour_ip=source_ip_add;                //需要用到查询自己IP的结构
 arpPackStru.arp.dest_ip=dest_ip_add;             //目的IP
 for(i=0;i<18;i++) arpPackStru.arp.padding[i]=0x00;
 return (unsigned char *)&arpPackStru;
}
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值