Advertisement
Guest User

Tomato STM Monitor v1.12art

a guest
Dec 11th, 2012
54
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 41.92 KB | None | 0 0
  1. #!/bin/sh -x
  2. #
  3. # Tomato STM Monitor v1.12art
  4. # Written by tievolu
  5. # http://www.tievolu.co.uk/stm/stm-monitor.html
  6. #
  7. # This script is for use on routers running Tomato, connected to the
  8. # Internet through a Virgin Media UK cable connection. VM's cable
  9. # connections implement Subscriber Traffic Management (STM) i.e. the
  10. # WAN bandwidth is limited for a set time (typically five hours) when
  11. # a predefined amount of data is transferred between certain hours of
  12. # the day.
  13. #
  14. # It allows the WAN bandwidth usage to be automatically monitored and
  15. # suitable QOS settings applied. There are three modes of operation:
  16. #
  17. # 1. STM Mitigation
  18. #
  19. #    This is the default mode. If an STM limit is exceeded, QOS limits
  20. #    are applied in accordance with the bandwidth limits imposed by STM.
  21. #
  22. # 2. STM Prevention
  23. #
  24. #    If bandwidth usage is on target to exceed an STM limit, QOS limits
  25. #    are applied to prevent that from happening. Activated by the "-p"
  26. #    option (see below), and controlled by the STM Prevention Threshold
  27. #    (default 80% of STM limit).
  28. #
  29. # 3. Intelligent STM Prevention/Mitigation
  30. #
  31. #    If bandwidth usage is on target to exceed an STM limit, the script
  32. #    analyses the two available options to see which is better - i.e.
  33. #    either applying STM Prevention, or allowing STM to be triggered and
  34. #    mitigating it. It makes the decision by calculating which option
  35. #    will allow more data to be transferred in the long term.
  36. #
  37. # Add the following to your "WAN Up" script to download the script and
  38. # set it to run every two minutes:
  39. #
  40. #    wget -O /tmp/stm-monitor.sh http://www.tievolu.co.uk/stm/stm-monitor.sh
  41. #    chmod 755 /tmp/stm-monitor.sh
  42. #    cru a STM-Monitor "1-59/2 * * * * /tmp/stm-monitor.sh [broadband type] [-p|-i]"
  43. #    logger -t STM-Monitor "Downloaded `head /tmp/stm-monitor.sh | grep \"STM Monitor\" | sed 's/# //g'`"
  44. #
  45. #    Where [broadband type] = "S5", "M", "L", "XL", "ML20", "L30", "XL30", "XXL", "XL60" or "XXL100" (no quotes)        
  46. #                      [-p] = Activates STM prevention
  47. #                      [-i] = Activates Intelligent STM Prevention/Mitigation
  48. #
  49. # Note: Default tier settings assume that your upload speed has been upgraded
  50. # to the latest 2012 levels, as described here:
  51. #
  52. # http://help.virginmedia.com/system/...E=Cable&CMD=VIEW_ARTICLE&ARTICLE_ID=2781#tier
  53. #
  54. # You can also add the following code to your WAN up script, which allows you
  55. # to customise some of the settings:
  56. #
  57. #    echo "STM_PERIOD_BW_LIMIT_1=" >> /tmp/stm-monitor.cfg
  58. #    echo "STM_PERIOD_BW_LIMIT_2=" >> /tmp/stm-monitor.cfg
  59. #    echo "STM_PERIOD_BW_LIMIT_3=" >> /tmp/stm-monitor.cfg
  60. #    echo "STM_PREVENTION_THRESHOLD=" >> /tmp/stm-monitor.cfg
  61. #    echo "STM_INBOUND_BANDWIDTH_WITHOUT_STM=" >> /tmp/stm-monitor.cfg
  62. #    echo "STM_INBOUND_BANDWIDTH_WITH_STM=" >> /tmp/stm-monitor.cfg
  63. #    echo "STM_OUTBOUND_BANDWIDTH_WITHOUT_STM=" >> /tmp/stm-monitor.cfg
  64. #    echo "STM_OUTBOUND_BANDWIDTH_WITH_STM=" >> /tmp/stm-monitor.cfg
  65. #
  66. # For example, to set the STM prevention threshold to 50%:
  67. #
  68. #    echo "STM_PREVENTION_THRESHOLD=50" >> /tmp/stm-monitor.cfg
  69. #
  70. # Events are recorded in the system log, and details are displayed in a
  71. # small web page located at:
  72. #
  73. #    http://[router IP address]/ext/stm-monitor.htm
  74. #
  75. # The script assumes that the time on your router is accurate to within
  76. # a minute or so, so make sure your NTP settings are correct! It also only
  77. # works correcly if your router is left on throughout each STM period,
  78. # because rebooting destroys the Tomato bandwidth stats this script relies on.
  79.  
  80. # Logging command
  81. LOGGER="logger -t STM-Monitor"
  82.  
  83. # STM Monitor version
  84. path_to_directory=`pwd`
  85. stm_monitor_version=`head $path_to_directory/stm-monitor.sh | grep "STM Monitor" | sed 's/# //g'`
  86.  
  87. # Check command line arguments
  88.  
  89. if [[ "$1" != "S5" && "$1" != "M" && "$1" != "L" && "$1" != "XL" && "$1" != "ML20" && "$1" != "L30" && "$1" != "XL30" && "$1" != "XXL" && "$1" != "XL60" && "$1" != "XXL100" ]]
  90. then
  91.     $LOGGER "Usage: stm-monitor.sh [S5|M|L|XL|ML20|L30|XL30|XXL|XL60|XXL100] [-p|-i] [-f] BACK-UP_FILE"
  92.     exit
  93. fi
  94.  
  95. bandwith_type=$1
  96. # Default settings for not-specified parameters
  97. stm_prevention=0
  98. intelligent=0
  99. use_backup=0
  100.  
  101. while [ $# -gt 1 ]; do
  102.    case $2 in
  103.     -p)
  104.         stm_prevention=1 # Enable STM prevention if specified
  105.         shift
  106.     ;;
  107.         -i)
  108.         intelligent=1 # Enable Intelligent STM Prevention/Mitigation if specified
  109.         shift
  110.     ;;
  111.     -f)
  112.         shift
  113.                         if [ $# -gt 1 ]; then
  114.                                 export backup_file=$2
  115.                 if [ ! -w $backup_file ]; then
  116.                     echo "back-up file not writable"
  117.                                     exit 1
  118.                 fi
  119.                
  120.                         else
  121.                                 echo "no back-up file specified"
  122.                                 exit 1
  123.                         fi
  124.             use_backup=1 # Enable back-up of rstats statistics in case of router reset
  125.                         shift  
  126.     ;;
  127.         *)
  128.         break
  129.     ;;
  130.    esac
  131. done
  132.  
  133. # The upload QOS bandwidth values are set at ~91% of the cable modem
  134. # bandwidth limiter (download set at 100%), which works well for my
  135. # connection. Cable connections tend to be pretty stable so they should work
  136. # ok for most users. The STM related variables are based on the information
  137. # published by VM here: http://allyours.virginmedia.com/html/internet/traffic.html
  138.  
  139. # STM period definitions (time values are hours of the day e.g. 16 = 16:00 = 4pm)
  140. stm_period_name_1="Daytime Downstream"
  141. stm_period_start_1=10
  142. stm_period_end_1=15
  143. stm_period_direction_1="RX"
  144.  
  145. stm_period_name_2="Evening Downstream"
  146. stm_period_start_2=16
  147. stm_period_end_2=21
  148. stm_period_direction_2="RX"
  149.  
  150. stm_period_name_3="Evening Upstream"
  151. stm_period_start_3=15
  152. stm_period_end_3=20
  153. stm_period_direction_3="TX"
  154.  
  155. # STM sentence length (i.e. how long STM lasts for once it's triggered)
  156. stm_sentence_length_hours=5
  157. stm_sentence_length_seconds=`expr $stm_sentence_length_hours \* 3600`
  158.  
  159. # Settings specific to XXL100 (100Mb down, 10Mb up)
  160. if [[ $bandwith_type = "XXL100" ]]
  161. then
  162.     # STM limits (values in MB)
  163.     stm_period_bw_limit_mb_1=20000
  164.     stm_period_bw_limit_mb_2=10000
  165.     stm_period_bw_limit_mb_3=12000
  166.     # QOS settings (values in Kbits/s)
  167.     inbound_bandwidth_without_stm=102400 # Not sure if this is accurate
  168.     inbound_bandwidth_with_stm=51200
  169.     outbound_bandwidth_without_stm=9318 # 10240 * 0.91
  170.     outbound_bandwidth_with_stm=2330 # 9318 * 0.25
  171. fi
  172.  
  173. # Settings specific to XL60 (60Mb down, 6Mb up)
  174. if [[ $bandwith_type = "XL60" ]]
  175. then
  176.     # STM limits (values in MB)
  177.     stm_period_bw_limit_mb_1=10000
  178.     stm_period_bw_limit_mb_2=5000
  179.     stm_period_bw_limit_mb_3=7000
  180.     # QOS settings (values in Kbits/s)
  181.     inbound_bandwidth_without_stm=64453 # 66000000 bps
  182.     inbound_bandwidth_with_stm=30720
  183.     outbound_bandwidth_without_stm=5591 # 6144 * 0.91
  184.     outbound_bandwidth_with_stm=1398 # 5591 * 0.25
  185. fi
  186.  
  187. # Settings specific to XXL (50Mb down, 5Mb up)
  188. if [[ $bandwith_type = "XXL" ]]
  189. then
  190.     # STM limits (values in MB)
  191.     stm_period_bw_limit_mb_1=10000
  192.     stm_period_bw_limit_mb_2=5000
  193.     stm_period_bw_limit_mb_3=6000
  194.     # QOS settings (values in Kbits/s)
  195.     inbound_bandwidth_without_stm=51757 # 53000000 bps
  196.     inbound_bandwidth_with_stm=25879
  197.     outbound_bandwidth_without_stm=4659 # 5120 * 0.91
  198.     outbound_bandwidth_with_stm=1630 # 4659 * 0.25
  199. fi
  200.  
  201. # Settings specific to XL30 (30Mb down, 3Mb up)
  202. if [[ $bandwith_type = "XL30" ]]
  203. then
  204.     # STM limits (values in MB)
  205.     stm_period_bw_limit_mb_1=7000
  206.     stm_period_bw_limit_mb_2=3500
  207.     stm_period_bw_limit_mb_3=4200
  208.     # QOS settings (values in Kbits/s)
  209.     inbound_bandwidth_without_stm=32548 # 33330000 b/s
  210.     inbound_bandwidth_with_stm=16274
  211.     outbound_bandwidth_without_stm=2962 # 3333000 b/s * 0.91
  212.     outbound_bandwidth_with_stm=740 # 2962 * 0.25
  213. fi
  214.  
  215.  
  216. # Settings specific to L30 (30Mb down, 3Mb up)
  217. if [[ $bandwith_type = "L30" ]]
  218. then
  219.     # STM limits (values in MB)
  220.     stm_period_bw_limit_mb_1=7000
  221.     stm_period_bw_limit_mb_2=3500
  222.     stm_period_bw_limit_mb_3=4200
  223.     # QOS settings (values in Kbits/s)
  224.     inbound_bandwidth_without_stm=32548 # 33330000 b/s
  225.     inbound_bandwidth_with_stm=16274
  226.     outbound_bandwidth_without_stm=2962 # 3333000 b/s * 0.91
  227.     outbound_bandwidth_with_stm=740 # 2962 * 0.25
  228. fi
  229.  
  230. # Settings specific to ML20 (20Mb down, 2Mb up)
  231. if [[ $bandwith_type = "ML20" ]]
  232. then
  233.     # STM limits (values in MB)
  234.     stm_period_bw_limit_mb_1=7000
  235.     stm_period_bw_limit_mb_2=3500
  236.     stm_period_bw_limit_mb_3=3000
  237.     # QOS settings (values in Kbits/s)
  238.     inbound_bandwidth_without_stm=20480
  239.     inbound_bandwidth_with_stm=5120
  240.     outbound_bandwidth_without_stm=1864 # 2048 * 0.91
  241.     outbound_bandwidth_with_stm=466 # 1864 * 0.25
  242. fi
  243.  
  244. # Settings specific to XL (20Mb down, 2Mb up)
  245. if [[ $bandwith_type = "XL" ]]
  246. then
  247.     # STM limits (values in MB)
  248.     stm_period_bw_limit_mb_1=7000
  249.     stm_period_bw_limit_mb_2=3500
  250.     stm_period_bw_limit_mb_3=3000
  251.     # QOS settings (values in Kbits/s)
  252.     inbound_bandwidth_without_stm=20480
  253.     inbound_bandwidth_with_stm=5120
  254.     outbound_bandwidth_without_stm=1864 # 2048 * 0.91
  255.     outbound_bandwidth_with_stm=466 # 1864 * 0.25
  256. fi
  257.  
  258. # Settings specific to L (10Mb down, 1Mb up)
  259. if [[ $bandwith_type = "L" ]]
  260. then
  261.     # STM limits (values in MB)
  262.     stm_period_bw_limit_mb_1=3000
  263.     stm_period_bw_limit_mb_2=1500
  264.     stm_period_bw_limit_mb_3=1500
  265.     # QOS settings (values in Kbits/s)
  266.     inbound_bandwidth_without_stm=10240
  267.     inbound_bandwidth_with_stm=2560
  268.     outbound_bandwidth_without_stm=932 # 1024 * 0.91
  269.     outbound_bandwidth_with_stm=233 # 932 * 0.25
  270. fi
  271.  
  272. # Settings specific to M (10Mb down, 1Mb up)
  273. if [[ $bandwith_type = "M" ]]
  274. then
  275.     # STM limits (values in MB)
  276.     stm_period_bw_limit_mb_1=1500
  277.     stm_period_bw_limit_mb_2=750
  278.     stm_period_bw_limit_mb_3=750
  279.     # QOS settings (values in Kbits/s)
  280.     inbound_bandwidth_without_stm=10240
  281.     inbound_bandwidth_with_stm=2560
  282.     outbound_bandwidth_without_stm=932 # 1024 * 0.91
  283.     outbound_bandwidth_with_stm=233 # 932 * 0.25
  284. fi
  285.  
  286. # Settings specific to S5 (5Mb down, 512Kb up)
  287. if [[ $bandwith_type = "S5" ]]
  288. then
  289.     # STM limits (values in MB)
  290.     stm_period_bw_limit_mb_1=500
  291.     stm_period_bw_limit_mb_2=250
  292.     stm_period_bw_limit_mb_3=200
  293.     # QOS settings (values in Kbits/s)
  294.     inbound_bandwidth_without_stm=10240
  295.     inbound_bandwidth_with_stm=2560
  296.     outbound_bandwidth_without_stm=932 # 1024 * 0.91
  297.     outbound_bandwidth_with_stm=233 # 932 * 0.25
  298. fi
  299.  
  300.  
  301. # STM prevention threshold. STM prevention only becomes active once
  302. # this percentage of the STM bandwidth limit has been transferred.
  303. # Default for STM Prevention is 80%.
  304. stm_prevention_threshold=80
  305.  
  306. # Override settings with user-defined values if valid values were specified
  307. if [[ -e /jffs/stm-monitor.cfg ]]
  308. then
  309.     source /jffs/stm-monitor.cfg
  310. fi
  311.  
  312. if [[ -e /tmp/stm-monitor.cfg ]]
  313. then
  314.     source /tmp/stm-monitor.cfg
  315. fi
  316.  
  317. if [[ "$STM_PERIOD_BW_LIMIT_1"  != "" ]]
  318. then
  319.     invalid_value=`echo "" | awk '{ if (value < 0) {print(1)} }' value=$STM_PERIOD_BW_LIMIT_1`
  320.     if [[  "$invalid_value" = 1 ]]
  321.     then
  322.         $LOGGER "Invalid STM_PERIOD_BW_LIMIT_1 (${STM_PERIOD_BW_LIMIT_1} MB). Reverting to default value (${stm_period_bw_limit_mb_1} MB)."
  323.     else
  324.         stm_period_bw_limit_mb_1=$STM_PERIOD_BW_LIMIT_1
  325.     fi
  326. fi
  327.  
  328. if [[ "$STM_PERIOD_BW_LIMIT_2"  != "" ]]
  329. then
  330.     invalid_value=`echo "" | awk '{ if (value < 0) {print(1)} }' value=$STM_PERIOD_BW_LIMIT_2`
  331.     if [[  "$invalid_value" = 1 ]]
  332.     then
  333.         $LOGGER "Invalid STM_PERIOD_BW_LIMIT_2 (${STM_PERIOD_BW_LIMIT_2} MB). Reverting to default value (${stm_period_bw_limit_mb_2} MB)."
  334.     else
  335.         stm_period_bw_limit_mb_2=$STM_PERIOD_BW_LIMIT_2
  336.     fi
  337. fi
  338.  
  339. if [[ "$STM_PERIOD_BW_LIMIT_3"  != "" ]]
  340. then
  341.     invalid_value=`echo "" | awk '{ if (value < 0) {print(1)} }' value=$STM_PERIOD_BW_LIMIT_3`
  342.     if [[  "$invalid_value" = 1 ]]
  343.     then
  344.         $LOGGER "Invalid STM_PERIOD_BW_LIMIT_3 (${STM_PERIOD_BW_LIMIT_3} MB). Reverting to default value (${stm_period_bw_limit_mb_3} MB)."
  345.     else
  346.         stm_period_bw_limit_mb_3=$STM_PERIOD_BW_LIMIT_3
  347.     fi
  348. fi
  349.  
  350. if [[ "$STM_PREVENTION_THRESHOLD" != "" ]]
  351. then
  352.     invalid_value=`echo "" | awk '{ if (value > 100 || value < 0) {print(1)} }' value=$STM_PREVENTION_THRESHOLD`
  353.     if [[  "$invalid_value" = 1 ]]
  354.     then
  355.         $LOGGER "Invalid STM_PREVENTION_THRESHOLD (${STM_PREVENTION_THRESHOLD}%). Reverting to default value (${stm_prevention_threshold}%)."
  356.     else
  357.         stm_prevention_threshold=$STM_PREVENTION_THRESHOLD
  358.     fi
  359. fi
  360.  
  361. if [[ "$STM_INBOUND_BANDWIDTH_WITHOUT_STM"  != "" ]]
  362. then
  363.     invalid_value=`echo "" | awk '{ if (value < 0) {print(1)} }' value=$STM_INBOUND_BANDWIDTH_WITHOUT_STM`
  364.     if [[  "$invalid_value" = 1 ]]
  365.     then
  366.         $LOGGER "Invalid STM_INBOUND_BANDWIDTH_WITHOUT_STM (${STM_INBOUND_BANDWIDTH_WITHOUT_STM} kb/s). Reverting to default value (${inbound_bandwidth_without_stm} kb/s)."
  367.     else
  368.         inbound_bandwidth_without_stm=$STM_INBOUND_BANDWIDTH_WITHOUT_STM
  369.     fi
  370. fi
  371.  
  372. if [[ "$STM_INBOUND_BANDWIDTH_WITH_STM"  != "" ]]
  373. then
  374.     invalid_value=`echo "" | awk '{ if (value < 0) {print(1)} }' value=$STM_INBOUND_BANDWIDTH_WITH_STM`
  375.     if [[  "$invalid_value" = 1 ]]
  376.     then
  377.         $LOGGER "Invalid STM_INBOUND_BANDWIDTH_WITH_STM (${STM_INBOUND_BANDWIDTH_WITH_STM} kb/s). Reverting to default value (${inbound_bandwidth_with_stm} kb/s)."
  378.     else
  379.         inbound_bandwidth_with_stm=$STM_INBOUND_BANDWIDTH_WITH_STM
  380.     fi
  381. fi
  382.  
  383. if [[ "$STM_OUTBOUND_BANDWIDTH_WITHOUT_STM"  != "" ]]
  384. then
  385.     invalid_value=`echo "" | awk '{ if (value < 0) {print(1)} }' value=$STM_OUTBOUND_BANDWIDTH_WITHOUT_STM`
  386.     if [[  "$invalid_value" = 1 ]]
  387.     then
  388.         $LOGGER "Invalid STM_OUTBOUND_BANDWIDTH_WITHOUT_STM (${STM_OUTBOUND_BANDWIDTH_WITHOUT_STM} kb/s). Reverting to default value (${outbound_bandwidth_without_stm} kb/s)."
  389.     else
  390.         outbound_bandwidth_without_stm=$STM_OUTBOUND_BANDWIDTH_WITHOUT_STM
  391.     fi
  392. fi
  393.  
  394. if [[ "$STM_OUTBOUND_BANDWIDTH_WITH_STM"  != "" ]]
  395. then
  396.     invalid_value=`echo "" | awk '{ if (value < 0) {print(1)} }' value=$STM_OUTBOUND_BANDWIDTH_WITH_STM`
  397.     if [[  "$invalid_value" = 1 ]]
  398.     then
  399.         $LOGGER "Invalid STM_OUTBOUND_BANDWIDTH_WITH_STM (${STM_OUTBOUND_BANDWIDTH_WITH_STM} kb/s). Reverting to default value (${outbound_bandwidth_with_stm} kb/s)."
  400.     else
  401.         outbound_bandwidth_with_stm=$STM_OUTBOUND_BANDWIDTH_WITH_STM
  402.     fi
  403. fi
  404.  
  405. # Grab the current time
  406. current_hours=`date +%H`
  407. current_minutes=`date +%M`
  408. current_unix_time=`date +%s`
  409.  
  410. # Set up web page. Use a string to store web page content and pipe
  411. # it to /var/wwwext/stm-monitor.htm when the script exits
  412. if [[ ! -e "/var/wwwext" ]]
  413. then
  414.     mkdir /var/wwwext
  415. fi
  416. web_page="<html><head><title>${stm_monitor_version} - Status at ${current_hours}:${current_minutes}</title><meta http-equiv=\"refresh\" content=\"120\"</head>"
  417. web_page="${web_page}<body style=\"font-family:verdana\"><h2>${stm_monitor_version}</h2>"
  418. web_page="${web_page}<h3>Status at ${current_hours}:${current_minutes}</h3>"
  419.  
  420. # Check whether we are still serving an STM sentence that has completed
  421. # Upstream
  422. if [[ "`nvram get tx_stm_sentence_active`" = 1  && $current_unix_time -gt "`nvram get tx_stm_sentence_end_unix_time`" ]]
  423. then
  424.     # Return QOS configuration to non-STM settings
  425.     $LOGGER "STM (TX) sentence served: applying normal outbound QOS configuration"
  426.     nvram set qos_obw=$outbound_bandwidth_without_stm
  427.     service qos restart
  428.  
  429.     # Record the time at which this sentence ended
  430.     nvram set tx_last_stm_sentence_end_unix_time=`nvram get tx_stm_sentence_end_unix_time`
  431.     nvram set tx_last_stm_sentence_end_time=`nvram get tx_stm_sentence_end_time`
  432.  
  433.     # Unset our NVRAM variables
  434.     nvram unset tx_stm_sentence_active
  435.     nvram unset tx_stm_sentence_end_time
  436.     nvram unset tx_stm_sentence_end_unix_time        
  437. fi
  438. # Downstream
  439. if [[ "`nvram get rx_stm_sentence_active`" = 1  && $current_unix_time -gt "`nvram get rx_stm_sentence_end_unix_time`" ]]
  440. then
  441.     # Return QOS configuration to non-STM settings
  442.     $LOGGER "STM (RX) sentence served: applying normal inbound QOS configuration"
  443.     nvram set qos_ibw=$inbound_bandwidth_without_stm
  444.     service qos restart
  445.  
  446.     # Record the time at which this sentence ended
  447.     nvram set rx_last_stm_sentence_end_unix_time=`nvram get rx_stm_sentence_end_unix_time`
  448.     nvram set rx_last_stm_sentence_end_time=`nvram get rx_stm_sentence_end_time`
  449.  
  450.     # Unset our NVRAM variables
  451.     nvram unset rx_stm_sentence_active
  452.     nvram unset rx_stm_sentence_end_time
  453.     nvram unset rx_stm_sentence_end_unix_time        
  454. fi
  455.  
  456. # Grab current statistics from rstats and wait for the file to be written
  457. killall -USR1 rstats
  458. sleep 2
  459. stats_file=/var/spool/rstats-speed.js
  460.  
  461. # Read the stats file and extract the parts we're interested in (WAN RX and TX)
  462. wan_interface=`nvram get wan_ifname` # Usually vlan1, but not always
  463. read_next_rx_tx=0
  464. while read line
  465. do
  466.     case $line in
  467.         *$wan_interface*) read_next_rx_tx=1 ;;
  468.     esac
  469.  
  470.     if [[ $read_next_rx_tx = 1 ]]
  471.     then
  472.         case $line in
  473.             *rx:*) rx_data=`echo $line | awk '
  474.                 {
  475.                     values_string = substr($0, index($0, "[") + 1, index($0, "]") - 6);
  476.                     print values_string
  477.                 }' ` ;;
  478.             *tx:*) tx_data=`echo $line | awk '
  479.                 {
  480.                     values_string = substr($0, index($0, "[") + 1, index($0, "]") - 6);
  481.                     print values_string
  482.                 }' ` ; read_next_rx_tx=0; ;;
  483.         esac
  484.     fi
  485. done < $stats_file
  486. rm $stats_file
  487.  
  488. if [[ $use_backup -eq 1 ]]; then
  489.     # Read backup
  490.     if [[ -e $backup_file ]]; then
  491.         backup_unix_time=$(head -n 1 $backup_file) #first line
  492.         rx_data_backup=$(head -n 2 $backup_file | tail -n 1) #second line
  493.         tx_data_backup=$(head -n 3 $backup_file | tail -n 1) #third line
  494.  
  495.         time_difference=`expr $current_unix_time - $backup_unix_time`
  496.         intervarls_since_backup=`expr $time_difference / 120`
  497.  
  498.         if [[ $intervarls_since_backup -gt 720 ]]; then
  499.             intervarls_since_backup=720
  500.         fi
  501.  
  502.         rx_data_from_back_up=`echo $rx_data_backup | awk '
  503.                         {
  504.                             split($0, values_array, ",");
  505.                             for (i=intervarls_since_backup+1; i<=720; i++) {
  506.                                 if(i==720)
  507.                                     deliminator=""
  508.                                 else
  509.                                     deliminator=","
  510.                                 buffer = buffer""values_array[i]""deliminator;
  511.                             } print buffer;
  512.                         }' intervarls_since_backup=$intervarls_since_backup`
  513.         tx_data_from_back_up=`echo $tx_data_backup | awk '
  514.                         {
  515.                             split($0, values_array, ",");
  516.                             for (i=intervarls_since_backup+1; i<=720; i++) {
  517.                                 if(i==720)
  518.                                     deliminator=""
  519.                                 else
  520.                                     deliminator=","
  521.                                 buffer = buffer""values_array[i]""deliminator;
  522.                             } print buffer;
  523.                         }' intervarls_since_backup=$intervarls_since_backup`
  524.  
  525.         rx_data_from_rstats=`echo $rx_data | awk '
  526.                         {
  527.                             split($0, values_array, ",");
  528.                             for (i=721-intervarls_since_backup; i<=720; i++) {
  529.                                 if(i==720)
  530.                                     deliminator=""
  531.                                 else
  532.                                     deliminator=","
  533.                                 buffer = buffer""values_array[i]""deliminator;
  534.                             } print buffer;
  535.                         }' intervarls_since_backup=$intervarls_since_backup`
  536.         tx_data_from_rstats=`echo $tx_data | awk '
  537.                         {
  538.                             split($0, values_array, ",");
  539.                             for (i=721-intervarls_since_backup; i<=720; i++) {
  540.                                 if(i==720)
  541.                                     deliminator=""
  542.                                 else
  543.                                     deliminator=","
  544.                                 buffer = buffer""values_array[i]""deliminator;
  545.                             } print buffer;
  546.                         }' intervarls_since_backup=$intervarls_since_backup`
  547.  
  548.         if [[ $rx_data_from_back_up != "" && $rx_data_from_rstats != "" ]];
  549.             then deliminator=","
  550.         else
  551.             deliminator=""
  552.         fi
  553.         rx_data="${rx_data_from_back_up}${deliminator}${rx_data_from_rstats}"
  554.  
  555.         if [[ $tx_data_from_back_up != "" && $tx_data_from_rstats != "" ]];
  556.             then deliminator=","
  557.         else
  558.             deliminator=""
  559.         fi
  560.         tx_data="${tx_data_from_back_up}${deliminator}${tx_data_from_rstats}"
  561.     fi
  562.  
  563.     backup_page="${current_unix_time}\n"
  564.     backup_page="${backup_page}${rx_data}\n"
  565.     backup_page="${backup_page}${tx_data}\n"
  566.    
  567.     # Writing backup file
  568.     echo -e $backup_page > $backup_file
  569. fi
  570.  
  571.  
  572. # Check which STM periods are active, check total TX/RX against
  573. # STM limits and note if an STM limit was exceeded
  574. tx_stm_sentence_triggered=0
  575. rx_stm_sentence_triggered=0
  576. add_adjustment_note=0
  577. web_page="${web_page}<table cellpadding=9 cellspacing=3 border=0>"
  578. 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>"
  579. for i in 1 2 3; do
  580.     stm_period_name=`eval echo "\\$stm_period_name_${i}"`
  581.     stm_period_start=`eval echo "\\$stm_period_start_${i}"`
  582.     stm_period_end=`eval echo "\\$stm_period_end_${i}"`
  583.     stm_period_direction=`eval echo "\\$stm_period_direction_${i}"`
  584.     stm_period_bw_limit_mb=`eval echo "\\$stm_period_bw_limit_mb_${i}"`
  585.    
  586.     if [[ $current_hours -ge $stm_period_start && $current_hours -lt $stm_period_end ]]
  587.     then
  588.         # This STM period is active.   
  589.         web_page="${web_page}<tr bgcolor=\"EEEEEE\" align=\"center\">"
  590.         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>"
  591.  
  592.         # Setup a few RX/TX dependent variables
  593.         if [[ $stm_period_direction = "RX" ]]
  594.         then
  595.             data=$rx_data
  596.             stm_period_rx_active=1
  597.             stm_sentence_active=`nvram get rx_stm_sentence_active`
  598.             last_stm_sentence_end_unix_time=`nvram get rx_last_stm_sentence_end_unix_time`
  599.         else
  600.             data=$tx_data
  601.             stm_period_tx_active=1
  602.             stm_sentence_active=`nvram get tx_stm_sentence_active`
  603.             last_stm_sentence_end_unix_time=`nvram get tx_last_stm_sentence_end_unix_time`
  604.         fi
  605.  
  606.         # Calculate the number of minutes since the STM period started, or since the last STM sentence
  607.         # ended (whichever happened more recently).
  608.         # Then calculate the number of values to take from the rstats data (each value covers two minutes)
  609.         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}`
  610.         if [[ "$last_stm_sentence_end_unix_time" != "" ]]
  611.         then
  612.             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`
  613.             if [[ $minutes_since_last_stm_sentence_ended -lt $minutes_since_stm_period_started ]]
  614.             then
  615.                 # Need to calculate the number of seconds to subtract from the length of the
  616.                 # STM period when we do the maximum average rate calculation later on
  617.                 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`
  618.                 number_of_values=`expr $minutes_since_last_stm_sentence_ended / 2`
  619.             else
  620.                 # Don't need to adjust the rate calculation
  621.                 max_rate_adjustment=0
  622.                 number_of_values=`expr $minutes_since_stm_period_started / 2`  
  623.             fi
  624.         else
  625.             # Don't need to adjust the rate calculation
  626.             max_rate_adjustment=0
  627.             number_of_values=`expr $minutes_since_stm_period_started / 2`
  628.         fi
  629.        
  630.         # Extract the useful numbers from the rstats data
  631.         if [[ $number_of_values != 0 ]]
  632.         then
  633.             # Sum the last XXX values of the 720 in the rstats data to get the
  634.             # total bytes transferred since the STM period started (or since the last
  635.             # STM sentence ended)
  636.             total_transferred_bytes=`echo $data | awk '
  637.                 {
  638.                     split($0, values_array, ",");
  639.                     for (i=(721-number_of_values); i<=720; i++) {
  640.                         total += values_array[i];
  641.                     } printf("%0.f" total);
  642.                 }' number_of_values=$number_of_values total=0`
  643.             total_transferred_mb=`echo "" | awk '{ printf("%.2f", bytes / 1048576) }' bytes=$total_transferred_bytes`  
  644.             average_rate=`echo "" | awk '{ printf("%.2f", bytes / (number_of_values * 2 * 60 * 1024)) }' number_of_values=$number_of_values bytes=$total_transferred_bytes`
  645.             average_rate_kilobits=`echo "" | awk '{printf("%.2f", rate_kilobytes * 8)}' rate_kilobytes=$average_rate`
  646.         else
  647.             total_transferred_bytes="0"
  648.             total_transferred_mb="0.00"
  649.             average_rate="0.00"
  650.             average_rate_kilobits="0.00"
  651.         fi 
  652.    
  653.         # Calculate maximum average rate (i.e. rate required to trigger STM),
  654.         # then compare this to our actual rate. If the actual rate is equal or
  655.         # higher, we paint the cell red, if it's greater than 90% of the max
  656.         # we paint it amber, and if it's anything else we paint it green.
  657.         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`
  658.         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`
  659.        
  660.         # STM Prevention code
  661.         if [[ $stm_prevention = 1 && "$stm_sentence_active" != 1 ]]
  662.         then
  663.             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`
  664.             if [[ $cell_color = "FF6633" && $exceeded_stm_prevention_threshold = 1 && "$stm_sentence_active" != 1 ]]
  665.             then
  666.                 # Cell is red => calculate preventative QOS limit
  667.                 # Calculate the number of kilobits we have left before we trigger STM
  668.                 total_kilobits_remaining=`echo "" | awk '{print(((limit*1048576)-total)/128)}' limit=$stm_period_bw_limit_mb total=$total_transferred_bytes`
  669.                            
  670.                 # Calculate time remaining until end of STM period
  671.                 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`
  672.            
  673.                 # 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
  674.                 # 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
  675.                 # arrives at the router before QOS throws it away in accordance with the temporary limit we've imposed. I've done extensive testing
  676.                 # and 50-55% is about as high as you can go.
  677.                 if [[ $stm_period_direction = RX ]]
  678.                 then
  679.                     preventative_qos_limit=`echo "" | awk '{printf("%.0f", 0.5*(kilobits/secs))}' kilobits=$total_kilobits_remaining secs=$seconds_remaining`
  680.                 else
  681.                     preventative_qos_limit=`echo "" | awk '{printf("%.0f", 0.9*(kilobits/secs))}' kilobits=$total_kilobits_remaining secs=$seconds_remaining`
  682.                 fi
  683.                
  684.                 if [[ $intelligent = 1 ]]
  685.                 then
  686.                     # Check whether we're actually better off NOT preventing STM
  687.                     seconds_until_stm_is_triggered=`echo "" | awk '{ printf("%0.f", kilobits / rate) }' kilobits=$total_kilobits_remaining rate=$average_rate_kilobits`
  688.                     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`
  689.                     if [[ $stm_period_direction = "RX" ]]
  690.                     then
  691.                         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`
  692.                         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`
  693.                     else
  694.                         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`
  695.                         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`
  696.                     fi
  697.                     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`
  698.                    
  699.                     # Compile detailed information
  700.                     total_mb_remaining=`echo "" | awk '{ printf("%.2f", bits / 8192) }' bits=$total_kilobits_remaining`
  701.                     potential_mb_transferred_without_stm_prevention=`echo "" | awk '{ printf("%.0f", bits / 8192) }' bits=$potential_kilobits_transferred_without_stm_prevention`
  702.                     potential_mb_transferred_with_stm_prevention=`echo "" | awk '{ printf("%.0f", bits / 8192) }' bits=$potential_kilobits_transferred_with_stm_prevention`
  703.                 else
  704.                     # Assume STM prevention is *always* beneficial
  705.                     stm_prevention_is_beneficial=1
  706.                 fi
  707.                
  708.                 if [[ $stm_period_direction = "RX" && "`nvram get qos_ibw`" -gt $preventative_qos_limit ]]
  709.                 then
  710.                     if  [[ $stm_prevention_is_beneficial = 1 ]]
  711.                     then
  712.                         $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."
  713.                             $LOGGER "Setting preventative inbound QOS limit of $preventative_qos_limit kbits/s"
  714.                             nvram set qos_ibw=$preventative_qos_limit
  715.                             # We must set the inbound rate limits to 100% or less for this to work ("None" will not work
  716.                             # because the rate will not be limited). To make sure this does work, we'll change the
  717.                             # settings to 100% across the board and restore the old settings when we remove the
  718.                             # temporary QOS limit.
  719.                             nvram set qos_irates_old=`nvram get qos_irates`
  720.                             nvram set qos_irates=100,100,100,100,100,100,100,100,100,100
  721.                             service qos restart
  722.                     else
  723.                         $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."
  724.                     fi 
  725.                 fi
  726.                 if [[ $stm_period_direction = "TX" && "`nvram get qos_obw`" -gt $preventative_qos_limit ]]
  727.                 then
  728.                     if [[ $stm_prevention_is_beneficial = 1 ]]
  729.                     then
  730.                         $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."
  731.                         $LOGGER "Setting preventative outbound QOS limit of $preventative_qos_limit kbits/s"
  732.                         nvram set qos_obw=$preventative_qos_limit
  733.                         service qos restart
  734.                     else
  735.                         $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."
  736.                     fi
  737.                 fi     
  738.             fi
  739.        
  740.             # Remove STM Prevention QOS settings if the cell is green
  741.             if [[ $cell_color = "66FF33" && "$stm_sentence_active" != 1 ]]
  742.             then
  743.                 if [[ $stm_period_direction = "RX" && "`nvram get qos_ibw`" != $inbound_bandwidth_without_stm ]]
  744.                 then
  745.                     $LOGGER "Removing preventative inbound QOS limit"
  746.                     nvram set qos_ibw=$inbound_bandwidth_without_stm
  747.                     nvram set qos_irates=`nvram get qos_irates_old`
  748.                     nvram unset qos_irates_old
  749.                     service qos restart
  750.                 fi
  751.                 if [[ $stm_period_direction = "TX" && "`nvram get qos_obw`" != $outbound_bandwidth_without_stm ]]
  752.                 then
  753.                     $LOGGER "Removing preventative outbound QOS limit"
  754.                     nvram set qos_obw=$outbound_bandwidth_without_stm
  755.                     service qos restart
  756.                 fi         
  757.             fi
  758.         fi # End of STM prevention code
  759.        
  760.         # Add data to web page
  761.         total_transferred_mb_percent=`echo "" | awk '{ printf("%.0f", (transferred / limit) * 100) }' transferred=$total_transferred_mb limit=$stm_period_bw_limit_mb`
  762.         if [[ $max_rate_adjustment != 0 ]]
  763.         then
  764.             # Add link to note explaining adjusted figures
  765.             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>"
  766.             add_adjustment_note=1
  767.         else
  768.             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>"
  769.         fi
  770.        
  771.         # Check whether STM limit has been exceeded
  772.         stm_period_bw_limit_bytes=`expr $stm_period_bw_limit_mb \* 1048576`
  773.         result=`echo "" | awk '{ if (total > limit) {print(1)} else {print(0)}}' total=$total_transferred_bytes limit=$stm_period_bw_limit_bytes`
  774.         if [[ $result = 1 && "$stm_sentence_active" != 1 ]]
  775.         then
  776.             if [[ $stm_period_direction = "RX" ]]
  777.             then
  778.                 rx_stm_sentence_triggered=1
  779.                 nvram set rx_stm_sentence_active=1
  780.             else
  781.                 tx_stm_sentence_triggered=1
  782.                 nvram set tx_stm_sentence_active=1
  783.             fi
  784.             $LOGGER "STM (${stm_period_direction}) triggered: ${stm_period_name} (${stm_period_start}:00 -> ${stm_period_end}:00, ${stm_period_bw_limit_mb} MB)"
  785.         fi
  786.     else
  787.         # This STM period is not currently active
  788.         web_page="${web_page}<tr bgcolor=\"EEEEEE\" style=\"color:AAAAAA\" align=\"center\">"
  789.         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>" 
  790.     fi
  791.     web_page="${web_page}</tr>"
  792. done
  793. web_page="${web_page}</table>"
  794.  
  795. # If some of the rate figures were adjusted due to a recent STM setence, add a note to make this clear
  796. if [[ $add_adjustment_note = 1 ]]
  797. then
  798.     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>"
  799. fi
  800.  
  801. # Remove RX/TX STM Prevention QOS limits if necessary. This code makes sure the temporary limits
  802. # are removed when they are not relevant (i.e. when we're not in an STM period and STM has not
  803. # been triggered)
  804. if [[ $stm_prevention = 1 ]]
  805. then
  806.     if [[ "`nvram get rx_stm_sentence_active`" != 1 && "$stm_period_rx_active" != 1 && "`nvram get qos_ibw`" != $inbound_bandwidth_without_stm ]]
  807.     then
  808.         $LOGGER "Removing preventative inbound QOS limit"
  809.         nvram set qos_ibw=$inbound_bandwidth_without_stm
  810.         nvram set qos_irates=`nvram get qos_irates_old`
  811.         nvram unset qos_irates_old
  812.         service qos restart
  813.     fi
  814.     if [[ "`nvram get tx_stm_sentence_active`" != 1 && "$stm_period_tx_active" != 1 && "`nvram get qos_obw`" != $outbound_bandwidth_without_stm ]]
  815.     then
  816.         $LOGGER "Removing preventative outbound QOS limit"
  817.         nvram set qos_obw=$outbound_bandwidth_without_stm
  818.         service qos restart
  819.     fi
  820. fi
  821.  
  822. # If STM is active, check whether QOS is set accordingly
  823. # Upstream
  824. if [[ "`nvram get tx_stm_sentence_active`" = 1  && "`nvram get qos_obw`" != $outbound_bandwidth_with_stm ]]
  825. then
  826.     if [[ $tx_stm_sentence_triggered = 1 ]]
  827.     then
  828.         # We must have triggered an STM sentence on this run.
  829.         # Work out the hour component of the time the STM sentence will end
  830.         # (for logging purposes only - we will use unix time to track the
  831.         # STM sentence accurately)
  832.         tx_stm_end_hour=`expr $current_hours + $stm_sentence_length_hours`
  833.         if [[ $tx_stm_end_hour -gt 23 ]]
  834.         then
  835.             tx_stm_end_hour="0`expr $stm_end_hour - 24`"
  836.         fi
  837.        
  838.         # Set NVRAM variables to describe the STM sentence being served
  839.         nvram set tx_stm_sentence_end_time="$stm_end_hour:$current_minutes"
  840.         nvram set tx_stm_sentence_end_unix_time=`expr $current_unix_time + $stm_sentence_length_seconds`
  841.  
  842.         $LOGGER "STM (TX) sentence started: applying STM outbound QOS configuration (until $stm_end_hour:$current_minutes)"
  843.     else
  844.         # An STM sentence is active and we didn't trigger it on this run,
  845.         # but the QOS settings are wrong. We must have rebooted, or someone
  846.         # messed with the QOS settings. So we want to set the QOS settings
  847.         # to deal with the STM, but we don't want to overwrite our NVRAM
  848.         # variables.
  849.         $LOGGER "STM (TX) sentence resumed: applying STM outbound QOS configuration (until `nvram get tx_stm_sentence_end_time`)"
  850.     fi
  851.    
  852.     # Apply STM QOS settings
  853.     nvram set qos_obw=$outbound_bandwidth_with_stm
  854.     service qos restart
  855. fi
  856. # Downstream
  857. if [[ "`nvram get rx_stm_sentence_active`" = 1  && "`nvram get qos_ibw`" != $inbound_bandwidth_with_stm ]]
  858. then
  859.     if [[ $rx_stm_sentence_triggered = 1 ]]
  860.     then
  861.         # We must have triggered an STM sentence on this run.
  862.         # Work out the hour component of the time the STM sentence will end
  863.         # (for logging purposes only - we will use unix time to track the
  864.         # STM sentence accurately)
  865.         rx_stm_end_hour=`expr $current_hours + $stm_sentence_length_hours`
  866.         if [[ $rx_stm_end_hour -gt 23 ]]
  867.         then
  868.             rx_stm_end_hour="0`expr $stm_end_hour - 24`"
  869.         fi
  870.        
  871.         # Set NVRAM variables to describe the STM sentence being served
  872.         nvram set rx_stm_sentence_end_time="$stm_end_hour:$current_minutes"
  873.         nvram set rx_stm_sentence_end_unix_time=`expr $current_unix_time + $stm_sentence_length_seconds`
  874.  
  875.         $LOGGER "STM (RX) sentence started: applying STM inbound QOS configuration (until $stm_end_hour:$current_minutes)"
  876.     else
  877.         # An STM sentence is active and we didn't trigger it on this run,
  878.         # but the QOS settings are wrong. We must have rebooted, or someone
  879.         # messed with the QOS settings. So we want to set the QOS settings
  880.         # to deal with the STM, but we don't want to overwrite our NVRAM
  881.         # variables.
  882.         $LOGGER "STM (RX) sentence resumed: applying STM inbound QOS configuration (until `nvram get rx_stm_sentence_end_time`)"
  883.     fi
  884.    
  885.     # Apply STM QOS settings
  886.     nvram set qos_ibw=$inbound_bandwidth_with_stm
  887.     service qos restart
  888. fi
  889.  
  890. # Add status to the web page
  891. if [[ $intelligent = 1 ]]
  892. then
  893.     web_page="${web_page}<h4>Intelligent STM Prevention: "
  894. else
  895.     web_page="${web_page}<h4>STM Prevention: "
  896. fi
  897. if [[ $stm_prevention = 1 ]]
  898. then
  899.     if [[ "`nvram get qos_ibw`" = $inbound_bandwidth_without_stm && "`nvram get qos_obw`" = $outbound_bandwidth_without_stm ]]
  900.     then
  901.         web_page="${web_page}<b style=\"color:green\">Inactive</b></h4>"
  902.     else
  903.         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 ]]
  904.         then
  905.             web_page="${web_page}<b style=\"color:red\">Active (inbound and outbound)</b></h4>"
  906.         else
  907.             if [[ "`nvram get rx_stm_sentence_active`" != 1 && "`nvram get qos_ibw`" != $inbound_bandwidth_without_stm ]]
  908.             then
  909.                 web_page="${web_page}<b style=\"color:red\">Active (inbound)</b></h4>"
  910.             fi
  911.             if [[ "`nvram get tx_stm_sentence_active`" != 1 && "`nvram get qos_obw`" != $outbound_bandwidth_without_stm ]]
  912.             then
  913.                 web_page="${web_page}<b style=\"color:red\">Active (outbound)</b></h4>"
  914.             fi
  915.         fi     
  916.     fi
  917. else
  918.     web_page="${web_page}<b style=\"color:CCCCCC\">Not enabled</b></h4>"
  919. fi
  920.  
  921. if [[ $intelligent = 1 ]]
  922. then
  923.     web_page="${web_page}<h4>Intelligent STM Mitigation: "
  924. else
  925.     web_page="${web_page}<h4>STM Mitigation: "
  926. fi
  927.  
  928. if [[ "`nvram get tx_stm_sentence_active`" = 1 ]]
  929. then
  930.     if [[ "`nvram get rx_stm_sentence_active`" = 1 ]]
  931.     then
  932.         # Serving an STM sentence for both RX and TX
  933.         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>"
  934.     else
  935.         # Serving an STM sentence for TX only
  936.         web_page="${web_page}<b style=\"color:red\">Active - Upstream STM sentence will end at `nvram get tx_stm_sentence_end_time`</b></h4>"
  937.     fi
  938. else
  939.     if [[ "`nvram get rx_stm_sentence_active`" = 1 ]]
  940.     then
  941.         # Serving an STM sentence for RX only
  942.         web_page="${web_page}<b style=\"color:red\">Active - Downstream STM sentence will end at `nvram get rx_stm_sentence_end_time`</b></h4>"
  943.     else
  944.         # Not serving an STM sentence
  945.         web_page="${web_page}<b style=\"color:green\">Inactive</b></h4>"
  946.     fi
  947. fi
  948.  
  949. 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>"
  950.  
  951. web_page="${web_page}<h4>Customisable settings:</h4><ul>"
  952. web_page="${web_page}<li>Daytime Downstream Bandwidth Limit: <font style=\"color:blue\">${stm_period_bw_limit_mb_1}</font> MB</li>"
  953. web_page="${web_page}<li>Evening Downstream Bandwidth Limit: <font style=\"color:blue\">${stm_period_bw_limit_mb_2}</font> MB</li>"
  954. web_page="${web_page}<li>Evening Upstream Bandwidth Limit: <font style=\"color:blue\">${stm_period_bw_limit_mb_3}</font> MB</li>"
  955. web_page="${web_page}<li>STM Prevention Threshold: <font style=\"color:blue\">${stm_prevention_threshold}</font>%</li>"
  956. web_page="${web_page}<li>Normal Inbound Bandwidth: <font style=\"color:blue\">${inbound_bandwidth_without_stm}</font> kb/s</li>"
  957. web_page="${web_page}<li>STM Inbound Bandwidth: <font style=\"color:blue\">${inbound_bandwidth_with_stm}</font> kb/s</li>"
  958. web_page="${web_page}<li>Normal Outbound Bandwidth: <font style=\"color:blue\">${outbound_bandwidth_without_stm}</font> kb/s</li>"
  959. web_page="${web_page}<li>STM Outbound Bandwidth: <font style=\"color:blue\">${outbound_bandwidth_with_stm}</font> kb/s</li>"
  960. web_page="${web_page}</ul>"
  961.  
  962. # Add latest log entries to web page
  963. web_page="${web_page}<h3>Latest Log Entries</h3>"
  964. log="<nobr><tt>`cat \`ls -r /var/log/ | sed 's/messages/\/var\/log\/messages/'\` | grep STM-Monitor | sed 's/\$/<br>/g'`</tt></nobr>"
  965. web_page="${web_page}${log}"
  966.  
  967. # Publish web page
  968. web_page="${web_page}</body></html>"
  969. echo $web_page > /var/wwwext/stm-monitor.htm
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement