Wie bekomme ich die IP-Adresse eines (Linux-)Rechners?

Lesezeit: 12 Minuten

Wie bekomme ich die IP Adresse eines Linux Rechners
BlaM

Diese Frage ist fast die gleiche wie die zuvor gestellte Wie erhalte ich die IP-Adresse eines lokalen Computers? -Frage. Allerdings muss ich die IP-Adresse(n) von a finden Linux-Maschine.

Also: Wie kann ich – programmgesteuert in C++ – Ermitteln Sie die IP-Adressen des Linux-Servers, auf dem meine Anwendung ausgeführt wird. Die Server haben mindestens zwei IP-Adressen und ich brauche eine bestimmte (die in einem bestimmten Netzwerk (die öffentliche)).

Ich bin mir sicher, dass es dafür eine einfache Funktion gibt – aber wo?


Um die Sache etwas klarer zu machen:

  • Der Server wird offensichtlich den „localhost“ haben: 127.0.0.1
  • Der Server hat eine interne (Verwaltungs-)IP-Adresse: 172.16.xx
  • Der Server hat eine externe (öffentliche) IP-Adresse: 80.190.xx

Ich muss die externe IP-Adresse finden, um meine Anwendung daran zu binden. Natürlich kann ich auch an INADDR_ANY binden (und das mache ich im Moment auch). Ich würde es jedoch vorziehen, die öffentliche Adresse zu erkennen.

  • Warum den Popen von ifconfig notieren? Es ist wirklich das Richtige. Bibliotheken ändern sich, aber ifconfig und popen werden immer da sein.

    – Erik Aronesty

    18. Mai 2011 um 13:40 Uhr

  • Nein, ifconfig, route usw. sind für die veraltet ip Befehl. Jetzt sollten Sie das stattdessen verwenden.

    – Anders

    12. September 2014 um 22:58 Uhr

  • ifconfig funktioniert auch heute noch auf mehr Architekturen als jeder andere Ansatz. Ändern Sie es also in das ip-Kommando, wenn/falls angemessen. popen ist immer noch die bessere lösung.

    – Erik Aronesty

    13. September 2016 um 12:54 Uhr

1646893212 427 Wie bekomme ich die IP Adresse eines Linux Rechners
Zwölf47

Ich fand die ioctl-Lösung unter OS X problematisch (das POSIX-kompatibel ist und daher Linux ähneln sollte). Mit getifaddress() können Sie jedoch dasselbe einfach tun. Es funktioniert für mich unter OS x 10.5 einwandfrei und sollte unten dasselbe sein.

Ich habe unten ein kurzes Beispiel erstellt, das die gesamte IPv4-Adresse des Computers druckt (Sie sollten auch überprüfen, ob getifaddrs erfolgreich war, dh 0 zurückgibt).

Ich habe es aktualisiert und zeigt auch IPv6-Adressen an.

#include <stdio.h>      
#include <sys/types.h>
#include <ifaddrs.h>
#include <netinet/in.h> 
#include <string.h> 
#include <arpa/inet.h>

