- UCI config: Add scoring section with event weights, sensitivity presets, whitelist, and decay options - dpi-correlator: Load scoring weights from UCI, apply sensitivity multipliers, check whitelist before auto-ban, periodic reputation decay - CLI: New 'tune', 'whitelist', 'decay' commands for runtime configuration - RPCD: 6 new methods - get_tuning, set_tuning, whitelist_add/remove/list, reset_reputation - ACL: Added permissions for new tuning methods Sensitivity presets: - low (0.7x) - fewer false positives - medium (1.0x) - balanced (default) - high (1.3x) - aggressive detection Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
653 lines
24 KiB
Bash
653 lines
24 KiB
Bash
#!/bin/sh
|
|
# RPCD handler for DPI Dual-Stream dashboard
|
|
# Part of luci-app-dpi-dual
|
|
|
|
. /lib/functions.sh
|
|
. /usr/share/libubox/jshn.sh
|
|
|
|
STATS_DIR="/tmp/secubox"
|
|
FLOW_DIR="/tmp/dpi-flows"
|
|
BUFFER_FILE="$STATS_DIR/dpi-buffer.json"
|
|
FLOWS_FILE="$STATS_DIR/dpi-flows.json"
|
|
THREATS_FILE="$STATS_DIR/correlated-threats.json"
|
|
ALERTS_FILE="$STATS_DIR/waf-alerts.json"
|
|
|
|
read_json_file() {
|
|
file="$1"
|
|
if [ -f "$file" ]; then
|
|
cat "$file"
|
|
else
|
|
echo '{}'
|
|
fi
|
|
}
|
|
|
|
case "$1" in
|
|
list)
|
|
cat << 'EOF'
|
|
{
|
|
"status": {},
|
|
"get_flows": {},
|
|
"get_buffer": {"limit": 100},
|
|
"get_threats": {"limit": 50},
|
|
"get_correlation": {"limit": 20},
|
|
"get_correlation_stats": {},
|
|
"get_ip_context": {"ip": "string"},
|
|
"get_ip_reputation": {"ip": "string"},
|
|
"get_timeline": {"limit": 50},
|
|
"get_mirror_status": {},
|
|
"search_correlations": {"ip": "string", "limit": 50},
|
|
"start": {},
|
|
"stop": {},
|
|
"restart": {},
|
|
"replay_request": {"req_hash": "string"},
|
|
"correlate_ip": {"ip": "string"},
|
|
"ban_ip": {"ip": "string", "duration": "string"},
|
|
"set_auto_ban": {"enabled": true},
|
|
"get_tuning": {},
|
|
"set_tuning": {"param": "string", "value": "string"},
|
|
"whitelist_add": {"ip": "string"},
|
|
"whitelist_remove": {"ip": "string"},
|
|
"whitelist_list": {},
|
|
"reset_reputation": {"ip": "string"},
|
|
"get_lan_status": {},
|
|
"get_lan_clients": {},
|
|
"get_lan_destinations": {"limit": 100},
|
|
"get_lan_protocols": {}
|
|
}
|
|
EOF
|
|
;;
|
|
|
|
call)
|
|
case "$2" in
|
|
status)
|
|
# Get unified status of both streams
|
|
config_load dpi-dual
|
|
|
|
enabled=""
|
|
mode=""
|
|
correlation=""
|
|
config_get enabled settings enabled "0"
|
|
config_get mode settings mode "dual"
|
|
config_get correlation settings correlation "0"
|
|
|
|
# Check processes (use partial match for truncated process names)
|
|
mitm_running=0
|
|
tap_running=0
|
|
collector_running=0
|
|
correlator_running=0
|
|
lan_collector_running=0
|
|
pgrep -f mitmproxy-in >/dev/null 2>&1 && mitm_running=1
|
|
pgrep netifyd >/dev/null 2>&1 && tap_running=1
|
|
pgrep -f dpi-flow-collect >/dev/null 2>&1 && collector_running=1
|
|
pgrep -f dpi-correlator >/dev/null 2>&1 && correlator_running=1
|
|
pgrep -f dpi-lan-collect >/dev/null 2>&1 && lan_collector_running=1
|
|
|
|
# Get TAP interface status
|
|
tap_if=""
|
|
tap_up=0
|
|
tap_rx=0
|
|
tap_tx=0
|
|
config_get tap_if tap interface "tap0"
|
|
if ip link show "$tap_if" >/dev/null 2>&1; then
|
|
tap_up=1
|
|
tap_rx=$(cat "/sys/class/net/$tap_if/statistics/rx_bytes" 2>/dev/null || echo 0)
|
|
tap_tx=$(cat "/sys/class/net/$tap_if/statistics/tx_bytes" 2>/dev/null || echo 0)
|
|
fi
|
|
|
|
# Get buffer stats
|
|
buffer_entries=0 buffer_threats=0 buffer_blocked=0
|
|
if [ -f "$BUFFER_FILE" ]; then
|
|
buffer_entries=$(jsonfilter -i "$BUFFER_FILE" -e '@.entries' 2>/dev/null || echo 0)
|
|
buffer_threats=$(jsonfilter -i "$BUFFER_FILE" -e '@.threats_detected' 2>/dev/null || echo 0)
|
|
buffer_blocked=$(jsonfilter -i "$BUFFER_FILE" -e '@.blocked_count' 2>/dev/null || echo 0)
|
|
fi
|
|
|
|
# Get flow stats
|
|
flows_1min=0
|
|
if [ -f "$FLOWS_FILE" ]; then
|
|
flows_1min=$(jsonfilter -i "$FLOWS_FILE" -e '@.flows_1min' 2>/dev/null || echo 0)
|
|
fi
|
|
|
|
# Get correlation stats
|
|
correlated_threats=0
|
|
if [ -f "$THREATS_FILE" ]; then
|
|
correlated_threats=$(wc -l < "$THREATS_FILE" 2>/dev/null || echo 0)
|
|
fi
|
|
|
|
# Get LAN passive analysis stats
|
|
lan_enabled=""
|
|
lan_if=""
|
|
config_get lan_enabled lan enabled "0"
|
|
config_get lan_if lan interface "br-lan"
|
|
|
|
lan_clients=0 lan_dests=0 lan_protos=0
|
|
lan_file="$STATS_DIR/lan-flows.json"
|
|
if [ -f "$lan_file" ]; then
|
|
lan_clients=$(jsonfilter -i "$lan_file" -e '@.active_clients' 2>/dev/null || echo 0)
|
|
lan_dests=$(jsonfilter -i "$lan_file" -e '@.unique_destinations' 2>/dev/null || echo 0)
|
|
lan_protos=$(jsonfilter -i "$lan_file" -e '@.detected_protocols' 2>/dev/null || echo 0)
|
|
fi
|
|
|
|
cat << EOF
|
|
{
|
|
"enabled": $enabled,
|
|
"mode": "$mode",
|
|
"correlation_enabled": $correlation,
|
|
"mitm_stream": {
|
|
"running": $mitm_running,
|
|
"buffer_entries": $buffer_entries,
|
|
"threats_detected": $buffer_threats,
|
|
"blocked_count": $buffer_blocked
|
|
},
|
|
"tap_stream": {
|
|
"running": $tap_running,
|
|
"interface": "$tap_if",
|
|
"interface_up": $tap_up,
|
|
"rx_bytes": $tap_rx,
|
|
"tx_bytes": $tap_tx,
|
|
"flows_1min": $flows_1min,
|
|
"collector_running": $collector_running
|
|
},
|
|
"correlation": {
|
|
"running": $correlator_running,
|
|
"threats_correlated": $correlated_threats
|
|
},
|
|
"lan_passive": {
|
|
"enabled": $lan_enabled,
|
|
"running": $lan_collector_running,
|
|
"interface": "$lan_if",
|
|
"active_clients": $lan_clients,
|
|
"unique_destinations": $lan_dests,
|
|
"detected_protocols": $lan_protos
|
|
}
|
|
}
|
|
EOF
|
|
;;
|
|
|
|
get_flows)
|
|
read_json_file "$FLOWS_FILE"
|
|
;;
|
|
|
|
get_buffer)
|
|
read "$3"
|
|
json_load "$REPLY"
|
|
json_get_var limit limit 100
|
|
|
|
if [ -f "$BUFFER_FILE" ]; then
|
|
cat "$BUFFER_FILE"
|
|
else
|
|
echo '{"entries": 0, "requests": []}'
|
|
fi
|
|
;;
|
|
|
|
get_threats)
|
|
read "$3"
|
|
json_load "$REPLY"
|
|
json_get_var limit limit 50
|
|
|
|
if [ -f "$ALERTS_FILE" ]; then
|
|
# Return last N alerts
|
|
total=$(jsonfilter -i "$ALERTS_FILE" -e '@[*]' 2>/dev/null | wc -l)
|
|
|
|
cat << EOF
|
|
{
|
|
"total": $total,
|
|
"alerts": $(tail -c 50000 "$ALERTS_FILE" 2>/dev/null || echo '[]')
|
|
}
|
|
EOF
|
|
else
|
|
echo '{"total": 0, "alerts": []}'
|
|
fi
|
|
;;
|
|
|
|
get_correlation)
|
|
read "$3"
|
|
json_load "$REPLY"
|
|
json_get_var limit limit 20
|
|
|
|
if [ -f "$THREATS_FILE" ]; then
|
|
total=$(wc -l < "$THREATS_FILE" 2>/dev/null || echo 0)
|
|
|
|
cat << EOF
|
|
{
|
|
"total": $total,
|
|
"correlated": $(tail -"$limit" "$THREATS_FILE" 2>/dev/null | tr '\n' ',' | sed 's/,$//' | awk '{print "["$0"]"}')
|
|
}
|
|
EOF
|
|
else
|
|
echo '{"total": 0, "correlated": []}'
|
|
fi
|
|
;;
|
|
|
|
get_mirror_status)
|
|
/usr/lib/dpi-dual/mirror-setup.sh status 2>&1 | \
|
|
awk 'BEGIN{print "{"}
|
|
/TAP Interface/ {tap=1}
|
|
/not found/ {up=0}
|
|
/UP/ {up=1}
|
|
/RX:/ {rx=$2}
|
|
/TX:/ {tx=$2}
|
|
/ingress/ {ing=1}
|
|
END{
|
|
printf "\"tap_found\": %s, \"tap_up\": %s, \"ingress_configured\": %s",
|
|
(tap?1:0), (up?1:0), (ing?1:0);
|
|
print "}"
|
|
}'
|
|
;;
|
|
|
|
start)
|
|
/usr/sbin/dpi-dualctl start >/dev/null 2>&1
|
|
echo '{"success": true}'
|
|
;;
|
|
|
|
stop)
|
|
/usr/sbin/dpi-dualctl stop >/dev/null 2>&1
|
|
echo '{"success": true}'
|
|
;;
|
|
|
|
restart)
|
|
/usr/sbin/dpi-dualctl restart >/dev/null 2>&1
|
|
echo '{"success": true}'
|
|
;;
|
|
|
|
replay_request)
|
|
read "$3"
|
|
json_load "$REPLY"
|
|
json_get_var req_hash req_hash ""
|
|
|
|
if [ -z "$req_hash" ]; then
|
|
echo '{"success": false, "error": "req_hash required"}'
|
|
else
|
|
# Add to replay queue (read by mitmproxy addon)
|
|
queue_file="/tmp/dpi-buffer/replay-queue.json"
|
|
mkdir -p /tmp/dpi-buffer
|
|
|
|
if [ ! -f "$queue_file" ]; then
|
|
echo "[]" > "$queue_file"
|
|
fi
|
|
|
|
entry="{\"req_hash\":\"$req_hash\",\"queued_at\":\"$(date -Iseconds)\",\"status\":\"pending\"}"
|
|
|
|
# Append to queue (keep last 100)
|
|
(cat "$queue_file" | jsonfilter -e '@[*]' 2>/dev/null; echo "$entry") | \
|
|
tail -100 | \
|
|
awk 'BEGIN{print "["} {if(NR>1)print ","; print} END{print "]"}' > "$queue_file.tmp"
|
|
mv "$queue_file.tmp" "$queue_file"
|
|
|
|
echo '{"success": true, "message": "Request queued for replay"}'
|
|
fi
|
|
;;
|
|
|
|
correlate_ip)
|
|
read "$3"
|
|
json_load "$REPLY"
|
|
json_get_var ip ip ""
|
|
|
|
if [ -z "$ip" ]; then
|
|
echo '{"success": false, "error": "IP required"}'
|
|
else
|
|
/usr/sbin/dpi-correlator correlate "$ip" "manual_request" >/dev/null 2>&1
|
|
echo '{"success": true, "message": "Correlation triggered for '"$ip"'"}'
|
|
fi
|
|
;;
|
|
|
|
get_correlation_stats)
|
|
/usr/sbin/dpi-correlator stats 2>/dev/null || echo '{"total_correlations": 0}'
|
|
;;
|
|
|
|
get_ip_context)
|
|
read "$3"
|
|
json_load "$REPLY"
|
|
json_get_var ip ip ""
|
|
|
|
if [ -z "$ip" ]; then
|
|
echo '{"error": "IP required"}'
|
|
else
|
|
/usr/sbin/dpi-correlator context "$ip" 2>/dev/null || echo '{"error": "Context not available"}'
|
|
fi
|
|
;;
|
|
|
|
get_ip_reputation)
|
|
read "$3"
|
|
json_load "$REPLY"
|
|
json_get_var ip ip ""
|
|
|
|
if [ -z "$ip" ]; then
|
|
echo '{"error": "IP required"}'
|
|
else
|
|
. /usr/lib/dpi-dual/correlation-lib.sh
|
|
init_reputation_db
|
|
score=$(get_ip_reputation "$ip")
|
|
echo "{\"ip\": \"$ip\", \"reputation_score\": $score}"
|
|
fi
|
|
;;
|
|
|
|
get_timeline)
|
|
read "$3"
|
|
json_load "$REPLY"
|
|
json_get_var limit limit 50
|
|
|
|
log_file="/tmp/secubox/correlated-threats.json"
|
|
if [ -f "$log_file" ]; then
|
|
total=$(wc -l < "$log_file" 2>/dev/null || echo 0)
|
|
|
|
# Get last N entries as JSON array
|
|
entries=$(tail -"$limit" "$log_file" 2>/dev/null | \
|
|
awk 'BEGIN { printf "[" }
|
|
{ if (NR > 1) printf ","; print }
|
|
END { printf "]" }')
|
|
|
|
cat << EOF
|
|
{
|
|
"total": $total,
|
|
"limit": $limit,
|
|
"entries": $entries
|
|
}
|
|
EOF
|
|
else
|
|
echo '{"total": 0, "limit": '$limit', "entries": []}'
|
|
fi
|
|
;;
|
|
|
|
search_correlations)
|
|
read "$3"
|
|
json_load "$REPLY"
|
|
json_get_var ip ip ""
|
|
json_get_var limit limit 50
|
|
|
|
results=$(/usr/sbin/dpi-correlator search "$ip" "$limit" 2>/dev/null | \
|
|
awk 'BEGIN { printf "[" }
|
|
{ if (NR > 1) printf ","; print }
|
|
END { printf "]" }')
|
|
|
|
echo "{\"results\": $results}"
|
|
;;
|
|
|
|
ban_ip)
|
|
read "$3"
|
|
json_load "$REPLY"
|
|
json_get_var ip ip ""
|
|
json_get_var duration duration "4h"
|
|
|
|
if [ -z "$ip" ]; then
|
|
echo '{"success": false, "error": "IP required"}'
|
|
else
|
|
if command -v cscli >/dev/null 2>&1; then
|
|
cscli decisions add -i "$ip" -d "$duration" -r "dpi-dual-manual" -t ban >/dev/null 2>&1
|
|
echo '{"success": true, "message": "IP '"$ip"' banned for '"$duration"'"}'
|
|
else
|
|
echo '{"success": false, "error": "CrowdSec not available"}'
|
|
fi
|
|
fi
|
|
;;
|
|
|
|
set_auto_ban)
|
|
read "$3"
|
|
json_load "$REPLY"
|
|
json_get_var enabled enabled "0"
|
|
|
|
val="0"
|
|
[ "$enabled" = "true" ] && val="1"
|
|
|
|
uci set dpi-dual.correlation.auto_ban="$val"
|
|
uci commit dpi-dual
|
|
echo '{"success": true, "auto_ban": '$val'}'
|
|
;;
|
|
|
|
get_tuning)
|
|
config_load dpi-dual
|
|
|
|
# Load correlation settings
|
|
sensitivity="" threshold="" duration="" notifications=""
|
|
notif_threshold="" decay="" decay_interval=""
|
|
config_get sensitivity correlation sensitivity "medium"
|
|
config_get threshold correlation auto_ban_threshold "80"
|
|
config_get duration correlation auto_ban_duration "4h"
|
|
config_get notifications correlation notifications "1"
|
|
config_get notif_threshold correlation notification_threshold "70"
|
|
config_get decay correlation reputation_decay "5"
|
|
config_get decay_interval correlation decay_interval "3600"
|
|
|
|
# Load scoring weights
|
|
waf_block="" waf_alert="" cs_ban="" dpi_threat="" scanner="" brute_force="" default_score=""
|
|
config_get waf_block scoring waf_block "25"
|
|
config_get waf_alert scoring waf_alert "15"
|
|
config_get cs_ban scoring crowdsec_ban "30"
|
|
config_get dpi_threat scoring dpi_threat "20"
|
|
config_get scanner scoring scanner "35"
|
|
config_get brute_force scoring brute_force "40"
|
|
config_get default_score scoring default "10"
|
|
|
|
# Calculate sensitivity multiplier
|
|
case "$sensitivity" in
|
|
low) mult=70 ;;
|
|
medium) mult=100 ;;
|
|
high) mult=130 ;;
|
|
*) mult=100 ;;
|
|
esac
|
|
|
|
cat << EOF
|
|
{
|
|
"sensitivity": "$sensitivity",
|
|
"sensitivity_multiplier": $mult,
|
|
"auto_ban_threshold": $threshold,
|
|
"auto_ban_duration": "$duration",
|
|
"notifications": $notifications,
|
|
"notification_threshold": $notif_threshold,
|
|
"reputation_decay": $decay,
|
|
"decay_interval": $decay_interval,
|
|
"scoring": {
|
|
"waf_block": $waf_block,
|
|
"waf_alert": $waf_alert,
|
|
"crowdsec_ban": $cs_ban,
|
|
"dpi_threat": $dpi_threat,
|
|
"scanner": $scanner,
|
|
"brute_force": $brute_force,
|
|
"default": $default_score
|
|
}
|
|
}
|
|
EOF
|
|
;;
|
|
|
|
set_tuning)
|
|
read "$3"
|
|
json_load "$REPLY"
|
|
json_get_var param param ""
|
|
json_get_var value value ""
|
|
|
|
if [ -z "$param" ] || [ -z "$value" ]; then
|
|
echo '{"success": false, "error": "param and value required"}'
|
|
else
|
|
case "$param" in
|
|
sensitivity)
|
|
case "$value" in
|
|
low|medium|high|custom)
|
|
uci set dpi-dual.correlation.sensitivity="$value"
|
|
uci commit dpi-dual
|
|
echo '{"success": true, "param": "sensitivity", "value": "'"$value"'"}'
|
|
;;
|
|
*)
|
|
echo '{"success": false, "error": "Invalid sensitivity: use low, medium, high, or custom"}'
|
|
;;
|
|
esac
|
|
;;
|
|
threshold)
|
|
if [ "$value" -ge 0 ] && [ "$value" -le 100 ] 2>/dev/null; then
|
|
uci set dpi-dual.correlation.auto_ban_threshold="$value"
|
|
uci commit dpi-dual
|
|
echo '{"success": true, "param": "threshold", "value": '$value'}'
|
|
else
|
|
echo '{"success": false, "error": "Threshold must be 0-100"}'
|
|
fi
|
|
;;
|
|
duration)
|
|
uci set dpi-dual.correlation.auto_ban_duration="$value"
|
|
uci commit dpi-dual
|
|
echo '{"success": true, "param": "duration", "value": "'"$value"'"}'
|
|
;;
|
|
decay)
|
|
if [ "$value" -ge 0 ] && [ "$value" -le 50 ] 2>/dev/null; then
|
|
uci set dpi-dual.correlation.reputation_decay="$value"
|
|
uci commit dpi-dual
|
|
echo '{"success": true, "param": "decay", "value": '$value'}'
|
|
else
|
|
echo '{"success": false, "error": "Decay must be 0-50"}'
|
|
fi
|
|
;;
|
|
notification_threshold)
|
|
if [ "$value" -ge 0 ] && [ "$value" -le 100 ] 2>/dev/null; then
|
|
uci set dpi-dual.correlation.notification_threshold="$value"
|
|
uci commit dpi-dual
|
|
echo '{"success": true, "param": "notification_threshold", "value": '$value'}'
|
|
else
|
|
echo '{"success": false, "error": "Notification threshold must be 0-100"}'
|
|
fi
|
|
;;
|
|
waf_block|waf_alert|crowdsec_ban|dpi_threat|scanner|brute_force|default)
|
|
if [ "$value" -ge 0 ] && [ "$value" -le 100 ] 2>/dev/null; then
|
|
uci set dpi-dual.scoring."$param"="$value"
|
|
uci commit dpi-dual
|
|
echo '{"success": true, "param": "'"$param"'", "value": '$value'}'
|
|
else
|
|
echo '{"success": false, "error": "Score weight must be 0-100"}'
|
|
fi
|
|
;;
|
|
*)
|
|
echo '{"success": false, "error": "Unknown param: '"$param"'"}'
|
|
;;
|
|
esac
|
|
fi
|
|
;;
|
|
|
|
whitelist_add)
|
|
read "$3"
|
|
json_load "$REPLY"
|
|
json_get_var ip ip ""
|
|
|
|
if [ -z "$ip" ]; then
|
|
echo '{"success": false, "error": "IP required"}'
|
|
else
|
|
uci add_list dpi-dual.whitelist.ip="$ip"
|
|
uci commit dpi-dual
|
|
echo '{"success": true, "message": "Added '"$ip"' to whitelist"}'
|
|
fi
|
|
;;
|
|
|
|
whitelist_remove)
|
|
read "$3"
|
|
json_load "$REPLY"
|
|
json_get_var ip ip ""
|
|
|
|
if [ -z "$ip" ]; then
|
|
echo '{"success": false, "error": "IP required"}'
|
|
else
|
|
uci del_list dpi-dual.whitelist.ip="$ip"
|
|
uci commit dpi-dual
|
|
echo '{"success": true, "message": "Removed '"$ip"' from whitelist"}'
|
|
fi
|
|
;;
|
|
|
|
whitelist_list)
|
|
config_load dpi-dual
|
|
|
|
# Collect whitelist IPs
|
|
wl_ips=""
|
|
append_wl_ip() {
|
|
[ -n "$wl_ips" ] && wl_ips="$wl_ips,"
|
|
wl_ips="$wl_ips\"$1\""
|
|
}
|
|
config_list_foreach whitelist ip append_wl_ip
|
|
|
|
echo "{\"whitelist\": [$wl_ips]}"
|
|
;;
|
|
|
|
reset_reputation)
|
|
read "$3"
|
|
json_load "$REPLY"
|
|
json_get_var ip ip ""
|
|
|
|
if [ -z "$ip" ]; then
|
|
echo '{"success": false, "error": "IP required"}'
|
|
else
|
|
. /usr/lib/dpi-dual/correlation-lib.sh
|
|
reset_ip_reputation "$ip"
|
|
echo '{"success": true, "message": "Reset reputation for '"$ip"'"}'
|
|
fi
|
|
;;
|
|
|
|
get_lan_status)
|
|
# LAN passive flow analysis status
|
|
config_load dpi-dual
|
|
|
|
lan_enabled=""
|
|
lan_if=""
|
|
config_get lan_enabled lan enabled "0"
|
|
config_get lan_if lan interface "br-lan"
|
|
|
|
collector_running=0
|
|
pgrep -f dpi-lan-collect >/dev/null 2>&1 && collector_running=1
|
|
|
|
lan_file="$STATS_DIR/lan-flows.json"
|
|
active_clients=0 unique_dests=0 detected_protos=0
|
|
rx_bytes=0 tx_bytes=0
|
|
|
|
if [ -f "$lan_file" ]; then
|
|
active_clients=$(jsonfilter -i "$lan_file" -e '@.active_clients' 2>/dev/null || echo 0)
|
|
unique_dests=$(jsonfilter -i "$lan_file" -e '@.unique_destinations' 2>/dev/null || echo 0)
|
|
detected_protos=$(jsonfilter -i "$lan_file" -e '@.detected_protocols' 2>/dev/null || echo 0)
|
|
rx_bytes=$(jsonfilter -i "$lan_file" -e '@.rx_bytes' 2>/dev/null || echo 0)
|
|
tx_bytes=$(jsonfilter -i "$lan_file" -e '@.tx_bytes' 2>/dev/null || echo 0)
|
|
fi
|
|
|
|
cat << EOF
|
|
{
|
|
"enabled": $lan_enabled,
|
|
"interface": "$lan_if",
|
|
"collector_running": $collector_running,
|
|
"active_clients": $active_clients,
|
|
"unique_destinations": $unique_dests,
|
|
"detected_protocols": $detected_protos,
|
|
"rx_bytes": $rx_bytes,
|
|
"tx_bytes": $tx_bytes
|
|
}
|
|
EOF
|
|
;;
|
|
|
|
get_lan_clients)
|
|
clients_file="$STATS_DIR/lan-clients.json"
|
|
if [ -f "$clients_file" ]; then
|
|
cat "$clients_file"
|
|
else
|
|
echo '{"timestamp":"","clients":[]}'
|
|
fi
|
|
;;
|
|
|
|
get_lan_destinations)
|
|
read "$3"
|
|
json_load "$REPLY"
|
|
json_get_var limit limit 100
|
|
|
|
dests_file="$STATS_DIR/lan-destinations.json"
|
|
if [ -f "$dests_file" ]; then
|
|
cat "$dests_file"
|
|
else
|
|
echo '{"timestamp":"","destinations":[]}'
|
|
fi
|
|
;;
|
|
|
|
get_lan_protocols)
|
|
protos_file="$STATS_DIR/lan-protocols.json"
|
|
if [ -f "$protos_file" ]; then
|
|
cat "$protos_file"
|
|
else
|
|
echo '{"timestamp":"","protocols":[]}'
|
|
fi
|
|
;;
|
|
|
|
*)
|
|
echo '{"error": "Unknown method"}'
|
|
;;
|
|
esac
|
|
;;
|
|
esac
|