VintageNet (vintage_net v0.11.0) View Source

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.

Link to this section Summary

Types

IP addresses in VintageNet can be specified as strings or tuples

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

The number of IP address bits for the subnet

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 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

Link to this section Types

Specs

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.

Specs

configure_options() :: [{:persist, boolean()}]

Valid options for VintageNet.configure/3

  • :persist - Whether or not to save the configuration (defaults to true)

Specs

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

Specs

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

Specs

info_options() :: {:redact, boolean()}

Valid options for VintageNet.info/1

  • :redact - Whether to hide passwords and similar information from the output (defaults to true)

Specs

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.

Specs

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.

Specs

ipv6_prefix_length() :: 0..128

The number of bits to use for an IPv6 subnet

Specs

prefix_length() :: ipv4_prefix_length() | ipv6_prefix_length()

The number of IP address bits for the subnet

Link to this section Functions

Specs

all_interfaces() :: [ifname()]

Return a list of all interfaces on the system

Link to this function

configuration_valid?(ifname, config)

View Source

Specs

configuration_valid?(ifname(), map()) :: boolean()

Check if this is a valid configuration

This runs the validation routines for a settings map, but doesn't try to apply them.

Link to this function

configure(ifname, config, options \\ [])

View Source

Specs

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 to false to avoid persisting this configuration. System restarts will revert to the previous configuration.

Specs

configured_interfaces() :: [ifname()]

Return a list of configured interface

Link to this function

deconfigure(ifname, options \\ [])

View Source

Specs

deconfigure(ifname(), configure_options()) :: :ok | {:error, any()}

Deconfigure settings for a specified interface.

Supports same options as configure/3

Link to this function

get(name, default \\ nil)

View Source

Specs

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).

Specs

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([])

Link to this function

get_configuration(ifname)

View Source

Specs

get_configuration(ifname()) :: map()

Return the settings for the specified interface

Specs

info([info_options()]) :: :ok

Print the current network status

Options include:

  • :redact - Set to false to print out passwords
Link to this function

ioctl(ifname, command, args \\ [])

View Source

Specs

ioctl(ifname(), atom(), any()) :: :ok | {:ok, any()} | {:error, any()}

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.

Specs

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.

Specs

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.

Link to this function

reset_to_defaults(ifname)

View Source

Specs

reset_to_defaults(ifname()) :: :ok | {:error, any()}

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.

Specs

scan(ifname()) :: :ok | {:error, any()}

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. 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.

Specs

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"])

Specs

Stop subscribing to property change messages

Link to this function

verify_system(opts \\ nil)

View Source

Specs

verify_system(keyword() | nil) :: :ok | {:error, String.t()}

Check that the system has the required programs installed

NOTE: This isn't completely implemented yet!