WikiDevi.Wi-Cat.RU:DD-WRT/Miscellaneous Scripts

From WikiDevi.Wi-Cat.RU
Jump to navigation Jump to search

Backup settings and restore them

Backup settings and restore them

Clear ttraff (WAN bandwidth graph) nvram data

The ttraff daemon can fill up a couple hundred bytes of nvram space every month. This may not seem like much but nvram is only ~32KB total and is full of lots of other data. Disabling ttraff and clearing it's old nvram data is sometimes needed for devices with complex configurations, or to keep the router stable. This script will clear all of ttraff's traffic data from nvram whereas using the ttraff GUI button to delete it still leaves the current month's variable.

for i in `nvram show | grep traff- | cut -f1 -d=""`; do nvram unset $i; done

Compress the Firewall Script (to reduce nvram usage)

If you have a large firewall script you can use this script to compress it with gzip to use less nvram space. See this thread for full usage info.

# Compress Firewall
nvram set pH_fw="`nvram get rc_firewall | gzip | uuencode -m /dev/stdout`"
nvram set rc_firewall="nvram get pH_fw | uudecode -o /tmp/pH_fw.gz;gunzip /tmp/pH_fw.gz;chmod +x
/tmp/pH_fw;/tmp/pH_fw"
nvram show >/dev/null

# Decompress Firewall
nvram get pH_fw | uudecode -o /tmp/pH_fw.gz
nvram unset pH_fw
gunzip /tmp/pH_fw.gz
nvram set rc_firewall="`cat /tmp/pH_fw`"
nvram show >/dev/null

# Editing the Firewall
vi /tmp/pH_fw

# finish editing with vi before running the rest
nvram set rc_firewall="`cat /tmp/pH_fw`"
nvram show >/dev/null

Web Server Wake-up

  • Wakes up your web server when the router receives a request from the internet. Credits from here.

Please note: syslogd needs to be on, logging enabled, with log level set high, and "accepted" on. Following the example script, replace target and MAC values with those of your LAN web server's network information and for "$WOL -i xxx.xxx.xxx.255", replace xxx.xxx.xxx.255 with your LAN network broadcast address.

#!/bin/sh

INTERVAL=5
NUMP=3
OLD=""
WOL=/usr/sbin/wol
TARGET=192.168.1.100
MAC=00:00:00:00:00:00
LOGFILE="/tmp/www/wol.log"

while sleep $INTERVAL;do
  NEW=`awk '/ACCEPT/ && /DST='"$TARGET"'/ && /DPT=80/ {print $3}' /var/log/messages | tail -1`
  SRC=`awk -F'[=| ]' '/ACCEPT/ && /DST='"$TARGET"'/ && /DPT=80/ {print $13}' /var/log/messages | tail -1`
  LINE=`awk '/ACCEPT/ && /DST='"$TARGET"'/ && /DPT=80/' /var/log/messages`
  if [ "$NEW" != "" -a "$NEW" != "$OLD" ]; then
    echo "$SRC $LINE"  >> $LOGFILE
    RET=`ping -c $NUMP $TARGET 2> /dev/null | awk '/packets received/ {print $4}'`
    if [ "$RET" -ne "$NUMP" ]; then
      echo "$SRC causes WOL at" `date`  >> $LOGFILE
      $WOL -i 192.168.1.255 -p 7 $MAC  >> $LOGFILE
      sleep 5
    fi
    OLD=$NEW
  fi
done

Auto Random MAC Address

  • This script will change your eth1 MAC address to a random address, then it will apply it to the system and restart the interfaces.
#!/bin/ash
MAC=`(date; cat /proc/interrupts) | md5sum | sed -r 's/^(.{10}).*$/\1/; s/([0-9a-f]{2})/\1:/g; s/:$//;'`
echo "00:${MAC}"
ifconfig eth1 hw ether 00:${MAC}
nvram set def_hwaddr="00:${MAC}"
nvram set wan_hwaddr="00:${MAC}"
stopservice wan
startservice wan

You may wish to also download curl (see ipkg), and use it to restart your modem, as some MAC changes may not reflect until your modem "sees" a new address, and they typically only do this when starting up.

Note: curl is sometimes problematic to install. You should use ipkg -force-depends

An example, to restart a Motorola Surfboard SB4100 cable model is:

curl -s -d "BUTTON_INPUT=Restart+Cable+Modem" http://192.168.100.1/configdata.html

To restart a Motorola SB5101:

curl -d ResetReq=1 http://192.168.100.1/goform/RgConfig

I added the following lines to the end of the above to restart a Motorola SB5120 (no curl required!!) and reboot. Running this script in cron, and my ISP won't automatically recover without the following:

nvram commit & sleep 5 && wget http://192.168.100.1/reset.htm?reset_modem=Restart+Cable+Modem
reboot

Don't know the reason but Motorola SB5101 only re-started with the two following lines:

curl -v -d "RestoreFactoryDefault=1&ResetReq=1" http://192.168.100.1/goform/RgConfig
curl -d ResetReq=1 http://192.168.100.1/goform/RgConfig

Wireless Network Scanner (awk -f scanner)

Wireless Network Scanner (awk -f scanner)

Wireless Network Scanner (working on DD-WRT v24)

I took the above script and tweaked it to work in DD-WRT v24 firmware, with the "wl" command.

To run just copy and paste in a console (telnet or ssh) or save as a "scanner.sh" and run as ./scanner.

#!/bin/sh

awk -F"[][]" '
BEGIN{
 IGNORECASE = 1;
 command = "site_survey 2>&1";
 red = "\x1b[31m";              green = "\x1b[32m";
 greenback="\x1b[42m";          yellow = "\x1b[33m";
 cyan = "\x1b[36m";             blue = "\x1b[34m";
 blueback = "\x1b[44m";         white = "\x1b[37m";
 whiteback = "\x1b[47m";        reset = "\x1b[0m";
 underscore = "\x1b[4m";        clear = "\x1b[2J";
 home = "\x1b[0;0H";            erase2end = "\x1b[K";
 cName = white;                 cSignal = green;
 cNoise = red;                  cCaps = green;
 cStrengthLow = blue blueback;  cChannel = green;               
 cStrengthMed = white whiteback;
 cStrengthHi = green greenback;
 cStrengthAged = red;
  
 print clear;
 for(;;)
 {
  while (command|getline)
  {    
    if ($22 == "") continue;
    bssid=$6;
	name[bssid] = $4;
	rssi[bssid] = $10;
	noise[bssid]= $12;
	channel[bssid] = $8;
	caps[bssid] = $22;
	age[bssid] = 1;
  }
  close(command);
  printf home;
  ln = 0;
  print white " Name       BSSID  Signal Noise Channel Type";
  for (x in name)
  {                  
        #arbitrary strength calc through trial and error... modify as you wish:
        sigstrength = ((rssi[x] - noise[x])*1.5) + ((rssi[x] +90)*1.5);
        if (sigstrength <1) sigstrength=0;
        cStrength = cStrengthLow;
        if(sigstrength>4) cStrength = cStrengthMed;
        if(sigstrength>7) cStrength = cStrengthHi;
        if(age[x]=0) cStrength = cStrengthAged;        
        fmt = "%s%-15s %s%0"sigstrength"d "reset erase2end "\n    %s  %s%-4d %s%-4d %s%-4d %s%2s "  reset erase2end "\n" erase2end "\n";
        printf fmt, cName,name[x],cStrength,0,x,cSignal,rssi[x],cNoise,noise[x],cChannel, channel[x],cCaps,caps[x]; 
        rssi[x] = "-100 xxxx";
        ln++;        
  }  
  if (ln ==0) 
    print red "No results - Do you have survey capability? \nThis program depends on site_survey to run. Hit ctrl-c to stop.";

  print erase2end;
 }
}
'

Name-based WOL (wake.sh)

  • Enables you to power on a LAN computer by name instead of IP address/MAC, based on DHCP lease table (mandatory).

Usage: /path/to/wake.sh <hostname> (default hostname is desktop)

STATION=mm
WOL=/usr/sbin/wol
STATICS=/tmp/udhcpd.statics
DEV=br0

if [ -n  "$1" ]; then
   STATION=$1
fi

while read LINE
do
   IP=`echo $LINE | awk '{print $1}'`
   MAC=`echo $LINE | awk '{print $2}'`
   FOUND=`ip neigh | grep "$IP.*REACHABLE"`
   if [ -z "$FOUND" ]; then
      echo Creating ARP entry for $IP $MAC
      ip neigh add $IP lladdr $MAC dev $DEV nud reachable 2> /dev/null
      ip neigh change $IP lladdr $MAC dev $DEV nud reachable 2> /dev/null
   fi
done < $STATICS


LEASE=`grep "\b$STATION\b$" $STATICS`
if [ -n "$LEASE" ]; then
   IP=`echo $LEASE | awk '{print $1}'`
   MAC=`echo $LEASE | awk '{print $2}'`
   $WOL -i $IP $MAC
else
   echo Unable to find \"$STATION\" in DHCP static file $STATICS, please use \"$0 \<hostname\>\"
fi

Automatic Connection Repair (always_on.sh)

  • Pings your default gateway every time and force a DHCP renew if no packets are received.
    Usage: /path/to/always_on.sh &
#!/bin/sh
INTERVAL=10
PACKETS=1
UDHCPC="udhcpc -i vlan1 -p /var/run/udhcpc.pid -s /tmp/udhcpc"
IFACE=vlan1


ME=`basename $0`
RUNNING=`ps | awk '/'"$ME"'/ {++x}; END {print x+0}'`
if [ "$RUNNING" -gt 3 ]; then
   echo "Another instance of \"$ME\" is running"
   exit 1
fi

while sleep $INTERVAL
do
   TARGET=`ip route | awk '/default via/ {print $3}'`
   RET=`ping -c $PACKETS $TARGET 2> /dev/null | awk '/packets received/ {print $4}'`

   if [ "$RET" -ne "$PACKETS" ]; then
      echo "Ping failed, releasing IP address on $IFACE"
	#send a RELEASE signal
      kill -USR2 `cat /var/run/udhcpc.pid` 2> /dev/null
	#ensure udhcpc is not running
      killall udhcpc 2> /dev/null
      echo "Renewing IP address: $IFACE"
      $UDHCPC
      echo "Waiting 10 s..."
      sleep 10
   else
      echo "Network is up via $TARGET"
   fi
done
  • The following version will work even on resource-starved Linksys WRT54G v8, which lacks most programs needed by the script above. To use it, just add this code to DD-WRT's startup script using the web interface.
