View Source GenICMP (GenICMP v0.1.0)

Wrapper around :gen_icmp to make it more elixir friendly.

example

Example

iex(1)> {:ok, host, _host_addr, _reply_addr, _details, _payload} = GenICMP.ping("2a05:dfc2::")
iex(2)> host
{10757, 57282, 0, 0, 0, 0, 0, 0}

iex(1)> {:error, details, _, _} = GenICMP.ping("2001:db8::1")
iex(2)> details
:timeout

iex(1)> require IP
iex(2)> {:ok, host, addr, _, _, _} = GenICMP.ping("dns.google")
iex(3)> {host, IP.is_ipv4(addr)}
{"dns.google", true}
iex(4)> {:ok, host, addr, _, _, _} = GenICMP.ping("dns.google", ip_version: :inet6)
iex(5)> {host, IP.is_ipv6(addr)}
{"dns.google", true}

Link to this section Summary

Functions

Close the socket.

Change the controlling process of a socket. The controlling process will receive ICMP messages from the socket if it's in active mode.

Shorthand for echo/4 with a payload of consisting of ASCII 32 to 79.

Utility function to construct an ICMP echo request manually, this is not required to use ping/3.

Get the currently active filter for a socket. You can use GenICMP.Filter.will_pass?/2 and GenICMP.Filter.will_block?/2 to check if a packet will pass or be dropped by the filter.

Apply a packet filter to a socket. You can use GenICMP.Filter to construct a filter.

Shorthand for open/2 with default options.

Shorthand for open/2 with no options for :gen_udp.open/2

Open a socket for ICMP communication. Only the controlling process will receive ICMP messages from the socket. To change the controlling process, use controlling_process/2. You can decide whether the socket is active or passive using the {:active, boolean() | :once | N} option. If it's active, you'll receive ICMP messages to the parent process. If it's passive, you can manually receive ICMP messages using recv/2. Socket options are passed to :gen_udp.open/2.

Utility function to construct an ICMP packet manually. For an echo packet, see echo/4.

Send a single ICMP echo request to a host. A socket will be opened and closed automatically. For more information, see ping/3.

Send a single ICMP echo request to a host using the specified socket. The target can be a hostname, an IP address, or a list of those.

Manually receive messages from a socket that's not in active mode with an optional timeout (in milliseconds).

Send an ICMP echo request to an IP address over an existing socket. The socket must be opened with open/2. Only the controlling process will receive ICMP messages from the socket. To change the controlling process, use controlling_process/2.

Set options for a socket. These are passed through to :inet.setopts/2

Link to this section Types

@type host() :: hostname() | IP.addr()
@type hosts() :: [host()]
@type icmp_header() :: [icmp_header_option()]
@type icmp_header_option() ::
  {:type, icmp_type()}
  | {:code, icmp_code()}
  | {:id, id()}
  | {:sequence, sequence()}
  | {:gateway, IP.v4()}
  | {:mtu, :pkt.uint32_t()}
  | {:pointer, byte()}
  | {:ts_orig, :pkt.uint32_t()}
  | {:ts_recv, :pkt.uint32_t()}
  | {:ts_tx, :pkt.uint32_t()}
@type icmp_type() ::
  :echoreply
  | :dest_unreach
  | :source_quench
  | :redirect
  | :echo
  | :time_exceeded
  | :parameterprob
  | :timestamp
  | :timestampreply
  | :info_request
  | :info_reply
  | :address
  | :addressreply
  | byte()
@type option() ::
  {:id, id()}
  | {:sequence, sequence()}
  | {:timeout, non_neg_integer()}
  | {:data, payload()}
  | {:timestamp, boolean()}
  | {:ttl, ttl()}
  | {:filter, binary()}
  | {:ip_version, ip_version()}
