Return types of os:type/0 and default route discovery

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Return types of os:type/0 and default route discovery

zxq9-2
I'm writing a convenience function to discover the default gateway,
network interface and local source IP address of the host machine.
Lacking a native interface to this within the runtime and needing it to
be as broadly cross platform as possible I'm currently thinking to check
the value of os:type/0 and issue the current system's default equivalent
of something like `os:cmd("ip route get 8.8.8.8")` and parse the output
to get the parts of the return value I need.

To do this properly I need to know what return types I should be
checking for in the OS name part of the return value, as most systems
have some differences in what default command line network information
utilities are available.

Picking an initial command to examine for IPv4 might look something like:

   default_iface() -> default_iface(os:type()).

   default_iface({unix, linux} ->
       Out = os:cmd("ip route get 8.8.8.8"),
       % get_stuff_from(Out);
   default_iface({unix, osx} ->
       Out = os:cmd("route -n get 8.8.8.8"),
       % get_stuff_from(Out);
   default_iface({unix, bsd} ->
       Out = os:cmd("netstat -r"),
       % get_stuff_from(Out);
   default_iface({windows, nt} ->
       Out = os:cmd("route -4"),
       % get_stuff_from(Out);
   default_iface({Family, Name} ->
       %...?


What else should I be looking for or be aware of? Is there a better way
to approach the problem? (Keep in mind this code needs to be purely in
Erlang, though callouts through os:cmd/1 could be anything as long as it
is guaranteed to be available by default on the target system)

Thanks,
-Craig
Reply | Threaded
Open this post in threaded view
|

Re: Return types of os:type/0 and default route discovery

zxq9-2
On 2021/02/05 16:03, zxq9 wrote:
>    default_iface({Family, Name} ->
>        %...?

I've been made aware of this in the OTP code:
https://github.com/erlang/otp/blob/ed4bc369fe6724083bd0decac961fb7b3462d202/lib/kernel/test/kernel_test_lib.erl?ts=2#L86

{unix, linux}
{unix, openbsd}
{unix, freebsd}
{unix, netbsd}
{unix, darwin}
{unix, sunos}
{win32, nt}

This isn't comprehensive, but it's probably good enough to solve the 90%
problem.

With that in mind...
What commands are the equivalent to `ip route get 8.8.8.8` on Linux
or `route -4` on Windows 10?

Both of those give me the default route, the default gateway, the
default interface and the default interface's address and subnet (or a
way I can get at all of those).

If I can just discover the default interface I can get the rest sorted
out from information in inet:getifaddrs/0.

-Craig