14

How would I check if the remote host is up without having a port number? Is there any other way I could check other then using regular ping.

There is a possibility that the remote host might drop ping packets

Teun Zengerink
  • 4,277
  • 5
  • 30
  • 32
user140736
  • 1,913
  • 9
  • 32
  • 53
  • Can you give an example? You could loop through all the ports for a given host (or at least common ports), but that starts to border on black-hat. – Brian Tol Mar 28 '10 at 23:43
  • 2
    From a quick glance at the answers I conclude that your question is somewhat vague. You might get better answers if you also state what your ultimate/high-level goal is: e.g. do you want to monitor the availability of a service or do you want to write some kind of network security check tool that discovers hosts that are "up"? – paprika Mar 29 '10 at 00:24

7 Answers7

21

This worked fine for me:

HOST_UP  = True if os.system("ping -c 1 " + SOMEHOST) is 0 else False
jmunsch
  • 22,771
  • 11
  • 93
  • 114
  • 20
    Warning. This can introduce a security flaw if the `SOMEHOST` comes from user input. e.g if `SOMEHOST = google.com; echo "nasty command"` then the users malicious command will be run after the ping finishes. – ABakerSmith May 11 '18 at 13:49
  • 1
    ICMP requests can be blocked on remote host, so you can get HOST_UP = False when host is up. – AmaHacka Sep 22 '21 at 08:19
  • this works but in windows 11 you get Access denied. Option -c requires administrative privileges. – 00__00__00 Jan 06 '23 at 11:28
  • IMHO I would use `== 0` instead of `is 0` – Save Apr 02 '23 at 18:01
  • `import os; HOST_UP= True if os.system("ping -n 1 " + SOMEHOST)== 0 else False` works for my purposes. `-n 1` excecutes ping only once – Aroc Jun 30 '23 at 12:33
3

A protocol-level PING is best, i.e., connecting to the server and interacting with it in a way that doesn't do real work. That's because it is the only real way to be sure that the service is up. An ICMP ECHO (a.k.a. ping) would only tell you that the other end's network interface is up, and even then might be blocked; FWIW, I have seen machines where all user processes were bricked but which could still be pinged. In these days of application servers, even getting a network connection might not be enough; what if the hosted app is down or otherwise non-functional? As I said, talking sweet-nothings to the actual service that you are interested in is the best, surest approach.

Donal Fellows
  • 133,037
  • 18
  • 149
  • 215
2

Many firewalls are configured to drop ping packets without responding. In addition, some network adapters will respond to ICMP ping requests without input from the operating system network stack, which means the operating system might be down, but the host still responds to pings (usually you'll notice if you reboot the server, say, it'll start responding to pings some time before the OS actually comes up and other services start up).

The only way to be certain that a host is up is to actually try to connect to it via some well-known port (e.g. web server port 80).

Why do you need to know if the host is "up", maybe there's a better way to do it.

Dean Harding
  • 71,468
  • 13
  • 145
  • 180
2
HOST_UP  = True if os.system("ping -c 5 " + SOMEHOST.strip(";")) is 0 else False

to remove nasty script execution just add .strip(";")

-c 5 

to increase the number of ping requests, if all pass than True

PS. Works only on Linux, on Windows always returns True

1

What about trying something that requires a RPC like a 'tasklist' command in conjunction with a ping?

chonerman
  • 117
  • 11
1

The best you can do is:

  • Try and connect on a known port (eg port 80 or 443 for HTTP or HTTPS); or
  • Ping the site. See Ping a site in Python?

Many sites block ICMP (the portocol used to ping sites) so you must know beforehand if the host in question has it enabled or not.

Connecting to a port tells you mixed information. It really depends on what you want to know. A port might be open but the site is effectively hung so you may get a false positive. A more stringent approach might involve using a HTTP library to execute a Web request against a site and see if you get back a response.

It really all depends on what you need to know.

Community
  • 1
  • 1
cletus
  • 616,129
  • 168
  • 910
  • 942
1

I would use a port scanner. Original question states that you don't want to use a port. Then you need to specify which Protocol (Yes, this needs a port) you want to monitor: HTTP, VNC, SSH, etc. In case you want to monitor via ICMP you can use subprocess and control ping parameters, number of pings, timeout, size, etc.

import subprocess 
    try:
        res = subprocess.Popen(['ping -t2 -c 4 110.10.0.254 &> /dev/null; echo $?'],shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
        out, err = res.communicate()
        out = out.rstrip()
        err = err.rstrip()
        print 'general.connectivity() Out: ' + out
        print 'general.connectivity() Err: ' + err
        if(out == "0"):
            print 'general.connectivity() Successful'
            return True
        print 'general.connectivity() Failed'
        return False
    except Exception,e:
        print 'general.connectivity() Exception'
        return False

In case you want a port scanner

import socket
from functools import partial
from multiprocessing import Pool
from multiprocessing.pool import ThreadPool
from errno import ECONNREFUSED

NUM_CORES = 4

def portscan(target,port):
    try:
        # Create Socket
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        socketTimeout = 5
        s.settimeout(socketTimeout)
        s.connect((target,port))
        print('port_scanner.is_port_opened() ' + str(port) + " is opened")
        return port
    except socket.error as err:
        if err.errno == ECONNREFUSED:
            return False

# Wrapper function that calls portscanner
def scan_ports(server=None,port=None,portStart=None,portEnd=None,**kwargs):
    p = Pool(NUM_CORES)
    ping_host = partial(portscan, server)
    if portStart and portStart:
        return filter(bool, p.map(ping_host, range(portStart, portStart)))
    else:
        return filter(bool, p.map(ping_host, range(port, port+1)))

# Check if port is opened
def is_port_opened(server=None,port=None, **kwargs):
    print('port_scanner.is_port_opened() Checking port...')
    try:
        # Add More proccesses in case we look in a range
        pool = ThreadPool(processes=1)
                     try:
                        ports = list(scan_ports(server=server,port=int(port)))
                        print("port_scanner.is_port_opened() Port scanner done.")
                        if len(ports)!=0:
                            print('port_scanner.is_port_opened() ' + str(len(ports)) + " port(s) available.")
                            return True
                        else:
                            print('port_scanner.is_port_opened() port not opened: (' + port  +')')
                            return False
                    except Exception, e:
                        raise
                
    except Exception,e:
        print e
        raise
gogasca
  • 9,283
  • 6
  • 80
  • 125