예제 #1
0
	def __init__(self, tap=True, readSockets=[]):
		""" Constructor for Ether2Any.

		isTap defines if the managed device should be a tap (ethernet tunnel)
		or a tun (IP tunnel). """
		self.readSockets = readSockets
		# create device
		self.dev = TapDevice(tap=tap)
		
		self.timeout = None
예제 #2
0
파일: TapLoop.py 프로젝트: grwl/pscan
class TapLoop:
	'''
	This class creates a pair of interconnected TAP interfaces.
	If address and netmask are provided, they get assigned to the "remote" interface.
	The users are supposed to call get_iface() method to obtain the name of the "local" interface.
	Then the users are expected to use raw sockets to send/receive traffic on that local interface,
	possibly to interact with the remote end.
	'''
	def __init__(self, local_address = None, remote_address = None, netmask = None):
		self.t1 = TapDevice(mode = IFF_TAP)
		self.t2 = TapDevice(mode = IFF_TAP)

		if local_address != None and netmask != None:
			self.t1.ifconfig(address = local_address, netmask = netmask)

		if remote_address != None and netmask != None:
			self.t2.ifconfig(address = remote_address, netmask = netmask)

		self.t1.up()
		self.t2.up()

		self.pump1 = Pump(self.t1, self.t2)
		self.pump2 = Pump(self.t2, self.t1)

		logger.debug("Allocated TAP interfaces %s/%s" % (self.t1.name, self.t2.name))

	def start(self):
		self.pump1.start()
		self.pump2.start()
		logger.debug("Started pump threads")

	def get_iface(self):
		return self.t1.name
예제 #3
0
파일: TapLoop.py 프로젝트: grwl/pscan
	def __init__(self, local_address = None, remote_address = None, netmask = None):
		self.t1 = TapDevice(mode = IFF_TAP)
		self.t2 = TapDevice(mode = IFF_TAP)

		if local_address != None and netmask != None:
			self.t1.ifconfig(address = local_address, netmask = netmask)

		if remote_address != None and netmask != None:
			self.t2.ifconfig(address = remote_address, netmask = netmask)

		self.t1.up()
		self.t2.up()

		self.pump1 = Pump(self.t1, self.t2)
		self.pump2 = Pump(self.t2, self.t1)

		logger.debug("Allocated TAP interfaces %s/%s" % (self.t1.name, self.t2.name))
예제 #4
0
    def __init__(self, tap=True, readSockets=[]):
        """ Constructor for Ether2Any.

		isTap defines if the managed device should be a tap (ethernet tunnel)
		or a tun (IP tunnel). """
        self.readSockets = readSockets
        # create device
        self.dev = TapDevice(tap=tap)

        self.timeout = None
예제 #5
0
    def __init__(self, options={}):
        self.secret = options.get('secret','')
        self.port = options.get('port',11111)
        self.buffer = []
        self.loadbalancer_pool = []

        _tap = options.get('tap', True)
        _name = options.get('name', '')
        self.dev = TapDevice(tap=_tap, name=_name)

        asyncore.file_dispatcher.__init__(self, self.dev.getFD())

        self.dev.up()
        if options.get('tunnel_address', False):
            self.dev.ifconfig(address=options.get('tunnel_address'))

        logging.debug('Interface ready')
