1

I am getting Segmentation Fault with the codes below.

What I need the program to do is, when an invalid/unknown name or service is entered as an argument, it displays an error only for that particular service and continues to work on the rest of the provided services.

Right now, the program works if I include an invalid service anywhere in a line of services (e.g ./dnslookup www.nhawurha.com www.google.com OR www.google.com www.nhawurha.com)

But it gives me a Segmentation Fault after printing the error if only the invalid service is used as the sole argument (e.g ./dnslookup www.nhawurha.com)

Any form of help would be much appreciated, thanks!

#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netdb.h>

#define BUFLEN 1500    

int main(int argc, char *argv[]) {
struct addrinfo hints, *ai, *result;    
char ipaddrv4[BUFLEN];
char ipaddrv6[BUFLEN];
int error;

if (argc < 2) {
    fprintf(stderr, "Missing <hostname> after %s \n", argv[0]);
    return 0;
}

for (int j = 1; j < argc; j++) {

    memset(&hints, 0, sizeof(hints));
    hints.ai_family = PF_UNSPEC;    /* IPv4, IPv6, or anything */
    hints.ai_socktype = SOCK_DGRAM; /* Dummy socket type */

    error = getaddrinfo(argv[j], NULL, &hints, &result);
    if (error) {
        fprintf(stderr, "ERROR (%s: %s)\n", argv[j], gai_strerror(error));
        continue;
    }

    for (ai = result; ai != NULL; ai = ai->ai_next) {
        if (ai->ai_family == AF_INET) {
            struct sockaddr_in *ipv4 = (struct sockaddr_in *) ai->ai_addr;
            void *addr = &(ipv4->sin_addr);
            inet_ntop(AF_INET, addr, ipaddrv4, BUFLEN);
            printf("%s IPv4 %s\n", argv[j], ipaddrv4);
        }

        else if (ai->ai_family == AF_INET6) {
            struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *) ai->ai_addr;
            void *addr = &(ipv6->sin6_addr);
            inet_ntop(AF_INET6, addr, ipaddrv6, BUFLEN);
            printf("%s IPv6 %s\n", argv[j], ipaddrv6);
        }

        else {
            continue;
        }
    }       
}

freeaddrinfo(result);
return 0;

}

Calvin
  • 13
  • 4
  • where exactly do you get the error? what's the error message? what have you allready tried? – Skandix Feb 12 '19 at 08:33
  • @Skandix, sorry I forgot to provide that information! I get the error here: `error = getaddrinfo(argv[j], NULL, &hints, &result); if (error) { fprintf(stderr, "ERROR (%s: %s)\n", argv[j], gai_strerror(error)); continue; }` The error message is: "Segmentation Fault (core dumped)". Changing "continue" to "return 0" stops the Segmentation Fault error from appearing, but the program won't process any other arguments after an invalid service is provided. – Calvin Feb 12 '19 at 08:45

1 Answers1

0

Have a look at the 'result' parameter - if your one and only lookup fails, result will be uninitialised and freeaddrinfo will segfault. Try initialising it to NULL first.

There is a second problem if you have more than one lookup - a memory leak because you don't call freeaddrinfo on each result.

So I think your logic should be more like:

for each command line arg
   if lookup succeeds
     print result
     free result
   else
     print error

See man page for getaddrinfo

Peter Hull
  • 6,683
  • 4
  • 39
  • 48