获取ip地址对应的mac地址,c/c++编程实现,linux下

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了获取ip地址对应的mac地址,c/c++编程实现,linux下相关的知识,希望对你有一定的参考价值。

在linux下,要求获取一个指定ip的mac地址,在同一局域网,要求用c/c++编程实现

/**

* @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);

参考技术A 在linux下用指令就可以获取啊,用脚本写很快的

华为交换机 端口 邦定 IP与MAC

**查找连接到端口设备的 MAC 地址,可以使用 ping + arp -a 命令:
可以ping 机器名或者IP地址
再使用 arp -a 显示 MAC表
查找到 IP地址对应的MAC地址

登录到交换机,使用dis mac-add 命令显示 MAC 对应的连接端口:
显示客户端连接的是 GE0/0/19

使用 user-bind 命令 邦定 ip 与 MAC :
进入 interface GigabitEthernet 0/0/19 界面,设置ip源检查:**
例:

C:UsersAdministrator>ping IT123

正在 Ping IT123 [192.168.1.123] 具有 32 字节的数据:
来自 192.168.1.123 的回复: 字节=32 时间<1ms TTL=64
来自 192.168.1.123 的回复: 字节=32 时间<1ms TTL=64
来自 192.168.1.123 的回复: 字节=32 时间<1ms TTL=64

192.168.1.123 的 Ping 统计信息:
    数据包: 已发送 = 3,已接收 = 3,丢失 = 0 (0% 丢失),
往返行程的估计时间(以毫秒为单位):
    最短 = 0ms,最长 = 0ms,平均 = 0ms
Control-C

**查找连接到端口设备的 MAC 地址,可以使用 ping + arp -a 命令:
可以ping 机器名或者IP地址
再使用 arp -a 显示 MAC表
查找到 IP地址对应的MAC地址

登录到交换机,使用dis mac-add 命令显示 MAC 对应的连接端口:
显示客户端连接的是 GE0/0/19

使用 user-bind 命令 邦定 ip 与 MAC :
进入 interface GigabitEthernet 0/0/19 界面,设置ip源检查:**


C:UsersAdministrator>arp -a

接口: 10.168.6.32 --- 0xd
  Internet 地址         物理地址              类型
  192.168.1.122         88-d7-f6-43-xx-xx     动态
  192.168.1.123         e0-d5-5e-61-xx-xx     动态

**查找连接到端口设备的 MAC 地址,可以使用 ping + arp -a 命令:
可以ping 机器名或者IP地址
再使用 arp -a 显示 MAC表
查找到 IP地址对应的MAC地址

登录到交换机,使用dis mac-add 命令显示 MAC 对应的连接端口:
显示客户端连接的是 GE0/0/19

使用 user-bind 命令 邦定 ip 与 MAC :
进入 interface GigabitEthernet 0/0/19 界面,设置ip源检查:**


dis mac-add e0d5-5e61-xxxx

-------------------------------------------------------------------------------
MAC Address    VLAN/VSI                          Learned-From        Type      
-------------------------------------------------------------------------------
e0d5-5e61-xxxx 206/-                             GE0/0/19            dynamic   

-------------------------------------------------------------------------------
Total items displayed = 1 

**查找连接到端口设备的 MAC 地址,可以使用 ping + arp -a 命令:
可以ping 机器名或者IP地址
再使用 arp -a 显示 MAC表
查找到 IP地址对应的MAC地址

登录到交换机,使用dis mac-add 命令显示 MAC 对应的连接端口:
显示客户端连接的是 GE0/0/19

使用 user-bind 命令 邦定 ip 与 MAC :
进入 interface GigabitEthernet 0/0/19 界面,设置ip源检查:**
user-bind static ip-address 192.168.1.123 mac-address e0d5-5e61-xxxx interface GigabitEthernet 0/0/19

**查找连接到端口设备的 MAC 地址,可以使用 ping + arp -a 命令:
可以ping 机器名或者IP地址
再使用 arp -a 显示 MAC表
查找到 IP地址对应的MAC地址

登录到交换机,使用dis mac-add 命令显示 MAC 对应的连接端口:
显示客户端连接的是 GE0/0/19

使用 user-bind 命令 邦定 ip 与 MAC :
进入 interface GigabitEthernet 0/0/19 界面,设置ip源检查:**

interface GigabitEthernet 0/0/19
port link-type access
ip source check user-bind enable

以上是关于获取ip地址对应的mac地址,c/c++编程实现,linux下的主要内容,如果未能解决你的问题,请参考以下文章

在C语言中,如何将字符串“192.168.1.1”转换成MAC地址或IP地址?

Linux通过c语言函数管理网络-----获取/修改IP和MAC地址

用c#处理下面字符串,将字符串中的ip地址对应mac录入到dataset中 字符串如下:

不同局域网内2个电脑MAC地址一样,会影响上网吗?

如何从 udp-socket (C/C++) 获取您自己的(本地)IP 地址

C#通过本地IP获取本地MAC地址(多个接口)