How to check if an ip-address is reachable in C fo

2019-09-24 10:10发布

问题:

I want to build a code which given an ip-address just prints the finalresult reachable or not. I guess we have to use ping command but am not able to correctly implement it.

回答1:

Note that "reachability" on IP networks is kind of tricky to test for.

It's perfectly possible that a server machine is running any number of real services (www, ftp, whatever), but has been configured not to reply to pings since some people do that.

If possible, it's better to just connect like the real service you want to check for.



回答2:

Consider the following example program:

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <string.h>

int main()
{
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);

    struct sockaddr_in sin;
    sin.sin_family = AF_INET;
    sin.sin_port   = htons(65432);  // Could be anything
    inet_pton(AF_INET, "192.168.0.1", &sin.sin_addr);

    if (connect(sockfd, (struct sockaddr *) &sin, sizeof(sin)) == -1)
    {
        printf("Error connecting 192.168.0.1: %d (%s)\n", errno, strerror(errno));
    }

    sin.sin_family = AF_INET;
    sin.sin_port   = htons(65432);  // Could be anything
    inet_pton(AF_INET, "192.168.0.9", &sin.sin_addr);

    if (connect(sockfd, (struct sockaddr *) &sin, sizeof(sin)) == -1)
    {
        printf("Error connecting 192.168.0.9: %d (%s)\n", errno, strerror(errno));
    }
}

On my system it prints:

Error connecting 192.168.0.1: 111 (Connection refused)
Error connecting 192.168.0.9: 113 (No route to host)

On my network 192.168.0.1 is my own computer, 192.168.0.9 is an address that is not on the network.

As you can see you get two different errors depending on if an address can be reached (the first line of output) or not (the second line).



回答3:

Well you'd want to construct a pipe between ping and your program using popen()

(see e.g.: http://pubs.opengroup.org/onlinepubs/009695399/functions/popen.html)

Then you need to parse the input appropriately.



回答4:

You could use e.g. popen with the ping command.

Or use the libping library.

Or, assuming some HTTP server is running on the remote machine, issue a HEAD HTTP request thru libcurl

Or code the low level system calls done by ping. Use strace to find them out.

P.S. some system calls require "root" privilege. This is why /bin/ping is setuid



回答5:

As others suggested, you can use popen().

But remember, ping isn't reliable, firewalls can block ICMP echo (which is used by ping) yet the host could be still reachable on specific ports.



标签: c linux