Simple ping routine, not receiving anything.
Hi,
I'm trying to create a simple ping routine, that can be used in other programs to test internet connectivity. I'm stuck, as the following code seems to send the request, but `recvfrom` blocks forever.
Since I don't normally deal with sockets like this, I'm completely lost as to what is wrong. And I don't think I can look at more code that doesn't satisfy my need.
Here's what I have:
Code:
// Declare includes.
#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
#include <libgen.h>
#include <netinet/in.h>
#include <netinet/ip_icmp.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
// Declare defines.
#define BUFFER_SIZE 1024
#define PING_ADDRESS "8.8.8.8"
#define RETURN_FAILURE 0
#define RETURN_SUCCESS 1
// Declare function prototypes.
int pinger (char *address);
int main (int argc, __attribute__ ((unused)) char *argv[])
{
// Check number of arguments.
if(argc != 1)
{
fprintf(stderr, "Usage: %s", program_invocation_short_name);
exit(EXIT_FAILURE);
}
// Check that user is root or that sudo is used.
if(geteuid() != 0)
{
fprintf(stderr, "%s: must be run as root or with 'sudo'", program_invocation_short_name);
exit(EXIT_FAILURE);
}
// Run process.
printf("Pinging %s was %s\n", PING_ADDRESS, pinger(PING_ADDRESS) == RETURN_SUCCESS ? "successful." : "unsuccessful.");
// Exit cleanly.
exit(EXIT_SUCCESS);
}
int pinger (char *address)
{
// Declare variables.
char buffer[BUFFER_SIZE] = {0};
struct icmp icmp_hdr = {0};
struct sockaddr_in dest_addr = {0};
struct sockaddr_in from_addr = {0};
socklen_t fromlen = {0};
int sockfd = {0};
// Populate the icmp structure.
icmp_hdr.icmp_type = ICMP_ECHO;
icmp_hdr.icmp_code = 0;
icmp_hdr.icmp_cksum = 0;
icmp_hdr.icmp_id = getpid();
icmp_hdr.icmp_seq = 1;
// Populate the socket address structure.
dest_addr.sin_family = AF_INET;
dest_addr.sin_addr.s_addr = inet_addr(address);
memset(&dest_addr.sin_zero, 0, sizeof(dest_addr.sin_zero));
// Create a raw socket.
if((sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) == -1)
{
fprintf(stderr, "%s: %s error: socket failed (%s)", program_invocation_short_name, __func__, strerror(errno));
return(RETURN_FAILURE);
}
// Send icmp request.
if(sendto(sockfd, &icmp_hdr, sizeof(struct icmp), 0, (struct sockaddr *) &dest_addr, sizeof(struct sockaddr_in)) == -1)
{
fprintf(stderr, "%s: %s error: sendto failed (%s)", program_invocation_short_name, __func__, strerror(errno));
return(RETURN_FAILURE);
}
// Receive icmp response.
if(recvfrom(sockfd, buffer, BUFFER_SIZE, 0, (struct sockaddr *) &from_addr, &fromlen) == -1)
{
fprintf(stderr, "%s: %s error: recvfrom failed (%s)", program_invocation_short_name, __func__, strerror(errno));
return(RETURN_FAILURE);
}
// Return success.
return(RETURN_SUCCESS);
}
Any help or insight is greatly appreciated. Ty.