www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How can i find my LAN IP Address using std.socket?

reply "TheFlyingFiddle" <theflyingfiddle gmail.com> writes:
I'm trying to find my own ip address using std.socket with little 
success. How would i go about doing this? (It should be a 
AddressFamily.INET socket)
Feb 04 2014
next sibling parent reply "Dicebot" <public dicebot.lv> writes:
On Tuesday, 4 February 2014 at 13:02:26 UTC, TheFlyingFiddle 
wrote:
 I'm trying to find my own ip address using std.socket with 
 little success. How would i go about doing this? (It should be 
 a AddressFamily.INET socket)
You can have lot of different local IP addresses on a single machine so question can't be answered properly. However you may use in `Socket.hostName` and resolve it via DNS to find IP machine itself currently consuders as its main pulbic IP.
Feb 04 2014
parent "TheFlyingFiddle" <theflyingfiddle gmail.com> writes:
On Tuesday, 4 February 2014 at 13:13:07 UTC, Dicebot wrote:
 On Tuesday, 4 February 2014 at 13:02:26 UTC, TheFlyingFiddle 
 wrote:
 I'm trying to find my own ip address using std.socket with 
 little success. How would i go about doing this? (It should be 
 a AddressFamily.INET socket)
You can have lot of different local IP addresses on a single machine so question can't be answered properly. However you may use in `Socket.hostName` and resolve it via DNS to find IP machine itself currently consuders as its main pulbic IP.
This works great thanks. I just need any (working) local IP address so getting more then one is not an issue for me.
Feb 04 2014
prev sibling next sibling parent reply "Stanislav Blinov" <stanislav.blinov gmail.com> writes:
On Tuesday, 4 February 2014 at 13:02:26 UTC, TheFlyingFiddle 
wrote:
 I'm trying to find my own ip address using std.socket with 
 little success. How would i go about doing this? (It should be 
 a AddressFamily.INET socket)
Create a connection to another LAN machine with a known address (e.g. gateway or router), then use Socket's localAddress property to get your IP. You cannot really do that before establishing a connection, as Dicebot already mentioned.
Feb 04 2014
next sibling parent reply "Dicebot" <public dicebot.lv> writes:
On Tuesday, 4 February 2014 at 13:21:54 UTC, Stanislav Blinov 
wrote:
 Create a connection to another LAN machine with a known address 
 (e.g. gateway or router), then use Socket's localAddress 
 property to get your IP.
Worth noting that this solution is not reliable in general either because your server can possibly have complicated routing configurations that will make, for example, LAN destination packets go via different network interface than WAN destination ones. It is probably better to tell what high-level problem you are trying to solve to find most useful compromise.
Feb 04 2014
parent reply "TheFlyingFiddle" <kurtyan student.chalmers.se> writes:
On Tuesday, 4 February 2014 at 13:24:59 UTC, Dicebot wrote:
 On Tuesday, 4 February 2014 at 13:21:54 UTC, Stanislav Blinov 
 wrote:
Worth noting that this solution is not reliable in general 
either because your server can possibly have complicated routing 
configurations that will make, for example, LAN destination 
packets go via different network interface than WAN destination 
ones.

 It is probably better to tell what high-level problem you are 
 trying to solve to find most useful compromise.
I'm setting up a simple local network enabling me to connect phones to the computer through the local wi-fi. The simplest way i could think of to make this work without relying on an external server was to simply broadcast the ip and port to all machines in the network.(Btw by server i mean my / my project groups windows boxes). So well the problem is that i need a way for the phones to find running servers on the LAN.
Feb 04 2014
parent reply "Dicebot" <public dicebot.lv> writes:
On Tuesday, 4 February 2014 at 20:19:14 UTC, TheFlyingFiddle 
wrote:
 I'm setting up a simple local network enabling me to connect 
 phones to the computer through the local wi-fi. The simplest 
 way i could think of to make this work without relying on an 
 external server was to simply broadcast the ip and port to all 
 machines in the network.(Btw by server i mean my / my project 
 groups windows boxes).

 So well the problem is that i need a way for the phones to find 
 running servers on the LAN.
