luac
luac

Reputation: 61

C++ Convert Uint32 IP address to text x.x.x.x

I want to convert an Uint32 IP Address to a concatenated string.

In the process of this i get uint8 data, but i need to change this to const char* to be able to concatenate it to other parts of the IP to be able to print the full IP in one variable.

How can I change the uint 8 to const char*? Or is there a better way for all the process of conversion?

uint32 ipAddress = GetHostIp();
if (ipAddress)
 {
    const int NBYTES = 4;
        uint8 octet[NBYTES];
        int x;
        char *ipAddressFinal;
        for (x = 0; x < NBYTES; x++)
        {
             octet[x] = (ipAddress >> (x * 8)) & (uint8)-1;
        }
        for (x = NBYTES - 1; x >= 0; --x)
        {
            if (NBYTES==4)
                        {
                            const char *IPPart = octet[x]; // HERE IS THE BUG!!!!! ?
                strcpy(ipAddressFinal, IPPart);
                        }
            else
                        {
                            const char *IPPart = octet[x];  // HERE IS THE BUG!!!!! ?
                strcat(ipAddressFinal, IPPart);
                        }
            if (x > 0)
                strcat(ipAddressFinal, ".");
        }
     LogAlways("IP:   %s", ipAddressFinal);
 }

Edit

Thanks guys - problem solved! Thanks to all! It's great to get very good answers in a short waiting time! Especially thanks to Lacrymology!!! Here is now working code, and I don't use Linux I should have wrote down my OS etc...

if (ipAddress)
{
    const int NBYTES = 4;
    uint8 octet[NBYTES];
    char ipAddressFinal[16];
    for(int i = 0 ; i < NBYTES ; i++)
    {
        octet[i] = ipAddress >> (i * 8);
    }
    sprintf(ipAddressFinal, "%d.%d.%d.%d", octet[3], octet[2], octet[1], octet[0]);
    LogAlways("IP:   \"%s\"", ipAddressFinal);
}

Upvotes: 6

Views: 21772

Answers (6)

Mark Lakata
Mark Lakata

Reputation: 20818

Here's an actual C++ solution

  #include <arpa/inet.h>

  std::string GetIPString(uint32_t x) const
  {
      char buffer[INET_ADDRSTRLEN + 1];
      auto result = inet_ntop(AF_INET, &x, buffer, sizeof(buffer));
      if (result == nullptr) throw std::runtime_error("Can't convert IP4 address");
      return buffer;
  }

Upvotes: 5

Oleg Vazhnev
Oleg Vazhnev

Reputation: 24057

why not just inet_ntoa(*(struct in_addr *)&uint32var)? as suggested here https://stackoverflow.com/a/9961072/93647

Upvotes: 1

user257111
user257111

Reputation:

At a guess you're using Linux - gethostip() seems to show up in Linux man pages. Anyway, if that is the case, what about using inet_ntoa()?

sprintf(ip_src, "%s", inet_ntoa(ipdata->ip_src));

Assuming char* ip_src has sufficient space to hold an ip address, of course. Designed to convert struct in_addr to char*.

Include with: #include <arpa/inet.h>

Upvotes: 9

Lacrymology
Lacrymology

Reputation: 2259

First of all, the line that you marked with "HERE IS THE BUG" should be something like sprintf("%d", octet[x]); but I'll give you what I consider a better solution (in no way the best)

uint32 ipAddress = GetHostIp();
if (ipAddress)
{
    const int NBYTES = 4;
    uint8 octet[NBYTES];
    int x;
    char *ipAddressFinal[16];
    for(int i = 0 ; i < NBYTES ; i++)
    {
        octet[i] = ipAddress >> (i * 8);
    }
    sprintf("%d.%d.%d.%d", octet[0], octet[1], octet[2], octet[3]);
}

now, this is "wrong" because I assume that there are 4 bytes in an IP address, but it does the job. Also assuming that, you could change that for-loop for

if (ipAddress)
{
   union {
       uint32 raw;
       uint8 octet[4];
   } ip;
   ip.raw = ipAddress;
   sprintf("%d.%d.%d.%d", ipAddressFinal, ip.octet[0], ip.octet[1],
                                          ip.octet[2], ip.octet[3]);
}

If you don't want to assume that 4 there you would have to stick to the first way and doing something like

sprintf("%s.%d", ipAddressFinal, , ipAddressFinal, ip.octet[i]);

which I don't know if works because it has the same string inputing and outputting

Upvotes: 2

luac
luac

Reputation: 1

Thanks guys - problem solved! Thanks to all! It's great to get very good answers in a short waiting time! Especially thanks to Lacrymology!!! Here is now working code, and I don't use Linux I should have wrote down my OS etc...

if (ipAddress) { const int NBYTES = 4; uint8 octet[NBYTES]; char ipAddressFinal[15]; for(int i = 0 ; i < NBYTES ; i++) { octet[i] = ipAddress >> (i * 8); } sprintf(ipAddressFinal, "%d.%d.%d.%d", octet[3], octet[2], octet[1], octet[0]); LogAlways("IP: \"%s\"", ipAddressFinal); }

Upvotes: -1

nos
nos

Reputation: 229058

How about just

uint32 ipAddress = GetHostIp();
if (ipAddress) {
    char ipAddr[16];
    snprintf(ipAddr,sizeof ipAddr,"%u.%u.%u.%u" ,(ipAddress & 0xff000000) >> 24 
                                                ,(ipAddress & 0x00ff0000) >> 16
                                                ,(ipAddress & 0x0000ff00) >> 8
                                                ,(ipAddress & 0x000000ff));
    // depending on the byte order your GetHostIp() returns the IP address in
    // you might need to reverse the above (i.e. print (ipAddress &0x000000ff)) first.
    LogAlways("IP:   %s", ipAddr);
}

You might use inet_ntoa or getnameinfo to convert an IP address to a string too though.

Upvotes: 6

Related Questions