INTERVAL=10
while true; do
  while [ \! $gw ]; do
    sleep 30
    route -n >/tmp/routes
    while read dest gw foo; do
      if [ $dest = "0.0.0.0" ]; then
        break
      fi
    done
    </tmp/routes
  done
  logger "auto-repair: default gateway is $gw"
  while ping -qc 2 $gw >/dev/null ; do
    sleep $INTERVAL
  done
  logger "auto-repair: gateway down, restarting WAN"
  kill -USR1 `cat /var/run/udhcpc.pid`
  unset gw
done &

Modifying $PATH at Startup

This will add whatever paths you want for $PATH and $LD_LIBRARY_PATH before the default system path. Change the paths to whatever you like. Have a good reason for doing this, it should be considered a hack until the feature is implemented permanently.

rm -f /tmp/newProfile
head -n1 /etc/profile | sed s!=!=/mmc/bin:/whatever/bin:! >> /tmp/newProfile
tail -n1 /etc/profile | sed s!=!=/mmc/lib:/whatever/lib:! >> /tmp/newProfile
mount --bind /tmp/newProfile /etc/profile

If you're adding /mmc/lib before the system library, in some circumstances you'll also need to do this on startup (after ensuring that the ldconfig on /mmc is up to date and happy):

mount --bind /mmc/etc/ld.so.conf /etc/ld.so.conf
mount --bind /mmc/etc/ld.so.cache /etc/ld.so.cache

Note: Only do this if you're receiving segmentation faults or your applications are failing to run, and even then only if you feel that this hack is imperative. Also note that if you're attempting this with Optware, the files are ld-opt.so.conf and ld-opt.so.cache

Another alternative to the above mentioned way of altering things is to simply copy /etc/profile to /jffs/etc, change PATH and LD_LIBRARY_PATH and bind the profile to the original location.

mkdir /jffs/etc
cp /etc/profile /jffs/etc/profile
cd /jffs/etc
vi profile (change everythings that suite your needs and save it with :x)

Afterward put the line below inside a startup script

mount --bind /jffs/etc/profile /etc/profile

Make sure you're familiar with what you're doing before attempting this, if you end up seeing a lot of segmentation faults when running things like ls, cat, cp, etc, than you'll want to either adjust the above commands, or else put those things into a script and run them manually when you enter your shell.

Modifying $PATH Manually (path.sh)

  • Enables adjustment of paths on a per-use basis (i.e. when you're running a terminal and need the new paths, run this script.).
#!/bin/sh
export PATH=$PATH:/mmc/bin:/whatever/bin
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/mmc/lib:/whatever/lib

Alternatively, if you want to give priority to you're personally installed applications (i.e. you've installed a more robust version of grep, and want to use it by default), add the new paths before $PATH and $LD_LIBRARY_PATH, as shown below.

#!/bin/sh
export PATH=/mmc/bin:/whatever/bin:$PATH
export LD_LIBRARY_PATH=/mmc/lib:/whatever/lib:$LD_LIBRARY_PATH

View Logfile in Browser without Local Syslogd (log.sh)

View Logfile in Browser without Local Syslogd

Speak Your Signal Strength

I use my WRT in client mode to connect to an access point, but I don't have a particularly good signal quality and I often need to re adjust the position of the WRT and its antenna. Unfortunately my computer is not in sight of the WRT and I had to keep going backwards and forwards from my computer to the WRT making adjustments then checking the signal strength on the screen of my computer. This can take ages to to set up properly, so I decided to get my computer to use the "festival" speech synthesis program to tell me what the current signal level is.

#! /bin/bash
# Use "festival" to say out loud how much signal strength we have

# The IP address of the WRT
ip_addr="192.168.1.1"

# The username and password for the WRT
user="root"
pass="admin"

# Tempory file used to hold the data from the WRT
tmp_file=/tmp/wrt.status

echo
echo "The signal level is:-"
echo
echo "The signal level is" | festival --tts
 
while true ; do
  wget --http-user=$user --http-password=$pass http://$ip_addr/Status_Wireless.live.asp -O $tmp_file -o /dev/null
  signal=`awk  -F "'" '/active_wireless/ { print  $8 }' $tmp_file`
  echo $signal | awk '{printf"Signal  :  "$1"\t";for(;j<$1;j++)printf"=";printf"\n"}'

  if [[ -n $signal ]] ; then
    echo $signal | festival --tts
  else
     echo "Not associated" | festival --tts
  fi
done

This works by using the same process as the 'Status-->Wireless' page i.e. it gets a chunk of data by wget'ing the Status_Wireless.live.asp page from the WRT then running awk to get the relevant chunk of data (the signal strength) and then piping that into the festival speech engine.

Now I just run this script and turn up the volume on my computer when I need to move the antenna.

Small Security Script (Firewall)

#!/bin/sh

#
# Warning! As I don't use Emule or similiar programs I can't guaranty their function.
# If you find a workable solution just add it to this wiki.
# I found testing some of the setting manually that the ipfrag settings will break emule, 
# maybe some others too...
# 
# Enjoy your enhanced security,
#
# St. Karitzl
# info@user1.walztech.de
# http://daywalker81.de.vu

echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all
echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
echo 1 > /proc/sys/net/ipv4/ip_forward