I think it is close to impossible to do in portable way. Most reliable approach is to get list of all configured network interfaces via posix functions (or via `system` call as least resort), filter out "lo" and broadcast message for every such interface. I think you can also filter only wireless interfaces that way relatively easily too.
Feb 04 2014
parent Mike Shah <mshah.475 gmail.com> writes:
On Tuesday, 4 February 2014 at 22:31:53 UTC, Dicebot wrote:
 On Tuesday, 4 February 2014 at 20:19:14 UTC, TheFlyingFiddle 
 wrote:
 I'm setting up a simple local network enabling me to connect 
 phones to the computer through the local wi-fi. The simplest 
 way i could think of to make this work without relying on an 
 external server was to simply broadcast the ip and port to all 
 machines in the network.(Btw by server i mean my / my project 
 groups windows boxes).

 So well the problem is that i need a way for the phones to 
 find running servers on the LAN.
I think it is close to impossible to do in portable way. Most reliable approach is to get list of all configured network interfaces via posix functions (or via `system` call as least resort), filter out "lo" and broadcast message for every such interface. I think you can also filter only wireless interfaces that way relatively easily too.
Apologies that I am bumping a post that is 9 years old, but I recently had to do this and thought this may help beginners. In a way it's a hack as suggested from the second post, that you can connect to a known ip address (e.g. google) from a socket and then see the endpoints with the local and remote addresses. ``` import std.stdio; import std.socket; void GetIP(){ // A bit of a hack, but we'll create a connection from google to // our current ip. // Use a well known port (i.e. google) to do this auto r = getAddress("8.8.8.8",53); // NOTE: This is effetively getAddressInfo writeln(r); // Create a socket auto sockfd = new Socket(AddressFamily.INET, SocketType.STREAM); // Connect to the google server import std.conv; const char[] address = r[0].toAddrString().dup; ushort port = to!ushort(r[0].toPortString()); sockfd.connect(new InternetAddress(address,port)); // Obtain local sockets name and address writeln(sockfd.hostName); writeln("Our ip address : ",sockfd.localAddress); writeln("the remote address: ",sockfd.remoteAddress); // Close our socket sockfd.close(); } ```
Feb 21 2023
prev sibling parent reply "TheFlyingFiddle" <theflyingfiddle gmail.com> writes:
On Tuesday, 4 February 2014 at 13:21:54 UTC, Stanislav Blinov 
wrote:
 On Tuesday, 4 February 2014 at 13:02:26 UTC, TheFlyingFiddle 
 wrote:
 I'm trying to find my own ip address using std.socket with 
 little success. How would i go about doing this? (It should be 
 a AddressFamily.INET socket)
Create a connection to another LAN machine with a known address (e.g. gateway or router), then use Socket's localAddress property to get your IP. You cannot really do that before establishing a connection, as Dicebot already mentioned.
Problem is that i don't know in what local network the server will be running, so this is unfortunatly not an option for me.
Feb 04 2014
parent "Stanislav Blinov" <stanislav.blinov gmail.com> writes:
On Tuesday, 4 February 2014 at 13:31:27 UTC, TheFlyingFiddle 
wrote:

 Problem is that i don't know in what local network the server 
 will be running, so this is unfortunatly not an option for me.
But if that's the case, the hostname solution may as well just give you your loopback address. :)
Feb 04 2014
prev sibling next sibling parent reply "Vladimir Panteleev" <vladimir thecybershadow.net> writes:
On Tuesday, 4 February 2014 at 13:02:26 UTC, TheFlyingFiddle 
wrote:
 I'm trying to find my own ip address using std.socket with 
 little success. How would i go about doing this? (It should be 
 a AddressFamily.INET socket)
This program will print all of your computer's IP addresses: import std.socket; import std.stdio; void main() { foreach (addr; getAddress(Socket.hostName)) writeln(addr.toAddrString()); } This includes IPv6 addresses. You can filter the address family by checking addr's addressFamily property.
Feb 04 2014
parent reply "Craig Dillabaugh" <cdillaba cg.scs.carleton.ca> writes:
On Tuesday, 4 February 2014 at 15:48:50 UTC, Vladimir Panteleev 
wrote:
 On Tuesday, 4 February 2014 at 13:02:26 UTC, TheFlyingFiddle 
 wrote:
 I'm trying to find my own ip address using std.socket with 
 little success. How would i go about doing this? (It should be 
 a AddressFamily.INET socket)
This program will print all of your computer's IP addresses: import std.socket; import std.stdio; void main() { foreach (addr; getAddress(Socket.hostName)) writeln(addr.toAddrString()); } This includes IPv6 addresses. You can filter the address family by checking addr's addressFamily property.
I am a bit lost in anything networking related, so I ran this on my machine just for fun and it printed: 127.0.0.1 127.0.0.1 127.0.0.1 which based on my understanding is the local loopback address (I am not completely, 100% ignorant). However if I run /sbin/ifconfig I get: enp7s0 Link encap:Ethernet HWaddr 50:E5:49:9B:29:49 inet addr:10.1.101.52 Bcast:10.1.101.255 Mask:255.255.255.0 inet6 addr: fe80::52e5:49ff:fe9b:2949/64 Scope:Link lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host This computer is on a network with dynamically assigned IP address (DHCP). So shouldn't the 10.1.101.52 address have been reported?
Feb 04 2014
next sibling parent reply "Dicebot" <public dicebot.lv> writes:
On Tuesday, 4 February 2014 at 16:02:33 UTC, Craig Dillabaugh 
wrote:
 However if I run /sbin/ifconfig I get:

 enp7s0    Link encap:Ethernet  HWaddr 50:E5:49:9B:29:49
           inet addr:10.1.101.52  Bcast:10.1.101.255  
 Mask:255.255.255.0
           inet6 addr: fe80::52e5:49ff:fe9b:2949/64 Scope:Link

 lo        Link encap:Local Loopback
           inet addr:127.0.0.1  Mask:255.0.0.0
           inet6 addr: ::1/128 Scope:Host

 This computer is on a network with dynamically assigned IP 
 address (DHCP).
 So shouldn't the 10.1.101.52 address have been reported?
It results in all addresses you hostname resolvs to. On all desktop linux machines /etc/hosts is configured to resolve hostname to "localhost" by default. On servers it usually resolves to externally accessible one.
Feb 04 2014
next sibling parent "Craig Dillabaugh" <cdillaba cg.scs.carleton.ca> writes:
On Tuesday, 4 February 2014 at 16:13:33 UTC, Dicebot wrote:
 On Tuesday, 4 February 2014 at 16:02:33 UTC, Craig Dillabaugh 
 wrote:
 However if I run /sbin/ifconfig I get:

 enp7s0    Link encap:Ethernet  HWaddr 50:E5:49:9B:29:49
          inet addr:10.1.101.52  Bcast:10.1.101.255  
 Mask:255.255.255.0
          inet6 addr: fe80::52e5:49ff:fe9b:2949/64 Scope:Link

 lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host

 This computer is on a network with dynamically assigned IP 
 address (DHCP).
 So shouldn't the 10.1.101.52 address have been reported?
It results in all addresses you hostname resolvs to. On all desktop linux machines /etc/hosts is configured to resolve hostname to "localhost" by default. On servers it usually resolves to externally accessible one.
Thanks.
Feb 04 2014
prev sibling parent "Dicebot" <public dicebot.lv> writes:
On Tuesday, 4 February 2014 at 16:13:33 UTC, Dicebot wrote:
 It results in all addresses you hostname resolvs to. On all 
 desktop linux machines /etc/hosts is configured to resolve 
 hostname to "localhost" by default. On servers it usually 
 resolves to externally accessible one.
Update: I have just checked and this is actually distro-specific right now. My Arch box does not have that /etc/hosts entry and resolves host name to whatever first configured network interface has. Ubuntu does have explicit host name entry in /etc/hosts which resolves to localhost.
Feb 04 2014
prev sibling parent reply "Stanislav Blinov" <stanislav.blinov gmail.com> writes:
On Tuesday, 4 February 2014 at 16:02:33 UTC, Craig Dillabaugh 
wrote:

 This computer is on a network with dynamically assigned IP 
 address (DHCP).
 So shouldn't the 10.1.101.52 address have been reported?
Nope. In out-of-the-box simple network setups (i.e. home network in the form PC/laptop -> router -> internet) the address resolution won't go further than your hosts file, which in turn will always give you back the loopback address (more specifically, the address that is specified for the hostname in aforementioned file). That's why both I and Dicebot mentioned there isn't any real way to query your local addresses without any live connection: only when a socket has a connection within a particular network can you tell your own IP address in that network. The address itself would depend on the network setup, your local routing configuration, etc. Your machine can have several network adaptors (ethernet boards, Wi-Fi, etc.), each configured with (numerous) routing setups, plus the routers they're connected to have their own routing setups... This can go on and on.
Feb 04 2014
parent Johannes Pfau <nospam example.com> writes:
Am Tue, 04 Feb 2014 16:19:08 +0000
schrieb "Stanislav Blinov" <stanislav.blinov gmail.com>:

 On Tuesday, 4 February 2014 at 16:02:33 UTC, Craig Dillabaugh 
 wrote:
 
 This computer is on a network with dynamically assigned IP 
 address (DHCP).
 So shouldn't the 10.1.101.52 address have been reported?
