witch3r
witch3r

Reputation: 87

Check if given input is a valid IP or Hostname or something invalid

I am trying to create a program to check whether the given input is a valid hostname, valid IP, or neither. The program is able to recognize a valid hostname or IP. However, If I try to put something random, like "xyz", it doesn't print the error message I want.

import socket
if __name__ == '__main__':
    hostname = 'hyuiolpp'
    if socket.gethostbyname(hostname) == hostname:
        print('{} is a valid IP address'.format(hostname))
    elif socket.gethostbyname(hostname) != hostname:
        print('{} is a valid hostname'.format(hostname))
    else:
        print("Something is wrong")

The error I get:

Traceback (most recent call last):
  File ".....", line 5, in <module>
    if socket.gethostbyname(hostname) == hostname:
socket.gaierror: [Errno 8] nodename nor servname provided, or not known

Upvotes: 5

Views: 3790

Answers (3)

r.ook
r.ook

Reputation: 13878

You can add a simple try block and catch the error(s) generated.

import socket

def main():
    hostname = 'hyuiolpp'
    try:
        if socket.gethostbyname(hostname) == hostname:
            print('{} is a valid IP address'.format(hostname))
        elif socket.gethostbyname(hostname) != hostname:
            print('{} is a valid hostname'.format(hostname))
    except socket.gaierror:
        print("Something is wrong")

if __name__ == '__main__':
   main()

Few Things:

1.) I added a main() function and just called it in your __main__ check as it seems to be a better practice. I don't think there's anything wrong with yours, but from my experiences most people code this way, probably because it's easier to comment out one #main() than dozens of lines during debug or even to test out different functions locally.

2.) You'll probably want to handle each error raised differently. During your unit testing you'll find out what other errors (beside socket.gaierror) are raised and what errors you might anticipate, and figure out how your program is supposed to handle those scenarios. You can add extra excepts for each error (or group them together if the group is handled one way). Using just except: to catch all is generally considered a bad practice unless you're okay with that.

Upvotes: 6

William Monteiro
William Monteiro

Reputation: 46

Firstly I think you have a concept problem:

check whether the given input is a valid Hostname or valid IP or none of them either

You can check if the IP is valid using the RFCs for IPv4 and IPv6 but you can never discard a hostname because xyz can be reachable within you LAN and not from the internet.

Also I don't know python very well but it seems that your code is generating an exception that must be caught with a try-catch block.

Upvotes: 0

Prune
Prune

Reputation: 77857

Use a try-except block. The problem is that xyz causes a run-time fault in gethostbyname -- instead of a False value, the program turns over to the error handler. Something like

try: 
    sock = socket.gethostbyname(hostname)
    if sock == ...
except:
    print("Something is wrong") 

Upvotes: 1

Related Questions