【问题标题】:Scapy: Inserting a new layer and logging issuesScapy:插入新层并记录问题
【发布时间】:2013-06-23 09:57:32
【问题描述】:
  1. 我正在尝试使用 Scapy 在 GRE 和 IP 之间插入 GRErouting 层。我正在阅读的 pcap 包含一个堆叠如下的数据包:Ethernet/IPv4/GRE/IPv4/ICMP。 我看到的是 getLayer 返回当前层 + 它的有效负载,其中可能包括其他层,这对我不利。我只想获取当前图层。当我为每一层执行 getLayer,然后写入整个数组时,我会得到一个奇怪的 pcap,因为每一层都有额外的有效负载。
  2. 我也无法使用简单的“打印”将任何数据输出到控制台。我知道这是因为 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])))            
    

【问题讨论】:

    标签: scapy


    【解决方案1】:

    我终于能够回答我自己的两个问题了。请参阅下面的修改代码:

        # 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]))))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-11-28
      • 2011-07-01
      • 2011-08-21
      • 1970-01-01
      • 2019-09-01
      • 2015-05-21
      • 1970-01-01
      相关资源
      最近更新 更多