@type options() :: [option()]
@type packet() :: binary()
@type response() ::
  {:ok, host(), IP.addr(), IP.addr(), details(), payload()}
  | {:error, icmp_error(), host(), IP.addr(), IP.addr(), details(), payload()}
  | {:error, :nxdomain, host(), :undefined}
  | {:error, network_error(), host(), IP.addr()}
@type responses() :: [response()]
@type result() :: response() | responses()
@type target() :: host() | hosts()

Link to this section Functions

@spec close(socket()) :: :ok

Close the socket.

Link to this function

controlling_process(socket, pid)

View Source
@spec controlling_process(socket(), pid()) :: :ok

Change the controlling process of a socket. The controlling process will receive ICMP messages from the socket if it's in active mode.

Link to this function

echo(family, id, sequence)

View Source
@spec echo(ip_version(), id(), sequence()) :: packet()

Shorthand for echo/4 with a payload of consisting of ASCII 32 to 79.

Link to this function

echo(family, id, sequence, payload)

View Source
@spec echo(ip_version(), id(), sequence(), payload()) :: packet()

Utility function to construct an ICMP echo request manually, this is not required to use ping/3.

@spec filter(socket()) :: {:ok, GenICMP.Filter.filter()} | :unsupported

Get the currently active filter for a socket. You can use GenICMP.Filter.will_pass?/2 and GenICMP.Filter.will_block?/2 to check if a packet will pass or be dropped by the filter.

@spec filter(socket(), GenICMP.Filter.filter()) :: :ok | :unsupported

Apply a packet filter to a socket. You can use GenICMP.Filter to construct a filter.

@spec open() :: GenServer.on_start()

Shorthand for open/2 with default options.

@spec open(options()) :: GenServer.on_start()

Shorthand for open/2 with no options for :gen_udp.open/2

Link to this function

open(options, socket_options)

View Source
@spec open(options(), [:gen_udp.option()]) :: GenServer.on_start()

Open a socket for ICMP communication. Only the controlling process will receive ICMP messages from the socket. To change the controlling process, use controlling_process/2. You can decide whether the socket is active or passive using the {:active, boolean() | :once | N} option. If it's active, you'll receive ICMP messages to the parent process. If it's passive, you can manually receive ICMP messages using recv/2. Socket options are passed to :gen_udp.open/2.

@spec packet(icmp_header(), payload()) :: packet()

Utility function to construct an ICMP packet manually. For an echo packet, see echo/4.

Link to this function

ping(target, options \\ [])

View Source
@spec ping(target(), options()) :: result()

Send a single ICMP echo request to a host. A socket will be opened and closed automatically. For more information, see ping/3.

Link to this function

ping(socket, target, options)

View Source
@spec ping(socket(), hosts(), options()) :: responses()
@spec ping(socket(), host(), options()) :: response()

Send a single ICMP echo request to a host using the specified socket. The target can be a hostname, an IP address, or a list of those.

This will set the socket to {:active, true} before sending, and {:active, false} after receiving automatically. You can pass in the :ip_version option to specify which IP version to use. It'll mostly affect the DNS lookup if you specify a domain name instead of an IP. This will try to auto detect any IPv6 IPs and fallback to IPv4 if it doesn't find any.

Link to this function

recv(socket, length, timeout \\ :infinity)

View Source
@spec recv(socket(), non_neg_integer(), timeout()) ::
  {:ok, {IP.addr(), binary() | charlist()}} | gen_udp_error()

Manually receive messages from a socket that's not in active mode with an optional timeout (in milliseconds).

Link to this function

send(socket, addr, packet)

View Source
@spec send(socket(), IP.addr(), packet()) :: :ok | gen_udp_error()

Send an ICMP echo request to an IP address over an existing socket. The socket must be opened with open/2. Only the controlling process will receive ICMP messages from the socket. To change the controlling process, use controlling_process/2.

Link to this function

setopts(socket, options)

View Source
@spec setopts(socket(), [:gen_udp.option()]) :: :ok | {:error, :inet.posix()}

Set options for a socket. These are passed through to :inet.setopts/2