Last active
May 16, 2024 23:09
-
-
Save tedpearson/e1b3319b93e3cb2f96d76d9c87f3aa65 to your computer and use it in GitHub Desktop.
UDP relayer. Modified from https://github.com/EtiennePerot/misc-scripts/blob/master/udp-relay.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
# Super simple script that listens to a local UDP port and relays all packets to an arbitrary remote host. | |
# Packets that the host sends back will also be relayed to the local UDP client. | |
# Works with Python 2 and 3 | |
import ipaddress | |
import socket | |
import sys | |
# Whether or not to print the IP address and port of each packet received | |
debug = False | |
def fail(reason): | |
sys.stderr.write(reason + '\n') | |
sys.exit(1) | |
def addressMatches(a, b: (str, str, str, str)) -> bool: | |
# convert embedded ipv4 to ipv4 | |
ip_a = ipaddress.ip_address(a[0]) | |
ip_b = ipaddress.ip_address(b[0]) | |
if ip_a.version == 6 and ip_a.ipv4_mapped is not None: | |
ip_a = ip_a.ipv4_mapped | |
if ip_b.version == 6 and ip_b.ipv4_mapped is not None: | |
ip_b = ip_b.ipv4_mapped | |
return ip_a == ip_b | |
if len(sys.argv) != 4: | |
fail('Usage: udp-relay.py localPort remoteHost remotePort') | |
localPort, remoteHost, remotePort = sys.argv[1], sys.argv[2], sys.argv[3] | |
try: | |
localPort = int(localPort) | |
except: | |
fail('Invalid port number: ' + str(localPort)) | |
try: | |
remotePort = int(remotePort) | |
except: | |
fail('Invalid port number: ' + str(remotePort)) | |
try: | |
s = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM) | |
s.bind(('::', localPort)) | |
except: | |
fail('Failed to bind on port ' + str(localPort)) | |
knownClient = None | |
knownServer = (remoteHost, remotePort, 0, 0) | |
print("known server: " + str(knownServer)) | |
sys.stdout.write('All set, listening on ' + str(localPort) + '.\n') | |
while True: | |
data, addr = s.recvfrom(32768) | |
if knownClient is None or not addressMatches(addr, knownServer): | |
if debug: | |
print("") | |
knownClient = addr | |
if debug: | |
print("Packet received from " + str(addr)) | |
if addr == knownClient: | |
if debug: | |
print("\tforwarding to " + str(knownServer)) | |
s.sendto(data, knownServer) | |
else: | |
if debug: | |
print("\tforwarding to " + str(knownClient)) | |
s.sendto(data, knownClient) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment