get_interface_by_ip.py 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. #!/usr/bin/env python3
  2. import array
  3. import fcntl
  4. import socket
  5. import struct
  6. import sys
  7. def format_ip(addr):
  8. return str(addr[0]) + '.' + \
  9. str(addr[1]) + '.' + \
  10. str(addr[2]) + '.' + \
  11. str(addr[3])
  12. def all_interfaces():
  13. max_possible = 128 # arbitrary. raise if needed.
  14. bytes = max_possible * 32
  15. s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  16. names = array.array('B', b'\0' * bytes)
  17. outbytes = struct.unpack('iL', fcntl.ioctl(
  18. s.fileno(),
  19. 0x8912, # SIOCGIFCONF
  20. struct.pack('iL', bytes, names.buffer_info()[0])
  21. ))[0]
  22. if hasattr(names, 'tobytes'):
  23. namestr = names.tobytes()
  24. elif hasattr(names, 'tostring'):
  25. namestr = names.tostring()
  26. else:
  27. raise Exception("can not convert names to string")
  28. lst = []
  29. for i in range(0, outbytes, 40):
  30. name = namestr[i:i+16].split(b'\0', 1)[0].decode('utf-8')
  31. ip = format_ip(struct.unpack('BBBB', namestr[i+20:i+24]))
  32. lst.append((name, ip))
  33. # 读取 /proc/net/if_inet6 获取 IPv6 地址
  34. try:
  35. with open('/proc/net/if_inet6', 'r') as f:
  36. for line in f:
  37. parts = line.strip().split()
  38. if len(parts) != 6:
  39. continue
  40. raw_addr, idx, plen, scope, flags, ifname = parts
  41. # 格式化 IPv6 地址
  42. ipv6_addr = ':'.join([raw_addr[i:i+4] for i in range(0, 32, 4)])
  43. ipv6_addr = socket.inet_ntop(socket.AF_INET6, bytearray.fromhex(raw_addr))
  44. # 过滤掉 ::1 和 fe80::/10
  45. if ipv6_addr == '::1' or ipv6_addr.startswith('fe80'):
  46. continue
  47. lst.append((ifname, ipv6_addr))
  48. except Exception as e:
  49. print(f"get ipv6error: {e}")
  50. pass
  51. return lst
  52. ifs = all_interfaces()
  53. def get_interface_by_ip(ip):
  54. if not ip:
  55. raise Exception("[get_interface_by_ip] empty ip")
  56. for i in ifs:
  57. if ip == i[1]:
  58. return i[0]
  59. raise Exception("Not found interface name for ip <%s>" % ip)
  60. def main():
  61. ip = sys.argv[1]
  62. print(get_interface_by_ip(ip))
  63. if __name__ == "__main__":
  64. main()