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.