# the following two parametes will break at least emule and are way too low to make sense.
#echo 1024 > /proc/sys/net/ipv4/ipfrag_high_thresh
#echo 512 > /proc/sys/net/ipv4/ipfrag_low_thresh 
echo 64000 > /proc/sys/net/ipv4/ipfrag_high_thresh
echo 48000 > /proc/sys/net/ipv4/ipfrag_low_thresh 
#

echo 10 > /proc/sys/net/ipv4/ipfrag_time 
echo 5 > /proc/sys/net/ipv4/icmp_ratelimit
echo 1 > /proc/sys/net/ipv4/tcp_syncookies
echo 0 > /proc/sys/net/ipv4/conf/eth1/accept_source_route
echo 0 > /proc/sys/net/ipv4/conf/eth1/accept_redirects 
echo 1 > /proc/sys/net/ipv4/conf/eth1/log_martians 
echo 10 > /proc/sys/net/ipv4/neigh/eth1/locktime
echo 0 > /proc/sys/net/ipv4/conf/eth1/proxy_arp
echo 50 > /proc/sys/net/ipv4/neigh/eth1/gc_stale_time

#
# The following entries secure the last bit and provide a
# moderate protection against man-in-the-middle attacks.
# 

echo 0 > /proc/sys/net/ipv4/conf/eth1/send_redirects
echo 0 > /proc/sys/net/ipv4/conf/eth1/secure_redirects
echo 1 > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses
echo 5 > /proc/sys/net/ipv4/igmp_max_memberships
echo 2 > /proc/sys/net/ipv4/igmp_max_msf
echo 1024 > /proc/sys/net/ipv4/tcp_max_orphans
echo 2 > /proc/sys/net/ipv4/tcp_syn_retries
echo 2 > /proc/sys/net/ipv4/tcp_synack_retries
echo 1 > /proc/sys/net/ipv4/tcp_abort_on_overflow
echo 10 > /proc/sys/net/ipv4/tcp_fin_timeout
echo 0 > /proc/sys/net/ipv4/route/redirect_number
echo 1 > /proc/sys/net/ipv4/conf/all/rp_filter
echo 1 > /proc/sys/net/ipv4/conf/eth1/rp_filter
echo 1 > /proc/sys/net/ipv4/tcp_syncookies
echo 0 > /proc/sys/net/ipv4/conf/all/accept_source_route
echo 61 > /proc/sys/net/ipv4/ip_default_ttl

# DoS protection by tweaking the timeouts
echo "1800" > /proc/sys/net/ipv4/tcp_keepalive_time
echo "0" > /proc/sys/net/ipv4/tcp_window_scaling
echo "0" > /proc/sys/net/ipv4/tcp_sack

# We pretend to be a Checkpoint firewall on Windows XP
echo 4096 87380 4194304 >/proc/sys/net/ipv4/tcp_rmem
echo 4096 87380 4194304 >/proc/sys/net/ipv4/tcp_wmem

# Check network overload (explicit congestion notification)
echo 1 > /proc/sys/net/ipv4/tcp_ecn

# Change port range for outgoing traffic
echo "30000 60000" > /proc/sys/net/ipv4/ip_local_port_range

# Change default queue size
# Modified for DD-WRT because of missing proc entries

echo 4096 > /proc/sys/net/ipv4/ip_conntrack_max

# LED signal feedback when script ends
sleep 1
gpio enable 3
sleep 1
gpio disable 3
sleep 1
gpio enable 3
sleep 1
gpio disable 2
sleep 1
gpio enable 2
sleep 1
gpio disable 2

# If you'd like to disable the web interface uncomment
# the following line
#killall httpd

Attention, you might have to change eth1 to the actual WAN (external) interface.

Installation is pretty simple:

  1. Log on to your WRT
  2. type cd /jffs
  3. type vi sec.sh (or any other name) and enter the script
  4. Connect to your WRT via web browser, page Administration:Commands
  5. Enter the script name (sec.sh) into the command field
  6. Click on "Save Startup"
  7. Reboot router


As a simple test try to ping your router. You should get no response otherwise you have to find the error.

Secure remote management for a WAP

Regards to the help of phusi0n dd-wrt guru and of HP from ubuntu-fr

This requires a recent >12533 to prevent milw0rm and to have the Disable "Allow any remote IP" feature. Also requires you have set the necessary port forwards in the gataways(s) on the path.

iptables -I INPUT -p tcp -j DROP
iptables -I INPUT -s `nvram get lan_ipaddr`/`nvram get lan_netmask` -p tcp -m multiport --dports `nvram get sshd_port`,443 -j ACCEPT
iptables -I INPUT -s `nvram get remote_ip | awk '{print $1}'` -p tcp -m multiport --dports `nvram get sshd_port`,443 -j ACCEPT

This allows the lowest (first) IP address set in the "Allow any remote IP" feature to connect to the https and ssh servers in the WAP (you just need the password and/or the private key) ;) . In addition, all LAN ip are allowed to do the same. Althought the "Allow any remote IP" feature doesn't work at this time when the router is set as a WAP (LAN-LAN link to the gateway, so no routing and WAN disabled, dhcp off and other stuff), this convenient script will use the first "remote_ip" you set in the GUI (wether the feature is enabled or not, as long as you stored at least one IP) and will follow the changes you could do to its static lan ip/netmask and ssh server port. Now you have full benefit of the GUI from a remote static IP and can leave the forwards enabled on the path.

