tos-plus: Support sniffing upstream port(s) too.

This commit is contained in:
Ben Greear
2020-04-07 09:08:11 -07:00
parent 330b58b212
commit 445d71f98c
2 changed files with 87 additions and 16 deletions

View File

@@ -49,6 +49,7 @@ FORMAT = '%(asctime)s %(name)s %(levelname)s: %(message)s'
lfmgr = "127.0.0.1" lfmgr = "127.0.0.1"
lfstation = "1.wlan0" lfstation = "1.wlan0"
sniffer_radios = "2.wiphy0" sniffer_radios = "2.wiphy0"
upstream = ""
dur = 5 * 60 dur = 5 * 60
moni_flags = "0x100000000"; # 160Mhz mode enabled moni_flags = "0x100000000"; # 160Mhz mode enabled
@@ -61,11 +62,13 @@ def usage():
print("--lfmgr: LANforge manager IP address") print("--lfmgr: LANforge manager IP address")
print("--duration: Duration to run traffic, in minutes") print("--duration: Duration to run traffic, in minutes")
print("--moni_flags: Monitor flags (see LANforge CLI help for set_wifi_monitor command) Default enables 160Mhz") print("--moni_flags: Monitor flags (see LANforge CLI help for set_wifi_monitor command) Default enables 160Mhz")
print("--upstreams: Upstream ports to sniff (1.eth1 ...)")
print("-h|--help") print("-h|--help")
def main(): def main():
global lfmgr global lfmgr
global lfstation global lfstation
global upstream
global sniffer_radios global sniffer_radios
global dur global dur
global moni_flags global moni_flags
@@ -76,12 +79,15 @@ def main():
parser.add_argument("--lfmgr", type=str, help="LANforge Manager IP address") parser.add_argument("--lfmgr", type=str, help="LANforge Manager IP address")
parser.add_argument("--duration", type=float, help="Duration to sniff, in minutes") parser.add_argument("--duration", type=float, help="Duration to sniff, in minutes")
parser.add_argument("--moni_flags", type=str, help="Monitor port flags, see LANforge CLI help for set_wifi_monitor. Default enables 160Mhz") parser.add_argument("--moni_flags", type=str, help="Monitor port flags, see LANforge CLI help for set_wifi_monitor. Default enables 160Mhz")
parser.add_argument("--upstreams", type=str, help="Upstream ports to sniff (1.eth1 ...)")
args = None args = None
try: try:
args = parser.parse_args() args = parser.parse_args()
if (args.station != None): if (args.station != None):
lfstation = args.station lfstation = args.station
if (args.upstreams != None):
upstream = args.upstreams
if (args.sniffer_radios != None): if (args.sniffer_radios != None):
sniffer_radios = args.sniffer_radios sniffer_radios = args.sniffer_radios
if (args.lfmgr != None): if (args.lfmgr != None):
@@ -98,6 +104,7 @@ def main():
# Use subprocess.check_output("Cmd") to utilize existing LF scripts. # Use subprocess.check_output("Cmd") to utilize existing LF scripts.
upstreams = upstream.split()
lfstations = lfstation.split() lfstations = lfstation.split()
radios = sniffer_radios.split() radios = sniffer_radios.split()
monis_n = [] # monitor device names monis_n = [] # monitor device names
@@ -255,6 +262,19 @@ def main():
"--cli_cmd", "sniff_port 1 %s %s NA %s %s.pcap %i"%(r, m, sflags, m, int(dur))]); "--cli_cmd", "sniff_port 1 %s %s NA %s %s.pcap %i"%(r, m, sflags, m, int(dur))]);
idx = idx + 1 idx = idx + 1
# Start sniffing on all upstream ports
for u in upstreams:
u_resource = "1"
u_name = u;
if u[0].isdigit():
tmpa = u.split(".", 1);
u_resource = tmpa[0];
u_name = tmpa[1];
print("Starting sniffer on upstream port %s.%s for %s seconds, saving to file %s.pcap on resource %s\n"%(u_resource, u_name, dur, u_name, u_resource))
subprocess.run(["./lf_portmod.pl", "--manager", lfmgr,
"--cli_cmd", "sniff_port 1 %s %s NA %s %s.pcap %i"%(u_resource, u_name, sflags, u_name, int(dur))]);
# ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- # ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
if __name__ == '__main__': if __name__ == '__main__':
main() main()

View File

