Get local IP address in C++ Linux [duplicate]
I needed to find the IP address for the local machine on of the webservices. In C#, I have
How could I do it in C++ Linux?
4 Answers 4
getifaddrs() will return a list of structures of all the interfaces in the machine. There is an example at the bottom of the man page.
You can also use ioctl with the SIOCGIFCONF parameter. There is an example here
- Make a UDP socket
- Bind to wildcard
- Connect to 1.2.3.4 1.1.1.1
- getsockname
1.2.3.4 is an impossible IP address that happens to be treated by all hosts as outobund. 1.1.1.1 is CloudFlare’s DNS server with multicast routing so your host can’t be it. (If they ever make 1. allocatable you will have to use 0.2.3.4 which can potentially invoke undefined behavior).
You will need to update this for IPv6 of course.
Your specific question is answered in the following pages:
But here is more information about BSD sockets. Beej’s Guide to Network Programming is a good place to learn more.
C++ in linux using the system call ‘getifaddr’ to get all interface of your network card. Here are two function and a struct you need.
And here is an example provided by user Twelve47 at Get the IP address of the machine to get IPv4 and IPv6 address of all interfaces:
Linux C: Get default interface’s IP address
My question is about the following code (in this link):
This code’s output is like this:
How can I get the default interface’s IP address? (You can give an answer with another code piece.)
2 Answers 2
This code will do the thing:
Alternatively, you can also use an IP address mask. For example, this will print only if mask is different from 255.0.0.0 (loopback mask)
A method that covers more situations would involve something like this:
- parse the /proc/net/route file to see which interface is the «default» one;
- use your piece of code from the first post (using getifaddrs ) to figure out the IP address for that interface.
The route file parsing might look like this (C++ code for brevity):
Then, in your code, in the for loop iterating over the ifAddrStruct structs, you could add a test for ifa->ifa_name to be the defaultInterface determined above.
How to get the primary IP address of the local machine on Linux and OS X? [closed]
Want to improve this question? Update the question so it’s on-topic for Stack Overflow.
I am looking for a command line solution that would return me the primary (first) IP address of the localhost, other than 127.0.0.1
The solution should work at least for Linux (Debian and RedHat) and OS X 10.7+
I am aware that ifconfig is available on both but its output is not so consistent between these platforms.
31 Answers 31
Use grep to filter IP address from ifconfig :
ifconfig | grep -Eo ‘inet (addr:)?(9*\.)<3>2*’ | grep -Eo ‘(5*\.)<3>9*’ | grep -v ‘127.0.0.1’
If you are only interested in certain interfaces, wlan0, eth0, etc. then:
You can alias the command in your .bashrc to create your own command called myip for instance.
alias myip=»ifconfig | sed -En ‘s/127.0.0.1//;s/.*inet (addr:)?((1*\.)<3>6*).*/\2/p'»
A much simpler way is hostname -I ( hostname -i for older versions of hostname but see comments). However, this is on Linux only.
The following will work on Linux but not OSX.
This doesn’t rely on DNS at all, and it works even if /etc/hosts is not set correctly ( 1 is shorthand for 1.0.0.0 ):
or avoiding awk and using Google’s public DNS at 8.8.8.8 for obviousness:
A less reliable way: (see comment below)
For linux machines (not OS X) :
hostname -I can return multiple addresses in an unreliable order (see the hostname manpage), but for me it just returns 192.168.1.X , which is what you wanted.
Solution
Explanation
The correct way to query network information is using ip :
- -o one-line output
- route get to get the actual kernel route to a destination
- 8.8.8.8 Google IP, but can use the real IP you want to reach
To extract the src ip, sed is the ligthest and most compatible with regex support:
- -n no output by default
- ‘s/pattern/replacement/p’ match pattern and print replacement only
- .*src \([0-9.]\+\).* match the src IP used by the kernel, to reach 8.8.8.8
Other answers
I think none of the preceding answer are good enough for me, as they don’t work in a recent machine (Gentoo 2018).
Issues I found with preceding answers:
- use of positional column in command output;
- use of ifconfig which is deprecated and — for example — don’t list multple IPs;
- use of awk for a simple task which sed can handle better;
- ip route get 1 is unclear, and is actually an alias for ip route get to 1.0.0.0
- use of hostname command, which don’t have -I option in all appliance and which return 127.0.0.1 in my case.
Edited (2014-06-01 2018-01-09)
For stronger config, with many interfaces and many IP configured on each interfaces, I wrote a pure bash script (not based on 127.0.0.1 ) for finding correct interface and ip, based on default route . I post this script at very bottom of this answer.
Intro
As both Os have bash installed by default, there is a bash tip for both Mac and Linux:
The locale issue is prevented by the use of LANG=C :
Putting this into a function:
Fancy tidy:
or, running same function, but with an argument:
Nota: Without argument, this function output on STDOUT, the IP and a newline, with an argument, nothing is printed, but a variable named as argument is created and contain IP without newline.
Nota2: This was tested on Debian, LaCie hacked nas and MaxOs. If this won’t work under your environ, I will be very interested by feed-backs!
Older version of this answer
( Not deleted because based on sed , not bash . )
Warn: There is an issue about locales!
Edit:
How! This seem not work on Mac OS.
Ok, this seem work quite same on Mac OS as on my Linux:
My script (jan 2018):
This script will first find your default route and interface used for, then search for local ip matching network of gateway and populate variables. The last two lines just print, something like:
Specific to only certain builds of Ubuntu. Though it may just tell you 127.0.0.1 :
You can also get IP version 4 address of eth0 by using this command in linux
Output will be like this
This works on Linux and OSX
This will get the interface associated to the default route
Using the interface discovered above, get the ip address.
Darwin laptop 14.4.0 Darwin Kernel Version 14.4.0: Thu May 28 11:35:04 PDT 2015; root:xnu-2782.30.5
CentOS Linux
Linux dev-cil.medfx.local 2.6.18-164.el5xen 1 SMP Thu Sep 3 04:03:03 EDT 2009 x86_64 x86_64 x86_64 GNU/Linux
Using some of the other methods You may enter a conflict where multiple IP adresses is defined on the system. This line always gets the IP address by default used.
Im extracting my comment to this answer:
It bases on @CollinAnderson answer which didn’t work in my case.
The shortest way to get your local ipv4-address on your linux system:
Assuming you need your primary public IP as it seen from the rest of the world, try any of those:
I have to add to Collin Andersons answer that this method also takes into account if you have two interfaces and they’re both showing as up.
I have been working on an application with Raspberry Pi’s and needed the IP address that was actually being used not just whether it was up or not. Most of the other answers will return both IP address which isn’t necessarily helpful — for my scenario anyway.
Primary network interface IP
Finds an IP address of this computer in a network which is a default gateway (for example excludes all virtual networks, docker bridges) eg. internet gateway, wifi gateway, ethernet
Another ifconfig variantion that works both on Linux and OSX:
I went through a lot of links (StackExchange, AskUbuntu, StackOverflow etc) and came to the decision to combine all the best solutions into one shell script.
In my opinion these two QAs are the best of seen:
How can I get my external IP address in a shell script? https://unix.stackexchange.com/q/22615
How do I find my internal ip address? https://askubuntu.com/a/604691
Here is my solution based on some ideas by rsp shared in his repository (https://github.com/rsp/scripts/).
Some of you could say that this script is extremely huge for so simple task but I’d like to make it easy and flexible in usage as much as possible. It supports simple configuration file allowing redefine the default values.
It was successfully tested under Cygwin, MINGW and Linux (Red Hat).