ipaddress address python python-3.x pyqt ip-address

ipaddress - python get ip address



Cómo obtener la dirección IP de la interfaz física desde una interfaz (3)

Lo que he hecho hasta ahora, usando clases de PyQt:

all_Addresses = QNetworkInterface.allAddresses() #list-of-QHostAddress for addr in all_Addresses: print(addr.toString())

Salida:

172.16.0.186 - Virtual Interface IP address 192.168.10.2 - Physical interface IP address. I want this one. 127.0.0.1

Utilizando socket

import socket print(socket.gethostbyname(socket.gethostname()))

Salida:

172.16.0.186 - When openVPN is on 192.168.10.2 - When its off

  1. ¿Hay alguna forma de distinguirlos?
  2. ¿Se puede hacer esto con Python ordinario, en lugar de usar clases de PyQt?
  3. ¿Cómo puedo obtener la dirección IPv6 también?

Usted debe utilizar los netifaces . Está diseñado para ser multiplataforma y contiene código especializado para Windows junto con una variedad de versiones genéricas que funcionan en diferentes plataformas similares a UNIX / UNIX.

A partir de la versión 0.10.0 de Netifaces, Python3 es compatible.

Resumen de uso

>>> from netifaces import AF_INET, AF_INET6, AF_LINK, AF_PACKET, AF_BRIDGE >>> import netifaces as ni >>> ni.interfaces() [''lo'', ''eth0'', ''eth1'', ''vboxnet0'', ''dummy1''] >>> >>> ni.ifaddresses(''eth0'')[AF_LINK] # NOTE: AF_LINK is an alias for AF_PACKET [{''broadcast'': ''ff:ff:ff:ff:ff:ff'', ''addr'': ''00:02:55:7b:b2:f6''}] >>> ni.ifaddresses(''eth0'')[AF_INET] [{''broadcast'': ''172.16.161.7'', ''netmask'': ''255.255.255.248'', ''addr'': ''172.16.161.6''}] >>> >>> # eth0 ipv4 interface address >>> ni.ifaddresses(''eth0'')[AF_INET][0][''addr''] ''172.16.161.6'' >>>>

Detalles

Soporte de Windows:

No se requiere compilador para la mayoría de las instalaciones de MS Windows. Si recibe advertencias sobre la instalación de MS Visual C ++ para Windows, tenga mucho cuidado, ya que debe hacer coincidir la versión del compilador que usó Python con la que usó para el módulo.

Ejemplo detallado de estructuras de datos de netifaces :

>>> import netifaces as ni >>> ni.interfaces() [''lo'', ''eth0'', ''eth1'', ''vboxnet0'', ''dummy1''] >>> ni.ifaddresses(''eth0'') { 17: [ { ''broadcast'': ''ff:ff:ff:ff:ff:ff'', ''addr'': ''00:02:55:7b:b2:f6'' } ], 2: [ { ''broadcast'': ''172.16.161.7'', ''netmask'': ''255.255.255.248'', ''addr'': ''172.16.161.6'' } ], 10: [ { ''netmask'': ''ffff:ffff:ffff:ffff::'', ''addr'': ''fe80::202:55ff:fe7b:b2f6%eth0'' } ] } >>> >>> print(ni.ifaddresses.__doc__) Obtain information about the specified network interface. Returns a dict whose keys are equal to the address family constants, e.g. netifaces.AF_INET, and whose values are a list of addresses in that family that are attached to the network interface. >>> >>> # for the IPv4 address of eth0 >>> ni.ifaddresses(''eth0'')[2][0][''addr''] ''172.16.161.6''

Los números utilizados para indexar protocolos son de /usr/include/linux/socket.h (en Linux) ... EDITAR : mi kernel 3.2 los tiene aquí: /usr/src/linux-headers-3.2.0-4-common/include/linux/socket.h

#define AF_INET 2 /* Internet IP Protocol */ #define AF_INET6 10 /* IP version 6 */ #define AF_PACKET 17 /* Packet family */

La buena noticia es que no tiene que recordar todas esas constantes de encabezado, se incluyen con los netifaces en netifaces :

>>> from netifaces import AF_INET, AF_INET6, AF_LINK, AF_PACKET, AF_BRIDGE >>> import netifaces as ni


Utiliza el ioctl SIOCGIFADDR de Linux para encontrar la dirección IP asociada con una interfaz de red, dado el nombre de esa interfaz, por ejemplo, " eth0 ". La dirección se devuelve como una cadena que contiene un quad punteado.

import socket import fcntl import struct def get_ip_address(ifname): s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) return socket.inet_ntoa(fcntl.ioctl( s.fileno(), 0x8915, # SIOCGIFADDR struct.pack(''256s'', ifname[:15]) )[20:24]) >>> get_ip_address(''lo'') ''127.0.0.1'' >>> get_ip_address(''eth0'') ''38.113.228.130''

Para más


Yo uso esta solución. En realidad, es un poco complicado y solo funciona en la familia Linux.

import commands intf = ''eth0'' intf_ip = commands.getoutput("ip address show dev " + intf).split() intf_ip = intf_ip[intf_ip.index(''inet'') + 1].split(''/'')[0] print intf_ip

Esos códigos utilizan el comando ip en el sistema operativo de la familia linux. Dividió la salida del comando ip y solo tomó la dirección IPv4 de esas interfaces. Puede cambiar el valor intf a eth1 o p2p1 .