#!/bin/sh

#
# tiny tool to scan the WebUI of an TC4400 DOCSIS cable modem
#
# add this to your crontab to stay informed about the modem status
#
# https://github.com/sp4rkie/docsis-cable-load-monitor
#

CABLE_MODEM_IP=$1
[ $CABLE_MODEM_IP ] || CABLE_MODEM_IP=192.168.100.1
TMPFILE=/tmp/scan_tc4400.$CABLE_MODEM_IP
USER=admin
PASS='bEn2o#US9s'

for i in \
http://$CABLE_MODEM_IP/info.html \
http://$CABLE_MODEM_IP/arpview.cmd \
http://$CABLE_MODEM_IP/cmswinfo.html \
http://$CABLE_MODEM_IP/cmconnectionstatus.html \
http://$CABLE_MODEM_IP/cmeventlog.html
do
wget --connect-timeout=1 -t 1 -q --http-user=$USER --http-password=$PASS $i -O - |
awk '{
    if (!HEAD++) {
        print "------------------ [ '$i' ] ------------------"
    }
    if (match($0, "<script")) {
        ++IGNORE
    } else if (IGNORE) {
        if (match($0, "/script?")) {
            IGNORE = 0
        }
    } else {
        print
    }
}'
done | 
w3m -r -T text/html -cols 1000 -no-graph -dump > ${TMPFILE}_raw
# prefer w3m since it works better with tables
#lynx -nolist -width 300 -dump -stdin > ${TMPFILE}_raw

awk '{
    # patch some minor fields to exclude from monitoring.
    # feel free to encomment lines with items you still want to be monitored.
    if (match($0, " (Critical|Error|Warning|Notice) \\([3456]\\) ") \
     && match($2, "^[0-9]+$")) $2 = "c_a"                       # line number
    if ($6 == "Locked" && match($19, "^[0-9.]+$")) $19 = "c_1"  # thresh/ TX lev
    if ($6 == "Locked" && match($22, "^[0-9.-]+$")) $22 = "c_2" # RX lev     
    if ($6 == "Locked" && match($27, "^[0-9]+$")) $27 = "c_3"   # unerrored code words
    if ($6 == "Locked" && match($29, "^[0-9]+$")) $29 = "c_4"   # corrected code words
    if (match($0, "Current System Time:")) $0 = "c_5"
    if (match($0, "IPv4=.*D:.*H:.*M:.*S:")) $0 = "c_6"
    if (match($0, "Uptime:   ")) $0 = "c_8"
    if (match($0, "Systime:  ")) $0 = "c_9"
    # for some unknown reason "CM Hardware Address" sometimes is left empty ->
    # ignore this to avoid false positives. the value does not change anyway.
    if (match($0, "CM Hardware Address:")) $0 = "c_0"
    $0 = gensub(" (\\?\\?\\?|Mon) ", " XXX ", "g")  # time sometimes is left empty

    print
    
'} < ${TMPFILE}_raw > ${TMPFILE}_new

[ -s ${TMPFILE}_new ] || { echo no modem data available; exit; }
[ -s ${TMPFILE}_old ] && diff -Bw -I ------------ ${TMPFILE}_old ${TMPFILE}_new
mv ${TMPFILE}_new ${TMPFILE}_old