[22a737b] | 1 | """Usage: python3 check_test_ips.py IP|HOSTNAME [...] |
---|
| 2 | |
---|
| 3 | Check if the given IPs, or IPs associated with given hostnames, are |
---|
| 4 | routable. Under the assumption that those IPs are local a positive |
---|
| 5 | result means they should be usable for tests. |
---|
| 6 | |
---|
| 7 | The script prints the first two (in order of arguments) usable |
---|
| 8 | addresses to sys.stdout. IPv6 addresses in the output are enclosed in |
---|
| 9 | square brackets. |
---|
| 10 | |
---|
| 11 | """ |
---|
| 12 | import socket |
---|
| 13 | import sys |
---|
| 14 | |
---|
| 15 | |
---|
| 16 | def try_connect(sockaddr): |
---|
| 17 | """Try to connect a UDP socket to the given address. "Connecting" a |
---|
| 18 | UDP socket means only setting the default destination for packets, |
---|
| 19 | so nothing is actually sent. Return True if the socket.connect() |
---|
| 20 | call was successful, False otherwise. |
---|
| 21 | |
---|
| 22 | For loopback this effectively tests if the address is really |
---|
| 23 | configured, to detect e.g. situations where a system may have "::1 |
---|
| 24 | localhost" in /etc/hosts, but actually has IPv6 disabled. |
---|
| 25 | |
---|
| 26 | """ |
---|
| 27 | af, socktype, proto, canonname, sa = sockaddr |
---|
| 28 | try: |
---|
| 29 | s = socket.socket(af, socktype, proto) |
---|
| 30 | s.connect(sa) |
---|
| 31 | except: |
---|
| 32 | return False |
---|
| 33 | finally: |
---|
| 34 | s.close() |
---|
| 35 | return True |
---|
| 36 | |
---|
| 37 | |
---|
| 38 | if __name__ == "__main__": |
---|
| 39 | import argparse |
---|
| 40 | parser = argparse.ArgumentParser( |
---|
| 41 | description='Check if IPs/hostnames are routable') |
---|
| 42 | parser.add_argument('hosts', metavar='HOST', nargs='+', |
---|
| 43 | help='the hostnames/IPs to check') |
---|
| 44 | parser.add_argument('--quiet', '-q', action='store_true', |
---|
| 45 | help='disable debug output') |
---|
[2b3a2814] | 46 | parser.add_argument('--hostname', '-H', action='store_true', |
---|
| 47 | help='append socket.gethostname() to hosts') |
---|
[22a737b] | 48 | args = parser.parse_args() |
---|
| 49 | |
---|
[2b3a2814] | 50 | if args.hostname: |
---|
| 51 | args.hosts.append(socket.gethostname()) |
---|
| 52 | |
---|
[22a737b] | 53 | test_ips = [] |
---|
| 54 | for name in args.hosts: |
---|
| 55 | addrs = list(map(lambda t: t[-1][0], |
---|
| 56 | filter(try_connect, |
---|
| 57 | socket.getaddrinfo(name, 12345, |
---|
| 58 | proto=socket.IPPROTO_UDP)))) |
---|
| 59 | if not args.quiet: |
---|
| 60 | print(f'{name}: {addrs}', file=sys.stderr) |
---|
| 61 | test_ips += addrs |
---|
| 62 | |
---|
| 63 | print(' '.join(f'[{i}]' if ':' in i else i for i in test_ips[:2])) |
---|