1

I am trying to convert an IP address (currently IPv4, but recognizes IPv6) from an int array format to a formatted string. I am working on Ubuntu Linux.

I distinguish between IPv4 and IPv6 addresses, and then try to convert the int array to a string.

This is the code that I'm using:

#include <stdio.h>
#include <string.h>
#include <arpa/inet.h>

int main(void)
{
    int i;
    unsigned int val32;
    int ma_ip[4];
    char m_ip[4];
    char ipaddr[INET_ADDRSTRLEN], ipv6[INET6_ADDRSTRLEN];
    int no = 0;
    char *token;
    char s3[] = "10.1.35.1";
    /* just example. test only one ip address.. */
    for(i = 0; i < 1; i++)
    {
        char *mm = strstr(s3, ":");
        if( *mm != NULL)
        {
             token = strtok(s3, ":");
             while(token != NULL)
             {
                 token = strtok(NULL, ":");
                 no++;
             }
             if(no >= 2 && no <= 7)
                 printf("\nthis is ipv6\n");
             else
                 printf("\nwrong ipv6\n");
         }
         else
         {
             token = strtok(s3, ".");
             while(token != NULL)
             {
                 token = strtok(NULL, ".");
                 no++;
             }
             if(no == 4)
             {
                 printf("\nthis is ipv4.\n");
                 val32 = inet_addr(s3)
                 ma_ip[i] = val32;
             }
             else
                 printf("\nwrong ipv4.\n")
         }
         inet_ntop(AF_INET,&ma_ip[0],ipaddr,INET_ADDRSTRLEN);
         printf("\nipaddr = %s\n", ipaddr);
         strcpy(&m_ip[0], ipaddr);
         printf("\nafter strcpy = %s\n", m_ip[0]);
    }
}

This output is wrong:

ipaddr = 0.0.0.10

It should actually be:

ipaddr = 10.1.35.1

I also get this error in the last printf after the strcpy:

format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘int’ error !**

Why is this happening, and how can I fix it?

Michael Gaskill
  • 7,913
  • 10
  • 38
  • 43
kara
  • 43
  • 8

3 Answers3

0

m_ip[0] points to the location of the first element. If you wish to print the string, please try with either m_ip i.e. array name or &m_ip[0] which basically passes the address of the first element which could be interpreted as a pointer and essentially leads to segmentation fault. With m_ip it prints (but still only 0.0.0.10).

Another point in your program is that you should compare mm with NULL after strstr operation.

For the network address manipulation, I would recommend you to have a look at this question.

Community
  • 1
  • 1
Ganesh
  • 5,880
  • 2
  • 36
  • 54
0

I have certain doubts in you program. Are you converting an ip string

 char s3[] = "10.1.35.1";

to an integer and again back to string??

I think this is what you need

struct sockaddr_in sa;
char str[INET_ADDRSTRLEN];

// store this IP address in sa:
inet_pton(AF_INET, "192.0.2.33", &(sa.sin_addr));

// now get it back and print it
inet_ntop(AF_INET, &(sa.sin_addr), str, INET_ADDRSTRLEN);

printf("%s\n", str); // prints "192.0.2.33"

Regarding the last printf after strcpy, it should be

printf("\nafter strcpy = %s\n", m_ip);
Twinkle
  • 514
  • 3
  • 8
  • 1
    Instead of `inet_pton` and `inet_ntop`, it would better to use `getaddrinfo()` and `getnameinfo()`. – glglgl Jun 27 '16 at 09:22
-1

This is a workable version. The problem of your code is, strtok() is trimming the string 's3'.By the time n == 4, the string only get "10" left.

 #include <stdio.h>
 #include <string.h>
 #include <arpa/inet.h>
 #include <malloc.h>

int main(void)
{
    int i;
    unsigned int val32;
    int ma_ip[4];
    char m_ip[4];
    char ipaddr[INET_ADDRSTRLEN], ipv6[INET6_ADDRSTRLEN];
    int no = 0;
    char *token;
    char s3[] = "10.1.35.1";
    char *s4 = malloc(strlen(s3)+1);   
    strcpy(s4, s3);               //You can save the original string.
    /* just example. test only one ip address.. */
    for(i = 0; i < 1; i++)
    {
        char *mm = strstr(s3, ":");
        if( mm != NULL)
        {
             token = strtok(s3, ":");
             while(token != NULL)
             {
                 token = strtok(NULL, ":");
                 no++;
             }
             if(no >= 2 && no <= 7)
                 printf("\nthis is ipv6\n");
             else
                 printf("\nwrong ipv6\n");
         }
         else
         {
             token = strtok(s3, ".");
             while(token != NULL)
             {
                 token = strtok(NULL, ".");
                 no++;
             }
             if(no == 4)
             {
                 printf("\nthis is ipv4.\n");
                 val32 = inet_addr(s4);  //use the intact string s4, instead of s3.
                 ma_ip[i] = val32;
             }
             else
                 printf("\nwrong ipv4.\n");
         }
         inet_ntop(AF_INET,&ma_ip[0],ipaddr,INET_ADDRSTRLEN);
         printf("\nipaddr = %s\n", ipaddr);
         strcpy(&m_ip[0], ipaddr);
         printf("\nafter strcpy = %s\n", m_ip);
    }
}
Lin
  • 104
  • 5
  • `strcpy(&m_ip[0], ipaddr);` is terribly wrong. Do not use `strcpy`, use `strncpy`. `char[4]` is clearly not large enough for a formatted ip address string. – Zulan Jun 29 '16 at 07:58
  • Yes, you are right. I just noticed the strtok() problem of the code, and made quick change to it. Didn't notice the strcpy() problem. Thanks. – Lin Jun 29 '16 at 08:23