Skip to content
Advertisement

Getting IP address from struct sockaddr doesn’t work for 32bit compilation

I have a small client/server app that sends/receives UDP discovery packets. When a UDP packet is received I want to display the source IP. The client/server code is based on the UDP example from Beej: https://beej.us/guide/bgnet/html/multi/clientserver.html

When I compile for 64bit the IP is displayed as expected but when I compile for 32bit (-m32 option) it doesn’t get the right value at all.

Code snippit:

// get sockaddr, IPv4 or IPv6:
void *get_in_addr(struct sockaddr *sa)
{
    if (sa->sa_family == AF_INET) {
        return &(((struct sockaddr_in*)sa)->sin_addr);
    }

    return &(((struct sockaddr_in6*)sa)->sin6_addr);
}

...

printf("listener: waiting to recvfrom...n");
addr_len = sizeof their_addr;
if ((numbytes = recvfrom(sockfd, buf, MAXBUFLEN-1 , 0,
    (struct sockaddr *)their_addr, &addr_len)) == -1) {
    perror("recvfrom");
    exit(1);
}

printf("listener: got packet from %sn",
    inet_ntop(their_addr->sa_family,
        get_in_addr((struct sockaddr *)their_addr),
        s, sizeof s));

printf("Sockaddr: ");
for (i=0; i<sizeof(struct sockaddr_in); i++)
    printf("%x ", ((char *)their_addr)[i]);
printf("n");

Correct output when compiled for 64bit:

    listener: waiting to recvfrom...
    listener: got packet from 192.168.20.6
    Sockaddr: 2 0 ffffff80 19 ffffffc0 ffffffa8 14 6 64 2e 40 0 0 0 0 0 

Wrong output when compiled with -m32:

    listener: waiting to recvfrom...
    listener: got packet from 168.32.140.255
    Sockaddr: 2 0 ffffff80 19 ffffffa8 20 ffffff8c ffffffff 50 ffffffdd 7d fffffff7 4 0 0 0 

I don’t really understand why there is a problem using get_in_addr or inet_ntop when compiling for 32bit?

Advertisement

Answer

addr_len should be set to the size of the address structure, not the size of the pointer (it’s happening to work in 64 bit mode, because pointers are twice as large in that mode). So it should be:

addr_len = sizeof *their_addr;

Incidentally, how is their_addr initialised? There has to be a real structure to point to.

User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement