get address of current computer

76 views
Skip to first unread message

Ashish Agarwal

unread,
Feb 24, 2015, 2:17:59 PM2/24/15
to ocaml...@googlegroups.com
I'm trying to get the IP address of the computer I'm on, but both Unix.Inet_addr.of_string_or_getbyname and Unix.Host.getbyname return only the loopback address 127.0.0.1. How can I get the inet address of non-loopback network interfaces?

David House

unread,
Feb 24, 2015, 2:24:16 PM2/24/15
to ocaml...@googlegroups.com
Are you calling them on "localhost" or on the result of Unix.Host.gethostname?

Calling Unix.Host.getbyname on the result of Unix.gethostname will probably work, but I expect that will do a reverse DNS lookup, and it seems a little silly to go via DNS when surely computers know what IP addresses its interfaces are configured to have... Perhaps the difference doesn't matter too much to you though.

On 24 February 2015 at 19:17, Ashish Agarwal <agarw...@gmail.com> wrote:
I'm trying to get the IP address of the computer I'm on, but both Unix.Inet_addr.of_string_or_getbyname and Unix.Host.getbyname return only the loopback address 127.0.0.1. How can I get the inet address of non-loopback network interfaces?

--
You received this message because you are subscribed to the Google Groups "ocaml-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ocaml-core+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

David House

unread,
Feb 24, 2015, 2:29:09 PM2/24/15
to ocaml...@googlegroups.com
On further inspection I see there is Linux_ext.get_ipv4_address_for_interface. If you know the name of your network interface, that ought to work. If not, I'm not sure how to get a list of interfaces.

It also seems wrong that that returns a string rather than an Inet_addr.t.

Ashish Agarwal

unread,
Feb 24, 2015, 2:38:01 PM2/24/15
to ocaml...@googlegroups.com
None of the combinations works:

# Unix.Inet_addr.(of_string_or_getbyname "localhost" >>| to_string);;
- : bytes = "127.0.0.1" 

# Unix.Host.getbyname "localhost" >>| (fun h -> Option.value_exn h |> fun h -> Array.map h.Unix.Host.addresses ~f:Unix.Inet_addr.to_string);;
- : bytes array = [|"127.0.0.1"|]   

# Unix.Inet_addr.(of_string_or_getbyname (Unix.gethostname()) >>| to_string);;
Exception:
(lib/monitor.ml.Error_
  ((exn (lib/core_unix.ml.Inet_addr.Get_inet_addr ip-172-30-4-59 "host not found"))
  (backtrace (""))
  (monitor
    (((name try_with) (here ()) (id 19) (has_seen_error true) (is_detached true) (kill_index 0)))))).

# Unix.Host.getbyname (Unix.gethostname());;
- : Unix.Host.t option = None 

David Scott

unread,
Feb 24, 2015, 2:38:59 PM2/24/15
to ocaml...@googlegroups.com
Would it be cheating to use a binding to getifaddrs, such as this one:


Dave
--
Dave Scott

Ashish Agarwal

unread,
Feb 24, 2015, 2:39:33 PM2/24/15
to ocaml...@googlegroups.com
But this one does. Thanks.

# ok_exn Linux_ext.get_ipv4_address_for_interface "eth0";;
- : bytes = "172.30.4.59"

That's good enough for my current needs since I know the interface name, but this seemed harder than it should have been.


Ashish Agarwal

unread,
Feb 24, 2015, 2:40:43 PM2/24/15
to ocaml...@googlegroups.com
I haven't used ocaml-tuntap, but I'll take a look at that too. Thanks.

Malcolm Matalka

unread,
Feb 25, 2015, 8:44:39 AM2/25/15
to ocaml...@googlegroups.com
Which address do you mean? Machines can have N. Are you trying to
determine what address you have when connecting to a specific machine?

David House

unread,
Feb 25, 2015, 9:16:40 AM2/25/15
to ocaml...@googlegroups.com
I think a given network interface usually (always?) has at most one IPv4 address. He wants that address for his "primary" network interface, where "primary" is a loose term that I can't define precisely but I could probably write a decent heuristic that picks it out from the list of all network interfaces in 99% of cases :)

Patrick Hahn

