Scannig the local network and get MAC, IP and Host

2019-06-14 19:25发布

问题:

I'm in trouble finding a suitable solution to my problem, and I hope you can help me with.
I wanna scan the local network in a Windows 7 environnement, and I must return:
- IP
- MAC address
- hostname

Of all PC in the local network. I was looking on the net, but i can't seem to found something who will do the three of that.
If someone knew a function or a group of function who can do the trick, it will be much appreciated.
I must do this in C++ or C#, but if possible, i'd rather prefer C++, since I'm better at it.
Thanks in advance for your support.

回答1:

I made a really basic prototype for you in c++ to get you onto the right path.

But keep in mind that its not safe at all and it can horribly fail at any second, you'll have to make some more checks to make sure the hostname doesn't overflow etc. And you'll also have to figure out how you want to fill the char address[][32] array because this is just handing in four example IPs.

main.h:

#pragma GCC system_header

#include <Winsock2.h>
#include <iphlpapi.h>
#include <cstdio>

//#pragma comment(lib, "iphlpapi.lib")
//#pragma comment(lib, "ws2_32.lib")

main.cpp:

#include "main.h"

bool get_name(unsigned char* name, char dest[32])
{
    struct in_addr destip;
    struct hostent* info;

    destip.s_addr = inet_addr(dest);

    info = gethostbyaddr((char*)&destip, 4, AF_INET);

    if (info != NULL)
    {
        strcpy((char*)name, info->h_name);
    }
    else
    {
        return false;
    }

    return true;
}

bool get_mac(unsigned char* mac , char dest[32])
{
    struct in_addr destip;
    ULONG mac_address[2];
    ULONG mac_address_len = 6;

    destip.s_addr = inet_addr(dest);

    SendARP((IPAddr)destip.S_un.S_addr, 0, mac_address, &mac_address_len);

    if (mac_address_len)
    {
        BYTE* mac_address_buffer = (BYTE*)&mac_address;
        for (int i = 0; i < (int)mac_address_len; i++)
        {
            mac[i] = (char)mac_address_buffer[i];
        }
    }
    else
    {
        return false;
    }

    return true;
}

int main()
{
    char address[][32] = {{"192.168.1.1"}, {"192.168.1.2"}, {"192.168.1.3"}, {"192.168.1.4"}};
    WSADATA sock;

    if (WSAStartup(MAKEWORD(2,2), &sock) != 0)
    {
        printf("Failed to initialise winsock. (%d)\n", WSAGetLastError());
        return 1;
    }

    for (int i = 0; i < (int)sizeof(address)/32; i++)
    {
        unsigned char mac[6] = {'\0'};
        unsigned char name[100] = {'\0'};

        if (get_mac(mac, address[i]))
        {
            printf("%s : %s : %.2X-%.2X-%.2X-%.2X-%.2X-%.2X\n", address[i], (get_name(name, address[i])) ? (char*)name : "-", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
            fflush(stdout);
        }
    }

    printf("\nDone.\n");
    fflush(stdout);

    return 0;
}

Output:

192.168.1.1 : pfsense.router : 00-40-F4-CC-A4-83
192.168.1.2 : - : 00-1D-7E-4B-69-BF

Done.

You'll want to link iphlpapi.lib and ws2_32.lib, I'm using GCC so pragma comment(lib, "") wont work, but if you're using msvc you can uncomment the lines in the header.