{% from "partials/_macros.html" import card_header %} {% set verdict_cls = { 'malicious': 'bg-red-900/40 text-red-300 border border-red-900/60', 'suspicious': 'bg-amber-900/40 text-amber-300 border border-amber-900/60', 'unknown': 'bg-slate-700/40 text-slate-300 border border-slate-600', 'benign': 'bg-emerald-900/30 text-emerald-300 border border-emerald-900/50', } %}
{{ card_header("network flows — tcpdump aggregator (by destination)") }} {% if flows.rows %} {# ----- aggregate summary: sum + counts ----- #}
{% set s = flows.summary %}
{{ s.destinations }}
destinations
{{ s.flows }}
flows
{% set tv = s.bytes | human_bytes %}
{{ tv if tv else "{:,}".format(s.packets) }}
{{ "volume" if tv else "packets" }}
{{ s.malicious }}
malicious
{{ s.suspicious }}
suspicious
{# ----- one row per destination IP (grouped / summed) ----- #} {% for f in flows.rows %} {% endfor %}
verdict destination process interface proto ports traffic why
{% if f.verdict %} {{ f.verdict }}{% if f.confidence is not none %} {{ "%.0f"|format(f.confidence * 100) }}% {% endif %} {% else %} {% endif %}
{# IP — the anchor #}
{{ f.dst_ip }}
{# resolved hostname / domain #} {% if f.hostname %}
{{ f.hostname }}
{% endif %} {# geolocation — city / region / country with flag #} {% if f.geo %} {% set place = [f.geo.city, f.geo.region, f.geo.country] | select | join(", ") %} {% if place %}
{%- set flag = f.geo.cc | flag_emoji -%} {%- if flag %}{{ flag }}{% endif -%} {{ place }}
{% endif %} {# network owner — ASN / org #} {% if f.geo.org or f.geo.asn %}
{%- if f.geo.asn %}AS{{ f.geo.asn }}{% if f.geo.org %} · {% endif %}{% endif -%} {{ f.geo.org or "" }}
{% endif %} {% endif %}
{{ f.process }} {% if f.iface and f.iface != '—' %} {{ f.iface }} {% else %} {% endif %}
{% for p in f.proto %} {{ p }} {% endfor %}
{% for p in f.ports[:12] %} {{ p }} {% endfor %} {% if f.ports | length > 12 %} +{{ f.ports | length - 12 }} {% endif %}
{% set vol = f.bytes | human_bytes %} {% if vol %}
{{ vol }}
{{ "{:,}".format(f.packets) }} pkts · {{ f.flows }} flow{{ '' if f.flows == 1 else 's' }}
{% else %}
{{ "{:,}".format(f.packets) }} pkts
{{ f.flows }} flow{{ '' if f.flows == 1 else 's' }}
{% endif %}
{{ f.reasoning }}
{% else %}
no network flows yet — the tcpdump aggregator needs root (run the monitor with sudo) and a capture window to elapse.
{% endif %}