Re: A network programming question (because why not)

Seth David Schoen <[email protected]> Fri, 12 Nov 2021 21:22:31 -0800
Newsgroups gmane.org.user-groups.linux.svlug
Message-ID <[email protected]>
Sarah Newman writes:

> Is there a better way than getaddrinfo to find out if there is usable IPv6 on Linux that doesn't involve checking /proc or /sys ? Is the only option 
> to try to actually create a socket of domain AF_INET6?
> 
> With getaddrinfo and AI_ADDRCONFIG set, the library will not return IPv6 results without an IPv6 address, but it also won't resolve a host if only 
> localhost is up and not an actual routable interface.
> 
> Without AI_ADDRCONFIG, if the libraries will resolve IPv6, getaddrinfo returns IPv6 results, even if IPv6 is disabled in the kernel and can't actually 
> be used.

I'm not totally positive what should count as "usable", since on many
systems you could validly create an AF_INET6 socket using a local
interface, yet not have any v6 routes to the Internet.  (You might still
be able to connect that socket on a link-scoped IPv6 address to another
host on the same network link.)

If you try

strace ip addr
strace ip addrlabel

you'll see netlink socket queries happening between ip and the kernel,
over which the kernel volunteers lots of information which includes
its IPv6 capabilities.  (The "ip addrlabel" part is an IPv6-specific
feature, so I think it should not even work if IPv6 is completely
unsupported.)

I predict that on a system with literally no IPv6 in the kernel at all,
you would not see any AF_INET6 references coming back in the first case.

I'm not sure how nice an interface you can get to this, and whether it
would be preferable to calling out to the ip command.  It looks like the
officially-recommended way to make netlink calls from C now is libmnl

https://netfilter.org/projects/libmnl/

but this already requires knowing a bunch of netlink to make use of.

Or if you're particularly interested in the local kernel's capabilities,
you could even do

egrep ipv?6 /proc/kallsyms

Sorry for the /proc in that last command, since you said you didn't want
to look in /proc. :-)