示例#1
0
    def _build_stack(self):
        """
        Create all the layer and link them together. Of
        course other layer could be added if implemented.
        """
        #Layer 2
        self.eth = EthernetProtocol(self.interface)

        #Layer2.5
        self.mpls = MPLSProtocol()
        self.eth.register_layer(self.mpls)

        #Layer 3
        ip = IPProtocol()
        self.eth.register_layer(ip)

        #register mpls layer
        self.mpls.register_upper_layer(ip.name, ip)
        print self.mpls.name
        ip.register_lower_layer(self.mpls.name, self.mpls)

        arp = ARPProtocol(self.interface)
        self.eth.register_layer(arp)

        #Layer 4
        self.tcp = TCPProtocol()
        ip.register_layer(self.tcp)
        self.udp = UDPProtocol()
        ip.register_layer(self.udp)

        #Layer 7
        self.dns = DNSProtocol(self.interface)
        self.udp.register_layer(self.dns)
示例#2
0
 def _build_stack(self):
     """
     Create all the layer and link them together. Of
     course other layer could be added if implemented.
     """
     #Layer 2
     self.eth = EthernetProtocol(self.interface)
     
     #Layer 3
     ip = IPProtocol()
     self.eth.register_layer(ip)
     arp = ARPProtocol(self.interface)
     self.eth.register_layer(arp)
     
     #Layer 4
     self.tcp = TCPProtocol()
     ip.register_layer(self.tcp)
     self.udp = UDPProtocol()
     ip.register_layer(self.udp)
     
     #Layer 7
     self.dns = DNSProtocol(self.interface)
     self.udp.register_layer(self.dns)
示例#3
0
class PyStack(object):
    """
    PyStack is the class that wrap all the layers together.
    It builds an entire stack linking all the layers. It implement
    the Singleton Pattern. So within a script or across modules if
    they all create a Pystack object only one will be instantiated 
    and all the connections and request will be handled by this one.
    It provides a method call register_tcp_application to attach a TCP
    application to the stack like a server or a client. Of course the 
    stack should be started with run to start listening packet and stop
    to stop listening packets.
    """
    
    instance = None  #Attributes for the singleton pattern
    instanciated = False
    running = False
    _session = TCPSession    
    
    def __new__(cls, *args, **kwargs):
        """ Override the new method to all the time return the same instance"""
        if not cls.instance:
            cls.instance = super(PyStack, cls).__new__(cls, *args, **kwargs)
        return cls.instance
    
    def __init__(self, iface=None):
        """
        Create the stack. An interface is needed in argument because
        various layer need it. Then buildstack is called to create the stack.
        """
        if not self.instanciated:
            if iface:
                self.interface = iface
            else:
                self.interface = conf.route.route("0.0.0.0")[0]
            self.eth = None
            self.tcp = None
            self.udp = None
            self.dns = None
            self._build_stack()
            self.instanciated = True
        
    def _build_stack(self):
        """
        Create all the layer and link them together. Of
        course other layer could be added if implemented.
        """
        #Layer 2
        self.eth = EthernetProtocol(self.interface)
        
        #Layer 3
        ip = IPProtocol()
        self.eth.register_layer(ip)
        arp = ARPProtocol(self.interface)
        self.eth.register_layer(arp)
        
        #Layer 4
        self.tcp = TCPProtocol()
        ip.register_layer(self.tcp)
        self.udp = UDPProtocol()
        ip.register_layer(self.udp)
        
        #Layer 7
        self.dns = DNSProtocol(self.interface)
        self.udp.register_layer(self.dns)
    
    def register_tcp_application(self, app):
        """
        Register a TCP application on the stack. So
        basically create a tcp session for the app and attach
        the TCPSession to the TCP layer.
        """
        
        #Layer 5
        tcpsession = self._session(self.interface)
        tcpsession.register_lower_layer("default", self.tcp)
        #self.tcp.register_layer(tcpsession)
        
        #Layer 6
        #Nothing for now 
        
        #Layer 7
        tcpsession.register_layer(app)

    def register_udp_application(self, app):
        """
        Register the given app as an UDP application.
        """
        app.register_lower_layer("default", self.udp)

    def run(self, doreactor=True):
        """
        Just call the start_listening of the Ethernet layer (which
        hold the ScapyIO). Except for reactor which normally catch SIGINT to
        stop the reactor. Here we catch the SIGINT oursleves and stop the reactor
        by changing a boolean (which is tested periodically)
        """
        if not self.running:
            if doreactor:
                import signal
                signal.signal(signal.SIGINT, self._siginthandler)
            self.running = True
            self.eth.start_listening(doreactor)
    
    def _siginthandler(self, signum, stackframe):
        """Handler for the SIGINT signal"""
        print("SIGINT : stop called, waiting to finish..")
        reactor.callInThread(self.stop) 
    
    def stop(self):
        """
        Stop will stop the stack. But to make it 'smartly' try for every
        connections of the tcp layer to call the close method if it exists.
        Then wait 5 seconds to be sure that all the connections have the time
        to stop and then stop the stack itself.
        """
        for conn in self.tcp.upperLayers.values():  #Try to close every opened sessions
            if hasattr(conn, "close"):
                if callable(getattr(conn,"close")):
                    print("call close for: ", conn.connectionID)
                    conn.close()
        time.sleep(5)  #To be sure all connections stops well..
        self.eth.stop()
        self.running = False

    def is_tcp_port_free(self, p):
        """Return either or not the port sent in parameter is free"""
        return self.tcp.is_port_free(p)
    
    def is_udp_port_free(self, p):
        """Return either or not the port sent in parameter is free"""
        return self.udp.is_port_free(p)

    def set_custom_session(self, sess):
        """ Method that allow to change the kind of session created when registering tcp application """
        self._session = sess