Вопрос по c, ip-address, posix, sockets – Как перечислить все IP-адреса, подключенные к машине, в POSIX C?
==========================================================================================================

**Background:**

Я пишу демон, который устанавливает исходящие соединения TCP / IP. Он будет работать на компьютерах с несколькими (не зацикленными) IP-адресами. Я хотел бы, чтобы пользователи могли указать в файле конфигурации демона, какой IP-адрес (а) использовать для исходящих соединений, или`*` использовать все.

Адреса будут использоваться по очереди, каждое соединение выходит из IP-адреса, который использовался не так давно. Это поведение важно, так как`*` быть заменой для "всех" таким образом, демоны, работающие на нескольких машинах, могут указывать на один и тот же файл конфигурации на файловом ресурсе, и каждый из них использует свой собственный набор IP-адресов.

**Problem:**

Как получить список всех IP-адресов, на которых машина может устанавливать исходящие (то есть на любой другой компьютер) соединения? Учитывая список всех IP-адресов, как бы я отфильтровал петлевые адреса?

Я нахожусь в Си, и, если возможно, я хотел бы использовать только POSIX, но демон, вероятно, будет работать только на Linux-блоках, поэтому я принимаю Linux-ориентированный ответ.

Каждый IP-адрес будет доступен только на одном (возможно, виртуальном) сетевом устройстве, и наоборот, поэтому достаточно было бы перечислить сетевые устройства и получить связанные IP-адреса, хотя мне бы это не очень понравилось. (Дополнительные вопросы: возможно ли даже связать несколько IP-адресов с одним устройством? Как «один и тот же IP-адрес на нескольких устройствах? Не важно.)

**Insufficient Solutions:**

`gethostname()`/`gethostbyname()` (as [this question](https://stackoverflow.com/questions/122208/get-the-ip-address-of-local-computer)). Using that method, I only ever get 127.0.0.1 back (or .1.1 in Debian). I suspect this is because the hostname of the machine is in the `hosts` file, and that's as far as `gethostbyname()` checks. (I believe that's why in Debian I always get 127.0.1.1: Debian defaults to adding localhost as 127.0.0.1 and the machine's hostname as 127.0.1.1 to the `hosts` file, right?) I'd like a solution that ignores `hosts` and gives me everything actually there.
I've had no more luck with `getaddrinfo()` than `gethostname()`/`gethostbyname()`. It seems to be bound by the same problem. I tested this passing the machine's hostname and a `NULL` service (port) into it; the docs say passing a `NULL` hostname AND a `NULL` service is illegal, and this is backed up by testing. Not sure how else to ask it for everything on the machine, but I'm open to suggestions in this vein.
EDIT: [this answer](https://stackoverflow.com/questions/259389/finding-an-ip-from-an-interface-name/259424#259424) shows how to get the IP address from a device name, but doesn't show how to enumerate the device names. Any ideas?
ОКОНЧАТЕЛЬНОЕ РЕДАКТИРОВАНИЕ: Я принят[ответ Кэски](https://stackoverflow.com/questions/1160963/how-to-enumerate-all-ip-addresses-attached-to-a-machine-in-posix-c/1161018#1161018) чтобы отдать ему должное за указание на то, как это нужно сделать. Я разместил свой[собственный ответ](https://stackoverflow.com/questions/1160963/how-to-enumerate-all-ip-addresses-attached-to-a-machine-in-posix-c/1162010#1162010) перечисление исходного кода того, как именно это сделать, если кому-то еще это нужно.

Adding multiple IPs to a device can be done with aliasing. Linux creates devices named like eth0:0 when you do this.

`ifconfig eth0:0 10.0.0.1`

Having the same IP under multiple devices can be done with channel bonding/link aggregation.



**How do I get a list of all the IP addresses a machine can make outgoing (i.e. to any other computer) connections on? Given a list of all IP addresses, how would I filter out loopback addresses?**

Посмотрите на исходный код**lsof** а также**netstat**, Вы увидите, что это включает в себя обход структур памяти ядра, а не просто выполнение системных вызовов.



 что используете gethostname () / gethostbyname () правильно? проверять, выписываться[Вот](http://windows-programming.suite101.com/article.cfm/socket_programming_gethostbyname)единственная проблема, которую я вижу при этом, состоит в том, что возможно, что доменное имя имеет несколько сопоставленных IP-адресов. Если это так, то нет никакого способа узнать, какой IP-адрес принадлежит локальной машине.



ы можете попытаться проанализировать вывод «iptables», ноright Ответ для Linux заключается в использовании ioctl.

Структура ifreq описана в linux / if.h:

Как видите, он содержит информацию об адресе, которую вы хотите.



[принятый ответ Caskey](https://stackoverflow.com/questions/1160963/how-to-enumerate-all-ip-addresses-attached-to-a-machine-in-posix-c/1161018#1161018)ради потомков:

Работает как шарм!



 требуемую несколькими способами, включая вызов ioctl () с опцией SIOCGIFCONF и цикл по возвращаемым структурам для получения информации об адресе интерфейса.

Given a list of all IP addresses, how would I filter out loopback addresses?

См. Структуру ifreq в ответе caskey. Вы можете определить петлю (правильно) с помощью:

Константы в if.h