from flask import Flask, request, redirect, url_for import os import sys import ipaddress import random import subprocess app = Flask(__name__) # where player are stored DB_DIR= "./db" PLAYER_DIR = os.path.join(DB_DIR, "players") NET_DIR = os.path.join(DB_DIR, "networks") REGULAR_PAGE = """
You are player: {player}
Afterwards register your network and then make your random ip reachable.
You are: {player}
Your registered random IPv6 address in your network is {random_ip}. The result of the check is: {returncode} (0 mean s reachable, everything else is an error) and the output of the ping command is:
{output}(we should really convert to jinja2 now) """ NO_NETWORK = """Sorry, this is not an IPv6 network""" NO_SLASH_64 = """Sorry, this is not a /64 IPv6 network""" NO_USER = """Sorry, you are not a user, you cannot check your IPv6 address. Register first""" def player_exists_at_address(address): fname = os.path.join(PLAYER_DIR, address) exists = False if os.path.exists(fname): exists = True return exists def addresses(): address_list = [] if os.path.isdir(PLAYER_DIR): address_list = os.listdir(PLAYER_DIR) return address_list def networks(): network_list = [] if os.path.isdir(NET_DIR): network_list = os.listdir(NET_DIR) return network_list def get_player_from_network(network): fname = os.path.join(NET_DIR, network, "address") with open(fname,"r") as fd: address = fd.readlines()[0].strip() return address def get_player_network(address): network = None for net in networks(): fname = os.path.join(NET_DIR, net, "address") with open(fname,"r") as fd: net_address = fd.readlines()[0].strip() if net_address == address: network = net return network def get_player_ip(address): random_ip = None network = get_player_network(address) if not network: return None fname = os.path.join(NET_DIR, network, "random_ip") if os.path.exists(fname): with open(fname,"r") as fd: random_ip = fd.readlines()[0].strip() return random_ip def get_player_name(address): fname = os.path.join(PLAYER_DIR, address) with open(fname, "r") as fd: name = fd.readlines() return name[0].strip() def save_player(name, address): fname = os.path.join(PLAYER_DIR, address) with open(fname, "w+") as fd: fd.write("{}\n".format(name)) def is_v6_network(network): is_network = True try: net = ipaddress.IPv6Network(network) except: is_network = False return is_network def is_v6_slash_64(network): is_64 = True try: net = ipaddress.IPv6Network(network) print("{} {}".format(net, network)) if not net.prefixlen == 64: is_64 = False except: is_64 = False return is_64 def get_random_ip(network): net = ipaddress.IPv6Network(network) addr_offset = random.randrange(2**64) addr = net[0] + addr_offset return addr def save_network(address, network): if not is_v6_network(network): return NO_NETWORK if not is_v6_slash_64(network): return NO_SLASH_64 if not os.path.isdir(NET_DIR): os.mkdir(NET_DIR) # get filesystem friendly name net_name = str(ipaddress.IPv6Network(network)[0]) dirname = os.path.join(NET_DIR, net_name) if not os.path.isdir(dirname): os.mkdir(dirname) fname = os.path.join(dirname, "address") with open(fname, "w+") as fd: fd.write("{}\n".format(address)) fname = os.path.join(dirname, "network") with open(fname, "w+") as fd: fd.write("{}\n".format(network)) random_ip = get_random_ip(network) print("ip={}".format(random_ip)) fname = os.path.join(dirname, "random_ip") with open(fname, "w+") as fd: fd.write("{}\n".format(random_ip)) return redirect(url_for('net')) def identify_user(address): """ Find user by connecting IPv6 address """ player = None # found the player if player_exists_at_address(address): return address # check whether player is connecting from a registered network v6_addr = ipaddress.IPv6Address(address) for net in networks(): v6_net = ipaddress.IPv6Network("{}/64".format(net)) if v6_addr in v6_net: player = get_player_from_network(net) break return player @app.route('/check_addr', methods=['GET']) def check_addr(): address = request.remote_addr player = identify_user(address) if not player: return NO_USER random_ip = get_player_ip(player) s = subprocess.run(["ping", "-c1", random_ip], capture_output=True) return ADDR_CHECK_PAGE.format(player=player, random_ip=random_ip, returncode=s.returncode, output=s.stdout.decode("utf-8")) @app.route('/net', methods=['GET', 'POST' ]) def net(): if request.method == 'GET': return NET_PAGE else: network = request.form['network'] address = request.remote_addr return save_network(address, network) @app.route('/', methods=['GET', 'POST' ]) def main(): address = request.remote_addr if request.method == 'GET': html = [] player = identify_user(address) for address in addresses(): name = get_player_name(address) network = get_player_network(address) random_ip = get_player_ip(address) html.append("