Получить самый последний глобальный IPv6-адрес интерфейса - PullRequest
0 голосов
/ 29 августа 2018

Я пытаюсь получить текущий публичный IPv6-адрес интерфейса в Python. При поиске я обнаружил пакет netifaces, который может дать мне список всех ipv6-адресов устройства.

Это будет включать

  • адрес локальной ссылки (который я мог бы отфильтровать простым взломом, что не очень хорошо, но хорошо ...)
  • несколько глобальных адресов ipv6, один из которых является текущим

Теперь, что я имею в виду под током? Через расширения конфиденциальности (RFC 4941) новый адрес назначается интерфейсу через равные промежутки времени. Старые глобальные адреса ipv6 все еще действительны, но помечены как устаревшие. Я хочу этот самый последний.

Вот что я попробовал (запутанные части адресов по соображениям безопасности):

>>> import netifaces 
>>> addrs = netifaces.ifaddresses('en0')
>>> for i in addrs[netifaces.AF_INET6]:
...     print(i)
...
{'addr': 'fe80::caa:452a:b8cb:862e%en0', 'netmask': 'ffff:ffff:ffff:ffff::/64', 'flags': 1024}
{'addr': '2a02:____:____:9f1:cd8:e__e:e57b:eaa8', 'netmask': 'ffff:ffff:ffff:ffff::/64', 'flags': 1088}
{'addr': '2a02:____:____:9f1:3489:b__7:fb34:101', 'netmask': 'ffff:ffff:ffff:ffff::/64', 'flags': 192}

Очевидно, что первым является адрес локальной ссылки. Второй и третий глобальные, и у них есть флаг, о котором я понятия не имею, что он означает.

Есть ли способ (возможно, с помощью флага или другого метода в python) выяснить текущий (временный, не устаревший) глобальный адрес?

В Linux я знаю, что могу анализировать вывод ip -o -6 addr show dev interface и анализировать этот вывод, но это не сработает, например. на Mac, и анализ выходных данных других инструментов - это то, что мне не нравится, если для него есть пакет python.

EDIT: Флаги, похоже, присутствуют не на каждой ОС. Выход выше был на Mac. Вот вывод на Linux-машине в той же сети (гораздо больше времени безотказной работы):

{'addr': '2a02:____:____:9f1:940c:f__f:f9c0:c274', 'netmask': 'ffff:ffff:ffff:ffff::/64'}
{'addr': '2a02:____:____:9f1:395a:6__d:650a:3a11', 'netmask': 'ffff:ffff:ffff:ffff::/64'}
{'addr': '2a02:____:____:9f1:d08a:6__d:d967:d28a', 'netmask': 'ffff:ffff:ffff:ffff::/64'}
{'addr': '2a02:____:____:9f1:9d20:b__7:3edc:96a4', 'netmask': 'ffff:ffff:ffff:ffff::/64'}
{'addr': '2a02:____:____:9f1:b584:d__b:16bf:5dd2', 'netmask': 'ffff:ffff:ffff:ffff::/64'}
{'addr': '2a02:____:____:9f1:61ba:d__b:78d8:197f', 'netmask': 'ffff:ffff:ffff:ffff::/64'}
{'addr': '2a02:____:____:9f1:c1df:7__7:236d:4219', 'netmask': 'ffff:ffff:ffff:ffff::/64'}
{'addr': '2a02:____:____:9f1:d021:4__3:1a44:4947', 'netmask': 'ffff:ffff:ffff:ffff::/64'}
{'addr': 'fe80::17ed:fbf5:a707:2a42%enp4s0', 'netmask': 'ffff:ffff:ffff:ffff::/64'}

РЕДАКТИРОВАТЬ 2:

Поскольку возникла путаница в том, что я имею в виду под «текущими» адресами, вот что я имею ввиду. На машине Linux предыдущего примера:

% ip -o -6 addr show dev enp4s0
2: enp4s0    inet6 2a02:____:____:9f1:940c:f__f:f9c0:c274/64 scope global temporary dynamic \       valid_lft 530760sec preferred_lft 12247sec
2: enp4s0    inet6 2a02:____:____:9f1:395a:6__d:650a:3a11/64 scope global temporary deprecated dynamic \       valid_lft 444473sec preferred_lft 0sec
2: enp4s0    inet6 2a02:____:____:9f1:d08a:6__d:d967:d28a/64 scope global temporary deprecated dynamic \       valid_lft 358187sec preferred_lft 0sec
2: enp4s0    inet6 2a02:____:____:9f1:9d20:b__7:3edc:96a4/64 scope global temporary deprecated dynamic \       valid_lft 271901sec preferred_lft 0sec
2: enp4s0    inet6 2a02:____:____:9f1:b584:d__b:16bf:5dd2/64 scope global temporary deprecated dynamic \       valid_lft 185616sec preferred_lft 0sec
2: enp4s0    inet6 2a02:____:____:9f1:61ba:d__b:78d8:197f/64 scope global temporary deprecated dynamic \       valid_lft 99330sec preferred_lft 0sec
2: enp4s0    inet6 2a02:____:____:9f1:c1df:7__7:236d:4219/64 scope global temporary deprecated dynamic \       valid_lft 13044sec preferred_lft 0sec
2: enp4s0    inet6 2a02:____:____:9f1:d021:4__3:1a44:4947/64 scope global dynamic mngtmpaddr noprefixroute \       valid_lft 2591735sec preferred_lft 604535sec
2: enp4s0    inet6 fe80::17ed:fbf5:a707:2a42/64 scope link noprefixroute \       valid_lft forever preferred_lft forever

Очевидно, что все «временные» адреса являются действительными адресами. Но только один не помечен как устаревший. Этот адрес будет использоваться для исходящих соединений. И это тот, который я хочу.

1 Ответ

0 голосов
socket.getaddrinfo(socket.gethostname(), None, socket.AF_INET6)
socket.getaddrinfo(socket.gethostname(), None, socket.AF_INET6)[0][4][0]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...