Ifone (Ifone v1.0.0)
View SourceiOS device USB interface discovery.
This module provides functions to discover NCM (Network Control Model) data interfaces on connected iOS devices, and to look up USB device information from network interface names.
Usage
List NCM data interfaces for a device by serial number:
iex> Ifone.list_ncm_data_interfaces("00008101000000000000001E")
{:ok, %{configuration: 5, interfaces: %{3 => "en16", 5 => "en17"}}}Or by USB location ID:
iex> Ifone.list_ncm_data_interfaces(0x02100000)
{:ok, %{configuration: 5, interfaces: %{3 => "en16", 5 => "en17"}}}Enumerate every connected device at once:
iex> Ifone.list_devices()
{:ok, %{"00008101000000000000001E" => %{configuration: 5, interfaces: %{3 => "en16", 5 => "en17"}}}}Look up which device a network interface belongs to:
iex> Ifone.get_serial_for_interface("en16")
{:ok, "00008101000000000000001E"}Platform Support
- macOS: Uses IOKit via a NIF
- Linux: Uses sysfs traversal (pure Elixir)
Note: On Linux, USB location ID lookup is not supported — use serial numbers instead.
Summary
Types
Result of listing NCM data interfaces.
Functions
Gets the USB serial number for a network interface.
Lists all connected iOS devices and their NCM interfaces in one call.
Lists NCM data interfaces for a USB device.
Types
@type interfaces_result() :: %{ configuration: non_neg_integer(), interfaces: %{required(non_neg_integer()) => String.t() | nil} }
Result of listing NCM data interfaces.
configuration- The current USB configuration numberinterfaces- Map of USB interface number to network interface name (or nil if not yet bound)
Functions
Gets the USB serial number for a network interface.
Given a network interface name (e.g., "en16"), returns the USB serial number of the iOS device that owns that interface. This is useful for correlating network interfaces back to specific devices.
Arguments
interface_name- Network interface name (e.g., "en16")
Returns
{:ok, serial}- The USB serial number of the device{:error, :not_found}- Interface not found or not a USB NCM interface
Examples
iex> Ifone.get_serial_for_interface("en16")
{:ok, "00008101000000000000001E"}
iex> Ifone.get_serial_for_interface("lo0")
{:error, :not_found}
@spec list_devices() :: {:ok, %{required(String.t()) => interfaces_result()}} | {:error, atom()}
Lists all connected iOS devices and their NCM interfaces in one call.
Returns a map keyed by USB serial number, where each value has the same shape
as list_ncm_data_interfaces/1 — the current USB configuration and a map of
NCM interface numbers to network interface names. This is the discovery
counterpart of list_ncm_data_interfaces/1: it tells you which devices are
present without needing to know a serial number up front.
Only iOS devices are listed. On platforms where no device can be enumerated,
returns {:ok, %{}}.
Returns
{:ok, %{serial => %{configuration: N, interfaces: %{...}}}}- Connected devices{:error, reason}- Error
Examples
# macOS — interfaces keyed by CDC-Data interface number
iex> Ifone.list_devices()
{:ok, %{"00008101000000000000001E" => %{configuration: 5, interfaces: %{3 => "en16", 5 => "en17"}}}}
# Linux — interfaces keyed by CDC-Control interface number
iex> Ifone.list_devices()
{:ok, %{"00008101000000000000001E" => %{configuration: 5, interfaces: %{2 => "enx8e7aaa54ae75", 4 => "enxb60457655ed3"}}}}
iex> Ifone.list_devices()
{:ok, %{}}
@spec list_ncm_data_interfaces(String.t() | non_neg_integer()) :: {:ok, interfaces_result()} | {:error, atom()}
Lists NCM data interfaces for a USB device.
Returns the current USB configuration and a map of NCM interfaces that belong
to the specified device. Each interface is mapped to its corresponding network
interface name (e.g., "en16" on macOS or "enx8e7aaa54ae75" on Linux), or nil
if the interface exists but has no network interface bound yet.
Arguments
identifier- Either a USB serial number (string) or USB location ID (integer)
Returns
{:ok, %{configuration: N, interfaces: %{...}}}- Map with configuration and interfaces{:error, :not_found}- Device not found{:error, reason}- Other error
Platform Differences
The interface numbers in the returned map differ by platform. On macOS, network interfaces are reported on the CDC-Data interface (e.g., interface 3). On Linux, they are reported on the CDC-Control interface (e.g., interface 2). To write cross-platform code, check for both:
case Ifone.list_ncm_data_interfaces("00008101000000000000001E") do
{:ok, %{configuration: 5, interfaces: interfaces}} ->
ifname = interfaces[2] || interfaces[3]
# ...
{:error, reason} ->
# ...
endExamples
# macOS — keyed by CDC-Data interface number
iex> Ifone.list_ncm_data_interfaces("00008101000000000000001E")
{:ok, %{configuration: 5, interfaces: %{3 => "en16", 5 => "en17"}}}
# Linux — keyed by CDC-Control interface number
iex> Ifone.list_ncm_data_interfaces("00008101000000000000001E")
{:ok, %{configuration: 5, interfaces: %{2 => "enx8e7aaa54ae75", 4 => "enxb60457655ed3"}}}
iex> Ifone.list_ncm_data_interfaces(0x02100000)
{:ok, %{configuration: 5, interfaces: %{3 => "en16", 5 => "en17"}}}
iex> Ifone.list_ncm_data_interfaces("nonexistent")
{:error, :not_found}