I'm writing a function that is supposed to do some operations and then return (using its arguments) the address of the device that is interacting with (i.e. that used sendto
) the recvfrom
inside the function.
Here's how I call the function, instantiating cliaddr
before.
struct sockaddr_in cliaddr;
memset((void *) &cliaddr, 0, sizeof(cliaddr));
rcv_string(sockfd, &return_string, &cliaddr);
// Here I'll need to use cliaddr, that's why I need it outside too
Here's the implementation of the function:
int rcv_string(int sockfd, char **return_string, struct sockaddr_in *sndaddr) {
// ...
char buff[PACKETSZ + 2];
memset(&buff, 0, sizeof(buff)); // Clean buffer
socklen_t *plen = malloc(sizeof(struct sockaddr *));
if ((recvfrom(sockfd, buff, sizeof(buff), 0, (struct sockaddr *) sndaddr, plen)) < 0) {
perror("recvfrom");
return -1;
}
char *snd_ip = malloc(INET_ADDRSTRLEN * sizeof(char));
if (inet_ntop(AF_INET, &((*sndaddr).sin_addr.s_addr), snd_ip, INET_ADDRSTRLEN * sizeof(char)) == NULL) {
perror("inet_ntop");
return -1;
}
printf("Received '%s' from '%s'.\n", buff, snd_ip);
// ...
}
Now, even if the ip address of the sending device is 192.168.1.251
I get the following output:
Received '0packetx' from '0.0.0.0'.
The received buffer is formatted correctly, but the address is evidently wrong. Why? Does it have to do with the definition of the address variable outside the function?
If after the memset
of cliaddr
I add also those 3 lines:
cliaddr.sin_family = AF_INET;
cliaddr.sin_addr.s_addr = htonl(INADDR_ANY);
cliaddr.sin_port = htons(SERV_PORT);
I get a random behavior. Sometimes I get 0.0.0.0
, sometimes 127.0.0.1
and sometimes the correct address (192.168.1.251
).
you are passing the wrong length to recvfrom
socklen_t *plen = malloc(sizeof(struct sockaddr *));
if ((recvfrom(sockfd, buff, sizeof(buff), 0, (struct sockaddr *) sndaddr, plen))
Why you malloc is a mystery, but you need
socklen_t *plen = malloc(sizeof(socklen_t));
*plen = sizeof(struct sockaddr_in );
much simpler is
socklen_t plen = sizeof(struct sockaddr_in);
if ((recvfrom(sockfd, buff, sizeof(buff), 0, (struct sockaddr *) sndaddr, &plen))