or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/pypi-ping3

A pure python3 version of ICMP ping implementation using raw socket.

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
pypipkg:pypi/ping3@5.1.x

To install, run

npx @tessl/cli install tessl/pypi-ping3@5.1.0

index.mddocs/

ping3

A pure Python 3 implementation of ICMP ping functionality using raw sockets. ping3 enables network connectivity testing and monitoring through both programmatic and command-line interfaces, supporting IPv4 and IPv6 protocols with comprehensive error handling and configurable options.

Package Information

  • Package Name: ping3
  • Language: Python
  • Installation: pip install ping3
  • Minimum Python Version: 3.5+

Core Imports

Basic ping functionality:

from ping3 import ping, verbose_ping

Module configuration:

import ping3
ping3.DEBUG = True        # Enable debug output (default False)
ping3.EXCEPTIONS = True   # Raise exceptions instead of returning None/False (default False)

Exception handling:

from ping3.errors import (
    PingError, Timeout, HostUnknown, 
    DestinationUnreachable, DestinationHostUnreachable,
    TimeToLiveExpired, TimeExceeded,
    AddressUnreachable, PortUnreachable
)

ICMP constants (advanced usage):

from ping3.enums import (
    ICMP_DEFAULT_CODE,
    IcmpV4Type, IcmpV6Type,
    IcmpV4DestinationUnreachableCode, IcmpV6DestinationUnreachableCode,
    IcmpTimeExceededCode
)

Basic Usage

from ping3 import ping, verbose_ping

# Simple ping - returns delay in seconds
delay = ping('example.com')
if delay is None:
    print("Timeout")
elif delay is False:
    print("Error (host unreachable or unknown)")
else:
    print(f"Ping successful: {delay:.3f}s")

# Ping with custom timeout and get result in milliseconds
delay = ping('8.8.8.8', timeout=2, unit='ms')
if delay:
    print(f"Google DNS: {delay:.1f}ms")

# IPv6 ping
delay = ping('2001:4860:4860::8888', version=6)

# Ping with custom options
delay = ping('example.com', 
             timeout=10,           # 10 second timeout
             ttl=64,              # Time-to-live
             size=128,            # Payload size in bytes
             src_addr='192.168.1.100',  # Source IP (multi-interface)
             interface='eth0',    # Linux only - network interface
             seq=5)               # ICMP sequence number

# Verbose ping (like command line ping)
verbose_ping('example.com', count=4, interval=1)
# Output:
# ping 'example.com' ... 215ms
# ping 'example.com' ... 216ms  
# ping 'example.com' ... 219ms
# ping 'example.com' ... 217ms

Architecture

ping3 implements ICMP ping functionality through a clean, socket-based architecture:

Socket Management

  • Raw Sockets: Attempts to use SOCK_RAW for full control over ICMP packet creation and parsing
  • DGRAM Fallback: Automatically falls back to SOCK_DGRAM on permission errors (Linux), where the kernel handles some ICMP details
  • Cross-Platform: Handles platform-specific socket behaviors and IP header presence/absence

Packet Flow

  1. Address Resolution: Converts domain names to IP addresses, auto-detects IPv4/IPv6
  2. Socket Creation: Creates appropriate socket type (raw/dgram) for the IP version
  3. ICMP Packet Construction: Builds ICMP header with ID, sequence, checksum, and timestamp payload
  4. Transmission: Sends packet via socket with configurable TTL, source binding, and interface selection
  5. Response Handling: Receives and parses ICMP responses, calculates round-trip time

Error Handling Strategy

  • Dual Mode: Returns None/False by default, or raises exceptions when EXCEPTIONS=True
  • Comprehensive Errors: Specific exception types for different failure modes (timeout, unreachable, TTL expired)
  • Debug Support: Optional debug output showing packet headers and transmission details

This design provides both simplicity for basic use cases and full control for advanced network diagnostics.

Capabilities

Core Ping Functions

Primary ping functionality for sending ICMP packets and measuring network latency.

def ping(dest_addr: str, timeout: int = 4, unit: str = "s", src_addr: str = "", 
         ttl=None, seq: int = 0, size: int = 56, interface: str = "", 
         version=None) -> float | None | bool:
    """
    Send one ping to destination address with configurable options.

    Parameters:
    - dest_addr (str): Destination IP address or domain name (e.g., "192.168.1.1", "example.com", "2001:db8::1")
    - timeout (int): Response timeout in seconds (default 4)
    - unit (str): Return unit "s" for seconds or "ms" for milliseconds (default "s")
    - src_addr (str): Source IP address for multi-interface systems (default "")
    - ttl (int|None): Time-To-Live value, None uses OS default (default None)
    - seq (int): ICMP packet sequence number (default 0)
    - size (int): ICMP payload size in bytes (default 56)
    - interface (str): Linux only - network interface name like "eth0" (default "")
    - version (int|None): IP version 4 or 6, None for auto-detect (default None)

    Returns:
    float|None|False: Delay in seconds/milliseconds, None on timeout, False on error

    Raises:
    PingError: Any ping-related error if ping3.EXCEPTIONS is True
    """

def verbose_ping(dest_addr: str, count: int = 4, interval: float = 0, 
                 *args, **kwargs) -> None:
    """
    Send multiple pings with formatted output display.

    Parameters:
    - dest_addr (str): Destination IP address or domain name
    - count (int): Number of pings to send, 0 for infinite loop (default 4)
    - interval (float): Seconds between pings, 0 for immediate (default 0)
    - *args, **kwargs: All ping() arguments except seq

    Returns:
    None: Prints formatted results to stdout
    """

Configuration

Global Settings

# Module-level configuration constants
DEBUG: bool        # Enable debug output (default False)
EXCEPTIONS: bool   # Raise exceptions instead of returning None/False (default False)  
LOGGER: object     # Logger instance for debug output (default None)
__version__: str   # Package version string (currently "5.1.5")

Command Line Interface

The package provides a ping3 command-line tool with full argument support:

# Basic usage
ping3 example.com

# With options
ping3 -c 10 -t 2 -i 0.5 -s 64 example.com

# IPv6 ping
ping3 -6 2001:4860:4860::8888

# Help
ping3 --help

Exception Handling

Exception Hierarchy

class PingError(Exception):
    """Base exception for all ping-related errors."""

class TimeExceeded(PingError):
    """Base exception for time-related errors."""

class TimeToLiveExpired(TimeExceeded):
    """Exception when TTL expires during routing."""
    # Attributes: ip_header, icmp_header, message

class DestinationUnreachable(PingError):
    """Base exception for unreachable destinations."""
    # Attributes: ip_header, icmp_header, message

class DestinationHostUnreachable(DestinationUnreachable):
    """Exception for unreachable hosts (IPv4)."""
    # Attributes: ip_header, icmp_header, message

class AddressUnreachable(DestinationUnreachable):
    """Exception for unreachable IPv6 addresses."""
    # Attributes: ip_header, icmp_header, message

class PortUnreachable(DestinationUnreachable):
    """Exception for unreachable ports."""
    # Attributes: ip_header, icmp_header, message

class HostUnknown(PingError):
    """Exception for unresolvable hostnames."""
    # Attributes: dest_addr, message

class Timeout(PingError):
    """Exception for ping timeouts."""
    # Attributes: timeout, message

Error Handling Patterns

from ping3 import ping
from ping3.errors import PingError, Timeout, HostUnknown

# Method 1: Check return values (default behavior)
result = ping('example.com')
if result is None:
    print("Ping timed out")
elif result is False:
    print("Ping failed (host unreachable or unknown)")
else:
    print(f"Ping successful: {result:.3f}s")

# Method 2: Exception handling
import ping3
ping3.EXCEPTIONS = True  # Enable exception mode

try:
    delay = ping('example.com')
    print(f"Ping successful: {delay:.3f}s")
except Timeout:
    print("Ping timed out")
except HostUnknown:
    print("Host could not be resolved")
