吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2398|回复: 10
收起左侧

[C&C++ 转载] arp获取ip、mac

[复制链接]
古月不傲 发表于 2020-10-29 00:55
[C++] 纯文本查看 复制代码
/*!
arp: (Address Resolution Protocal)地址解析协议
功能:通过ip地址获取mac地址
报文格式:
----------------------------------------------------------------------------------------
|  6       6      2      2      2          1         1       2   6    4      6      4  |
|目的mac  源mac  帧类型 硬件类型 协议类型  硬件地址长度 协议地址长度 op 源mac 源ip  目的mac 目的ip|
----------------------------------------------------------------------------------------             
目的mac:       FF:FF:FF:FF:FF:FF
源mac:        本机mac
帧类型:        0x0800(IP)--0x0806(ARP)--0x8035(RARP)
硬件类型:      以太网地址(1)
协议类型:      0x0800(IP)
硬件地址长度:   6
协议地址长度:   4  
op:           ARP请求(1)--ARP应答(2)--RARP请求(3)--RARP应答(4)
源mac:        本机mac
源ip:         本机ip
目的mac:       0
目的ip:       目的ip地址
*/
#include <iostream>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/ether.h>
#include <unistd.h>
#include <linux/if_ether.h>
#include <net/if.h>
#include <netpacket/packet.h>
#include <cstring>
#include <sys/ioctl.h>
#include <pthread.h>

/*!
* @brief:   通过arp获取指定网段ip、mac地址
* @param:   原始套接字
* @return:  NULL
*/
void *send_arp(void *arg)
{
    int sock_raw_fd = *(int *)arg;
    
    unsigned char send_data[1024] = 
    {
        // 以太网报文
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // 目的mac
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 源mac
        0x08, 0x06,                         // 帧类型
        // ARP报文
        0x00, 0x01,                         // 硬件类型
        0x08, 0x00,                         // 协议类型
        0x06, 0x04,                         // 硬件地址长度 协议地址长度
        0x00, 0x01,                         // op
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 源mac
        0x00, 0x00, 0x00, 0x00,             // 源ip
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 目的mac
        0x00, 0x00, 0x00, 0x00              // 目的ip
    };
    struct sockaddr_ll sll;  // #include <netpacket/packet.h>
    struct ifreq ethreq;    // #include <net/if.h>
    strncpy(ethreq.ifr_ifrn.ifrn_name, "enp4s0", IF_NAMESIZE);

    ioctl(sock_raw_fd, SIOCGIFINDEX, (char *)ereq);
    bzero(&sll, sizeof(sll));
    sll.sll_ifindex = ethreq.ifr_ifru.ifru_ivalue;
    sendto(sock_raw_fd, send_data, 42, 0, (struct sockaddr *)&sll, sizeof(sll));
    // 获取本机ip
    ioctl(sock_raw_fd, SIOCGIFADDR, (char *)ereq);
    unsigned int num = ntohl(((struct sockaddr_in *)(ereq.ifr_ifru.ifru_addr))->sin_addr.s_addr);
    for (int i = 0; i < 4; i++)
        send_data[31 - i] = num >> (8 * i) & 0xff;      
    char ip[16]{};
    sprintf(ip, "%d:%d:%d:%d", 
    send_data[28], send_data[29], send_data[30], send_data[31]);
    printf("%s\n",  ip);
    // 获取本机mac
    ioctl(sock_raw_fd, SIOCGIFHWADDR, (char *)ereq);
    for (int i = 0; i < 6; i++)
        send_data[6 + i] = send_data[22 + i] = (unsigned char)ethreq.ifr_ifru.ifru_hwaddr.sa_data[i];
    char mac[18]{};
    sprintf(mac, "%02x:%02x:%02x:%02x:%02x:%02x", 
    send_data[22], send_data[23], send_data[24], send_data[25], send_data[26], send_data[27]);
    printf("%s\n",  mac);

    unsigned int network[10]{};
    unsigned char inbuf[32]{};
    printf("请输入输入一个指定网段:\n");
    fgets((char *)inbuf, sizeof(inbuf), stdin);
    sscanf((char *)inbuf, "%d.%d.%d.%d", &network[0], &network[1], &network[2], &network[3]);

    for (int i = 0; i < 4; i++)
        send_data[38 + i] = network[i];
    for (int i = 1; i <= 254; i++)
    {
        send_data[41] = i;
        sendto(sock_raw_fd, send_data, 42, 0, (struct sockaddr *)&sll, sizeof(sll));
    } 
    return NULL;
}