--Bib 14:03, 17 May 2010 (CEST)

Block URLs with an Automatically Downloaded Host File

This was originally taken from mraneri from the Linksys forum, but was heavily modified.

#!/bin/sh

logger WAN up script executing
sleep 5
if test ! -s /tmp/dlhosts
then
	cat >/tmp/dlhosts <<"EOF"
#!/bin/sh
logger Downloading http://www.mvps.org/winhelp2002/hosts.txt
wget -O - http://www.mvps.org/winhelp2002/hosts.txt |
	grep 127.0.0.1 |
	sed '2,$s/127.0.0.1/0.0.0.0/g; s/[[:space:]]*#.*$//g;' |
	grep -v localhost |
	tr ' ' '\t' |
	tr -s '\t' |
	sort -u >/tmp/hosts0
grep addn-hosts /tmp/dnsmasq.conf ||
	echo "addn-hosts=/tmp/hosts0" >>/tmp/dnsmasq.conf
logger Restarting dnsmasq
killall -1 dnsmasq
EOF
	chmod 777 /tmp/dlhosts
	/tmp/dlhosts
fi
grep -q '/tmp/dlhosts' /tmp/crontab || 
	echo "45 23 * * 5 root /tmp/dlhosts" >>/tmp/crontab

This script automatically downloads a host file from: "http://www.mvps.org/winhelp2002/hosts.txt" and redirects all the URLs in that file to 127.0.0.1. All those URLs are common malware or advertisement sites so is better to block them. You can also download the file, modify it with new URLs that you want to block or delete the ones you don't want to block and then upload to a web site and change the URL in the code to your custom one. Be aware that the more URLs in the file the more RAM that you will be eating from your router. Check the file size and your free memory to see if it will suit you. If not just erase some URLs... If you want to block all URLs since the router boots then just placed in the startup scripts.

Directory Listing for DD-WRT Micro

Since the Micro version of DD-WRT doesn't provide a ls command, here is a very simple script to list directory contents

#!/bin/sh
files=`echo *`
for x in $files; do
  if [ -d $x ]; then
    echo -n "$x/ "
  else
    echo -n "$x "
  fi
done
echo

See the Telnet/SSH and the Command_Line Talk page for other variants.

Global Management of Blacklists

If you have a lot of DD-WRT routers, then denying of access for abusing users through the web interface of each router can be time consuming. Here is a small firewall script to automatically download MAC-addresses of computers that should be denied access. The format of the file is Unix textfile one MAC address per line. The script assumes that you have a jffs partition. You can run it at startup by saving it as /jffs/etc/config/wifi_bl.wanup

#!/bin/sh
cd /jffs
rm wifi_blacklist.txt
#Please modify the script to download the blacklist file from your web server
wget http://www.myserver.com/wifi_blacklist.txt
module_exists=`lsmod | grep ipt_mac`
if [ -z "$module_exists" ] ; then
    insmod ipt_mac
fi
#Deleting the old table
old_mac=`iptables -L | egrep "..:..:..:..:..:.."  | sed "s/.*\(..:..:..:..:..:..\).*/\1/"`
for mac in $old_mac ; do
    iptables -D FORWARD -p tcp -m mac --mac-source $mac -j REJECT --reject-with tcp-reset
done
#Adding the table again
for mac in `cat /jffs/wifi_blacklist.txt` ; do
    iptables -I FORWARD -p tcp -m mac --mac-source $mac -j REJECT --reject-with tcp-reset
done

White Listing

If you want to create a white list to block access by default but allow certain traffic through, then you can use this script to do it. Remove any junk comment lines beginning with # to save nvram space. Discuss here.

# IP Tables White Listing script by phuzi0n -Tek @ http://www.dd-wrt.com/phpBB2/viewtopic.php?t=56588

# Set up the chain
iptables -N wanout
iptables -I INPUT -i `nvram get lan_ifname` -j wanout
iptables -I FORWARD -i `nvram get lan_ifname` -j wanout

# Create whitelist 'function' script
WOUT="/tmp/wanout"
echo 'iptables -I wanout $1 -j ACCEPT' > $WOUT
chmod 777 $WOUT

# Exempt Machine MAC
insmod ipt_mac
$WOUT '-m mac --mac-source 00:30:18:A9:A9:C6'

# Exempt Machine IP
$WOUT '-s 192.168.1.2'

# Allow everyone access to these sites
$WOUT '-d www.google.com'
$WOUT '-d www.yahoo.com'
$WOUT '-d www.dd-wrt.com'

# Allow everyone access to these IP Addresses
$WOUT '-d 74.125.67.100'
$WOUT '-d 74.125.127.100'
$WOUT '-d 74.125.45.100'
$WOUT '-d 209.131.36.158'

#Allow everyone access to specific destination ports
$WOUT '-p udp --dport 8000'
$WOUT '-p tcp --dport 80'


# Everything else gets blocked
iptables -A wanout -j REJECT --reject-with icmp-proto-unreachable

Reset Wireless Radio

#!/bin/sh