int main (int argc, const char * argv[]) {
    struct ifaddrs * ifAddrStruct=NULL;
    struct ifaddrs * ifa=NULL;
    void * tmpAddrPtr=NULL;

    getifaddrs(&ifAddrStruct);

    for (ifa = ifAddrStruct; ifa != NULL; ifa = ifa->ifa_next) {
        if (!ifa->ifa_addr) {
            continue;
        }
        if (ifa->ifa_addr->sa_family == AF_INET) { // check it is IP4
            // is a valid IP4 Address
            tmpAddrPtr=&((struct sockaddr_in *)ifa->ifa_addr)->sin_addr;
            char addressBuffer[INET_ADDRSTRLEN];
            inet_ntop(AF_INET, tmpAddrPtr, addressBuffer, INET_ADDRSTRLEN);
            printf("%s IP Address %s\n", ifa->ifa_name, addressBuffer); 
        } else if (ifa->ifa_addr->sa_family == AF_INET6) { // check it is IP6
            // is a valid IP6 Address
            tmpAddrPtr=&((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr;
            char addressBuffer[INET6_ADDRSTRLEN];
            inet_ntop(AF_INET6, tmpAddrPtr, addressBuffer, INET6_ADDRSTRLEN);
            printf("%s IP Address %s\n", ifa->ifa_name, addressBuffer); 
        } 
    }
    if (ifAddrStruct!=NULL) freeifaddrs(ifAddrStruct);
    return 0;
}

  • +1 und danke, dass du diesen netten Ansatz anstelle dieser langweiligen ioctl’s gebracht hast! Ihr Umgang mit IP6 ist jedoch immer noch falsch – Sie sollten in sockaddr_in6 umwandeln, dh so etwas wie tmpAddrPtr=&((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr;

    – Andrej

    14. Oktober 2011 um 10:04 Uhr

  • @Andrey, danke. Ich habe meine Antwort aktualisiert (hatte jedoch keine Gelegenheit, sie zu testen)

    – Zwölf47

    17. Oktober 2011 um 11:14 Uhr

  • gibt lo und wlan0 Schnittstellen in meinem Fall. Was ich benötige ist wlan0 oder eth0 die Internetverbindung hat. Also, sollte ich verwenden strcmp oder gibt es einen besseren Weg?

    – Sudip Bhattarai

    27. Februar 2016 um 7:14 Uhr


Wie bekomme ich die IP Adresse eines Linux Rechners
Steve Baker

  1. Erstellen Sie eine Steckdose.
  2. Ausführen ioctl(<socketfd>, SIOCGIFCONF, (struct ifconf)&buffer);

Lesen /usr/include/linux/if.h für Informationen über die ifconf und ifreq Strukturen. Dies sollte Ihnen die IP-Adresse jeder Schnittstelle im System geben. Lesen Sie auch /usr/include/linux/sockios.h für zusätzliche ioctls.

  • Ich hatte den Eindruck, dass es Ihnen nur die Adresse der Schnittstelle gibt, an die es bindet.

    – Matt Tischler

    12. März 2011 um 7:06 Uhr

  • @MattJoiner Nein, schau dir die Manpage an, SIOCGIFCONF gibt Informationen zu allen Schnittstellen zurück. Teil der hier zitierten Manpage: “Return a list of interface (transport layer) address. Dies bedeutet derzeit nur Adressen der AF_INET (IPv4)-Familie aus Kompatibilitätsgründen. Der Benutzer übergibt eine ifconf-Struktur als Argument an ioctl. Sie enthält a Zeiger auf ein Array von ifreq-Strukturen in ifc_req und seine Länge in Bytes in ifc_len. Der Kernel füllt die ifreqs mit allen aktuellen L3-Schnittstellenadressen, die ausgeführt werden.

    – Stefan

    26. März 2017 um 0:44 Uhr

1646893213 353 Wie bekomme ich die IP Adresse eines Linux Rechners
4dan

Ich mag jjvainios Antwort. Wie Zan Lnyx sagt, verwendet es die lokale Routing-Tabelle, um die IP-Adresse der Ethernet-Schnittstelle zu finden, die für eine Verbindung zu einem bestimmten externen Host verwendet würde. Wenn Sie einen verbundenen UDP-Socket verwenden, können Sie die Informationen abrufen, ohne tatsächlich Pakete zu senden. Der Ansatz erfordert, dass Sie einen bestimmten externen Host auswählen. Meistens sollte jede bekannte öffentliche IP ausreichen. Ich mag für diesen Zweck die öffentliche DNS-Serveradresse 8.8.8.8 von Google, aber es kann vorkommen, dass Sie eine andere externe Host-IP wählen möchten. Hier ist ein Code, der den vollständigen Ansatz veranschaulicht.

void GetPrimaryIp(char* buffer, size_t buflen) 
{
    assert(buflen >= 16);

    int sock = socket(AF_INET, SOCK_DGRAM, 0);
    assert(sock != -1);

    const char* kGoogleDnsIp = "8.8.8.8";
    uint16_t kDnsPort = 53;
    struct sockaddr_in serv;
    memset(&serv, 0, sizeof(serv));
    serv.sin_family = AF_INET;
    serv.sin_addr.s_addr = inet_addr(kGoogleDnsIp);
    serv.sin_port = htons(kDnsPort);

    int err = connect(sock, (const sockaddr*) &serv, sizeof(serv));
    assert(err != -1);

    sockaddr_in name;
    socklen_t namelen = sizeof(name);
    err = getsockname(sock, (sockaddr*) &name, &namelen);
    assert(err != -1);

    const char* p = inet_ntop(AF_INET, &name.sin_addr, buffer, buflen);
    assert(p);

    close(sock);
}

  • Dies gibt mir die private IP 127.*.*.* . vielleicht weil ich hinter NAT stehe?

    – Eugen

    7. April 2011 um 10:42 Uhr

Wie Sie herausgefunden haben, gibt es keine einzelne “lokale IP-Adresse”. So finden Sie die lokale Adresse heraus, die an einen bestimmten Host gesendet werden kann.

  1. Erstellen Sie einen UDP-Socket
  2. Verbinden Sie den Socket mit einer externen Adresse (dem Host, der schließlich die lokale Adresse erhält)
  3. Verwenden Sie getsockname, um die lokale Adresse abzurufen

1646893214 924 Wie bekomme ich die IP Adresse eines Linux Rechners
Erik Aronesty

Dies hat den Vorteil, dass es auf vielen Arten von Unix funktioniert … und Sie können es trivial modifizieren, um auf jedem Betriebssystem zu arbeiten. Alle oben genannten Lösungen geben mir abhängig von der Mondphase Compilerfehler. Im Moment gibt es einen guten POSIX-Weg, dies zu tun … verwenden Sie dies nicht (als dies geschrieben wurde, war dies nicht der Fall).

// ifconfig | perl -ne 'print "$1\n" if /inet addr:([\d.]+)/'

#include <stdlib.h>

int main() {
        setenv("LANG","C",1);
        FILE * fp = popen("ifconfig", "r");
        if (fp) {
                char *p=NULL, *e; size_t n;
                while ((getline(&p, &n, fp) > 0) && p) {
                   if (p = strstr(p, "inet ")) {
                        p+=5;
                        if (p = strchr(p, ':')) {
                            ++p;
                            if (e = strchr(p, ' ')) {
                                 *e="\0";
                                 printf("%s\n", p);
                            }
                        }
                   }
              }
        }
        pclose(fp);
        return 0;
}

  • Vielen Dank für diese Lösung, funktioniert bei mir hervorragend und ist in vielen Situationen sehr praktisch, wenn Sie nur einige Daten aus cl-Programmen abrufen möchten

    – Zitroneneis

    9. April 2012 um 15:43 Uhr

  • Obwohl ifconfig die erforderlichen Daten ausgibt, würde ich dringend davon abraten, ein Programm auf diese Weise zu verwenden. Es ist viel besser, tatsächlich in die Quelle von ifconfig einzusteigen und die Funktionalität zu erhalten, als es auszuführen und seine Ausgabe zu analysieren.

    – Zaur Nasibov

    12. Juni 2012 um 11:52 Uhr

  • @MartinMeeser: Sprachneutral gemacht, indem nach “inet” und dann “:” separat gesucht wurde.

    – Erik Aronesty

    22. Januar 2014 um 16:09 Uhr

  • Dann haben Sie andere Sprachen, die nicht einmal auf lateinischen Zeichensätzen basieren. Die Lösung besteht darin, keine Befehlswerkzeuge zu verwenden, da diese veraltet sind ifconfig. Du solltest benutzen ip jetzt. Die richtig Eine Möglichkeit, eine sprachneutrale Ausgabe zu erzeugen, ist das Setzen LANG Umgebungsvariable zu Cwie: LANG=C ls -l

    – Anders

    12. September 2014 um 23:03 Uhr

  • Danke. Es ist eine einfache und geniale Lösung!

    – Ahmad Afkande

    11. August 2020 um 5:24 Uhr

1646893214 907 Wie bekomme ich die IP Adresse eines Linux Rechners
Gemeinschaft

Ich glaube nicht, dass es eine endgültige richtige Antwort auf Ihre Frage gibt. Stattdessen gibt es ein großes Bündel von Möglichkeiten, wie Sie dem, was Sie wünschen, nahe kommen können. Daher werde ich einige Hinweise geben, wie man es macht.

Wenn eine Maschine mehr als 2 Schnittstellen hat (lo als eins zählt) werden Sie Probleme haben, die richtige Schnittstelle einfach automatisch zu erkennen. Hier sind einige Rezepte, wie es geht.

Das Problem ist beispielsweise, wenn sich Hosts in einer DMZ hinter einer NAT-Firewall befinden, die die öffentliche IP in eine private IP ändert und die Anfragen weiterleitet. Ihre Maschine kann 10 Schnittstellen haben, aber nur eine entspricht der öffentlichen.

Selbst die automatische Erkennung funktioniert nicht, wenn Sie sich auf Double-NAT befinden, wo Ihre Firewall sogar die Quell-IP in etwas völlig anderes übersetzt. Sie können also nicht einmal sicher sein, dass die Standardroute zu Ihrer Schnittstelle mit einer öffentlichen Schnittstelle führt.

Erkennen Sie es über die Standardroute

Dies ist meine empfohlene Methode, um Dinge automatisch zu erkennen

Etwas wie ip r get 1.1.1.1 teilt Ihnen normalerweise die Schnittstelle mit, die die Standardroute hat.

Wenn Sie dies in Ihrer bevorzugten Skript-/Programmiersprache neu erstellen möchten, verwenden Sie strace ip r get 1.1.1.1 und folgen Sie dem gelben Ziegelsteinweg.

Stellen Sie es mit ein /etc/hosts

Das ist meine Empfehlung, wenn Sie die Kontrolle behalten wollen

Sie können einen Eintrag erstellen in /etc/hosts wie

80.190.1.3 publicinterfaceip

Dann können Sie diesen Alias ​​verwenden publicinterfaceip um auf Ihre öffentliche Schnittstelle zu verweisen.

Leider haproxy grok nicht diesen Trick mit IPv6

Nutze die Umgebung

Dies ist eine gute Problemumgehung für /etc/hosts falls du es nicht bist root

Gleich wie /etc/hosts. sondern nutze dafür die Umgebung. Du kannst es versuchen /etc/profile oder ~/.profile dafür.

Wenn Ihr Programm also eine Variable benötigt MYPUBLICIP dann können Sie Code einfügen wie (das ist C, Sie können C++ daraus erstellen):

#define MYPUBLICIPENVVAR "MYPUBLICIP"

const char *mypublicip = getenv(MYPUBLICIPENVVAR);

if (!mypublicip) { fprintf(stderr, "please set environment variable %s\n", MYPUBLICIPENVVAR); exit(3); }

So können Sie Ihr Skript/Programm aufrufen /path/to/your/script so was

MYPUBLICIP=80.190.1.3 /path/to/your/script

das geht sogar rein crontab.

Zählen Sie alle Schnittstellen auf und eliminieren Sie diejenigen, die Sie nicht wollen

Der verzweifelte Weg, wenn Sie nicht verwenden können ip

Wenn Sie wissen, was Sie nicht wollen, können Sie alle Schnittstellen aufzählen und alle falschen ignorieren.

Hier scheint es bereits eine Antwort https://stackoverflow.com/a/265978/490291 für diesen Ansatz zu geben.

Mach es wie DLNA

Der Weg des Betrunkenen, der versucht, sich in Alkohol zu ertränken

Sie können versuchen, alle UPnP-Gateways in Ihrem Netzwerk aufzulisten und auf diese Weise eine geeignete Route für etwas “Externes” herauszufinden. Dies kann sogar auf einer Route liegen, auf die Ihre Standardroute nicht zeigt.

Mehr dazu vielleicht unter https://en.wikipedia.org/wiki/Internet_Gateway_Device_Protocol

Dies gibt Ihnen einen guten Eindruck, welches Ihre wirkliche öffentliche Schnittstelle ist, auch wenn Ihre Standardroute woanders hinführt.

Es gibt noch mehr

Wo der Berg den Propheten trifft

IPv6-Router werben für sich selbst, um Ihnen das richtige IPv6-Präfix zu geben. Ein Blick auf das Präfix gibt Ihnen einen Hinweis darauf, ob es eine interne IP oder eine globale hat.

Sie können auf IGMP- oder IBGP-Frames hören, um ein geeignetes Gateway zu finden.

Es gibt weniger als 2^32 IP-Adressen. Daher dauert es in einem LAN nicht lange, sie alle anzupingen. So erhalten Sie einen statistischen Hinweis darauf, wo sich aus Ihrer Sicht der Großteil des Internets befindet. Allerdings sollte man etwas vernünftiger sein als die Berühmten https://de.wikipedia.org/wiki/SQL_Slammer

ICMP und sogar ARP sind gute Quellen für Netzwerkseitenbandinformationen. Es könnte dir auch weiterhelfen.

Sie können die Ethernet-Broadcast-Adresse verwenden, um alle Ihre Netzwerkinfrastrukturgeräte zu kontaktieren, die oft hilfreich sind, wie DHCP (sogar DHCPv6) und so weiter.

Diese zusätzliche Liste ist wahrscheinlich endlos und immer unvollständig, da jeder Hersteller von Netzwerkgeräten eifrig neue Sicherheitslücken erfindet, wie er seine eigenen Geräte automatisch erkennen kann. Was oft sehr hilfreich ist, um eine öffentliche Schnittstelle zu erkennen, wo keine sein sollte.

‘Nuff sagte. Aus.

  • Vielen Dank für diese Lösung, funktioniert bei mir hervorragend und ist in vielen Situationen sehr praktisch, wenn Sie nur einige Daten aus cl-Programmen abrufen möchten

    – Zitroneneis

    9. April 2012 um 15:43 Uhr

  • Obwohl ifconfig die erforderlichen Daten ausgibt, würde ich dringend davon abraten, ein Programm auf diese Weise zu verwenden. Es ist viel besser, tatsächlich in die Quelle von ifconfig einzusteigen und die Funktionalität zu erhalten, als es auszuführen und seine Ausgabe zu analysieren.

    – Zaur Nasibov

    12. Juni 2012 um 11:52 Uhr

  • @MartinMeeser: Sprachneutral gemacht, indem nach “inet” und dann “:” separat gesucht wurde.

    – Erik Aronesty

    22. Januar 2014 um 16:09 Uhr

  • Dann haben Sie andere Sprachen, die nicht einmal auf lateinischen Zeichensätzen basieren. Die Lösung besteht darin, keine Befehlswerkzeuge zu verwenden, da diese veraltet sind ifconfig. Du solltest benutzen ip jetzt. Die richtig Eine Möglichkeit, eine sprachneutrale Ausgabe zu erzeugen, ist das Setzen LANG Umgebungsvariable zu Cwie: LANG=C ls -l

    – Anders

    12. September 2014 um 23:03 Uhr

  • Danke. Es ist eine einfache und geniale Lösung!

    – Ahmad Afkande

    11. August 2020 um 5:24 Uhr

1646893215 177 Wie bekomme ich die IP Adresse eines Linux Rechners
camh

Zusätzlich zu dem, was Steve Baker gesagt hat, finden Sie eine Beschreibung des SIOCGIFCONF ioctl in der netdevice(7) Manpage.

Sobald Sie die Liste aller IP-Adressen auf dem Host haben, müssen Sie anwendungsspezifische Logik verwenden, um die Adressen herauszufiltern, die Sie nicht wollen, und hoffen, dass Sie eine IP-Adresse übrig haben.

986600cookie-checkWie bekomme ich die IP-Adresse eines (Linux-)Rechners?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy