Skip to content

Commit

Permalink
Merge pull request #22 from mrtnRitter/main
Browse files Browse the repository at this point in the history
Added 'interface' to send magic packet to specific NIC
  • Loading branch information
remcohaszing authored Oct 17, 2021
2 parents 9ba45a9 + 01c8c47 commit 22a2b47
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 6 deletions.
11 changes: 9 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -65,22 +65,29 @@ required. The default ip address is 255.255.255.255 and the default port is 9.
... port=1337)


A network adapter may be specified. The magic packet will be routed through this interface.

>>> send_magic_packet('ff.ff.ff.ff.ff.ff',
... interface='192.168.0.2')


As a standalone script
======================

::

usage: wakeonlan [-h] [-i ip] [-p port] mac address [mac address ...]
usage: wakeonlan [-h] [-i ip] [-p port] [-n interface] mac address [mac address ...]

Wake one or more computers using the wake on lan protocol.

positional arguments:
mac address The mac addresses or of the computers you are trying to wake.
mac address The mac addresses of the computers you are trying to wake.

optional arguments:
-h, --help show this help message and exit
-i ip The ip address of the host to send the magic packet to. (default 255.255.255.255)
-p port The port of the host to send the magic packet to. (default 9)
-n interface The ip address of the network adapter to route the magic packet through. (optional)


************
Expand Down
74 changes: 73 additions & 1 deletion test_wakeonlan.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,13 +208,85 @@ def test_send_magic_packet_default(sock: Mock) -> None:
]


@patch("socket.socket")
def test_send_magic_packet_interface(sock: Mock) -> None:
"""
Test whether the magic packets are broadcasted to the specified network via specified interface.
"""
send_magic_packet(
"133713371337",
"00-00-00-00-00-00",
ip_address="example.com",
port=7,
interface="192.168.0.2",
)
assert sock.mock_calls == [
call(socket.AF_INET, socket.SOCK_DGRAM),
call().__enter__(),
call().__enter__().bind(("192.168.0.2", 0)),
call().__enter__().setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1),
call().__enter__().connect(("example.com", 7)),
call()
.__enter__()
.send(
b"\xff\xff\xff\xff\xff\xff"
b"\x137\x137\x137"
b"\x137\x137\x137"
b"\x137\x137\x137"
b"\x137\x137\x137"
b"\x137\x137\x137"
b"\x137\x137\x137"
b"\x137\x137\x137"
b"\x137\x137\x137"
b"\x137\x137\x137"
b"\x137\x137\x137"
b"\x137\x137\x137"
b"\x137\x137\x137"
b"\x137\x137\x137"
b"\x137\x137\x137"
b"\x137\x137\x137"
b"\x137\x137\x137"
),
call()
.__enter__()
.send(
b"\xff\xff\xff\xff\xff\xff"
b"\x00\x00\x00\x00\x00\x00"
b"\x00\x00\x00\x00\x00\x00"
b"\x00\x00\x00\x00\x00\x00"
b"\x00\x00\x00\x00\x00\x00"
b"\x00\x00\x00\x00\x00\x00"
b"\x00\x00\x00\x00\x00\x00"
b"\x00\x00\x00\x00\x00\x00"
b"\x00\x00\x00\x00\x00\x00"
b"\x00\x00\x00\x00\x00\x00"
b"\x00\x00\x00\x00\x00\x00"
b"\x00\x00\x00\x00\x00\x00"
b"\x00\x00\x00\x00\x00\x00"
b"\x00\x00\x00\x00\x00\x00"
b"\x00\x00\x00\x00\x00\x00"
b"\x00\x00\x00\x00\x00\x00"
b"\x00\x00\x00\x00\x00\x00"
),
call().__exit__(None, None, None),
]


@patch("wakeonlan.send_magic_packet")
def test_main(send_magic_packet: Mock) -> None:
"""
Test if processed arguments are passed to send_magic_packet.
"""
main(["00:11:22:33:44:55", "-i", "host.example", "-p", "1337"])
main(["00:11:22:33:44:55", "-i", "host.example", "-p", "1337", "-n", "192.168.0.2"])
assert send_magic_packet.mock_calls == [
call("00:11:22:33:44:55", ip_address="host.example", port=1337,)
call("00:11:22:33:44:55", ip_address="host.example", port=1337, interface=None),
call(
"00:11:22:33:44:55",
ip_address="host.example",
port=1337,
interface="192.168.0.2",
),
]
18 changes: 15 additions & 3 deletions wakeonlan.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@ def create_magic_packet(macaddress: str) -> bytes:


def send_magic_packet(
*macs: str, ip_address: str = BROADCAST_IP, port: int = DEFAULT_PORT
*macs: str,
ip_address: str = BROADCAST_IP,
port: int = DEFAULT_PORT,
interface: str = None
) -> None:
"""
Wake up computers having any of the given mac addresses.
Expand All @@ -47,11 +50,14 @@ def send_magic_packet(
Keyword Args:
ip_address: the ip address of the host to send the magic packet to.
port: the port of the host to send the magic packet to.
interface: the ip address of the network adapter to route the magic packet through.
"""
packets = [create_magic_packet(mac) for mac in macs]

with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock:
if interface is not None:
sock.bind((interface, 0))
sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
sock.connect((ip_address, port))
for packet in packets:
Expand All @@ -71,7 +77,7 @@ def main(argv: List[str] = None) -> None:
"macs",
metavar="mac address",
nargs="+",
help="The mac addresses or of the computers you are trying to wake.",
help="The mac addresses of the computers you are trying to wake.",
)
parser.add_argument(
"-i",
Expand All @@ -86,8 +92,14 @@ def main(argv: List[str] = None) -> None:
default=DEFAULT_PORT,
help="The port of the host to send the magic packet to.",
)
parser.add_argument(
"-n",
metavar="interface",
default=None,
help="The ip address of the network adapter to route the magic packet through.",
)
args = parser.parse_args(argv)
send_magic_packet(*args.macs, ip_address=args.i, port=args.p)
send_magic_packet(*args.macs, ip_address=args.i, port=args.p, interface=args.n)


if __name__ == "__main__": # pragma: nocover
Expand Down

0 comments on commit 22a2b47

Please sign in to comment.