Как программно получить IP-адрес в системе на основе Debian?

Я пытаюсь получить IP Address локального компьютера в своей программе. Операционная система Ubuntu 8.10. Я пробовал использовать gethostname() и gethostbyname(), чтобы получить IP Address. Я получил ответ 127.0.1.1. Я узнал, что это похоже на Debian вещь: В указанном здесь документе объясняется идея.

Содержимое моего /etc/hosts файла:

127.0.0.1 локальный хост
127.0.1.1 mymachine

В этом случае, есть ли другой способ программным способом (предпочтительнее C или C ++) получить IP-адрес без изменения системного файла на машине?


person gc .    schedule 31.03.2009    source источник
comment
В одной системе может быть несколько локальных IP-адресов. Как узнать, какой именно вам нужен?   -  person Paul Tomblin    schedule 31.03.2009
comment
Спасибо, что напомнили мне, в конце концов, я понимаю, что мне нужно знать все.   -  person gc .    schedule 31.03.2009
comment
В любом случае gethostbyname - это старая процедура, специфичная для IPv4. Вы должны использовать getaddrinfo (но обратите внимание, что весь алгоритм ошибочен, потому что ничто не гарантирует, что разрешение имени даст вам реальный IP-адрес, DNS и / etc / hosts могут лгать ...)   -  person bortzmeyer    schedule 01.04.2009


Ответы (6)


См. "Netdevice" через man netdevice или в Интернете.
SIOCGIFCONF может затем использоваться для получения перечисления всех адресов транспортного уровня.

Изменить (на страницах руководства): man - очень полезная команда в Linux (или других UNIX-подобных системах). Он показывает краткое описание большинства команд, библиотечных функций, программ и т. Д. Откройте приглашение оболочки и введите man ls или man netdevice, и вы поймете, что я имею в виду.

Изменить (при общем получении IP-адреса): самый простой способ, если вы считаете, что способ C слишком запутан, - это простой сценарий оболочки, например (только из верхней части моей головы):
ifconfig|grep 'inet addr'|awk '{print $2}'|sed 's/addr://g'

Изменить (в решении для мозга): он использует if_nameindex () для поиска имен всех сетевых устройств, а затем SIOCFIFCONF ioctl для каждого из этих имен для определения их IP. По его словам, для каждого устройства указан только один IP-адрес.

person E Dominique    schedule 31.03.2009
comment
Вероятно, мне следует спросить Brain, но эта цепочка датируется прошлым годом, поэтому я все равно спрошу здесь, в каком случае у устройства может быть несколько IP-адресов? Может ли программа, размещенная здесь sigjuice, перечислить все эти IP-адреса? Я не видел устройства с несколькими IP-адресами, думаю, сам не могу его протестировать. - person gc .; 01.04.2009
comment
Нет, решение sigjuice такое же, как и решение Brain. Интерфейс может иметь несколько IP-адресов (например, некоторые интерфейсы WLAN не могут). Я бы сказал, что обычно не используется. Нужен ли вам пример, в котором можно их перечислить? Вы поиграли с текущими примерами? - person E Dominique; 01.04.2009
comment
Извините, что так долго не отвечал, зацепился за кое-что еще. Да, я пробовал примеры, и они работают. Если это не займет у вас слишком много времени, не могли бы вы привести мне пример, в котором можно перечислить все? - person gc .; 07.04.2009
comment
Что ж, похоже, я ошибался. В коде (sigjuice) перечислены все IP-адреса на всех машинах, на которых я его тестировал, поэтому, немного отполировав, вы можете использовать его. - person E Dominique; 07.04.2009
comment
Хорошо, еще раз спасибо. Думаю, я не заметил разницы при запуске программы, потому что у меня нет устройства с несколькими IP-адресами. - person gc .; 07.04.2009
comment
Привязка нескольких IP-адресов к устройству в Linux (они называют это `` IP-псевдонимом '') имеет интересный побочный эффект: IP-адреса не являются первоклассными гражданами, то есть основной IP-адрес устройства - это то, что используется, и любой IP-адрес, который совпадает с псевдонимом (а), просто отправляйтесь в путь. - person Avery Payne; 16.04.2009
comment
Вот почему вы, вероятно, видите только один IP-адрес для каждого интерфейса - я бы рискнул, что это настоящий IP-адрес, который привязан к устройству, а не псевдонимы. - person Avery Payne; 16.04.2009

Вот быстрый и грязный код, демонстрирующий SIOCGIFCONF:

#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int main()
{
    int sock, i;
    struct ifreq ifreqs[20];
    struct ifconf ic;

    ic.ifc_len = sizeof ifreqs;
    ic.ifc_req = ifreqs;

    sock = socket(AF_INET, SOCK_DGRAM, 0);
    if (sock < 0) {
        perror("socket");
        exit(1);
    }

    if (ioctl(sock, SIOCGIFCONF, &ic) < 0) {
        perror("SIOCGIFCONF");
        exit(1);
    }

    for (i = 0; i < ic.ifc_len/sizeof(struct ifreq); ++i)
        printf("%s: %s\n", ifreqs[i].ifr_name,
                inet_ntoa(((struct sockaddr_in*)&ifreqs[i].ifr_addr)->sin_addr));

    return 0;
}

На моем компьютере с Linux я получаю следующий результат.

lo: 127.0.0.1
br0: 192.168.0.42
dummy1: 10.0.0.2
person sigjuice    schedule 31.03.2009

Итак, по мнению Кена:

ip addr show scope global | grep inet | cut -d' ' -f6 | cut -d/ -f1

Жалко, что когда боги Debian создали команду «ip», они не подумали добавить простую команду для получения только IP-адреса.

person Martin Cleaver    schedule 23.04.2011

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

person sigjuice    schedule 31.03.2009

Всем спасибо за акции!

Для решения bash это то, что я в итоге выбрал:

#!/bin/bash

/sbin/ifconfig|fgrep 'inet addr:'|fgrep -v '127'|cut -d: -f2|awk '{print $1}'|head -n1

Головка гарантирует, что будет возвращен основной IP-адрес, так как многодомные и / или логические интерфейсы также будут возвращены без головы.

Итак, если скрипт находится в / sbin / get_primary_ip, вы можете делать что-то вроде:

foo=$(get_primary_ip)
person Kyle    schedule 28.10.2010

ifconfig устарел и устарел. iproute2 - это новый стек, используйте команду ip:

ip addr и выполните синтаксический анализ оттуда.

person ken    schedule 23.04.2011