通过IP或socket获取对方的MAC地址

来源:互联网 发布:美工零基础带薪真的吗 编辑:程序博客网 时间:2024/05/01 15:46

http://blog.chinaunix.net/uid-17188120-id-2820866.html

1.通过已经连接的socket文件获取:

  1. int getpeermac( int sockfd, char *buf ) 
  2.     int ret =0;  
  3.     struct arpreq arpreq;  
  4.     struct sockaddr_in dstadd_in;  
  5.     socklen_t  len = sizeofstruct sockaddr_in );  
  6.     memset( &arpreq, 0, sizeofstruct arpreq ));  
  7.     memset( &dstadd_in, 0, sizeofstruct sockaddr_in ));  
  8.     if( getpeername( sockfd, (struct sockaddr*)&dstadd_in, &len ) < 0 )  
  9.         err_err("getpeername()");  
  10.     else  
  11.     {  
  12.         memcpy( &arpreq.arp_pa, &dstadd_in, sizeofstruct sockaddr_in ));  
  13.         strcpy(arpreq.arp_dev, "eth1");  
  14.         arpreq.arp_pa.sa_family = AF_INET;  
  15.         arpreq.arp_ha.sa_family = AF_UNSPEC;  
  16.         if( ioctl( sockfd, SIOCGARP, &arpreq ) < 0 )  
  17.             err_err("ioctl SIOCGARP");  
  18.         else  
  19.         {  
  20.             unsigned char* ptr = (unsigned char *)arpreq.arp_ha.sa_data;  
  21.             ret = sprintf(buf, "%02x%02x%02x%02x%02x%02x", *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4), *(ptr+5));  
  22.         }  
  23.     }  
  24.     return ret;  
  25. }   

2. 通过IP获取:

/**
* @send_arp.c
* @This software is intended to be used as a example to show how to send and receive arp request with Linux * PF_PACKET interface
* @Author:xuelei
**/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <net/if.h>
#include <sys/types.h>
#include <asm/types.h>
#include <features.h> /* 需要里面的 glibc 版本号 */
#if __GLIBC__ >= 2 && __GLIBC_MINOR >= 1
        #include <netpacket/packet.h>
        #include <net/ethernet.h> /* 链路层(L2)协议 */
#else
        #include <asm/types.h>
        #include <linux/if_packet.h>
        #include <linux/if_ether.h> /* 链路层协议 */
#endif
#include <netinet/if_ether.h>

#define INLEN 4
#define MAC_BCAST_ADDR  (uint8_t *) "\xff\xff\xff\xff\xff\xff"

void usage_quit(char *arg0);
int get_ifi(char *dev, char *mac, int macln, struct in_addr *lc_addr, int ipln);
void prmac(u_char *ptr);

int main(int argc, char **argv)
{
        if(argc != 2)
                usage_quit(argv[0]);

        int fd, salen, n;
        u_char *mac;
        char recv_buf[120], rep_addr[16];
        struct in_addr lc_addr, req_addr;
        struct sockaddr_ll reqsa, repsa;
        struct arp_pkt {
                struct ether_header eh;
                struct ether_arp ea;
                u_char padding[18];
        } req;

        bzero(&reqsa, sizeof(reqsa));
        reqsa.sll_family = PF_PACKET;
        reqsa.sll_ifindex = if_nametoindex("eth0");

        if((fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ARP))) < 0) {
                perror("Socket error");
                exit(1);
        }

        mac = (char *)malloc(ETH_ALEN);
        bzero(&req, sizeof(req));

        if(get_ifi("eth0", mac, ETH_ALEN, &lc_addr, INLEN)) {
                fprintf(stderr, "Error: Get host’s information failed\n");
                exit(0);
        }
        printf("        Host MAC is: %02x:%02x:%02x:%02x:%02x:%02x\n",*mac,*(mac+1),*(mac+2),*(mac+3),*(mac+4),*(mac+5));
         printf("       Host IP is: %s\n", inet_ntop(AF_INET, &lc_addr, rep_addr, 1024));
        /* 填写以太网头部*/
        memcpy(req.eh.ether_dhost, MAC_BCAST_ADDR, ETH_ALEN);
        memcpy(req.eh.ether_shost, mac, ETH_ALEN);
        req.eh.ether_type = htons(ETHERTYPE_ARP);

        /* 填写arp数据 */
        req.ea.arp_hrd = htons(ARPHRD_ETHER);
        req.ea.arp_pro = htons(ETHERTYPE_IP);
        req.ea.arp_hln = ETH_ALEN;
        req.ea.arp_pln = INLEN;
        req.ea.arp_op = htons(ARPOP_REQUEST);
        memcpy(req.ea.arp_sha, mac, ETH_ALEN);
        memcpy(req.ea.arp_spa, &lc_addr, INLEN);
        inet_aton(argv[1], req.ea.arp_tpa);

        bzero(recv_buf, sizeof(recv_buf));
        bzero(&repsa, sizeof(repsa));
        salen = sizeof(struct sockaddr_ll);

        if((n = sendto(fd, &req, sizeof(req), 0, (struct sockaddr *)&reqsa, sizeof(reqsa))) <= 0) {
                perror("Sendto error");
                exit(1);
        }
        printf("Broadcast arp request of %s, %d bytes be sent\n\n", argv[1], n);



        while(1) {
                if((n = recvfrom(fd, recv_buf, sizeof(req), 0, (struct sockaddr *)&repsa, &salen)) <= 0) {
                        perror("Recvfrom error");
                        exit(1);
                }
                if(ntohs(*(__be16 *)(recv_buf + 20))==2 && !memcmp(req.ea.arp_tpa, recv_buf + 28, 4)) {
                        printf("Response from %s, %d bytes received\n", argv[1], n);
                        printf("        Peer IP is: %s\n", inet_ntop(AF_INET, (struct in_addr *)(recv_buf + 28), rep_addr, 1024));
                        prmac( (u_char *)(recv_buf + 22) ); //prmac( (u_char *)(recv_buf + 6) );
                        break;
                }
                else
                    {
                    printf("Have recive data\n");
                    break;
                    }
        }

        free(mac);
}

