Benny Isaacs
Benny Isaacs

Reputation: 105

Can't get the ip address with pcap_findalldevs

i am using pcap_findalldevs to get the device list in the computer. I get it successfully, with the name of the device, and description, but I don't know why, I get Netmask 0.0.0.0 and the ip address also 0.0.0.0. here is my code to generate the list:

/* get the devices list */
if (pcap_findalldevs(&devList, errbuf) == -1)
{
    fprintf(stderr, "There is a problem with pcap_findalldevs: %s\n", errbuf);
    return -1;
}

/* scan the list for a suitable device to capture from */
for (dev = devList; dev != NULL; dev = dev->next)
{

    pcap_addr_t *dev_addr; //interface address that used by pcap_findalldevs()

    /* check if the device captureble*/
    if ((dev_addr = dev->addresses) != NULL && dev_addr->addr->sa_family == AF_INET && dev_addr->addr && dev_addr->netmask) {
        printf("Found a device %s on address %s with netmask %s\n", dev->name, iptos(((struct sockaddr_in *)dev_addr->addr)->sin_addr.s_addr), iptos(((struct sockaddr_in *)dev_addr->netmask)->sin_addr.s_addr));
        break;
    }
}

Upvotes: 2

Views: 5503

Answers (5)

CanO
CanO

Reputation: 111

The post from Anrew Medico brought me to this solution:

At first I used const auto to initialize. This was a const char*. And I also got the subnetmask for ip-address. As the iptos() doesnt worked for me, I changed the deklaration to const string.

const string interface_ip = inet_ntoa(reinterpret_cast<struct sockaddr_in*>(address->addr)->sin_addr);
const string interface_netmask = inet_ntoa(reinterpret_cast<struct sockaddr_in*>(address->netmask)->sin_addr);

Hope this helps others, as it helped me.

Upvotes: 1

Midhun C E
Midhun C E

Reputation: 1

This worked for me.. Open Network connection settings.Right click on ur connection and select properties. Now Uncheck Internet protocol version 6(TCP/IPV6). Now run your application,You will get the proper IP address.

Upvotes: -1

user862787
user862787

Reputation:

Here's what you should be doing:

/* get the devices list */
if (pcap_findalldevs(&devList, errbuf) == -1)
{
    fprintf(stderr, "There is a problem with pcap_findalldevs: %s\n", errbuf);
    return -1;
}

/* scan the list for a suitable device to capture from */
for (dev = devList; dev != NULL; dev = dev->next)
{

    pcap_addr_t *dev_addr; //interface address that used by pcap_findalldevs()

    /* check if the device captureble*/
    for (dev_addr = dev->addresses; dev_addr != NULL; dev_addr = dev_addr->next) {
        if (dev_addr->addr->sa_family == AF_INET && dev_addr->addr && dev_addr->netmask) {
            printf("Found a device %s on address %s with netmask %s\n", dev->name, iptos(((struct sockaddr_in *)dev_addr->addr)->sin_addr.s_addr), iptos(((struct sockaddr_in *)dev_addr->netmask)->sin_addr.s_addr));
            goto found;
        }
    }
}

found:

That way, you check the entire address list, not just the first address in the list. If, when you reach found, dev is non-null, it points to a device with at least one IPv4 address, and dev_addr points to that address. If dev is null, there are no devices with IPv4 addresses.

Upvotes: 6

nobody
nobody

Reputation: 20174

The iptos example from WinPcap uses a single static buffer to produce its result. This means that when you call it twice, the result of the second call overwrites the result of the first call.

Thus your code:

printf("Found a device %s on address %s with netmask %s\n",
       dev->name, iptos(<addr-expr>), iptos(<mask-expr>));

will always print the same value (either address or netmask, depending on your compiler's order of argument evaluation) in both the address and netmask positions.

To correct this, you can duplicate the result strings and save them to separate variables, like so:

char* addr = strdup(iptos(<addr-expr>));
char* mask = stdrup(iptos(<mask-expr>));
printf("Found a device %s on address %s with netmask %s\n",
       dev->name, addr, mask>);
free(addr);
free(mask);

Upvotes: 0

Paolo Brandoli
Paolo Brandoli

Reputation: 4728

You are exiting the loop after the first interface you find, which probably is the loopback interface.

Here is the code I used in the past (I skip the loopback which has address 0.0.0.0):

    for(pcap_if_t* pInterface(m_pAllDevices); pInterface != 0; pInterface = pInterface->next)
    {
        if((pInterface->flags & PCAP_IF_LOOPBACK) != 0) // Skip loopback interfaces
        {
            continue;
        }
        std::string address;
        if(pInterface->addresses != 0)
        {
#if defined(WIN32)
            static char tempChar[1] = {0};
            DWORD stringSize(0);
            if(pInterface->addresses != 0 && WSAAddressToStringA(pInterface->addresses->addr, sizeof(*(pInterface->addresses->addr)), 0, tempChar, &stringSize) == SOCKET_ERROR && WSAGetLastError() == WSAEFAULT)
            {
                address.resize((size_t)stringSize);
                WSAAddressToStringA(pInterface->addresses->addr, sizeof(*(pInterface->addresses->addr)), 0, &(address[0]), &stringSize);
            }
#else
            char tempBuffer[INET_ADDRSTRLEN];
            inet_ntop(AF_INET, pInterface->addresses->addr, tempBuffer, sizeof(tempBuffer));
            address = tempBuffer;
#endif
        }

    }

Upvotes: 0

Related Questions