1# 2# tshark module - refactored from test_scan.py 3# 4# Copyright (c) 2014, Qualcomm Atheros, Inc. 5# Copyright (c) 2015, Intel Mobile Communications GmbH 6# 7# This software may be distributed under the terms of the BSD license. 8# See README for more details. 9 10import time 11import subprocess 12import logging 13logger = logging.getLogger() 14 15from utils import * 16 17class UnknownFieldsException(Exception): 18 def __init__(self, fields): 19 Exception.__init__(self, "unknown tshark fields %s" % ','.join(fields)) 20 self.fields = fields 21 22_tshark_filter_arg = '-Y' 23 24def _run_tshark(filename, filter, display=None, wait=True): 25 global _tshark_filter_arg 26 27 if wait: 28 # wait a bit to make it more likely for wlantest sniffer to have 29 # captured and written the results into a file that we can process here 30 time.sleep(0.1) 31 32 try: 33 arg = ["tshark", "-r", filename, 34 _tshark_filter_arg, filter] 35 if display: 36 arg.append('-Tfields') 37 for d in display: 38 arg.append('-e') 39 arg.append(d) 40 else: 41 arg.append('-V') 42 cmd = subprocess.Popen(arg, stdout=subprocess.PIPE, 43 stderr=subprocess.PIPE) 44 except Exception as e: 45 logger.info("Could run run tshark check: " + str(e)) 46 if "No such file or directory: 'tshark'" in str(e): 47 raise HwsimSkip("No tshark available") 48 cmd = None 49 return None 50 51 output = cmd.communicate() 52 out = output[0].decode(errors='ignore') 53 out1 = output[1].decode() 54 res = cmd.wait() 55 if res == 1: 56 errmsg = "Some fields aren't valid" 57 if errmsg in out1: 58 errors = out1.split('\n') 59 fields = [] 60 collect = False 61 for f in errors: 62 if collect: 63 f = f.strip() 64 if f: 65 fields.append(f) 66 continue 67 if errmsg in f: 68 collect = True 69 continue 70 raise UnknownFieldsException(fields) 71 # remember this for efficiency 72 _tshark_filter_arg = '-R' 73 arg[3] = '-R' 74 cmd = subprocess.Popen(arg, stdout=subprocess.PIPE, 75 stderr=open('/dev/null', 'w')) 76 out = cmd.communicate()[0].decode() 77 cmd.wait() 78 if res == 2: 79 if "tshark: Neither" in out1 and "are field or protocol names" in out1: 80 errors = out1.split('\n') 81 fields = [] 82 for f in errors: 83 if f.startswith("tshark: Neither "): 84 f = f.split(' ')[2].strip('"') 85 if f: 86 fields.append(f) 87 continue 88 raise UnknownFieldsException(fields) 89 90 if res != 0: 91 raise AssertionError('tshark reported an error: ' + out1) 92 93 return out 94 95def run_tshark(filename, filters, display=None, wait=True): 96 if display is None: display = [] 97 98 if not isinstance(filters, list) and not isinstance(filters, tuple): 99 filters = [filters] 100 101 last_exception = None 102 for filter in filters: 103 try: 104 return _run_tshark(filename, filter.replace('wlan_mgt', 'wlan'), 105 [x.replace('wlan_mgt', 'wlan') for x in display], 106 wait) 107 except UnknownFieldsException as e: 108 all_wlan_mgt = True 109 for f in e.fields: 110 if not f.startswith('wlan_mgt.'): 111 all_wlan_mgt = False 112 break 113 if not all_wlan_mgt: 114 raise 115 return _run_tshark(filename, filter, display, wait) 116 117 except AssertionError as e: 118 # Catch the error (and try the next provided filter) 119 last_exception = e 120 121 raise last_exception 122 123def run_tshark_json(filename, filter): 124 arg = ["tshark", "-r", filename, 125 _tshark_filter_arg, filter] 126 arg.append('-Tjson') 127 arg.append('-x') 128 try: 129 cmd = subprocess.Popen(arg, stdout=subprocess.PIPE, 130 stderr=subprocess.PIPE) 131 except Exception as e: 132 logger.info("Could run run tshark: " + str(e)) 133 if "No such file or directory: 'tshark'" in str(e): 134 raise HwsimSkip("No tshark available") 135 return None 136 output = cmd.communicate() 137 out = output[0].decode() 138 res = cmd.wait() 139 return out 140