古月不傲 发表于 2020-10-29 00:55

arp获取ip、mac

/*!
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 =
    {
      // 以太网报文
      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 = num >> (8 * i) & 0xff;      
    char ip{};
    sprintf(ip, "%d:%d:%d:%d",
    send_data, send_data, send_data, send_data);
    printf("%s\n",ip);
    // 获取本机mac
    ioctl(sock_raw_fd, SIOCGIFHWADDR, (char *)ereq);
    for (int i = 0; i < 6; i++)
      send_data = send_data = (unsigned char)ethreq.ifr_ifru.ifru_hwaddr.sa_data;
    char mac{};
    sprintf(mac, "%02x:%02x:%02x:%02x:%02x:%02x",
    send_data, send_data, send_data, send_data, send_data, send_data);
    printf("%s\n",mac);

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

    for (int i = 0; i < 4; i++)
      send_data = network;
    for (int i = 1; i <= 254; i++)
    {
      send_data = 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;
    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 == 0x08 &&
            recv_data == 0x06 &&
            recv_data == 0x02)
      {
            char mac{};
            char ip{};
            sprintf(mac, "%02x:%02x:%02x:%02x:%02x:%02x",
            recv_data, recv_data, recv_data, recv_data, recv_data, recv_data);
            sprintf(ip, "%d:%d:%d:%d",
            recv_data, recv_data, recv_data, recv_data);
            printf("ip:%s--mac:%s\n", ip, mac);
      }
    }
    pthread_detach(send_arp_thread);
    return 0;
}

JuncoJet 发表于 2020-10-29 09:13

#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(IPAddripAddr){
        HRESULT hr;
        ULONG   pulMac;
        ULONG   ulLen;
        char strMacAddr;
        //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,mac_addr,mac_addr,mac_addr,mac_addr,mac_addr);
        //sprintf(strMacAddr,"%.2x-%.2x-%.2x-%.2x-%.2x-%.2x\n",mac_addr,mac_addr,mac_addr,mac_addr,mac_addr,mac_addr);
        printf(strMacAddr);
}
int main(int argc,char* argv[])
{
        IPAddripAddr,ipAddr2=0;
        char ip;
        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){
                        case '*':
                                ip='1';
                                x=255;
                                break;                               
                        case '~':
                                ip='\0';
                                x=atoi(&ip);
                                break;
                        case '-':
                                ip='\0';
                                ipAddr2 = htonl(inet_addr (&ip));
                                break;
                }
                //if(ip=='.')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

要成品,不要代码{:1_896:}

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 ???
页: [1] 2
查看完整版本: arp获取ip、mac