2013-12-23 2 views
8

Я пытаюсь получить IPv6-адрес в моей ОС Linux как следующее:Получить адреса IPv6 в Linux с помощью IOCTL

sd = Socket_m(AF_INET6_m, SOCK_DGRAM_m, 0); 

ifc.ifc_buf = buffer_p; 
ifc.ifc_len = buffSize; 
Ioctl_m(sd, SIOCGIFCONF, &ifc); 

Он работает успешно, если какой-либо адрес IPv4 настроен на интерфейс, но если интерфейс имеет только один адрес IPv6 ioctl не возвращается.

Например, я не смог получить IPv6-адрес интерфейса followith, потому что только IPv6-адрес настраивается:

br1  Link encap:Ethernet HWaddr 00:10:18:2D:BB:34 
      inet6 addr: fe80::210:18ff:fe2d:be54/64 Scope:Link 
      UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 
      RX packets:194244850 errors:0 dropped:0 overruns:0 frame:0 
      TX packets:72005 errors:0 dropped:0 overruns:0 carrier:0 
      collisions:0 txqueuelen:0 
      RX bytes:12331900995 (11760.6 Mb) TX bytes:6192406 (5.9 Mb) 

ответ

12

Да, этот ioctl является устаревшим и не будет возвращать IPv6. Каждая платформа имеет другой способ получить те IPv6:

  • Linux, использовать NETLINK, если вы с ума, используйте getifaddrs, если у вас есть неопределенно недавнюю glibc, в противном случае прочитать /proc/net/if_inet6 (например, на Android).
  • Darwin или FreeBSD: используйте getifaddrs.
  • Solaris, используйте SIOCGLIFCONF.
  • AIX, используйте SIOCGIFCONF, который фактически возвращает адреса IPv4 и IPv6 (поскольку они имеют поле sa_len в struct sockaddr, они могут фактически поддерживать это).
+0

Большое спасибо за разъяснение, не могли бы вы помочь мне с пониманием формата «/ proc/net/if_inet6», как я могу определить адреса UP и non-loopback? Я читал http://www.tldp.org/HOWTO/Linux+IPv6-HOWTO/proc-net.html, но это не ясно. –

+0

Документы довольно понятны - это «флаги интерфейса», которые вы используете. См. Значения в заголовках системы («if.h») для 'IFF_LOOPBACK' и' IFF_UP'. Если вы пытаетесь разобрать if_inet6 с помощью оболочки, вы можете извлечь правое поле с помощью awk и AND с соответствующей константой с помощью '&'. –

3

Это, вероятно, не будет работать.

От man 7 netdevice:

SIOCGIFCONF

Возвращает список интерфейсов (транспортного уровня) адресов. В настоящее время это означает только адреса семейства AF_INET (IPv4) для обеспечения совместимости.

[...]

ПРИМЕЧАНИЯ

[...]

Локальный IPv6 IP-адреса могут быть найдены через/Proc/сети или через rtnetlink (7).

+0

Я не могу использовать разъемы маршрутизации, предложенные Николасом Уилсоном, мне нужен способ, совместимый с LSB, но это не возможно? –

+0

@Unmanner: Если вам нужно знать адрес, к которому привязан сокет, локально использовать 'getsockname()'. Если вам нужно найти адреса всех локальных интерфейсов, используйте 'getifaddrs()' или зачитайте '/ proc/net/if_inet6', как было предложено * Николасом Уилсоном * в его ответе. – alk

Смежные вопросы