Skip to content
Open
Show file tree
Hide file tree
Changes from 5 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