{{ title }}
Generated: {{ generated }}
Total hosts: {{ total_hosts }}  Matching expected: {{ ok_hosts }}  With issues: {{ hosts_with_issues|length }}
{% if not only_issues and ok_hosts == total_hosts and total_hosts > 0 %}
All hosts matched expected ports.
{% endif %} {% if only_issues and hosts_with_issues|length == 0 %}
No hosts with issues found. ✅
{% endif %} {# Host sections #} {% for ip_key, r in reports|dictsort %} {% set has_issues = r.unexpected_tcp or r.missing_tcp or r.unexpected_udp or r.missing_udp %} {% set hr = host_results_by_ip.get(ip_key) %} {% set header_title = ip_key ~ ((' (' ~ hr.host ~ ')') if hr and hr.host else '') %} {% if has_issues %} {% macro delta_row(label, ports) -%} {%- endmacro %} {{ delta_row('Unexpected TCP open ports', r.unexpected_tcp) }} {{ delta_row('Expected TCP ports not seen', r.missing_tcp) }} {{ delta_row('Unexpected UDP open ports', r.unexpected_udp) }} {{ delta_row('Expected UDP ports not seen', r.missing_udp) }} {% if hr and hr.ports %} {% for p in hr.ports %} {% endfor %} {% else %} {% endif %} {% else %} {# Host has no issues #} {% endif %}
{{ header_title }} {% if has_issues %} {{ badge('ISSUES', '#ef4444') }} {% else %} {{ badge('OK', '#16a34a') }} {% endif %}
{{ badge('ISSUES', '#ef4444') }}
{{ label }}: {{ fmt_ports(ports) }}
Discovered Ports
Protocol Port State Service
{{ pill_proto(p.protocol) }} {{ p.port }} {{ pill_state(p.state) }} {{ p.service or '-' }}
No per-port details available for this host.
{{ badge('OK', '#16a34a') }}   Matches expected ports.
{% endfor %}
Report generated by mass-scan-v2 • {{ generated }}