Diese Frage entspricht fast der zuvor gestellten Frage: IP-Adresse des lokalen Computers abrufen - Frage. Ich muss jedoch die IP-Adresse (n) eines Linux-Computers finden .
Also: Wie erkenne ich - programmgesteuert in C ++ - die IP-Adressen des Linux-Servers, auf dem meine Anwendung ausgeführt wird? Die Server haben mindestens zwei IP-Adressen und ich benötige 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 Dinge 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 mich auch an INADDR_ANY binden (und genau das mache ich gerade). Ich würde es jedoch vorziehen, die öffentliche Adresse zu ermitteln.
quelle
ifconfig
,route
etc. sind für den veraltetenip
Befehl. Jetzt sollten Sie das stattdessen verwenden.Antworten:
Ich fand die ioctl-Lösung unter os x problematisch (die POSIX-kompatibel ist und daher Linux ähneln sollte). Mit getifaddress () können Sie das Gleiche problemlos tun. Für OS x 10.5 funktioniert es jedoch einwandfrei und sollte unten gleich sein.
Ich habe unten ein kurzes Beispiel erstellt, in dem die gesamte IPv4-Adresse des Geräts gedruckt wird (Sie sollten auch überprüfen, ob getifaddrs erfolgreich war, dh 0 zurückgibt).
Ich habe es aktualisiert, um auch IPv6-Adressen anzuzeigen.
quelle
tmpAddrPtr=&((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr;
lo
undwlan0
Schnittstellen in meinem Fall. Was ich benötige, istwlan0
odereth0
welche Internetverbindung hat.strcmp
Also , sollte ich verwenden oder es ist ein besserer Weg?ioctl(<socketfd>, SIOCGIFCONF, (struct ifconf)&buffer);
Lesen Sie
/usr/include/linux/if.h
für Informationen zuifconf
undifreq
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.quelle
Ich mag die Antwort von jjvainio . Wie Zan Lnyx sagt, verwendet es die lokale Routing-Tabelle, um die IP-Adresse der Ethernet-Schnittstelle zu ermitteln, die für eine Verbindung zu einem bestimmten externen Host verwendet werden 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 den Trick tun. Ich mag die öffentliche DNS-Serveradresse 8.8.8.8 von Google für diesen Zweck, aber es kann vorkommen, dass Sie eine andere externe Host-IP auswählen möchten. Hier ist ein Code, der den vollständigen Ansatz veranschaulicht.
quelle
Wie Sie herausgefunden haben, gibt es keine einzige "lokale IP-Adresse". Hier erfahren Sie, welche lokale Adresse an einen bestimmten Host gesendet werden kann.
quelle
Dies hat den Vorteil, dass Sie an vielen Unix-Varianten arbeiten können ... und Sie können es trivial ändern, um an jedem Betriebssystem zu arbeiten. Alle oben genannten Lösungen führen zu Compilerfehlern in Abhängigkeit von der Mondphase. Im Moment gibt es eine gute POSIX-Methode ... verwenden Sie diese nicht (zu dem Zeitpunkt, als dies geschrieben wurde, war dies nicht der Fall).
quelle
ifconfig
. Sie solltenip
jetzt verwenden. Die richtige Methode zum Generieren einer sprachneutralen Ausgabe besteht darin, dieLANG
UmgebungsvariableC
wie folgtLANG=C ls -l
Ich glaube nicht, dass es eine endgültige richtige Antwort auf Ihre Frage gibt. Stattdessen gibt es eine Vielzahl von Möglichkeiten, wie Sie sich Ihren Wünschen nähern können. Daher werde ich einige Hinweise geben, wie es geht.
Wenn eine Maschine mehr als 2 Schnittstellen hat (
lo
zählt als eine), haben Sie Probleme, die richtige Schnittstelle einfach automatisch zu erkennen. Hier sind einige Rezepte, wie es geht.Das Problem besteht beispielsweise darin, dass sich Hosts in einer DMZ hinter einer NAT-Firewall befinden, die die öffentliche IP in eine private IP ändert und die Anforderungen weiterleitet. Ihr Computer verfügt möglicherweise über 10 Schnittstellen, 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
Etwas wie
ip r get 1.1.1.1
normalerweise sagt Ihnen die Schnittstelle, 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
die gelbe Backsteinstraße und folgen Sie ihr.Stellen Sie es mit ein
/etc/hosts
Sie können einen Eintrag in
/etc/hosts
like erstellenDann können Sie diesen Alias verwenden
publicinterfaceip
, um auf Ihre öffentliche Schnittstelle zu verweisen.Nutze die Umgebung
Gleich wie
/etc/hosts
. aber nutzen Sie die Umgebung dafür. Sie können versuchen/etc/profile
oder~/.profile
dafür.Wenn Ihr Programm eine Variable benötigt
MYPUBLICIP
, können Sie Code wie folgt einfügen (dies ist C, Sie können C ++ daraus erstellen):So können Sie Ihr Skript / Programm
/path/to/your/script
so aufrufenMYPUBLICIP=80.190.1.3 /path/to/your/script
das funktioniert sogar in
crontab
.Zählen Sie alle Schnittstellen auf und entfernen Sie diejenigen, die Sie nicht möchten
Wenn Sie wissen, was Sie nicht wollen, können Sie alle Schnittstellen auflisten und alle falschen ignorieren.
Hier scheint bereits eine Antwort https://stackoverflow.com/a/265978/490291 für diesen Ansatz zu sein.
Mach es wie DLNA
Sie können versuchen, alle UPnP-Gateways in Ihrem Netzwerk aufzulisten, und auf diese Weise einen geeigneten Weg für eine "externe" Sache finden. Dies kann sogar auf einer Route der Fall sein, auf die Ihre Standardroute nicht verweist.
Weitere Informationen hierzu finden Sie unter https://en.wikipedia.org/wiki/Internet_Gateway_Device_Protocol
Dies gibt Ihnen einen guten Eindruck davon, welches Ihre echte öffentliche Schnittstelle ist, selbst wenn Ihre Standardroute auf eine andere Stelle verweist.
Es gibt noch mehr
IPv6-Router bewerben sich selbst, um Ihnen das richtige IPv6-Präfix zu geben. Wenn Sie sich das Präfix ansehen, erhalten Sie einen Hinweis darauf, ob es eine interne oder eine globale IP-Adresse hat.
Sie können nach IGMP- oder IBGP-Frames suchen, 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. Dies gibt Ihnen einen statistischen Hinweis darauf, wo sich aus Ihrer Sicht der Großteil des Internets befindet. Sie sollten jedoch etwas vernünftiger sein als der berühmte https://de.wikipedia.org/wiki/SQL_Slammer
ICMP und sogar ARP sind gute Quellen für Netzwerkseitenbandinformationen. Es könnte Ihnen auch helfen.
Sie können die Ethernet Broadcast-Adresse verwenden, um mit all Ihren Netzwerkinfrastrukturgeräten in Kontakt zu treten, die häufig hilfreich sind, z. B. DHCP (sogar DHCPv6) usw.
Diese zusätzliche Liste ist wahrscheinlich endlos und immer unvollständig, da jeder Hersteller von Netzwerkgeräten fleißig neue Sicherheitslücken erfindet, um seine eigenen Geräte automatisch zu erkennen. Das hilft oft sehr dabei, eine öffentliche Schnittstelle zu erkennen, bei der es keine geben sollte.
'Nuff sagte. Aus.
quelle
Zusätzlich zu dem, was Steve Baker gesagt hat, finden Sie eine Beschreibung des SIOCGIFCONF ioctl in der Manpage netdevice (7) .
Sobald Sie die Liste aller IP-Adressen auf dem Host haben, müssen Sie eine anwendungsspezifische Logik verwenden, um die nicht gewünschten Adressen herauszufiltern, und hoffen, dass Sie noch eine IP-Adresse haben.
quelle
Codieren Sie es nicht hart: So etwas kann sich ändern. Viele Programme finden heraus, woran sie sich binden müssen, indem sie eine Konfigurationsdatei einlesen und alles tun, was dazu gehört. Auf diese Weise kann Ihr Programm dies tun, falls es irgendwann in der Zukunft an etwas gebunden werden muss, das keine öffentliche IP-Adresse ist.
quelle
Da die Frage Linux angibt, ist meine bevorzugte Technik zum Ermitteln der IP-Adressen eines Computers die Verwendung von Netlink. Durch Erstellen eines Netlink-Sockets des Protokolls NETLINK_ROUTE und Senden eines RTM_GETADDR erhält Ihre Anwendung eine Nachricht mit allen verfügbaren IP-Adressen. Ein Beispiel finden Sie hier .
Libmnl ist praktisch, um Teile der Nachrichtenverarbeitung einfach zu gestalten. Wenn Sie neugierig sind, mehr über die verschiedenen Optionen von NETLINK_ROUTE (und wie sie analysiert werden) herauszufinden, ist die beste Quelle der Quellcode von iproute2 (insbesondere die Monitoranwendung) sowie die Empfangsfunktionen im Kernel. Die Manpage von rtnetlink enthält auch nützliche Informationen.
quelle
Sie können eine Integration mit Curl so einfach wie möglich durchführen: Über
curl www.whatismyip.org
die Shell erhalten Sie Ihre globale IP. Sie sind auf einen externen Server angewiesen, aber Sie werden es immer sein, wenn Sie hinter einem NAT stehen.quelle
Eine elegante Skriptlösung für Linux finden Sie unter: http://www.damnsmalllinux.org/f/topic-3-23-17031-0.html
quelle
// Use a HTTP request to a well known server that echo's back the public IP address void GetPublicIP(CString & csIP) { // Initialize COM bool bInit = false; if (SUCCEEDED(CoInitialize(NULL))) { // COM was initialized bInit = true;
}
quelle