예제 #6
0
class Ether2Any:
    """ Baseclass for writing arbitrary Ethernet/IP tunnel using a TUN/TAP device.
	
	This class handles a TUN/TAP devices and runs a select loop for it and,
	if given, a set of sockets. To use this class at least sendToNet() has
	to be implemented by a subclass. """

    def __init__(self, tap=True, readSockets=[]):
        """ Constructor for Ether2Any.

		isTap defines if the managed device should be a tap (ethernet tunnel)
		or a tun (IP tunnel). """
        self.readSockets = readSockets
        # create device
        self.dev = TapDevice(tap=tap)

        self.timeout = None

    def setupLogging(self, name):
        l = logging.getLogger(name)
        fmt = logging.Formatter("%(asctime)s - [%(levelname)s] (%(name)s) - %(message)s")
        ch = logging.StreamHandler()
        ch.setFormatter(fmt)
        l.addHandler(ch)

        return l

    def addSocket(self, sock):
        """ Add socket to readSockets set. """
        self.readSockets.append(sock)

    def delSocket(self, socket):
        """ Remove socket from readSockets set. """
        try:
            self.readSockets.remove(socket)
        except ValueError:
            pass

            # outgoing data

    def sendToNet(self, packet):
        """ This function has to be implemented to handle outgoing
		data (read from the TUN/TAP device) """
        raise NotImplementedError("You need to overload sendToNet()")

        # incoming data

    def sendToDev(self, sock):
        """ This function has to be implemented to handle incoming
		data which is read from the extra sockets (self.readSockets).
		It will not be called when no extra readSockets are specified. """
        raise NotImplementedError("You need to overload sendToDev()")

    def setTimeout(self, t):
        """ Set select timeout. """
        self.timeout = t

    def callAfterSelect(self):
        """ Will be called as last operation of the mainloop when
		handling of the select result / the select timeout is hit.
		"""
        pass

    def run(self):
        """ Run main select-loop. """
        try:
            while True:
                sockets = [self.dev.getFD()] + self.readSockets
                (readFDs, _, _) = select.select(sockets, [], [], self.timeout)
                for readFD in readFDs:
                    if readFD == self.dev.getFD():
                        self.sendToNet(self.dev.read())
                    elif readFD in self.readSockets:
                        self.sendToDev(readFD)
                self.callAfterSelect()
        except KeyboardInterrupt:
            self.quit()
        self.dev.close()

    def quit(self):
        """ Will be called after the run-select() and its processing is done. """
        pass
예제 #7
0
class Ether2Any:
	""" Baseclass for writing arbitrary Ethernet/IP tunnel using a TUN/TAP device.
	
	This class handles a TUN/TAP devices and runs a select loop for it and,
	if given, a set of sockets. To use this class at least sendToNet() has
	to be implemented by a subclass. """
	def __init__(self, tap=True, readSockets=[]):
		""" Constructor for Ether2Any.

		isTap defines if the managed device should be a tap (ethernet tunnel)
		or a tun (IP tunnel). """
		self.readSockets = readSockets
		# create device
		self.dev = TapDevice(tap=tap)
		
		self.timeout = None
	
	def setupLogging(self, name):
		l = logging.getLogger(name)
		fmt = logging.Formatter("%(asctime)s - [%(levelname)s] (%(name)s) - %(message)s")
		ch = logging.StreamHandler()
		ch.setFormatter(fmt)
		l.addHandler(ch)
		
		return l
	
	def addSocket(self, sock):
		""" Add socket to readSockets set. """
		self.readSockets.append(sock)
	
	def delSocket(self, socket):
		""" Remove socket from readSockets set. """
		try:
			self.readSockets.remove(socket)
		except ValueError:
			pass

	# outgoing data
	def sendToNet(self, packet):
		""" This function has to be implemented to handle outgoing
		data (read from the TUN/TAP device) """
		raise NotImplementedError("You need to overload sendToNet()")
	
	# incoming data
	def sendToDev(self, sock):
		""" This function has to be implemented to handle incoming
		data which is read from the extra sockets (self.readSockets).
		It will not be called when no extra readSockets are specified. """
		raise NotImplementedError("You need to overload sendToDev()")
	
	def setTimeout(self, t):
		""" Set select timeout. """
		self.timeout = t
	
	def callAfterSelect(self):
		""" Will be called as last operation of the mainloop when
		handling of the select result / the select timeout is hit.
		"""
		pass
	
	def run(self):
		""" Run main select-loop. """
		try:
			while True:
				sockets = [self.dev.getFD()] + self.readSockets
				(readFDs, _, _) = select.select(sockets, [], [], self.timeout)
				for readFD in readFDs:
					if readFD == self.dev.getFD():
						self.sendToNet(self.dev.read())
					elif readFD in self.readSockets:
						self.sendToDev(readFD)
				self.callAfterSelect()
		except KeyboardInterrupt:
			self.quit()
		self.dev.close()
	
	def quit(self):
		""" Will be called after the run-select() and its processing is done. """
		pass
