DdwrtControl


#!/bin/sh

# Controls some activities of a router running DD-WRT.
# The present script design is for the DD-WRT v24 firmware.
# Tested under Debian Lenny with curl 7.18.2.
# Currently, the wget variant does not work.
# The latter is a pitty because, for that reason, the script itself cannot
# be executed on another router with DD-WRT, as other scripts can be.
# No write access is necessary.

# To obtain usage information the present script can be invoked
# without arguments.

# A special feature is further that, if the script itself is not running on
# a router with DD-WRT, it blocks until the controlled router has reached
# the desired state, being useful for unattended operation in batch mode.

# This script was written by Stephan Seidl in 2010, no copyright is claimed.
# It is offered as-is, without any warranty.
# This script is in the public domain; do with it what you wish.

unset LANG LC_ALL
LC_ALL=C
export LC_ALL

set -e

WGET=/jffs/usr/bin/wget
CURL=/usr/bin/curl
HOSTNAME=scomm.snet
USER="<user>"
PASSWORD="<passwd>"

test -x ${WGET} || WGET=wget
test -x ${CURL} || CURL=curl

usewget=1
usewget=0

accessdata=/jffs/usr/bin/SmallSystemsAccessData
test -e ${accessdata} || accessdata=/jffs/etc/SmallSystemsAccessData
test -e ${accessdata} || accessdata=/etc/SmallSystemsAccessData

