#!/bin/sh # Copyright (C) 2019 iopsys Software Solutions AB # Author: IMEN Bhiri # Author: AMIN Ben Ramdhane UCI_GET_BBFDM="/sbin/uci -q -c /etc/bbfdm get" UCI_SET_BBFDM="/sbin/uci -q -c /etc/bbfdm set" UCI_ADD_BBFDM="/sbin/uci -q -c /etc/bbfdm add" UCI_DELETE_BBFDM="/sbin/uci -q -c /etc/bbfdm delete" UCI_COMMIT_BBFDM="/sbin/uci -q -c /etc/bbfdm commit" CAPTURE_FILE="/tmp/upload_dump" UPLOAD_DIAGNOSTIC_FILE="/tmp/bbfdm_upload_diagnostic" CONNECTION_TIMEOUT=20 upload_get() { local val=`$UCI_GET_BBFDM $1` echo ${val:-$2} } upload_launch() { local proto tx_bytes_before rx_bytes_before time1 tx_bytes_after rx_bytes_after time2 res ba stc periodtime local url=$2 local device=$3 local size=$4 [ "$1" == "cwmp" ] && [ "`$UCI_GET_BBFDM dmmap_diagnostics.upload.DiagnosticState`" != "Requested" ] && return [ "$url" = "" ] && { $UCI_SET_BBFDM dmmap_diagnostics.upload.DiagnosticState=Error_InitConnectionFailed; $UCI_COMMIT_BBFDM; return; } local protocol=`upload_get dmmap_diagnostics.upload.ProtocolVersion Any` if [ "$protocol" == "IPv4" ]; then proto="-4"; elif [ "$protocol" == "IPv6" ]; then proto="-6"; else proto=""; fi # Disable acceleration on Broadcom devices to capture all packets with tcpdump [ -e /usr/sbin/fcctl ] && { fcctl disable >/dev/null 2>&1; fcctl flush >/dev/null 2>&1; } tcpdump -i $device tcp -w ${CAPTURE_FILE} > /dev/null 2>&1 & PID=$! sleep 1 dd if=/dev/zero of=${UPLOAD_DIAGNOSTIC_FILE} bs=${size} count=1 2>/dev/null if [ ${url:0:7} = http:// ]; then tx_bytes_before=`ubus call network.device status "{'name':'$device'}" | jsonfilter -e @.statistics.tx_bytes` rx_bytes_before=`ubus call network.device status "{'name':'$device'}" | jsonfilter -e @.statistics.rx_bytes` time1=`date +%s` res=$(curl $proto --fail --connect-timeout ${CONNECTION_TIMEOUT} -T ${UPLOAD_DIAGNOSTIC_FILE} $url 2>&1) time2=`date +%s` tx_bytes_after=`ubus call network.device status "{'name':'$device'}" | jsonfilter -e @.statistics.tx_bytes` rx_bytes_after=`ubus call network.device status "{'name':'$device'}" | jsonfilter -e @.statistics.rx_bytes` ba=`echo "$res" | grep "bad address"` [ -n "$ba" ] && { $UCI_SET_BBFDM dmmap_diagnostics.upload.DiagnosticState=Error_InitConnectionFailed; $UCI_COMMIT_BBFDM; kill $PID &> /dev/null; return; } stc=`echo "$res" | grep "404 Not Found"` [ -n "$stc" ] && { $UCI_SET_BBFDM dmmap_diagnostics.upload.DiagnosticState=Error_NoResponse; $UCI_COMMIT_BBFDM; kill $PID &> /dev/null; return; } stc=`echo "$res" |sed -n 3p|awk '{print $13}'` [ "$stc" != "100" ] && { $UCI_SET_BBFDM dmmap_diagnostics.upload.DiagnosticState=Error_TransferFailed; $UCI_COMMIT_BBFDM; kill $PID &> /dev/null; return; } elif [ ${url:0:6} = ftp:// ]; then #add user and pass if they exist substr="@" if [ -z "${url##*$substr*}" ] ;then url=`echo $url |sed -e "s/ftp:\/\/\([^:]*\):\([^:]*\)@\(.*\)/-u \1:\2 ftp:\/\/\3/"` fi tx_bytes_before=`ubus call network.device status "{'name':'$device'}" | jsonfilter -e @.statistics.tx_bytes` rx_bytes_before=`ubus call network.device status "{'name':'$device'}" | jsonfilter -e @.statistics.rx_bytes` time1=`date +%s` res=$(curl $proto --fail --disable-epsv --ftp-pasv --connect-timeout ${CONNECTION_TIMEOUT} -T ${UPLOAD_DIAGNOSTIC_FILE} $url 2>&1) time2=`date +%s` tx_bytes_after=`ubus call network.device status "{'name':'$device'}" | jsonfilter -e @.statistics.tx_bytes` rx_bytes_after=`ubus call network.device status "{'name':'$device'}" | jsonfilter -e @.statistics.rx_bytes` ba=`echo "$res" | grep "Couldn't resolve host"` [ -n "$ba" ] && { $UCI_SET_BBFDM dmmap_diagnostics.upload.DiagnosticState=Error_InitConnectionFailed; $UCI_COMMIT_BBFDM; kill $PID 2> /dev/null; return; } stc=`echo "$res" | grep "Access denied"` [ -n "$stc" ] && { $UCI_SET_BBFDM dmmap_diagnostics.upload.DiagnosticState=Error_LoginFailed; $UCI_COMMIT_BBFDM; kill $PID 2> /dev/null; return; } stc=`echo "$res" | grep "Failed FTP upload"` [ -n "$stc" ] && { $UCI_SET_BBFDM dmmap_diagnostics.upload.DiagnosticState=Error_NoResponse; $UCI_COMMIT_BBFDM; kill $PID 2> /dev/null; return; } stc=`echo "$res" |tail -n 1 |awk '{print $(NF-11)}'` [ "$stc" != "100" ] && { $UCI_SET_BBFDM dmmap_diagnostics.upload.DiagnosticState=Error_TransferFailed; $UCI_COMMIT_BBFDM; kill $PID 2> /dev/null; return; } fi tx_bytes=$((tx_bytes_after-tx_bytes_before)) rx_bytes=$((rx_bytes_after-rx_bytes_before)) periodtime=$(($((time2-time1))*1000000)) $UCI_SET_BBFDM dmmap_diagnostics.upload.DiagnosticState=Complete $UCI_SET_BBFDM dmmap_diagnostics.upload.TestBytesSent=$size $UCI_SET_BBFDM dmmap_diagnostics.upload.TotalBytesReceived=$rx_bytes $UCI_SET_BBFDM dmmap_diagnostics.upload.TotalBytesSent=$tx_bytes $UCI_SET_BBFDM dmmap_diagnostics.upload.PeriodOfFullLoading=$periodtime local perconnection=`$UCI_GET_BBFDM dmmap_diagnostics.upload.EnablePerConnection` if ([ "$perconnection" == "true" ] || [ "$perconnection" == "1" ]); then $UCI_ADD_BBFDM dmmap_diagnostics UploadPerConnection $UCI_SET_BBFDM dmmap_diagnostics.@UploadPerConnection[0].TestBytesSent=$size $UCI_SET_BBFDM dmmap_diagnostics.@UploadPerConnection[0].TotalBytesReceived=$rx_bytes $UCI_SET_BBFDM dmmap_diagnostics.@UploadPerConnection[0].TotalBytesSent=$tx_bytes else $UCI_DELETE_BBFDM dmmap_diagnostics.@UploadPerConnection[0] fi $UCI_COMMIT_BBFDM rm ${UPLOAD_DIAGNOSTIC_FILE} &>/dev/null sleep 3 local pids=`ps | grep $PID` kill $PID &>/dev/null # Enable acceleration on Broadcom devices after killing the tcpdump pid [ -e /usr/sbin/fcctl ] && { fcctl enable >/dev/null 2>&1; fcctl flush >/dev/null 2>&1; } } upload_stop_diagnostic() { $UCI_DELETE_BBFDM dmmap_diagnostics.@UploadPerConnection[0] local pids=`ps | grep upload_launch.*run | grep -v grep | awk '{print $1}'` if [ -n "$pids" ]; then kill -9 $pids &>/dev/null $UCI_SET_BBFDM dmmap_diagnostics.upload.DiagnosticState=None fi local pids=`ps | grep upload_launch.*run | grep -v grep | awk '{print $1}'` if [ -n "$pids" ]; then kids=$(grep -l "PPid.*$pids" /proc/*/task/*/status | grep -o "[0-9]*") for kid in $kids; do kill -9 $kid &>/dev/null done kill -9 $pids &>/dev/null $UCI_SET_BBFDM dmmap_diagnostics.upload.DiagnosticState=None fi $UCI_COMMIT_BBFDM } if [ "$1" == "run" ] ; then upload_launch $2 $3 $4 $5 elif [ "$1" == "stop" ]; then upload_stop_diagnostic else return fi