Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wrong output inet_ntop

I'm trying to print an ip address from inet_ntop, but the output seems pretty weird.

The program seems to work well, I succeed to connect the socket but it print this:

H��H9�u�H�[]A\A]A^A_�ff.�

Here is my code:

#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);
}
like image 377
jehutyy Avatar asked Feb 10 '23 16:02

jehutyy


1 Answers

Two issues here:

  1. The 3rd parameter to inet_ntop() should be a char-array or a pointer to the 1st element of a char-array.

  2. The 4th parameter to inet_ntop() should be the size of the destination buffer, whose address is passed as 3rd parameter.

What you do is to pass the uninitialised char-pointer dst as destination and tell the function it would point to sizeof(char*) bytes memory.

An AF_INET address (which has the form xxx.xxx.xxx.xxx) uses a maximum of 4x3 characters plus 3 delimiting . chars which sums up to 15 chars plus 1 additional char used as 0-terminator to make it a C-"string", so the corrected code would look like this:

char dst[16] = ""; /* inet_ntop() does not necessarily 0-terminates the result. */
inet_ntop(AF_INET, &sockin->sin_addr, dst, sizeof dst);

As pointed out by Filipe Gonçalves in his comment one can use INET_ADDRSTRLEN (if available) instead of the hard coded "magic number" 16 to define the buffer size for the textual representation of a IPv4 address. It's a good thing.


Documentation for inet_ntop() is here:

  • POSIX in general
  • Specific to Linux
like image 82
alk Avatar answered Feb 24 '23 07:02

alk