3
\$\begingroup\$

I am trying to extract the ip address of my machine when connected to multiple wireless networks. The motivation here is then I can make a socket connection on that ip when I have two networks that have the same default gateway. I am hoping that there is either a way to greatly improve the code or replace it with some functionality that does what I am doing in a more robust cleaner way. In particular, the part that worries me most is using the MAX_OFFSET to ensure that the code does not return the next ip address.

import os
import subprocess

if os.name == "nt":
    WIRELESS_ADAPTER0 = b"Wi-Fi:"
    WIRELESS_ADAPTER1 = b"Wi-Fi 2"
    COMMAND = "ipconfig"
    IPV4_LINE = b"IPv4"
    IPV6_LINE = b"IPv6"
    IP_INDEX = -1
    MAX_OFFSET = 5

else:
    WIRELESS_ADAPTER0 = b"wlan0"
    WIRELESS_ADAPTER1 = b"wlan1"
    COMMAND = "ifconfig"
    IPV4_LINE = b"inet"
    IPV6_LINE = b"inet6"
    IP_INDEX = 1
    MAX_OFFSET = 7


def get_ip(all_lines, start_index):
    try:
        search_lines = list(filter(lambda x: (IPV4_LINE in x) or (IPV6_LINE in x), all_lines[start_index:start_index+MAX_OFFSET]))
        return search_lines[0].split()[IP_INDEX]
    except IndexError:
        pass

all_lines = subprocess.check_output(COMMAND).split(b"\n")
for i in range(len(all_lines)):
    if WIRELESS_ADAPTER0 in all_lines[i]:
        ip0 = get_ip(all_lines, i)
    if WIRELESS_ADAPTER1 in all_lines[i]:
        ip1 = get_ip(all_lines, i)

I have included some sample output from ipconfig below:

    Wireless LAN adapter Wi-Fi 2:

       Media State . . . . . . . . . . . : Media disconnected
       Connection-specific DNS Suffix  . : lan

    Ethernet adapter Ethernet 5:

       Connection-specific DNS Suffix  . : enceptacorp.local
       Link-local IPv6 Address . . . . . : fe80::80f0:901c:f4d3:1c6%5
       IPv4 Address. . . . . . . . . . . : 192.168.128.226
       Subnet Mask . . . . . . . . . . . : 255.255.255.0
       Default Gateway . . . . . . . . . : 192.168.128.1

The reason I use MAX_OFFSET is to make sure that I don't get the next ip address down (i.e. the IP for Ethernet 5, when Wi-Fi 2 is disconnected). I have also noticed that sometimes when first connecting to the router, I won't get assigned an IPv4 Address right away, and that is why I have included IPv4 and IPv6. If anyone can comment on whether I will always get an IPv6 address (and thus can ignore IPv4), that would be useful to know. Is there a better way to get the IP address of a particular network interface? Or even just a command like ipconfig that returns more concise/consistent/cleaner output?

\$\endgroup\$
  • \$\begingroup\$ Which operating systems do you expect your code to work on? \$\endgroup\$ – 200_success Apr 23 at 23:00
  • \$\begingroup\$ Windows 10 and Linux. Specifically, I will be running it on a Windows laptop and a raspberry pi running posix. I have tested it on both and it seems to work for now. \$\endgroup\$ – Albert Rothman Apr 23 at 23:07
  • \$\begingroup\$ I'm not convinced that it will work on Linux. The second line of ifconfig output for each interface is ` inet addr:1.2.3.4 Bcast:1.2.3.255 Mask:255.255.255.0. So, it would get addr:1.2.3.4` as the IP address. \$\endgroup\$ – 200_success Apr 23 at 23:09
  • \$\begingroup\$ Hmm, I have inet 192.168.128.105 netmask 255.255.255.0 broadcast 192.168.128.255, no addr \$\endgroup\$ – Albert Rothman Apr 23 at 23:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.