Cette question est presque la même que celle demandée précédemment Obtenir l'adresse IP de l'ordinateur local -Question. Cependant, j'ai besoin de trouver la ou les adresses IP d'une machine Linux .
Donc: Comment puis-je - par programmation en C ++ - détecter les adresses IP du serveur Linux sur lequel mon application s'exécute. Les serveurs auront au moins deux adresses IP et j'en ai besoin d'une spécifique (celle d'un réseau donné (le public)).
Je suis sûr qu'il existe une fonction simple pour le faire - mais où?
Pour rendre les choses un peu plus claires:
- Le serveur aura évidemment le "localhost": 127.0.0.1
- Le serveur aura une adresse IP interne (de gestion): 172.16.xx
- Le serveur aura une adresse IP externe (publique): 80.190.xx
J'ai besoin de trouver l'adresse IP externe pour y lier mon application. Évidemment, je peux aussi me lier à INADDR_ANY (et en fait c'est ce que je fais pour le moment). Je préférerais cependant détecter l'adresse publique.
ifconfig
,route
etc sont déconseillés pour laip
commande. Vous devriez maintenant l'utiliser à la place.Réponses:
J'ai trouvé la solution ioctl problématique sur os x (qui est compatible POSIX et devrait donc être similaire à Linux). Cependant, getifaddress () vous permettra de faire la même chose facilement, cela fonctionne très bien pour moi sur os x 10.5 et devrait être le même ci-dessous.
J'ai fait un exemple rapide ci-dessous qui affichera toute l'adresse IPv4 de la machine, (vous devriez également vérifier que getifaddrs a réussi, c'est-à-dire renvoie 0).
Je l'ai mis à jour pour afficher les adresses IPv6 également.
la source
tmpAddrPtr=&((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr;
lo
etwlan0
interfaces dans mon cas. Ce dont j'ai besoin estwlan0
oueth0
qui a une connexion Internet.Dois-je utiliserstrcmp
ou est-ce un meilleur moyen?ioctl(<socketfd>, SIOCGIFCONF, (struct ifconf)&buffer);
Lisez
/usr/include/linux/if.h
pour plus d'informations sur les structuresifconf
etifreq
. Cela devrait vous donner l'adresse IP de chaque interface du système. Lisez également/usr/include/linux/sockios.h
pour d'autres ioctls.la source
J'aime la réponse de jjvainio . Comme le dit Zan Lnyx, il utilise la table de routage locale pour trouver l'adresse IP de l'interface Ethernet qui serait utilisée pour une connexion à un hôte externe spécifique. En utilisant une prise UDP connectée, vous pouvez obtenir les informations sans envoyer de paquets. L'approche nécessite que vous choisissiez un hôte externe spécifique. La plupart du temps, toute adresse IP publique bien connue devrait faire l'affaire. J'aime l'adresse du serveur DNS public 8.8.8.8 de Google à cette fin, mais il se peut que vous souhaitiez parfois choisir une adresse IP d'hôte externe différente. Voici un code qui illustre l'approche complète.
la source
Comme vous l'avez découvert, il n'y a pas une seule "adresse IP locale". Voici comment trouver l'adresse locale qui peut être envoyée à un hôte spécifique.
la source
Cela a l'avantage de travailler sur de nombreuses versions d'Unix ... et vous pouvez le modifier de manière triviale pour travailler sur n'importe quel o / s. Toutes les solutions ci-dessus me donnent des erreurs de compilation en fonction de la phase de la lune. Au moment où il existe un bon moyen POSIX de le faire ... ne l'utilisez pas (au moment où cela a été écrit, ce n'était pas le cas).
la source
ifconfig
. Vous devriez utiliserip
maintenant. La bonne façon de générer une sortieLANG
indépendante du langage est de définir la variable d'environnement surC
, comme:LANG=C ls -l
Je ne pense pas qu'il y ait une bonne réponse définitive à votre question. Au lieu de cela, il existe un grand nombre de façons de vous rapprocher de ce que vous souhaitez. Par conséquent, je vais fournir quelques conseils pour y parvenir.
Si une machine a plus de 2 interfaces (
lo
compte pour une), vous aurez des problèmes pour détecter automatiquement la bonne interface facilement. Voici quelques recettes pour y parvenir.Le problème, par exemple, est si les hôtes se trouvent dans une zone démilitarisée derrière un pare-feu NAT qui transforme l'adresse IP publique en une adresse IP privée et transmet les demandes. Votre machine peut avoir 10 interfaces, mais une seule correspond à celle publique.
Même la détection automatique ne fonctionne pas si vous êtes en double NAT, où votre pare-feu traduit même l'IP source en quelque chose de complètement différent. Vous ne pouvez donc même pas être sûr que la route par défaut mène à votre interface avec une interface publique.
Détectez-le via l'itinéraire par défaut
Quelque chose comme
ip r get 1.1.1.1
vous indique généralement l'interface qui a la route par défaut.Si vous souhaitez recréer cela dans votre langage de script / programmation préféré, utilisez
strace ip r get 1.1.1.1
et suivez la route de briques jaunes.Réglez-le avec
/etc/hosts
Vous pouvez créer une entrée
/etc/hosts
commeEnsuite, vous pouvez utiliser cet alias
publicinterfaceip
pour faire référence à votre interface publique.Utilisez l'environnement
Identique à
/etc/hosts
. mais utilisez l'environnement pour cela. Vous pouvez essayer/etc/profile
ou~/.profile
pour cela.Par conséquent, si votre programme a besoin d'une variable,
MYPUBLICIP
vous pouvez inclure du code comme (c'est C, n'hésitez pas à créer C ++ à partir de celui-ci):Vous pouvez donc appeler votre script / programme
/path/to/your/script
comme ceciMYPUBLICIP=80.190.1.3 /path/to/your/script
cela fonctionne même dans
crontab
.Énumérez toutes les interfaces et éliminez celles que vous ne voulez pas
Si vous savez ce que vous ne voulez pas, vous pouvez énumérer toutes les interfaces et ignorer toutes les fausses.
Ici semble déjà être une réponse https://stackoverflow.com/a/265978/490291 pour cette approche.
Faites-le comme DLNA
Vous pouvez essayer d'énumérer toutes les passerelles UPnP sur votre réseau et de cette façon trouver une route appropriée pour quelque chose "externe". Cela peut même être sur une route sur laquelle votre route par défaut ne pointe pas.
Pour en savoir plus, consultez peut-être https://en.wikipedia.org/wiki/Internet_Gateway_Device_Protocol
Cela vous donne une bonne idée de celle qui est votre véritable interface publique, même si votre itinéraire par défaut pointe ailleurs.
Il y en a encore plus
Les routeurs IPv6 s'annoncent pour vous donner le bon préfixe IPv6. L'examen du préfixe vous donne un indice pour savoir s'il a une adresse IP interne ou une adresse IP globale.
Vous pouvez écouter les trames IGMP ou IBGP pour trouver une passerelle appropriée.
Il y a moins de 2 ^ 32 adresses IP. Par conséquent, il ne faut pas longtemps sur un réseau local pour les envoyer tous. Cela vous donne un indice statistique sur l'endroit où se trouve la majorité d'Internet de votre point de vue. Cependant, vous devriez être un peu plus sensible que le célèbre https://de.wikipedia.org/wiki/SQL_Slammer
ICMP et même ARP sont de bonnes sources d'informations sur la bande latérale du réseau. Cela pourrait aussi vous aider.
Vous pouvez utiliser l'adresse de diffusion Ethernet pour contacter tous les périphériques de votre infrastructure réseau, ce qui vous aidera souvent, comme DHCP (même DHCPv6), etc.
Cette liste supplémentaire est probablement infinie et toujours incomplète, car chaque fabricant de périphériques réseau invente activement de nouvelles failles de sécurité sur la façon de détecter automatiquement ses propres périphériques. Ce qui aide souvent beaucoup à détecter une interface publique là où il ne devrait pas y en avoir.
Dit Nuff. En dehors.
la source
Suite à ce que Steve Baker a dit, vous pouvez trouver une description de l'ioctl SIOCGIFCONF dans la page de manuel netdevice (7) .
Une fois que vous avez la liste de toutes les adresses IP sur l'hôte, vous devrez utiliser une logique spécifique à l'application pour filtrer les adresses que vous ne voulez pas et espérer qu'il vous reste une adresse IP.
la source
Ne le codez pas en dur: c'est le genre de chose qui peut changer. De nombreux programmes déterminent à quoi se lier en lisant un fichier de configuration et en faisant tout ce qui est dit. De cette façon, si votre programme a besoin à un moment donné de se lier à quelque chose qui n'est pas une adresse IP publique, il peut le faire.
la source
Comme la question spécifie Linux, ma technique préférée pour découvrir les adresses IP d'une machine est d'utiliser netlink. En créant une socket netlink du protocole NETLINK_ROUTE et en envoyant un RTM_GETADDR, votre application recevra un ou plusieurs messages contenant toutes les adresses IP disponibles. Un exemple est fourni ici .
Afin de n'utiliser que des parties de la gestion des messages, libmnl est pratique. Si vous êtes curieux d'en savoir plus sur les différentes options de NETLINK_ROUTE (et comment elles sont analysées), la meilleure source est le code source d'iproute2 (en particulier l'application de moniteur) ainsi que les fonctions de réception dans le noyau. La page de manuel de rtnetlink contient également des informations utiles.
la source
Vous pouvez faire une intégration avec curl aussi simplement que: à
curl www.whatismyip.org
partir du shell, vous obtiendrez votre adresse IP globale. Vous dépendez en quelque sorte d'un serveur externe, mais vous le serez toujours si vous êtes derrière un NAT.la source
Une élégante solution scriptée pour Linux peut être trouvée à: http://www.damnsmalllinux.org/f/topic-3-23-17031-0.html
la source
// 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;
}
la source