#!/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())