#!/usr/bin/env python

import os
import asyncore
import socket
from struct import unpack


class BGPHandler(asyncore.dispatcher_with_send):
	def read_message (self):
		header = self.recv(19)
		length = unpack('!H',header[16:18])[0]
		body = self.recv(length)
		return header,body

	def handle_read (self):
		# reply with a IBGP response with the same capability (just changing routerID)
		print "reading open"
		header,body = self.read_message()
		routerid = chr((ord(body[8])+1) & 0xFF)
		o = header+body[:8]+routerid+body[9:]
		self.send(o)

class BGPServer(asyncore.dispatcher):
	def __init__ (self, host, port):
		asyncore.dispatcher.__init__(self)
		self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
		self.set_reuse_addr()
		self.bind((host, port))
		self.listen(5)

	def handle_accept (self):
		pair = self.accept()
		if pair is not None:
			# The if prevent invalid unpacking
			sock, addr = pair  # pylint: disable=W0633
			print "new BGP connection from", addr
			handler = BGPHandler(sock)


if os.environ.get('exabgp.tcp.port','').isdigit():
	port = int(os.environ.get('exabgp.tcp.port'))
elif os.environ.get('exabgp_tcp_port','').isdigit():
	port = int(os.environ.get('exabgp_tcp_port'))
else:
	port = 179

server = BGPServer('localhost', port)
asyncore.loop()
