219 lines
7.3 KiB
Python
219 lines
7.3 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Script di test per verificare se il server SFP sta inviando pacchetti
|
|
e per analizzare il contenuto dei messaggi ricevuti.
|
|
"""
|
|
|
|
import socket
|
|
import time
|
|
import sys
|
|
import ctypes
|
|
from datetime import datetime
|
|
|
|
|
|
# Struttura SFP Header (32 bytes)
|
|
class SFPHeader(ctypes.Structure):
|
|
_pack_ = 1
|
|
_fields_ = [
|
|
("SFP_MARKER", ctypes.c_uint8),
|
|
("SFP_DIRECTION", ctypes.c_uint8),
|
|
("SFP_PROT_VER", ctypes.c_uint8),
|
|
("SFP_PT_SPARE", ctypes.c_uint8),
|
|
("SFP_TAG", ctypes.c_uint8),
|
|
("SFP_SRC", ctypes.c_uint8),
|
|
("SFP_FLOW", ctypes.c_uint8),
|
|
("SFP_TID", ctypes.c_uint8),
|
|
("SFP_FLAGS", ctypes.c_uint8),
|
|
("SFP_WIN", ctypes.c_uint8),
|
|
("SFP_ERR", ctypes.c_uint8),
|
|
("SFP_ERR_INFO", ctypes.c_uint8),
|
|
("SFP_TOTFRGAS", ctypes.c_uint16),
|
|
("SFP_FRAG", ctypes.c_uint16),
|
|
("SFP_RECTYPE", ctypes.c_uint8),
|
|
("SFP_RECSPARE", ctypes.c_uint8),
|
|
("SFP_PLDAP", ctypes.c_uint8),
|
|
("SFP_PLEXT", ctypes.c_uint8),
|
|
("SFP_RECCOUNTER", ctypes.c_uint16),
|
|
("SFP_PLSIZE", ctypes.c_uint16),
|
|
("SFP_TOTSIZE", ctypes.c_uint32),
|
|
("SFP_PLOFFSET", ctypes.c_uint32),
|
|
]
|
|
|
|
|
|
# DataTag (8 bytes)
|
|
class DataTag(ctypes.Structure):
|
|
_pack_ = 1
|
|
_fields_ = [
|
|
("ID", ctypes.c_uint8 * 2),
|
|
("VALID", ctypes.c_uint8),
|
|
("VERSION", ctypes.c_uint8),
|
|
("SIZE", ctypes.c_uint32),
|
|
]
|
|
|
|
|
|
def main():
|
|
# Configurazione
|
|
LOCAL_IP = "0.0.0.0"
|
|
LOCAL_PORT = 60012
|
|
SERVER_IP = "127.0.0.1"
|
|
SERVER_PORT = 60013
|
|
|
|
print("=" * 70)
|
|
print("TEST SERVER SFP - Verifica ricezione pacchetti")
|
|
print("=" * 70)
|
|
print(f"Locale: {LOCAL_IP}:{LOCAL_PORT}")
|
|
print(f"Server: {SERVER_IP}:{SERVER_PORT}")
|
|
print("=" * 70)
|
|
|
|
# Crea socket UDP
|
|
try:
|
|
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
|
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
|
|
|
# Aumenta il buffer di ricezione
|
|
sock.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 8388608)
|
|
|
|
sock.bind((LOCAL_IP, LOCAL_PORT))
|
|
sock.settimeout(5.0) # Timeout di 5 secondi
|
|
|
|
print(f"[OK] Socket creato e bound su {LOCAL_IP}:{LOCAL_PORT}")
|
|
print(
|
|
f"[INFO] Buffer size: {sock.getsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF)} bytes"
|
|
)
|
|
print()
|
|
|
|
except Exception as e:
|
|
print(f"[ERROR] Impossibile creare socket: {e}")
|
|
return 1
|
|
|
|
print("In ascolto per pacchetti dal server...")
|
|
print("(Premi Ctrl+C per terminare)")
|
|
print()
|
|
|
|
packet_count = 0
|
|
start_time = time.time()
|
|
last_report_time = start_time
|
|
flow_stats = {}
|
|
|
|
try:
|
|
while True:
|
|
try:
|
|
data, addr = sock.recvfrom(65535)
|
|
packet_count += 1
|
|
current_time = time.time()
|
|
|
|
# Analizza l'header SFP
|
|
if len(data) < 32:
|
|
print(f"[WARN] Pacchetto troppo corto: {len(data)} bytes da {addr}")
|
|
continue
|
|
|
|
try:
|
|
header = SFPHeader.from_buffer_copy(data)
|
|
flow_char = (
|
|
chr(header.SFP_FLOW)
|
|
if 32 <= header.SFP_FLOW <= 126
|
|
else f"0x{header.SFP_FLOW:02X}"
|
|
)
|
|
direction = (
|
|
chr(header.SFP_DIRECTION)
|
|
if 32 <= header.SFP_DIRECTION <= 126
|
|
else f"0x{header.SFP_DIRECTION:02X}"
|
|
)
|
|
|
|
# Aggiorna statistiche per flow
|
|
if flow_char not in flow_stats:
|
|
flow_stats[flow_char] = 0
|
|
flow_stats[flow_char] += 1
|
|
|
|
# Timestamp leggibile
|
|
ts = datetime.now().strftime("%H:%M:%S.%f")[:-3]
|
|
|
|
# Analizza il payload (primi bytes dopo l'header)
|
|
payload = data[32:]
|
|
tag_info = ""
|
|
if len(payload) >= 8:
|
|
try:
|
|
tag = DataTag.from_buffer_copy(payload)
|
|
tag_str = (
|
|
f"{chr(tag.ID[0]) if 32 <= tag.ID[0] <= 126 else tag.ID[0]:02X}"
|
|
f"{chr(tag.ID[1]) if 32 <= tag.ID[1] <= 126 else tag.ID[1]:02X}"
|
|
)
|
|
tag_info = f" | Tag: {tag_str} (valid={tag.VALID}, size={tag.SIZE})"
|
|
except:
|
|
pass
|
|
|
|
# Mostra preview dei primi bytes del payload
|
|
preview = (
|
|
payload[:16].hex() if len(payload) >= 16 else payload.hex()
|
|
)
|
|
|
|
print(
|
|
f"[{ts}] Pkt #{packet_count:04d} | From: {addr[0]}:{addr[1]} | "
|
|
f"Flow: {flow_char} | Dir: {direction} | TID: {header.SFP_TID:03d} | "
|
|
f"Size: {len(data):5d} bytes | Payload: {header.SFP_PLSIZE:5d} bytes{tag_info}"
|
|
)
|
|
|
|
if packet_count <= 3:
|
|
print(f" Payload preview: {preview}")
|
|
print()
|
|
|
|
except Exception as e:
|
|
print(f"[ERROR] Impossibile parsare header: {e}")
|
|
print(f" Raw bytes (primi 32): {data[:32].hex()}")
|
|
|
|
# Report periodico ogni 5 secondi
|
|
if current_time - last_report_time >= 5.0:
|
|
elapsed = current_time - start_time
|
|
rate = packet_count / elapsed if elapsed > 0 else 0
|
|
print()
|
|
print("-" * 70)
|
|
print(
|
|
f"[STATS] Tempo: {elapsed:.1f}s | Pacchetti: {packet_count} | "
|
|
f"Rate: {rate:.1f} pkt/s"
|
|
)
|
|
print(f"[STATS] Distribuzione per Flow: {flow_stats}")
|
|
print("-" * 70)
|
|
print()
|
|
last_report_time = current_time
|
|
|
|
except socket.timeout:
|
|
print(f"[WARN] Nessun pacchetto ricevuto negli ultimi 5 secondi")
|
|
print(
|
|
f" Verifica che il server sia in esecuzione su {SERVER_IP}:{SERVER_PORT}"
|
|
)
|
|
print()
|
|
|
|
except KeyboardInterrupt:
|
|
print()
|
|
print("=" * 70)
|
|
print("Test terminato dall'utente")
|
|
|
|
finally:
|
|
sock.close()
|
|
elapsed = time.time() - start_time
|
|
rate = packet_count / elapsed if elapsed > 0 else 0
|
|
|
|
print("=" * 70)
|
|
print("STATISTICHE FINALI:")
|
|
print(f" Durata: {elapsed:.1f} secondi")
|
|
print(f" Pacchetti ricevuti: {packet_count}")
|
|
print(f" Rate medio: {rate:.1f} pkt/s")
|
|
print(f" Distribuzione Flow: {flow_stats}")
|
|
print("=" * 70)
|
|
|
|
if packet_count == 0:
|
|
print()
|
|
print("[ATTENZIONE] Nessun pacchetto ricevuto!")
|
|
print("Possibili cause:")
|
|
print(" 1. Il server non è in esecuzione")
|
|
print(" 2. Il server non sta trasmettendo sulla porta corretta")
|
|
print(" 3. Firewall sta bloccando i pacchetti")
|
|
print(" 4. Problema di network/routing")
|
|
return 1
|
|
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|