Packages
vintage_net
0.2.2
0.13.12
0.13.11
0.13.10
0.13.9
0.13.8
0.13.7
0.13.6
0.13.5
0.13.4
0.13.3
0.13.2
0.13.1
0.13.0
0.12.2
0.12.1
0.12.0
0.11.5
0.11.4
0.11.3
0.11.2
0.11.1
0.11.0
0.10.5
0.10.4
0.10.3
0.10.2
0.10.1
0.10.0
0.9.3
0.9.2
0.9.1
0.9.0
0.8.0
0.7.9
0.7.8
0.7.7
0.7.6
0.7.5
0.7.4
0.7.3
0.7.2
0.7.1
0.7.0
0.6.6
0.6.5
0.6.4
0.6.3
0.6.2
0.6.1
0.6.0
0.5.1
0.5.0
0.4.1
0.4.0
0.3.1
0.3.0
0.2.4
0.2.3
0.2.2
0.2.1
0.2.0
0.1.0
Network configuration and management for Nerves
Current section
Files
Jump to
Current section
Files
vintage_net
README.md
README.md
# 🍇 VintageNet[](https://circleci.com/gh/nerves-networking/vintage_net)[](https://coveralls.io/github/nerves-networking/vintage_net?branch=master)[](https://hex.pm/packages/vintage_net)> **_NOTE:_** This library is very much a work in progress without sufficient> documentation. It will get there, but the current Nerves libraries are much> more stable, tested for what they do, and integrated into most other Nerves> libraries and examples. Most importantly, the official Nerves systems do not> contain some of the programs and kernel configuration needed to make this> work.`VintageNet` is network configuration library built specifically for [NervesProject](https://nerves-project.org) 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 (configurations are obfuscated by default to hide WiFi passphrases)* 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)The following network configurations are supported:* [x] Wired Ethernet, IPv4 DHCP* [ ] Wired Ethernet, IPv4 static IP* [x] WiFi password-less and WEP* [x] WPA2 PSK and EAP* [ ] USB gadget mode Ethernet, IPv4 DHCP server to supply host IP address* [ ] Cellular networks* [x] WiFi AP mode* [ ] IPv6`VintageNet` takes a different approach to networking from `nerves_network`. Itsupports calling "old school" Linux utilities like `ifup` and `ifdown` toconfigure networks. While this isn't ideal, some network configurations are onlydocumented for Linux systems and this can be a huge timesaver for getting anunusual network configuration working. `VintageNet` supports a migration path topulling configuration back into Elixir piecemeal. Additionally, `VintageNet`doesn't attempt to make incremental modifications to configurations. Itcompletely tears down an interface's connection and then brings up newconfigurations in a fresh state. Network reconfiguration is assumed to be aninfrequent event so while this can cause a hiccup in the network connectivity,it removes most of the state machine code that made `nerves_network` hard tomaintain.## InstallationThe `vintage_net` and `nerves_init_gadget` packages are not compatible. If youare using `nerves_init_gadget`, you will need to remove it from your dependencylist and add back in things it supplies like `nerves_runtime` and`nerves_firmware_ssh`.When [available in Hex](https://hex.pm/docs/publish), the package can beinstalled by adding `vintage_net` to your list of dependencies in `mix.exs`:```elixirdef deps do [ {:vintage_net, "~> 0.1.0", targets: @all_targets} ]end```Erlang/OTP provides many libraries for debugging networking issues. You may alsowant to add [Toolshed](https://github.com/fhunleth/toolshed) to your dependenciesso that you can have more familiar looking tools like `ifconfig` and `ping` atthe IEx prompt.## Configuration`VintageNet` has many application configuration keys. Most defaults are fine. Ata minimum, you'll want to specify a default configuration and default regulatorydomain if using WiFi. In your main `config.exs`, add the following:```elixirconfig :vintage_net, regulatory_domain: "US", config: [ {"eth0", %{type: VintageNet.Technology.Ethernet, ipv4: %{method: :dhcp}}}, {"wlan0", %{type: VintageNet.Technology.WiFi}} ]```This sets the regulatory domain to the US (set to your [ISO 3166-1 alpha-2country code](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2). This code ispassed on to the drivers for WiFi and other wireless networking technologies sothat they comply with local regulations. If you need a global default, set to"00" or don't set at all. Unfortunately, this may mean that an access pointisn't visible if it is running on a frequency that's allowed in your country,but not globally.The `config` section is a list of network configurations. The one shown aboveconfigures DHCP on wired Ethernet and minimally starts up a WiFi LAN so thatit's possible to scan for networks. Details on network configuration aredescribed later.The following table describes the other application config keys.Key | Description ----------------- | ---------------------------config | A list of default network configurationstmpdir | Path to a temporary directory for VintageNetto_elixir_socket | Name to use for the Unix domain socket for C to Elixir communicationbin_ifup | Path to `ifup`bin_ifdown | Path to `ifdown`bin_chat | Path to `chat`bin_pppd | Path to `pppd`bin_mknod | Path to `mknod`bin_killall | Path to `killall`bin_wpa_supplicant | Path to `wpa_supplicant`bin_wpa_cli | Path to `wpa_cli`bin_ip | Path to `ip`udhcpc_handler | Module for handling notifications from `udhcpc`resolvconf | Path to `/etc/resolv.conf`persistence | Module for persisting network configurationspersistence_dir | Path to a directory for storing persisted configurationspersistence_secret | A 16-byte secret or an MFA for getting a secretinternet_host | IP address for host to `ping` to check for Internet connectivityregulatory_domain | ISO 3166-1 alpha-2 country (`00` for global, `US`, etc.)## Network interface configuration`VintageNet` supports several network technologies out of the box andthird-party libraries can provide more via the `VintageNet.Technology`behaviour.Configurations are Elixir maps. These are specified in three places:1. The `vintage_net` application config (e.g., your `config.exs`)2. Locally saved configuration (see the `VintageNet.Persistence` behaviour for replacing the default)3. Calling `VintageNet.configure/2` to change the configuration at run-timeWhen `vintage_net` starts, it applies saved configurations first and if anything is wrong with those configs, it reverts to the application config. A goodpractice is to have safe defaults for all network interfaces in the applicationconfig.The only required key in the configuration maps is `:type`. All other keysfollow from the type. `:type` should be set to a module that implements the`VintageNet.Technology` behaviour. The following are included:* `VintageNet.Technology.Ethernet` - Standard wired Ethernet* `VintageNet.Technology.WiFi` - Client configurations for 802.11 WiFi* `VintageNet.Technology.Mobile` - Cellular configurations (likely to be refactored to a separate library)* `VintageNet.Technology.Null` - An empty configuration useful for turning off a configurationThe following sections describe the types in more detail.### Wired EthernetWired Ethernet interfaces typically have names like `"eth0"`, `"eth1"`, etc.when using Nerves.Currently only IPv4 support using DHCP is supported:```elixir%{type: VintageNet.Technology.Ethernet, ipv4: %{method: :dhcp}}```For example, to set the configuration at runtime:```elixiriex> VintageNet.configure("eth0", %{type: VintageNet.Technology.Ethernet, ipv4: %{method: :dhcp}}):ok```Wired Ethernet connections are monitored for Internet connectivity. Wheninternet-connected, they are preferred over all other network technologies evenwhen the others provide default gateways.### WiFiWiFi network interfaces typically have names like `"wlan0"` or `"wlan1"` whenusing Nerves. Most of the time, there's only one WiFi interface and its`"wlan0"`. Some WiFi adapters expose separate interfaces for 2.4 GHz and 5 GHzand they can be configured independently.WiFi configuration looks like this:```elixir%{ type: VintageNet.Technology.WiFi, wifi: %{ key_mgmt: :wpa_psk, mode: :client, psk: "a_passphrase_or_psk", ssid: "my_network_ssid" }, ipv4: %{method: :dhcp}}```The `:ipv4` key is the same as in Wired Ethernet and only DHCP is currentlysupported.The `:wifi` key has the following common fields:* `:key_mgmt` - WiFi security mode (`:wpa_psk` for WPA2, `:none` for no password)* `:mode` - * `:client` (default) - Normal operation. Associate with an AP * `:adhoc` - peer to peer mode * `:host` - access point mode* `:psk` - A WPA2 passphrase or the raw PSK. If a passphrase is passed in, it will be converted to a PSK and disgarded.* `:ssid` - The SSID for the networkSee the [officialdocs](https://w1.fi/cgit/hostap/plain/wpa_supplicant/wpa_supplicant.conf) forthe complete list of options.Here's an example:```elixiriex> VintageNet.configure("wlan0", %{ type: VintageNet.Technology.WiFi, wifi: %{ key_mgmt: :wpa_psk, mode: :client, psk: "a_passphrase_or_psk", ssid: "my_network_ssid" }, ipv4: %{method: :dhcp} })```Example of WEP:```elixiriex> VintageNet.configure("wlan0", %{ type: VintageNet.Technology.WiFi, wifi: %{ ssid: "my_network_ssid", wep_key0: "42FEEDDEAFBABEDEAFBEEFAA55", key_mgmt: :none, wep_tx_keyidx: 0 }, ipv4: %{method: :dhcp} })```Example of WPA-EAP:```elixiriex> VintageNet.configure("wlan0", %{ type: VintageNet.Technology.WiFi, wifi: %{ ssid: "testing", key_mgmt: :wpa_eap, scan_ssid: 1, pairwise: "CCMP TKIP", group: "CCMP TKIP", eap: "PEAP", identity: "user1", password: "supersecret", phase1: "peapver=auto", phase2: "MSCHAPV2" }, ipv4: %{method: :dhcp}})```Example of access point mode:```elixiriex> VintageNet.configure("wlan0", %{ type: VintageNet.Technology.WiFi, wifi: %{ mode: :host, ssid: "test ssid", key_mgmt: :none }, ipv4: %{ method: :static, address: "192.168.24.1", netmask: "255.255.255.0", gateway: "192.168.24.1" }, dhcpd: %{ start: "192.168.24.2", end: "192.168.24.10" }})```### LTE```elixir```## Properties`VintageNet` maintains a key/value store for retrieving information onnetworking information:```elixiriex> VintageNet.get(["interface", "eth0", "connection"]):internetiex> VintageNet.get_by_prefix([])[ {["interface", "eth0", "connection"], :internet}, {["interface", "eth0", "state"], :configured}, {["interface", "eth0", "type"], VintageNet.Technology.Ethernet}, {["interface", "wlan0", "connection"], :internet}, {["interface", "wlan0", "state"], :configured}, {["interface", "wlan0", "type"], VintageNet.Technology.WiFi}]```You can also subscribe to keys and receive a message every time it or one itschild keys changes:```elixiriex> VintageNet.subscribe(["interface", "eth0"]):okiex> flush{VintageNet, ["interface", "eth0", "state"], :configuring, :configured, %{}}```The message format is `{VintageNet, name, old_value, new_value, metadata}`### Global propertiesProperty | Values | Description --------------------- | ---------------- | -----------`available_interfaces` | `[eth0, ...]` | Currently available network interfaces in priority order. E.g., the first one is used by default`connection` | `:disconnected`, `:lan`, `:internet` | The overall network connection status. This is the best status of all interfaces.### Common network interface propertiesAll network interface properties can be found under `["interface", ifname]` inthe `PropertyTable`. The following table lists out properties common to allinterfaces:Property | Values | Description ----------- | ---------------- | -----------`type` | `VintageNet.Technology.Ethernet`, etc. | The type of the interface`state` | `:configured`, `:configuring`, etc. | The state of the interface from `VintageNet`'s point of view.`connection` | `:disconnected`, `:lan`, `:internet` | This provides a determination of the Internet connection status`ipv4` | IPv4 parameters | This is a map of IPv4 parameters on the interface. This includes IP address, subnet, gateway, etc.Specific types of interfaces provide more parameters.### Wired Ethernet statusNo additional parameters### WiFi statusProperty | Values | Description ----------- | ---------------- | -----------### LTE statusProperty | Values | Description ----------- | ---------------- | -----------`signal` | 0 - 100 | This is a rough measure of signal strength from 0 (none) to 100 (all bars)## System Requirements### Busybox Requirements* `CONFIG_UDHCPC=y` - `udhcpc` DHCP Client* `CONFIG_UDHCPD=y` - `udhcpd` DHCP Server (optional)* `CONFIG_IFUP=y` - `ifup`* `CONFIG_IFDOWN=y` `ifdown`* `CONFIG_RUN_PARTS=y`* `CONFIG_MKTEMP=y`### Buildroot Requirements* `BR2_PACKAGE_WPA_SUPPLICANT`* `BR2_PACKAGE_WPA_SUPPLICANT_CLI`### Additional Requirements for Access Point Mode* `BR2_PACKAGE_DNSMASQ` or `CONFIG_UDHCPD` (in busybox)* `BR2_PACKAGE_HOSTAPD` or `BR2_PACKAGE_WPA_SUPPLICANT_HOTSPOT`### Additional Requirements for LTE#### Kernel modules (defconfig)* `CONFIG_PPP=m`* `CONFIG_PPP_BSDCOMP=m`* `CONFIG_PPP_DEFLATE=m`* `CONFIG_PPP_ASYNC=m`* `CONFIG_PPP_SYNC_TTY=m`* `CONFIG_USB_NET_CDC_NCM=m`* `CONFIG_USB_NET_HUAWEI_CDC_NCM=m`* `CONFIG_USB_SERIAL_OPTION=m`#### System deps* `pppd`* `mknod`