net(3)

πŸ“¦
version 29.0.6 Β· 3 versions
, in ubuntu stonking

πŸ’– net β€” the network interface module (net(3), bestie!!)

okay so real talk, this is net from Erlang's kernel application, and it's basically your ride-or-die for talking to the network interface layer. let's get into it πŸ¦‹


✨ NAME ✨

net β€” Network interface. that's it, that's the whole vibe. she's the network interface module and she knows it πŸ’…


🌸 DESCRIPTION 🌸

This module provides an API for the network interface.

like, that's the whole point. it's the doorway between your Erlang code and the actual network-y stuff happening underneath. slay ✨


πŸŽ€ DATA TYPES πŸŽ€

okay bestie, this is the part where we define all the shapes of things. buckle up, there's a bunch, but every single one matters πŸ’–

address_info()

address_info() ::
          #{family := socket:domain(),
            socktype := any | socket:type() | integer(),
            protocol := socket:protocol(),
            address := socket:sockaddr()}.

the lil info map that describes an address. all four keys are mandatory (the := is giving demands, honestly πŸ‘‘).


ifaddrs()

ifaddrs() ::
          #{name := string(),
            flags := ifaddrs_flags(),
            addr => socket:sockaddr(),
            netmask => socket:sockaddr(),
            broadaddr => socket:sockaddr(),
            dstaddr => socket:sockaddr()}.

Interface addresses and flags.

This type defines addresses and flags for an interface.

NOTE: Not all fields of this map has to be present. The flags field can be used to test for some of the fields. For example broadaddr will only be present if the broadcast flag is present in flags.

so like, name and flags are non-negotiable, but the address-y ones are optional (=> = maybe, := = mandatory, iykyk). the flags field is literally your little cheat sheet for figuring out which of the optional fields showed up to the party 🫢


ifaddrs_filter()

ifaddrs_filter() ::
          all | default | inet | inet6 | packet | link | hwaddr |
          ifaddrs_filter_map() |
          ifaddrs_filter_fun().

Interface address filtering selector. here's what each one means, bestie:

  • all β€” All interfaces
  • default β€” Interfaces with address family inet or inet6
  • inet | inet6 | packet | link β€” Interfaces with only the specified address family
  • hwaddr β€” Interfaces with address family packet or link

ifaddrs_filter_fun()

ifaddrs_filter_fun() :: fun((ifaddrs()) -> boolean()).

Interface address filtering selector function/0.

For each ifaddrs entry, return either true to keep the entry or false to discard the entry.

For example, to get an interface list which only contains non-loopback inet interfaces:

net:getifaddrs(
    fun (#{ addr  := #{family := inet},
            flags := Flags}) ->
          not lists:member(loopback, Flags);
        (_) ->
          false
    end).

see how she pattern matches and then falls through to false for everything else? that's the move. iconic πŸ’…


ifaddrs_filter_map()

ifaddrs_filter_map() ::
          #{family :=
                all | default | local | inet | inet6 | packet | link |
                [local | inet | inet6 | packet | link],
            flags := any | [ifaddrs_flag()]}.

Interface address filtering selector map.

The family field can only have the (above) specified values (and not all the values of socket:domain()). It can also be a list of values, to cover the situation when any of the specified families are accepted. For example, family can be set to [inet,inet6] if either inet or inet6 is accepted.

The use of the flags field is that any flag provided must exist for the interface.

For example, if family is set to inet and flags to [broadcast, multicast] only interfaces with address family inet and the flags broadcast and multicast will be listed.


ifaddrs_flag()

ifaddrs_flag() ::
          up | broadcast | debug | loopback | pointopoint | notrailers |
          running | noarp | promisc | master | slave | multicast |
          portsel | automedia | dynamic.

the full menu of flags, no substitutions πŸ“


ifaddrs_flags()

ifaddrs_flags() :: [ifaddrs_flag()].

just a list of those. simple, clean, correct.


name_info()

name_info() :: #{host := string(), service := string()}.

the host + service map you get back from the name lookups 🌸


name_info_flag()

name_info_flag() ::
          namereqd | dgram | nofqdn | numerichost | numericserv.

name_info_flag_ext()

name_info_flag_ext() :: idn.

an extension flag, just the one, she's special ✨


name_info_flags()

name_info_flags() :: [name_info_flag() | name_info_flag_ext()].

network_interface_index()

network_interface_index() :: non_neg_integer().

network_interface_name()

network_interface_name() :: string().

