import struct
import socket
import fcntl


def get_interface_IP(interface_name):
    """Retrieve IP address of the specified network interface.

    Args:
        interface_name (str): Name of the interace.

    Returns:
        str: Standard dotted-quad string representation of the IP address.
    """
    IFNAMSIZ = 16      # Maximum size of the interface name including zero character.
    SIOCGIFADDR = 0x8915  # IOCTL control code
    IFREQSIZ = 40      # sizeof(struct ifreq)

    # Pack interface name into ASCIIZ form while making sure
    # the interface name length is within the alowed range.
    interface_name_z = struct.pack("%ds" % IFREQSIZ, bytes(interface_name[:IFNAMSIZ-1], "utf-8"))

    # Open UDP socket.
    udpSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

    # Execute IOCTL.
    result = fcntl.ioctl(udpSock.fileno(), SIOCGIFADDR, interface_name_z)

    # Extract binary IP and convert to string.
    # The code below is an emulation of:
    #   (struct sockaddr_in *) &ifr.ifr_addr)->sin_addr
    bin_IP = result[20:24]
    return socket.inet_ntoa(bin_IP)