View Source VintageNet (vintage_net v0.13.5)
VintageNet
is network configuration library built specifically for Nerves
Project devices. It has the following features:
- Ethernet and WiFi support included. Extendible to other technologies
- Default configurations specified in your Application config
- Runtime updates to configurations are persisted and applied on next boot (can be disabled)
- Simple subscription to network status change events
- Connect to multiple networks at a time and prioritize which interfaces are used (Ethernet over WiFi over cellular)
- Internet connection monitoring and failure detection (currently slow and simplistic)
See github.com/nerves-networking/vintage_net for more information.
Summary
Types
IP addresses in VintageNet can be specified as strings or tuples
Valid options for VintageNet.configure/3
Interface connection status
A name for the network interface
Valid options for VintageNet.info/1
Interface type
The number of bits to use for an IPv4 subnet
The number of bits to use for an IPv6 subnet
A pattern for matching against VintageNet properties
The number of IP address bits for the subnet
A VintageNet property
A property's value
Functions
Return a list of all interfaces on the system
Check if this is a valid configuration
Update the configuration of a network interface
Return a list of configured interface
Deconfigure and persists (by default) settings for a specified interface.
Get the current value of a network property
Get a list of all properties matching the specified prefix
Return the settings for the specified interface
Print the current network status
Run a command on a network interface
Get a list of all properties matching a pattern
Return the maximum number of interfaces controlled by VintageNet
Configure an interface to use the defaults
Initiate an access point scan on a wireless interface
Subscribe to property change messages
Stop subscribing to property change messages
Check that the system has the required programs installed
Types
@type any_ip_address() :: String.t() | :inet.ip_address()
IP addresses in VintageNet can be specified as strings or tuples
While VintageNet uses IP addresses in tuple form internally, it can be cumbersome to always convert to tuple form in practice. The general rule is that VintageNet is flexible in how it accepts IP addresses, but if you get an address from a VintageNet API, it will be in tuple form.
@type configure_options() :: [{:persist, boolean()}]
Valid options for VintageNet.configure/3
:persist
- Whether or not to save the configuration (defaults totrue
)
@type connection_status() :: :lan | :internet | :disconnected
Interface connection status
:disconnected
- The interface doesn't exist or it's not connected:lan
- The interface is connected to the LAN, but may not be able reach the Internet:internet
- Packets going through the interface should be able to reach the Internet
@type ifname() :: String.t()
A name for the network interface
Names depend on the device drivers and any software that may rename them. Typical names on Nerves are:
- "eth0", "eth1", etc. for wired Ethernet interfaces
- "wlan0", etc. for WiFi interfaces
- "ppp0" for cellular modems
- "usb0" for gadget USB virtual Ethernet interfaces
@type info_options() :: [{:redact, boolean()}]
Valid options for VintageNet.info/1
:redact
- Whether to hide passwords and similar information from the output (defaults totrue
)
@type interface_type() :: :ethernet | :wifi | :mobile | :local | :unknown
Interface type
This is a coarse characterization of a network interface that can be useful for prioritizing interfaces.
:ethernet
- Wired-based networking. Generally expected to be fast.:wifi
- Wireless networking. Expected to be not as fast as Ethernet,:mobile
- Cellular-based networking. Expected to be metered and slower than:wifi
and:ethernet
:local
- Interfaces that never route to other hosts:unknown
- Catch-all when the network interface can't be categorized
These are general categories that are helpful for VintageNet's default
routing prioritization. See VintageNet.Route.DefaultMetric
for more
information on the use.
@type ipv4_prefix_length() :: 0..32
The number of bits to use for an IPv4 subnet
For example, if you have a subnet mask of 255.255.255.0, then the prefix length would be 24.
@type ipv6_prefix_length() :: 0..128
The number of bits to use for an IPv6 subnet
@type pattern() :: [String.t() | :_ | :"$"]
A pattern for matching against VintageNet properties
Patterns are used when subscribing for network property changes or getting a set of properties and their values.
Since properties are organized hierarchically, the default way of matching patterns is to match on prefixes. It's also
possible to use the :_
wildcard to match anything at a position.
@type prefix_length() :: ipv4_prefix_length() | ipv6_prefix_length()
The number of IP address bits for the subnet
@type property() :: [String.t()]
A VintageNet property
VintageNet uses lists of strings to name networking configuration and status items.
@type value() :: any()
A property's value
See the README.md
for documentation on available properties.
Functions
@spec all_interfaces() :: [ifname()]
Return a list of all interfaces on the system
Check if this is a valid configuration
This runs the validation routines for a settings map, but doesn't try to apply them.
@spec configure(ifname(), map(), configure_options()) :: :ok | {:error, any()}
Update the configuration of a network interface
Configurations are validated and normalized before being applied. This means
that type errors and missing required fields will be caught and old or
redundant ways of specifying configurations will be fixed. Call
get_configuration/1
to see how what changes, if any, were made as part of
the normalization process.
After validation, the configuration is optionally persisted and applied.
See the VintageNet
documentation for configuration examples or your
VintageNet.Technology
provider's docs.
Options:
:persist
- set tofalse
to avoid persisting this configuration. System restarts will revert to the previous configuration. Defaults to true.
@spec configured_interfaces() :: [ifname()]
Return a list of configured interface
@spec deconfigure(ifname(), configure_options()) :: :ok | {:error, any()}
Deconfigure and persists (by default) settings for a specified interface.
Supports same options as configure/3
Get the current value of a network property
See get_by_prefix/1
for exact prefix matches (i.e., get all properties for one
interface) and match/1
to run wildcard matches (i.e., get a specific
property for all interfaces).
Get a list of all properties matching the specified prefix
To get a list of all known properties and their values, call
VintageNet.get_by_prefix([])
Return the settings for the specified interface
@spec info(info_options()) :: :ok
Print the current network status
Options include:
:redact
- Set tofalse
to print out passwords
Run a command on a network interface
Commands are mostly network interface-specific. Also see the VintageNet
PropertyTable fo getting status or registering for status changes.
Get a list of all properties matching a pattern
Patterns are list of strings that optionally specify :_
at
a position in the list to match any value.
@spec max_interface_count() :: 1..100
Return the maximum number of interfaces controlled by VintageNet
Internal constraints mean that VintageNet can't manage an arbitrary number of interfaces and knowing the max can reduce some processing. The limit is set by the application config. Unless you need over 100 network interfaces, VintageNet's use of the Linux networking API is not likely to be an issue, though.
Configure an interface to use the defaults
This configures an interface to the defaults found in the application
environment (config.exs
). If the application environment doesn't have a
default configuration, the interface is deconfigured. On reboot, the
interface will continue to use the defaults and if a new version of firmware
updates the defaults, it will use those.
Initiate an access point scan on a wireless interface
The scan results are posted asynchronously to the ["interface", ifname, "wifi", "access_points"]
property as they come in. After waiting a second or two they can be fetched via
VintageNet.get(["interface", ifname, "wifi", "access_points"])
.
It appears that there's some variation in how scanning is implemented on WiFi adapters. One
strategy that seems to work is to call scan/1
every 10 seconds or so while prompting a user to
pick a WiFi network.
This is a utility function for calling the :scan
ioctl.
@spec subscribe(pattern()) :: :ok
Subscribe to property change messages
Messages have the form:
{VintageNet, property_name, old_value, new_value, metadata}
Subscriptions are prefix matches. For example, to get notified whenever a property changes on "wlan0", run this:
VintageNet.subscribe(["interface", "wlan0"])
It's also possible to match with wildcards using :_
. For example, to
get notified whenever an IP address in the system changes, do this:
VintageNet.subscribe(["interface", :_, "addresses"])
@spec unsubscribe(pattern()) :: :ok
Stop subscribing to property change messages
Check that the system has the required programs installed
NOTE: This isn't completely implemented yet!