Use a função getaddrinfo em C

Jinku Hu 12 outubro 2023
  1. Use a função getaddrinfo para o nome do host para o endereço IP em C
  2. Use a função getnameinfo para o endereço IP do nome do host em C
Use a função getaddrinfo em C

Este artigo irá demonstrar vários métodos sobre como usar a função getaddrinfo em C.

Use a função getaddrinfo para o nome do host para o endereço IP em C

getaddrinfo faz parte das facilidades de programação de rede UNIX e pode converter informações de host de rede para o endereço IP e vice-versa. getaddrinfo também é uma chamada de função compatível com POSIX e pode fazer a conversão independentemente dos protocolos subjacentes.

getaddrinfo leva quatro argumentos,

  1. O primeiro pode ser o ponteiro para o nome do host ou string de endereço formatado IPv4 / IPv6.
  2. O segundo argumento pode ser um nome de serviço ou um número de porta representado com o número inteiro decimal.
  3. Os próximos dois argumentos são ponteiros para estruturas addrinfo. O primeiro é hints que especifica os requisitos para filtrar as estruturas de socket recuperadas, enquanto o segundo é o ponteiro, onde a função irá alocar dinamicamente uma lista vinculada de estruturas addrinfo.

Observe que a estrutura hints deve ser definida com zeros e, em seguida, seus membros devem ser atribuídos. O membro ai_family indica a família do endereço, por exemplo, IPv4 ou IPv6 como AF_INET e AF_INET6, respectivamente. Nesse caso, não estamos interessados na conversão do nome do serviço e especificamos NULL como o segundo argumento da função. Finalmente, chamamos getnameinfo para traduzir as estruturas sockaddr fornecidas para a forma imprimível.

#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>

int main(int argc, char const *argv[]) {
  struct addrinfo hints;
  struct addrinfo *res, *tmp;
  char host[256];

  memset(&hints, 0, sizeof(struct addrinfo));
  hints.ai_family = AF_INET;

  if (argc != 2) {
    fprintf(stderr, "%s string\n", argv[0]);
    exit(EXIT_FAILURE);
  }

  int ret = getaddrinfo(argv[1], NULL, &hints, &res);
  if (ret != 0) {
    fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(ret));
    exit(EXIT_FAILURE);
  }

  for (tmp = res; tmp != NULL; tmp = tmp->ai_next) {
    getnameinfo(tmp->ai_addr, tmp->ai_addrlen, host, sizeof(host), NULL, 0,
                NI_NUMERICHOST);
    puts(host);
  }

  freeaddrinfo(res);
  exit(EXIT_SUCCESS);
}

Comando de amostra:

./program localhost

Resultado:

127.0.0.1
127.0.0.1
127.0.0.1

Use a função getnameinfo para o endereço IP do nome do host em C

A função getnameinfo é usada em conjunto com getaddrinfo neste caso, e recupera os nomes de host para os endereços IP correspondentes. Observe que processamos a entrada do usuário a partir do primeiro argumento da linha de comando e o passamos como o argumento getaddrinfo para recuperar as estruturas socketaddr. Finalmente, cada estrutura pode ser traduzida para a string do nome do host. Uma vez que getaddrinfo aloca memória dinâmica para armazenar a lista vinculada no quarto argumento, este ponteiro deve ser liberado pelo usuário com a chamada de função freeaddrinfo.

#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>

int main(int argc, char const *argv[]) {
  struct addrinfo hints;
  struct addrinfo *res, *tmp;
  char host[256];

  memset(&hints, 0, sizeof(struct addrinfo));
  hints.ai_family = AF_INET;

  if (argc != 2) {
    fprintf(stderr, "%s string\n", argv[0]);
    exit(EXIT_FAILURE);
  }

  int ret = getaddrinfo(argv[1], NULL, &hints, &res);
  if (ret != 0) {
    fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(ret));
    exit(EXIT_FAILURE);
  }

  for (tmp = res; tmp != NULL; tmp = tmp->ai_next) {
    getnameinfo(tmp->ai_addr, tmp->ai_addrlen, host, sizeof(host), NULL, 0, 0);
  }

  freeaddrinfo(res);
  exit(EXIT_SUCCESS);
}

Comando de amostra:

./program 127.0.0.1

Resultado:

localhost
localhost
localhost
Autor: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn Facebook

Artigo relacionado - C Networking