-4

I want to know is there any python script (better a command) that can tell me am I connected to network or not.

I am not talking about "INTERNET", i'm talking about wired or wireless "NETWORK" (So please do not set this quetion as duplicate)

I mean my modem router is on and i'm connected to it (and it's not important it has internet or not) so the script returns True (It's better to not suggest terminal commands like ping etc.)

And also another question that might be an answer of this question: Is it good to get requests.get('192.168.1.1').status_code and if its 200 we're connected to a network?

Ramin-RX7
  • 128
  • 1
  • 1
  • 13
  • 1
    what operating system are you working on – M Z Aug 24 '20 at 19:50
  • @MZ I want a script for all operating systems but first of all 'linux' then 'windows' – Ramin-RX7 Aug 24 '20 at 19:51
  • Maybe you want to check over a ping function (https://stackoverflow.com/questions/26468640/python-function-to-test-ping/39563638) – rblais Aug 24 '20 at 19:57
  • @MZ well as I said I do not want ping (or any other terminal command if exists). But if I want use ping, what ip to use for testing? 192.168.1.1? – Ramin-RX7 Aug 24 '20 at 20:02
  • This will get you the address of your default gateway - should be your internet router - https://stackoverflow.com/a/6556951/13596037 . Try pinging that. – alani Aug 24 '20 at 20:03
  • @Ramin-RX7 that wasn't me lol – M Z Aug 24 '20 at 20:04

2 Answers2

0

And also another question that might be an answer of this question: Is it good to get requests.get('192.168.1.1').status_code and if its 200 we're connected to a network?

This isn't a great idea.

  • What if the local network isn't 192.168.1.0/24?
  • What if the gateway isn't 192.168.1.1?
  • What if the router doesn't have an HTTP interface?

The only sane thing you can do is pick a well known endpoint (e.g. "google.com") and try to contact it (for example, requests.get("http://google.com")). If it works...great, you're connected! If it doesn't work, you don't have enough information to decide if you're connected or not.

If you're only interested in local network connectivity, you could first determine your default gateway address (e.g. by running ip route under Linux, or route print on Windows), and then attempt to ping that. Once again, you can only detect a positive: if you get a response, you're connected, but if you don't, then you don't know whether you're connected or not.

larsks
  • 277,717
  • 41
  • 399
  • 399
  • There's a helpful function here that will get the default gateway on Linux https://stackoverflow.com/a/6556951/13596037 . Might also be worth mentioning that as the parameter to `requests.get()` is a URL just giving it an IP address won't be valid. – alani Aug 24 '20 at 20:06
  • I said "not INTERNET". I do not have internet but I'm connected to a NETWORK. This answer is not enough for me Because I said I want python command not terminal. with `route print` I need to get output and then filter it by regex pattern. Because this output might be different in other devices I don't think it can work. – Ramin-RX7 Aug 24 '20 at 20:11
  • I think you may have missed the second part of the answer that satisfies your "not INTERNET" requirement. I'm sorry that you're uncomfortable working with terminal commands; getting some more experience in that area will probably help you in the future. – larsks Aug 24 '20 at 21:28
0

everything that @larsks said is correct. additional You can check if You have an IP adress on Your host (or only localhost).

what You can do :

  • check if You have an IP adress on Your box, which is different from localhost, loopback address range

  • if You KNOW the default gateway (You can get it) You might ping the default gateway - but that might fail, because ICMP ping packets might be disabled on that default gateway.

to avoid TOCTOU Errors - just USE the adress and catch the errors ! (see: https://en.wikipedia.org/wiki/Time-of-check_to_time-of-use )

here the functions I use usually in that context:

def get_host_ip_or_localhost() -> Union[str, None]:
    """
    >>> result = get_host_ip_or_localhost()
    >>> assert is_valid_ip_adress(result)
    """
    host_ip = get_host_ip()

    if not host_ip:                                                                     # pragma: no cover
        logger.warning('can not get default gateway IP, setting localhost as IP')       # pragma: no cover
        host_ip = socket.gethostbyname('localhost')                                     # pragma: no cover
    return host_ip


def ip_is_localhost(host_ip: str) -> bool:
    """
    >>> ip_is_localhost('127.0.0.1')
    True
    >>> ip_is_localhost('localhost')
    True
    >>> ip_is_localhost('192.168.168.17')
    False
    >>> ip_is_localhost('192.168.168.254')
    False
    """
    host_ip = socket.gethostbyname(host_ip)
    local_host_ip = socket.gethostbyname('localhost')
    if host_ip == local_host_ip or host_ip.startswith('127.'):
        return True
    else:
        return False


def get_host_ip() -> Union[str, None]:
    """
    >>> result = get_host_ip()
    >>> assert is_valid_ip_adress(result)
    """
    o_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    # noinspection PyBroadException
    try:
        # doesn't even have to be reachable
        o_socket.connect(('1.1.1.1', 1))
        s_ip = str(o_socket.getsockname()[0])  # type: Union[str, None]
    except Exception:           # pragma: no cover
        s_ip = None             # pragma: no cover
    finally:
        o_socket.close()
    return s_ip


def is_internet_connected(ip_adress: str = '1.1.1.1') -> bool:
    """
    >>> is_internet_connected()
    True
    >>> is_internet_connected(ip_adress='www.un-kno-wn.com')
    False
    """
    response = lib_ping.ping(target=ip_adress, times=1)
    return bool(response.reached)


def is_valid_ip_adress(address: str) -> bool:
    """
    check if it is valid IPV4 or IPV6 Adress
    >>> is_valid_ip_adress('1.1.1.1')
    True
    >>> is_valid_ip_adress('::1')
    True
    >>> is_valid_ip_adress('unknown')
    False
    """
    if is_valid_ipv4_address(address) or is_valid_ipv6_address(address):
        return True
    else:
        return False


def is_valid_ipv4_address(address: str) -> bool:
    """
    >>> is_valid_ipv4_address('1.1.1.1')
    True
    >>> is_valid_ipv4_address('1.1.1.')
    False
    >>> is_valid_ipv4_address('unknown')
    False
    """
    try:
        socket.inet_pton(socket.AF_INET, address)
    except AttributeError:                      # pragma: no cover      # no inet_pton here, sorry
        try:                                    # pragma: no cover
            socket.inet_aton(address)           # pragma: no cover
        except socket.error:                    # pragma: no cover
            return False                        # pragma: no cover
        return address.count('.') == 3          # pragma: no cover
    except socket.error:                        # not a valid address
        return False

    return True


def is_valid_ipv6_address(address: str) -> bool:
    """
    >>> is_valid_ipv6_address('::1')
    True
    >>> is_valid_ipv6_address('127.0.0.1')
    False
    >>> is_valid_ipv6_address('unknown')
    False
    """
    try:
        socket.inet_pton(socket.AF_INET6, address)
    except socket.error:  # not a valid address
        return False
    return True
bitranox
  • 1,664
  • 13
  • 21
  • Oh It's totally wrong. It's not about localhost at all. What is the use of 127.0.0.1 to check for network connection?! – Ramin-RX7 Aug 24 '20 at 20:17
  • @RAMIN-RX7, if You ONLY have a loopback interface, You are not connected to the LAN ! So - You can not really determine if You are connected to a LAN, if You cant ping the default gateway, but You can check if You have a local IP Adress different from the loopback adress. If You DONT have an IP Adress on Your Host Adapter, for SURE You are NOT connected. – bitranox Aug 24 '20 at 20:23