Your here: .../.../DD-WRT Tutorials/Useful Scripts/Miscellaneous Scripts
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 (log.sh)
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:
- Log on to your WRT
- type
cd /jffs
- type
vi sec.sh
(or any other name) and enter the script - Connect to your WRT via web browser, page Administration:Commands
- Enter the script name (sec.sh) into the command field
- Click on "Save Startup"
- 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
This script solves an intermittent 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.
#!/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.
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:
- (Paste script per below, reboot)
echo Hello > /tmp/nvram_files/world
/tmp/nvram_files/commit
- 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