예제 #8
0
class LoadbalancerControl(asyncore.file_dispatcher):
    shutdown = False    # Loadbalancers shouldn't reconnect
    rr = 0              # RoundRobin iterator counter

    def __init__(self, options={}):
        self.secret = options.get('secret','')
        self.port = options.get('port',11111)
        self.buffer = []
        self.loadbalancer_pool = []

        _tap = options.get('tap', True)
        _name = options.get('name', '')
        self.dev = TapDevice(tap=_tap, name=_name)

        asyncore.file_dispatcher.__init__(self, self.dev.getFD())

        self.dev.up()
        if options.get('tunnel_address', False):
            self.dev.ifconfig(address=options.get('tunnel_address'))

        logging.debug('Interface ready')

    def eth_addr (self, a) :
        b = "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x" % (ord(a[0]) , ord(a[1]) , ord(a[2]), ord(a[3]), ord(a[4]) , ord(a[5]))
        return b

    def validate(self, data):
        eth_length = 14
         
        eth_header = data[:eth_length]
        eth = struct.unpack('!6s6sH' , eth_header)
        eth_protocol = socket.ntohs(eth[2])
#        print 'Destination MAC : ' + self.eth_addr(data[0:6]) + ' Source MAC : ' + self.eth_addr(data[6:12]) + ' Protocol : ' + str(eth_protocol)

        ip_header = data[eth_length:20+eth_length]
        iph = struct.unpack('!BBHHHBBH4s4s' , ip_header)
        version_ihl = iph[0]
        ihl = version_ihl & 0xF

        iph_length = ihl * 4
        protocol = iph[6]
        s_addr = socket.inet_ntoa(iph[8])
        d_addr = socket.inet_ntoa(iph[9])

#        udp_header = data[iph_length+eth_length:iph_length+20+eth_length]
#        udph = struct.unpack('!HHLLBBHHH' , udp_header)
#        print "[{}] - {}:{} -> {}:{}".format(protocol, s_addr,udph[0], d_addr,udph[1])

    def writable(self):
        return len(self.buffer) > 0

    def handle_write(self):
        """ Write local buffer to interface """
        try:
            packet = self.buffer.pop()
            logging.debug('Writing {}byte packet to device'.format(len(packet)))
            self.dev.write(packet)
        except IndexError:
            pass
        except OSError as e:
            if e.errno == 22:
                # Invalid packet
                logging.debug('Failed to write invalid packet "{}"'.format(packet))
            else:
                logging.exception('Writing "{}" to device caused exception: {}'.format(packet, e.strerror))
        except Exception as e:
            logging.exception('Writing "{}" to device caused exception: {}'.format(packet, e.strerror))

    def write(self, packet):
        """ Forward data from loadbalancers to local buffer """
        if packet:
#            self.validate(packet)
            self.buffer.append(packet)

    def handle_read_event(self):
        """ Forward received packets to loadbalancers """
        packet = self.dev.read()
        self.balance_data_round_robin(packet)

    def balance_data_round_robin(self, packet):
        """ Use Round Robin to distribute each packet via revolving loadbalancers """
        if len(self.loadbalancer_pool) == 0:
            return
        
#        logging.debug('Sending {}byte packet via {}'.format(len(packet), repr(self.loadbalancer_pool[self.rr])))
        self.loadbalancer_pool[self.rr].send(packet)
        self.rr = self.rr+1 if self.rr < len(self.loadbalancer_pool)-1 else 0

    def quit(self):
        """ Gracefully close all loadbalancers and self """
        self.shutdown = True
        logging.debug('Closing loadbalancers...')
        # Loadbalancer modifies the pool in close, so make a static list
        for s in list(self.loadbalancer_pool):
            s.handle_close()

        if self.loadbalancer_pool:
            logging.debug('Waiting for loadbalancers to close...')
            for i in range(5):
                if len(self.loadbalancer_pool) == 0:
                    break
                time.sleep(1)
            else:
                for s in self.loadbalancer_pool:
                    s.close()
                    del s

        logging.debug('Closing self...')
        self.dev.close()