# This script solves an intermitent problem on my
# NetGear WNDR3300 wireless N radio.  Every few
# hours,  the wireless N radio stops broadcasting
# and cannot be seen by wireless clients.  Bringing
# the wireless interface down and then back up
# resolves the issue.  This script pings a
# wireless client, in my case, a WET610N wireless
# bridge that should always remain up and only
# connects to the wireless N radio.  If the
# ping fails twice within a given time, it
# brings the interface down and then back up.

# A wireless client that should always be up
CLIENT_IP=192.168.35.250

# Wireless interface that disappears
INTERFACE=`nvram get wl0_ifname`

# seconds to wait after failed ping to try again
FAIL_AGAIN=10

# seconds between checks
CHECK_EVERY=60

# after cycling, wait this many seconds
AFTER_CYCLE=360

# Client must be up before starting main loop
while true
do
  if ping -c 1 ${CLIENT_IP} >/dev/null
  then
    echo "${CLIENT_UP} ok - begining main loop"
    break
  fi
done

# main script
while sleep ${CHECK_EVERY}
do
  if ping -c 1 ${CLIENT_IP} >/dev/null
  then
    echo "${CLIENT_IP} ok"
  else
    echo "${CLIENT_IP} dropped one"
    sleep ${FAIL_AGAIN}
    if ! ping -c 1 ${CLIENT_IP} >/dev/null
    then
      echo "${CLIENT_IP} dropped two, sending restarting ${INTERFACE}"
      wl -i ${INTERFACE} down
      sleep 3
      wl -i ${INTERFACE} up
      sleep ${AFTER_CYCLE}
    fi
  fi
done 2>&1

Change WLAN Channel on Command Line

If you have trouble with the web interface you might find this small script useful.
It just changes the WLAN channel from the command line.
The basic idea is from here.

#!/bin/sh

cur_channel=`nvram get wl_channel`

usage()
{
cat << END

Usage:   `basename $0` <1-14>
Example: `basename $0` 1 - set channel to 1

Current channel is $cur_channel
END
exit 1
}

# Test if there is only one parameter
# and if this parameter is an integer between 1 and 14
if [ $# -ne 1 ]; then
  usage
else
  if echo $1 | grep "^[0-9]*$" > /dev/null 2>&1; then
    if [ $1 -gt 14 ]; then
      usage
    fi
  else
    usage
  fi
fi

echo "Setting channel from $cur_channel to $1"
nvram set d11g_channel=$1
nvram set wl_channel=$1
nvram set wl0_channel=$1

# Make the change permanent
nvram commit > /dev/null 2>&1

ssid=`nvram get wl0_ssid`
I=`nvram get wl0_ifname`

wl -i $I channel $1
wl -i $I ssid $ssid
arp -d `nvram get lan_gateway`

exit 0
# EOF

Display Connection Counts Per IP

for i in `grep 0x /proc/net/arp | cut -d ' ' -f1`; do echo "$i connection count: $(grep -c $i /proc/net/ip_conntrack)"; done

Randome mac generator script

#!/bin/ash
MAC=`(date; cat /proc/interrupts) | md5sum | sed -r 's/^(.{10}).*$/\1/; s/([0-9a-f]{2})/\1:/g; s/:$//;'`
echo "00:${MAC}"
ifconfig eth1 hw ether 00:${MAC}
nvram set def_hwaddr="00:${MAC}"
nvram set wan_hwaddr="00:${MAC}"
stopservice wan
startservice wan

Single button multifunction script

by discofreakboot

 
#!/bin/sh

### Single button multifunction script.
### In lamens terms, press a button a different number of times
### to perform different tasks.

### Created by David J. Thompson, a.k.a. discofreakboot.
### This script is free to use, modify, copy, and all that
### extra bullcrap.  Personal and commercial use is cool with
### me.

### This script was written specifically for my WRT54G-TM
### running DD-WRT.  I do not specifically endorse DD-WRT and
### would gladly welcome translating this to other router
### firmwares.  I'm just too lazy to do it myself.

### Basically, I wanted to do more than one thing with my SES
### button, so I spent hours learning how to write shell
### scripts so I could write this.  Depending on how many
### times you hit the button during a short period of time,
### it will execute commands or scripts of your choosing.

### Oh! Almost forgot.  You really need a JFFS partition to
### store this on.  Or if you've hardware modded your router
### to accept SD cards, whatever.

### Also I do not own the AutoAP script.  You can go find a
### copy of it yourself.  Just Google it.  Really comes in
### handy, though.

count_down()
{
sleep 1
nvram set code_sleepTime="$(( $(nvram get code_sleepTime) - $one ))"
if [ "$(nvram get code_sleepTime)" -gt "0" ];
   then   
      echo "$(nvram get code_sleepTime)"
      count_down      
fi
}


if [ "$(nvram get code_FIRSTPUSH)" -eq "0" ];
   then
      nvram set code_FIRSTPUSH="1"
      gpio disable 2
      sleep 5
      if [ "$(nvram get code_clickVar)" -eq "0" ];
         then
            nvram set code_FIRSTPUSH="0"
            gpio enable 2
            wl radio off ##--- Make sure you comment out or delete this line.  I use it as sort of a panic mode, so with a single button press the radio gets killed.
         exit
      else
         count_down
         gpio enable 2
         nvram set code_FIRSTPUSH="0"
         nvram set code_sleepTime="0"
         case "$(nvram get code_clickVar)" in
            "1") wl radio on  ##--- This means one after the initial click, so really two clicks.
            break
            ;;
            "2") /jffs/etc/config/autoap.sh   ##--- Three clicks, and I think you get the idea.
            break
            ;;
            "3") reboot  ##--- I wouldn't get too carried away.  I think three or four tasks is enough.
            break
            ;;
         esac
         nvram set code_clickVar="0"
      fi