arg=""
arg2=""
arg3=""
if [ ${#} -eq 1 -o ${#} -eq 3 ]; then
  arg="${1}"
  shift
  if [ ${#} -eq 2 ]; then
    arg2="${1}"
    shift
    arg3="${1}"
    shift
    fi
  if [ "${arg}" = "-h" ]; then
    arg="${arg3}"
    arg3="${arg2}"
    arg2="-h"
    fi
  if [ -z "${arg2}" ]; then
    arg2="-h"
    arg3="${HOSTNAME}"
    fi
  if [ "${arg2}" != "-h" ]; then
    arg=""
    fi
  fi
if [ "${arg}" != "-a" -a \
     "${arg}" != "-p" -a \
     "${arg}" != "-q" -a \
     "${arg}" != "-r" ]; then
  arg=""
  fi
if [ -z "${arg}" ]; then
  pgm=`basename ${0}`
  txt=""
  txt="${txt}Usage: ${pgm} [-h <hostname>] -a (to enable the WAN interface (allow));"
  txt="${txt}       ${pgm} [-h <hostname>] -p (to disable the WAN interface (prevent);"
  txt="${txt}       ${pgm} [-h <hostname>] -q (to query the WAN interface state);"
  txt="${txt}       ${pgm} [-h <hostname>] -r (to reboot the router)"
  echo "${txt}" | tr ';' '\012' 1>&2
  exit 1
  fi

HOSTNAME="${arg3}"
nodename="${arg3}"
nodename="${nodename}.domainname"
nodename=`echo "${nodename}" | cut -f1 -d'.'`
nodename=`echo "${nodename}" | tr '[A-Z]' '[a-z]'`

if [ -r ${accessdata} ]; then
  . ${accessdata}
  eval "USER=\"\${${nodename}_user}\""
  eval "PASSWORD=\"\${${nodename}_passwd}\""
  fi

if [ ${usewget} -ne 0 ]
  then
    cmd="${WGET}"
    cmd="${cmd} --user=${USER} --password=${PASSWORD}"
    cmd="${cmd} -o /dev/null -O -"
    cmd="${cmd} http://${HOSTNAME}"
    out=`${cmd}` || :
  else
    cmd="${CURL}"
    cmd="${cmd} --user ${USER}:${PASSWORD}"
    cmd="${cmd} --output /proc/self/fd/1"
    cmd="${cmd} http://${HOSTNAME}"
    out=`${cmd} 2>/dev/null` || :
  fi
tst=`echo "${out}" | tr '\012' '@'`
if [ "${tst}" = "@" ]; then
  # Device not found.
  exit 0
  fi
out=`echo "${out}" | tr '\015' ' '`
out=`echo "${out}" | tr '\011' ' '`
out=`echo "${out}" | tr '[A-Z]' '[a-z]'`
out=`echo "${out}" | tr '"' '@'`
out=`echo "${out}" | sed 's,@,,g'`
out=`echo "${out}" | sed 's,&nbsp;, ,'`
out=`echo "${out}" | sed 's,< *span  *id=[a-z][a-z0-9]* *>,,'`
out=`echo "${out}" | sed 's,<,@<,g'`
out=`echo "${out}" | sed 's,>,>@,g'`
out=`echo "${out}" | tr '@' '\012'`
out=`echo "${out}" | sed 's,dd-wrt  *control  *panel,,g'`
out=`echo "${out}" | sed 's,dd-wrt ,@dd-wrt ,g'`
out=`echo "${out}" | sed 's,wan  *ip *:,@wan ip:,g'`
out=`echo "${out}" | sed 's,^ *wan *: *disabled *$,@wan ip: 0.0.0.0,'`
out=`echo "${out}" | sed 's,401 ,@401 ,g'`
out=`echo "${out}" | tr '@' '\012'`
out=`echo "${out}" | sed 's,^dd-wrt ,@dd-wrt ,'`
out=`echo "${out}" | sed 's,^wan ip:,@wan ip:,'`
out=`echo "${out}" | sed 's,^401 ,@401 ,'`
out=`echo "${out}" | sed -n 's,^@,,p'`
out=`echo "${out}" | sed 's,   *, ,g'`
out=`echo "${out}" | sed 's,^ ,,'`
out=`echo "${out}" | sed 's, $,,'`
problemdescription="${out}"
problemdescription=`echo "${problemdescription}" | sed -n 's,^401 ,,p'`
problemdescription=`echo "${problemdescription}" | sed -n '1p'`
majorversion="${out}"
majorversion=`echo "${majorversion}" | sed -n 's,^dd-wrt ,,p'`
majorversion=`echo "${majorversion}" | cut -f1 -d' '`
majorversion=`echo "${majorversion}" | cut -f1 -d'-'`
wanaddr="${out}"
wanaddr=`echo "${wanaddr}" | sed -n 's,^wan ip: ,,p'`
tstaddr="${wanaddr}"
tstaddr=`echo "${tstaddr}" | sed 's,[1-9],0,g'`
tstaddr=`echo "${tstaddr}" | sed 's,00*,0,g'`

if [ -n "${problemdescription}" ]; then
  pgm=`basename ${0}`
  txt="Found problem description \`${problemdescription}'."
  echo "${txt}" 1>&2
  exit 1
  fi

if [ -z "${majorversion}" ]; then
  pgm=`basename ${0}`
  txt="Found empty string as dd-wrt firmware major version, anything went wrong."
  echo "${txt}" 1>&2
  exit 1
  fi

if [ "${majorversion}" != "v24" -a \
     "${majorversion}" != "v24" -a \
     "${majorversion}" != "v24" ]; then
  pgm=`basename ${0}`
  txt="Found dd-wrt with major version \`${majorversion}' which is not supported."
  echo "${txt}" 1>&2
  exit 1
  fi

if [ "${tstaddr}" != "0.0.0.0" ]; then
  pgm=`basename ${0}`
  txt="Got illegal \`${wanaddr}' as wan ip from dd-wrt with major version \`${majorversion}'."
  echo "${txt}" 1>&2
  exit 1
  fi

if [ "${arg}" = "-a" -a "${wanaddr}" != "0.0.0.0" ]; then
  echo "${wanaddr} (WAN interface enabled)"
  exit 0
  fi

if [ "${arg}" = "-p" -a "${wanaddr}" = "0.0.0.0" ]; then
  echo "${wanaddr} (WAN interface disabled)"
  exit 0
  fi

if [ "${arg}" = "-q" ]; then
  if [ "${wanaddr}" != "0.0.0.0" ]
    then echo "${wanaddr} (WAN interface enabled)"
    else echo "${wanaddr} (WAN interface disabled)"
    fi
  exit 0
  fi

post=""
if [ "${arg}" = "-a" ]; then
  post=""
  post="${post}submit_button=Status_Internet'&'"
  post="${post}action=Apply'&'"
  post="${post}change_action=gozila_cgi'&'"
  post="${post}submit_type=Connect_pppoe"
  fi
if [ "${arg}" = "-p" ]; then
  post=""
  post="${post}submit_button=Status_Internet'&'"
  post="${post}action=Apply'&'"
  post="${post}change_action=gozila_cgi'&'"
  post="${post}submit_type=Disconnect_pppoe"
  fi
if [ "${arg}" = "-r" ]; then
  post=""
  post="${post}submit_button=Management'&'"
  post="${post}action=Reboot'&'"
  post="${post}change_action='&'"
  post="${post}submit_type='&'"
  post="${post}commit="
  fi
if [ -n "${post}" ]; then
  if [ ${usewget} -ne 0 ]
    then
      cmd="${WGET}"
      cmd="${cmd} --ignore-length"
      cmd="${cmd} --tries=1 --timeout=60"
      cmd="${cmd} --user=${USER} --password=${PASSWORD}"
      cmd="${cmd} -o /dev/null -O /dev/null"
      cmd="${cmd} --post-data=${post}"
      cmd="${cmd} http://${HOSTNAME}/apply.cgi"
      eval "${cmd}" || :
    else
      cmd="${CURL}"
      cmd="${cmd} --user ${USER}:${PASSWORD}"
      cmd="${cmd} --output /dev/null"
      cmd="${cmd} --data ${post}"
      cmd="${cmd} http://${HOSTNAME}/apply.cgi"
      eval "${cmd}" 2>/dev/null || :
    fi
  fi

if [ "${accessdata}" = "/jffs/usr/bin/SmallSystemsAccessData" ]; then
  # Finish here, if we are on a router.
  exit 0
  fi

if [ "${arg}" = "-r" ]; then
  sleep 15
  fi

while :; do
  if [ ${usewget} -ne 0 ]
    then
      cmd="${WGET}"
      cmd="${cmd} --user=${USER} --password=${PASSWORD}"
      cmd="${cmd} -o /dev/null -O -"
      cmd="${cmd} http://${HOSTNAME}"
      out=`${cmd}` || :
    else
      cmd="${CURL}"
      cmd="${cmd} --user ${USER}:${PASSWORD}"
      cmd="${cmd} --output /proc/self/fd/1"
      cmd="${cmd} http://${HOSTNAME}"
      out=`${cmd} 2>/dev/null` || :
    fi
  out=`echo "${out}" | tr '\015' ' '`
  out=`echo "${out}" | tr '\011' ' '`
  out=`echo "${out}" | tr '[A-Z]' '[a-z]'`
  out=`echo "${out}" | tr '"' '@'`
  out=`echo "${out}" | sed 's,@,,g'`
  out=`echo "${out}" | sed 's,&nbsp;, ,'`
  out=`echo "${out}" | sed 's,< *span  *id=[a-z][a-z0-9]* *>,,'`
  out=`echo "${out}" | sed 's,<,@<,g'`
  out=`echo "${out}" | sed 's,>,>@,g'`
  out=`echo "${out}" | tr '@' '\012'`
  out=`echo "${out}" | sed 's,wan  *ip *:,@wan ip:,g'`
  out=`echo "${out}" | sed 's,^ *wan *: *disabled *$,@wan ip: 127.0.0.1,'`
  out=`echo "${out}" | tr '@' '\012'`
  out=`echo "${out}" | sed -n 's,^wan ip: ,,p'`
  wanaddr="${out}"
  tstaddr="${wanaddr}"
  tstaddr=`echo "${tstaddr}" | sed 's,[1-9],0,g'`
  tstaddr=`echo "${tstaddr}" | sed 's,00*,0,g'`
  if [ -n "${out}" ]; then
    if [ "${tstaddr}" = "0.0.0.0" ]; then
      test "${arg}" = "-a" -a "${wanaddr}" != "0.0.0.0" && break || :
      test "${arg}" = "-p" -a "${wanaddr}"  = "0.0.0.0" && break || :
      test "${arg}" = "-r" -a "${wanaddr}" != "0.0.0.0" && break || :
      fi
    fi
  sleep 1
  done

if [ "${wanaddr}" = "127.0.0.1" ]; then
  wanaddr="0.0.0.0"
  fi

if [ "${wanaddr}" != "0.0.0.0" ]
  then echo "${wanaddr} (WAN interface enabled)"
  else echo "${wanaddr} (WAN interface disabled)"
  fi

exit 0


Stephan K.H. Seidl