Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

All notable changes to this project will be documented in this file.

## [Unreleased]
- Add `interface` parameter to bind sockets to a specific network interface.
- Available in `ping`, `multiping`, `traceroute`, `async_ping`, and `async_multiping` functions.
- Available in `ICMPv4Socket` and `ICMPv6Socket` classes.
- Only available on Linux. Ignored on macOS and Windows.

## [v3.0.4](https://github.com/ValentinBELYN/icmplib/releases/tag/v3.0.4) - 2023-10-10
- Fix licensing inconsistencies.
- Add support for the latest versions of Python.
Expand Down
30 changes: 26 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ Use the built-in functions or build your own, you have the choice!
Send ICMP Echo Request packets to a network host.

```python
ping(address, count=4, interval=1, timeout=2, id=None, source=None, family=None, privileged=True, **kwargs)
ping(address, count=4, interval=1, timeout=2, id=None, source=None, family=None, privileged=True, interface=None, **kwargs)
```

#### Parameters
Expand Down Expand Up @@ -153,6 +153,17 @@ ping(address, count=4, interval=1, timeout=2, id=None, source=None, family=None,
- Type: `bool`
- Default: `True`

- `interface`

The network interface to bind to (e.g., `lo`, `eth0`, `wlan0`). By default, the socket is not bound to a specific interface.

*Only available on Linux. Ignored on macOS and Windows.*

*This function requires root privileges to run.*

- Type: `str`
- Default: `None`

- `payload`

The payload content in bytes. A random payload is used by default.
Expand Down Expand Up @@ -248,7 +259,7 @@ True
Send ICMP Echo Request packets to several network hosts.

```python
multiping(addresses, count=2, interval=0.5, timeout=2, concurrent_tasks=50, source=None, family=None, privileged=True, **kwargs)
multiping(addresses, count=2, interval=0.5, timeout=2, concurrent_tasks=50, source=None, family=None, privileged=True, interface=None, **kwargs)
```

#### Parameters
Expand Down Expand Up @@ -312,6 +323,17 @@ multiping(addresses, count=2, interval=0.5, timeout=2, concurrent_tasks=50, sour
- Type: `bool`
- Default: `True`

- `interface`

The network interface to bind to (e.g., `lo`, `eth0`, `wlan0`). By default, the socket is not bound to a specific interface.

*Only available on Linux. Ignored on macOS and Windows.*

*This function requires root privileges to run.*

- Type: `str`
- Default: `None`

- `payload`

The payload content in bytes. A random payload is used by default.
Expand Down Expand Up @@ -549,7 +571,7 @@ Send ICMP Echo Request packets to a network host.
*This function is non-blocking.*

```python
async_ping(address, count=4, interval=1, timeout=2, id=None, source=None, family=None, privileged=True, **kwargs)
async_ping(address, count=4, interval=1, timeout=2, id=None, source=None, family=None, privileged=True, interface=None, **kwargs)
```

#### Parameters, return value and exceptions
Expand Down Expand Up @@ -579,7 +601,7 @@ Send ICMP Echo Request packets to several network hosts.
*This function is non-blocking.*

```python
async_multiping(addresses, count=2, interval=0.5, timeout=2, concurrent_tasks=50, source=None, family=None, privileged=True, **kwargs)
async_multiping(addresses, count=2, interval=0.5, timeout=2, concurrent_tasks=50, source=None, family=None, privileged=True, interface=None, **kwargs)
```

#### Parameters, return value and exceptions
Expand Down
41 changes: 37 additions & 4 deletions docs/2-functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,17 @@ ping(address, count=4, interval=1, timeout=2, id=None, source=None, family=None,
- Type: `bool`
- Default: `True`

- `interface`

The network interface to bind to (e.g., `'lo'`, `'eth0'`, `'wlan0'`). By default, the socket is not bound to a specific interface.

*Only available on Linux. Ignored on macOS and Windows.*

*This function requires root privileges to run.*

- Type: `str`
- Default: `None`

- `payload`

The payload content in bytes. A random payload is used by default.
Expand Down Expand Up @@ -164,7 +175,7 @@ True
Send ICMP Echo Request packets to several network hosts.

```python
multiping(addresses, count=2, interval=0.5, timeout=2, concurrent_tasks=50, source=None, family=None, privileged=True, **kwargs)
multiping(addresses, count=2, interval=0.5, timeout=2, concurrent_tasks=50, source=None, family=None, privileged=True, interface=None, **kwargs)
```

#### Parameters
Expand Down Expand Up @@ -228,6 +239,17 @@ multiping(addresses, count=2, interval=0.5, timeout=2, concurrent_tasks=50, sour
- Type: `bool`
- Default: `True`

- `interface`

The network interface to bind to (e.g., `'lo'`, `'eth0'`, `'wlan0'`). By default, the socket is not bound to a specific interface.

*Only available on Linux. Ignored on macOS and Windows.*

*This function requires root privileges to run.*

- Type: `str`
- Default: `None`

- `payload`

The payload content in bytes. A random payload is used by default.
Expand Down Expand Up @@ -306,7 +328,7 @@ The Internet is a large and complex aggregation of network hardware, connected t
*This function requires root privileges to run.*

```python
traceroute(address, count=2, interval=0.05, timeout=2, first_hop=1, max_hops=30, fast=False, id=None, source=None, family=None, **kwargs)
traceroute(address, count=2, interval=0.05, timeout=2, first_hop=1, max_hops=30, fast=False, id=None, source=None, family=None, interface=None, **kwargs)
```

#### Parameters
Expand Down Expand Up @@ -380,6 +402,17 @@ traceroute(address, count=2, interval=0.05, timeout=2, first_hop=1, max_hops=30,
- Type: `int`
- Default: `None`

- `interface`

The network interface to bind to (e.g., `'lo'`, `'eth0'`, `'wlan0'`). By default, the socket is not bound to a specific interface.

*Only available on Linux. Ignored on macOS and Windows.*

*This function requires root privileges to run.*

- Type: `str`
- Default: `None`

- `payload`

The payload content in bytes. A random payload is used by default.
Expand Down Expand Up @@ -465,7 +498,7 @@ Send ICMP Echo Request packets to a network host.
*This function is non-blocking.*

```python
async_ping(address, count=4, interval=1, timeout=2, id=None, source=None, family=None, privileged=True, **kwargs)
async_ping(address, count=4, interval=1, timeout=2, id=None, source=None, family=None, privileged=True, interface=None, **kwargs)
```

#### Parameters, return value and exceptions
Expand Down Expand Up @@ -495,7 +528,7 @@ Send ICMP Echo Request packets to several network hosts.
*This function is non-blocking.*

```python
async_multiping(addresses, count=2, interval=0.5, timeout=2, concurrent_tasks=50, source=None, family=None, privileged=True, **kwargs)
async_multiping(addresses, count=2, interval=0.5, timeout=2, concurrent_tasks=50, source=None, family=None, privileged=True, interface=None, **kwargs)
```

#### Parameters, return value and exceptions
Expand Down
17 changes: 14 additions & 3 deletions docs/3-sockets.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ ICMPReply(source, family, id, sequence, type, code, bytes_received, time)
Class for sending and receiving ICMPv4 packets.

```python
ICMPv4Socket(address=None, privileged=True)
ICMPv4Socket(address=None, privileged=True, interface=None)
```

#### Parameters
Expand All @@ -174,9 +174,20 @@ ICMPv4Socket(address=None, privileged=True)
- Type: `bool`
- Default: `True`

- `interface`

The network interface to bind to (e.g., `'lo'`, `'eth0'`, `'wlan0'`). By default, the socket is not bound to a specific interface.

*Only available on Linux. Ignored on macOS and Windows.*

*This function requires root privileges to run.*

- Type: `str`
- Default: `None`

#### Methods

- `__init__(address=None, privileged=True)`
- `__init__(address=None, privileged=True, interface=None)`

*Constructor. Automatically called: do not call it directly.*

Expand Down Expand Up @@ -280,7 +291,7 @@ ICMPv4Socket(address=None, privileged=True)
Class for sending and receiving ICMPv6 packets.

```python
ICMPv6Socket(address=None, privileged=True)
ICMPv6Socket(address=None, privileged=True, interface=None)
```

#### Methods and properties
Expand Down
46 changes: 46 additions & 0 deletions examples/interface_ping.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
'''
icmplib
~~~~~~~

Easily forge ICMP packets and make your own ping and traceroute.

https://github.com/ValentinBELYN/icmplib

:copyright: Copyright 2017-2023 Valentin BELYN.
:license: GNU LGPLv3, see the LICENSE for details.

~~~~~~~

Example: interface binding
'''

from icmplib import ping, multiping


# Ping with interface binding
# Bind to loopback interface (Linux only)
host = ping('127.0.0.1', count=4, interface='lo')

print(host.is_alive)
# True


# Ping via specific network interface (Linux only)
# Common interface names: lo, eth0, wlan0, ens33, etc.
# You can list interfaces with: ip link show

# Uncomment and adjust the interface name to test:
# host = ping('8.8.8.8', count=4, interface='eth0')
# print(host.is_alive)
# True


# Multiping with interface binding (Linux only)
addresses = ['127.0.0.1', '::1']
hosts = multiping(addresses, count=2, interface='lo')

for host in hosts:
print(host.address, host.is_alive)

# 127.0.0.1 True
# ::1 True
17 changes: 15 additions & 2 deletions icmplib/multiping.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@

async def async_multiping(addresses, count=2, interval=0.5, timeout=2,
concurrent_tasks=50, source=None, family=None, privileged=True,
**kwargs):
interface=None, **kwargs):
'''
Send ICMP Echo Request packets to several network hosts.

Expand Down Expand Up @@ -83,6 +83,11 @@ async def async_multiping(addresses, count=2, interval=0.5, timeout=2,
Default to True.
Only available on Unix systems. Ignored on Windows.

:type interface: str, optional
:param interface: The network interface to bind to (e.g., 'eth0',
'wlan0'). By default, the socket is not bound to a specific
interface. Only available on Linux. Ignored on macOS and Windows.

Advanced (**kwags):

:type payload: bytes, optional
Expand Down Expand Up @@ -153,6 +158,7 @@ async def async_multiping(addresses, count=2, interval=0.5, timeout=2,
source=source,
family=family,
privileged=privileged,
interface=interface,
**kwargs))

tasks.append(task)
Expand All @@ -165,7 +171,7 @@ async def async_multiping(addresses, count=2, interval=0.5, timeout=2,

def multiping(addresses, count=2, interval=0.5, timeout=2,
concurrent_tasks=50, source=None, family=None, privileged=True,
**kwargs):
interface=None, **kwargs):
'''
Send ICMP Echo Request packets to several network hosts.

Expand Down Expand Up @@ -213,6 +219,12 @@ def multiping(addresses, count=2, interval=0.5, timeout=2,
Default to True.
Only available on Unix systems. Ignored on Windows.

:type interface: str, optional
:param interface: The network interface to bind to (e.g., 'eth0',
'wlan0'). By default, the socket is not bound to a specific
interface. Only available on Linux. Ignored on macOS and Windows.


Advanced (**kwags):

:type payload: bytes, optional
Expand Down Expand Up @@ -274,4 +286,5 @@ def multiping(addresses, count=2, interval=0.5, timeout=2,
source=source,
family=family,
privileged=privileged,
interface=interface,
**kwargs))
19 changes: 15 additions & 4 deletions icmplib/ping.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@


def ping(address, count=4, interval=1, timeout=2, id=None, source=None,
family=None, privileged=True, **kwargs):
family=None, privileged=True, interface=None, **kwargs):
'''
Send ICMP Echo Request packets to a network host.

Expand Down Expand Up @@ -82,6 +82,11 @@ def ping(address, count=4, interval=1, timeout=2, id=None, source=None,
Default to True.
Only available on Unix systems. Ignored on Windows.

:type interface: str, optional
:param interface: The network interface to bind to (e.g., 'eth0',
'wlan0'). By default, the socket is not bound to a specific
interface. Only available on Linux. Ignored on macOS and Windows.

Advanced (**kwags):

:type payload: bytes, optional
Expand Down Expand Up @@ -138,7 +143,7 @@ def ping(address, count=4, interval=1, timeout=2, id=None, source=None,
packets_sent = 0
rtts = []

with _Socket(source, privileged) as sock:
with _Socket(source, privileged, interface) as sock:
for sequence in range(count):
if sequence > 0:
sleep(interval)
Expand Down Expand Up @@ -166,7 +171,7 @@ def ping(address, count=4, interval=1, timeout=2, id=None, source=None,


async def async_ping(address, count=4, interval=1, timeout=2, id=None,
source=None, family=None, privileged=True, **kwargs):
source=None, family=None, privileged=True, interface=None, **kwargs):
'''
Send ICMP Echo Request packets to a network host.

Expand Down Expand Up @@ -214,6 +219,12 @@ async def async_ping(address, count=4, interval=1, timeout=2, id=None,
Default to True.
Only available on Unix systems. Ignored on Windows.

:type interface: str, optional
:param interface: The network interface to bind to (e.g., 'eth0',
'wlan0'). By default, the socket is not bound to a specific
interface. Only available on Linux. Ignored on macOS and Windows.


Advanced (**kwags):

:type payload: bytes, optional
Expand Down Expand Up @@ -271,7 +282,7 @@ async def async_ping(address, count=4, interval=1, timeout=2, id=None,
packets_sent = 0
rtts = []

with AsyncSocket(_Socket(source, privileged)) as sock:
with AsyncSocket(_Socket(source, privileged, interface)) as sock:
for sequence in range(count):
if sequence > 0:
await asyncio.sleep(interval)
Expand Down
Loading