else
   nvram set code_clickVar="$(( $(nvram get code_clickVar) + $one ))"
   nvram set code_sleepTime="$(( $(nvram get code_sleepTime) + 2 ))"
fi
## I hope you like my script.  Let me know if you've made any improvements.

Asus RT-N16 WPS button

http://www.dd-wrt.com/phpBB2/viewtopic.php?p=679436#679436

#!/opt/bin/bash

# JuiciPackets' WPS.sesbutton v2
# Customizes the action of the red WPS button on Asus RT-N16 (and possibly other routers running DD-WRT)
# Flashes Power LED and emits audio beeps (via USB audio) to give feedback


# If you find this script useful please send me a (very) small fraction of a bitcoin - just for the fun of it :)
# (e.g. 0.01 BTC equals around 0.05 USD today - that's just 5 cents!) at 1P7SL8ris4pHtWNgR9chFstgPJKKVLzJmP
# This is not about the money (after all 100 times 0.01 BTC barely buys me a beer around here)
# It's more for the thrill of receiving "something" :) and to spread the word about Bitcoin


# This script needs USB audio and sox working in order to give you audio feedback
# But if you don't have or don't want them you can simply comment out the lines below.
# The act?.wav files in /opt/download/asusvoices/ are some text-to-speech .wav files I generated
# to describe the performed actions (e.g. "rebooting in 5 seconds" for action 5 below).
# You can of course record your own voice if you so wish :)


set -o nounset
#set -o errexit

# temporary nvram variables (not committed to flash):
WPS_FIRST=WPS_FIRST
WPS_MUTEX=WPS_MUTEX
WPS_COUNT=WPS_count

# Check the number of button "clicks" at most 5 times at 3 seconds intervals:
TRIES=5
INTERVAL=3

# Asus RT-N16 specific:
LED=1
WPS_BUTTON=8

# feedback parameters:
LED_FLASHES=1
LED_OFF=80000
LED_ON=20000

logit="logger -p local0.notice -t sesbutton"
arg_count=$(echo ${1:-1} | tr -dc '[0-9]')

# usage: flash_led count usec_off usec_on
flash_led ()
{
  counter=$1; shift
  off=$1; shift
  on=$1; shift

  while [ $counter -gt 0 ];do
    gpio enable $LED
    #echo led off
    usleep $off
    gpio disable $LED
    #echo led on
    usleep $on
    let counter-=1
  done
}

# usage: beep count usec_off usec_on
beep ()
{
  counter=$1; shift
  off=$1; shift
  on=$1; shift
  duration=$(echo "scale=2; $on/1000000" | /opt/bin/bc)

  while [ $counter -gt 0 ];do
    /opt/bin/sox 1>/dev/null 2>&1 -q -r 8000 -n -t ossdsp /dev/dsp synth $duration sine 300-3300
    usleep $off
    let counter-=1
  done
}


#$logit "$$ WPS button press detected"
flash_led $arg_count $LED_OFF $LED_ON &
beep $arg_count 0 $LED_ON

if [ -n "$(nvram get $WPS_FIRST)" ]
then
    #$logit "$$ can not acquire $WPS_FIRST"
    while [ -n "$(nvram get $WPS_MUTEX)" ]
    do
        usleep 100000
    done
    trap 'nvram unset $WPS_MUTEX; trap - INT TERM EXIT; exit 3' INT TERM EXIT
    nvram set $WPS_MUTEX=$$
      nvram set $WPS_COUNT=$(($(nvram get $WPS_COUNT)+$arg_count))
      #$logit "$$ $WPS_COUNT=$(nvram get $WPS_COUNT)"
    nvram unset $WPS_MUTEX
    trap - INT TERM EXIT
    exit 1
fi

trap 'nvram unset $WPS_COUNT; nvram unset $WPS_MUTEX; nvram unset $WPS_FIRST; trap - INT TERM EXIT; exit 2' INT TERM EXIT
nvram set $WPS_FIRST=1
#$logit "$$ $WPS_FIRST acquired"
nvram set $WPS_MUTEX=$$
  nvram set $WPS_COUNT=$arg_count
  #$logit "$$ $WPS_COUNT=$arg_count"
nvram unset $WPS_MUTEX
old_count=$arg_count

while ((TRIES > 0))
do
    sleep $INTERVAL
    new_count=$(nvram get $WPS_COUNT)
    if [ $new_count -gt $old_count ]
    then
        old_count=$new_count
        TRIES=$(($TRIES-1))
        continue
    else
        break
    fi
