diff --git a/packet-capture-diagnostics/Makefile b/packet-capture-diagnostics/Makefile new file mode 100644 index 000000000..d8c8971a8 --- /dev/null +++ b/packet-capture-diagnostics/Makefile @@ -0,0 +1,51 @@ +# +# Copyright (C) 2023 IOPSYS +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=packet-capture-diagnostics +PKG_VERSION:=1.0.0 + +LOCAL_DEV:=0 +ifneq ($(LOCAL_DEV),1) +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=https://dev.iopsys.eu/bbf/packet-capture-diagnostics.git +PKG_SOURCE_VERSION:=a47189b5faa9f678f1a27475c474cc1524d777f4 +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz +PKG_MIRROR_HASH:=skip +endif + +PKG_LICENSE:=BSD-3-Clause +PKG_LICENSE_FILES:=LICENSE + +include $(INCLUDE_DIR)/package.mk +include ../bbfdm/bbfdm.mk + +define Package/packet-capture-diagnostics + SECTION:=utils + CATEGORY:=Utilities + SUBMENU:=TRx69 + TITLE:=PacketCaptureDiagnostics datamodel + DEPENDS:=+libbbfdm-api +tcpdump + MENU:=1 +endef + +MAKE_PATH:=src + +define Package/packet-capture-diagnostics/description + Package to add Device.PacketCaptureDiagnostics. datamodel support using bbfdm +endef + +ifeq ($(LOCAL_DEV),1) +define Build/Prepare + $(CP) -rf ~/git/packet-capture-diagnostics/* $(PKG_BUILD_DIR)/ +endef +endif + +define Package/packet-capture-diagnostics/install + $(BBFDM_INSTALL_SCRIPT) ./files/scripts/packetcapture $(1) + $(BBFDM_INSTALL_CORE_PLUGIN) $(PKG_BUILD_DIR)/src/libpackcapture.so $(1) +endef + +$(eval $(call BuildPackage,packet-capture-diagnostics)) diff --git a/packet-capture-diagnostics/files/scripts/packetcapture b/packet-capture-diagnostics/files/scripts/packetcapture new file mode 100644 index 000000000..d170fcdc6 --- /dev/null +++ b/packet-capture-diagnostics/files/scripts/packetcapture @@ -0,0 +1,192 @@ +#!/bin/sh +# Copyright (C) 2024 iopsys Software Solutions AB +# Author: Suvendhu Hansa + +. /usr/share/libubox/jshn.sh + +ROOT="$(dirname "${0}")" +. "${ROOT}"/bbf_api + +UPLOAD_TIMEOUT=1800 + +packet_capture_error() { + json_init + json_add_string "Status" "$1" + json_add_string "FileLocation" "" + json_add_string "StartTime" "0" + json_add_string "EndTime" "0" + json_add_string "Count" "0" + json_dump + + [ "$2" = "both_proto" ] && { + $UCI_SET_BBF_DMMAP dmmap_diagnostics.packetcapture.DiagnosticState="$1" + $UCI_SET_BBF_DMMAP dmmap_diagnostics.packetcapture.FileLocation="" + $UCI_SET_BBF_DMMAP dmmap_diagnostics.packetcapture.StartTime=0 + $UCI_SET_BBF_DMMAP dmmap_diagnostics.packetcapture.EndTime=0 + $UCI_SET_BBF_DMMAP dmmap_diagnostics.packetcapture.Count=0 + $UCI_COMMIT_BBF_DMMAP + } +} + +packet_capture_launch() { + input="$1" + intf="" + filename=$(mktemp /tmp/capture.XXXXXXX) + + # Delete if any local capture file exist + find / -name "packetcapture.pcap" -exec rm {} \; + + json_load "${input}" + + json_get_var interface interface + json_get_var format format + json_get_var duration duration + json_get_var packet_count packet_count + json_get_var file_target file_target + json_get_var expression expression + json_get_var username username + json_get_var password password + json_get_var proto proto + json_get_var cancel cancel + + [ "$proto" = "both_proto" ] && { + old_pid=$(cat /tmp/packetcapture_pid) + + [ -n "${old_pid}" ] && { + cmd=$(cat /proc/$old_pid/cmdline) + } + + if [[ "${cmd}" = *packetcapture* ]]; then + kill -9 ${old_pid} + fi + + if [ "${cancel}" -eq "1" ]; then + json_init + json_add_string "Status" "None" + json_add_string "FileLocation" "" + json_add_string "StartTime" "0" + json_add_string "EndTime" "0" + json_add_string "Count" "0" + json_dump + + $UCI_SET_BBF_DMMAP dmmap_diagnostics.packetcapture.DiagnosticState="None" + $UCI_SET_BBF_DMMAP dmmap_diagnostics.packetcapture.FileLocation="" + $UCI_SET_BBF_DMMAP dmmap_diagnostics.packetcapture.StartTime=0 + $UCI_SET_BBF_DMMAP dmmap_diagnostics.packetcapture.EndTime=0 + $UCI_SET_BBF_DMMAP dmmap_diagnostics.packetcapture.Count=0 + $UCI_COMMIT_BBF_DMMAP + + return + else + echo $$ > /tmp/packetcapture_pid + $UCI_SET_BBF_DMMAP dmmap_diagnostics.packetcapture.DiagnosticState="Requested_running" + $UCI_COMMIT_BBF_DMMAP + fi + } + + if [ -n "${format}" ] && [ "${format}" != "libpcap" ]; then + # Error + packet_capture_error "Error_Internal" "${proto}" + return + fi + + if [ -z "${file_target}" ]; then + # Error + packet_capture_error "Error_Internal" "${proto}" + return + fi + + if [ -n "${interface}" ]; then + intf=$(ifstatus "${interface}" | jq ".l3_device") + + if [ -z "${intf}" ]; then + # Error + packet_capture_error "Error_Internal" "${proto}" + return + fi + + intf=$(eval echo "${intf}") + fi + + cmd="timeout ${duration} tcpdump -w ${filename}" + + if [ -n "${intf}" ]; then + cmd="${cmd} -i ${intf}" + fi + + if [ "${packet_count}" -ne 0 ]; then + cmd="${cmd} -c ${packet_count}" + fi + + if [ -n "${expression}" ]; then + cmd="${cmd} \"${expression}\"" + fi + + time_start=$(date +"%s") + output=$(eval ${cmd} 2>&1 | grep "packets captured") + res="$?" + time_stop=$(date +"%s") + + if [ "${res}" -ne 0 ]; then + # Error + packet_capture_error "Error_Internal" "${proto}" + return + fi + + pkt_count=$(echo $output | cut -d' ' -f 1) + + if [[ "${file_target}" == "file://"* ]]; then + # Local file + file_target=$(realpath "${file_target:6}/packetcapture.pcap") + if [ -z "${file_target}" ]; then + # Invalid local path Error + rm -rf "${filename}" + res=1 + else + # Copy file to destination + mv "${filename}" "${file_target}" + res="$?" + fi + else + # Remote file + opt="" + if [ -n "${username}" ] && [ -n "${password}" ]; then + opt="--user ${username}:${password}" + fi + + file_target="${file_target}/packetcapture.pcap" + opt="${opt} --upload-file ${filename}" + eval curl --fail --silent "${opt}" --max-time ${UPLOAD_TIMEOUT} "${file_target}" + res="$?" + rm -rf "${filename}" + fi + + if [ "$res" -ne 0 ]; then + # Error + packet_capture_error "Error_Internal" "${proto}" + return + else + json_init + json_add_string "Status" "Complete" + json_add_string "FileLocation" "${file_target}" + json_add_string "StartTime" "${time_start}" + json_add_string "EndTime" "${time_stop}" + json_add_string "Count" "${pkt_count}" + json_dump + + [ "${proto}" = "both_proto" ] && { + $UCI_SET_BBF_DMMAP dmmap_diagnostics.packetcapture.DiagnosticState="Complete" + $UCI_SET_BBF_DMMAP dmmap_diagnostics.packetcapture.FileLocation="${file_target}" + $UCI_SET_BBF_DMMAP dmmap_diagnostics.packetcapture.StartTime="${time_start}" + $UCI_SET_BBF_DMMAP dmmap_diagnostics.packetcapture.EndTime="${time_stop}" + $UCI_SET_BBF_DMMAP dmmap_diagnostics.packetcapture.Count="${pkt_count}" + $UCI_COMMIT_BBF_DMMAP + } + fi +} + +if [ -n "$1" ]; then + packet_capture_launch "$1" +else + packet_capture_error "Error_Internal" +fi