Fookie Rookie
Fookie Rookie

Reputation: 31

GetAdaptersAddresses() not giving correct IP address

I am using a USB Internet dongle that assigns an IPv6 address to my computer. When I use ipconfig, I can see the IPv6 address assigned, it's a public IP.

When I use GetAdaptersAddresses(), I get a long linked list of anycast, multicast, and unicast addresses, but none of them match the system's IP address.

Is there some other place where I would get system's IP? I actually want to get the IP address of the system so that I can bind it to a socket.

I use Windows 7.

// getadaptersinfo.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include<WinSock2.h>
#include<iphlpapi.h>
#include<ws2tcpip.h>
#include<iostream>
#pragma comment(lib,"IPHLPAPI.lib")
#pragma comment(lib,"Ws2_32.lib")
using namespace std;

int main()
{
    cout << "\nusing getadapteraddress";
    PIP_ADAPTER_ADDRESSES p, tp;
    ULONG u;
    DWORD ret;
    p = (IP_ADAPTER_ADDRESSES*)HeapAlloc(GetProcessHeap(), 0, sizeof(IP_ADAPTER_ADDRESSES));
    u = sizeof(p);
    GetAdaptersAddresses(0, GAA_FLAG_INCLUDE_PREFIX, NULL, p, &u);
    p = (IP_ADAPTER_ADDRESSES*)HeapAlloc(GetProcessHeap(), 0, u);
    ret = GetAdaptersAddresses(0, GAA_FLAG_INCLUDE_PREFIX, NULL, p, &u);
    if (ret == NO_ERROR)
    {
        tp = p;
        while (tp)
        {
            cout << "\nlength of ip adapter address";
            tp->Length;
            cout << "\nifindex (ipv4):" << tp->IfIndex;
            cout << "\n Adapter name::" << tp->AdapterName;
            PIP_ADAPTER_UNICAST_ADDRESS pu;
            pu = tp->FirstUnicastAddress;
            int i = 0;
            cout << "\nunicast address:";
            while (pu)
            {
                i++;
                cout << "\nlength of sockaddr: " << (pu->Address).iSockaddrLength;
                if (pu->Address.lpSockaddr->sa_family == AF_INET)
                {
                    cout << "\n ipv4 addr:";
                    sockaddr_in *si = (sockaddr_in *)&(pu->Address.lpSockaddr);
                    char a[INET_ADDRSTRLEN];
                    inet_ntop(AF_INET, si, a, sizeof(a));
                    cout << a;
                }
                else if (pu->Address.lpSockaddr->sa_family == AF_INET6)
                {
                    cout << "\n ipv6 addr:";
                    sockaddr_in6 *si = (sockaddr_in6 *)&(pu->Address.lpSockaddr);
                    char a[INET6_ADDRSTRLEN];
                    inet_ntop(AF_INET6, si, a, sizeof(a));
                    cout << a;
                }
                pu = pu->Next;
            }
            cout << "\n no of unicast address" << i;
            PIP_ADAPTER_ANYCAST_ADDRESS pa;
            i = 0;
            pa = tp->FirstAnycastAddress;
            cout << "\nanycast address:"; 
            while (pa)
            {
                i++;
                cout << "\nlength of sockaddr: " << (pa->Address).iSockaddrLength;
                if (pa->Address.lpSockaddr->sa_family == AF_INET)
                {
                    cout << "\n ipv4 addr:";
                    sockaddr_in *si = (sockaddr_in *)&(pa->Address.lpSockaddr);
                    char a[INET_ADDRSTRLEN];
                    inet_ntop(AF_INET, si, a, sizeof(a));
                    cout << a;
                }
                else if (pa->Address.lpSockaddr->sa_family == AF_INET6)
                {
                    cout << "\n ipv6 addr:";
                    sockaddr_in6 *si = (sockaddr_in6 *)&(pa->Address.lpSockaddr);
                    char a[INET6_ADDRSTRLEN];
                    inet_ntop(AF_INET6, si, a, sizeof(a));
                    cout << a;
                }
                pa = pa->Next;
            }
            cout << "\n no of anycast address" << i;
            PIP_ADAPTER_MULTICAST_ADDRESS pm;
            i = 0;
            pm = tp->FirstMulticastAddress;
            cout << "\nmulticast address:";
            while (pm)
            {
                i++;
                cout << "\nlength of sockaddr: " << (pm->Address).iSockaddrLength;
                if (pm->Address.lpSockaddr->sa_family == AF_INET)
                {
                    cout << "\n ipv4 addr:";
                    sockaddr_in *si = (sockaddr_in *)&(pm->Address.lpSockaddr);
                    char a[INET_ADDRSTRLEN];
                    inet_ntop(AF_INET, si, a, sizeof(a));
                    cout << a;
                }
                else if (pm->Address.lpSockaddr->sa_family == AF_INET6)
                {
                    cout << "\n ipv6 addr:";
                    sockaddr_in6 *si = (sockaddr_in6 *)&(pm->Address.lpSockaddr);
                    char a[INET6_ADDRSTRLEN];
                    inet_ntop(AF_INET6, si, a, sizeof(a));
                    cout << a;
                }
                pm = pm->Next;
            }
            cout << "\n no of multicast address" << i;
            PIP_ADAPTER_DNS_SERVER_ADDRESS pd;
            i = 0;
            pd = tp->FirstDnsServerAddress;
            cout << "\ndns address:";
            while (pd)
            {
                i++;
                cout << "\nlength of sockaddr: " << (pd->Address).iSockaddrLength;
                if (pd->Address.lpSockaddr->sa_family == AF_INET)
                {
                    cout << "\n ipv4 addr:";
                    sockaddr_in *si = (sockaddr_in *)&(pd->Address.lpSockaddr);
                    char a[INET_ADDRSTRLEN];
                    inet_ntop(AF_INET, si, a, sizeof(a));
                    cout << a;
                }
                else if (pd->Address.lpSockaddr->sa_family == AF_INET6)
                {
                    cout << "\n ipv6 addr:";
                    sockaddr_in6 *si = (sockaddr_in6 *)&(pd->Address.lpSockaddr);
                    char a[INET6_ADDRSTRLEN];
                    inet_ntop(AF_INET6, si, a, sizeof(a));
                    cout << a;
                }
                pd = pd->Next;
            }
            cout << "\n no of dns server address" << i;
            PIP_ADAPTER_GATEWAY_ADDRESS_LH pg;
            i = 0;
            pg = tp->FirstGatewayAddress;
            cout << "\ngateway address:"; 
            while (pg)
            {
                i++;
                cout << "\nlength of sockaddr: " << (pg->Address).iSockaddrLength;
                if (pg->Address.lpSockaddr->sa_family == AF_INET)
                {
                    cout << "\n ipv4 addr:";
                    sockaddr_in *si = (sockaddr_in *)&(pg->Address.lpSockaddr);
                    char a[INET_ADDRSTRLEN];
                    inet_ntop(AF_INET, si, a, sizeof(a));
                    cout << a;
                }
                else if (pg->Address.lpSockaddr->sa_family == AF_INET6)
                {
                    cout << "\n ipv6 addr:";
                    sockaddr_in6 *si = (sockaddr_in6 *)&(pg->Address.lpSockaddr);
                    char a[INET6_ADDRSTRLEN];
                    inet_ntop(AF_INET6, si, a, sizeof(a));
                    cout << a;
                }
                pg = pg->Next;
            }
            cout << "\ngateway address:" << i;
            cout << "\n dns suffix" << tp->DnsSuffix;
            cout << "\n description" << tp->Description;
            cout << "\n friendly name" << tp->FriendlyName;
            if (tp->PhysicalAddressLength != 0)
                for (UINT i = 0; i < tp->PhysicalAddressLength; i++)
                {
                    if (i == (tp->PhysicalAddressLength - 1))
                        cout << std::hex << (int)tp->PhysicalAddress[i];
                    else
                        cout << "-" << std::hex << (int)tp->PhysicalAddress[i];
                }
            cout << "\n Flags" << tp->Flags;
            cout << "\nmtu" << tp->Mtu;
            cout << "\n IfType" << tp->IfType;
            cout << "\n OperStatus" << tp->OperStatus;
            cout << "\n ipv6 ifindex :" << tp->Ipv6IfIndex;
            cout << "\nand more";
            tp = tp->Next;
        }

    }
    else {
        cout << "something went wrong";
    }
    HeapFree(GetProcessHeap(), 0, p);
    p = NULL;
    cin >> ret;
    return 0;
}

