1
#include <string.h>
#include <stdio.h>
#include <netdb.h>

int main(){
    char buff[50];
    char port[5];

    printf("Enter address to lookup: ");
    fgets(buff, 50, stdin);

    printf("Enter Port: ");
    fgets(port, 5, stdin);

    struct addrinfo* res;
    struct addrinfo hints; memset(&hints, 0, sizeof(hints)); hints.ai_flags= AI_PASSIVE;

    __auto_type error = getaddrinfo(buff, port, &hints, &res);
    if (error < 0 )
        return 4;

    printf("Host IP: %s", buff);
    error = getnameinfo(res->ai_addr, res->ai_addrlen, buff, 50, 0, 0, 0);
    if (error < 0)
        return 5;

    printf("Host IP: %s", buff);
    freeaddrinfo(res);
}

Running This code Cause getaddrinfo( ) to terminate program due to a segmentation fault. Edit: The error seems to come from getaddrinfo( ) after checking return Value of getaddrinfo the input is just www.google.com (A bunch of other address have been tested also ) 443 (tried it with port 80 as well )

KMG
  • 1,433
  • 1
  • 8
  • 19
  • 1
    What is your input? And for starters, add error checking code. Check return value of all functions - should not blindly dereference `res` without knowing whether it contains a valid pointer or not. Should not blindly assume `buff` contains a valid string without checking function return values. – kaylum Jul 16 '20 at 00:56
  • @kaylum my input is just www.google.com with port 443 I know about error checking but this code is very simple that it's supposed to just work but something isn't right . – KMG Jul 16 '20 at 01:28
  • Your problem is you are passing `&res` to `getaddrinfo`. But, `res` is an _unitialized_ pointer. Try: `struct addrinfo res;` (i.e. _without_ the `*`). And, if you do that, change all `res->` into `res.` – Craig Estey Jul 16 '20 at 01:29
  • @CraigEstey actually getaddinfo( ) is supposed to allocate the struct and assign the pointer to res According to the documentation – KMG Jul 16 '20 at 01:32
  • "it's supposed to just work". Well it obviously isn't. Just add the error checking. All good code needs that and it will help you debug any problems that there may be. You can't just say "it should work" and not do basic debugging such as error checking, debug prints, running in debugger, etc. – kaylum Jul 16 '20 at 01:36
  • @kaylum just edited the question with new code doing error checking always return with with number 4(i.e getaddrinfo seems to fail ) – KMG Jul 16 '20 at 01:41
  • Don't return a random error code. Call `perror` or examine `errno` directly to get a more precise error reason. – kaylum Jul 16 '20 at 01:43
  • @KhaledGaber Oops, my bad. But, I just found the real problem. See my answer. – Craig Estey Jul 16 '20 at 01:48

1 Answers1

1

When I run your original code, I get a res value of 0x1.

The problem is that the buff and port strings have a newline (\n) in them.

When the newlines are stripped it runs to completion.

Here's the modified code I used:

#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <netdb.h>

void
fixup(char *buf)
{
    char *cp;

    cp = strchr(buf,'\n');
    if (cp != NULL)
        *cp = 0;
}

int
main()
{
    char buff[50];
    char port[5];

#if 1
    FILE *xf = stdin;
#else
    FILE *xf = fopen("input.txt","r");
#endif

    printf("Enter address to lookup: ");
    fgets(buff, 50, xf);
    fixup(buff);

    printf("Enter Port: ");
    fgets(port, 5, xf);
    fixup(port);

    struct addrinfo *res;
    struct addrinfo hints;

    memset(&hints, 0, sizeof(hints));
    hints.ai_flags = AI_ALL;

    getaddrinfo(buff, port, &hints, &res);
    printf("res=%p\n",res);
    printf("Host IP: %s\n", buff);

    getnameinfo(res->ai_addr, res->ai_addrlen, buff, 50, 0, 0, NI_NUMERICHOST);
    printf("Host IP: %s\n", buff);

    freeaddrinfo(res);
}
Craig Estey
  • 30,627
  • 4
  • 24
  • 48
  • so the whole problem was that getaddrinfo can't deal with a '\n' character, it's seems a little bit weird right :). – KMG Jul 16 '20 at 01:54
  • @KhaledGaber It could probably do a better job of protecting itself. But, `getaddrinfo` isn't "human facing" (i.e. it assumes its input has already been checked) for speed. – Craig Estey Jul 16 '20 at 01:59