Files
firegex-traffic-viewer/docs/TRAFFIC_VIEWER.md
Your Name 9af3023a37 dsa
2025-12-08 01:41:08 +03:00

3.9 KiB

Traffic Viewer - JSON Event Format

The traffic viewer is now fully integrated. To enable structured event display, the NFProxy C++ binary (backend/binsrc/nfproxy.cpp) should emit JSON lines to stdout with the following format:

JSON Event Schema

{
  "ts": 1701964234567,
  "direction": "in",
  "src_ip": "192.168.1.100",
  "src_port": 54321,
  "dst_ip": "10.0.0.5",
  "dst_port": 443,
  "proto": "tcp",
  "size": 1420,
  "verdict": "accept",
  "filter": "filter_sanitize",
  "sample_hex": "474554202f20485454502f312e310d0a486f73743a206578616d706c652e636f6d..."
}

Fields

  • ts (required): Unix timestamp in milliseconds
  • direction: "in" (client→server) or "out" (server→client)
  • src_ip, dst_ip: Source and destination IP addresses
  • src_port, dst_port: Source and destination ports
  • proto: Protocol name (e.g., "tcp", "udp")
  • size: Packet/payload size in bytes
  • verdict (required): "accept", "drop", "reject", or "edited"
  • filter: Name of the Python filter that processed this packet
  • sample_hex: Hex-encoded sample of payload (first 64-128 bytes recommended)

Implementation Notes

  1. Backward Compatibility: The parser in firegex.py::_stream_handler only processes lines starting with {. Non-JSON output (logs, ACK messages) continues to work as before.

  2. Performance: Emit JSON only when needed. Consider an env flag:

    bool emit_traffic_json = getenv("FIREGEX_TRAFFIC_JSON") != nullptr;
    if (emit_traffic_json) {
        std::cout << json_event << std::endl;
    }
    
  3. Sample Code (C++ with nlohmann/json or similar):

    #include <nlohmann/json.hpp>
    using json = nlohmann::json;
    
    void emit_traffic_event(const PacketInfo& pkt, const char* verdict, const char* filter_name) {
        json event = {
            {"ts", current_timestamp_ms()},
            {"direction", pkt.is_inbound ? "in" : "out"},
            {"src_ip", pkt.src_addr},
            {"src_port", pkt.src_port},
            {"dst_ip", pkt.dst_addr},
            {"dst_port", pkt.dst_port},
            {"proto", pkt.protocol},
            {"size", pkt.payload_len},
            {"verdict", verdict},
            {"filter", filter_name},
            {"sample_hex", hex_encode(pkt.payload, std::min(64, pkt.payload_len))}
        };
        std::cout << event.dump() << std::endl;
    }
    

Testing Without Binary Changes

The viewer works immediately—it will display "No traffic events yet" until the binary is updated. You can manually test the Socket.IO flow by emitting mock events from Python:

# In backend shell or script
import asyncio
import json
from utils import socketio

async def emit_test_event():
    event = {
        "ts": int(time.time() * 1000),
        "direction": "in",
        "src_ip": "192.168.1.50",
        "src_port": 12345,
        "dst_ip": "10.0.0.1",
        "dst_port": 80,
        "proto": "tcp",
        "size": 512,
        "verdict": "accept",
        "filter": "test_filter"
    }
    await socketio.emit("nfproxy-traffic-YOUR_SERVICE_ID", event, room="nfproxy-traffic-YOUR_SERVICE_ID")

Current Features

Backend:

  • Ring buffer stores last 500 events per service
  • REST endpoint: GET /api/nfproxy/services/{id}/traffic?limit=500
  • REST endpoint: POST /api/nfproxy/services/{id}/traffic/clear
  • Socket.IO channels: nfproxy-traffic-{service_id} for live events, nfproxy-traffic-history on join

Frontend:

  • Live table view at /nfproxy/{service_id}/traffic
  • Client-side text filter (searches IP, verdict, filter name, proto)
  • Click row to view full event details + hex payload
  • Auto-scroll, clear history button
  • Accessible via new button (double-arrow icon) in ServiceDetails page

Next Steps

  1. Update backend/binsrc/nfproxy.cpp to emit JSON events as shown above
  2. Rebuild the C++ binary
  3. Start a service and generate traffic—viewer will populate in real-time
  4. Optionally add more filters (by verdict, time range) or export to PCAP