done
nvram set $WPS_MUTEX=$$
  new_count=$(nvram get $WPS_COUNT)
  #$logit "$$ final $WPS_COUNT=$new_count"
  flash_led $new_count "$LED_ON"0 "$LED_OFF"0 &
  beep $new_count 0 "$LED_ON"

  case $new_count in
  "1") $logit "$$ running action 1 - ..."
       /opt/bin/sox 1>/dev/null 2>&1 -q -v 3.0 /opt/download/asusvoices/act1.wav -t ossdsp /dev/dsp
       result=$(command1)
       if [ -n "$result" ]
       then
         $logit "$$ action 1 returned output $result"
         /opt/bin/sox 1>/dev/null 2>&1 -q -r 8000 -n -t ossdsp /dev/dsp synth 0.5 sine 300-3300 repeat 2
       else
         $logit "$$ action 1 did not return any output"
         /opt/bin/sox 1>/dev/null 2>&1 -q -r 8000 -n -t ossdsp /dev/dsp synth 1 sine 5000 repeat 1
       fi
       ;;
  "2") $logit "$$ running action 2 - ..."
       /opt/bin/sox 1>/dev/null 2>&1 -q -v 3.0 /opt/download/asusvoices/act2.wav -t ossdsp /dev/dsp
       /path/to/command2 arg1 arg2 arg3 ...
       result=$?
       $logit "$$ action 2 returned exit code $result"
       /opt/bin/sox 1>/dev/null 2>&1 -q -r 8000 -n -t ossdsp /dev/dsp synth 0.5 sine 300-3300 repeat 2
       ;;
  "3") $logit "$$ running action 3 - ..."
       /opt/bin/sox 1>/dev/null 2>&1 -q -v 3.0 /opt/download/asusvoices/act3.wav -t ossdsp /dev/dsp
       command3
       ;;
  "4") $logit "$$ running action 4 - ..."
       /opt/bin/sox 1>/dev/null 2>&1 -q -v 3.0 /opt/download/asusvoices/act4.wav -t ossdsp /dev/dsp
       command4
       ;;
  "5") $logit "$$ rebooting in 5 seconds (/sbin/reboot)"
       /opt/bin/sox 1>/dev/null 2>&1 -q -v 3.0 /opt/download/asusvoices/act5.wav -t ossdsp /dev/dsp
       /opt/bin/sox 1>/dev/null 2>&1 -q -r 8000 -n -t ossdsp /dev/dsp synth 30 pinknoise &
       ( /opt/bin/sleep 5; sync; /sbin/reboot ) &
       ;;
  "6") $logit "$$ running action 6 - ..."
       ;;
  "7") $logit "$$ running action 7 - ..."
       ;;
  esac


nvram unset $WPS_COUNT
nvram unset $WPS_MUTEX
nvram unset $WPS_FIRST
trap - INT TERM EXIT
#$logit "$$ $WPS_FIRST released"

exit 0

Storing arbitrary scripts in nvram (nvram_files)

by nathan1

I have a memory limited WNDR3300 that I wanted to use OpenVPN with filesystem configuration (not via the GUI). Due to lacking jffs space (320k) with the openvpn build I decided to write something to basically serialize arbitrary files to nvram and then load them back on boot.

This has been useful for any files/scripts on systems where I don't have a usable jffs but still have a need for some normal files that persist.

You can paste this as-is into Administration->Commands->Save Startup. At next boot, it will deploy itself with a few commands available under /tmp/nvram_scripts/. Any file saved under /tmp/nvram_scripts/ will be tar'd up and stored in nvram variable nvram_files, assuming there is enough space in nvram. The script attempts to ensure there is at least 1000 bytes left in nvram ($minfree) or will refuse to commit.

After creating configuration or scripts in /tmp/nvram_files, the commit script can be used to save it to persist to next boot. load is useful for debugging but unlikely to be of any use to most people. load/commit scripts will be overwritten each boot, you cannot modify these in-place like other files. There is also a boot script that will be executed after everything is restored. Another nice side effect of this method is that everything is nicely backed up with a normal dd-wrt backup unlike jffs.

For my use, I have /tmp/nvram_files/openvpn/ and it contains a configuration file and a secret key. I then have /tmp/nvram_files/boot launch openvpn as a daemon and I am good to go.

The installation/startup script could probably be more compact but I wanted to keep it relatively readable for auditing purposes.

This is intended for small files/scripts, there isn't much nvram space available. Hopefully this is useful to someone else.


Simple example:

1. (Paste script per below, reboot)
echo Hello > /tmp/nvram_files/world
/tmp/nvram_files/commit
2. reboot
cat /tmp/nvram_files/world

PS: While writing this, I found phuzi0n's post for compressing firewall rules ([1]). This is very similar to his work but intended for generic files.


Paste this into Administration->Commands->Save Startup and reboot. Login and you can start tweaking /tmp/nvram_files/, make sure you don't forget to commit Smile

Code:

 
#nvram files
p="/tmp/nvram_files"
minfree=1000

mkdir $p
cd /tmp/

echo "
   tar cvf - $p  | gzip -9 | (echo -n nvram set nvram_files=\"'\"; uuencode -m -; echo \"'\") | sh - || exit 1
   nvram show > /dev/null
   if nvram show 2>&1 > /dev/null | awk '{print \$0; f=int(substr(\$4,2)); if (f > $minfree) print \"OK\" }' | grep OK; then
      nvram commit && echo "commit success"
   else
      echo "commit failure - minfree $minfree met?"
   fi
" > commit

echo "nvram get nvram_files | uudecode -o - | (cd /; tar zxv)" > load
chmod +x commit load
./load
mv commit load $p

cd $p
touch -a ./boot
chmod +x ./boot
./boot

Email Bandwidth Usage Daily