unread,
Feb 25, 2015, 9:25:54 AM2/25/15
to ocaml...@googlegroups.com
Linux network interfaces can have an arbitrary number of IP addresses, both v4 and v6: 


Usually though, yeah one per interface. 

--
Patrick Hahn

Ashish Agarwal

unread,
Feb 25, 2015, 9:46:02 AM2/25/15
to ocaml...@googlegroups.com
My need is to have worker nodes report to a server their own identity, so that the server now knows how to reach them.

Sebastien Mondet

unread,
Feb 25, 2015, 9:58:33 AM2/25/15
to ocaml...@googlegroups.com

When they connect to the server, they should already be giving their address as part of TCP (or UCP)
http://caml.inria.fr/pub/docs/manual-ocaml/libref/Unix.html#VALgetpeername
it should be the address that the server "sees/understands" (no need to guess the network interface)

Malcolm Matalka

unread,
Feb 25, 2015, 10:06:47 AM2/25/15
to ocaml...@googlegroups.com

The server has their address from the connection.

Ashish Agarwal

unread,
Feb 25, 2015, 10:11:37 AM2/25/15
to ocaml...@googlegroups.com
For what I'm doing right now, I don't create a client-server connection. I'm just having the worker node report itself to a database.

Malcolm Matalka

unread,
Feb 25, 2015, 10:14:39 AM2/25/15
to ocaml...@googlegroups.com

I believe you can create a udp socket and send a packet to the server and the use the api Sebastian pointed out to get your ip for that socket.  This doesn't require the server doing anything.

But this is bound to be a pain in the but for any realistic setup.

Ashish Agarwal

unread,
Feb 25, 2015, 10:20:31 AM2/25/15
to ocaml...@googlegroups.com
It seems wrong to create a connection just to get the IP address of the node I'm on. There has to be a better way.

Malcolm Matalka

unread,
Feb 25, 2015, 10:29:51 AM2/25/15
to ocaml...@googlegroups.com
I think you are only considering the extremely simple case which you
have. But consider all the layers you actually have. At the very
least, your interface, of which you can have many and each with a
different IP. Each interface can have multiple IPs. And then which of
these is actually used depends on your routing table.

It may seem wrong, but if you go by the end-to-end principle, it gets
you the answer you want by executing all of the layers between you and a
machine.

David House

unread,
Feb 25, 2015, 10:33:43 AM2/25/15
to ocaml...@googlegroups.com
And of course if there is NAT in the way then the worker has no chance of knowing what address the server should use. Although it sounds like we have a solution for the simple case at this point.

-David

Ashish Agarwal

unread,
Feb 25, 2015, 10:36:35 AM2/25/15
to ocaml...@googlegroups.com
I see your point, but right now I am indeed doing something quick and dirty.

Malcolm Matalka

unread,
Feb 25, 2015, 10:44:55 AM2/25/15
to ocaml...@googlegroups.com
Then I don't see why you're complaining that the solution I suggested is
dirty. Perhaps it's not quick enough? ;)

Ashish Agarwal

unread,
Feb 25, 2015, 10:52:14 AM2/25/15
to ocaml...@googlegroups.com
Well, I already got a solution for my needs: Linux_ext.get_ipv4_address_for_interface.

But then we're talking about how to do this in more general settings. The main question is "what is/are my ip address(es)"? Creating a connection with a particular server can't be the way to answer that. Whatever getifaddrs is doing is probably the answer I'm looking for.


Malcolm Matalka

unread,
Feb 25, 2015, 10:57:44 AM2/25/15
to ocaml...@googlegroups.com
Sorry, I was hoping my winky smiley would giving away the sarcasm in my
written tone, but alas no dice.

Re: this can't possibly be the answer - this is the only solution I've
found that works over many years. Even getting your interface addresses
doesn't tell you which address is selected when you try to talk to a
particular machine. It's really not that nasty of a solution if you
think about it, it's exercising all of the code you will be using to
talk to another.

But sorry for dragging this on, you've got a solution and I'm just
spamming people here by responding. Happy hacking!

Ashish Agarwal

unread,
Feb 25, 2015, 11:09:51 AM2/25/15
to ocaml...@googlegroups.com
I appreciate the discussion! Thanks. I obviously need to read a lot more about all this.

Reply all
Reply to author
Forward
0 new messages