7827cda224
- logger.py: note why log path uses abspath(__file__) instead of a relative path - token.py: note why [7:] slice is safe (startswith already verified) - ipcalc.py: explain /32 single-host and /31 RFC-3021 point-to-point special cases; explain why (~netmask) must be masked with 0xFFFFFFFF (Python ~int returns a negative arbitrary-precision value, not a 32-bit unsigned integer) - notes.py: document the module-level _table_ready flag lifetime; explain why tzinfo is stripped before passing datetime to mysql-connector - admin.py: document the module-level _tables_initialized flag lifetime Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
65 lines
2.4 KiB
Python
65 lines
2.4 KiB
Python
from flask import Blueprint, request, jsonify
|
|
import ipaddress
|
|
from util.logger import logger
|
|
from auth.token import verify_token
|
|
|
|
ipcalc_blueprint = Blueprint('ipcalc_tool', __name__)
|
|
|
|
|
|
@ipcalc_blueprint.route('/api/ip/calculate', methods=['POST'])
|
|
def ip_calculate():
|
|
user = verify_token()
|
|
if not user:
|
|
return jsonify({"message": "Nicht autorisiert"}), 401
|
|
try:
|
|
data = request.get_json(silent=True) or {}
|
|
cidr = data.get("cidr", "").strip()
|
|
|
|
try:
|
|
network = ipaddress.IPv4Network(cidr, strict=False)
|
|
except ValueError as e:
|
|
return jsonify({"message": f"Ungültige CIDR-Notation: {e}"}), 400
|
|
|
|
prefix = network.prefixlen
|
|
net_int = int(network.network_address)
|
|
bcast_int = int(network.broadcast_address)
|
|
|
|
# Avoid materialising millions of host objects for large networks.
|
|
if prefix == 32:
|
|
# Single-host route: the address is both network and host.
|
|
total_hosts = 1
|
|
first_host = str(network.network_address)
|
|
last_host = str(network.network_address)
|
|
elif prefix == 31:
|
|
# RFC 3021 point-to-point: both addresses are usable hosts,
|
|
# there is no dedicated network or broadcast address.
|
|
total_hosts = 2
|
|
first_host = str(network.network_address)
|
|
last_host = str(network.broadcast_address)
|
|
else:
|
|
total_hosts = network.num_addresses - 2
|
|
first_host = str(ipaddress.IPv4Address(net_int + 1))
|
|
last_host = str(ipaddress.IPv4Address(bcast_int - 1))
|
|
|
|
netmask_int = int(network.netmask)
|
|
# Python's ~ on an int yields a negative arbitrary-precision value;
|
|
# mask to 32 bits to get the correct unsigned wildcard address.
|
|
wildcard = str(ipaddress.IPv4Address((~netmask_int) & 0xFFFFFFFF))
|
|
ip_class = "Privat" if network.is_private else "Öffentlich"
|
|
|
|
return jsonify({
|
|
"network": str(network.network_address),
|
|
"broadcast": str(network.broadcast_address),
|
|
"netmask": str(network.netmask),
|
|
"wildcard": wildcard,
|
|
"first_host": first_host,
|
|
"last_host": last_host,
|
|
"total_hosts": total_hosts,
|
|
"prefix_length": prefix,
|
|
"ip_class": ip_class,
|
|
})
|
|
|
|
except Exception as e:
|
|
logger.error(f"Fehler ipcalc: {e}")
|
|
return jsonify({"message": "Fehler bei der Berechnung"}), 500
|