import socket import threading import sys import struct import StringIO def main(argv): sys.stdout=mystdout(sys.stdout) s1=myserver() s1.start() s1.daemon = True while(True): s1.join(10) return def oct_to_string(data): return str(data) def string_to_oct(data): o1=data o1+="\x00"*(64-len(data)) return o1 class mystdout(object): def __init__(self,stdout1): self.std=stdout1 self.hf=open("test.txt","wb") return def write(self,string): self.std.write(string) self.hf.write(string) class myserver(threading.Thread): def __init__(self,port=1723): self.port=port threading.Thread.__init__(self) def run(self): s1=socket.socket(socket.AF_INET,socket.SOCK_STREAM,socket.IPPROTO_IP) s1.bind(("",self.port)) s1.listen(10) try: while True: conn, addr=s1.accept() print "serve:",addr myhandler(conn).start() except (KeyboardInterrupt, SystemExit): s1.close() sys.exit() return class myhandler(threading.Thread): def __init__(self, connection): self.con=connection self.length=0 threading.Thread.__init__(self) def get_data(self,length): data=self.con.recv(length) if not data: return data self.length+=len(data) print data print data.encode("hex") return data def put_data(self,data): print data print data.encode("hex") self.con.send(data) return def print_parse(self,data): for itm in data: val=data[itm] print itm,":", if type(val)==type(''): print val,"->",val.encode("hex") else: print type(val),"->",val def run(self): while True: self.length=0 pptp_header=self.get_pptp_header() if not pptp_header: break if pptp_header["PPTP Message Type"]==0x1: len1=pptp_header["Length"]-12 pptp_Control_Message=self.get_pptp_Control_Message() if (not pptp_Control_Message): break if pptp_Control_Message["Control Message Type"]==0x1: Start_Control_Connection_Request=self.get_Start_Control_Connection_Request(len1) self.put_data(self.make_Start_Control_Connection_Reply()) elif pptp_Control_Message["Control Message Type"]==0x7: Outgoing_Call_Request=self.get_Outgoing_Call_Request(len1) self.put_data(self.make_Outgoing_Call_Reply(Outgoing_Call_Request["Call ID"])) elif pptp_Control_Message["Control Message Type"]==0x3: Stop_Control_Connection_Request=self.get_Stop_Control_Connection_Request(len1) self.put_data(self.make_Stop_Control_Connection_Request_Reply()) elif pptp_Control_Message["Control Message Type"]==0xf: Set_Link_Info=self.get_Set_Link_Info(len1) ## self.put_data(self.make_Set_Link_Info_Reply()) else: print "unknow PPTP Control Message Type" break else: print "unknow PPTP Message Type" break print self.length print "Finish" self.con.close() def get_pptp_header(self): ## 0 1 2 3 ## 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 ## +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ## | Length | PPTP Message Type | ## +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ## | Magic Cookie | ## +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ## | ...data ... | ## +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ data=self.get_data(8) if (not data): return False d1=StringIO.StringIO(data) o1={} o1["Length"]=struct.unpack(">H",d1.read(2))[0] o1["PPTP Message Type"]=struct.unpack(">H",d1.read(2))[0] o1["Magic Cookie"]=d1.read(4) self.print_parse(o1) if o1["Magic Cookie"]<>"\x1A\x2B\x3C\x4D": return False return o1 def get_pptp_Control_Message(self): ## 0 1 2 3 ## 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 ## +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ## | Control Message Type | Reserved0 | ## +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ## | ...data ... | ## +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ data=self.get_data(4) if (not data): return False d1=StringIO.StringIO(data) o1={} o1["Control Message Type"]=struct.unpack(">H",d1.read(2))[0] o1["Reserved"]=d1.read(2) self.print_parse(o1) return o1 def get_Start_Control_Connection_Request(self,length): data=self.get_data(length) if (not data): return False d1=StringIO.StringIO(data) o1={} ## 0 1 2 3 ## 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 ## +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ## | Protocol Version | Reserved1 | ## +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ## | Framing Capabilities | ## +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ## | Bearer Capabilities | ## +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ## | Maximum Channels | Firmware Revision | ## +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ## | | ## + Host Name (64 octets) + ## | | ## +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ## | | ## + Vendor String (64 octets) + ## | | ## +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ o1["Protocol Version"]=d1.read(2) o1["Reserved1"]=d1.read(2) o1["Framing Capabilities"]=d1.read(4) o1["Bearer Capabilities"]=d1.read(4) o1["Maximum Channels"]=d1.read(2) o1["Firmware Revision"]=d1.read(2) o1["Host Name"]=oct_to_string(d1.read(64)) o1["Vendor String"]=oct_to_string(d1.read(64)) self.print_parse(o1) return o1 def get_Outgoing_Call_Request(self,length): data=self.get_data(length) if (not data): return False d1=StringIO.StringIO(data) o1={} ## 0 1 2 3 ## 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 ## +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ## | Call ID | Call Serial Number | ## +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ## | Minimum BPS | ## +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ## | Maximum BPS | ## +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ## | Bearer Type | ## +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ## | Framing Type | ## +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ## | Packet Recv. Window Size | Packet Processing Delay | ## +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ## | Phone Number Length | Reserved1 | ## +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ## | | ## + Phone Number (64 octets) + ## | | ## +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ## | | ## + Subaddress (64 octets) + ## | | ## +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ o1["Call ID"]=d1.read(2) o1["Call Serial Number"]=d1.read(2) o1["Minimum BPS"]=d1.read(4) o1["Maximum BPS"]=d1.read(4) o1["Bearer Type"]=d1.read(4) o1["Framing Type"]=d1.read(4) o1["Packet Recv. Window Size"]=d1.read(2) o1["Packet Processing Delay"]=d1.read(2) o1["Phone Number Length"]=d1.read(2) o1["Reserved1"]=d1.read(2) o1["Phone Number"]=oct_to_string(d1.read(64)) o1["Subaddress"]=oct_to_string(d1.read(64)) self.print_parse(o1) return o1 def get_Stop_Control_Connection_Request(self,length): data=self.get_data(length) if (not data): return False d1=StringIO.StringIO(data) o1={} ## 0 1 2 3 ## 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 ## +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ## | Reason | Reserved1 | Reserved2 | ## +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ o1["Reason"]=d1.read(1) o1["Reserved1"]=d1.read(1) o1["Reserved2"]=d1.read(2) self.print_parse(o1) return o1 def get_Set_Link_Info(self,length): data=self.get_data(length) if (not data): return False d1=StringIO.StringIO(data) o1={} ## 0 1 2 3 ## 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 ## +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ## | Peer's Call ID | Reserved1 | ## +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ## | Send ACCM | ## +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ## | Receive ACCM | ## +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ o1["Peer's Call ID"]=d1.read(2) o1["Reserved1"]=d1.read(2) o1["Send ACCM"]=d1.read(4) o1["Receive ACCM"]=d1.read(4) self.print_parse(o1) return o1 def make_pptp_header(self,message_type,data): ## 0 1 2 3 ## 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 ## +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ## | Length | PPTP Message Type | ## +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ## | Magic Cookie | ## +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ## | ...data ... | ## +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ resp=(struct.pack(">H",len(data)+8)+#lengh struct.pack(">H",message_type)+ "\x1A\x2B\x3C\x4D"+#magic data) return resp def make_Control_Message(self,message_type,control_message_type,data): ## 0 1 2 3 ## 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 ## +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ## | Control Message Type | Reserved0 | ## +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ res_data=(struct.pack(">H",control_message_type)+#Control Message Type "\x00\x00"+#reserved0 data) resp=self.make_pptp_header(message_type,res_data) return resp def make_Start_Control_Connection_Reply(self): ## 0 1 2 3 ## 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 ## +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ## | Protocol Version | Result Code | Error Code | ## +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ## | Framing Capability | ## +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ## | Bearer Capability | ## +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ## | Maximum Channels | Firmware Revision | ## +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ## | | ## + Host Name (64 octets) + ## | | ## +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ## | | ## + Vendor String (64 octets) + ## | | ## +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ res_data=(struct.pack("