2013-06-23 26 views
1
  1. 我試圖在使用Scapy的GRE和IP之間插入GRErouting層。我正在閱讀的pcap包含單個數據包,如下所示:Ethernet/IPv4/GRE/IPv4/ICMP。 我看到的是,getLayer返回當前圖層+其有效載荷,其中可能包含其他圖層,這對我並不好。我只想獲得當前圖層。當我爲每層獲取層時,然後寫入整個數組時,由於每層都有附加的有效載荷,所以我得到了一個奇怪的pcap。
  2. 我也無法使用簡單的'打印'輸出任何數據到控制檯。我知道這是因爲Scapy添加了日誌記錄模塊,並且抑制了系統日誌記錄,但是我想知道如何撤消它並能夠使用'print'語句。Scapy:插入一個新圖層並記錄問題

    import os 
    import sys 
    import logging 
    logging.basicConfig() 
    logging.getLogger("scapy.runtime").setLevel(logging.ERROR) 
    from scapy.all import PcapReader, PcapWriter, fuzz, Packet 
    from scapy.layers.l2 import GRE, GRErouting 
    from scapy.layers.inet import IP 
    logging.getLogger("scapy.runtime").setLevel(logging.DEBUG) 
    logging.getLogger().setLevel(logging.DEBUG) 
    
    
    def foo(in_filename, out_filename): 
        f = PcapReader(in_filename) 
        o = PcapWriter(out_filename) 
    
        p = f.read_packet() 
    
        while p: 
         layers = [] 
         counter = 0 
         while True: 
          layer = p.getlayer(counter) 
          if (layer != None): 
           layers.append(layer) 
    
           if (type(layer) is IP): 
            del layer.chksum 
           if (type(layer) is GRE): 
            logging.getLogger().debug("there is a GRE layer") 
            layer.routing_present = 1 
            gr = GRErouting() 
            fuzz(gr) 
            layers.append(gr) 
            del layer.chksum 
          else: 
           break 
          counter += 1 
         logging.getLogger().debug("Layers are: %s\t\t",layers) 
         for l in layers: 
          logging.getLogger().debug("%s", l) 
         o.write(layers) 
         p = f.read_packet() 
    
    
        f.close() 
        o.close() 
    
    if __name__ == "__main__": 
        logging.getLogger().debug('Executing main') 
        if (len(sys.argv) == 3): 
         in_filename = str(sys.argv[1]) 
         out_filename = str(sys.argv[2]) 
         if os.path.exists(in_filename) == False: 
          sys.stderr.write("Either {0} does not exist, or you do not have proper permissions\n".format(in_filename)) 
         else: 
          foo(in_filename, out_filename) 
        else: 
         sys.stderr.write("USAGE: {0} <path to input file> <path to output file>\n".format(str(sys.argv[0])))    
    

回答

2

我終於能回答我的兩個問題。請參閱下面的修改代碼:

# importing the os package (see api at http://docs.python.org/2.6/library/io.html) 
    import os 
    # import function 'basename' from module os.path 
    from os.path import basename 
    # importing the sys package (see api at http://docs.python.org/2.6/library/sys.html) 
    import sys 
    # importing the logging package (see api at http://docs.python.org/2.6/library/logging.html) 
    import logging 
    # by default Scapy attempts to find ipv6 routing information, 
    # and if it does not find any it prints out a warning when running the module. 
    # the following statement changes log level to ERROR so that this warning will not 
    # occur 
    effective_level = logging.getLogger("scapy.runtime").getEffectiveLevel() 
    logging.getLogger("scapy.runtime").setLevel(logging.ERROR) 
    # importing Scapy 
    from scapy.all import PcapReader, PcapWriter 
    from scapy.layers.l2 import GRE, GRErouting, NoPayload 
    # return the log level o be what it was 
    logging.getLogger("scapy.runtime").setLevel(effective_level) 
    # unfortunately, somewhere in Scapy sys.stdout is being reset. 
    # thus, using the 'print' command will not produce output to the console. 
    # the following two lines place stdout back into sys. 
    if sys.stdout != sys.__stdout__: 
     sys.stdout = sys.__stdout__ 

    # this is a function declaration. there is no need for explicit types. 
    # python can infer an object type from its usage 
    def foo(in_filename, out_filename): 
     # open the input file for reading 
     f = PcapReader(in_filename) 
     # open the output file for writing 
     o = PcapWriter(out_filename) 

     # read the first packet from the input file 
     p = f.read_packet() 

     # while we haven't processed the last packet 
     while p: 
      # gets the first layer of the current packet 
      layer = p.firstlayer() 
      # loop over the layers 
      while not isinstance(layer, NoPayload): 

       if layer.default_fields.has_key('chksum'): 
        del layer.chksum 
       if layer.default_fields.has_key('len'): 
        del layer.len 

       if (type(layer) is GRE): 
        layer.routing_present = 1 
        layer.chksum_present = 1 
        # make sure to delete the checksum field. hopefully scapy will calculate it correctly one day 
        del layer.chksum 

        gr = GRErouting() 
        gr.address_family = 0x0800 
        gr.SRE_len = 4 
        gr.SRE_offset = 0 
        gr.routing_info = "1111" 
        # the NULL routing field 
        empty_gr = GRErouting() 
        empty_gr.address_family = 0x0000 
        empty_gr.SRE_len = 0 

        gr.add_payload(empty_gr) 
        gr.add_payload(layer.payload) 
        layer.remove_payload() 
        layer.add_payload(gr) 
        layer = empty_gr 

       # advance to the next layer 
       layer = layer.payload 


      # write the packet we just dissected into the output file  
      o.write(p) 
      # read the next packet 
      p = f.read_packet() 

     # close the input file 
     f.close() 
     # close the output file 
     o.close() 

    # i believe this is needed only if we are running the this module 
    # as the main module. i don't know if this will get executed if this module 
    # is imported into some other main module 
    if __name__ == "__main__": 
     # letting the user know we are starting. 
     # sys.argv[0] includes the path to the module, including the module name. 
     # convert sys.argv[0] into string, and extract the module name only 
     # (using basename) 
     print '===> Running', basename(str(sys.argv[0])) 
     # making sure that two parameters were entered on the command line 
     if (len(sys.argv) == 3): 
      # get the path to the input file 
      in_filename = str(sys.argv[1]) 
      # get the path to the output file 
      out_filename = str(sys.argv[2]) 
      # make sure the input file actually exists. 
      # if it doesn't, we print out an error and exit 
      if os.path.exists(in_filename) == False: 
       # note the method for entering conversion specifiers ({<ordinal>}) 
       sys.stderr.write("Either {0} does not exist, or you do not have proper permissions\n".format(in_filename)) 
      else: 
       # if the input file does exist, execute 'foo' 
       foo(in_filename, out_filename) 
       # print an end script notification 
       print basename(str(sys.argv[0])), '===> completed successfully' 
     else: 
      # write a USAGE message to the standard output stream 
      sys.stderr.write("USAGE: {0} <path to input file> <path to output file>\n".format(basename(str(sys.argv[0])))) 
+0

務必接受您自己的答案。 – RyPeck