image

As you can see, none of the addresses match the address in the command prompt.

Upvotes: 1

Views: 6851

Answers (2)

sdm
sdm

Reputation: 1

This code:

sockaddr_in *si = (sockaddr_in *)&(pu->Address.lpSockaddr);
sockaddr_in6 *si = (sockaddr_in6 *)&(pu->Address.lpSockaddr);

Needs to be like this instead:

sockaddr_in *si = ((sockaddr_in *)pu->Address.lpSockaddr);
sockaddr_in6 *si = ((sockaddr_in6 *)pu->Address.lpSockaddr);

Upvotes: -2

Remy Lebeau
Remy Lebeau

Reputation: 595981

I see a number of problems with your code:

  • you are not performing adequate error handling when calling GetAdaptersAddresses().

  • you are leaking the first IP_ADAPTER_ADDRESSES struct that you allocate.

  • you are not outputting tp->Length to the console at the top of your while (tp) loop.

  • you are not retrieving and formatting the IP addresses correctly!

That last point is the root of your problem.

When you attempt to retrieve an IP address from the list, you are accessing the sockaddr_X struct incorrectly.

This code:

sockaddr_in *si = (sockaddr_in *)&(pu->Address.lpSockaddr);

sockaddr_in6 *si = (sockaddr_in6 *)&(pu->Address.lpSockaddr);