πŸ‘‘ FUNCTIONS πŸ‘‘

here's where it gets fun. every single clause, every single spec, all of it, let's gooo πŸ”₯


getaddrinfo/2

getaddrinfo(Host, undefined) -> {ok, Info} | {error, Reason}
                     when
                         Host :: string(),
                         Info :: [address_info()],
                         Reason :: term();
                 (undefined, Service) -> {ok, Info} | {error, Reason}
                     when
                         Service :: string(),
                         Info :: [address_info()],
                         Reason :: term();
                 (Host, Service) -> {ok, Info} | {error, Reason}
                     when
                         Host :: string(),
                         Service :: string(),
                         Info :: [address_info()],
                         Reason :: term().

Network address and service translation.

This function is the inverse of getnameinfo. It converts host and service to a corresponding socket address.

One of the Host and Service may be undefined but not both.

so like β€” you can absolutely be mysterious and leave one blank, but NOT both. both is a hard no πŸ™ˆ

gethostname/0

gethostname() -> {ok, HostName} | {error, Reason}
                     when HostName :: string(), Reason :: term().

Return the name of the current host.


getifaddrs/1

getifaddrs(Filter) -> {ok, IfAddrs} | {error, Reason}
                    when
                        Filter :: ifaddrs_filter(),
                        IfAddrs :: [ifaddrs()],
                        Reason :: term();
                (Namespace) -> {ok, IfAddrs} | {error, Reason}
                    when
                        Namespace :: file:filename_all(),
                        IfAddrs :: [ifaddrs()],
                        Reason :: term().

Get interface addresses.

  • With argument Filter: get the machines interface addresses, filtered according to Filter.
  • With argument Namespace: equivalent to getifaddrs(default, Namespace).

getifaddrs/2

getifaddrs(Filter, Namespace) -> {ok, IfAddrs} | {error, Reason}
                    when
                        Filter :: ifaddrs_filter(),
                        Namespace :: file:filename_all(),
                        IfAddrs :: [ifaddrs()],
                        Reason :: term().

Get interface addresses in a namespace.

The same as getifaddrs(Filter) but in the specified Namespace.


getnameinfo/2

getnameinfo(SockAddr, Flags) -> {ok, Info} | {error, Reason}
                     when
                         SockAddr :: socket:sockaddr(),
                         Flags :: name_info_flags() | undefined,
                         Info :: name_info(),
                         Reason :: term().

Address-to-name translation in a protocol-independant manner.

This function is the inverse of getaddrinfo. It converts a socket address to a corresponding host and service.


getservbyname/2

getservbyname(Name, Protocol) ->
                       {ok, PortNumber} | {error, Reason}
                       when
                           Name :: atom() | string(),
                           PortNumber :: socket:port_number(),
                           Protocol :: any | socket:protocol(),
                           Reason :: term().

Get service by name.

This function is used to get the port number of the specified protocol for the named service.


getservbyport/2

getservbyport(PortNumber, Protocol) ->
                       {ok, Name} | {error, Reason}
                       when
                           PortNumber :: socket:port_number(),
                           Protocol :: any | socket:protocol(),
                           Name :: atom() | string(),
                           Reason :: term().

Get service by name.

This function is used to get the service name of the specified protocol for the given port number.


if_index2name/1

if_index2name(Idx) -> {ok, Name} | {error, Reason}
                       when
                           Idx :: network_interface_index(),
                           Name :: network_interface_name(),
                           Reason :: term().

Mappings between network interface index and names.


if_name2index/1

if_name2index(Name) -> {ok, Idx} | {error, Reason}
                       when
                           Name :: network_interface_name(),
                           Idx :: network_interface_index(),
                           Reason :: term().

Mappings between network interface names and indexes.

like, if_index2name goes one way and if_name2index goes the other way. they're a matched set, obsessed with them actually 🧚


if_names/0

if_names() -> {ok, Names} | {error, Reason}
                  when
                      Names :: [{Idx, If}],
                      Idx :: network_interface_index(),
                      If :: network_interface_name(),
                      Reason :: term().

Get network interface names and indexes.


and that's the whole page, bestie!! get you a module that does both directions of the lookup and never misses πŸ’œ


kisses, and remember: one of Host and Service may be undefined but NOT BOTH πŸ’…βœ¨

this lil manual page comes to you from Ericsson AB, shipping with kernel 11.0.3, and it's filed under net(3). stan a networking module fr fr πŸ«ΆπŸ’–

πŸ“¦ where this page comes from