Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/bin/sh -x
- #
- # Tomato STM Monitor v1.12art
- # Written by tievolu
- # http://www.tievolu.co.uk/stm/stm-monitor.html
- #
- # This script is for use on routers running Tomato, connected to the
- # Internet through a Virgin Media UK cable connection. VM's cable
- # connections implement Subscriber Traffic Management (STM) i.e. the
- # WAN bandwidth is limited for a set time (typically five hours) when
- # a predefined amount of data is transferred between certain hours of
- # the day.
- #
- # It allows the WAN bandwidth usage to be automatically monitored and
- # suitable QOS settings applied. There are three modes of operation:
- #
- # 1. STM Mitigation
- #
- # This is the default mode. If an STM limit is exceeded, QOS limits
- # are applied in accordance with the bandwidth limits imposed by STM.
- #
- # 2. STM Prevention
- #
- # If bandwidth usage is on target to exceed an STM limit, QOS limits
- # are applied to prevent that from happening. Activated by the "-p"
- # option (see below), and controlled by the STM Prevention Threshold
- # (default 80% of STM limit).
- #
- # 3. Intelligent STM Prevention/Mitigation
- #
- # If bandwidth usage is on target to exceed an STM limit, the script
- # analyses the two available options to see which is better - i.e.
- # either applying STM Prevention, or allowing STM to be triggered and
- # mitigating it. It makes the decision by calculating which option
- # will allow more data to be transferred in the long term.
- #
- # Add the following to your "WAN Up" script to download the script and
- # set it to run every two minutes:
- #
- # wget -O /tmp/stm-monitor.sh http://www.tievolu.co.uk/stm/stm-monitor.sh
- # chmod 755 /tmp/stm-monitor.sh
- # cru a STM-Monitor "1-59/2 * * * * /tmp/stm-monitor.sh [broadband type] [-p|-i]"
- # logger -t STM-Monitor "Downloaded `head /tmp/stm-monitor.sh | grep \"STM Monitor\" | sed 's/# //g'`"
- #
- # Where [broadband type] = "S5", "M", "L", "XL", "ML20", "L30", "XL30", "XXL", "XL60" or "XXL100" (no quotes)
- # [-p] = Activates STM prevention
- # [-i] = Activates Intelligent STM Prevention/Mitigation
- #
- # Note: Default tier settings assume that your upload speed has been upgraded
- # to the latest 2012 levels, as described here:
- #
- # http://help.virginmedia.com/system/...E=Cable&CMD=VIEW_ARTICLE&ARTICLE_ID=2781#tier
- #
- # You can also add the following code to your WAN up script, which allows you
- # to customise some of the settings:
- #
- # echo "STM_PERIOD_BW_LIMIT_1=" >> /tmp/stm-monitor.cfg
- # echo "STM_PERIOD_BW_LIMIT_2=" >> /tmp/stm-monitor.cfg
- # echo "STM_PERIOD_BW_LIMIT_3=" >> /tmp/stm-monitor.cfg
- # echo "STM_PREVENTION_THRESHOLD=" >> /tmp/stm-monitor.cfg
- # echo "STM_INBOUND_BANDWIDTH_WITHOUT_STM=" >> /tmp/stm-monitor.cfg
- # echo "STM_INBOUND_BANDWIDTH_WITH_STM=" >> /tmp/stm-monitor.cfg
- # echo "STM_OUTBOUND_BANDWIDTH_WITHOUT_STM=" >> /tmp/stm-monitor.cfg
- # echo "STM_OUTBOUND_BANDWIDTH_WITH_STM=" >> /tmp/stm-monitor.cfg
- #
- # For example, to set the STM prevention threshold to 50%:
- #
- # echo "STM_PREVENTION_THRESHOLD=50" >> /tmp/stm-monitor.cfg
- #
- # Events are recorded in the system log, and details are displayed in a
- # small web page located at:
- #
- # http://[router IP address]/ext/stm-monitor.htm
- #
- # The script assumes that the time on your router is accurate to within
- # a minute or so, so make sure your NTP settings are correct! It also only
- # works correcly if your router is left on throughout each STM period,
- # because rebooting destroys the Tomato bandwidth stats this script relies on.
- # Logging command
- LOGGER="logger -t STM-Monitor"
- # STM Monitor version
- path_to_directory=`pwd`
- stm_monitor_version=`head $path_to_directory/stm-monitor.sh | grep "STM Monitor" | sed 's/# //g'`
- # Check command line arguments
- if [[ "$1" != "S5" && "$1" != "M" && "$1" != "L" && "$1" != "XL" && "$1" != "ML20" && "$1" != "L30" && "$1" != "XL30" && "$1" != "XXL" && "$1" != "XL60" && "$1" != "XXL100" ]]
- then
- $LOGGER "Usage: stm-monitor.sh [S5|M|L|XL|ML20|L30|XL30|XXL|XL60|XXL100] [-p|-i] [-f] BACK-UP_FILE"
- exit
- fi
- bandwith_type=$1
- # Default settings for not-specified parameters
- stm_prevention=0
- intelligent=0
- use_backup=0
- while [ $# -gt 1 ]; do
- case $2 in
- -p)
- stm_prevention=1 # Enable STM prevention if specified
- shift
- ;;
- -i)
- intelligent=1 # Enable Intelligent STM Prevention/Mitigation if specified
- shift
- ;;
- -f)
- shift
- if [ $# -gt 1 ]; then
- export backup_file=$2
- if [ ! -w $backup_file ]; then
- echo "back-up file not writable"
- exit 1
- fi
- else
- echo "no back-up file specified"
- exit 1
- fi
- use_backup=1 # Enable back-up of rstats statistics in case of router reset
- shift
- ;;
- *)
- break
- ;;
- esac
- done
- # The upload QOS bandwidth values are set at ~91% of the cable modem
- # bandwidth limiter (download set at 100%), which works well for my
- # connection. Cable connections tend to be pretty stable so they should work
- # ok for most users. The STM related variables are based on the information
- # published by VM here: http://allyours.virginmedia.com/html/internet/traffic.html
- # STM period definitions (time values are hours of the day e.g. 16 = 16:00 = 4pm)
- stm_period_name_1="Daytime Downstream"
- stm_period_start_1=10
- stm_period_end_1=15
- stm_period_direction_1="RX"
- stm_period_name_2="Evening Downstream"
- stm_period_start_2=16
- stm_period_end_2=21
- stm_period_direction_2="RX"
- stm_period_name_3="Evening Upstream"
- stm_period_start_3=15
- stm_period_end_3=20
- stm_period_direction_3="TX"
- # STM sentence length (i.e. how long STM lasts for once it's triggered)
- stm_sentence_length_hours=5
- stm_sentence_length_seconds=`expr $stm_sentence_length_hours \* 3600`
- # Settings specific to XXL100 (100Mb down, 10Mb up)
- if [[ $bandwith_type = "XXL100" ]]
- then
- # STM limits (values in MB)
- stm_period_bw_limit_mb_1=20000
- stm_period_bw_limit_mb_2=10000
- stm_period_bw_limit_mb_3=12000
- # QOS settings (values in Kbits/s)
- inbound_bandwidth_without_stm=102400 # Not sure if this is accurate
- inbound_bandwidth_with_stm=51200
- outbound_bandwidth_without_stm=9318 # 10240 * 0.91
- outbound_bandwidth_with_stm=2330 # 9318 * 0.25
- fi
- # Settings specific to XL60 (60Mb down, 6Mb up)
- if [[ $bandwith_type = "XL60" ]]
- then
- # STM limits (values in MB)
- stm_period_bw_limit_mb_1=10000
- stm_period_bw_limit_mb_2=5000
- stm_period_bw_limit_mb_3=7000
- # QOS settings (values in Kbits/s)
- inbound_bandwidth_without_stm=64453 # 66000000 bps
- inbound_bandwidth_with_stm=30720
- outbound_bandwidth_without_stm=5591 # 6144 * 0.91
- outbound_bandwidth_with_stm=1398 # 5591 * 0.25
- fi
- # Settings specific to XXL (50Mb down, 5Mb up)
- if [[ $bandwith_type = "XXL" ]]
- then
- # STM limits (values in MB)
- stm_period_bw_limit_mb_1=10000
- stm_period_bw_limit_mb_2=5000
- stm_period_bw_limit_mb_3=6000
- # QOS settings (values in Kbits/s)
- inbound_bandwidth_without_stm=51757 # 53000000 bps
- inbound_bandwidth_with_stm=25879
- outbound_bandwidth_without_stm=4659 # 5120 * 0.91
- outbound_bandwidth_with_stm=1630 # 4659 * 0.25
- fi
- # Settings specific to XL30 (30Mb down, 3Mb up)
- if [[ $bandwith_type = "XL30" ]]
- then
- # STM limits (values in MB)
- stm_period_bw_limit_mb_1=7000
- stm_period_bw_limit_mb_2=3500
- stm_period_bw_limit_mb_3=4200
- # QOS settings (values in Kbits/s)
- inbound_bandwidth_without_stm=32548 # 33330000 b/s
- inbound_bandwidth_with_stm=16274
- outbound_bandwidth_without_stm=2962 # 3333000 b/s * 0.91
- outbound_bandwidth_with_stm=740 # 2962 * 0.25
- fi
- # Settings specific to L30 (30Mb down, 3Mb up)
- if [[ $bandwith_type = "L30" ]]
- then
- # STM limits (values in MB)
- stm_period_bw_limit_mb_1=7000
- stm_period_bw_limit_mb_2=3500
- stm_period_bw_limit_mb_3=4200
- # QOS settings (values in Kbits/s)
- inbound_bandwidth_without_stm=32548 # 33330000 b/s
- inbound_bandwidth_with_stm=16274
- outbound_bandwidth_without_stm=2962 # 3333000 b/s * 0.91
- outbound_bandwidth_with_stm=740 # 2962 * 0.25
- fi
- # Settings specific to ML20 (20Mb down, 2Mb up)
- if [[ $bandwith_type = "ML20" ]]
- then
- # STM limits (values in MB)
- stm_period_bw_limit_mb_1=7000
- stm_period_bw_limit_mb_2=3500
- stm_period_bw_limit_mb_3=3000
- # QOS settings (values in Kbits/s)
- inbound_bandwidth_without_stm=20480
- inbound_bandwidth_with_stm=5120
- outbound_bandwidth_without_stm=1864 # 2048 * 0.91
- outbound_bandwidth_with_stm=466 # 1864 * 0.25
- fi
- # Settings specific to XL (20Mb down, 2Mb up)
- if [[ $bandwith_type = "XL" ]]
- then
- # STM limits (values in MB)
- stm_period_bw_limit_mb_1=7000
- stm_period_bw_limit_mb_2=3500
- stm_period_bw_limit_mb_3=3000
- # QOS settings (values in Kbits/s)
- inbound_bandwidth_without_stm=20480
- inbound_bandwidth_with_stm=5120
- outbound_bandwidth_without_stm=1864 # 2048 * 0.91
- outbound_bandwidth_with_stm=466 # 1864 * 0.25
- fi
- # Settings specific to L (10Mb down, 1Mb up)
- if [[ $bandwith_type = "L" ]]
- then
- # STM limits (values in MB)
- stm_period_bw_limit_mb_1=3000
- stm_period_bw_limit_mb_2=1500
- stm_period_bw_limit_mb_3=1500
- # QOS settings (values in Kbits/s)
- inbound_bandwidth_without_stm=10240
- inbound_bandwidth_with_stm=2560
- outbound_bandwidth_without_stm=932 # 1024 * 0.91
- outbound_bandwidth_with_stm=233 # 932 * 0.25
- fi
- # Settings specific to M (10Mb down, 1Mb up)
- if [[ $bandwith_type = "M" ]]
- then
- # STM limits (values in MB)
- stm_period_bw_limit_mb_1=1500
- stm_period_bw_limit_mb_2=750
- stm_period_bw_limit_mb_3=750
- # QOS settings (values in Kbits/s)
- inbound_bandwidth_without_stm=10240
- inbound_bandwidth_with_stm=2560
- outbound_bandwidth_without_stm=932 # 1024 * 0.91
- outbound_bandwidth_with_stm=233 # 932 * 0.25
- fi
- # Settings specific to S5 (5Mb down, 512Kb up)
- if [[ $bandwith_type = "S5" ]]
- then
- # STM limits (values in MB)
- stm_period_bw_limit_mb_1=500
- stm_period_bw_limit_mb_2=250
- stm_period_bw_limit_mb_3=200
- # QOS settings (values in Kbits/s)
- inbound_bandwidth_without_stm=10240
- inbound_bandwidth_with_stm=2560
- outbound_bandwidth_without_stm=932 # 1024 * 0.91
- outbound_bandwidth_with_stm=233 # 932 * 0.25
- fi
- # STM prevention threshold. STM prevention only becomes active once
- # this percentage of the STM bandwidth limit has been transferred.
- # Default for STM Prevention is 80%.
- stm_prevention_threshold=80
- # Override settings with user-defined values if valid values were specified
- if [[ -e /jffs/stm-monitor.cfg ]]
- then
- source /jffs/stm-monitor.cfg
- fi
- if [[ -e /tmp/stm-monitor.cfg ]]
- then
- source /tmp/stm-monitor.cfg
- fi
- if [[ "$STM_PERIOD_BW_LIMIT_1" != "" ]]
- then
- invalid_value=`echo "" | awk '{ if (value < 0) {print(1)} }' value=$STM_PERIOD_BW_LIMIT_1`
- if [[ "$invalid_value" = 1 ]]
- then
- $LOGGER "Invalid STM_PERIOD_BW_LIMIT_1 (${STM_PERIOD_BW_LIMIT_1} MB). Reverting to default value (${stm_period_bw_limit_mb_1} MB)."
- else
- stm_period_bw_limit_mb_1=$STM_PERIOD_BW_LIMIT_1
- fi
- fi
- if [[ "$STM_PERIOD_BW_LIMIT_2" != "" ]]
- then
- invalid_value=`echo "" | awk '{ if (value < 0) {print(1)} }' value=$STM_PERIOD_BW_LIMIT_2`
- if [[ "$invalid_value" = 1 ]]
- then
- $LOGGER "Invalid STM_PERIOD_BW_LIMIT_2 (${STM_PERIOD_BW_LIMIT_2} MB). Reverting to default value (${stm_period_bw_limit_mb_2} MB)."
- else
- stm_period_bw_limit_mb_2=$STM_PERIOD_BW_LIMIT_2
- fi
- fi
- if [[ "$STM_PERIOD_BW_LIMIT_3" != "" ]]
- then
- invalid_value=`echo "" | awk '{ if (value < 0) {print(1)} }' value=$STM_PERIOD_BW_LIMIT_3`
- if [[ "$invalid_value" = 1 ]]
- then
- $LOGGER "Invalid STM_PERIOD_BW_LIMIT_3 (${STM_PERIOD_BW_LIMIT_3} MB). Reverting to default value (${stm_period_bw_limit_mb_3} MB)."
- else
- stm_period_bw_limit_mb_3=$STM_PERIOD_BW_LIMIT_3
- fi
- fi
- if [[ "$STM_PREVENTION_THRESHOLD" != "" ]]
- then
- invalid_value=`echo "" | awk '{ if (value > 100 || value < 0) {print(1)} }' value=$STM_PREVENTION_THRESHOLD`
- if [[ "$invalid_value" = 1 ]]
- then
- $LOGGER "Invalid STM_PREVENTION_THRESHOLD (${STM_PREVENTION_THRESHOLD}%). Reverting to default value (${stm_prevention_threshold}%)."
- else
- stm_prevention_threshold=$STM_PREVENTION_THRESHOLD
- fi
- fi
- if [[ "$STM_INBOUND_BANDWIDTH_WITHOUT_STM" != "" ]]
- then
- invalid_value=`echo "" | awk '{ if (value < 0) {print(1)} }' value=$STM_INBOUND_BANDWIDTH_WITHOUT_STM`
- if [[ "$invalid_value" = 1 ]]
- then
- $LOGGER "Invalid STM_INBOUND_BANDWIDTH_WITHOUT_STM (${STM_INBOUND_BANDWIDTH_WITHOUT_STM} kb/s). Reverting to default value (${inbound_bandwidth_without_stm} kb/s)."
- else
- inbound_bandwidth_without_stm=$STM_INBOUND_BANDWIDTH_WITHOUT_STM
- fi
- fi
- if [[ "$STM_INBOUND_BANDWIDTH_WITH_STM" != "" ]]
- then
- invalid_value=`echo "" | awk '{ if (value < 0) {print(1)} }' value=$STM_INBOUND_BANDWIDTH_WITH_STM`
- if [[ "$invalid_value" = 1 ]]
- then
- $LOGGER "Invalid STM_INBOUND_BANDWIDTH_WITH_STM (${STM_INBOUND_BANDWIDTH_WITH_STM} kb/s). Reverting to default value (${inbound_bandwidth_with_stm} kb/s)."
- else
- inbound_bandwidth_with_stm=$STM_INBOUND_BANDWIDTH_WITH_STM
- fi
- fi
- if [[ "$STM_OUTBOUND_BANDWIDTH_WITHOUT_STM" != "" ]]
- then
- invalid_value=`echo "" | awk '{ if (value < 0) {print(1)} }' value=$STM_OUTBOUND_BANDWIDTH_WITHOUT_STM`
- if [[ "$invalid_value" = 1 ]]
- then
- $LOGGER "Invalid STM_OUTBOUND_BANDWIDTH_WITHOUT_STM (${STM_OUTBOUND_BANDWIDTH_WITHOUT_STM} kb/s). Reverting to default value (${outbound_bandwidth_without_stm} kb/s)."
- else
- outbound_bandwidth_without_stm=$STM_OUTBOUND_BANDWIDTH_WITHOUT_STM
- fi
- fi
- if [[ "$STM_OUTBOUND_BANDWIDTH_WITH_STM" != "" ]]
- then
- invalid_value=`echo "" | awk '{ if (value < 0) {print(1)} }' value=$STM_OUTBOUND_BANDWIDTH_WITH_STM`
- if [[ "$invalid_value" = 1 ]]
- then
- $LOGGER "Invalid STM_OUTBOUND_BANDWIDTH_WITH_STM (${STM_OUTBOUND_BANDWIDTH_WITH_STM} kb/s). Reverting to default value (${outbound_bandwidth_with_stm} kb/s)."
- else
- outbound_bandwidth_with_stm=$STM_OUTBOUND_BANDWIDTH_WITH_STM
- fi
- fi
- # Grab the current time
- current_hours=`date +%H`
- current_minutes=`date +%M`
- current_unix_time=`date +%s`
- # Set up web page. Use a string to store web page content and pipe
- # it to /var/wwwext/stm-monitor.htm when the script exits
- if [[ ! -e "/var/wwwext" ]]
- then
- mkdir /var/wwwext
- fi
- web_page="<html><head><title>${stm_monitor_version} - Status at ${current_hours}:${current_minutes}</title><meta http-equiv=\"refresh\" content=\"120\"</head>"
- web_page="${web_page}<body style=\"font-family:verdana\"><h2>${stm_monitor_version}</h2>"
- web_page="${web_page}<h3>Status at ${current_hours}:${current_minutes}</h3>"
- # Check whether we are still serving an STM sentence that has completed
- # Upstream
- if [[ "`nvram get tx_stm_sentence_active`" = 1 && $current_unix_time -gt "`nvram get tx_stm_sentence_end_unix_time`" ]]
- then
- # Return QOS configuration to non-STM settings
- $LOGGER "STM (TX) sentence served: applying normal outbound QOS configuration"
- nvram set qos_obw=$outbound_bandwidth_without_stm
- service qos restart
- # Record the time at which this sentence ended
- nvram set tx_last_stm_sentence_end_unix_time=`nvram get tx_stm_sentence_end_unix_time`
- nvram set tx_last_stm_sentence_end_time=`nvram get tx_stm_sentence_end_time`
- # Unset our NVRAM variables
- nvram unset tx_stm_sentence_active
- nvram unset tx_stm_sentence_end_time
- nvram unset tx_stm_sentence_end_unix_time
- fi
- # Downstream
- if [[ "`nvram get rx_stm_sentence_active`" = 1 && $current_unix_time -gt "`nvram get rx_stm_sentence_end_unix_time`" ]]
- then
- # Return QOS configuration to non-STM settings
- $LOGGER "STM (RX) sentence served: applying normal inbound QOS configuration"
- nvram set qos_ibw=$inbound_bandwidth_without_stm
- service qos restart
- # Record the time at which this sentence ended
- nvram set rx_last_stm_sentence_end_unix_time=`nvram get rx_stm_sentence_end_unix_time`
- nvram set rx_last_stm_sentence_end_time=`nvram get rx_stm_sentence_end_time`
- # Unset our NVRAM variables
- nvram unset rx_stm_sentence_active
- nvram unset rx_stm_sentence_end_time
- nvram unset rx_stm_sentence_end_unix_time
- fi
- # Grab current statistics from rstats and wait for the file to be written
- killall -USR1 rstats
- sleep 2
- stats_file=/var/spool/rstats-speed.js
- # Read the stats file and extract the parts we're interested in (WAN RX and TX)
- wan_interface=`nvram get wan_ifname` # Usually vlan1, but not always
- read_next_rx_tx=0
- while read line
- do
- case $line in
- *$wan_interface*) read_next_rx_tx=1 ;;
- esac
- if [[ $read_next_rx_tx = 1 ]]
- then
- case $line in
- *rx:*) rx_data=`echo $line | awk '
- {
- values_string = substr($0, index($0, "[") + 1, index($0, "]") - 6);
- print values_string
- }' ` ;;
- *tx:*) tx_data=`echo $line | awk '
- {
- values_string = substr($0, index($0, "[") + 1, index($0, "]") - 6);
- print values_string
- }' ` ; read_next_rx_tx=0; ;;
- esac
- fi
- done < $stats_file
- rm $stats_file
- if [[ $use_backup -eq 1 ]]; then
- # Read backup
- if [[ -e $backup_file ]]; then
- backup_unix_time=$(head -n 1 $backup_file) #first line
- rx_data_backup=$(head -n 2 $backup_file | tail -n 1) #second line
- tx_data_backup=$(head -n 3 $backup_file | tail -n 1) #third line
- time_difference=`expr $current_unix_time - $backup_unix_time`
- intervarls_since_backup=`expr $time_difference / 120`
- if [[ $intervarls_since_backup -gt 720 ]]; then
- intervarls_since_backup=720
- fi
- rx_data_from_back_up=`echo $rx_data_backup | awk '
- {
- split($0, values_array, ",");
- for (i=intervarls_since_backup+1; i<=720; i++) {
- if(i==720)
- deliminator=""
- else
- deliminator=","
- buffer = buffer""values_array[i]""deliminator;
- } print buffer;
- }' intervarls_since_backup=$intervarls_since_backup`
- tx_data_from_back_up=`echo $tx_data_backup | awk '
- {
- split($0, values_array, ",");
- for (i=intervarls_since_backup+1; i<=720; i++) {
- if(i==720)
- deliminator=""
- else
- deliminator=","
- buffer = buffer""values_array[i]""deliminator;
- } print buffer;
- }' intervarls_since_backup=$intervarls_since_backup`
- rx_data_from_rstats=`echo $rx_data | awk '
- {
- split($0, values_array, ",");
- for (i=721-intervarls_since_backup; i<=720; i++) {
- if(i==720)
- deliminator=""
- else
- deliminator=","
- buffer = buffer""values_array[i]""deliminator;
- } print buffer;
- }' intervarls_since_backup=$intervarls_since_backup`
- tx_data_from_rstats=`echo $tx_data | awk '
- {
- split($0, values_array, ",");
- for (i=721-intervarls_since_backup; i<=720; i++) {
- if(i==720)
- deliminator=""
- else
- deliminator=","
- buffer = buffer""values_array[i]""deliminator;
- } print buffer;
- }' intervarls_since_backup=$intervarls_since_backup`
- if [[ $rx_data_from_back_up != "" && $rx_data_from_rstats != "" ]];
- then deliminator=","
- else
- deliminator=""
- fi
- rx_data="${rx_data_from_back_up}${deliminator}${rx_data_from_rstats}"
- if [[ $tx_data_from_back_up != "" && $tx_data_from_rstats != "" ]];
- then deliminator=","
- else
- deliminator=""
- fi
- tx_data="${tx_data_from_back_up}${deliminator}${tx_data_from_rstats}"
- fi
- backup_page="${current_unix_time}\n"
- backup_page="${backup_page}${rx_data}\n"
- backup_page="${backup_page}${tx_data}\n"
- # Writing backup file
- echo -e $backup_page > $backup_file
- fi
- # Check which STM periods are active, check total TX/RX against
- # STM limits and note if an STM limit was exceeded
- tx_stm_sentence_triggered=0
- rx_stm_sentence_triggered=0
- add_adjustment_note=0
- web_page="${web_page}<table cellpadding=9 cellspacing=3 border=0>"
- web_page="${web_page}<tr align=\"center\" bgcolor=\"DDDDFF\"><th>STM Description<th>Start</th><th>End</th><th>Bandwidth Limit</th><th>Bandwidth Used</th><th>Average Rate</th></tr>"
- for i in 1 2 3; do
- stm_period_name=`eval echo "\\$stm_period_name_${i}"`
- stm_period_start=`eval echo "\\$stm_period_start_${i}"`
- stm_period_end=`eval echo "\\$stm_period_end_${i}"`
- stm_period_direction=`eval echo "\\$stm_period_direction_${i}"`
- stm_period_bw_limit_mb=`eval echo "\\$stm_period_bw_limit_mb_${i}"`
- if [[ $current_hours -ge $stm_period_start && $current_hours -lt $stm_period_end ]]
- then
- # This STM period is active.
- web_page="${web_page}<tr bgcolor=\"EEEEEE\" align=\"center\">"
- web_page="${web_page}<td align=\"left\">${stm_period_name} ($bandwith_type)</td><td>${stm_period_start}:00</td><td>${stm_period_end}:00</td><td>${stm_period_bw_limit_mb} MB</td>"
- # Setup a few RX/TX dependent variables
- if [[ $stm_period_direction = "RX" ]]
- then
- data=$rx_data
- stm_period_rx_active=1
- stm_sentence_active=`nvram get rx_stm_sentence_active`
- last_stm_sentence_end_unix_time=`nvram get rx_last_stm_sentence_end_unix_time`
- else
- data=$tx_data
- stm_period_tx_active=1
- stm_sentence_active=`nvram get tx_stm_sentence_active`
- last_stm_sentence_end_unix_time=`nvram get tx_last_stm_sentence_end_unix_time`
- fi
- # Calculate the number of minutes since the STM period started, or since the last STM sentence
- # ended (whichever happened more recently).
- # Then calculate the number of values to take from the rstats data (each value covers two minutes)
- minutes_since_stm_period_started=`echo "" | awk '{ printf("%0.f", (((hours - stm_start) * 60) + minutes)); }' hours=$current_hours minutes=$current_minutes stm_start=${stm_period_start}`
- if [[ "$last_stm_sentence_end_unix_time" != "" ]]
- then
- minutes_since_last_stm_sentence_ended=`echo "" | awk '{ printf("%0.f", (current - sentence_end) / 60); }' current=$current_unix_time sentence_end=$last_stm_sentence_end_unix_time`
- if [[ $minutes_since_last_stm_sentence_ended -lt $minutes_since_stm_period_started ]]
- then
- # Need to calculate the number of seconds to subtract from the length of the
- # STM period when we do the maximum average rate calculation later on
- max_rate_adjustment=`echo "" | awk '{ print((mins_since_stm_start - mins_since_sentence_end) * 60); }' mins_since_stm_start=$minutes_since_stm_period_started mins_since_sentence_end=$minutes_since_last_stm_sentence_ended`
- number_of_values=`expr $minutes_since_last_stm_sentence_ended / 2`
- else
- # Don't need to adjust the rate calculation
- max_rate_adjustment=0
- number_of_values=`expr $minutes_since_stm_period_started / 2`
- fi
- else
- # Don't need to adjust the rate calculation
- max_rate_adjustment=0
- number_of_values=`expr $minutes_since_stm_period_started / 2`
- fi
- # Extract the useful numbers from the rstats data
- if [[ $number_of_values != 0 ]]
- then
- # Sum the last XXX values of the 720 in the rstats data to get the
- # total bytes transferred since the STM period started (or since the last
- # STM sentence ended)
- total_transferred_bytes=`echo $data | awk '
- {
- split($0, values_array, ",");
- for (i=(721-number_of_values); i<=720; i++) {
- total += values_array[i];
- } printf("%0.f" total);
- }' number_of_values=$number_of_values total=0`
- total_transferred_mb=`echo "" | awk '{ printf("%.2f", bytes / 1048576) }' bytes=$total_transferred_bytes`
- average_rate=`echo "" | awk '{ printf("%.2f", bytes / (number_of_values * 2 * 60 * 1024)) }' number_of_values=$number_of_values bytes=$total_transferred_bytes`
- average_rate_kilobits=`echo "" | awk '{printf("%.2f", rate_kilobytes * 8)}' rate_kilobytes=$average_rate`
- else
- total_transferred_bytes="0"
- total_transferred_mb="0.00"
- average_rate="0.00"
- average_rate_kilobits="0.00"
- fi
- # Calculate maximum average rate (i.e. rate required to trigger STM),
- # then compare this to our actual rate. If the actual rate is equal or
- # higher, we paint the cell red, if it's greater than 90% of the max
- # we paint it amber, and if it's anything else we paint it green.
- stm_period_max_ave_rate=`echo "" | awk '{printf((limit * 1024) / (((end - start)*3600) - adjustment))}' limit=$stm_period_bw_limit_mb start=$stm_period_start end=$stm_period_end adjustment=$max_rate_adjustment`
- cell_color=`echo | awk '{ if (rate >= max) {print("FF6633")} else if (rate > (0.9 * max)) {print("FFCC33")} else {print("66FF33")}}' rate=$average_rate max=$stm_period_max_ave_rate`
- # STM Prevention code
- if [[ $stm_prevention = 1 && "$stm_sentence_active" != 1 ]]
- then
- exceeded_stm_prevention_threshold=`echo "" | awk '{ if (transferred > (limit * (threshold/100))) {print("1")} else {print("0")} }' transferred=$total_transferred_mb limit=$stm_period_bw_limit_mb threshold=$stm_prevention_threshold`
- if [[ $cell_color = "FF6633" && $exceeded_stm_prevention_threshold = 1 && "$stm_sentence_active" != 1 ]]
- then
- # Cell is red => calculate preventative QOS limit
- # Calculate the number of kilobits we have left before we trigger STM
- total_kilobits_remaining=`echo "" | awk '{print(((limit*1048576)-total)/128)}' limit=$stm_period_bw_limit_mb total=$total_transferred_bytes`
- # Calculate time remaining until end of STM period
- seconds_remaining=`echo "" | awk '{print(((end_hour - current_hour - 1) * 3600) + (3600 - (60 * current_minute)))}' end_hour=$stm_period_end current_hour=$current_hours current_minute=$current_minutes`
- # Calculate a QOS limit such that we'll transfer a maximum of 90% (TX) or 50% (RX) of the remaining allowance in the remaining time
- # It has to be as harsh as 50% to work properly for RX. If it's set any higher it won't work because VM counts all the data that
- # arrives at the router before QOS throws it away in accordance with the temporary limit we've imposed. I've done extensive testing
- # and 50-55% is about as high as you can go.
- if [[ $stm_period_direction = RX ]]
- then
- preventative_qos_limit=`echo "" | awk '{printf("%.0f", 0.5*(kilobits/secs))}' kilobits=$total_kilobits_remaining secs=$seconds_remaining`
- else
- preventative_qos_limit=`echo "" | awk '{printf("%.0f", 0.9*(kilobits/secs))}' kilobits=$total_kilobits_remaining secs=$seconds_remaining`
- fi
- if [[ $intelligent = 1 ]]
- then
- # Check whether we're actually better off NOT preventing STM
- seconds_until_stm_is_triggered=`echo "" | awk '{ printf("%0.f", kilobits / rate) }' kilobits=$total_kilobits_remaining rate=$average_rate_kilobits`
- total_assessment_time=`echo "" | awk '{printf("%0.f", seconds_until_stm + sentence_length)}' seconds_until_stm=$seconds_until_stm_is_triggered sentence_length=$stm_sentence_length_seconds`
- if [[ $stm_period_direction = "RX" ]]
- then
- potential_kilobits_transferred_without_stm_prevention=`echo "" | awk '{ print((no_stm_rate * seconds_until_stm) + (stm_rate * sentence_length)) }' no_stm_rate=$inbound_bandwidth_without_stm stm_rate=$inbound_bandwidth_with_stm sentence_length=$stm_sentence_length_seconds seconds_until_stm=$seconds_until_stm_is_triggered`
- potential_kilobits_transferred_with_stm_prevention=`echo "" | awk '{ print((seconds_remaining * proposed_limit) + ((total_assessment_time - seconds_remaining) * no_stm_rate)) }' seconds_remaining=$seconds_remaining total_assessment_time=$total_assessment_time proposed_limit=$preventative_qos_limit no_stm_rate=$inbound_bandwidth_without_stm`
- else
- potential_kilobits_transferred_without_stm_prevention=`echo "" | awk '{ print((no_stm_rate * seconds_until_stm) + (stm_rate * sentence_length)) }' no_stm_rate=$outbound_bandwidth_without_stm stm_rate=$outbound_bandwidth_with_stm sentence_length=$stm_sentence_length_seconds seconds_until_stm=$seconds_until_stm_is_triggered`
- potential_kilobits_transferred_with_stm_prevention=`echo "" | awk '{ print((seconds_remaining * proposed_limit) + ((total_assessment_time - seconds_remaining) * no_stm_rate)) }' seconds_remaining=$seconds_remaining total_assessment_time=$total_assessment_time proposed_limit=$preventative_qos_limit no_stm_rate=$outbound_bandwidth_without_stm`
- fi
- stm_prevention_is_beneficial=`echo "" | awk '{if (with_prevention > without_prevention) {print(1)} else {print(0)}}' with_prevention=$potential_kilobits_transferred_with_stm_prevention without_prevention=$potential_kilobits_transferred_without_stm_prevention`
- # Compile detailed information
- total_mb_remaining=`echo "" | awk '{ printf("%.2f", bits / 8192) }' bits=$total_kilobits_remaining`
- potential_mb_transferred_without_stm_prevention=`echo "" | awk '{ printf("%.0f", bits / 8192) }' bits=$potential_kilobits_transferred_without_stm_prevention`
- potential_mb_transferred_with_stm_prevention=`echo "" | awk '{ printf("%.0f", bits / 8192) }' bits=$potential_kilobits_transferred_with_stm_prevention`
- else
- # Assume STM prevention is *always* beneficial
- stm_prevention_is_beneficial=1
- fi
- if [[ $stm_period_direction = "RX" && "`nvram get qos_ibw`" -gt $preventative_qos_limit ]]
- then
- if [[ $stm_prevention_is_beneficial = 1 ]]
- then
- $LOGGER "STM (RX) will trigger in `date -ud 00:00:${seconds_until_stm_is_triggered} +%Hh%Mm%Ss`. Potential ${stm_period_direction} over `date -ud 00:00:${total_assessment_time} +%Hh%Mm%Ss` with/without STM Prevention: ${potential_mb_transferred_with_stm_prevention} MB / ${potential_mb_transferred_without_stm_prevention} MB => STM Prevention is beneficial."
- $LOGGER "Setting preventative inbound QOS limit of $preventative_qos_limit kbits/s"
- nvram set qos_ibw=$preventative_qos_limit
- # We must set the inbound rate limits to 100% or less for this to work ("None" will not work
- # because the rate will not be limited). To make sure this does work, we'll change the
- # settings to 100% across the board and restore the old settings when we remove the
- # temporary QOS limit.
- nvram set qos_irates_old=`nvram get qos_irates`
- nvram set qos_irates=100,100,100,100,100,100,100,100,100,100
- service qos restart
- else
- $LOGGER "STM (RX) will trigger in `date -ud 00:00:${seconds_until_stm_is_triggered} +%Hh%Mm%Ss`. Potential ${stm_period_direction} over `date -ud 00:00:${total_assessment_time} +%Hh%Mm%Ss` with/without STM Prevention: ${potential_mb_transferred_with_stm_prevention} MB / ${potential_mb_transferred_without_stm_prevention} MB => STM Prevention is not beneficial."
- fi
- fi
- if [[ $stm_period_direction = "TX" && "`nvram get qos_obw`" -gt $preventative_qos_limit ]]
- then
- if [[ $stm_prevention_is_beneficial = 1 ]]
- then
- $LOGGER "STM (TX) will trigger in `date -ud 00:00:${seconds_until_stm_is_triggered} +%Hh%Mm%Ss`. Potential ${stm_period_direction} over `date -ud 00:00:${total_assessment_time} +%Hh%Mm%Ss` with/without STM Prevention: ${potential_mb_transferred_with_stm_prevention} MB / ${potential_mb_transferred_without_stm_prevention} MB => STM Prevention is beneficial."
- $LOGGER "Setting preventative outbound QOS limit of $preventative_qos_limit kbits/s"
- nvram set qos_obw=$preventative_qos_limit
- service qos restart
- else
- $LOGGER "STM (TX) will trigger in `date -ud 00:00:${seconds_until_stm_is_triggered} +%Hh%Mm%Ss`. Potential ${stm_period_direction} over `date -ud 00:00:${total_assessment_time} +%Hh%Mm%Ss` with/without STM Prevention: ${potential_mb_transferred_with_stm_prevention} MB / ${potential_mb_transferred_without_stm_prevention} MB => STM Prevention is not beneficial."
- fi
- fi
- fi
- # Remove STM Prevention QOS settings if the cell is green
- if [[ $cell_color = "66FF33" && "$stm_sentence_active" != 1 ]]
- then
- if [[ $stm_period_direction = "RX" && "`nvram get qos_ibw`" != $inbound_bandwidth_without_stm ]]
- then
- $LOGGER "Removing preventative inbound QOS limit"
- nvram set qos_ibw=$inbound_bandwidth_without_stm
- nvram set qos_irates=`nvram get qos_irates_old`
- nvram unset qos_irates_old
- service qos restart
- fi
- if [[ $stm_period_direction = "TX" && "`nvram get qos_obw`" != $outbound_bandwidth_without_stm ]]
- then
- $LOGGER "Removing preventative outbound QOS limit"
- nvram set qos_obw=$outbound_bandwidth_without_stm
- service qos restart
- fi
- fi
- fi # End of STM prevention code
- # Add data to web page
- total_transferred_mb_percent=`echo "" | awk '{ printf("%.0f", (transferred / limit) * 100) }' transferred=$total_transferred_mb limit=$stm_period_bw_limit_mb`
- if [[ $max_rate_adjustment != 0 ]]
- then
- # Add link to note explaining adjusted figures
- web_page="${web_page}<td>${total_transferred_mb} MB (${total_transferred_mb_percent}%) *</td><td bgcolor=\"${cell_color}\">${average_rate} KB/s (${average_rate_kilobits} kb/s) *</td>"
- add_adjustment_note=1
- else
- web_page="${web_page}<td>${total_transferred_mb} MB (${total_transferred_mb_percent}%)</td><td bgcolor=\"${cell_color}\">${average_rate} KB/s (${average_rate_kilobits} kb/s)</td>"
- fi
- # Check whether STM limit has been exceeded
- stm_period_bw_limit_bytes=`expr $stm_period_bw_limit_mb \* 1048576`
- result=`echo "" | awk '{ if (total > limit) {print(1)} else {print(0)}}' total=$total_transferred_bytes limit=$stm_period_bw_limit_bytes`
- if [[ $result = 1 && "$stm_sentence_active" != 1 ]]
- then
- if [[ $stm_period_direction = "RX" ]]
- then
- rx_stm_sentence_triggered=1
- nvram set rx_stm_sentence_active=1
- else
- tx_stm_sentence_triggered=1
- nvram set tx_stm_sentence_active=1
- fi
- $LOGGER "STM (${stm_period_direction}) triggered: ${stm_period_name} (${stm_period_start}:00 -> ${stm_period_end}:00, ${stm_period_bw_limit_mb} MB)"
- fi
- else
- # This STM period is not currently active
- web_page="${web_page}<tr bgcolor=\"EEEEEE\" style=\"color:AAAAAA\" align=\"center\">"
- web_page="${web_page}<td align=\"left\">${stm_period_name} ($bandwith_type)</td><td>${stm_period_start}:00</td><td>${stm_period_end}:00</td><td>${stm_period_bw_limit_mb} MB</td><td>N/A</td><td>N/A</td>"
- fi
- web_page="${web_page}</tr>"
- done
- web_page="${web_page}</table>"
- # If some of the rate figures were adjusted due to a recent STM setence, add a note to make this clear
- if [[ $add_adjustment_note = 1 ]]
- then
- web_page="${web_page}<p><small>* This data was calculated from the end of the last STM sentence, rather than from the beginning of the STM period.</small></p>"
- fi
- # Remove RX/TX STM Prevention QOS limits if necessary. This code makes sure the temporary limits
- # are removed when they are not relevant (i.e. when we're not in an STM period and STM has not
- # been triggered)
- if [[ $stm_prevention = 1 ]]
- then
- if [[ "`nvram get rx_stm_sentence_active`" != 1 && "$stm_period_rx_active" != 1 && "`nvram get qos_ibw`" != $inbound_bandwidth_without_stm ]]
- then
- $LOGGER "Removing preventative inbound QOS limit"
- nvram set qos_ibw=$inbound_bandwidth_without_stm
- nvram set qos_irates=`nvram get qos_irates_old`
- nvram unset qos_irates_old
- service qos restart
- fi
- if [[ "`nvram get tx_stm_sentence_active`" != 1 && "$stm_period_tx_active" != 1 && "`nvram get qos_obw`" != $outbound_bandwidth_without_stm ]]
- then
- $LOGGER "Removing preventative outbound QOS limit"
- nvram set qos_obw=$outbound_bandwidth_without_stm
- service qos restart
- fi
- fi
- # If STM is active, check whether QOS is set accordingly
- # Upstream
- if [[ "`nvram get tx_stm_sentence_active`" = 1 && "`nvram get qos_obw`" != $outbound_bandwidth_with_stm ]]
- then
- if [[ $tx_stm_sentence_triggered = 1 ]]
- then
- # We must have triggered an STM sentence on this run.
- # Work out the hour component of the time the STM sentence will end
- # (for logging purposes only - we will use unix time to track the
- # STM sentence accurately)
- tx_stm_end_hour=`expr $current_hours + $stm_sentence_length_hours`
- if [[ $tx_stm_end_hour -gt 23 ]]
- then
- tx_stm_end_hour="0`expr $stm_end_hour - 24`"
- fi
- # Set NVRAM variables to describe the STM sentence being served
- nvram set tx_stm_sentence_end_time="$stm_end_hour:$current_minutes"
- nvram set tx_stm_sentence_end_unix_time=`expr $current_unix_time + $stm_sentence_length_seconds`
- $LOGGER "STM (TX) sentence started: applying STM outbound QOS configuration (until $stm_end_hour:$current_minutes)"
- else
- # An STM sentence is active and we didn't trigger it on this run,
- # but the QOS settings are wrong. We must have rebooted, or someone
- # messed with the QOS settings. So we want to set the QOS settings
- # to deal with the STM, but we don't want to overwrite our NVRAM
- # variables.
- $LOGGER "STM (TX) sentence resumed: applying STM outbound QOS configuration (until `nvram get tx_stm_sentence_end_time`)"
- fi
- # Apply STM QOS settings
- nvram set qos_obw=$outbound_bandwidth_with_stm
- service qos restart
- fi
- # Downstream
- if [[ "`nvram get rx_stm_sentence_active`" = 1 && "`nvram get qos_ibw`" != $inbound_bandwidth_with_stm ]]
- then
- if [[ $rx_stm_sentence_triggered = 1 ]]
- then
- # We must have triggered an STM sentence on this run.
- # Work out the hour component of the time the STM sentence will end
- # (for logging purposes only - we will use unix time to track the
- # STM sentence accurately)
- rx_stm_end_hour=`expr $current_hours + $stm_sentence_length_hours`
- if [[ $rx_stm_end_hour -gt 23 ]]
- then
- rx_stm_end_hour="0`expr $stm_end_hour - 24`"
- fi
- # Set NVRAM variables to describe the STM sentence being served
- nvram set rx_stm_sentence_end_time="$stm_end_hour:$current_minutes"
- nvram set rx_stm_sentence_end_unix_time=`expr $current_unix_time + $stm_sentence_length_seconds`
- $LOGGER "STM (RX) sentence started: applying STM inbound QOS configuration (until $stm_end_hour:$current_minutes)"
- else
- # An STM sentence is active and we didn't trigger it on this run,
- # but the QOS settings are wrong. We must have rebooted, or someone
- # messed with the QOS settings. So we want to set the QOS settings
- # to deal with the STM, but we don't want to overwrite our NVRAM
- # variables.
- $LOGGER "STM (RX) sentence resumed: applying STM inbound QOS configuration (until `nvram get rx_stm_sentence_end_time`)"
- fi
- # Apply STM QOS settings
- nvram set qos_ibw=$inbound_bandwidth_with_stm
- service qos restart
- fi
- # Add status to the web page
- if [[ $intelligent = 1 ]]
- then
- web_page="${web_page}<h4>Intelligent STM Prevention: "
- else
- web_page="${web_page}<h4>STM Prevention: "
- fi
- if [[ $stm_prevention = 1 ]]
- then
- if [[ "`nvram get qos_ibw`" = $inbound_bandwidth_without_stm && "`nvram get qos_obw`" = $outbound_bandwidth_without_stm ]]
- then
- web_page="${web_page}<b style=\"color:green\">Inactive</b></h4>"
- else
- if [[ "`nvram get rx_stm_sentence_active`" != 1 && "`nvram get tx_stm_sentence_active`" != 1 && "`nvram get qos_ibw`" != $inbound_bandwidth_without_stm && "`nvram get qos_obw`" != $outbound_bandwidth_without_stm ]]
- then
- web_page="${web_page}<b style=\"color:red\">Active (inbound and outbound)</b></h4>"
- else
- if [[ "`nvram get rx_stm_sentence_active`" != 1 && "`nvram get qos_ibw`" != $inbound_bandwidth_without_stm ]]
- then
- web_page="${web_page}<b style=\"color:red\">Active (inbound)</b></h4>"
- fi
- if [[ "`nvram get tx_stm_sentence_active`" != 1 && "`nvram get qos_obw`" != $outbound_bandwidth_without_stm ]]
- then
- web_page="${web_page}<b style=\"color:red\">Active (outbound)</b></h4>"
- fi
- fi
- fi
- else
- web_page="${web_page}<b style=\"color:CCCCCC\">Not enabled</b></h4>"
- fi
- if [[ $intelligent = 1 ]]
- then
- web_page="${web_page}<h4>Intelligent STM Mitigation: "
- else
- web_page="${web_page}<h4>STM Mitigation: "
- fi
- if [[ "`nvram get tx_stm_sentence_active`" = 1 ]]
- then
- if [[ "`nvram get rx_stm_sentence_active`" = 1 ]]
- then
- # Serving an STM sentence for both RX and TX
- web_page="${web_page}<b style=\"color:red\">Active - Upstream/Downstream STM sentences will end at `nvram get tx_stm_sentence_end_time`/`nvram get rx_stm_sentence_end_time`</b></h4>"
- else
- # Serving an STM sentence for TX only
- web_page="${web_page}<b style=\"color:red\">Active - Upstream STM sentence will end at `nvram get tx_stm_sentence_end_time`</b></h4>"
- fi
- else
- if [[ "`nvram get rx_stm_sentence_active`" = 1 ]]
- then
- # Serving an STM sentence for RX only
- web_page="${web_page}<b style=\"color:red\">Active - Downstream STM sentence will end at `nvram get rx_stm_sentence_end_time`</b></h4>"
- else
- # Not serving an STM sentence
- web_page="${web_page}<b style=\"color:green\">Inactive</b></h4>"
- fi
- fi
- web_page="${web_page}<h4>Current QOS bandwidth: <b style=\"color:blue\">`nvram get qos_ibw`</b> kb/s down, <b style=\"color:blue\">`nvram get qos_obw`</b> kb/s up</h4>"
- web_page="${web_page}<h4>Customisable settings:</h4><ul>"
- web_page="${web_page}<li>Daytime Downstream Bandwidth Limit: <font style=\"color:blue\">${stm_period_bw_limit_mb_1}</font> MB</li>"
- web_page="${web_page}<li>Evening Downstream Bandwidth Limit: <font style=\"color:blue\">${stm_period_bw_limit_mb_2}</font> MB</li>"
- web_page="${web_page}<li>Evening Upstream Bandwidth Limit: <font style=\"color:blue\">${stm_period_bw_limit_mb_3}</font> MB</li>"
- web_page="${web_page}<li>STM Prevention Threshold: <font style=\"color:blue\">${stm_prevention_threshold}</font>%</li>"
- web_page="${web_page}<li>Normal Inbound Bandwidth: <font style=\"color:blue\">${inbound_bandwidth_without_stm}</font> kb/s</li>"
- web_page="${web_page}<li>STM Inbound Bandwidth: <font style=\"color:blue\">${inbound_bandwidth_with_stm}</font> kb/s</li>"
- web_page="${web_page}<li>Normal Outbound Bandwidth: <font style=\"color:blue\">${outbound_bandwidth_without_stm}</font> kb/s</li>"
- web_page="${web_page}<li>STM Outbound Bandwidth: <font style=\"color:blue\">${outbound_bandwidth_with_stm}</font> kb/s</li>"
- web_page="${web_page}</ul>"
- # Add latest log entries to web page
- web_page="${web_page}<h3>Latest Log Entries</h3>"
- log="<nobr><tt>`cat \`ls -r /var/log/ | sed 's/messages/\/var\/log\/messages/'\` | grep STM-Monitor | sed 's/\$/<br>/g'`</tt></nobr>"
- web_page="${web_page}${log}"
- # Publish web page
- web_page="${web_page}</body></html>"
- echo $web_page > /var/wwwext/stm-monitor.htm
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement