Есть несколько подходов;во-первых, вы можете установить соединение с известным узлом, используя connect(2)
, а затем прочитать имя локального сокета с помощью getsockname(2)
.Это довольно слабый механизм, но он прост.
Но getsockname(2)
будет сообщать только один IP-адрес, когда у машины может быть тысячи IP-адресов и какой IP-адресВозвращение будет зависеть отчасти от выбранного вами партнера!Итак, не очень надежный.
Гораздо лучший ответ - использовать rtnetlink(7)
для считывания IP-адресов машины непосредственно из ядра: вы бы отправляли в ядро сообщения RTM_GETADDR
для каждого интерфейса намашинка и читай ответы обратно.Лучше всего понять, как использовать это, вероятно, прочитав исходный код программы ip
.
Другой вариант - использовать SIOCGIFCONF
ioctl(2)
на сокете IP.Этот интерфейс не такой гибкий, как интерфейс rtnetlink(7)
, поэтому он не всегда может быть правильным, но это будет промежуточная точка.Утилита ifconfig(8)
использует этот подход для отображения вывода ifconfig -a
.Опять же, вам лучше всего прочитать исходный текст.(Есть небольшая документация в ioctl_list(2)
.)