except PingError as e:
    print(f"Ping failed: {e}")

ICMP Constants and Enums

ICMP Type Constants

ICMP_DEFAULT_CODE = 0  # Default code for ECHO_REPLY and ECHO_REQUEST

class IcmpV4Type(enum.IntEnum):
    """ICMPv4 message type constants."""
    ECHO_REPLY = 0
    DESTINATION_UNREACHABLE = 3
    REDIRECT_MESSAGE = 5
    ECHO_REQUEST = 8
    ROUTER_ADVERTISEMENT = 9
    ROUTER_SOLICITATION = 10
    TIME_EXCEEDED = 11
    BAD_IP_HEADER = 12
    TIMESTAMP = 13
    TIMESTAMP_REPLY = 14

class IcmpV6Type(enum.IntEnum):
    """ICMPv6 message type constants."""
    DESTINATION_UNREACHABLE = 1
    TIME_EXCEEDED = 3
    ECHO_REQUEST = 128
    ECHO_REPLY = 129
    ROUTER_SOLICITATION = 133
    ROUTER_ADVERTISEMENT = 134
    REDIRECT_MESSAGE = 137

ICMP Code Constants

class IcmpV4DestinationUnreachableCode(enum.IntEnum):
    """ICMPv4 destination unreachable code constants."""
    DESTINATION_NETWORK_UNREACHABLE = 0
    DESTINATION_HOST_UNREACHABLE = 1
    DESTINATION_PROTOCOL_UNREACHABLE = 2
    DESTINATION_PORT_UNREACHABLE = 3
    FRAGMENTATION_REQUIRED = 4
    SOURCE_ROUTE_FAILED = 5
    DESTINATION_NETWORK_UNKNOWN = 6
    DESTINATION_HOST_UNKNOWN = 7
    SOURCE_HOST_ISOLATED = 8
    NETWORK_ADMINISTRATIVELY_PROHIBITED = 9
    HOST_ADMINISTRATIVELY_PROHIBITED = 10
    NETWORK_UNREACHABLE_FOR_TOS = 11
    HOST_UNREACHABLE_FOR_TOS = 12
    COMMUNICATION_ADMINISTRATIVELY_PROHIBITED = 13
    HOST_PRECEDENCE_VIOLATION = 14
    PRECEDENCE_CUTOFF_IN_EFFECT = 15

class IcmpV6DestinationUnreachableCode(enum.IntEnum):
    """ICMPv6 destination unreachable code constants."""
    NO_ROUTE_TO_DESTINATION = 0
    COMMUNICATION_PROHIBITED = 1
    BEYOND_SCOPE = 2
    ADDRESS_UNREACHABLE = 3
    PORT_UNREACHABLE = 4
    SOURCE_ADDRESS_FAILED = 5
    REJECT_ROUTE_TO_DESTINATION = 6
    ERROR_IN_SOURCE_ROUTING_HEADER = 7

class IcmpTimeExceededCode(enum.IntEnum):
    """ICMP time exceeded code constants for both IPv4 and IPv6."""
    TTL_EXPIRED = 0
    FRAGMENT_REASSEMBLY_TIME_EXCEEDED = 1

Platform Considerations

Permissions

  • Root/Administrator Required: ICMP ping requires raw socket access on most platforms
  • Linux Unprivileged: Falls back to DGRAM sockets with kernel ICMP ID rewriting
  • Windows: Requires administrator privileges for raw sockets
  • macOS: Requires root privileges for raw sockets

Cross-Platform Compatibility

  • IPv4 Support: Full support on all platforms (Windows, Linux, macOS)
  • IPv6 Support: Full support with automatic address family detection
  • Interface Binding: Linux-only feature using SO_BINDTODEVICE
  • Source Address: IPv4 source binding supported, IPv6 uses OS routing

Socket Types

ping3 automatically handles socket type selection:

  • Attempts SOCK_RAW first for full control
  • Falls back to SOCK_DGRAM on permission errors (Linux)
  • Handles platform-specific IP header presence/absence