int main(void)
{
    int sock_raw_fd = -1;
    sock_raw_fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));

    pthread_t send_arp_thread;

    pthread_create(&send_arp_thread, NULL, send_arp, (void *)&sock_raw_fd);
    usleep(100000);  

    unsigned char recv_data[1024];
    for (int i = 1; i <= 254; i++)
    {
        bzero(recv_data, sizeof(recv_data));
        recvfrom(sock_raw_fd, recv_data, sizeof(recv_data), 0, NULL, NULL);
        if (recv_data[12] == 0x08 && 
            recv_data[13] == 0x06 && 
            recv_data[21] == 0x02)
        {
            char mac[18]{};
            char ip[16]{};
            sprintf(mac, "%02x:%02x:%02x:%02x:%02x:%02x", 
            recv_data[22], recv_data[23], recv_data[24], recv_data[25], recv_data[26], recv_data[27]);
            sprintf(ip, "%d:%d:%d:%d", 
            recv_data[28], recv_data[29], recv_data[30], recv_data[31]);
            printf("ip:%s--mac:%s\n", ip, mac);
        }
    }
    pthread_detach(send_arp_thread);
    return 0;
}

免费评分

参与人数 1热心值 +1 收起 理由
linuxcool + 1 好像不支持IPV6地址吧?

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

JuncoJet 发表于 2020-10-29 09:13
[C] 纯文本查看 复制代码
#include <winsock2.h>
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <iphlpapi.h>
#pragma comment(lib,"iphlpapi.lib")
#pragma comment(lib,"ws2_32.lib")

void GetMac(IPAddr  ipAddr){
	HRESULT hr;
	ULONG   pulMac[2];
	ULONG   ulLen;
	char strMacAddr[200];
	//memset(pulMac, 0xff, sizeof (pulMac));
	ulLen = 6;
	hr = SendARP (ipAddr, 0, pulMac, &ulLen);
	if(hr!=NO_ERROR)
	{
		//printf("Nothing Find!");
		return;
	}
	unsigned char * mac_addr=(unsigned char*)pulMac;
	typedef struct in_addr addr;
	//_addr* addr;
	sprintf(strMacAddr,"%s\t%.2x-%.2x-%.2x-%.2x-%.2x-%.2x\n",inet_ntoa(*(addr*)&ipAddr),
		mac_addr[0],mac_addr[1],mac_addr[2],mac_addr[3],mac_addr[4],mac_addr[5]);
	//sprintf(strMacAddr,"%.2x-%.2x-%.2x-%.2x-%.2x-%.2x\n",mac_addr[0],mac_addr[1],mac_addr[2],mac_addr[3],mac_addr[4],mac_addr[5]);
	printf(strMacAddr);
}
int main(int argc,char* argv[])
{
	IPAddr  ipAddr,ipAddr2=0;
	char ip[200];
	int x=0;
	printf("192.168.1.1-192.168.1.255\n"
			"192.168.1.1~255\n"
			"192.168.1.*  ArpScan -by JuncoJet\n\nIP: ");
	gets(ip);
	for(int i=strlen(ip);i>0;i--){
		switch(ip[i]){
			case '*':
				ip[i]='1';
				x=255;
				break;				
			case '~':
				ip[i]='\0';
				x=atoi(&ip[i+1]);
				break;
			case '-':
				ip[i]='\0';
				ipAddr2 = htonl(inet_addr (&ip[i+1]));
				break;
		}
		//if(ip[i]=='.')break;
	}
	ipAddr = htonl(inet_addr (ip));
	if(x)ipAddr2=ipAddr+x;
	if(!ipAddr2)ipAddr2=ipAddr+1;
	//printf("%x %x\n",ipAddr,ipAddr2);
	DWORD dwThreadId;
	for(int i=ipAddr;i<ipAddr2;i++){
		CreateThread(0,0,(LPTHREAD_START_ROUTINE)GetMac,(LPVOID)htonl(i),0,&dwThreadId);
	}
	getch();
	return 0;
}


Windows 版
cu2oh2co38 发表于 2020-10-29 06:48
jwpiaoi 发表于 2020-10-29 06:55
wangior 发表于 2020-10-29 07:32
要成品,不要代码
liking163 发表于 2020-10-29 08:00
怎么感觉那么多要成品的呢
huchhc 发表于 2020-10-29 08:01
不会怎么用的学习学习。
dojunhui 发表于 2020-10-29 08:01
这个很多软件都可以做到的吧
sssjcccz01a 发表于 2020-10-29 08:56
掌握电基础的编译技术就可以编译了
JuncoJet 发表于 2020-10-29 09:12
VC个毛线,VC能编译到 Linux ???
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-25 23:29

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表