nickdodd25

Query flood proxy for samp

Mar 29th, 2019
536
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.13 KB | None | 0 0
  1. #!/usr/bin/env python3
  2.  
  3.  
  4. #
  5. #    iptables -t nat -A PREROUTING -p udp --dport 7777 -m string --algo bm --string 'SAMP' -j REDIRECT --to-port 7778
  6. #    make sure ports above match ports below
  7. #    
  8. #    Basicly all query packets get directed to this script, and sync packets are left untouched
  9. #
  10.  
  11.  
  12. import socketserver
  13. import socket
  14. import threading
  15. import time
  16. import struct
  17.  
  18.  
  19.  
  20. SERVER_PORT = 7777
  21. PROXY_PORT = 7778
  22. SAMP_SERVER_ADDRESS = "YOUR PUBLIC SERVER IP" #Public ip
  23.  
  24.  
  25.  
  26. SAMP_SERVER_LOCALHOST = "127.0.0.1" #assumes you run this on the same server as samp serber
  27. SAMP_SERVER_ADDRESS_BYTES = socket.inet_aton(SAMP_SERVER_ADDRESS)
  28. SAMP_SERVER_LOCAL_ADDRESS_BYTES = socket.inet_aton(SAMP_SERVER_LOCALHOST)
  29.  
  30. info = " "
  31. rules = " "
  32. clients = " "
  33. detail = " "
  34.  
  35.  
  36. class UDPProxy:
  37.   def __init__(self, bind_address, target_address, internal_host = "127.0.0.1", timeout = 0.1): #ulimit?
  38.     self.target_address = target_address
  39.     self.timeout = timeout
  40.  
  41.     self.server = socketserver.UDPServer(bind_address, create_handler(self.handle_external_packet))
  42.  
  43.  
  44.   def querythread(self):
  45.  
  46.     global info
  47.     global rules
  48.     global clients
  49.     global detail
  50.  
  51.     socket.setdefaulttimeout(1)
  52.     self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  53.     while True:
  54.      
  55.       if self.ping():
  56.  
  57.         packet = self.assemblePacket("i")
  58.         self.sock.sendto(packet.encode(), (SAMP_SERVER_LOCALHOST, SERVER_PORT))
  59.         info = self.sock.recv(1024)[11:]
  60.  
  61.  
  62.         packet = self.assemblePacket("r")
  63.         self.sock.sendto(packet.encode(), (SAMP_SERVER_LOCALHOST, SERVER_PORT))
  64.         rules = self.sock.recv(1024)[11:]
  65.  
  66.  
  67.         packet = self.assemblePacket("d")
  68.         self.sock.sendto(packet.encode(), (SAMP_SERVER_LOCALHOST, SERVER_PORT))
  69.         detail = self.sock.recv(1024)[11:]
  70.  
  71.         packet = self.assemblePacket("c")
  72.         self.sock.sendto(packet.encode(), (SAMP_SERVER_LOCALHOST, SERVER_PORT))
  73.         clients = self.sock.recv(1024)[11:]
  74.  
  75.       else:
  76.         print("Server unable to be reached")
  77.       time.sleep(2)
  78.  
  79.   def ping(self):
  80.  
  81.     pack = self.assemblePacket("p0101")
  82.     self.sock.sendto(pack.encode(), (SAMP_SERVER_LOCALHOST, SERVER_PORT))
  83.     try:
  84.       reply = self.sock.recv(1024)[10:]
  85.       if reply == b'p0101':
  86.         return True
  87.       else:
  88.         return False
  89.     except socket.timeout:
  90.       return False
  91.      
  92.   def assemblePacket(self, type):
  93.     ipSplit = str.split(SAMP_SERVER_LOCALHOST, '.')
  94.  
  95.     packet = 'SAMP'
  96.     packet += chr(int(ipSplit[0]))
  97.     packet += chr(int(ipSplit[1]))
  98.     packet += chr(int(ipSplit[2]))
  99.     packet += chr(int(ipSplit[3]))
  100.     packet += chr(SERVER_PORT & 0xFF)
  101.     packet += chr(SERVER_PORT >> 8 & 0xFF)
  102.     packet += type
  103.  
  104.     return packet
  105.  
  106.   def start(self):
  107.     q = threading.Thread(target=self.querythread)
  108.     q.daemon = True
  109.     q.start()
  110.     self.server.serve_forever()
  111.  
  112.  
  113.   def stop(self):
  114.     self.server.shutdown()
  115.  
  116.  
  117.  
  118.   def handle_external_packet(self, handler):
  119.     (payload, socket) = handler.request
  120.     client_address = handler.client_address
  121.  
  122.     if payload[0:4] != b'SAMP': #could be sync packets, no need to go further
  123.       #print("%a",payload)
  124.       return False
  125.  
  126.     if len(payload) <4: #because the packet size varies - can't really determine the defaults here.
  127.       return False
  128.  
  129.     if payload[4:8] != SAMP_SERVER_ADDRESS_BYTES:
  130.       print("Unknown host %r %r" % (socket.inet_ntoa(payload[4:8]), SAMP_SERVER_ADDRESS))
  131.       return False
  132.  
  133.     if payload[10] not in b'pirdc': #opcodes defined here: https://wiki.sa-mp.com/wiki/Query/Request#Opcodes
  134.       print("Wrong opcode %r" % (payload[10]))
  135.       return False
  136.  
  137.  
  138.  
  139.  
  140.  
  141.     if payload[10] in b'p': #Ping packets are just sent back to the client
  142.       client_address = handler.client_address
  143.       self.server.socket.sendto(payload, client_address)
  144.       return True
  145.  
  146.     elif payload[10] in b'i':
  147.  
  148.       client_address = handler.client_address
  149.       self.server.socket.sendto(payload+info, client_address)
  150.       return True
  151.      
  152.  
  153.     elif payload[10] in b'r':
  154.       #print(rules)
  155.       client_address = handler.client_address
  156.       self.server.socket.sendto(payload+rules, client_address)
  157.       return True
  158.      
  159.  
  160.     elif payload[10] in b'd':
  161.       #print(detail)
  162.       client_address = handler.client_address
  163.       self.server.socket.sendto(payload+detail, client_address)
  164.       return True
  165.      
  166.  
  167.     elif payload[10] in b'c':
  168.       #print(clients)
  169.       client_address = handler.client_address
  170.       self.server.socket.sendto(payload+clients, client_address)
  171.       return True
  172.     return
  173.  
  174. def create_handler(func):
  175.   class Handler(socketserver.BaseRequestHandler):
  176.     def handle(self):
  177.       try:
  178.         func(self)
  179.       except Exception as e:
  180.         print("An error occured: %s" % (e,))
  181.   return Handler
  182.  
  183. if __name__ == '__main__':
  184.   print("Listening on port", PROXY_PORT, "for server",SAMP_SERVER_ADDRESS,"on port",SERVER_PORT)
  185.   bind_address = ("0.0.0.0", PROXY_PORT)
  186.   target_address = ("127.0.0.1", SERVER_PORT)
  187.   proxy = UDPProxy(bind_address, target_address)
  188.   proxy.start()
  189.   # UDPProxy.start(proxy)
Advertisement
Add Comment
Please, Sign In to add comment