trx_toolkit: Add cmdline arg to set bind addr

Previous hardcoded default of 0.0.0.0 was inappropiate in some
scenarios, as it sets the SRC addr of the packets sent through the
socket based on the routing.

For instance, if iface IF1 has assigned two IP addresses A and B,
A being the first addr of the interface, and osmo-bts-trx is
configured with "osmotrx ip local A" and "osmotrx ip remote B",
the following happens:

  CMD POWER OFF src=A:5801 dst=B:5701
  RSP POWER OFF src=A:5701 dst=A:5701 <-- A is assigned as src addr.

But osmo-bts-trx is waiting for packets from B:5701, and the packet
is dropped with ICMP Unreachable. If addr binding is forced in
fake_trx to B, then everthing's fine.

Let's extend the UDPLink in order to allow manual, but optional
setting of bind address, and add a corresponding cmdline
argument to all executables.

Change-Id: I7be18fef40967fb7551f4115f22cbbd9cdb0840d
This commit is contained in:
Pau Espin 2018-03-21 13:46:34 +01:00
parent 9d90d1907b
commit 55afe0072b
8 changed files with 58 additions and 36 deletions

View File

@ -39,6 +39,7 @@ from data_msg import *
class Application: class Application:
# Application variables # Application variables
remote_addr = "127.0.0.1" remote_addr = "127.0.0.1"
bind_addr = "0.0.0.0"
base_port = 5700 base_port = 5700
conn_mode = "TRX" conn_mode = "TRX"
output_file = None output_file = None
@ -70,11 +71,11 @@ class Application:
def run(self): def run(self):
# Init DATA interface with TRX or L1 # Init DATA interface with TRX or L1
if self.conn_mode == "TRX": if self.conn_mode == "TRX":
self.data_if = DATAInterface(self.remote_addr, self.data_if = DATAInterface(self.remote_addr, self.base_port + 2,
self.base_port + 2, self.base_port + 102) self.bind_addr, self.base_port + 102)
elif self.conn_mode == "L1": elif self.conn_mode == "L1":
self.data_if = DATAInterface(self.remote_addr, self.data_if = DATAInterface(self.remote_addr, self.base_port + 102,
self.base_port + 102, self.base_port + 2) self.bind_addr, self.base_port + 2)
# Init random burst generator # Init random burst generator
burst_gen = RandBurstGen() burst_gen = RandBurstGen()
@ -149,6 +150,7 @@ class Application:
" -o --output-file Write bursts to a capture file\n" \ " -o --output-file Write bursts to a capture file\n" \
" -m --conn-mode Send bursts to: TRX (default) / L1\n" \ " -m --conn-mode Send bursts to: TRX (default) / L1\n" \
" -r --remote-addr Set remote address (default %s)\n" \ " -r --remote-addr Set remote address (default %s)\n" \
" -b --bind-addr Set local address (default %s)\n" \
" -p --base-port Set base port number (default %d)\n\n" " -p --base-port Set base port number (default %d)\n\n"
s += " Burst generation\n" \ s += " Burst generation\n" \
@ -161,7 +163,7 @@ class Application:
" --toa Set ToA in symbols (default random)\n" \ " --toa Set ToA in symbols (default random)\n" \
" --toa256 Set ToA in 1/256 symbol periods\n" " --toa256 Set ToA in 1/256 symbol periods\n"
print(s % (self.remote_addr, self.base_port)) print(s % (self.remote_addr, self.bind_addr, self.base_port))
if msg is not None: if msg is not None:
print(msg) print(msg)
@ -169,12 +171,13 @@ class Application:
def parse_argv(self): def parse_argv(self):
try: try:
opts, args = getopt.getopt(sys.argv[1:], opts, args = getopt.getopt(sys.argv[1:],
"o:m:r:p:b:c:f:t:h", "o:m:r:b:p:b:c:f:t:h",
[ [
"help", "help",
"output-file=" "output-file="
"conn-mode=", "conn-mode=",
"remote-addr=", "remote-addr=",
"bind-addr=",
"base-port=", "base-port=",
"burst-type=", "burst-type=",
"burst-count=", "burst-count=",
@ -200,6 +203,8 @@ class Application:
self.conn_mode = v self.conn_mode = v
elif o in ("-r", "--remote-addr"): elif o in ("-r", "--remote-addr"):
self.remote_addr = v self.remote_addr = v
elif o in ("-b", "--bind-addr"):
self.bind_addr = v
elif o in ("-p", "--base-port"): elif o in ("-p", "--base-port"):
self.base_port = int(v) self.base_port = int(v)

View File

@ -37,6 +37,7 @@ from data_msg import *
class Application: class Application:
# Application variables # Application variables
remote_addr = "127.0.0.1" remote_addr = "127.0.0.1"
bind_addr = "0.0.0.0"
base_port = 5700 base_port = 5700
conn_mode = "TRX" conn_mode = "TRX"
@ -65,12 +66,12 @@ class Application:
def run(self): def run(self):
# Init DATA interface with TRX or L1 # Init DATA interface with TRX or L1
if self.conn_mode == "TRX": if self.conn_mode == "TRX":
self.data_if = DATAInterface(self.remote_addr, self.data_if = DATAInterface(self.remote_addr, self.base_port + 2,
self.base_port + 2, self.base_port + 102) self.bind_addr, self.base_port + 102)
l12trx = True l12trx = True
elif self.conn_mode == "L1": elif self.conn_mode == "L1":
self.data_if = DATAInterface(self.remote_addr, self.data_if = DATAInterface(self.remote_addr, self.base_port + 102,
self.base_port + 102, self.base_port + 2) self.bind_addr, self.base_port + 2)
l12trx = False l12trx = False
else: else:
self.print_help("[!] Unknown connection type") self.print_help("[!] Unknown connection type")
@ -124,6 +125,7 @@ class Application:
s += " TRX interface specific\n" \ s += " TRX interface specific\n" \
" -m --conn-mode Send bursts to: TRX (default) / L1\n" \ " -m --conn-mode Send bursts to: TRX (default) / L1\n" \
" -r --remote-addr Set remote address (default %s)\n" \ " -r --remote-addr Set remote address (default %s)\n" \
" -b --bind-addr Set bind address (default %s)\n" \
" -p --base-port Set base port number (default %d)\n\n" " -p --base-port Set base port number (default %d)\n\n"
s += " Burst source\n" \ s += " Burst source\n" \
@ -138,7 +140,7 @@ class Application:
" --frame-num-lt NUM TDMA frame number lower than NUM\n" \ " --frame-num-lt NUM TDMA frame number lower than NUM\n" \
" --frame-num-gt NUM TDMA frame number greater than NUM\n" " --frame-num-gt NUM TDMA frame number greater than NUM\n"
print(s % (self.remote_addr, self.base_port)) print(s % (self.remote_addr, self.bind_addr, self.base_port))
if msg is not None: if msg is not None:
print(msg) print(msg)
@ -146,11 +148,12 @@ class Application:
def parse_argv(self): def parse_argv(self):
try: try:
opts, args = getopt.getopt(sys.argv[1:], opts, args = getopt.getopt(sys.argv[1:],
"m:r:p:i:h", "m:r:b:p:i:h",
[ [
"help", "help",
"conn-mode=", "conn-mode=",
"remote-addr=", "remote-addr=",
"bind-addr=",
"base-port=", "base-port=",
"capture-file=", "capture-file=",
"msg-skip=", "msg-skip=",
@ -177,6 +180,8 @@ class Application:
self.conn_mode = v self.conn_mode = v
elif o in ("-r", "--remote-addr"): elif o in ("-r", "--remote-addr"):
self.remote_addr = v self.remote_addr = v
elif o in ("-b", "--bind-addr"):
self.bind_addr = v
elif o in ("-p", "--base-port"): elif o in ("-p", "--base-port"):
self.base_port = int(v) self.base_port = int(v)

View File

@ -102,7 +102,7 @@ class Application:
signal.signal(signal.SIGINT, self.sig_handler) signal.signal(signal.SIGINT, self.sig_handler)
def run(self): def run(self):
self.link = UDPLink("127.0.0.1", 5800, 5700) self.link = UDPLink("127.0.0.1", 5800, "0.0.0.0", 5700)
self.clck = CLCKGen([self.link], ind_period = 51) self.clck = CLCKGen([self.link], ind_period = 51)
self.clck.start() self.clck.start()

View File

@ -36,6 +36,7 @@ from udp_link import UDPLink
class Application: class Application:
# Application variables # Application variables
remote_addr = "127.0.0.1" remote_addr = "127.0.0.1"
bind_addr = "0.0.0.0"
base_port = 5700 base_port = 5700
bind_port = 0 bind_port = 0
fuzzing = False fuzzing = False
@ -48,8 +49,8 @@ class Application:
signal.signal(signal.SIGINT, self.sig_handler) signal.signal(signal.SIGINT, self.sig_handler)
# Init UDP connection # Init UDP connection
self.ctrl_link = UDPLink(self.remote_addr, self.ctrl_link = UDPLink(self.remote_addr, self.base_port + 1,
self.base_port + 1, self.bind_port) self.bind_addr, self.bind_port)
# Debug print # Debug print
print("[i] Init CTRL interface (%s)" \ print("[i] Init CTRL interface (%s)" \
@ -64,9 +65,10 @@ class Application:
" -r --remote-addr Set remote address (default %s)\n" \ " -r --remote-addr Set remote address (default %s)\n" \
" -p --base-port Set base port number (default %d)\n" \ " -p --base-port Set base port number (default %d)\n" \
" -P --bind-port Set local port number (default: random)\n" \ " -P --bind-port Set local port number (default: random)\n" \
" -b --bind-addr Set local address (default %s)\n" \
" -f --fuzzing Send raw payloads (without CMD)\n" \ " -f --fuzzing Send raw payloads (without CMD)\n" \
print(s % (self.remote_addr, self.base_port)) print(s % (self.remote_addr, self.base_port, self.bind_addr))
if msg is not None: if msg is not None:
print(msg) print(msg)
@ -74,12 +76,13 @@ class Application:
def parse_argv(self): def parse_argv(self):
try: try:
opts, args = getopt.getopt(sys.argv[1:], opts, args = getopt.getopt(sys.argv[1:],
"r:p:P:fh", "r:p:P:b:fh",
[ [
"help", "help",
"fuzzing", "fuzzing",
"base-port=", "base-port=",
"bind-port=", "bind-port=",
"bind-addr=",
"remote-addr=", "remote-addr=",
]) ])
except getopt.GetoptError as err: except getopt.GetoptError as err:
@ -93,6 +96,8 @@ class Application:
elif o in ("-r", "--remote-addr"): elif o in ("-r", "--remote-addr"):
self.remote_addr = v self.remote_addr = v
elif o in ("-b", "--bind-addr"):
self.bind_addr = v
elif o in ("-p", "--base-port"): elif o in ("-p", "--base-port"):
self.base_port = int(v) self.base_port = int(v)
elif o in ("-P", "--bind-port"): elif o in ("-P", "--bind-port"):

View File

@ -32,8 +32,8 @@ class CTRLInterfaceBB(CTRLInterface):
tx_freq = None tx_freq = None
pm = None pm = None
def __init__(self, remote_addr, remote_port, bind_port): def __init__(self, remote_addr, remote_port, bind_addr, bind_port):
CTRLInterface.__init__(self, remote_addr, remote_port, bind_port) CTRLInterface.__init__(self, remote_addr, remote_port, bind_addr, bind_port)
print("[i] Init CTRL interface for BB (%s)" % self.desc_link()) print("[i] Init CTRL interface for BB (%s)" % self.desc_link())
def parse_cmd(self, request): def parse_cmd(self, request):

View File

@ -33,8 +33,8 @@ class CTRLInterfaceBTS(CTRLInterface):
tx_freq = None tx_freq = None
pm = None pm = None
def __init__(self, remote_addr, remote_port, bind_port): def __init__(self, remote_addr, remote_port, bind_addr, bind_port):
CTRLInterface.__init__(self, remote_addr, remote_port, bind_port) CTRLInterface.__init__(self, remote_addr, remote_port, bind_addr, bind_port)
print("[i] Init CTRL interface for BTS (%s)" % self.desc_link()) print("[i] Init CTRL interface for BTS (%s)" % self.desc_link())
def parse_cmd(self, request): def parse_cmd(self, request):

View File

@ -42,6 +42,7 @@ class Application:
# Application variables # Application variables
bts_addr = "127.0.0.1" bts_addr = "127.0.0.1"
bb_addr = "127.0.0.1" bb_addr = "127.0.0.1"
trx_bind_addr = "0.0.0.0"
bts_base_port = 5700 bts_base_port = 5700
bb_base_port = 6700 bb_base_port = 6700
@ -60,12 +61,12 @@ class Application:
def run(self): def run(self):
# Init TRX CTRL interface for BTS # Init TRX CTRL interface for BTS
self.bts_ctrl = CTRLInterfaceBTS(self.bts_addr, self.bts_ctrl = CTRLInterfaceBTS(self.bts_addr, self.bts_base_port + 101,
self.bts_base_port + 101, self.bts_base_port + 1) self.trx_bind_addr, self.bts_base_port + 1)
# Init TRX CTRL interface for BB # Init TRX CTRL interface for BB
self.bb_ctrl = CTRLInterfaceBB(self.bb_addr, self.bb_ctrl = CTRLInterfaceBB(self.bb_addr, self.bb_base_port + 101,
self.bb_base_port + 101, self.bb_base_port + 1) self.trx_bind_addr, self.bb_base_port + 1)
# Power measurement emulation # Power measurement emulation
# Noise: -120 .. -105 # Noise: -120 .. -105
@ -77,10 +78,10 @@ class Application:
self.bb_ctrl.pm = self.pm self.bb_ctrl.pm = self.pm
# Init DATA links # Init DATA links
self.bts_data = UDPLink(self.bts_addr, self.bts_data = UDPLink(self.bts_addr, self.bts_base_port + 102,
self.bts_base_port + 102, self.bts_base_port + 2) self.trx_bind_addr, self.bts_base_port + 2)
self.bb_data = UDPLink(self.bb_addr, self.bb_data = UDPLink(self.bb_addr, self.bb_base_port + 102,
self.bb_base_port + 102, self.bb_base_port + 2) self.trx_bind_addr, self.bb_base_port + 2)
# BTS <-> BB burst forwarding # BTS <-> BB burst forwarding
self.burst_fwd = BurstForwarder(self.bts_data, self.bb_data) self.burst_fwd = BurstForwarder(self.bts_data, self.bb_data)
@ -94,8 +95,8 @@ class Application:
self.bb_ctrl.burst_fwd = self.burst_fwd self.bb_ctrl.burst_fwd = self.burst_fwd
# Provide clock to BTS # Provide clock to BTS
self.bts_clck = UDPLink(self.bts_addr, self.bts_clck = UDPLink(self.bts_addr, self.bts_base_port + 100,
self.bts_base_port + 100, self.bts_base_port) self.trx_bind_addr, self.bts_base_port)
self.clck_gen = CLCKGen([self.bts_clck]) self.clck_gen = CLCKGen([self.bts_clck])
self.bts_ctrl.clck_gen = self.clck_gen self.bts_ctrl.clck_gen = self.clck_gen
@ -142,7 +143,8 @@ class Application:
" -R --bts-addr Set BTS remote address (default %s)\n" \ " -R --bts-addr Set BTS remote address (default %s)\n" \
" -r --bb-addr Set BB remote address (default %s)\n" \ " -r --bb-addr Set BB remote address (default %s)\n" \
" -P --bts-base-port Set BTS base port number (default %d)\n" \ " -P --bts-base-port Set BTS base port number (default %d)\n" \
" -p --bb-base-port Set BB base port number (default %d)\n\n" " -p --bb-base-port Set BB base port number (default %d)\n" \
" -b --trx-bind-addr Set TRX bind address (default %s)\n\n"
s += " Simulation\n" \ s += " Simulation\n" \
" --rand-dl-rssi Enable DL RSSI randomization\n" \ " --rand-dl-rssi Enable DL RSSI randomization\n" \
@ -151,7 +153,8 @@ class Application:
" --rand-ul-toa Enable UL ToA randomization\n" " --rand-ul-toa Enable UL ToA randomization\n"
print(s % (self.bts_addr, self.bb_addr, print(s % (self.bts_addr, self.bb_addr,
self.bts_base_port, self.bb_base_port)) self.bts_base_port, self.bb_base_port,
self.trx_bind_addr))
if msg is not None: if msg is not None:
print(msg) print(msg)
@ -159,11 +162,12 @@ class Application:
def parse_argv(self): def parse_argv(self):
try: try:
opts, args = getopt.getopt(sys.argv[1:], opts, args = getopt.getopt(sys.argv[1:],
"R:r:P:p:h", "R:r:P:p:b:h",
[ [
"help", "help",
"bts-addr=", "bb-addr=", "bts-addr=", "bb-addr=",
"bts-base-port=", "bb-base-port=", "bts-base-port=", "bb-base-port=",
"trx-bind-addr=",
"rand-dl-rssi", "rand-ul-rssi", "rand-dl-rssi", "rand-ul-rssi",
"rand-dl-toa", "rand-ul-toa", "rand-dl-toa", "rand-ul-toa",
]) ])
@ -186,6 +190,9 @@ class Application:
elif o in ("-p", "--bb-base-port"): elif o in ("-p", "--bb-base-port"):
self.bb_base_port = int(v) self.bb_base_port = int(v)
elif o in ("-b", "--trx-bind-addr"):
self.trx_bind_addr = v
# Message field randomization # Message field randomization
elif o == "rand-dl-rssi": elif o == "rand-dl-rssi":
self.randomize_dl_rssi = True self.randomize_dl_rssi = True

View File

@ -25,10 +25,10 @@
import socket import socket
class UDPLink: class UDPLink:
def __init__(self, remote_addr, remote_port, bind_port = 0): def __init__(self, remote_addr, remote_port, bind_addr = '0.0.0.0', bind_port = 0):
self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.sock.bind(('0.0.0.0', bind_port)) self.sock.bind((bind_addr, bind_port))
self.sock.setblocking(0) self.sock.setblocking(0)
# Save remote info # Save remote info