Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import socket
- import sys
- from os.path import exists,getsize
- import os
- import time
- import threading
- import math
- import msvcrt
- import random
- # virtual guest os:es set to
- # Generic Driver
- # Name=UDPTunnel
- # !check advanced
- # Generic Properties
- # dest=UDP RELAY SERVER HOST EXTERNAL IP (local ip on server host guest (0th client))
- # sport=ROUTED PORT INTERNET (port to send packets from SERVER(udp_relay_server) (setting name listen (tuple(tuple(ip,port),mac,tuple(ip,port),mac))) (client shouldn't need to be routed if packets are sent before server is running (server still routed))
- # dport=RELAY SERVER ROUTED PORT (setting name serverport)
- #without encryption data will be visible to middleman attacks
- #UDP SERVER SERVER external ip in example 111.111.111.111
- autolocalip=autoip() # DO NOT EDIT, this for autoconfiguring local ip (example ip 192.168.100.20 if we got 127.0.0.1 something failed, if we got external address looking address then you probably have bridging internet connection don't worry it still works.)
- serverport=27000 # port to host UDP RELAY SERVER/CLIENT(if client mode) (packet distributor)
- clientused=[0,1,2,3] # this is for easy disabling enabling clients. 0 is never disabled as UDP RELAY SERVER (you can safely remove 0 from the list if no guest os on server). (order which to send broadcast packets)
- listen= ((autolocalip, 26000) ,b'\x08\x00\x27\xff\xff\x00', # 0th enter here your server local ip + sport of virtual machine + your guest os virtual network card mac
- ('123.123.123.123',26000),b'\x08\x00\x27\xff\xff\x01', # 1st client ip of his/her host + sport value + 1st client guest os virtual network card mac
- ('231.231.231.231',26000),b'\x08\x00\x27\xff\xff\x02', # 2nd client ip of his/her host + sport value + 2nd client guest os virtual network card mac
- ('213.213.213.213',26000),b'\x08\x00\x27\xff\xff\x03') # 3rd client ip of his/her host + sport value + 3rd client guest os virtual network card mac
- data_payload = 2048 #max packet size (shouldn't need to be on mtu, preferably over it (low value will split packets and UDP RELAY SERVER cannot handle split packets))
- allclientsbroadcast = True #if False, only server host (client 0) broadcast packets are transmitted to all. host guest os (client 0) gameservers will be ONLY visible gameservers. (set this to True if server is running without guest os)
- broadcastonlyactive = True #if True, broadcast packets are only sent clients that have connected UDP RELAY SERVER (activates settings defaultstate,droptimeout and droppedremind)
- defaultstate= True #starting state of client DROPPED status (by starting dropped broadcast packets don't get send to clients until they have connected to server (UDP RELAY SERVER))
- displayfake = True #reports even if broadcastonlyactive is False on timeouts. (console output setting only)
- droptimeout = 360 #seconds clients are to remain in packet target if no connection from them.
- droppedremind = 120 #seconds bethween reminding dropped clients. (console output setting only)
- logfilename="logfile" #log for umatching connections (cannot be disabled) (you can provide file address here (example: "c:/logs/filename"))
- logfileext=".txt"
- #POSSIBLE MODES
- #star mode -> everyone connected to everyone
- # -each of clients are running this script
- # -each of clients known each of connected encryption keys,seeds, if using encryption
- # -everyone must have allclientsbroadcast False, (othervice packets get reflected (duplicated) back to source from who has it on)
- # -self is client 0 on each script
- #server - client mode -> everyone is connected to server
- # -each of clients are running this script, but in different settings look example bellow
- # -clients have allclientsbroadcast False (othervice packets get reflected (duplicated) back to source from who has it on)
- # -each client only knows it's own encryption keys,seeds, if using encryption
- # -self is client 0 on each script
- #server only mode -> everyone is connected to server (directly with guest os)
- # -only server is running this script
- # -each of clients is connect directly by their guest os
- # -therefore no encryption possible (if not encrypting directly from guest os)
- #encrypting settings (only possible on client mode system, where each client runs this script as client to communicate bethween UDP RELAY SERVER and from there to others (unless you manage encrypt network traffic at base level at guest os:es.))
- encryptingon=[False,True,True,True] #is encrypting turned on (reseprents client 0-3)
- cryptlvl=[0,1,1,1] #encryption level 0 byte at time, 1 half byte at time, 2 quarter byte at time, 3 bit at time (higher number better encryption but slower encrypting)(reseprents client 0-3)
- cryptseed=[123, #lan does not require enryption. client 0
- 1234567899876543210000000123, #use any, but high numbers recomended. client 1
- 1234567899876543210000000231, #use any, but high numbers recomended. client 2
- 1234567899876543210000000213] #use any, but high numbers recomended. client 3
- cryptpassword=["5341", #lan does not require enryption. client 0
- "0123456789abcdeffedcba98765432100123", #use any, long key recomended & amount of hex divisable by 2. client 1
- "0123456789abcdeffedcba98765432100231", #use any, long key recomended & amount of hex divisable by 2. client 2
- "0123456789abcdeffedcba98765432100213"] #use any, long key recomended & amount of hex divisable by 2. client 3
- #use this on python to get safe codes (next 3 lines)(you still have to check that it is divisable for 2 hex when mentioned)
- #import secrets
- #print(secrets.randbelow(1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000))
- #print(secrets.token_hex(60))
- #CLIENTMODE DEFAULT SETTINGS (example client 1)
- #allclientsbroadcast = False #don't send broadcast recived back, so we don't stuck on infinite loop
- #broadcastonlyactive = False #always send packets even if normally would be disconnected so we can re-etablish
- #displayfake = True #helps determine wheter connection has been disconnected
- #clientused=[0,1,2,3] #list all used client slots (client side server is client 1 and client 0 is client 1 in UDP REALAY SERVER list(tuple)
- #listen=(('192.168.100.20', 26000),b'\x08\x00\x27\xff\xff\x01', #local ip of the client connecting to UDP RELAY SERVER,sport of that user (client 1) guest os, that user (client 1) guest os mac
- # ('111.111.111.111',27000),b'\x08\x00\x27\xff\xff\x00', #UDP RELAY SERVER external ip, serverport setting of the UDP RELAY SERVER, client 0 server host guest os mac
- # ('111.111.111.111',27000),b'\x08\x00\x27\xff\xff\x02', #UDP RELAY SERVER external ip, serverport setting of the UDP RELAY SERVER, client 2 host guest os mac
- # ('111.111.111.111',27000),b'\x08\x00\x27\xff\xff\x03') #UDP RELAY SERVER external ip, serverport setting of the UDP RELAY SERVER, client 3 host guest os mac
- #encryptingon=[False,True,True,True] #is encrypting turned on (reseprents client 1,0,2,3) (use client 1 enc, except on first one)
- #cryptlvl=[0,1,1,1] #encryption level 0 byte at time, 1 half byte at time, 2 quarter byte at time, 3 bit at time (higher number better encryption but slower encrypting)(reseprents client 1,0,2,3) (use client 1 enc, except on first one)
- #cryptseed=[123, #lan does not require enryption. client 1
- # 1234567899876543210000000123, #use any, but high numbers recomended. client 0 (use client 1 enc)
- # 1234567899876543210000000123, #use any, but high numbers recomended. client 2 (use client 1 enc)
- # 1234567899876543210000000123] #use any, but high numbers recomended. client 3 (use client 1 enc)
- #cryptpassword=["5341", #lan does not require enryption. client 1
- # "0123456789abcdeffedcba98765432100123", #use any, long key recomended & amount of hex divisable by 2. client 0 (use client 1 enc)
- # "0123456789abcdeffedcba98765432100123", #use any, long key recomended & amount of hex divisable by 2. client 2 (use client 1 enc)
- # "0123456789abcdeffedcba98765432100123"] #use any, long key recomended & amount of hex divisable by 2. client 3 (use client 1 enc)
- #NO MORE SETTINGS TO CONFIGURE AFTER THIS LINE
- if len(cryptlvl) != len(cryptseed) or len(cryptseed) != len(cryptpassword) or len(cryptseed) != len(encryptingon):
- raise ValueError("Error:encryption keys/seeds not same length.")
- cryptlevel=[0]*len(cryptlvl)
- cryptmask=["0"]*len(cryptlvl)
- for i in range(0,len(cryptlvl)):
- cryptlevel[i]=2 ** cryptlvl[i] if cryptlvl[i] <= 3 else 8
- cryptmask[i]=math.floor(256**(1/2**(cryptlvl[i] if cryptlvl[i] <= 3 else 3)))-1
- macbroad=b'\xff\xff\xff\xff\xff\xff' #do not touch (broadcast mac address)
- clientamount=4 #does nothing (gets auto set by clientused)
- clienttime=[]
- logifile=open(logfilename + logfileext, 'a')
- prevpri=time.time() - 10.0
- def autoip():
- s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
- try:
- s.connect(('255.255.255.255', 65301))
- IP = s.getsockname()[0]
- except Exception:
- IP = '127.0.0.1'
- finally:
- s.close()
- print("auto get local ip : %s" % IP)
- return IP
- def listeshow():
- global prevpri
- while True:
- if prevpri + 2.5 < time.time():
- print ("[%03d] Waiting to receive message from client" % (math.floor(time.time())%1000) )
- return
- time.sleep(0.05)
- def quitdetect():
- infod=[False,False]
- while msvcrt.kbhit():
- if msvcrt.getch()==b'\x1b':
- infod[1]=True
- else:
- infod[0]=True
- if infod[1]:
- print("Quiting...")
- os.abort()
- elif infod[0]:
- print("Key press detected. Kill process with Escape")
- def dropfollow():
- global clienttime
- global clientused
- while True:
- for x in clientused:
- if clienttime[x*2] + droptimeout < time.time() and not clienttime[x*2+1]:
- print("[%03d] %s dropped from connection.%s" % (math.floor(time.time())%1000,listen[x*2],"fake" if not broadcastonlyactive else ""))
- clienttime[x*2+1]=True
- clienttime[x*2]=time.time()
- elif clienttime[x*2+1] and clienttime[x*2] + droppedremind < time.time():
- print("[%03d] %s still down...%s" % (math.floor(time.time())%1000,listen[x*2],"fake" if not broadcastonlyactive else ""))
- clienttime[x*2]=time.time()
- quitdetect()
- time.sleep(1.0)
- def mysendpacket(sock,data,target):
- try:
- return sock.sendto(data,target)
- except Exception as e:
- print(str(e))
- return -1
- def getpartbyte(mybytes,part,info):
- cryptlvl=info[0]
- cryptlevel=info[1]
- cryptmask=info[2]
- if cryptlvl == 0:
- return mybytes[part]
- return (mybytes[part//cryptlevel] >> ((8 // cryptlevel)*(part % cryptlevel))) & cryptmask
- def setpartbyte(mybytes,part,what,info):
- cryptlvl=info[0]
- cryptlevel=info[1]
- cryptmask=info[2]
- if cryptlvl == 0:
- mybytes[part]=what
- return
- drop=(8 // cryptlevel)*(part % cryptlevel)
- mask=255 - (cryptmask << drop)
- mybytes[part//cryptlevel]=mybytes[part//cryptlevel] & mask | what << drop
- def crypt(data,password,seed,encrypt,info):
- datalen=len(data)
- pdata=bytearray(data)
- passlen=len(password)
- random.seed(seed,2)
- if encrypt:
- curbyte=0
- while curbyte < datalen:
- pdata[curbyte]=(pdata[curbyte] + password[curbyte%passlen])%256
- curbyte+=1
- curbyte=0
- while curbyte < datalen*info[1]-1:
- swap=getpartbyte(pdata,curbyte,info)
- num=random.randrange(curbyte,datalen*info[1])
- setpartbyte(pdata,curbyte,getpartbyte(pdata,num,info),info)
- setpartbyte(pdata,num,swap,info)
- curbyte+=1
- else:
- randomnums=[0] * (datalen*info[1]-1)
- for i in range(0,datalen*info[1]-1):
- randomnums[i]=random.randrange(i,datalen*info[1])
- curbyte=datalen*info[1]-2
- while curbyte >= 0:
- num=randomnums[curbyte]
- swap=getpartbyte(pdata,num,info)
- setpartbyte(pdata,num,getpartbyte(pdata,curbyte,info),info)
- setpartbyte(pdata,curbyte,swap,info)
- curbyte-=1
- curbyte=0
- while curbyte < datalen:
- pdata[curbyte]=(pdata[curbyte] - password[curbyte%passlen])%256
- curbyte+=1
- return pdata
- def echo_server(port):
- global cryptpassword
- for x in range(0,len(cryptpassword)):
- cryptpassword[x]=bytearray.fromhex(cryptpassword[x])
- # Create a UDP socket
- sock = socket.socket(socket.AF_INET,
- socket.SOCK_DGRAM)
- # Bind the socket to the port
- server_address = (listen[0][0], port)
- global logifile
- global clienttime
- global clientused
- if exists(logfilename + logfileext):
- if os.path.getsize(logfilename + logfileext) == 0:
- pass
- else:
- if exists(logfilename + "9" + logfileext):
- os.remove(logfilename + "9" + logfileext)
- for x in range(8,0,-1):
- if exists((logfilename + "%s" + logfileext) % x):
- os.rename((logfilename + "%s" + logfileext) % x,(logfilename + "%s" + logfileext) % (x+1))
- logifile.close()
- os.rename(logfilename + logfileext,(logfilename + "1" + logfileext))
- logifile=open(logfilename + logfileext,"x")
- else:
- logifile=open(logfilename + logfileext,"x")
- tmp=[]
- for i in clientused:
- if i not in tmp and i < math.floor(len(listen)/2):
- tmp.append(i)
- print("Allowed %d %s client." % (i,listen[i*2]))
- else:
- print("Unlisted %d (max id %d) client. (if already allowed it's still listed)" % (i,math.floor(len(listen)/2)-1))
- clientused=tmp
- del tmp
- clientamount=len(clientused)
- if clientamount > len(encryptingon):
- raise ValueError("Error:Not enough encrypt states")
- for i in range(0,math.floor(len(listen)/2)):
- clienttime.append(time.time())
- clienttime.append(defaultstate)
- print ("Starting UDP RELAY SERVER on %s port %s" % server_address)
- if clientamount < 1:
- print("QUITING DUE NO CLIENTS ALLOWED")
- return
- sock.bind(server_address)
- #licount=0 #this line is related to notepad++ python console
- strtoprint=""
- global prevpri
- global allclientsbroadcast
- while True:
- try:
- dispwaiting
- except NameError:
- dispwaiting=threading.Thread(target=listeshow)
- dispwaiting.start()
- if broadcastonlyactive or displayfake:
- dispdrop=threading.Thread(target=dropfollow)
- dispdrop.start()
- else:
- if broadcastonlyactive or displayfake:
- if not dispdrop.is_alive():
- dispdrop=threading.Thread(target=dropfollow)
- dispdrop.start()
- if not dispwaiting.is_alive():
- dispwaiting=threading.Thread(target=listeshow)
- dispwaiting.start()
- ctest=[0,0,0,0]
- try:
- data, address = sock.recvfrom(data_payload)
- tmp=-1
- for x in clientused:
- if listen[x*2][0] == address[0]:
- ctest[0]=2
- if listen[x*2][1] == address[1]:
- ctest[1]=2
- if listen[x*2][0] == address[0] and listen[x*2][1] == address[1]:
- ctest[0]=2
- ctest[1]=2
- tmp=x
- break
- if tmp != -1:
- if encryptingon[tmp]:
- data=crypt(data,cryptpassword[tmp],cryptseed[tmp],False,(cryptlvl[tmp],cryptlevel[tmp],cryptmask[tmp]))
- except Exception as e:
- print(str(e))
- strtoprint="%s%s\n" % (strtoprint,("[%03d] received %s bytes from %s" % (math.floor(time.time())%1000,len(data), address)))
- #print ("Data: %s" %data)
- cindex=-1
- deta=data
- for x in clientused:
- if data[6:12] == listen[x*2+1]:
- ctest[2]=2
- if data and listen[x*2][0] == address[0] and listen[x*2][1] == address[1] and data[6:12] == listen[x*2+1]:
- ctest[0]=1
- ctest[1]=1
- ctest[2]=1
- clienttime[x*2]=time.time()
- clienttime[x*2+1]=False
- cindex=x
- break
- if cindex != -1:
- if data[:6] == macbroad:
- ctest[3]=1
- if allclientsbroadcast or cindex==0:
- for x in clientused:
- if x != cindex and (not clienttime[x*2+1] or not broadcastonlyactive):
- if encryptingon[x]:
- deta=crypt(data,cryptpassword[x],cryptseed[x],True,(cryptlvl[x],cryptlevel[x],cryptmask[x]))
- else:
- deta=data
- sent = mysendpacket(sock,deta,listen[x*2])
- strtoprint="%s%s\n" % (strtoprint,("[%03d] broadcast %s bytes to %s" % (math.floor(time.time())%1000,sent, listen[x*2])))
- else:
- if encryptingon[0]:
- deta=crypt(data,cryptpassword[0],cryptseed[0],True,(cryptlvl[0],cryptlevel[0],cryptmask[0]))
- else:
- deta=data
- sent = mysendpacket(sock,deta,listen[0*2])
- strtoprint="%s%s\n" % (strtoprint,("[%03d] handled localbroadcast %s bytes to %s" % (math.floor(time.time())%1000,len(deta), listen[0*2])))
- else:
- for x in clientused:
- if data[:6] == listen[x*2+1]:
- ctest[3]=2
- if x != cindex and (not clienttime[x*2+1] or not broadcastonlyactive):
- if encryptingon[x]:
- deta=crypt(data,cryptpassword[x],cryptseed[x],True,(cryptlvl[x],cryptlevel[x],cryptmask[x]))
- else:
- deta=data
- ctest[3]=1
- sent = mysendpacket(sock,deta,listen[x*2])
- strtoprint="%s%s\n" % (strtoprint,("[%03d] send %s bytes to %s %s" % (math.floor(time.time())%1000,sent, listen[x*2],data[:6].hex())))
- break
- if not (ctest[0]==1 and ctest[1]==1 and ctest[2]==1 and ctest[3]==1):
- if cindex == -1:
- tmpstr=" %15s %05i %s %s %s\n" % (address[0],address[1],deta[:6].hex(),deta[6:12].hex(),deta[12:].hex())
- else:
- tmpstr=" %15s %05i %s %s %s\n" % (listen[cindex*2][0],listen[cindex*2][1],deta[:6].hex(),deta[6:12].hex(),deta[12:].hex())
- tmpbyt=bytearray(tmpstr,"ascii") #33 -> "!" 63 -> "?" 32 -> " "
- tmpbyt[0]=33 if (ctest[0] == 0) else (63 if ctest[0] == 2 else 32)
- tmpbyt[16]=33 if (ctest[0] == 0) else (63 if ctest[0] == 2 else 32)
- tmpbyt[18]=33 if (ctest[1] == 0) else (63 if ctest[1] == 2 else 32)
- tmpbyt[24]=33 if (ctest[1] == 0) else (63 if ctest[1] == 2 else 32)
- tmpbyt[26]=33 if (ctest[3] == 0) else (63 if ctest[3] == 2 else 32)
- tmpbyt[39]=33 if (ctest[3] == 0) else (63 if ctest[3] == 2 else 32)
- tmpbyt[41]=33 if (ctest[2] == 0) else (63 if ctest[2] == 2 else 32)
- tmpbyt[54]=33 if (ctest[2] == 0) else (63 if ctest[2] == 2 else 32)
- tmpstr=tmpbyt.decode("ascii")
- try:
- logifile.write(tmpstr)
- logifile.close()
- logifile=open(logfilename + logfileext, 'a')
- except Exception as e:
- print("Logfile failure.")
- print(str(e))
- strtoprint="%s\n" % strtoprint
- if (prevpri + 0.3 < time.time()):
- prevpri=time.time()
- print(strtoprint,end='')
- strtoprint=""
- # licount+=1 #these 5 lines are related to notepad++ python console
- # if licount > 500:
- # licount=0
- # if console.editor.getCurrentPos() > 50000:
- # console.clear()
- #sys.stderr = console # remove first "#" to make standard log visible to notepad++ python console
- #sys.stdout = console # remove first "#" to make standard log visible to notepad++ python console
- try:
- echo_server(serverport)
- finally:
- pass
- # logifile.close()
- # if os.path.getsize(logfilename + logfileext) == 0:
- # os.remove(logfilename + logfileext)
Add Comment
Please, Sign In to add comment