getaddrinfo, Ошибка сегментации - PullRequest
0 голосов
/ 12 февраля 2019

Я получаю ошибку сегментации с приведенными ниже кодами.

Что мне нужно, чтобы программа сделала, когда неверное / неизвестное имя или служба введены в качестве аргумента, она отображает ошибку только для этого конкретногои продолжает работать с остальными предоставляемыми услугами.

В настоящий момент программа работает, если я включаю недопустимую службу где-либо в линейке услуг (например, ./dnslookup www.nhawurha.com www.google.com ИЛИ www.google.com www.nhawurha.com)

Но после печати ошибки у меня возникает ошибка сегментации, если в качестве единственного аргумента используется только недействительный сервис (например, ./dnslookup www.nhawurha.com)

Буду признателен за любую помощь, спасибо!

#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;

}

1 Ответ

0 голосов
/ 12 февраля 2019

Посмотрите на параметр «result» - если ваш единственный поиск не удастся, результат будет неинициализирован, а freeaddrinfo будет segfault.Попробуйте сначала инициализировать его в NULL.

Существует вторая проблема, если у вас есть более одного поиска - утечка памяти, потому что вы не вызываете freeaddrinfo для каждого результата.

Так что ядумаю, что ваша логика должна быть больше похожа на:

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

См. справочную страницу для getaddrinfo

...