Needs to be like this instead:

sockaddr_in *si = (sockaddr_in *)(pu->Address.lpSockaddr);

sockaddr_in6 *si = (sockaddr_in6 *)(pu->Address.lpSockaddr);

The lpSockaddr field is already a pointer to a sockaddr_X struct, so you need to type-cast that pointer value, DO NOT use the & operator to take the address of that pointer itself, you would be type-casting the wrong memory address and so the binary data you attempt to format for the IP address is garbage!

You are also calling inet_ntop() incorrectly. It expects a pointer to a in_addr/in6_addr struct as input, but you are passing it a pointer to a sockaddr_in/sockaddr_in6 struct instead. So the formatted output strings are garbage as well!

This code:

inet_ntop(AF_INET, si, a, sizeof(a));

inet_ntop(AF_INET6, si, a, sizeof(a));

Needs to be like this instead:

inet_ntop(AF_INET, &(si->sin_addr), a, sizeof(a));

inet_ntop(AF_INET6, &(si->sin6_addr), a, sizeof(a));

You are making these 2 mistakes for all of the anycast, unicast, multicast, DNS server, and gateway IP addresses in the linked lists.

With that said, try something more like this:

// getadaptersinfo.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <WinSock2.h>
#include <iphlpapi.h>
#include <ws2tcpip.h>
#include <iostream>

#pragma comment(lib,"IPHLPAPI.lib")
#pragma comment(lib,"Ws2_32.lib")

using namespace std;

void displayAddress(const SOCKET_ADDRESS &Address)
{
    cout << "\n  Length of sockaddr: " << Address.iSockaddrLength;
    if (Address.lpSockaddr->sa_family == AF_INET)
    {
        sockaddr_in *si = (sockaddr_in *)(Address.lpSockaddr);
        char a[INET_ADDRSTRLEN] = {};
        if (inet_ntop(AF_INET, &(si->sin_addr), a, sizeof(a)))
            cout << "\n   IPv4 address: " << a;
    }
    else if (Address.lpSockaddr->sa_family == AF_INET6)
    {
        sockaddr_in6 *si = (sockaddr_in6 *)(Address.lpSockaddr);
        char a[INET6_ADDRSTRLEN] = {};
        if (inet_ntop(AF_INET6, &(si->sin6_addr), a, sizeof(a)))
            cout << "\n   IPv6 address: " << a;
    }
}