int get_ifi(char *dev, char * mac, int macln, struct in_addr *lc_addr, int ipln)
{
        int reqfd, n;
        struct ifreq macreq;

        reqfd = socket(AF_INET, SOCK_DGRAM, 0);
        strcpy(macreq.ifr_name, dev);

        /* 获取本地接口MAC地址*/
        if(ioctl(reqfd, SIOCGIFHWADDR, &macreq) != 0)
                return 1;
        memcpy(mac, macreq.ifr_hwaddr.sa_data, macln);

        /* 获取本地接口IP地址*/
        if(ioctl(reqfd, SIOCGIFADDR, &macreq) != 0)
                return 1;
        memcpy(lc_addr, &((struct sockaddr_in *)(&macreq.ifr_addr))->sin_addr, ipln);

        return 0;
}

void prmac(u_char *ptr)
{
        printf("        Peer MAC is: %02x:%02x:%02x:%02x:%02x:%02x\n",*ptr,*(ptr+1),*(ptr+2),*(ptr+3),*(ptr+4),*(ptr+5));
}

void usage_quit(char *arg0)
{
        fprintf(stderr, "Usage: %s <query_IP>\n", arg0);
        exit(1);
}
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 平板电脑充电口坏了怎么办 平板电脑系统坏了怎么办 平板电脑充电器坏了怎么办 平板电脑触摸屏坏了怎么办 平板电脑关不了机怎么办 平板电脑触摸屏没反应怎么办 平板电脑声音太小怎么办 平板电脑频碎了怎么办? 淘宝直播展示频道排后怎么办 网店头像改不了怎么办 被骗了7500追不回来怎么办 steam中国版原来的游戏怎么办 老公买驾照被骗妻子应该怎么办 被淘密码骗了怎么办 逛街手机没电了怎么办 电脑登入密码忘了怎么办 晚上睡不好觉经常做梦怎么办 开淘宝店开始零销量怎么办 淘宝店开直通车后销量怎么办 淘宝直播一开始直播没人该怎么办 淘宝店铺访客数据下滑怎么办 2个ctrl键都失灵怎么办 淘宝上搜索不到很久以前订单怎么办 关键词找不到了是不是被降权怎么办 购买小程序关键词想退款怎么办? 浏览器审查元素不拆分关键词怎么办 拼多多商品想重新编辑怎么办 新开店铺没有销量怎么办 新开的店铺没有销量怎么办 淘宝的商品权重下降是怎么办 360n5手机耗电快怎么办 怪兽充电宝丢了怎么办 有已处置的评价怎么办 淘宝降权了怎么办2018 使用虚假广告词被工商查到怎么办 为什么手机淘宝店关注不了怎么办 淘宝买东西付钱后卖家不发货怎么办 微信销售群没人买东西怎么办 淘宝想开2个店铺怎么办 拼多多没钱交保证金怎么办 差评一个月后怎么办