@@ -5,13 +5,7 @@ Create connections using stations with different a/b/g/n/AC/AX modes,
traffic with different QoS, packet size, requested rate, and tcp or udp protocol. traffic with different QoS, packet size, requested rate, and tcp or udp protocol.
Report the latency and other throughput values. Report the latency and other throughput values.
make sure pexpect is installed: Optionally start packet-capture on secondary radio(s) and upstream port.
$ sudo yum install python3-pexpect
$ sudo yum install python3-xlsxwriter
You might need to install pexpect-serial using pip:
$ pip3 install pexpect-serial
$ pip3 install XlsxWriter
When specifying ports, if the port starts with [Number]., like 1.eth1, then the 1 specifies When specifying ports, if the port starts with [Number]., like 1.eth1, then the 1 specifies
the resource ID. the resource ID.
@@ -23,13 +17,31 @@ Use NA if you do not want to change from current values. Use 0 for any channel.
Supported modes are: a, b, g, abg, abgn, bgn, bg, abgnAC, anAC, an, bgnAC, abgnAX, bgnAX, anAX Supported modes are: a, b, g, abg, abgn, bgn, bg, abgnAC, anAC, an, bgnAC, abgnAX, bgnAX, anAX
If sniffer_radios is specified, then the lf_sniff.py script will be started in the background once
the stations have become admin-up, and the sniff will run for the entire duration time specified
(there is not a good way to stop the capture early based on packets-sent since on-the-air frames
are very likely more than the PDU count)
# Run connections on wlan0 and sta0, set radio wiphy0 to use any frequency # Run connections on wlan0 and sta0, set radio wiphy0 to use any frequency
# and 2 spatial streams. # and 2 spatial streams. Use wiphy2 as a sniffer, stop traffic after 10,000 PDUs
./lf_tos_plus_test.py --lfmgr 192.168.100.178 --ssid testme --passwd mypsk \ # have been sent. Sniffer radio will automatically change to the correct settings
[ --txpkts 10000 ] # to sniff the first station.
--radio "1.wiphy0 2 0"
--cx "1.wiphy0 1.wlan0 an 1.eth1 udp 1024 1000000 56000 BK" \ ./lf_tos_plus_test.py --dur 5 --lfmgr 192.168.100.156 --ssid NETGEAR68-5G --passwd aquaticbug712 \
--cx "1.wiphy0 1.sta0 anAC 1.eth1 udp 1472 56000 1000000 BK" .. --radio "1.wiphy0 2 0" --txpkts 9999 \
--cx "1.wiphy0 1.wlan0 an 1.eth1 udp 1024 10000 500000000 BK" \
--cx "1.wiphy0 1.wlan0 an 1.eth1 udp MTU 10000 500000000 VI" \
--cx "1.wiphy0 1.sta0 anAC 1.eth1 tcp 1472 56000 2000000 BK" \
--sniffer_radios "1.wiphy2"
make sure pexpect is installed:
$ sudo yum install python3-pexpect
$ sudo yum install python3-xlsxwriter
You might need to install pexpect-serial using pip:
$ pip3 install pexpect-serial
$ pip3 install XlsxWriter
''' '''
@@ -66,6 +78,7 @@ ssid = "Test-SSID"
security = "open" security = "open"
radio_strs = [] # Radios to modify: radio nss channel radio_strs = [] # Radios to modify: radio nss channel
txpkts = 0 # 0 == Run forever txpkts = 0 # 0 == Run forever
sniffer_radios = ""
# rssi_adjust = (current_nf - nf_at_calibration) # rssi_adjust = (current_nf - nf_at_calibration)
@@ -79,6 +92,7 @@ def usage():
print("--ssid: AP's SSID") print("--ssid: AP's SSID")
print("--passwd: Optional: password (do not add this option for OPEN)") print("--passwd: Optional: password (do not add this option for OPEN)")
print("--txpkts: Optional: amount of packets to transmit (and then stop the data connections)") print("--txpkts: Optional: amount of packets to transmit (and then stop the data connections)")
print("--sniffer_radios: Optional: list of radios to sniff wifi traffic \"1.wiphy2 1.wiphy4\")")
print("-h|--help") print("-h|--help")
def main(): def main():
@@ -91,6 +105,7 @@ def main():
global security global security
global radio_strs global radio_strs
global txpkts global txpkts
global sniffer_radios
parser = argparse.ArgumentParser(description="ToS++ report Script") parser = argparse.ArgumentParser(description="ToS++ report Script")
parser.add_argument("--cx", type=str, action='append', help="Connection tuple: station-radio station-port mode upstream-port protocol pkt-size speed_ul speed_dl QoS") parser.add_argument("--cx", type=str, action='append', help="Connection tuple: station-radio station-port mode upstream-port protocol pkt-size speed_ul speed_dl QoS")
@@ -101,6 +116,7 @@ def main():
parser.add_argument("--ssid", type=str, help="AP's SSID") parser.add_argument("--ssid", type=str, help="AP's SSID")
parser.add_argument("--passwd", type=str, help="AP's password if using PSK authentication, skip this argement for OPEN") parser.add_argument("--passwd", type=str, help="AP's password if using PSK authentication, skip this argement for OPEN")
parser.add_argument("--txpkts", type=str, help="Optional: Packets (PDUs) to send before stopping data connections Default (0) means infinite") parser.add_argument("--txpkts", type=str, help="Optional: Packets (PDUs) to send before stopping data connections Default (0) means infinite")
parser.add_argument("--sniffer_radios", type=str, help="Optional: list of radios to sniff wifi traffic \"1.wiphy2 1.wiphy4\"")
args = None args = None
try: try:
@@ -120,6 +136,8 @@ def main():
outfile = args.outfile outfile = args.outfile
if (args.txpkts != None): if (args.txpkts != None):
txpkts = args.txpkts txpkts = args.txpkts
if (args.sniffer_radios != None):
sniffer_radios = args.sniffer_radios
filehandler = None filehandler = None
except Exception as e: except Exception as e:
logging.exception(e); logging.exception(e);
@@ -270,7 +288,8 @@ def main():
subprocess.run(["./lf_portmod.pl", "--manager", lfmgr, "--card", rad_resource, "--port_name", rad_name, subprocess.run(["./lf_portmod.pl", "--manager", lfmgr, "--card", rad_resource, "--port_name", rad_name,
"--set_nss", nss, "--set_channel", ch]); "--set_nss", nss, "--set_channel", ch]);
upstreams = []
stations = []
for cx in cx_strs: for cx in cx_strs:
cxa = cx.split() cxa = cx.split()
#station-radio, station-port, mode, upstream-port, protocol, pkt-size, speed_ul, speed_dl, QoS. #station-radio, station-port, mode, upstream-port, protocol, pkt-size, speed_ul, speed_dl, QoS.
@@ -308,6 +327,11 @@ def main():
continue continue
else: else:
sta_to_mode[sta_key] = mode sta_to_mode[sta_key] = mode
stations.append(sta_key)
ukey = "%s.%s"%(u_resource, u_name)
if not ukey in upstreams:
upstreams.append(ukey)
rad_resource = "1" rad_resource = "1"
rad_name = radio; rad_name = radio;
@@ -426,7 +450,30 @@ def main():
"add_cx %s default_tm %s %s"%(cxn, ena, enb)])# capture_output=True); "add_cx %s default_tm %s %s"%(cxn, ena, enb)])# capture_output=True);
count = count + 1 count = count + 1
# Start sniffer?
if sniffer_radios != "":
radios = sniffer_radios.split()
lfstations = ""
lfupstreams = ""
ri = 0
for r in radios:
lfstations = lfstations + " " + stations[ri]
ri = ri + 1
for u in upstreams:
lfupstreams = lfupstreams + " " + u
# Add 15 seconds to capture length in case it takes a bit of time to start all
# of the connections.
if lfupstreams == "":
subprocess.run(["./lf_sniff.py", "--lfmgr", lfmgr, "--duration", "%f"%((dur + 15) / 60), "--station", lfstations,
"--sniffer_radios", sniffer_radios])# capture_output=True);
else:
subprocess.run(["./lf_sniff.py", "--lfmgr", lfmgr, "--duration", "%f"%((dur + 15) / 60), "--station", lfstations,
"--sniffer_radios", sniffer_radios, "--upstreams", lfupstreams])# capture_output=True);
sniff_done_at = time.time() + dur + 15;
# All traffic connects are created, now start them all # All traffic connects are created, now start them all
for cxn in cxnames: for cxn in cxnames:
# Start traffic # Start traffic
@@ -440,7 +487,7 @@ def main():
time.sleep(dur) time.sleep(dur)
else: else:
# Wait until connections are done transmitting and all are stopped # Wait until connections are done transmitting and all are stopped
print("Waiting until all connections have finished transmitting %s and have stopped themselves."%txpkts); print("Waiting until all connections have finished transmitting %s PDUs and have stopped themselves."%txpkts);
done = False done = False
while not done: while not done:
if time.time() > stop_at: if time.time() > stop_at:
@@ -463,7 +510,7 @@ def main():
foundone = True foundone = True
#print("Flags, was running: %s"%flags) #print("Flags, was running: %s"%flags)
break break
else: #else:
#print("Flags, was not running: %s"%flags) #print("Flags, was not running: %s"%flags)
if foundone: if foundone:
@@ -664,6 +711,10 @@ def main():
workbook.close() workbook.close()
if sniffer_radios != "":
now = time.time()
if now < sniff_done_at:
print("Sniffer will complete in %f seconds."%(sniff_done_at - now))
# ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- # ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
if __name__ == '__main__': if __name__ == '__main__':