0

I have problem. I have code where I need to convert domain name to IP. For that purpose I am using function getaddrinfo(). But it seems, that when I call another function (AFTER GETADDRINFO()), that my program falls (getaddrinfo return error and Segmentation fault is generated). I discover, that problem is in calling function inet_ntop() after calling getaddrinfo(). But I don't know why this strange behaviour is happening... Here is my code:

#include<stdio.h>   //scanf , printf
#include<string.h>  //strtok
#include<stdlib.h>  //realloc
#include<sys/socket.h>  //socket
#include<netinet/in.h> //sockaddr_in
#include<arpa/inet.h>   //getsockname
#include<netdb.h>   //hostent
#include<unistd.h>  //close
#include <getopt.h> //getopt


#define DEFAULT_SOCKET_PROTOCOL 0
#define SERVER_PORT 43
#define IPv4_MAX_LENGTH 16
#define IPv6_MAX_LENGTH 40
#define DOMAIN_NAME_MAX_LENGTH 254
#define MAX_ADDRES_COUNT 3


typedef struct argument{
    char address[DOMAIN_NAME_MAX_LENGTH];
    char IPv4[IPv4_MAX_LENGTH];
    char IPv6[IPv6_MAX_LENGTH];
    int address_family;
    struct argument *next;
} Argument;

int addres_to_ip(char * hostname , char* ip);
int get_IP_addresses(Argument **args);


int main(int argc , char *argv[])
{
    Argument *args = NULL;  
    args = malloc(sizeof(Argument));    

    strcpy(args->address, "google.com");

    get_IP_addresses(&args);
    return 0;
}

int get_IP_addresses(Argument **args){

    char addrstr[DOMAIN_NAME_MAX_LENGTH];
    char tmp_ip[DOMAIN_NAME_MAX_LENGTH];
    strcpy(tmp_ip, (*args)->address);
    struct addrinfo tmp_ai, *new_ai;

    tmp_ai.ai_flags = AI_CANONNAME;
    tmp_ai.ai_family = AF_INET;
    tmp_ai.ai_socktype = SOCK_STREAM;

    printf("a\n");
    if(getaddrinfo (tmp_ip, NULL, &tmp_ai, &new_ai) != 0){
        printf("CHYBA: gettaddrinfo()\n");
    }

    while (new_ai)
    {
      inet_ntop (AF_INET, new_ai->ai_addr->sa_data, addrstr, DOMAIN_NAME_MAX_LENGTH);
      new_ai = new_ai->ai_next;
    }

    return 0;
}

If you remove

inet_ntop (AF_INET, new_ai->ai_addr->sa_data, addrstr, DOMAIN_NAME_MAX_LENGTH);

it will not give seg fault. But why it give it?? Please help, thanks!

(PS: I tried to simplify my code as I can. It is reason why it don't produce any useful results)

Petr Marek
  • 59
  • 1
  • 7
  • A segmentation fault is usually caused by writing to memory you're not supposed to. the more common ways of causing this are indexing out of range on an array or writing a string that is too long into a predefined array that does not have enough space. – William Dussault Oct 07 '19 at 15:44

1 Answers1

0

… give seg fault. But why it give it?

getaddrinfo(…, &new_ai) returned with error, and in this case you may not rely on new_ai being set.

The reason for the error return is that you forgot to initialize tmp_ai.ai_protocol. This wouldn't have happened if you used an initializer at the definition of tmp_ai:

    struct addrinfo tmp_ai = { .ai_flags = AI_CANONNAME,
                               .ai_family = AF_INET,
                               .ai_socktype = SOCK_STREAM }, *new_ai;
Armali
  • 18,255
  • 14
  • 57
  • 171