Estoy tratando de imprimir una dirección IP desde inet_ntop, pero el resultado parece bastante extraño.
El programa parece funcionar bien, logré conectar el zócalo pero imprimió esto:
H��H9�u�H�[]A\A]A^A_�ff.�Aquí está mi código:
#include <stdio.h> #include <stdlib.h> #include <sys/socket.h> #include <sys/types.h> #include <netdb.h> #include <string.h> #include <arpa/inet.h> int main(int argc, char *argv[]){ int sock = socket(AF_INET, SOCK_STREAM, 0); struct addrinfo hints, *result; memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = 0; hints.ai_flags = 0; int s = getaddrinfo("irc.root-me.org", "6667", &hints, &result); if( s != 0){ printf("erreur\n"); exit(EXIT_FAILURE); } int f = connect(sock, result->ai_addr, result->ai_addrlen); if(f != 0){ printf("erreur connect\n"); } struct sockaddr_in *sockin; sockin = (struct sockaddr_in *)result->ai_addr; char *dst; inet_ntop(AF_INET, &sockin->sin_addr, dst, sizeof(char *)); printf("%s\n", dst); freeaddrinfo(result); exit(0); }Dos problemas aquí:
El tercer parámetro de inet_ntop inet_ntop() debe ser una char de caracteres o un puntero al primer elemento de una char de caracteres.
El cuarto parámetro de inet_ntop inet_ntop() debe ser el tamaño del búfer de destino, cuya dirección se pasa como tercer parámetro.
Lo que hace es pasar el char -pointer dst no inicializado como destino y decirle a la función que apuntaría a la memoria de bytes sizeof(char*) .
Una dirección AF_INET (que tiene la forma xxx.xxx.xxx.xxx ) utiliza un máximo de 4x3 caracteres más 3 delimitadores . char s que suma hasta 15 char s más 1 char adicional usado como 0 -terminator para convertirlo en una C-"cadena", por lo que el código corregido se vería así:
char dst[16] = ""; /* inet_ntop() does not necessarily 0-terminates the result. */ inet_ntop(AF_INET, &sockin->sin_addr, dst, sizeof dst); Como señaló Filipe Gonçalves en su comentario , se puede usar INET_ADDRSTRLEN (si está disponible) en lugar del "número mágico" codificado de forma rígida 16 para definir el tamaño del búfer para la representación textual de una dirección IPv4. Es algo bueno.
La documentación para inet_ntop() está aquí:
El problema es con el tamaño del carácter de destino* en el que está intentando guardar el resultado, y el hecho de que no está inicializado, lo que quiere hacer es guardarlo en un carácter[].
sizeof(char*) en x86 es 4B y 8B en x64, las direcciones IP suelen ser más grandes que eso (una dirección IPv4 tiene entre 7 y 15 bytes) + 1 para el terminador nulo.
Puede corregir el código de la siguiente manera:
char dst[16] = {0}; inet_ntop(AF_INET, &sockin->sin_addr, dst, sizeof(dst));Después de la corrección:
$ ./main 212.83.153.145Si desea el main.c completo y fijo, lo he subido a github.