Reputation: 5025
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
).
Upvotes: 2
Views: 2367
Reputation: 156
It should work if you fill plen with valid sizeof data.
*plen = sizeof(struct sockaddr_in);
You can put that right before the recvfrom call.
Upvotes: -3
Reputation: 50190
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))
Upvotes: 4