Dd Wrt Ip Routing

2013-05-13

I have a Linksys router and, naturally, I've got custom firmware on it.

I went for the DD-WRT ( @@ http://www.dd-wrt.com ddwrt link @@ ) quite some time ago and I've gotten used to it. One of the best features is the ability to manage everything via SSH.

However, the biggest hurdle with doing that is getting to grips with the limitations of it's shell (which is ash -- *not* bash). Things that you would take for granted in bash, such as arrays, are not necessarily present in ash.

Function declaration is much stricter as well -- requiring the () to be immediately after the function name with no spacing. You also can't use the (albeit unnecessary) "function" declaration either.

Anyway -- I had a need to route multiple external IP addresses to an internal machine and rather than doing the iptables commands every time, I thought I would write a script to do it for me.

Edit: updated script to accept user input

~~~~
#!/bin/sh

## Usage: __port_route__ [IPADDRESS] [EXTERNAL_PORT->INTERNAL_PORT : EXTERNAL_PORT->INTERNAL_PORT] ##
__port_route__() {
        ipaddress="${1}"
        ports="${2}"
        oldIFS=${IFS}
        IFS=" : "
        for route in ${ports}; do
                IFS="->"
                local i=0
                for port in ${route}; do
                        if [ ${i} == 0 ]; then
                                local extport=${port}
                        else
                                local intport=${port}
                        fi
                local i=1
                done
                iptables -t nat -I PREROUTING -p tcp --dport ${extport} -j DNAT --to ${ipaddress}:${intport}
                iptables -I FORWARD -p tcp -d ${ipaddress} --dport ${extport} -j ACCEPT
                echo "External port ${extport} routed to ${ipaddress}:${intport}"
        done
        IFS=${oldIFS}
}

## Fair warning -- port routing *MUST* be enclosed in quotes, preferably single quotes. otherwise you'll end up creating files. ##
__port_route__ ${1} ${2}
~~~~

Usage:
~~~~
portroute 255.255.255.255 '80->80 : 22->22 : 143->143'
~~~~

I had to go round the houses to get the, potentially, different external and internal ports in as different variables so I could use them all in one go -- however, I think considering the restrictions that the result is fairly clean.

Also, the ports and IP address mentioned in the script are not the ones I *had* used (they are all blocked again now anyway).

As usual, I'm not responsible for what you do with this script or if it breaks anything.