Changeset 5


Ignore:
Timestamp:
Feb 26, 2013 11:17:34 AM (5 years ago)
Author:
pawanranganath
Message:

updates for tickets 2 & 3

File:
1 edited

Legend:

Unmodified
Added
Removed
  • netcheck/trace_ordering.py

    r3 r5  
    22Steven Portzer 
    33Start Date: 07/1/2012 
    4  
    54Purpose: To order system calls from traces collected across multiple trace. 
    6  
    75usage: python trace_ordering.py CONFIG_FILE 
    8  
    96""" 
    10  
    117import model_network_syscalls as model 
    128import trace_output 
    139import ip_matching 
    1410import sys 
    15  
    1611 
    1712 
     
    3227 
    3328# System calls whose relative ordering we care about across traces. 
     29# PRR: Added getpeername to the list of system calls whose ordering we care about 
    3430ORDERED_SYSCALLS = RECV_SYSCALLS + SEND_SYSCALLS + [ 
    3531  "accept_syscall", "connect_syscall", "close_syscall", "implicit_close", 
    36   "poll_syscall", "select_syscall", "shutdown_syscall", "listen_syscall" 
     32  "poll_syscall", "select_syscall", "shutdown_syscall", "listen_syscall", 
     33  "getpeername_syscall" 
    3734] 
    38  
    39  
    4035 
    4136def verify_traces(config_filename): 
     
    4439  by the configuration file through the model. 
    4540  """ 
    46  
    4741  traces_generators = ip_matching.initialize_hosts(config_filename) 
    4842  trace_output.log_intialize(traces_generators.keys()) 
    49  
     43   
    5044  syscall_dict = {} 
    51  
     45   
    5246  for trace_id in traces_generators: 
    5347    try: 
     
    5549    except StopIteration: 
    5650      pass 
    57  
     51     
    5852  while syscall_dict: 
    59  
    6053    next_syscall_index = choose_next_syscall(syscall_dict.values()) 
    61  
     54     
    6255    try: 
    6356      syscall_dict[next_syscall_index] = traces_generators[next_syscall_index].next() 
     
    6659 
    6760  trace_output.log_done() 
    68  
    69  
    70  
     61   
     62   
    7163def verify_unit_test(trace_filenames): 
    7264  """ 
     
    7466  the model. 
    7567  """ 
    76  
    7768  traces_generators = ip_matching.initialize_unit_test(trace_filenames) 
     69 
    7870  trace_output.log_intialize(traces_generators.keys()) 
    79  
     71   
    8072  syscall_dict = {} 
    81  
     73   
    8274  for trace_id in traces_generators: 
    8375    try: 
     
    8577    except StopIteration: 
    8678      pass 
    87  
     79     
    8880  while syscall_dict: 
    89  
    9081    next_syscall_index = choose_next_syscall(syscall_dict.values()) 
    91  
    9282    try: 
    9383      syscall_dict[next_syscall_index] = traces_generators[next_syscall_index].next() 
     
    9686 
    9787  trace_output.log_done() 
    98  
    99  
     88   
    10089 
    10190def choose_next_syscall(syscall_list): 
     
    10594  returned, or if no action is possible an exception is raised. 
    10695  """ 
    107  
    10896  syscall_list.sort(key=syscall_priority) 
    109  
     97   
    11098  for syscall in syscall_list: 
    11199    if verify_syscall(syscall): 
    112100      return syscall[1][0] 
    113  
     101     
    114102  syscall_err_list = [] 
     103   
    115104  for syscall in syscall_list: 
    116105    err = get_syscall_err(syscall) 
    117106    syscall_err_list.append((syscall, err)) 
    118  
     107     
    119108  trace_output.log_execution_blocked(syscall_err_list) 
     109   
    120110  raise NoValidOrderingException("No valid action exists") 
    121  
    122111 
    123112def syscall_priority(syscall): 
     
    128117 
    129118  name, args, ret = syscall 
    130  
     119   
    131120  if name not in ORDERED_SYSCALLS: 
    132121    return 0 
    133  
     122   
    134123  if name == 'select_syscall': 
    135124    if model.care_about_fd_list(args[0], args[1]) and (isinstance(ret[0], int) 
    136125        or model.care_about_fd_list(args[0], ret[0])): 
    137126      return 1 
     127     
     128    #PRR: Select system call now dependent on recv/read 
     129    elif name in RECV_SYSCALLS: 
     130      return 1 
     131     
    138132    else: # Don't care about the call 
    139133      return 0 
    140  
     134     
    141135  if name == 'poll_syscall': 
    142136    if model.care_about_fd_list(args[0], args[1]) and (isinstance(ret[0], int) 
    143137        or model.care_about_fd_list(args[0], ret[0][0])): 
    144138      return 1 
     139     
     140    #PRR: Poll System call now dependent on recv/read 
     141    elif name in RECV_SYSCALLS: 
     142      return 1 
     143     
    145144    else: # Don't care about the call 
    146145      return 0 
    147  
     146     
    148147  # Make sure the socket is one we care about. 
    149148  sock = syscall[1][:2] 
     
    152151 
    153152  socket = model.sockets[sock] 
    154  
     153   
    155154  # Make sure if there is a remote address involved that we care about it. 
    156155  ip, port = None, None 
    157  
    158156  if name == 'accept_syscall': 
    159157    trace_id, fd, ip, port = args 
     158     
    160159  elif name == 'recvfrom_syscall': 
    161160    trace_id, sock, msg, buf_len, flags, ip, port = args 
     161     
    162162  elif name == 'recvmsg_syscall': 
    163163    trace_id, sock, msg, buf_len, ip, port, flags = args 
     164     
    164165  elif name == 'connect_syscall': 
    165166    trace_id, sock, ip, port = args 
     167     
    166168  elif name == 'sendto_syscall': 
    167169    trace_id, sock, msg, flags, ip, port = args 
     170     
    168171  elif name == "sendmsg_syscall": 
    169172    trace_id, sock, msg, ip, port, flags = args 
    170  
     173     
    171174  if not ip and socket['protocol'] == model.IPPROTO_UDP and name in SEND_SYSCALLS: 
    172175    ip, port = socket['peer_ip'], socket['peer_port'] 
    173  
     176     
    174177  if ip and ip not in model.broadcast_ip and ip_matching.addr_dont_care(ip, port): 
    175178    return 0 
    176  
     179   
    177180  # We care about these calls, so now order them according to our rules. 
    178  
    179181  if name == 'accept_syscall': 
    180182    return 1 
     183   
    181184  elif name in RECV_SYSCALLS: 
    182185    return 1 
    183  
     186   
    184187  elif name == 'connect_syscall': 
    185188    if socket['protocol'] == model.IPPROTO_UDP: 
    186189      return 0 
    187190    return 2 
     191   
    188192  elif name in SEND_SYSCALLS: 
    189193    return 2 
    190194 
    191   elif name == 'listen_syscall': 
     195  #PRR: getpeername now has a lower priority - dependent on close 
     196  elif name == 'listen_syscall' or name == 'getpeername_syscall': 
    192197    return 3 
     198   
    193199  elif name in ["close_syscall", "implicit_close", "shutdown_syscall"]: 
    194200    if socket['state'] not in ['CONNECTED', 'LISTEN']: 
    195201      return 0 
    196202    return 3 
    197  
     203   
    198204  raise Exception("Failed to handle priority of " + name) 
    199205 
     
    205211  the model is not updated. 
    206212  """ 
    207  
    208213  try: 
    209214    model_call(syscall) 
    210  
     215     
    211216  except model.SyscallError, err: 
    212217    trace_output.log_syscall_attempt(syscall, err) 
    213218    return False 
    214  
     219   
    215220  except model.SyscallException, err: 
    216221    trace_output.log_syscall(syscall, err) 
    217  
     222     
    218223  else: 
    219224    trace_output.log_syscall(syscall) 
    220  
     225     
    221226  return True 
    222227 
     
    227232  the model. 
    228233  """ 
    229  
    230234  try: 
    231235    model_call(syscall) 
    232  
     236     
    233237  except Exception, err: 
    234238    return err 
    235239 
    236  
     240   
    237241def model_call(syscall): 
    238242  """ 
     
    241245  or SyscallDontCare depending on what failed. 
    242246  """ 
    243  
    244247  name, args, ret = syscall 
     248   
    245249  impl_ret, impl_errno = ret 
    246  
     250   
    247251  try: 
    248  
     252     
    249253    ##### SOCKET ##### 
    250254    if name == 'socket_syscall': 
    251255      trace_id, dom, typ, prot = args 
    252256      model_ret = model.socket_syscall(trace_id, dom, typ, prot, impl_ret) 
    253  
     257       
    254258    ##### BIND ##### 
    255259    elif name == 'bind_syscall': 
    256260      trace_id, sock, addr, port = args 
    257261      model_ret = model.bind_syscall(trace_id, sock, addr, port, impl_errno) 
    258  
     262       
    259263    ##### LISTEN ##### 
    260264    elif name == 'listen_syscall': 
    261265      trace_id, sock, log = args 
    262266      model_ret = model.listen_syscall(trace_id, sock, log, impl_errno) 
    263  
     267       
    264268    ##### ACCEPT ##### 
    265269    elif name == 'accept_syscall': 
    266270      trace_id, fd, ip, port = args 
    267271      model_ret = model.accept_syscall(trace_id, fd, ip, port, impl_ret, impl_errno) 
    268  
    269     ##### CONNECT #####  
     272       
     273    ##### CONNECT ##### 
    270274    elif name == 'connect_syscall': 
    271275      trace_id, sock, addr, port = args 
    272276      model_ret = model.connect_syscall(trace_id, sock, addr, port, impl_errno) 
    273  
     277       
    274278    ##### SEND ##### 
    275279    elif name == 'send_syscall': 
    276280      trace_id, sock, msg, flag = args 
    277281      model_ret = model.send_syscall(trace_id, sock, msg, flag, impl_ret, impl_errno) 
    278      
     282    
    279283    ##### WRITE ##### 
    280284    elif name == 'write_syscall': 
    281285      trace_id, sock, msg = args 
    282286      model_ret = model.send_syscall(trace_id, sock, msg, 0, impl_ret, impl_errno) 
    283      
     287    
    284288    ##### WRITEV ##### 
    285289    elif name == 'writev_syscall': 
    286290      trace_id, sock, msg, count = args 
    287291      model_ret = model.send_syscall(trace_id, sock, msg, 0, impl_ret, impl_errno) 
    288  
     292       
    289293    ##### SENDTO ##### 
    290294    elif name == 'sendto_syscall': 
    291295      trace_id, sock, msg, flags, remoteip, remoteport = args 
    292296      model_ret = model.sendto_syscall(trace_id, sock, msg, impl_ret, flags, remoteip, remoteport, impl_errno) 
    293  
     297       
    294298    ##### SENDMSG ##### 
    295299    elif name == "sendmsg_syscall": 
    296300      trace_id, sock, msg, remoteip, remoteport, flags = args 
    297301      model_ret = model.sendto_syscall(trace_id, sock, msg, impl_ret, flags, remoteip, remoteport, impl_errno) 
    298  
     302       
    299303    ##### SENDFILE ##### 
    300304    elif name == "sendfile_syscall": 
    301305      trace_id, out_sock, in_sock, offset, count = args 
    302306      model_ret = model.sendfile_syscall(trace_id, out_sock, in_sock, offset, count, impl_ret, impl_errno) 
    303  
     307       
    304308    ##### RECVFROM ##### 
    305309    elif name == 'recvfrom_syscall': 
    306310      trace_id, sock, msg, buf_len, flags, ip, port = args 
    307311      model_ret = model.recvfrom_syscall(trace_id, sock, buf_len, flags, ip, port, msg, impl_ret, impl_errno) 
    308  
     312       
    309313    ##### RECVMSG ##### 
    310314    elif name == "recvmsg_syscall": 
    311315      trace_id, sock, msg, buf_len, remoteip, remoteport, flags = args 
    312316      model_ret = model.recvfrom_syscall(trace_id, sock, buf_len, flags, remoteip, remoteport, msg, impl_ret, impl_errno) 
    313  
     317       
    314318    ##### RECV ##### 
    315319    elif name == 'recv_syscall': 
    316320      trace_id, sock, msg, buf_len, flag = args 
    317321      model_ret = model.recv_syscall(trace_id, sock, buf_len, flag, msg, impl_ret, impl_errno) 
    318  
     322       
    319323    ##### READ ##### 
    320324    elif name == 'read_syscall': 
    321325      trace_id, sock, msg, buf_len = args 
    322326      model_ret = model.recv_syscall(trace_id, sock, buf_len, 0, msg, impl_ret, impl_errno) 
    323  
     327       
    324328    ##### CLOSE ##### 
    325329    elif name == 'close_syscall' or name == 'implicit_close': 
    326330      trace_id, sock = args 
    327331      model_ret = model.close_syscall(trace_id, sock, impl_errno) 
    328  
     332       
    329333    ##### SETSOCKOPT ##### 
    330334    elif name == 'setsockopt_syscall': 
    331335      trace_id, sockfd, level, optname, optval = args 
    332336      model_ret = model.setsockopt_syscall(trace_id, sockfd, level, optname, optval) 
    333  
     337       
    334338    ##### GETSOCKOPT ##### 
    335339    elif name == 'getsockopt_syscall': 
    336340      trace_id, sockfd, level, optname = args 
    337341      model_ret = model.getsockopt_syscall(trace_id, sockfd, level, optname) 
    338  
     342       
    339343    ##### GETPEERNAME ##### 
    340344    elif name == 'getpeername_syscall': 
     
    342346      peer_addr, peer_port = impl_ret 
    343347      model_ret = model.getpeername_syscall(trace_id, sock, peer_addr, peer_port) 
    344  
     348       
    345349    ##### GETSOCKNAME ##### 
    346350    elif name == 'getsockname_syscall': 
     
    348352      sock_ip, sock_port = impl_ret 
    349353      model_ret = model.getsockname_syscall(trace_id, sock, sock_ip, sock_port) 
    350  
     354       
    351355    ##### IOCTL ##### 
    352356    elif name == 'ioctl_syscall': 
    353357      trace_id, fd, cmd, val = args 
    354358      model_ret = model.ioctl_syscall(trace_id, fd, cmd, val) 
    355  
     359       
    356360    ##### FCNTL ##### 
    357361    elif name == 'fcntl_syscall': 
    358362      model_ret = model.fcntl_syscall(impl_ret, *args) 
    359  
     363       
    360364    ##### SELECT ##### 
    361365    elif name == 'select_syscall': 
    362366      trace_id, readfds, writefds, errorfds, timeout = args 
    363367      model_ret = model.select_syscall(trace_id, readfds, writefds, errorfds, timeout, impl_ret, impl_errno) 
    364  
     368       
    365369    ##### POLL ##### 
    366370    elif name == 'poll_syscall': 
    367371      trace_id, new_pollin, new_pollout, new_pollerr, timeout = args 
    368372      model_ret = model.poll_syscall(trace_id, new_pollin, new_pollout, new_pollerr, timeout, impl_ret, impl_errno) 
    369  
     373       
    370374    ##### SHUTDOWN ##### 
    371375    elif name == 'shutdown_syscall': 
    372376      trace_id, sock, how = args 
    373377      model_ret = model.shutdown_syscall(trace_id, sock, how) 
    374  
    375378    else: 
    376379      raise model.SyscallNotice(name, 'UNKNOWN_SYSCALL', "'" + name + "' is not a recognized system call.") 
    377  
     380     
     381     
    378382  except model.SyscallError, err: 
    379383    if impl_ret == -1 and isinstance(impl_errno, str) and impl_errno in err.args[1]: 
    380384      return 
    381  
    382385    raise err 
    383  
     386   
    384387  if impl_ret == -1: 
    385388    raise model.SyscallWarning(name, 'UNEXPECTED_SUCCESS', "Model succeeded but implementation failed.") 
    386  
     389   
    387390  if impl_ret != model_ret[0]: 
    388391    raise model.SyscallWarning(name, 'UNEXPECTED_RETURN_VALUE', "Model returned " + str(model_ret[0])) 
    389392 
    390  
    391  
     393   
    392394def main(): 
    393  
    394395  if len(sys.argv) >= 2 and sys.argv[1] == '-u': 
     396     
    395397    try: 
    396398      verify_unit_test(sys.argv[2:]) 
     399       
    397400    except NoValidOrderingException: 
    398401      pass 
    399  
     402     
    400403  elif len(sys.argv) == 2: 
    401404    try: 
    402405      verify_traces(sys.argv[1]) 
     406       
    403407    except NoValidOrderingException: 
    404408      pass 
    405  
    406409  else: 
    407410    print "usage: python trace_ordering.py CONFIG_FILE" 
    408411 
    409  
     412     
    410413if __name__ == "__main__": 
    411414  main() 
    412  
Note: See TracChangeset for help on using the changeset viewer.