def get_interface_ip(sock: socket.socket, ifname: str) -> str:
"""Obtain an IP address for a network interface, as a string."""
ifreq_tuple = (ifname.encode('utf-8')[:15], socket.AF_INET, b'\x00' * 14)
ifreq = struct.pack(b'16sH14s', *ifreq_tuple)
try:
info = fcntl.ioctl(sock, SIOCGIFADDR, ifreq)
except OSError as e:
if e.errno == errno.ENODEV:
raise InterfaceNotFound(
"Interface not found: '%s'." % ifname)
elif e.errno == errno.EADDRNOTAVAIL:
raise IPAddressNotAvailable(
"No IP address found on interface '%s'." % ifname)
else:
raise IPAddressNotAvailable(
"Failed to get IP address for '%s': %s." % (
ifname, strerror(e.errno)))
else:
# Parse the `struct ifreq` that comes back from the ioctl() call.
# 16x --> char ifr_name[IFNAMSIZ];
# ... next is a union of structures; we're interested in the
# `sockaddr_in` that is returned from this particular ioctl().
# 2x --> short sin_family;
# 2x --> unsigned short sin_port;
# 4s --> struct in_addr sin_addr;
# 8x --> char sin_zero[8];
addr, = struct.unpack(b'16x2x2x4s8x', info)
ip = socket.inet_ntoa(addr)
return ip
评论列表
文章目录