Nope. In out-of-the-box simple network setups (i.e. home network in the form PC/laptop -> router -> internet) the address resolution won't go further than your hosts file, which in turn will always give you back the loopback address (more specifically, the address that is specified for the hostname in aforementioned file). That's why both I and Dicebot mentioned there isn't any real way to query your local addresses without any live connection: only when a socket has a connection within a particular network can you tell your own IP address in that network. The address itself would depend on the network setup, your local routing configuration, etc. Your machine can have several network adaptors (ethernet boards, Wi-Fi, etc.), each configured with (numerous) routing setups, plus the routers they're connected to have their own routing setups... This can go on and on.
As a last resort there are always OS specific APIs to iterate network interfaces. For example, for linux: http://man7.org/linux/man-pages/man3/getifaddrs.3.html (Of course this doesn't tell you at all whether a local IP-address is actually routable. And you probably have to figure out if you got a link local / ULA IPv6 or a global one)
Feb 04 2014
prev sibling next sibling parent Forest <forest example.com> writes:
On Tuesday, 4 February 2014 at 13:02:26 UTC, TheFlyingFiddle 
wrote:
 I'm trying to find my own ip address using std.socket with 
 little success. How would i go about doing this? (It should be 
 a AddressFamily.INET socket)
Sadly, the standard library doesn't seem to offer network interface enumeration. However, if you don't mind delving into platform-specific C APIs that are exposed by Phobos but not mentioned in the docs ([issue 5872](https://issues.dlang.org/show_bug.cgi?id=5872)), it can be done. The code I found here was enough to get me started: https://github.com/Kripth/my-ip/blob/356e02f0/src/myip/private_.d The key to a linux implementation was `getifaddrs()`, which can be found in core.sys.linux.ifaddrs.
Feb 17
prev sibling parent cc <cc nevernet.com> writes:
On Tuesday, 4 February 2014 at 13:02:26 UTC, TheFlyingFiddle 
wrote:
 I'm trying to find my own ip address using std.socket with 
 little success. How would i go about doing this? (It should be 
 a AddressFamily.INET socket)
On Windows, you can use the Win32`GetAdaptersInfo`[1] function to get a list of IPv4 adapters and addresses. If you need IPv6 addresses or other more modern features, there is the `GetAdaptersAddresses`[2] function, however it doesn't seem the necessary Windows headers (IPTypes.h / ifdef.h) have been ported to D for this yet. [1] https://learn.microsoft.com/en-us/windows/win32/api/iphlpapi/nf-iphlpapi-getadaptersinfo [2] https://learn.microsoft.com/en-us/windows/win32/api/iphlpapi/nf-iphlpapi-getadaptersaddresses As I attempt to post this, I now see this thread is... 10 years old. Oh well, still relevant I think. ```d import std.string; pragma(lib, `mingw/iphlpapi.lib`); // included with dmd struct Adapter { string name; string desc; struct IPMask { string ip; string mask; } IPMask[] addresses; } Adapter[] getAdapters() { import core.sys.windows.windows; //import core.sys.windows.nspapi; import core.sys.windows.iptypes; import core.sys.windows.iphlpapi; void[] buf; uint size = 0; auto ret = GetAdaptersInfo(null, &size); assert(ret == ERROR_BUFFER_OVERFLOW && size > 0, "Expected GetAdaptersInfo to return ERROR_BUFFER_OVERFLOW to query size of buffer"); buf.length = size; ret = GetAdaptersInfo(cast(IP_ADAPTER_INFO*) buf.ptr, &size); assert(!ret, "GetAdaptersInfo error"); auto adpt = cast(IP_ADAPTER_INFO*) buf.ptr; Adapter[] adapters; while (adpt) { scope(success) adpt = adpt.Next; Adapter adapter; adapter.name = adpt.AdapterName.fromStringz.idup; adapter.desc = adpt.Description.fromStringz.idup; IP_ADDR_STRING addr = adpt.IpAddressList; auto paddr = &addr; while (paddr) { scope(success) paddr = addr.Next; adapter.addresses ~= Adapter.IPMask(paddr.IpAddress.String.fromStringz.idup, paddr.IpMask.String.fromStringz.idup); } adapters ~= adapter; } return adapters; } void main() { import std.stdio; auto adapters = getAdapters(); adapters.writeln; } ```
Feb 18