From eee89bf3a9197514526f3548fef5e5f9283280d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20L=C3=BCssing?= Date: Tue, 17 Aug 2021 05:23:04 +0200 Subject: [PATCH 1/4] bpfcountd: add initial package MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit bpfcountd was created to obtain packet statistics in larger networks without stressing the cpu resources. bpfcountd will count the amount of packages and bytes over time (for each defined rule). The rules are defined using the tcpdump filter syntax (bpf). The collected data is provided on a unix socket in plaintext. Signed-off-by: Linus Lüssing --- package/bpfcountd/Makefile | 42 +++++++++ package/bpfcountd/files/etc/bpfcountd.filters | 2 + package/bpfcountd/files/etc/config/bpfcountd | 13 +++ package/bpfcountd/files/etc/init.d/bpfcountd | 92 +++++++++++++++++++ 4 files changed, 149 insertions(+) create mode 100644 package/bpfcountd/Makefile create mode 100644 package/bpfcountd/files/etc/bpfcountd.filters create mode 100644 package/bpfcountd/files/etc/config/bpfcountd create mode 100755 package/bpfcountd/files/etc/init.d/bpfcountd diff --git a/package/bpfcountd/Makefile b/package/bpfcountd/Makefile new file mode 100644 index 00000000..f6b97c2e --- /dev/null +++ b/package/bpfcountd/Makefile @@ -0,0 +1,42 @@ +# SPDX-License-Identifier: MIT +# Copyright (C) 2022 Linus Lüssing + +include $(TOPDIR)/rules.mk + +PKG_NAME:=bpfcountd +PKG_RELEASE:=1 + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_DATE:=2021-06-26 +PKG_SOURCE_URL=https://github.com/lemoer/bpfcountd.git +PKG_SOURCE_VERSION:=8b1aeb18d686815f93e2bfe976e536c5699d6371 +PKG_MIRROR_HASH:=e6e7adcc11c0fd33c6d3ac31423d3288812270944c2f31d9610ac8c3173a8c5f + +PKG_MAINTAINER:=Linus Lüssing +PKG_LICENSE:=MIT +PKG_LICENSE_FILES:=LICENSE + +include $(INCLUDE_DIR)/package.mk + +define Package/bpfcountd + SECTION:=net + CATEGORY:=Network + TITLE:=Berkeley Packet Filter Counting Daemon + DEPENDS:=+libpcap +endef + +define Package/bpfcountd/description + bpfcountd was created to obtain packet statistics in larger networks + without stressing the cpu resources. bpfcountd will count the amount + of packages and bytes over time (for each defined rule). The rules + are defined using the tcpdump filter syntax (bpf). The collected + data is provided on a unix socket in plaintext. +endef + +define Package/bpfcountd/install + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/bpfcountd $(1)/usr/sbin/ + $(CP) ./files/* $(1)/ +endef + +$(eval $(call BuildPackage,bpfcountd)) diff --git a/package/bpfcountd/files/etc/bpfcountd.filters b/package/bpfcountd/files/etc/bpfcountd.filters new file mode 100644 index 00000000..8c1029a2 --- /dev/null +++ b/package/bpfcountd/files/etc/bpfcountd.filters @@ -0,0 +1,2 @@ +arp;arp +icmp6;icmp6 diff --git a/package/bpfcountd/files/etc/config/bpfcountd b/package/bpfcountd/files/etc/config/bpfcountd new file mode 100644 index 00000000..790de16c --- /dev/null +++ b/package/bpfcountd/files/etc/config/bpfcountd @@ -0,0 +1,13 @@ +config bpfcountd 'eth0_in' + option ifname 'eth0' + option prefilter 'inbound' + option filterfile '/etc/bpfcountd.filters' + option buffersize '2097152' + option disabled '1' + +config bpfcountd 'eth0_out' + option ifname 'eth0' + option prefilter 'outbound' + option filterfile '/etc/bpfcountd.filters' + option buffersize '2097152' + option disabled '1' diff --git a/package/bpfcountd/files/etc/init.d/bpfcountd b/package/bpfcountd/files/etc/init.d/bpfcountd new file mode 100755 index 00000000..2db2a4ba --- /dev/null +++ b/package/bpfcountd/files/etc/init.d/bpfcountd @@ -0,0 +1,92 @@ +#!/bin/sh /etc/rc.common +# SPDX-License-Identifier: MIT +# Copyright (C) 2022 Linus Lüssing + +USE_PROCD=1 +START=20 +STOP=90 + +UNIXSOCKDIR=/var/run/bpfcountd + +bpfcountd_start() { + local cfg="$1" + local disabled + + local ifname + local prefilter + local filterfile + local buffersize + + config_get_bool disabled "$cfg" disabled 0 + [ "$disabled" -gt 0 ] && return 0 + + mkdir -p "$UNIXSOCKDIR" + + config_get ifname "$cfg" "ifname" + config_get prefilter "$cfg" "prefilter" + config_get filterfile "$cfg" "filterfile" + config_get buffersize "$cfg" "buffersize" + + [ -z "$ifname" ] && { + echo "Error: no ifname specified for $cfg" >&2 + return 0 + } + [ -z "$filterfile" ] && { + echo "Error: no filterfile specified for $cfg" >&2 + return 0 + } + + procd_open_instance "$cfg" + + procd_set_param command /usr/sbin/bpfcountd + procd_append_param command -i "$ifname" + procd_append_param command -f "$filterfile" + procd_append_param command -u $UNIXSOCKDIR/"$cfg".sock + [ -n "$prefilter" ] && procd_append_param command -F "$prefilter" + [ -n "$buffersize" ] && procd_append_param command -b "$buffersize" + + procd_set_param respawn ${respawn_threshold:-3600} ${respawn_timeout:-5} ${respawn_retry:-5} + + procd_set_param stderr 1 + procd_close_instance +} + +start_service() { + local cfg="$1" + local instance_found=0 + + . /lib/functions/network.sh + + config_cb() { + local type="$1" + local name="$2" + if [ "$type" = "bpfcountd" ]; then + if [ -n "$cfg" -a "$cfg" = "$name" ]; then + instance_found=1 + fi + fi + } + + config_load bpfcountd + + if [ -n "$cfg" ]; then + [ "$instance_found" -gt 0 ] || return + bpfcountd_start "$cfg" + else + config_foreach bpfcountd_start bpfcountd + fi +} + +stop_service() { + local cfg="$1" + + if [ -n "$cfg" ]; then + rm $UNIXSOCKDIR/$cfg.sock + else + rm $UNIXSOCKDIR/*.sock + fi +} + +service_triggers() { + procd_add_reload_trigger bpfcountd +} From 7f47038026ac39e11e2aa3ada7d33c78e25ae16a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20L=C3=BCssing?= Date: Fri, 9 Dec 2022 18:22:27 +0100 Subject: [PATCH 2/4] scripts: lint-sh: ignore POSIX string replacement warnings [SC3060] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This ignores the following warning: warning: In POSIX sh, string replacement is undefined. [SC3060] As string replacements are supported by ash and we are only going to use ash. This allows us to use something short like ${QUERY_STRING//+/ } to replace all '+' to a whitespace in an URL or to make an ${IFNAME//-/_} UCI compatible in the future, for example. Instead of needing to use something long like "echo ${IFNAME} | tr '-' '_'. Signed-off-by: Linus Lüssing --- scripts/lint-sh.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/lint-sh.sh b/scripts/lint-sh.sh index 96335c7a..3eae78ab 100755 --- a/scripts/lint-sh.sh +++ b/scripts/lint-sh.sh @@ -17,7 +17,7 @@ find package -type f | while read -r file; do is_scriptfile "$file" || continue echo "Checking $file" - shellcheck -f gcc -x -s sh -e SC2039,SC1091,SC2155,SC2034,SC3043,SC3037,SC3057 "$file" + shellcheck -f gcc -x -s sh -e SC2039,SC1091,SC2155,SC2034,SC3043,SC3037,SC3057,SC3060 "$file" done find scripts -type f | while read -r file; do From d0fa7dd0bb3e6f23d85daa09336f8d4de4555275 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20L=C3=BCssing?= Date: Tue, 17 Aug 2021 05:24:31 +0200 Subject: [PATCH 3/4] gluon-statistics-mcast: adding initial package MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This package collects disected statistics on multicast and management traffic and provides them via respondd in "statistics-extended". Such information can be helpful for further development and comparison of mesh routing protocols and troubleshooting network issues. The statistics gathered disect into batman-adv packets as well. Statistics are collected both on client bridge ports and br-client as well as mesh interfaces. This introduces a performance penalty but tries to keep the impact on unicast traffic small. Note that respondd replies are rather large (several UDP datagrams, even when LZMA compressed). Therefore you might want to use slower intervals for querying respondd "statistics-extended". Signed-off-by: Linus Lüssing --- package/gluon-statistics-mcast/Makefile | 33 + .../files/etc/hotplug.d/iface/40-bpfcountd | 68 ++ .../files/lib/gluon/bpfcountd/mesh.filters | 618 ++++++++++++++++++ .../lib/gluon/core/mesh/setup.d/40-bpfcountd | 67 ++ .../gluon/core/mesh/teardown.d/40-bpfcountd | 33 + package/gluon-statistics-mcast/src/Makefile | 6 + package/gluon-statistics-mcast/src/respondd.c | 491 ++++++++++++++ 7 files changed, 1316 insertions(+) create mode 100644 package/gluon-statistics-mcast/Makefile create mode 100644 package/gluon-statistics-mcast/files/etc/hotplug.d/iface/40-bpfcountd create mode 100644 package/gluon-statistics-mcast/files/lib/gluon/bpfcountd/mesh.filters create mode 100755 package/gluon-statistics-mcast/files/lib/gluon/core/mesh/setup.d/40-bpfcountd create mode 100755 package/gluon-statistics-mcast/files/lib/gluon/core/mesh/teardown.d/40-bpfcountd create mode 100644 package/gluon-statistics-mcast/src/Makefile create mode 100644 package/gluon-statistics-mcast/src/respondd.c diff --git a/package/gluon-statistics-mcast/Makefile b/package/gluon-statistics-mcast/Makefile new file mode 100644 index 00000000..517b6f0f --- /dev/null +++ b/package/gluon-statistics-mcast/Makefile @@ -0,0 +1,33 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=gluon-statistics-mcast +PKG_VERSION:=1 + +include ../gluon.mk + +define Package/gluon-statistics-mcast + TITLE:=Gluon Statistics for Multicast Traffic + DEPENDS:= +bpfcountd +libgluonutil +endef + +define Package/gluon-statistics-mcast/description + This package collects disected statistics on multicast + and management traffic and provides them via respondd in + "statistics-extended". Such information can be helpful + for further development and comparison of mesh routing + protocols and troubleshooting network issues. + + The statistics gathered disect into batman-adv + packets as well. Statistics are collected both on client + bridge ports and br-client as well as mesh interfaces. + + This introduces a performance penalty but tries to + keep the impact on unicast traffic small. + + Note that respondd replies are rather large + (several UDP datagrams, even when LZMA compressed). + Therefore you might want to use slower intervals for + querying respondd "statistics-extended". +endef + +$(eval $(call BuildPackageGluon,gluon-statistics-mcast)) diff --git a/package/gluon-statistics-mcast/files/etc/hotplug.d/iface/40-bpfcountd b/package/gluon-statistics-mcast/files/etc/hotplug.d/iface/40-bpfcountd new file mode 100644 index 00000000..bc963f14 --- /dev/null +++ b/package/gluon-statistics-mcast/files/etc/hotplug.d/iface/40-bpfcountd @@ -0,0 +1,68 @@ +case "$INTERFACE" in + "client"|\ + "mmfd") + ;; + *) + exit 0 + ;; +esac + +BPFCOUNTD_RUN="/var/run/bpfcountd" +mkdir -p "${BPFCOUNTD_RUN}/gluon-ifaces" + +get_ifup_ifaces() { + local ifaces="$DEVICE" + local brports + + if [ -d "/sys/class/net/$DEVICE/bridge/" ]; then + brports="$(ls "/sys/class/net/$DEVICE/brif/")" + [ -n "$brports" ] && ifaces="$(echo -e "${brports}\n${ifaces}")" + fi + + echo "$ifaces" +} + +get_ifdown_ifaces() { + cat "${BPFCOUNTD_RUN}/gluon-ifaces/$INTERFACE" +} + +bpfcountd_start() { + local ifaces="$(get_ifup_ifaces)" + local iface + + [ -z "$ifaces" ] && return + [ -f "${BPFCOUNTD_RUN}/gluon-ifaces/$INTERFACE" ] && return + echo "$ifaces" > "${BPFCOUNTD_RUN}/gluon-ifaces/$INTERFACE" + + for iface in $ifaces; do + IFNAME="$iface" /lib/gluon/core/mesh/setup.d/40-bpfcountd "clients" + done +} + +bpfcountd_stop() { + local ifaces="$(get_ifdown_ifaces)" + local iface + + [ -z "$ifaces" ] && return + rm "${BPFCOUNTD_RUN}/gluon-ifaces/$INTERFACE" + + for iface in $ifaces; do + IFNAME="$iface" /lib/gluon/core/mesh/teardown.d/40-bpfcountd + done +} + +# synchronize reads+writes to /var/run/gluon-ifaces/$INTERFACE +lock /var/lock/gluon_bpfcountd_ifaces.lock + +case "$ACTION" in + "ifup") + bpfcountd_start + ;; + "ifdown") + bpfcountd_stop + ;; + *) + ;; +esac + +lock -u /var/lock/gluon_bpfcountd_ifaces.lock diff --git a/package/gluon-statistics-mcast/files/lib/gluon/bpfcountd/mesh.filters b/package/gluon-statistics-mcast/files/lib/gluon/bpfcountd/mesh.filters new file mode 100644 index 00000000..beb21792 --- /dev/null +++ b/package/gluon-statistics-mcast/files/lib/gluon/bpfcountd/mesh.filters @@ -0,0 +1,618 @@ +%SSDP;udp dst port 1900 +%LLMNR;udp dst port 5355 +%MDNS;udp dst port 5353 +%NB-NS;udp dst port 137 +%NB-DGM;udp dst port 138 +%DP-LSP;udp dst port 17500 +%TRAP-DAEMON;udp dst port 3600 +%DHCP4;udp port (67 || 68) +%DHCP6;udp port (546 || 547) +%WS-DISC;udp port 3702 +%WSP;udp dst port 9200 +%TEREDO;udp dst port 3544 +%SPOTIFY;udp dst port 57621 +%SIP;udp dst port 5060 +%BT-LPD;udp dst port 6771 +%NVBM;udp dst port 8225 +%SVRLOC;udp dst port 427 +%ENPC;udp dst port 3289 +%QTSTREAM;udp dst port 7555 +%HDHOMERUN;udp dst port 65001 +%PLEX-DISC0;udp dst port 32410 +%PLEX-DISC2;udp dst port 32412 +%PLEX-DISC3;udp dst port 32413 +%PLEX-DISC4;udp dst port 32414 +%BT-UTP;udp dst port 16680 +%WF-BSSERV;udp dst port 61117 +%FAXIMUM;udp dst port 7437 +%TOMCAT;udp dst port 9006 +%DISTINCT;udp dst port 9999 +%UDP-25412;udp dst port 25412 +%UDP-10203;udp dst port 10203 +%UDP-60128;udp dst port 60128 +%COREL-VNC;udp dst port 2654 +%HPVMMCTRL;udp dst port 1124 +%CBT;udp dst port 7777 +%MCAFEE;udp dst port 6646 +%UDP-39455;udp dst port 39455 +%UDP-889;udp dst port 889 +%UDP-16962;udp dst port 16962 +%TSEQ;udp dst port 0 +%CANON-BJNP;udp dst port 8612 +%RIP;udp dst port 520 +%RIPNG;udp dst port 521 +%OLSRV1;udp dst port 698 +%BABEL;udp dst port 6696 +%MANET;udp dst port 269 +%RESPONDD-QRY;udp dst port 1001 +%SYNCTHING-LPD;udp dst port 21027 +%USTEER;udp dst port 16720 +%L3ROAMD;udp dst port 5523 +%MMFD;udp dst port 27275 +%RETICULUM;udp dst port 29716 + +IP4;ip +IP6;ip6 +BLA;arp and arp[0:2] = 0x0001 and arp[2:2] = 0x0800 and arp[6:2] = 0x0002 and arp[14:4] = 0x00000000 and arp[18:2] = 0xff43 and arp[20:1] = 0x05 and arp[24:4] = 0x00000000 +ARP;arp and not ${BLA} +IPX;ipx +NETBEUI;netbeui +LLDP;ether proto 0x88CC + +IP4:IGMP;${IP4} && igmp +IP4:IGMP:QUERY-V1;${IP4:IGMP} and igmp[0] = 0x11 and ip[2:2] = 0x0020 and igmp[1] = 0x00 +IP4:IGMP:QUERY-V2;${IP4:IGMP} and igmp[0] = 0x11 and ip[2:2] = 0x0020 and not (igmp[1] = 0x00) +IP4:IGMP:QUERY-V3;${IP4:IGMP} and igmp[0] = 0x11 and ip[2:2] >= 0x0024 +IP4:IGMP:QUERY-UNKNOWN;${IP4:IGMP} and igmp[0] = 0x11 and not ((ip[2:2] = 0x0020 and igmp[1] = 0x00) or (ip[2:2] = 0x0020 and not (igmp[1] = 0x00)) or ip[2:2] >= 0x0024) +IP4:IGMP:REPORT-V1;${IP4:IGMP} and igmp[0] = 0x12 +IP4:IGMP:REPORT-V2;${IP4:IGMP} and igmp[0] = 0x16 +IP4:IGMP:LEAVE-V2;${IP4:IGMP} and igmp[0] = 0x17 +IP4:IGMP:REPORT-V3;${IP4:IGMP} and igmp[0] = 0x22 +IP4:IGMP:MRD-ADV;${IP4:IGMP} and igmp[0] = 0x30 +IP4:IGMP:MRD-SOL;${IP4:IGMP} and igmp[0] = 0x31 +IP4:IGMP:MRD-TERM;${IP4:IGMP} and igmp[0] = 0x32 + +IP4:MC;${IP4} && ip multicast +IP4:MC:PIM;${IP4:MC} && ((ip proto 103) or ((ip proto 2) and (ip[20] == 0x14))) +IP4:MC:OSPF;${IP4:MC} && ip proto 89 +IP4:MC:MANET;${IP4:MC} && ip proto 138 +IP4:MC:UDP;${IP4:MC} && udp + +IP4:MC:UDP:SSDP;${IP4:MC:UDP} && ${%SSDP} +IP4:MC:UDP:LLMNR;${IP4:MC:UDP} && ${%LLMNR} +IP4:MC:UDP:MDNS;${IP4:MC:UDP} && ${%MDNS} +IP4:MC:UDP:NB-NS;${IP4:MC:UDP} && ${%NB-NS} +IP4:MC:UDP:NB-DGM;${IP4:MC:UDP} && ${%NB-DGM} +IP4:MC:UDP:DP-LSP;${IP4:MC:UDP} && ${%DP-LSP} +IP4:MC:UDP:TRAP-DAEMON;${IP4:MC:UDP} && ${%TRAP-DAEMON} +IP4:MC:UDP:DHCP4;${IP4:MC:UDP} && ${%DHCP4} +IP4:MC:UDP:DHCP6;${IP4:MC:UDP} && ${%DHCP6} +IP4:MC:UDP:WS-DISC;${IP4:MC:UDP} && ${%WS-DISC} +IP4:MC:UDP:WSP;${IP4:MC:UDP} && ${%WSP} +IP4:MC:UDP:TEREDO;${IP4:MC:UDP} && ${%TEREDO} +IP4:MC:UDP:SPOTIFY;${IP4:MC:UDP} && ${%SPOTIFY} +IP4:MC:UDP:SIP;${IP4:MC:UDP} && ${%SIP} +IP4:MC:UDP:BT-LPD;${IP4:MC:UDP} && ${%BT-LPD} +IP4:MC:UDP:NVBM;${IP4:MC:UDP} && ${%NVBM} +IP4:MC:UDP:SVRLOC;${IP4:MC:UDP} && ${%SVRLOC} +IP4:MC:UDP:ENPC;${IP4:MC:UDP} && ${%ENPC} +IP4:MC:UDP:QTSTREAM;${IP4:MC:UDP} && ${%QTSTREAM} +IP4:MC:UDP:HDHOMERUN;${IP4:MC:UDP} && ${%HDHOMERUN} +IP4:MC:UDP:PLEX-DISC0;${IP4:MC:UDP} && ${%PLEX-DISC0} +IP4:MC:UDP:PLEX-DISC2;${IP4:MC:UDP} && ${%PLEX-DISC2} +IP4:MC:UDP:PLEX-DISC3;${IP4:MC:UDP} && ${%PLEX-DISC3} +IP4:MC:UDP:PLEX-DISC4;${IP4:MC:UDP} && ${%PLEX-DISC4} +IP4:MC:UDP:BT-UTP;${IP4:MC:UDP} && ${%BT-UTP} +IP4:MC:UDP:WF-BSSERV;${IP4:MC:UDP} && ${%WF-BSSERV} +IP4:MC:UDP:FAXIMUM;${IP4:MC:UDP} && ${%FAXIMUM} +IP4:MC:UDP:TOMCAT;${IP4:MC:UDP} && ${%TOMCAT} +IP4:MC:UDP:DISTINCT;${IP4:MC:UDP} && ${%DISTINCT} +IP4:MC:UDP:UDP-25412;${IP4:MC:UDP} && ${%UDP-25412} +IP4:MC:UDP:UDP-10203;${IP4:MC:UDP} && ${%UDP-10203} +IP4:MC:UDP:UDP-60128;${IP4:MC:UDP} && ${%UDP-60128} +IP4:MC:UDP:COREL-VNC;${IP4:MC:UDP} && ${%COREL-VNC} +IP4:MC:UDP:HPVMMCTRL;${IP4:MC:UDP} && ${%HPVMMCTRL} +IP4:MC:UDP:CBT;${IP4:MC:UDP} && ${%CBT} +IP4:MC:UDP:MCAFEE;${IP4:MC:UDP} && ${%MCAFEE} +IP4:MC:UDP:UDP-39455;${IP4:MC:UDP} && ${%UDP-39455} +IP4:MC:UDP:UDP-889;${IP4:MC:UDP} && ${%UDP-889} +IP4:MC:UDP:UDP-16962;${IP4:MC:UDP} && ${%UDP-16962} +IP4:MC:UDP:TSEQ;${IP4:MC:UDP} && ${%TSEQ} +IP4:MC:UDP:CANON-BJNP;${IP4:MC:UDP} && ${%CANON-BJNP} +IP4:MC:UDP:RIP;${IP4:MC:UDP} && ${%RIP} +IP4:MC:UDP:RIPNG;${IP4:MC:UDP} && ${%RIPNG} +IP4:MC:UDP:OLSRV1;${IP4:MC:UDP} && ${%OLSRV1} +IP4:MC:UDP:BABEL;${IP4:MC:UDP} && ${%BABEL} +IP4:MC:UDP:MANET;${IP4:MC:UDP} && ${%MANET} +IP4:MC:UDP:RESPONDD-QRY;${IP4:MC:UDP} && ${%RESPONDD-QRY} +IP4:MC:UDP:SYNCTHING-LPD;${IP4:MC:UDP} && ${%SYNCTHING-LPD} +IP4:MC:UDP:USTEER;${IP4:MC:UDP} && ${%USTEER} +IP4:MC:UDP:L3ROAMD;${IP4:MC:UDP} && ${%L3ROAMD} +IP4:MC:UDP:MMFD;${IP4:MC:UDP} && ${%MMFD} +IP4:MC:UDP:RETICULUM;${IP4:MC:UDP} && ${%RETICULUM} + +IP6:MC;${IP6} && ip6 multicast +IP6:MC:PIM;${IP6:MC} && ip6 proto 103 +IP6:MC:OSPF;${IP6:MC} && ip6 proto 89 +IP6:MC:MANET;${IP6:MC} && ip6 proto 138 +IP6:MC:UDP;${IP6:MC} && udp + +IP6:MC:UDP:SSDP;${IP6:MC:UDP} && ${%SSDP} +IP6:MC:UDP:LLMNR;${IP6:MC:UDP} && ${%LLMNR} +IP6:MC:UDP:MDNS;${IP6:MC:UDP} && ${%MDNS} +IP6:MC:UDP:NB-NS;${IP6:MC:UDP} && ${%NB-NS} +IP6:MC:UDP:NB-DGM;${IP6:MC:UDP} && ${%NB-DGM} +IP6:MC:UDP:DP-LSP;${IP6:MC:UDP} && ${%DP-LSP} +IP6:MC:UDP:TRAP-DAEMON;${IP6:MC:UDP} && ${%TRAP-DAEMON} +IP6:MC:UDP:DHCP4;${IP6:MC:UDP} && ${%DHCP4} +IP6:MC:UDP:DHCP6;${IP6:MC:UDP} && ${%DHCP6} +IP6:MC:UDP:WS-DISC;${IP6:MC:UDP} && ${%WS-DISC} +IP6:MC:UDP:WSP;${IP6:MC:UDP} && ${%WSP} +IP6:MC:UDP:TEREDO;${IP6:MC:UDP} && ${%TEREDO} +IP6:MC:UDP:SPOTIFY;${IP6:MC:UDP} && ${%SPOTIFY} +IP6:MC:UDP:SIP;${IP6:MC:UDP} && ${%SIP} +IP6:MC:UDP:BT-LPD;${IP6:MC:UDP} && ${%BT-LPD} +IP6:MC:UDP:NVBM;${IP6:MC:UDP} && ${%NVBM} +IP6:MC:UDP:SVRLOC;${IP6:MC:UDP} && ${%SVRLOC} +IP6:MC:UDP:ENPC;${IP6:MC:UDP} && ${%ENPC} +IP6:MC:UDP:QTSTREAM;${IP6:MC:UDP} && ${%QTSTREAM} +IP6:MC:UDP:HDHOMERUN;${IP6:MC:UDP} && ${%HDHOMERUN} +IP6:MC:UDP:PLEX-DISC0;${IP6:MC:UDP} && ${%PLEX-DISC0} +IP6:MC:UDP:PLEX-DISC2;${IP6:MC:UDP} && ${%PLEX-DISC2} +IP6:MC:UDP:PLEX-DISC3;${IP6:MC:UDP} && ${%PLEX-DISC3} +IP6:MC:UDP:PLEX-DISC4;${IP6:MC:UDP} && ${%PLEX-DISC4} +IP6:MC:UDP:BT-UTP;${IP6:MC:UDP} && ${%BT-UTP} +IP6:MC:UDP:WF-BSSERV;${IP6:MC:UDP} && ${%WF-BSSERV} +IP6:MC:UDP:FAXIMUM;${IP6:MC:UDP} && ${%FAXIMUM} +IP6:MC:UDP:TOMCAT;${IP6:MC:UDP} && ${%TOMCAT} +IP6:MC:UDP:DISTINCT;${IP6:MC:UDP} && ${%DISTINCT} +IP6:MC:UDP:UDP-25412;${IP6:MC:UDP} && ${%UDP-25412} +IP6:MC:UDP:UDP-10203;${IP6:MC:UDP} && ${%UDP-10203} +IP6:MC:UDP:UDP-60128;${IP6:MC:UDP} && ${%UDP-60128} +IP6:MC:UDP:COREL-VNC;${IP6:MC:UDP} && ${%COREL-VNC} +IP6:MC:UDP:HPVMMCTRL;${IP6:MC:UDP} && ${%HPVMMCTRL} +IP6:MC:UDP:CBT;${IP6:MC:UDP} && ${%CBT} +IP6:MC:UDP:MCAFEE;${IP6:MC:UDP} && ${%MCAFEE} +IP6:MC:UDP:UDP-39455;${IP6:MC:UDP} && ${%UDP-39455} +IP6:MC:UDP:UDP-889;${IP6:MC:UDP} && ${%UDP-889} +IP6:MC:UDP:UDP-16962;${IP6:MC:UDP} && ${%UDP-16962} +IP6:MC:UDP:TSEQ;${IP6:MC:UDP} && ${%TSEQ} +IP6:MC:UDP:CANON-BJNP;${IP6:MC:UDP} && ${%CANON-BJNP} +IP6:MC:UDP:RIP;${IP6:MC:UDP} && ${%RIP} +IP6:MC:UDP:RIPNG;${IP6:MC:UDP} && ${%RIPNG} +IP6:MC:UDP:OLSRV1;${IP6:MC:UDP} && ${%OLSRV1} +IP6:MC:UDP:BABEL;${IP6:MC:UDP} && ${%BABEL} +IP6:MC:UDP:MANET;${IP6:MC:UDP} && ${%MANET} +IP6:MC:UDP:RESPONDD-QRY;${IP6:MC:UDP} && ${%RESPONDD-QRY} +IP6:MC:UDP:SYNCTHING-LPD;${IP6:MC:UDP} && ${%SYNCTHING-LPD} +IP6:MC:UDP:USTEER;${IP6:MC:UDP} && ${%USTEER} +IP6:MC:UDP:L3ROAMD;${IP6:MC:UDP} && ${%L3ROAMD} +IP6:MC:UDP:MMFD;${IP6:MC:UDP} && ${%MMFD} +IP6:MC:UDP:RETICULUM;${IP6:MC:UDP} && ${%RETICULUM} + +IP6:MC:HBH6;${IP6:MC} && ip6 proto 0 +IP6:MC:ICMP6;${IP6:MC} && ip6 proto 58 + +IP6:MC:HBH6:MLD;${IP6:MC:HBH6} and ip6[40] = 58 and ip6[41] = 0x00 and ip6[42:4] = 0x05020000 and (ip6[46:2] = 0x0000 or ip6[46:2] = 0x0100) +IP6:MC:HBH6:MLD:QUERY-V1;${IP6:MC:HBH6:MLD} and ip6[48] = 130 and ip6[4:2] = 0x0020 +IP6:MC:HBH6:MLD:QUERY-V1:GENERAL;${IP6:MC:HBH6:MLD:QUERY-V1} and ip6[56:4] = 0x00000000 and ip6[60:4] = 0x00000000 and ip6[64:4] = 0x00000000 and ip6[68:4] = 0x00000000 +IP6:MC:HBH6:MLD:QUERY-V1:ADDRSPEC;${IP6:MC:HBH6:MLD:QUERY-V1} and not (ip6[56:4] = 0x00000000 and ip6[60:4] = 0x00000000 and ip6[64:4] = 0x00000000 and ip6[68:4] = 0x00000000) +IP6:MC:HBH6:MLD:QUERY-V2;${IP6:MC:HBH6:MLD} and ip6[48] = 130 and ip6[4:2] >= 0x0024 +IP6:MC:HBH6:MLD:QUERY-V2:GENERAL;${IP6:MC:HBH6:MLD:QUERY-V2} and ip6[56:4] = 0x00000000 and ip6[60:4] = 0x00000000 and ip6[64:4] = 0x00000000 and ip6[68:4] = 0x00000000 +IP6:MC:HBH6:MLD:QUERY-V2:ADDRSPEC;${IP6:MC:HBH6:MLD:QUERY-V2} and not (ip6[56:4] = 0x00000000 and ip6[60:4] = 0x00000000 and ip6[64:4] = 0x00000000 and ip6[68:4] = 0x00000000) +IP6:MC:HBH6:MLD:QUERY-UNKNOWN;${IP6:MC:HBH6:MLD} and ip6[48] = 130 and not (ip6[4:2] = 0x0020 or ip6[4:2] >= 0x0024) +IP6:MC:HBH6:MLD:REPORT-V1;${IP6:MC:HBH6:MLD} and ip6[48] = 131 +IP6:MC:HBH6:MLD:DONE-V1;${IP6:MC:HBH6:MLD} and ip6[48] = 132 +IP6:MC:HBH6:MLD:REPORT-V2;${IP6:MC:HBH6:MLD} and ip6[48] = 143 +IP6:MC:HBH6:MLD:MRD-ADV;${IP6:MC:HBH6:MLD} and ip6[48] = 151 +IP6:MC:HBH6:MLD:MRD-SOL;${IP6:MC:HBH6:MLD} and ip6[48] = 152 +IP6:MC:HBH6:MLD:MRD-TERM;${IP6:MC:HBH6:MLD} and ip6[48] = 153 +IP6:MC:HBH6:OTHER;${IP6:MC:HBH6} and not ${IP6:MC:HBH6:MLD} + +IP6:MC:ICMP6:ECHOREQ;${IP6:MC:ICMP6} && icmp6[icmp6type] = icmp6-echo +IP6:MC:ICMP6:ECHOREP;${IP6:MC:ICMP6} && icmp6[icmp6type] = icmp6-echoreply +IP6:MC:ICMP6:NDSOL;${IP6:MC:ICMP6} && icmp6[icmp6type] = icmp6-neighborsolicit +IP6:MC:ICMP6:NDADV;${IP6:MC:ICMP6} && icmp6[icmp6type] = icmp6-neighboradvert +IP6:MC:ICMP6:NDADV:UNSOL;${IP6:MC:ICMP6:NDADV} and ip6 host ff02::1 +IP6:MC:ICMP6:NDADV:OTHER;${IP6:MC:ICMP6:NDADV} and not (ip6 host ff02::1) +IP6:MC:ICMP6:RTRSOL;${IP6:MC:ICMP6} && icmp6[icmp6type] = icmp6-routersolicit +IP6:MC:ICMP6:RTRADV;${IP6:MC:ICMP6} && icmp6[icmp6type] = icmp6-routeradvert +IP6:MC:ICMP6:OTHER;${IP6:MC:ICMP6} && not (${IP6:MC:ICMP6:ECHOREQ} || ${IP6:MC:ICMP6:ECHOREP} || ${IP6:MC:ICMP6:NDSOL} || ${IP6:MC:ICMP6:NDADV} || ${IP6:MC:ICMP6:RTRSOL} || ${IP6:MC:ICMP6:RTRADV}) + +BLA:CLAIM;${BLA} and arp[21:1] = 0x00 +BLA:UNCLAIM;${BLA} and arp[21:1] = 0x01 +BLA:ANNOUNCE;${BLA} and arp[21:1] = 0x02 +BLA:REQUEST;${BLA} and arp[21:1] = 0x03 +BLA:LOOPDETECT;${BLA} and arp[21:1] = 0x04 + +ARP:REQ;${ARP} and arp[6:2] = 0x0001 +ARP:REQ:UNSOL;${ARP:REQ} and arp[18:4] = 0xffffffff and arp[22:2] = 0xffff +ARP:REQ:OTHER;${ARP:REQ} and not (arp[18:4] = 0xffffffff and arp[22:2] = 0xffff) +ARP:REP;${ARP} and arp[6:2] = 0x0002 +ARP:REP:UNSOL;${ARP:REP} and arp[18:4] = 0xffffffff and arp[22:2] = 0xffff +ARP:REP:OTHER;${ARP:REP} and not (arp[18:4] = 0xffffffff and arp[22:2] = 0xffff) + +BAT;batadv +BAT:BAT-OGM_IV;batadv 15 iv_ogm +BAT:BAT-OGM_V;batadv 15 ogm2 +BAT:BAT-ELP;batadv 15 elp +BAT:BAT-UCAST;batadv 15 unicast +BAT:BAT-UCAST4;batadv 15 unicast_4addr +BAT:BAT-UCAST_FRAG;batadv 15 unicast_frag +BAT:BAT-UCAST_TVLV;batadv 15 unicast_tvlv +BAT:BAT-BCAST;batadv 15 bcast +BAT:BAT-ICMP;batadv 15 \icmp +BAT:BAT-CODED;batadv 15 coded +BAT:BAT-OTHER;batadv and not (${BAT:BAT-OGM_IV} || ${BAT:BAT-OGM_V} || ${BAT:BAT-ELP} || ${BAT:BAT-UCAST} || ${BAT:BAT-UCAST4} || ${BAT:BAT-UCAST_FRAG} || ${BAT:BAT-UCAST_TVLV} || ${BAT:BAT-BCAST} || ${BAT:BAT-ICMP} || ${BAT:BAT-CODED}) + + +BAT:BAT-BCAST:IP4;${BAT:BAT-BCAST} && ${IP4} +BAT:BAT-BCAST:IP6;${BAT:BAT-BCAST} && ${IP6} +BAT:BAT-BCAST:BLA;${BAT:BAT-BCAST} && ${BLA} +BAT:BAT-BCAST:ARP;${BAT:BAT-BCAST} && ${ARP} +BAT:BAT-BCAST:IPX;${BAT:BAT-BCAST} && ${IPX} +BAT:BAT-BCAST:NETBEUI;${BAT:BAT-BCAST} && ${NETBEUI} +BAT:BAT-BCAST:LLDP;${BAT:BAT-BCAST} && ${LLDP} +BAT:BAT-BCAST:OTHER;${BAT:BAT-BCAST} && not (${BAT:BAT-BCAST:IP4} || ${BAT:BAT-BCAST:IP6} || ${BAT:BAT-BCAST:BLA} || ${BAT:BAT-BCAST:ARP} || ${BAT:BAT-BCAST:IPX} || ${BAT:BAT-BCAST:NETBEUI} || ${BAT:BAT-BCAST:LLDP}) + +BAT:BAT-UCAST:IP4;${BAT:BAT-UCAST} && ${IP4} +BAT:BAT-UCAST:IP6;${BAT:BAT-UCAST} && ${IP6} +BAT:BAT-UCAST:BLA;${BAT:BAT-UCAST} && ${BLA} +BAT:BAT-UCAST:ARP;${BAT:BAT-UCAST} && ${ARP} +BAT:BAT-UCAST:IPX;${BAT:BAT-UCAST} && ${IPX} +BAT:BAT-UCAST:NETBEUI;${BAT:BAT-UCAST} && ${NETBEUI} +BAT:BAT-UCAST:LLDP;${BAT:BAT-UCAST} && ${LLDP} +BAT:BAT-UCAST:OTHER;${BAT:BAT-UCAST} && not (${BAT:BAT-UCAST:IP4} || ${BAT:BAT-UCAST:IP6} || ${BAT:BAT-UCAST:BLA} || ${BAT:BAT-UCAST:ARP} || ${BAT:BAT-UCAST:IPX} || ${BAT:BAT-UCAST:NETBEUI} || ${BAT:BAT-UCAST:LLDP}) + +BAT:BAT-UCAST4:IP4;${BAT:BAT-UCAST4} && ${IP4} +BAT:BAT-UCAST4:IP6;${BAT:BAT-UCAST4} && ${IP6} +BAT:BAT-UCAST4:BLA;${BAT:BAT-UCAST4} && ${BLA} +BAT:BAT-UCAST4:ARP;${BAT:BAT-UCAST4} && ${ARP} +BAT:BAT-UCAST4:IPX;${BAT:BAT-UCAST4} && ${IPX} +BAT:BAT-UCAST4:NETBEUI;${BAT:BAT-UCAST4} && ${NETBEUI} +BAT:BAT-UCAST4:LLDP;${BAT:BAT-UCAST4} && ${LLDP} +BAT:BAT-UCAST4:OTHER;${BAT:BAT-UCAST4} && not (${BAT:BAT-UCAST4:IP4} || ${BAT:BAT-UCAST4:IP6} || ${BAT:BAT-UCAST4:BLA} || ${BAT:BAT-UCAST4:ARP} || ${BAT:BAT-UCAST4:IPX} || ${BAT:BAT-UCAST4:NETBEUI} || ${BAT:BAT-UCAST4:LLDP}) + +BAT:BAT-UCAST_TVLV:IP4;${BAT:BAT-UCAST_TVLV} && ${IP4} +BAT:BAT-UCAST_TVLV:IP6;${BAT:BAT-UCAST_TVLV} && ${IP6} +BAT:BAT-UCAST_TVLV:BLA;${BAT:BAT-UCAST_TVLV} && ${BLA} +BAT:BAT-UCAST_TVLV:ARP;${BAT:BAT-UCAST_TVLV} && ${ARP} +BAT:BAT-UCAST_TVLV:IPX;${BAT:BAT-UCAST_TVLV} && ${IPX} +BAT:BAT-UCAST_TVLV:NETBEUI;${BAT:BAT-UCAST_TVLV} && ${NETBEUI} +BAT:BAT-UCAST_TVLV:LLDP;${BAT:BAT-UCAST_TVLV} && ${LLDP} +BAT:BAT-UCAST_TVLV:OTHER;${BAT:BAT-UCAST_TVLV} && not (${BAT:BAT-UCAST_TVLV:IP4} || ${BAT:BAT-UCAST_TVLV:IP6} || ${BAT:BAT-UCAST_TVLV:BLA} || ${BAT:BAT-UCAST_TVLV:ARP} || ${BAT:BAT-UCAST_TVLV:IPX} || ${BAT:BAT-UCAST_TVLV:NETBEUI} || ${BAT:BAT-UCAST_TVLV:LLDP}) + + +BAT:BAT-BCAST:IP4:IGMP;${BAT:BAT-BCAST} && ${IP4:IGMP} +BAT:BAT-BCAST:IP4:IGMP:QUERY-V1;${BAT:BAT-BCAST} && ${IP4:IGMP:QUERY-V1} +BAT:BAT-BCAST:IP4:IGMP:QUERY-V2;${BAT:BAT-BCAST} && ${IP4:IGMP:QUERY-V2} +BAT:BAT-BCAST:IP4:IGMP:QUERY-V3;${BAT:BAT-BCAST} && ${IP4:IGMP:QUERY-V3} +BAT:BAT-BCAST:IP4:IGMP:QUERY-UNKNOWN;${BAT:BAT-BCAST} && ${IP4:IGMP:QUERY-UNKNOWN} +BAT:BAT-BCAST:IP4:IGMP:REPORT-V1;${BAT:BAT-BCAST} && ${IP4:IGMP:REPORT-V1} +BAT:BAT-BCAST:IP4:IGMP:REPORT-V2;${BAT:BAT-BCAST} && ${IP4:IGMP:REPORT-V2} +BAT:BAT-BCAST:IP4:IGMP:LEAVE-V2;${BAT:BAT-BCAST} && ${IP4:IGMP:LEAVE-V2} +BAT:BAT-BCAST:IP4:IGMP:REPORT-V3;${BAT:BAT-BCAST} && ${IP4:IGMP:REPORT-V3} +BAT:BAT-BCAST:IP4:IGMP:MRD-ADV;${BAT:BAT-BCAST} && ${IP4:IGMP:MRD-ADV} +BAT:BAT-BCAST:IP4:IGMP:MRD-SOL;${BAT:BAT-BCAST} && ${IP4:IGMP:MRD-SOL} +BAT:BAT-BCAST:IP4:IGMP:MRD-TERM;${BAT:BAT-BCAST} && ${IP4:IGMP:MRD-TERM} + +BAT:BAT-BCAST:IP4:MC;${BAT:BAT-BCAST} && ${IP4:MC} +BAT:BAT-BCAST:IP4:MC:PIM;${BAT:BAT-BCAST} && ${IP4:MC:PIM} +BAT:BAT-BCAST:IP4:MC:OSPF;${BAT:BAT-BCAST} && ${IP4:MC:OSPF} +BAT:BAT-BCAST:IP4:MC:MANET;${BAT:BAT-BCAST} && ${IP4:MC:MANET} +BAT:BAT-BCAST:IP4:MC:UDP;${BAT:BAT-BCAST} && ${IP4:MC:UDP} + +BAT:BAT-BCAST:IP4:MC:UDP:SSDP;${BAT:BAT-BCAST:IP4:MC:UDP} && ${%SSDP} +BAT:BAT-BCAST:IP4:MC:UDP:LLMNR;${BAT:BAT-BCAST:IP4:MC:UDP} && ${%LLMNR} +BAT:BAT-BCAST:IP4:MC:UDP:MDNS;${BAT:BAT-BCAST:IP4:MC:UDP} && ${%MDNS} +BAT:BAT-BCAST:IP4:MC:UDP:NB-NS;${BAT:BAT-BCAST:IP4:MC:UDP} && ${%NB-NS} +BAT:BAT-BCAST:IP4:MC:UDP:NB-DGM;${BAT:BAT-BCAST:IP4:MC:UDP} && ${%NB-DGM} +BAT:BAT-BCAST:IP4:MC:UDP:DP-LSP;${BAT:BAT-BCAST:IP4:MC:UDP} && ${%DP-LSP} +BAT:BAT-BCAST:IP4:MC:UDP:TRAP-DAEMON;${BAT:BAT-BCAST:IP4:MC:UDP} && ${%TRAP-DAEMON} +BAT:BAT-BCAST:IP4:MC:UDP:DHCP4;${BAT:BAT-BCAST:IP4:MC:UDP} && ${%DHCP4} +BAT:BAT-BCAST:IP4:MC:UDP:DHCP6;${BAT:BAT-BCAST:IP4:MC:UDP} && ${%DHCP6} +BAT:BAT-BCAST:IP4:MC:UDP:WS-DISC;${BAT:BAT-BCAST:IP4:MC:UDP} && ${%WS-DISC} +BAT:BAT-BCAST:IP4:MC:UDP:WSP;${BAT:BAT-BCAST:IP4:MC:UDP} && ${%WSP} +BAT:BAT-BCAST:IP4:MC:UDP:TEREDO;${BAT:BAT-BCAST:IP4:MC:UDP} && ${%TEREDO} +BAT:BAT-BCAST:IP4:MC:UDP:SPOTIFY;${BAT:BAT-BCAST:IP4:MC:UDP} && ${%SPOTIFY} +BAT:BAT-BCAST:IP4:MC:UDP:SIP;${BAT:BAT-BCAST:IP4:MC:UDP} && ${%SIP} +BAT:BAT-BCAST:IP4:MC:UDP:BT-LPD;${BAT:BAT-BCAST:IP4:MC:UDP} && ${%BT-LPD} +BAT:BAT-BCAST:IP4:MC:UDP:NVBM;${BAT:BAT-BCAST:IP4:MC:UDP} && ${%NVBM} +BAT:BAT-BCAST:IP4:MC:UDP:SVRLOC;${BAT:BAT-BCAST:IP4:MC:UDP} && ${%SVRLOC} +BAT:BAT-BCAST:IP4:MC:UDP:ENPC;${BAT:BAT-BCAST:IP4:MC:UDP} && ${%ENPC} +BAT:BAT-BCAST:IP4:MC:UDP:QTSTREAM;${BAT:BAT-BCAST:IP4:MC:UDP} && ${%QTSTREAM} +BAT:BAT-BCAST:IP4:MC:UDP:HDHOMERUN;${BAT:BAT-BCAST:IP4:MC:UDP} && ${%HDHOMERUN} +BAT:BAT-BCAST:IP4:MC:UDP:PLEX-DISC0;${BAT:BAT-BCAST:IP4:MC:UDP} && ${%PLEX-DISC0} +BAT:BAT-BCAST:IP4:MC:UDP:PLEX-DISC2;${BAT:BAT-BCAST:IP4:MC:UDP} && ${%PLEX-DISC2} +BAT:BAT-BCAST:IP4:MC:UDP:PLEX-DISC3;${BAT:BAT-BCAST:IP4:MC:UDP} && ${%PLEX-DISC3} +BAT:BAT-BCAST:IP4:MC:UDP:PLEX-DISC4;${BAT:BAT-BCAST:IP4:MC:UDP} && ${%PLEX-DISC4} +BAT:BAT-BCAST:IP4:MC:UDP:BT-UTP;${BAT:BAT-BCAST:IP4:MC:UDP} && ${%BT-UTP} +BAT:BAT-BCAST:IP4:MC:UDP:WF-BSSERV;${BAT:BAT-BCAST:IP4:MC:UDP} && ${%WF-BSSERV} +BAT:BAT-BCAST:IP4:MC:UDP:FAXIMUM;${BAT:BAT-BCAST:IP4:MC:UDP} && ${%FAXIMUM} +BAT:BAT-BCAST:IP4:MC:UDP:TOMCAT;${BAT:BAT-BCAST:IP4:MC:UDP} && ${%TOMCAT} +BAT:BAT-BCAST:IP4:MC:UDP:DISTINCT;${BAT:BAT-BCAST:IP4:MC:UDP} && ${%DISTINCT} +BAT:BAT-BCAST:IP4:MC:UDP:UDP-25412;${BAT:BAT-BCAST:IP4:MC:UDP} && ${%UDP-25412} +BAT:BAT-BCAST:IP4:MC:UDP:UDP-10203;${BAT:BAT-BCAST:IP4:MC:UDP} && ${%UDP-10203} +BAT:BAT-BCAST:IP4:MC:UDP:UDP-60128;${BAT:BAT-BCAST:IP4:MC:UDP} && ${%UDP-60128} +BAT:BAT-BCAST:IP4:MC:UDP:COREL-VNC;${BAT:BAT-BCAST:IP4:MC:UDP} && ${%COREL-VNC} +BAT:BAT-BCAST:IP4:MC:UDP:HPVMMCTRL;${BAT:BAT-BCAST:IP4:MC:UDP} && ${%HPVMMCTRL} +BAT:BAT-BCAST:IP4:MC:UDP:CBT;${BAT:BAT-BCAST:IP4:MC:UDP} && ${%CBT} +BAT:BAT-BCAST:IP4:MC:UDP:MCAFEE;${BAT:BAT-BCAST:IP4:MC:UDP} && ${%MCAFEE} +BAT:BAT-BCAST:IP4:MC:UDP:UDP-39455;${BAT:BAT-BCAST:IP4:MC:UDP} && ${%UDP-39455} +BAT:BAT-BCAST:IP4:MC:UDP:UDP-889;${BAT:BAT-BCAST:IP4:MC:UDP} && ${%UDP-889} +BAT:BAT-BCAST:IP4:MC:UDP:UDP-16962;${BAT:BAT-BCAST:IP4:MC:UDP} && ${%UDP-16962} +BAT:BAT-BCAST:IP4:MC:UDP:TSEQ;${BAT:BAT-BCAST:IP4:MC:UDP} && ${%TSEQ} +BAT:BAT-BCAST:IP4:MC:UDP:CANON-BJNP;${BAT:BAT-BCAST:IP4:MC:UDP} && ${%CANON-BJNP} +BAT:BAT-BCAST:IP4:MC:UDP:RIP;${BAT:BAT-BCAST:IP4:MC:UDP} && ${%RIP} +BAT:BAT-BCAST:IP4:MC:UDP:RIPNG;${BAT:BAT-BCAST:IP4:MC:UDP} && ${%RIPNG} +BAT:BAT-BCAST:IP4:MC:UDP:OLSRV1;${BAT:BAT-BCAST:IP4:MC:UDP} && ${%OLSRV1} +BAT:BAT-BCAST:IP4:MC:UDP:BABEL;${BAT:BAT-BCAST:IP4:MC:UDP} && ${%BABEL} +BAT:BAT-BCAST:IP4:MC:UDP:MANET;${BAT:BAT-BCAST:IP4:MC:UDP} && ${%MANET} +BAT:BAT-BCAST:IP4:MC:UDP:RESPONDD-QRY;${BAT:BAT-BCAST:IP4:MC:UDP} && ${%RESPONDD-QRY} +BAT:BAT-BCAST:IP4:MC:UDP:SYNCTHING-LPD;${BAT:BAT-BCAST:IP4:MC:UDP} && ${%SYNCTHING-LPD} +BAT:BAT-BCAST:IP4:MC:UDP:USTEER;${BAT:BAT-BCAST:IP4:MC:UDP} && ${%USTEER} +BAT:BAT-BCAST:IP4:MC:UDP:L3ROAMD;${BAT:BAT-BCAST:IP4:MC:UDP} && ${%L3ROAMD} +BAT:BAT-BCAST:IP4:MC:UDP:MMFD;${BAT:BAT-BCAST:IP4:MC:UDP} && ${%MMFD} +BAT:BAT-BCAST:IP4:MC:UDP:RETICULUM;${BAT:BAT-BCAST:IP4:MC:UDP} && ${%RETICULUM} + +BAT:BAT-BCAST:IP6:MC;${BAT:BAT-BCAST} && ${IP6:MC} +BAT:BAT-BCAST:IP6:MC:PIM;${BAT:BAT-BCAST} && ${IP6:MC:PIM} +BAT:BAT-BCAST:IP6:MC:OSPF;${BAT:BAT-BCAST} && ${IP6:MC:OSPF} +BAT:BAT-BCAST:IP6:MC:MANET;${BAT:BAT-BCAST} && ${IP6:MC:MANET} +BAT:BAT-BCAST:IP6:MC:UDP;${BAT:BAT-BCAST} && ${IP6:MC:UDP} + +BAT:BAT-BCAST:IP6:MC:UDP:SSDP;${BAT:BAT-BCAST:IP6:MC:UDP} && ${%SSDP} +BAT:BAT-BCAST:IP6:MC:UDP:LLMNR;${BAT:BAT-BCAST:IP6:MC:UDP} && ${%LLMNR} +BAT:BAT-BCAST:IP6:MC:UDP:MDNS;${BAT:BAT-BCAST:IP6:MC:UDP} && ${%MDNS} +BAT:BAT-BCAST:IP6:MC:UDP:NB-NS;${BAT:BAT-BCAST:IP6:MC:UDP} && ${%NB-NS} +BAT:BAT-BCAST:IP6:MC:UDP:NB-DGM;${BAT:BAT-BCAST:IP6:MC:UDP} && ${%NB-DGM} +BAT:BAT-BCAST:IP6:MC:UDP:DP-LSP;${BAT:BAT-BCAST:IP6:MC:UDP} && ${%DP-LSP} +BAT:BAT-BCAST:IP6:MC:UDP:TRAP-DAEMON;${BAT:BAT-BCAST:IP6:MC:UDP} && ${%TRAP-DAEMON} +BAT:BAT-BCAST:IP6:MC:UDP:DHCP4;${BAT:BAT-BCAST:IP6:MC:UDP} && ${%DHCP4} +BAT:BAT-BCAST:IP6:MC:UDP:DHCP6;${BAT:BAT-BCAST:IP6:MC:UDP} && ${%DHCP6} +BAT:BAT-BCAST:IP6:MC:UDP:WS-DISC;${BAT:BAT-BCAST:IP6:MC:UDP} && ${%WS-DISC} +BAT:BAT-BCAST:IP6:MC:UDP:WSP;${BAT:BAT-BCAST:IP6:MC:UDP} && ${%WSP} +BAT:BAT-BCAST:IP6:MC:UDP:TEREDO;${BAT:BAT-BCAST:IP6:MC:UDP} && ${%TEREDO} +BAT:BAT-BCAST:IP6:MC:UDP:SPOTIFY;${BAT:BAT-BCAST:IP6:MC:UDP} && ${%SPOTIFY} +BAT:BAT-BCAST:IP6:MC:UDP:SIP;${BAT:BAT-BCAST:IP6:MC:UDP} && ${%SIP} +BAT:BAT-BCAST:IP6:MC:UDP:BT-LPD;${BAT:BAT-BCAST:IP6:MC:UDP} && ${%BT-LPD} +BAT:BAT-BCAST:IP6:MC:UDP:NVBM;${BAT:BAT-BCAST:IP6:MC:UDP} && ${%NVBM} +BAT:BAT-BCAST:IP6:MC:UDP:SVRLOC;${BAT:BAT-BCAST:IP6:MC:UDP} && ${%SVRLOC} +BAT:BAT-BCAST:IP6:MC:UDP:ENPC;${BAT:BAT-BCAST:IP6:MC:UDP} && ${%ENPC} +BAT:BAT-BCAST:IP6:MC:UDP:QTSTREAM;${BAT:BAT-BCAST:IP6:MC:UDP} && ${%QTSTREAM} +BAT:BAT-BCAST:IP6:MC:UDP:HDHOMERUN;${BAT:BAT-BCAST:IP6:MC:UDP} && ${%HDHOMERUN} +BAT:BAT-BCAST:IP6:MC:UDP:PLEX-DISC0;${BAT:BAT-BCAST:IP6:MC:UDP} && ${%PLEX-DISC0} +BAT:BAT-BCAST:IP6:MC:UDP:PLEX-DISC2;${BAT:BAT-BCAST:IP6:MC:UDP} && ${%PLEX-DISC2} +BAT:BAT-BCAST:IP6:MC:UDP:PLEX-DISC3;${BAT:BAT-BCAST:IP6:MC:UDP} && ${%PLEX-DISC3} +BAT:BAT-BCAST:IP6:MC:UDP:PLEX-DISC4;${BAT:BAT-BCAST:IP6:MC:UDP} && ${%PLEX-DISC4} +BAT:BAT-BCAST:IP6:MC:UDP:BT-UTP;${BAT:BAT-BCAST:IP6:MC:UDP} && ${%BT-UTP} +BAT:BAT-BCAST:IP6:MC:UDP:WF-BSSERV;${BAT:BAT-BCAST:IP6:MC:UDP} && ${%WF-BSSERV} +BAT:BAT-BCAST:IP6:MC:UDP:FAXIMUM;${BAT:BAT-BCAST:IP6:MC:UDP} && ${%FAXIMUM} +BAT:BAT-BCAST:IP6:MC:UDP:TOMCAT;${BAT:BAT-BCAST:IP6:MC:UDP} && ${%TOMCAT} +BAT:BAT-BCAST:IP6:MC:UDP:DISTINCT;${BAT:BAT-BCAST:IP6:MC:UDP} && ${%DISTINCT} +BAT:BAT-BCAST:IP6:MC:UDP:UDP-25412;${BAT:BAT-BCAST:IP6:MC:UDP} && ${%UDP-25412} +BAT:BAT-BCAST:IP6:MC:UDP:UDP-10203;${BAT:BAT-BCAST:IP6:MC:UDP} && ${%UDP-10203} +BAT:BAT-BCAST:IP6:MC:UDP:UDP-60128;${BAT:BAT-BCAST:IP6:MC:UDP} && ${%UDP-60128} +BAT:BAT-BCAST:IP6:MC:UDP:COREL-VNC;${BAT:BAT-BCAST:IP6:MC:UDP} && ${%COREL-VNC} +BAT:BAT-BCAST:IP6:MC:UDP:HPVMMCTRL;${BAT:BAT-BCAST:IP6:MC:UDP} && ${%HPVMMCTRL} +BAT:BAT-BCAST:IP6:MC:UDP:CBT;${BAT:BAT-BCAST:IP6:MC:UDP} && ${%CBT} +BAT:BAT-BCAST:IP6:MC:UDP:MCAFEE;${BAT:BAT-BCAST:IP6:MC:UDP} && ${%MCAFEE} +BAT:BAT-BCAST:IP6:MC:UDP:UDP-39455;${BAT:BAT-BCAST:IP6:MC:UDP} && ${%UDP-39455} +BAT:BAT-BCAST:IP6:MC:UDP:UDP-889;${BAT:BAT-BCAST:IP6:MC:UDP} && ${%UDP-889} +BAT:BAT-BCAST:IP6:MC:UDP:UDP-16962;${BAT:BAT-BCAST:IP6:MC:UDP} && ${%UDP-16962} +BAT:BAT-BCAST:IP6:MC:UDP:TSEQ;${BAT:BAT-BCAST:IP6:MC:UDP} && ${%TSEQ} +BAT:BAT-BCAST:IP6:MC:UDP:CANON-BJNP;${BAT:BAT-BCAST:IP6:MC:UDP} && ${%CANON-BJNP} +BAT:BAT-BCAST:IP6:MC:UDP:RIP;${BAT:BAT-BCAST:IP6:MC:UDP} && ${%RIP} +BAT:BAT-BCAST:IP6:MC:UDP:RIPNG;${BAT:BAT-BCAST:IP6:MC:UDP} && ${%RIPNG} +BAT:BAT-BCAST:IP6:MC:UDP:OLSRV1;${BAT:BAT-BCAST:IP6:MC:UDP} && ${%OLSRV1} +BAT:BAT-BCAST:IP6:MC:UDP:BABEL;${BAT:BAT-BCAST:IP6:MC:UDP} && ${%BABEL} +BAT:BAT-BCAST:IP6:MC:UDP:MANET;${BAT:BAT-BCAST:IP6:MC:UDP} && ${%MANET} +BAT:BAT-BCAST:IP6:MC:UDP:RESPONDD-QRY;${BAT:BAT-BCAST:IP6:MC:UDP} && ${%RESPONDD-QRY} +BAT:BAT-BCAST:IP6:MC:UDP:SYNCTHING-LPD;${BAT:BAT-BCAST:IP6:MC:UDP} && ${%SYNCTHING-LPD} +BAT:BAT-BCAST:IP6:MC:UDP:USTEER;${BAT:BAT-BCAST:IP6:MC:UDP} && ${%USTEER} +BAT:BAT-BCAST:IP6:MC:UDP:L3ROAMD;${BAT:BAT-BCAST:IP6:MC:UDP} && ${%L3ROAMD} +BAT:BAT-BCAST:IP6:MC:UDP:MMFD;${BAT:BAT-BCAST:IP6:MC:UDP} && ${%MMFD} +BAT:BAT-BCAST:IP6:MC:UDP:RETICULUM;${BAT:BAT-BCAST:IP6:MC:UDP} && ${%RETICULUM} + +BAT:BAT-BCAST:IP6:MC:HBH6;${BAT:BAT-BCAST} && ${IP6:MC:HBH6} +BAT:BAT-BCAST:IP6:MC:ICMP6;${BAT:BAT-BCAST} && ${IP6:MC:ICMP6} + +BAT:BAT-BCAST:IP6:MC:HBH6:MLD;${BAT:BAT-BCAST} && ${IP6:MC:HBH6:MLD} +BAT:BAT-BCAST:IP6:MC:HBH6:MLD:QUERY-V1;${BAT:BAT-BCAST} && ${IP6:MC:HBH6:MLD:QUERY-V1} +BAT:BAT-BCAST:IP6:MC:HBH6:MLD:QUERY-V1:GENERAL;${BAT:BAT-BCAST} && ${IP6:MC:HBH6:MLD:QUERY-V1:GENERAL} +BAT:BAT-BCAST:IP6:MC:HBH6:MLD:QUERY-V1:ADDRSPEC;${BAT:BAT-BCAST} && ${IP6:MC:HBH6:MLD:QUERY-V1:ADDRSPEC} +BAT:BAT-BCAST:IP6:MC:HBH6:MLD:QUERY-V2;${BAT:BAT-BCAST} && ${IP6:MC:HBH6:MLD:QUERY-V2} +BAT:BAT-BCAST:IP6:MC:HBH6:MLD:QUERY-V2:GENERAL;${BAT:BAT-BCAST} && ${IP6:MC:HBH6:MLD:QUERY-V2:GENERAL} +BAT:BAT-BCAST:IP6:MC:HBH6:MLD:QUERY-V2:ADDRSPEC;${BAT:BAT-BCAST} && ${IP6:MC:HBH6:MLD:QUERY-V2:ADDRSPEC} +BAT:BAT-BCAST:IP6:MC:HBH6:MLD:QUERY-UNKNOWN;${BAT:BAT-BCAST} && ${IP6:MC:HBH6:MLD:QUERY-UNKNOWN} +BAT:BAT-BCAST:IP6:MC:HBH6:MLD:REPORT-V1;${BAT:BAT-BCAST} && ${IP6:MC:HBH6:MLD:REPORT-V1} +BAT:BAT-BCAST:IP6:MC:HBH6:MLD:DONE-V1;${BAT:BAT-BCAST} && ${IP6:MC:HBH6:MLD:DONE-V1} +BAT:BAT-BCAST:IP6:MC:HBH6:MLD:REPORT-V2;${BAT:BAT-BCAST} && ${IP6:MC:HBH6:MLD:REPORT-V2} +BAT:BAT-BCAST:IP6:MC:HBH6:MLD:MRD-ADV;${BAT:BAT-BCAST} && ${IP6:MC:HBH6:MLD:MRD-ADV} +BAT:BAT-BCAST:IP6:MC:HBH6:MLD:MRD-SOL;${BAT:BAT-BCAST} && ${IP6:MC:HBH6:MLD:MRD-SOL} +BAT:BAT-BCAST:IP6:MC:HBH6:MLD:MRD-TERM;${BAT:BAT-BCAST} && ${IP6:MC:HBH6:MLD:MRD-TERM} +BAT:BAT-BCAST:IP6:MC:HBH6:OTHER;${BAT:BAT-BCAST} && ${IP6:MC:HBH6} and not (${BAT:BAT-BCAST:IP6:MC:HBH6:MLD}) + +BAT:BAT-BCAST:IP6:MC:ICMP6:ECHOREQ;${BAT:BAT-BCAST} && ${IP6:MC:ICMP6:ECHOREQ} +BAT:BAT-BCAST:IP6:MC:ICMP6:ECHOREP;${BAT:BAT-BCAST} && ${IP6:MC:ICMP6:ECHOREP} +BAT:BAT-BCAST:IP6:MC:ICMP6:NDSOL;${BAT:BAT-BCAST} && ${IP6:MC:ICMP6:NDSOL} +BAT:BAT-BCAST:IP6:MC:ICMP6:NDADV;${BAT:BAT-BCAST} && ${IP6:MC:ICMP6:NDADV} +BAT:BAT-BCAST:IP6:MC:ICMP6:NDADV:UNSOL;${BAT:BAT-BCAST} and ${IP6:MC:ICMP6:NDADV:UNSOL} +BAT:BAT-BCAST:IP6:MC:ICMP6:NDADV:OTHER;${BAT:BAT-BCAST} and ${IP6:MC:ICMP6:NDADV:OTHER} +BAT:BAT-BCAST:IP6:MC:ICMP6:RTRSOL;${BAT:BAT-BCAST} && ${IP6:MC:ICMP6:RTRSOL} +BAT:BAT-BCAST:IP6:MC:ICMP6:RTRADV;${BAT:BAT-BCAST} && ${IP6:MC:ICMP6:RTRADV} +BAT:BAT-BCAST:IP6:MC:ICMP6:OTHER;${BAT:BAT-BCAST} && ${IP6:MC:ICMP6:OTHER} + +BAT:BAT-BCAST:BLA:CLAIM;${BAT:BAT-BCAST} and ${BLA:CLAIM} +BAT:BAT-BCAST:BLA:UNCLAIM;${BAT:BAT-BCAST} and ${BLA:UNCLAIM} +BAT:BAT-BCAST:BLA:ANNOUNCE;${BAT:BAT-BCAST} and ${BLA:ANNOUNCE} +BAT:BAT-BCAST:BLA:REQUEST;${BAT:BAT-BCAST} and ${BLA:REQUEST} +BAT:BAT-BCAST:BLA:LOOPDETECT;${BAT:BAT-BCAST} and ${BLA:LOOPDETECT} + +BAT:BAT-BCAST:ARP:REQ;${BAT:BAT-BCAST} and ${ARP:REQ} +BAT:BAT-BCAST:ARP:REQ:UNSOL;${BAT:BAT-BCAST} and ${ARP:REQ:UNSOL} +BAT:BAT-BCAST:ARP:REQ:OTHER;${BAT:BAT-BCAST} and ${ARP:REQ:OTHER} +BAT:BAT-BCAST:ARP:REP;${BAT:BAT-BCAST} and ${ARP:REP} +BAT:BAT-BCAST:ARP:REP:UNSOL;${BAT:BAT-BCAST} and ${ARP:REP:UNSOL} +BAT:BAT-BCAST:ARP:REP:OTHER;${BAT:BAT-BCAST} and ${ARP:REP:OTHER} + + +BAT:BAT-UCAST:IP4:MC;${BAT:BAT-UCAST} && ${IP4:MC} +BAT:BAT-UCAST:IP4:MC:PIM;${BAT:BAT-UCAST} && ${IP4:MC:PIM} +BAT:BAT-UCAST:IP4:MC:OSPF;${BAT:BAT-UCAST} && ${IP4:MC:OSPF} +BAT:BAT-UCAST:IP4:MC:MANET;${BAT:BAT-UCAST} && ${IP4:MC:MANET} +BAT:BAT-UCAST:IP4:MC:UDP;${BAT:BAT-UCAST} && ${IP4:MC:UDP} + +BAT:BAT-UCAST:IP4:MC:UDP:SSDP;${BAT:BAT-UCAST:IP4:MC:UDP} && ${%SSDP} +BAT:BAT-UCAST:IP4:MC:UDP:LLMNR;${BAT:BAT-UCAST:IP4:MC:UDP} && ${%LLMNR} +BAT:BAT-UCAST:IP4:MC:UDP:MDNS;${BAT:BAT-UCAST:IP4:MC:UDP} && ${%MDNS} +BAT:BAT-UCAST:IP4:MC:UDP:NB-NS;${BAT:BAT-UCAST:IP4:MC:UDP} && ${%NB-NS} +BAT:BAT-UCAST:IP4:MC:UDP:NB-DGM;${BAT:BAT-UCAST:IP4:MC:UDP} && ${%NB-DGM} +BAT:BAT-UCAST:IP4:MC:UDP:DP-LSP;${BAT:BAT-UCAST:IP4:MC:UDP} && ${%DP-LSP} +BAT:BAT-UCAST:IP4:MC:UDP:TRAP-DAEMON;${BAT:BAT-UCAST:IP4:MC:UDP} && ${%TRAP-DAEMON} +BAT:BAT-UCAST:IP4:MC:UDP:DHCP4;${BAT:BAT-UCAST:IP4:MC:UDP} && ${%DHCP4} +BAT:BAT-UCAST:IP4:MC:UDP:DHCP6;${BAT:BAT-UCAST:IP4:MC:UDP} && ${%DHCP6} +BAT:BAT-UCAST:IP4:MC:UDP:WS-DISC;${BAT:BAT-UCAST:IP4:MC:UDP} && ${%WS-DISC} +BAT:BAT-UCAST:IP4:MC:UDP:WSP;${BAT:BAT-UCAST:IP4:MC:UDP} && ${%WSP} +BAT:BAT-UCAST:IP4:MC:UDP:TEREDO;${BAT:BAT-UCAST:IP4:MC:UDP} && ${%TEREDO} +BAT:BAT-UCAST:IP4:MC:UDP:SPOTIFY;${BAT:BAT-UCAST:IP4:MC:UDP} && ${%SPOTIFY} +BAT:BAT-UCAST:IP4:MC:UDP:SIP;${BAT:BAT-UCAST:IP4:MC:UDP} && ${%SIP} +BAT:BAT-UCAST:IP4:MC:UDP:BT-LPD;${BAT:BAT-UCAST:IP4:MC:UDP} && ${%BT-LPD} +BAT:BAT-UCAST:IP4:MC:UDP:NVBM;${BAT:BAT-UCAST:IP4:MC:UDP} && ${%NVBM} +BAT:BAT-UCAST:IP4:MC:UDP:SVRLOC;${BAT:BAT-UCAST:IP4:MC:UDP} && ${%SVRLOC} +BAT:BAT-UCAST:IP4:MC:UDP:ENPC;${BAT:BAT-UCAST:IP4:MC:UDP} && ${%ENPC} +BAT:BAT-UCAST:IP4:MC:UDP:QTSTREAM;${BAT:BAT-UCAST:IP4:MC:UDP} && ${%QTSTREAM} +BAT:BAT-UCAST:IP4:MC:UDP:HDHOMERUN;${BAT:BAT-UCAST:IP4:MC:UDP} && ${%HDHOMERUN} +BAT:BAT-UCAST:IP4:MC:UDP:PLEX-DISC0;${BAT:BAT-UCAST:IP4:MC:UDP} && ${%PLEX-DISC0} +BAT:BAT-UCAST:IP4:MC:UDP:PLEX-DISC2;${BAT:BAT-UCAST:IP4:MC:UDP} && ${%PLEX-DISC2} +BAT:BAT-UCAST:IP4:MC:UDP:PLEX-DISC3;${BAT:BAT-UCAST:IP4:MC:UDP} && ${%PLEX-DISC3} +BAT:BAT-UCAST:IP4:MC:UDP:PLEX-DISC4;${BAT:BAT-UCAST:IP4:MC:UDP} && ${%PLEX-DISC4} +BAT:BAT-UCAST:IP4:MC:UDP:BT-UTP;${BAT:BAT-UCAST:IP4:MC:UDP} && ${%BT-UTP} +BAT:BAT-UCAST:IP4:MC:UDP:WF-BSSERV;${BAT:BAT-UCAST:IP4:MC:UDP} && ${%WF-BSSERV} +BAT:BAT-UCAST:IP4:MC:UDP:FAXIMUM;${BAT:BAT-UCAST:IP4:MC:UDP} && ${%FAXIMUM} +BAT:BAT-UCAST:IP4:MC:UDP:TOMCAT;${BAT:BAT-UCAST:IP4:MC:UDP} && ${%TOMCAT} +BAT:BAT-UCAST:IP4:MC:UDP:DISTINCT;${BAT:BAT-UCAST:IP4:MC:UDP} && ${%DISTINCT} +BAT:BAT-UCAST:IP4:MC:UDP:UDP-25412;${BAT:BAT-UCAST:IP4:MC:UDP} && ${%UDP-25412} +BAT:BAT-UCAST:IP4:MC:UDP:UDP-10203;${BAT:BAT-UCAST:IP4:MC:UDP} && ${%UDP-10203} +BAT:BAT-UCAST:IP4:MC:UDP:UDP-60128;${BAT:BAT-UCAST:IP4:MC:UDP} && ${%UDP-60128} +BAT:BAT-UCAST:IP4:MC:UDP:COREL-VNC;${BAT:BAT-UCAST:IP4:MC:UDP} && ${%COREL-VNC} +BAT:BAT-UCAST:IP4:MC:UDP:HPVMMCTRL;${BAT:BAT-UCAST:IP4:MC:UDP} && ${%HPVMMCTRL} +BAT:BAT-UCAST:IP4:MC:UDP:CBT;${BAT:BAT-UCAST:IP4:MC:UDP} && ${%CBT} +BAT:BAT-UCAST:IP4:MC:UDP:MCAFEE;${BAT:BAT-UCAST:IP4:MC:UDP} && ${%MCAFEE} +BAT:BAT-UCAST:IP4:MC:UDP:UDP-39455;${BAT:BAT-UCAST:IP4:MC:UDP} && ${%UDP-39455} +BAT:BAT-UCAST:IP4:MC:UDP:UDP-889;${BAT:BAT-UCAST:IP4:MC:UDP} && ${%UDP-889} +BAT:BAT-UCAST:IP4:MC:UDP:UDP-16962;${BAT:BAT-UCAST:IP4:MC:UDP} && ${%UDP-16962} +BAT:BAT-UCAST:IP4:MC:UDP:TSEQ;${BAT:BAT-UCAST:IP4:MC:UDP} && ${%TSEQ} +BAT:BAT-UCAST:IP4:MC:UDP:CANON-BJNP;${BAT:BAT-UCAST:IP4:MC:UDP} && ${%CANON-BJNP} +BAT:BAT-UCAST:IP4:MC:UDP:RIP;${BAT:BAT-UCAST:IP4:MC:UDP} && ${%RIP} +BAT:BAT-UCAST:IP4:MC:UDP:RIPNG;${BAT:BAT-UCAST:IP4:MC:UDP} && ${%RIPNG} +BAT:BAT-UCAST:IP4:MC:UDP:OLSRV1;${BAT:BAT-UCAST:IP4:MC:UDP} && ${%OLSRV1} +BAT:BAT-UCAST:IP4:MC:UDP:BABEL;${BAT:BAT-UCAST:IP4:MC:UDP} && ${%BABEL} +BAT:BAT-UCAST:IP4:MC:UDP:MANET;${BAT:BAT-UCAST:IP4:MC:UDP} && ${%MANET} +BAT:BAT-UCAST:IP4:MC:UDP:RESPONDD-QRY;${BAT:BAT-UCAST:IP4:MC:UDP} && ${%RESPONDD-QRY} +BAT:BAT-UCAST:IP4:MC:UDP:SYNCTHING-LPD;${BAT:BAT-UCAST:IP4:MC:UDP} && ${%SYNCTHING-LPD} +BAT:BAT-UCAST:IP4:MC:UDP:USTEER;${BAT:BAT-UCAST:IP4:MC:UDP} && ${%USTEER} +BAT:BAT-UCAST:IP4:MC:UDP:L3ROAMD;${BAT:BAT-UCAST:IP4:MC:UDP} && ${%L3ROAMD} +BAT:BAT-UCAST:IP4:MC:UDP:MMFD;${BAT:BAT-UCAST:IP4:MC:UDP} && ${%MMFD} +BAT:BAT-UCAST:IP4:MC:UDP:RETICULUM;${BAT:BAT-UCAST:IP4:MC:UDP} && ${%RETICULUM} + +BAT:BAT-UCAST:IP6:MC;${BAT:BAT-UCAST} && ${IP6:MC} +BAT:BAT-UCAST:IP6:MC:PIM;${BAT:BAT-UCAST} && ${IP6:MC:PIM} +BAT:BAT-UCAST:IP6:MC:OSPF;${BAT:BAT-UCAST} && ${IP6:MC:OSPF} +BAT:BAT-UCAST:IP6:MC:MANET;${BAT:BAT-UCAST} && ${IP6:MC:MANET} +BAT:BAT-UCAST:IP6:MC:UDP;${BAT:BAT-UCAST} && ${IP6:MC:UDP} + +BAT:BAT-UCAST:IP6:MC:UDP:SSDP;${BAT:BAT-UCAST:IP6:MC:UDP} && ${%SSDP} +BAT:BAT-UCAST:IP6:MC:UDP:LLMNR;${BAT:BAT-UCAST:IP6:MC:UDP} && ${%LLMNR} +BAT:BAT-UCAST:IP6:MC:UDP:MDNS;${BAT:BAT-UCAST:IP6:MC:UDP} && ${%MDNS} +BAT:BAT-UCAST:IP6:MC:UDP:NB-NS;${BAT:BAT-UCAST:IP6:MC:UDP} && ${%NB-NS} +BAT:BAT-UCAST:IP6:MC:UDP:NB-DGM;${BAT:BAT-UCAST:IP6:MC:UDP} && ${%NB-DGM} +BAT:BAT-UCAST:IP6:MC:UDP:DP-LSP;${BAT:BAT-UCAST:IP6:MC:UDP} && ${%DP-LSP} +BAT:BAT-UCAST:IP6:MC:UDP:TRAP-DAEMON;${BAT:BAT-UCAST:IP6:MC:UDP} && ${%TRAP-DAEMON} +BAT:BAT-UCAST:IP6:MC:UDP:DHCP4;${BAT:BAT-UCAST:IP6:MC:UDP} && ${%DHCP4} +BAT:BAT-UCAST:IP6:MC:UDP:DHCP6;${BAT:BAT-UCAST:IP6:MC:UDP} && ${%DHCP6} +BAT:BAT-UCAST:IP6:MC:UDP:WS-DISC;${BAT:BAT-UCAST:IP6:MC:UDP} && ${%WS-DISC} +BAT:BAT-UCAST:IP6:MC:UDP:WSP;${BAT:BAT-UCAST:IP6:MC:UDP} && ${%WSP} +BAT:BAT-UCAST:IP6:MC:UDP:TEREDO;${BAT:BAT-UCAST:IP6:MC:UDP} && ${%TEREDO} +BAT:BAT-UCAST:IP6:MC:UDP:SPOTIFY;${BAT:BAT-UCAST:IP6:MC:UDP} && ${%SPOTIFY} +BAT:BAT-UCAST:IP6:MC:UDP:SIP;${BAT:BAT-UCAST:IP6:MC:UDP} && ${%SIP} +BAT:BAT-UCAST:IP6:MC:UDP:BT-LPD;${BAT:BAT-UCAST:IP6:MC:UDP} && ${%BT-LPD} +BAT:BAT-UCAST:IP6:MC:UDP:NVBM;${BAT:BAT-UCAST:IP6:MC:UDP} && ${%NVBM} +BAT:BAT-UCAST:IP6:MC:UDP:SVRLOC;${BAT:BAT-UCAST:IP6:MC:UDP} && ${%SVRLOC} +BAT:BAT-UCAST:IP6:MC:UDP:ENPC;${BAT:BAT-UCAST:IP6:MC:UDP} && ${%ENPC} +BAT:BAT-UCAST:IP6:MC:UDP:QTSTREAM;${BAT:BAT-UCAST:IP6:MC:UDP} && ${%QTSTREAM} +BAT:BAT-UCAST:IP6:MC:UDP:HDHOMERUN;${BAT:BAT-UCAST:IP6:MC:UDP} && ${%HDHOMERUN} +BAT:BAT-UCAST:IP6:MC:UDP:PLEX-DISC0;${BAT:BAT-UCAST:IP6:MC:UDP} && ${%PLEX-DISC0} +BAT:BAT-UCAST:IP6:MC:UDP:PLEX-DISC2;${BAT:BAT-UCAST:IP6:MC:UDP} && ${%PLEX-DISC2} +BAT:BAT-UCAST:IP6:MC:UDP:PLEX-DISC3;${BAT:BAT-UCAST:IP6:MC:UDP} && ${%PLEX-DISC3} +BAT:BAT-UCAST:IP6:MC:UDP:PLEX-DISC4;${BAT:BAT-UCAST:IP6:MC:UDP} && ${%PLEX-DISC4} +BAT:BAT-UCAST:IP6:MC:UDP:BT-UTP;${BAT:BAT-UCAST:IP6:MC:UDP} && ${%BT-UTP} +BAT:BAT-UCAST:IP6:MC:UDP:WF-BSSERV;${BAT:BAT-UCAST:IP6:MC:UDP} && ${%WF-BSSERV} +BAT:BAT-UCAST:IP6:MC:UDP:FAXIMUM;${BAT:BAT-UCAST:IP6:MC:UDP} && ${%FAXIMUM} +BAT:BAT-UCAST:IP6:MC:UDP:TOMCAT;${BAT:BAT-UCAST:IP6:MC:UDP} && ${%TOMCAT} +BAT:BAT-UCAST:IP6:MC:UDP:DISTINCT;${BAT:BAT-UCAST:IP6:MC:UDP} && ${%DISTINCT} +BAT:BAT-UCAST:IP6:MC:UDP:UDP-25412;${BAT:BAT-UCAST:IP6:MC:UDP} && ${%UDP-25412} +BAT:BAT-UCAST:IP6:MC:UDP:UDP-10203;${BAT:BAT-UCAST:IP6:MC:UDP} && ${%UDP-10203} +BAT:BAT-UCAST:IP6:MC:UDP:UDP-60128;${BAT:BAT-UCAST:IP6:MC:UDP} && ${%UDP-60128} +BAT:BAT-UCAST:IP6:MC:UDP:COREL-VNC;${BAT:BAT-UCAST:IP6:MC:UDP} && ${%COREL-VNC} +BAT:BAT-UCAST:IP6:MC:UDP:HPVMMCTRL;${BAT:BAT-UCAST:IP6:MC:UDP} && ${%HPVMMCTRL} +BAT:BAT-UCAST:IP6:MC:UDP:CBT;${BAT:BAT-UCAST:IP6:MC:UDP} && ${%CBT} +BAT:BAT-UCAST:IP6:MC:UDP:MCAFEE;${BAT:BAT-UCAST:IP6:MC:UDP} && ${%MCAFEE} +BAT:BAT-UCAST:IP6:MC:UDP:UDP-39455;${BAT:BAT-UCAST:IP6:MC:UDP} && ${%UDP-39455} +BAT:BAT-UCAST:IP6:MC:UDP:UDP-889;${BAT:BAT-UCAST:IP6:MC:UDP} && ${%UDP-889} +BAT:BAT-UCAST:IP6:MC:UDP:UDP-16962;${BAT:BAT-UCAST:IP6:MC:UDP} && ${%UDP-16962} +BAT:BAT-UCAST:IP6:MC:UDP:TSEQ;${BAT:BAT-UCAST:IP6:MC:UDP} && ${%TSEQ} +BAT:BAT-UCAST:IP6:MC:UDP:CANON-BJNP;${BAT:BAT-UCAST:IP6:MC:UDP} && ${%CANON-BJNP} +BAT:BAT-UCAST:IP6:MC:UDP:RIP;${BAT:BAT-UCAST:IP6:MC:UDP} && ${%RIP} +BAT:BAT-UCAST:IP6:MC:UDP:RIPNG;${BAT:BAT-UCAST:IP6:MC:UDP} && ${%RIPNG} +BAT:BAT-UCAST:IP6:MC:UDP:OLSRV1;${BAT:BAT-UCAST:IP6:MC:UDP} && ${%OLSRV1} +BAT:BAT-UCAST:IP6:MC:UDP:BABEL;${BAT:BAT-UCAST:IP6:MC:UDP} && ${%BABEL} +BAT:BAT-UCAST:IP6:MC:UDP:MANET;${BAT:BAT-UCAST:IP6:MC:UDP} && ${%MANET} +BAT:BAT-UCAST:IP6:MC:UDP:RESPONDD-QRY;${BAT:BAT-UCAST:IP6:MC:UDP} && ${%RESPONDD-QRY} +BAT:BAT-UCAST:IP6:MC:UDP:SYNCTHING-LPD;${BAT:BAT-UCAST:IP6:MC:UDP} && ${%SYNCTHING-LPD} +BAT:BAT-UCAST:IP6:MC:UDP:USTEER;${BAT:BAT-UCAST:IP6:MC:UDP} && ${%USTEER} +BAT:BAT-UCAST:IP6:MC:UDP:L3ROAMD;${BAT:BAT-UCAST:IP6:MC:UDP} && ${%L3ROAMD} +BAT:BAT-UCAST:IP6:MC:UDP:MMFD;${BAT:BAT-UCAST:IP6:MC:UDP} && ${%MMFD} +BAT:BAT-UCAST:IP6:MC:UDP:RETICULUM;${BAT:BAT-UCAST:IP6:MC:UDP} && ${%RETICULUM} + +BAT:BAT-UCAST:IP6:MC:HBH6;${BAT:BAT-UCAST} && ${IP6:MC:HBH6} +BAT:BAT-UCAST:IP6:MC:ICMP6;${BAT:BAT-UCAST} && ${IP6:MC:ICMP6} + +BAT:BAT-UCAST:IP6:MC:HBH6:MLD;${BAT:BAT-UCAST} && ${IP6:MC:HBH6:MLD} +BAT:BAT-UCAST:IP6:MC:HBH6:MLD:QUERY-V1;${BAT:BAT-UCAST} && ${IP6:MC:HBH6:MLD:QUERY-V1} +BAT:BAT-UCAST:IP6:MC:HBH6:MLD:QUERY-V1:GENERAL;${BAT:BAT-UCAST} && ${IP6:MC:HBH6:MLD:QUERY-V1:GENERAL} +BAT:BAT-UCAST:IP6:MC:HBH6:MLD:QUERY-V1:ADDRSPEC;${BAT:BAT-UCAST} && ${IP6:MC:HBH6:MLD:QUERY-V1:ADDRSPEC} +BAT:BAT-UCAST:IP6:MC:HBH6:MLD:QUERY-V2;${BAT:BAT-UCAST} && ${IP6:MC:HBH6:MLD:QUERY-V2} +BAT:BAT-UCAST:IP6:MC:HBH6:MLD:QUERY-V2:GENERAL;${BAT:BAT-UCAST} && ${IP6:MC:HBH6:MLD:QUERY-V2:GENERAL} +BAT:BAT-UCAST:IP6:MC:HBH6:MLD:QUERY-V2:ADDRSPEC;${BAT:BAT-UCAST} && ${IP6:MC:HBH6:MLD:QUERY-V2:ADDRSPEC} +BAT:BAT-UCAST:IP6:MC:HBH6:MLD:QUERY-UNKNOWN;${BAT:BAT-UCAST} && ${IP6:MC:HBH6:MLD:QUERY-UNKNOWN} +BAT:BAT-UCAST:IP6:MC:HBH6:MLD:REPORT-V1;${BAT:BAT-UCAST} && ${IP6:MC:HBH6:MLD:REPORT-V1} +BAT:BAT-UCAST:IP6:MC:HBH6:MLD:DONE-V1;${BAT:BAT-UCAST} && ${IP6:MC:HBH6:MLD:DONE-V1} +BAT:BAT-UCAST:IP6:MC:HBH6:MLD:REPORT-V2;${BAT:BAT-UCAST} && ${IP6:MC:HBH6:MLD:REPORT-V2} +BAT:BAT-UCAST:IP6:MC:HBH6:MLD:MRD-ADV;${BAT:BAT-UCAST} && ${IP6:MC:HBH6:MLD:MRD-ADV} +BAT:BAT-UCAST:IP6:MC:HBH6:MLD:MRD-SOL;${BAT:BAT-UCAST} && ${IP6:MC:HBH6:MLD:MRD-SOL} +BAT:BAT-UCAST:IP6:MC:HBH6:MLD:MRD-TERM;${BAT:BAT-UCAST} && ${IP6:MC:HBH6:MLD:MRD-TERM} +BAT:BAT-UCAST:IP6:MC:HBH6:OTHER;${BAT:BAT-UCAST} && ${IP6:MC:HBH6} and not (${BAT:BAT-UCAST:IP6:MC:HBH6:MLD}) + +BAT:BAT-UCAST:IP6:MC:ICMP6:ECHOREQ;${BAT:BAT-UCAST} && ${IP6:MC:ICMP6:ECHOREQ} +BAT:BAT-UCAST:IP6:MC:ICMP6:ECHOREP;${BAT:BAT-UCAST} && ${IP6:MC:ICMP6:ECHOREP} +BAT:BAT-UCAST:IP6:MC:ICMP6:NDSOL;${BAT:BAT-UCAST} && ${IP6:MC:ICMP6:NDSOL} +BAT:BAT-UCAST:IP6:MC:ICMP6:NDADV;${BAT:BAT-UCAST} && ${IP6:MC:ICMP6:NDADV} +BAT:BAT-UCAST:IP6:MC:ICMP6:NDADV:UNSOL;${BAT:BAT-UCAST} && ${IP6:MC:ICMP6:NDADV:UNSOL} +BAT:BAT-UCAST:IP6:MC:ICMP6:NDADV:OTHER;${BAT:BAT-UCAST} && ${IP6:MC:ICMP6:NDADV:OTHER} +BAT:BAT-UCAST:IP6:MC:ICMP6:RTRSOL;${BAT:BAT-UCAST} && ${IP6:MC:ICMP6:RTRSOL} +BAT:BAT-UCAST:IP6:MC:ICMP6:RTRADV;${BAT:BAT-UCAST} && ${IP6:MC:ICMP6:RTRADV} +BAT:BAT-UCAST:IP6:MC:ICMP6:OTHER;${BAT:BAT-UCAST} && ${IP6:MC:ICMP6:OTHER} + +BAT:BAT-UCAST:BLA:CLAIM;${BAT:BAT-UCAST} and ${BLA:CLAIM} +BAT:BAT-UCAST:BLA:UNCLAIM;${BAT:BAT-UCAST} and ${BLA:UNCLAIM} +BAT:BAT-UCAST:BLA:ANNOUNCE;${BAT:BAT-UCAST} and ${BLA:ANNOUNCE} +BAT:BAT-UCAST:BLA:REQUEST;${BAT:BAT-UCAST} and ${BLA:REQUEST} +BAT:BAT-UCAST:BLA:LOOPDETECT;${BAT:BAT-UCAST} and ${BLA:LOOPDETECT} + +BAT:BAT-UCAST:ARP:REQ;${BAT:BAT-UCAST} and ${ARP:REQ} +BAT:BAT-UCAST:ARP:REQ:UNSOL;${BAT:BAT-UCAST} and ${ARP:REQ:UNSOL} +BAT:BAT-UCAST:ARP:REQ:OTHER;${BAT:BAT-UCAST} and ${ARP:REQ:OTHER} +BAT:BAT-UCAST:ARP:REP;${BAT:BAT-UCAST} and ${ARP:REP} +BAT:BAT-UCAST:ARP:REP:UNSOL;${BAT:BAT-UCAST} and ${ARP:REP:UNSOL} +BAT:BAT-UCAST:ARP:REP:OTHER;${BAT:BAT-UCAST} and ${ARP:REP:OTHER} diff --git a/package/gluon-statistics-mcast/files/lib/gluon/core/mesh/setup.d/40-bpfcountd b/package/gluon-statistics-mcast/files/lib/gluon/core/mesh/setup.d/40-bpfcountd new file mode 100755 index 00000000..9c9b5a7e --- /dev/null +++ b/package/gluon-statistics-mcast/files/lib/gluon/core/mesh/setup.d/40-bpfcountd @@ -0,0 +1,67 @@ +#!/bin/sh + +[ -z "$IFNAME" ] && exit 0 + +if [ -z "$1" ]; then + SOCKETSSUB="mesh" +else + SOCKETSSUB="$1" +fi + +. /lib/functions.sh + +lock /var/lock/gluon_bpfcountd.lock + +BPFCOUNTD_RUN="/var/run/bpfcountd" +mkdir -p "${BPFCOUNTD_RUN}/gluon-sockets/$SOCKETSSUB" + +export UCI_CONFIG_DIR="${BPFCOUNTD_RUN}/gluon-config" +mkdir -p "${UCI_CONFIG_DIR}" +touch "${UCI_CONFIG_DIR}/bpfcountd" + + +# Skip anything which might be unicast payload to avoid +# a noticeable performance impact: +# -> a batadv unicast packet with an IP unicast destination in +# the inner ethernet header; all batadv unicast fragments +# Note: batadv unicast fragments might contain a multicast +# packet, too (though unlikely, usually they are smaller +# than MTU). + +# All IP packets with a unicast destination, except +# IGMP, OSPF (89), PIM (103) or MANET (138) +PREFILTER_IP4_UC="(ip and not ip multicast and not igmp and not (ip proto (89 or 103 or 138)))" +PREFILTER_IP6_UC="(ip6 and not ip6 multicast and not ip6 proto 0 and not (ip6 proto (89 or 103 or 138)))" +PREFILTER_IP_UC="(${PREFILTER_IP4_UC} or ${PREFILTER_IP6_UC})" + +PREFILTER_CLIENT="not ${PREFILTER_IP_UC}" +PREFILTER_MESH="not (batadv 15 unicast and ${PREFILTER_IP_UC}) and not batadv 15 unicast_frag" +PREFILTER="${PREFILTER_CLIENT} and ${PREFILTER_MESH}" + +SECTION_IN="gluon_${IFNAME//-/_}_in" +SECTION_OUT="gluon_${IFNAME//-/_}_out" +uci -c "${UCI_CONFIG_DIR}" batch <<-EOF + set bpfcountd.${SECTION_IN}="bpfcountd" + set bpfcountd.${SECTION_IN}.ifname=${IFNAME} + set bpfcountd.${SECTION_IN}.prefilter="inbound and (${PREFILTER})" + set bpfcountd.${SECTION_IN}.filterfile='/lib/gluon/bpfcountd/mesh.filters' + set bpfcountd.${SECTION_IN}.buffersize='131072' + set bpfcountd.${SECTION_IN}.disabled='0' + + set bpfcountd.${SECTION_OUT}="bpfcountd" + set bpfcountd.${SECTION_OUT}.ifname=${IFNAME} + set bpfcountd.${SECTION_OUT}.prefilter="outbound and (${PREFILTER})" + set bpfcountd.${SECTION_OUT}.filterfile='/lib/gluon/bpfcountd/mesh.filters' + set bpfcountd.${SECTION_OUT}.buffersize='131072' + set bpfcountd.${SECTION_OUT}.disabled='0' + + commit bpfcountd +EOF + +ln -s "../../${SECTION_IN}.sock" "${BPFCOUNTD_RUN}/gluon-sockets/$SOCKETSSUB/${IFNAME}.in.sock" +ln -s "../../${SECTION_OUT}.sock" "${BPFCOUNTD_RUN}/gluon-sockets/$SOCKETSSUB/${IFNAME}.out.sock" + +/etc/init.d/bpfcountd start "${SECTION_IN}" +/etc/init.d/bpfcountd start "${SECTION_OUT}" + +lock -u /var/lock/gluon_bpfcountd.lock diff --git a/package/gluon-statistics-mcast/files/lib/gluon/core/mesh/teardown.d/40-bpfcountd b/package/gluon-statistics-mcast/files/lib/gluon/core/mesh/teardown.d/40-bpfcountd new file mode 100755 index 00000000..cc41c185 --- /dev/null +++ b/package/gluon-statistics-mcast/files/lib/gluon/core/mesh/teardown.d/40-bpfcountd @@ -0,0 +1,33 @@ +#!/bin/sh + +[ -z "$IFNAME" ] && exit 0 + +. /lib/functions.sh + +BPFCOUNTD_RUN="/var/run/bpfcountd" + +lock /var/lock/gluon_bpfcountd.lock +export UCI_CONFIG_DIR="${BPFCOUNTD_RUN}/gluon-config" + + +bpfcountd_uci_delete() { + local cfg="$1" + local uci_ifname + + config_get uci_ifname "$cfg" ifname + [ "${uci_ifname}" = "$IFNAME" ] || return + + uci -c "${UCI_CONFIG_DIR}" delete "bpfcountd.$cfg" +} + +/etc/init.d/bpfcountd stop "gluon_${IFNAME//-/_}_in" +/etc/init.d/bpfcountd stop "gluon_${IFNAME//-/_}_out" + +rm "${BPFCOUNTD_RUN}/gluon-sockets/"*"/${IFNAME}.in.sock" +rm "${BPFCOUNTD_RUN}/gluon-sockets/"*"/${IFNAME}.out.sock" + +config_load bpfcountd +config_foreach bpfcountd_uci_delete bpfcountd +uci -c "${UCI_CONFIG_DIR}" commit bpfcountd + +lock -u /var/lock/gluon_bpfcountd.lock diff --git a/package/gluon-statistics-mcast/src/Makefile b/package/gluon-statistics-mcast/src/Makefile new file mode 100644 index 00000000..3ddc8a58 --- /dev/null +++ b/package/gluon-statistics-mcast/src/Makefile @@ -0,0 +1,6 @@ +all: respondd.so + +CFLAGS += -Wall + +respondd.so: respondd.c + $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -shared -fPIC -D_GNU_SOURCE -o $@ $^ $(LDLIBS) -lgluonutil -luci diff --git a/package/gluon-statistics-mcast/src/respondd.c b/package/gluon-statistics-mcast/src/respondd.c new file mode 100644 index 00000000..5300ffa0 --- /dev/null +++ b/package/gluon-statistics-mcast/src/respondd.c @@ -0,0 +1,491 @@ +/* + Copyright (c) 2021, Linus Lüssing + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BPFCOUNTD_SOCKS_DIR "/var/run/bpfcountd/gluon-sockets" + +#define ARRAY_SIZE(arr) (sizeof((arr)) / sizeof((arr)[0])) + +enum capdir { + CAP_IN, + CAP_OUT, + CAP_UNDEF, + CAP_MAX, +}; + +static const char *dirstr[CAP_MAX] = { + [CAP_IN] = "in", + [CAP_OUT] = "out", + [CAP_UNDEF] = "", +}; + +static int check_socket_suffix(const char *socketname) +{ + unsigned int offset; + + if (strlen(socketname) <= strlen(".sock")) + return -EINVAL; + + offset = strlen(socketname) - strlen(".sock"); + if (strcmp(&socketname[offset], ".sock")) + return -EINVAL; + + return 0; +} + +static int regexecmp(const char *re_pattern, const char *re_string) +{ + regex_t regex; + regmatch_t pmatch[1]; + int ret = -EINVAL; + + if (regcomp(®ex, re_pattern, 0)) + return -EINVAL; + + if (!regexec(®ex, re_string, ARRAY_SIZE(pmatch), pmatch, 0)) + ret = 0; + + regfree(®ex); + return ret; +} + +static enum capdir parse_socket_dir(const char *socketname) +{ + if (!regexecmp("\\.in\\.sock$", socketname)) + return CAP_IN; + else if (!regexecmp("\\.out\\.sock$", socketname)) + return CAP_OUT; + else + return CAP_UNDEF; +} + +static int parse_socket_iface(const char *socketname, enum capdir dir, + char *iface) +{ + unsigned int iface_len = strlen(socketname); + + if (dir == CAP_IN) + iface_len -= strlen(".in.sock"); + else if (dir == CAP_OUT) + iface_len -= strlen(".out.sock"); + else + return -EINVAL; + + if (iface_len >= IFNAMSIZ) + return -EINVAL; + + memset(iface, 0, IFNAMSIZ); + strncpy(iface, socketname, iface_len); + + return 0; +} + +static struct json_object *get_json_new(struct json_object *parent, + const char *key) +{ + struct json_object *child = NULL; + json_bool ret; + + ret = json_object_object_get_ex(parent, key, &child); + if (ret && child) { + /* sanity check */ + if (!json_object_is_type(child, json_type_object)) + return NULL; + + return child; + } + + child = json_object_new_object(); + if (!child) + return NULL; + + /* json-c 0.12, should check return codes for >= 0.13 */ + json_object_object_add(parent, key, child); + + return child; +} + +static struct json_object *parse_socket_name(const char *socketname, + struct json_object *obj, + enum capdir *dir) +{ + int ret; + char iface[IFNAMSIZ]; + + *dir = parse_socket_dir(socketname); + if (*dir == CAP_UNDEF) + return NULL; + + ret = parse_socket_iface(socketname, *dir, iface); + if (ret < 0) + return NULL; + + return get_json_new(obj, iface); +} + +static int parse_num(const char *start, int64_t *num) +{ + unsigned long long value; + char *endptr; + + if (*start == '-') + return -EINVAL; + + value = strtoull(start, &endptr, 10); + if ((value == ULLONG_MAX && errno == ERANGE) || + start == endptr) + return -EINVAL; + + /* limit to int64 max for json-c */ + if (value > INT64_MAX) + return -EINVAL; + + *num = (int64_t)value; + return 0; +} + +static int add_num_to_json(struct json_object *dir_obj, const char *key, + int64_t num) +{ + struct json_object *elem; + + elem = json_object_new_int64(num); + if (!elem) + return -ENOMEM; + + /* json-c < 0.13 */ + json_object_object_add(dir_obj, key, elem); + return 0; +} + +/* + * Example: + * { + * "bytes": 12345, + * "packets": 456 + * } + */ +static struct json_object *create_dir_object(int64_t bytes, int64_t packets) +{ + struct json_object *dir_obj; + int ret; + + dir_obj = json_object_new_object(); + if (!dir_obj) + return NULL; + + ret = add_num_to_json(dir_obj, "bytes", bytes); + if (ret < 0) + goto err; + + ret = add_num_to_json(dir_obj, "packets", packets); + if (ret < 0) + goto err; + + return dir_obj; +err: + json_object_put(dir_obj); + return NULL; +} + +static int add_line_to_json(struct json_object *iface_obj, enum capdir dir, + const char *rule, int64_t bytes, int64_t packets) +{ + struct json_object *dir_obj, *rule_obj = NULL; + int ret; + + dir_obj = create_dir_object(bytes, packets); + if (!dir_obj) + return -ENOMEM; + + rule_obj = get_json_new(iface_obj, rule); + if (!rule_obj) + goto err; + + /* sanity check, should not exist yet */ + ret = json_object_object_get_ex(rule_obj, dirstr[dir], NULL); + if (ret) + goto err; + + /* json-c < 0.13 */ + json_object_object_add(rule_obj, dirstr[dir], dir_obj); + return 0; +err: + json_object_put(dir_obj); + return -ENOMEM; +} + +/* Parses a line of the following format: + * :: + * + * And adds it to the provided json object. + */ +static int parse_line(struct json_object *obj, enum capdir dir, + char *line) +{ + int64_t bytes; + int64_t packets; + char *start; + int ret; + + /* skip lines prefixed with '%' */ + if (line[0] == '%') + return 0; + + /* packets */ + start = strrchr(line, ':'); + if (!start) + return -EINVAL; + + ret = parse_num(&start[1], &packets); + if (ret < 0) + return ret; + + *start = '\0'; + + /* bytes */ + start = strrchr(line, ':'); + if (!start) + return -EINVAL; + + ret = parse_num(&start[1], &bytes); + if (ret < 0) + return ret; + + *start = '\0'; + /* line: is now rule name */ + + ret = add_line_to_json(obj, dir, line, bytes, packets); + if (ret < 0) + return -EINVAL; + + return 0; +} + +static int parse_socket(const char *socketname, struct json_object *iface_obj, + enum capdir dir) +{ + char linebuf[1024]; + struct sockaddr_un addr; + int sd, ret; + FILE *file; + + sd = socket(AF_UNIX, SOCK_STREAM, 0); + if (sd < 0) + return sd; + + memset(&addr, 0, sizeof(addr)); + addr.sun_family = AF_UNIX; + strncpy(addr.sun_path, socketname, sizeof(addr.sun_path) - 1); + + ret = connect(sd, (const struct sockaddr *)&addr, + sizeof(addr)); + if (ret < 0) + goto out; + + file = fdopen(sd, "r"); + if (!file) { + ret = -EACCES; + goto out; + } + + /* Does this really help or maybe even worsen performance? */ + setlinebuf(file); + + while (!feof(file)) { + if (!fgets(linebuf, sizeof(linebuf)-1, file)) + break; + + parse_line(iface_obj, dir, linebuf); + } + + ret = 0; +out: + close(sd); + return ret; +} + +static void parse_socket_subdir(struct dirent *subdir, struct json_object *obj) +{ + struct json_object *subdir_obj; + struct dirent *dp; + DIR *dir; + + if (chdir(subdir->d_name) < 0) + return; + + dir = opendir("./"); + if (!dir) + goto err; + + subdir_obj = json_object_new_object(); + if (!subdir_obj) + goto err2; + + json_object_object_add(obj, subdir->d_name, subdir_obj); + + /* scan: /var/run/bpfcountd/gluon-sockets/