int main()
{
    cout << "\nUsing GetAdaptersAddresses";

    ULONG size = 1024 * 15;    
    PIP_ADAPTER_ADDRESSES p = (IP_ADAPTER_ADDRESSES*) HeapAlloc(GetProcessHeap(), 0, size);
    if (!p)
    {
        cout << "\nCannot allocate memory";
        cin.get();
        return -1;
    }

    ULONG ret;
    do
    {
        ret = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, p, &size);
        if (ret != ERROR_BUFFER_OVERFLOW)
            break;

        PIP_ADAPTER_ADDRESSES newp = (IP_ADAPTER_ADDRESSES*) HeapReAlloc(GetProcessHeap(), 0, p, size);
        if (!newp)
        {
            cout << "\nCannot reallocate memory";
            HeapFree(GetProcessHeap(), 0, p);
            cin.get();
            return -1;
        }

        p = newp;
    }
    while (true);

    if (ret != NO_ERROR)
    {
        cout << "\nSomething went wrong. Error: " << ret;
        HeapFree(GetProcessHeap(), 0, p);
        cin.get();
        return -1;
    }

    int i = 0;
    for(PIP_ADAPTER_ADDRESSES tp = p; tp != NULL; tp = tp->Next)
    {
        ++i;
        cout << "\nLength of IP Adapter info: " << tp->Length;
        cout << "\n IPv4 IfIndex: " << tp->IfIndex;
        cout << "\n Adapter name: " << tp->AdapterName;
        cout << "\n Unicast addresses:";
        int j = 0;
        for (PIP_ADAPTER_UNICAST_ADDRESS pu = tp->FirstUnicastAddress; pu != NULL; pu = pu->Next)
        {
            ++j;
            displayAddress(pu->Address);
        }
        cout << "\n # of Unicast addresses: " << j;
        cout << "\n Anycast addresses:"; 
        j = 0;
        for (PIP_ADAPTER_ANYCAST_ADDRESS pa = tp->FirstAnycastAddress; pa != NULL; pa = pa->Next)
        {
            ++j;
            displayAddress(pa->Address);
        }
        cout << "\n # of Anycast addresses: " << j;
        cout << "\n Multicast addresses:";
        j = 0;
        for (PIP_ADAPTER_MULTICAST_ADDRESS pm = tp->FirstMulticastAddress; pm != NULL; pm = pm->Next)
        {
            ++j;
            displayAddress(pm->Address);
        }
        cout << "\n # of Multicast addresses: " << j;
        cout << "\n DNS server addresses:";
        j = 0;
        for (PIP_ADAPTER_DNS_SERVER_ADDRESS pd tp->FirstDnsServerAddress; pd != NULL; pd = pd->Next)
        {
            ++j;
            displayAddress(pd->Address);
        }
        cout << "\n # of DNS server addresses: " << j;
        cout << "\n Gateway addresses:"; 
        j = 0;
        for (PIP_ADAPTER_GATEWAY_ADDRESS_LH pg = tp->FirstGatewayAddress; pg != NULL; pg = pg->Next)
        {
            ++j;
            displayAddress(pg->Address);
        }
        cout << "\n # of Gateway addresses: " << j;
        cout << "\n DNS suffix" << tp->DnsSuffix;
        cout << "\n Description" << tp->Description;
        cout << "\n Friendly name" << tp->FriendlyName;
        if (tp->PhysicalAddressLength != 0)
        {
            cout << "\n Physical address: ";
            cout << std::hex << (int)tp->PhysicalAddress[0];
            for (UINT i = 1; i < tp->PhysicalAddressLength; i++)
                cout << "-" << std::hex << (int)tp->PhysicalAddress[i];
        }
        cout << "\n Flags" << tp->Flags;
        cout << "\n MTU" << tp->Mtu;
        cout << "\n IfType" << tp->IfType;
        cout << "\n OperStatus" << tp->OperStatus;
        cout << "\n IPv6 IfIndex :" << tp->Ipv6IfIndex;
        cout << "\n and more...";
    }
    cout << "\n# of IP Adapters: " << i;

    HeapFree(GetProcessHeap(), 0, p);

    cin.get();
    return 0;
}

Upvotes: 5

Related Questions