eibgrad

ddwrt-wol-port-forward.sh

Jan 10th, 2022
192
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/bin/sh
  2. unset DEBUG
  3. DEBUG= # uncomment/comment to enable/disable debug mode
  4.  
  5. #          name: ddwrt-wol-port-forward.sh
  6. #       version: 1.2.0, 07-jan-2022, by eibgrad
  7. #       purpose: port forward w/ wol activation
  8. #   script type: wanup (autostart) + startup (autostart)
  9. #  installation:
  10. #    1. enable jffs2 (administration->jffs2)
  11. #    2. enable syslogd (services->services->system log)
  12. #    3. use shell (telnet/ssh) to execute one of the following commands:
  13. #         curl -kLs bit.ly/ddwrt-installer|tr -d '\r'|sh -s -- --dir /tmp NUb73JqK
  14. #       or
  15. #         wget -qO - bit.ly/ddwrt-installer|tr -d '\r'|sh -s -- --dir /tmp NUb73JqK
  16. #    4. use vi editor to modify installer options:
  17. #         vi /tmp/ddwrt-wol-port-forward.sh
  18. #    5. execute installer:
  19. #         /tmp/ddwrt-wol-port-forward.sh
  20. #    6. reboot
  21.  
  22. SCRIPTS_DIR='/jffs/etc/config'; mkdir -p $SCRIPTS_DIR
  23.  
  24. SCRIPT1="$SCRIPTS_DIR/ddwrt-wol-pf.wanup"
  25. SCRIPT2="$SCRIPTS_DIR/ddwrt-wol-pf.startup"
  26.  
  27. # ------------------------- begin ddwrt-wol-pf.wanup ------------------------- #
  28. cat << 'EOF' > $SCRIPT1
  29. #!/bin/sh
  30. set -x # uncomment/comment to enable/disable debug mode
  31. {
  32. #!/bin/sh
  33.  
  34. # ------------------------------ BEGIN OPTIONS ------------------------------- #
  35.  
  36. # protocol (tcp|udp) of port forward
  37. PROTO='tcp'
  38.  
  39. # source ip(s)/network(s) of port forward (comma-separated)
  40. SOURCE='0.0.0.0/0'
  41.  
  42. # external port of port forward
  43. EXT_PORT='5900'
  44.  
  45. # internal ip of port forward
  46. INT_IP='192.168.1.100'
  47.  
  48. # internal port of port forward
  49. INT_PORT='5900'
  50.  
  51. # ------------------------------- END OPTIONS -------------------------------- #
  52.  
  53. # ---------------------- DO NOT CHANGE BELOW THIS LINE ----------------------- #
  54.  
  55. # create port forward
  56. iptables -t nat -I PREROUTING -p $PROTO -s $SOURCE -d $(nvram get wan_ipaddr) \
  57.     --dport $EXT_PORT -j DNAT --to $INT_IP:$INT_PORT
  58. iptables -I FORWARD -p $PROTO -s $SOURCE -d $INT_IP --dport $INT_PORT -j ACCEPT
  59.  
  60. # record access of port forward to log
  61. iptables -I FORWARD -p $PROTO -s $SOURCE -d $INT_IP --dport $INT_PORT \
  62.     -m state --state NEW -j LOG --log-prefix "WOL Port Forward "
  63.  
  64. } 2>&1 | logger -t $(basename $0)[$$]
  65. EOF
  66. [ ${DEBUG+x} ] || sed -ri 's/^(set -x)/#\1/g' $SCRIPT1
  67. chmod +x $SCRIPT1
  68. echo "installed: $SCRIPT1"
  69. # -------------------------- end ddwrt-wol-pf.wanup -------------------------- #
  70.  
  71. # ------------------------ begin ddwrt-wol-pf.startup ------------------------ #
  72. cat << 'EOF' > $SCRIPT2
  73. #!/bin/sh
  74. set -x # uncomment/comment to enable/disable debug mode
  75. (
  76. # ------------------------------ BEGIN OPTIONS ------------------------------- #
  77.  
  78. # mac address of internal ip (unspecified = static lease search)
  79. MAC_ADDR='' # hexidecimal format: XX:XX:XX:XX:XX:XX
  80.  
  81. # broadcast interface of internal ip
  82. BCAST_IF='br0'
  83.  
  84. # how often (in secs) to check for new kernel messages
  85. INTERVAL=10
  86.  
  87. # ------------------------------- END OPTIONS -------------------------------- #
  88.  
  89. # ---------------------- DO NOT CHANGE BELOW THIS LINE ----------------------- #
  90.  
  91. get_val() { sed -rn "s/^$1=(.*)/\1/p" $SCRIPT1 | tr -d \'\"; }
  92.  
  93. get_mac() {
  94.   sed -rn \
  95.     "s/^dhcp-host=.*(([[:xdigit:]]{2}:){5}[[:xdigit:]]{2}).*,$1(,.*|$)/\1/p" \
  96.       /tmp/dnsmasq.conf | head -n1
  97. }
  98.  
  99. # internal ip of port forward
  100. INT_IP=$(get_val 'INT_IP')
  101.  
  102. # protocol (tcp|udp) of port forward
  103. PROTO=$(get_val 'PROTO' | awk '{print toupper($0)}')
  104.  
  105. # internal port of port forward
  106. INT_PORT=$(get_val 'INT_PORT')
  107.  
  108. # broadcast ip of internal ip's network interface
  109. BCAST_IP="$(ifconfig $BCAST_IF | awk '/Bcast/{split ($3,A,":"); print A[2]}')"
  110.  
  111. # mask used for finding wol messages
  112. WOL_MSG_MASK="^WOL Port Forward .* DST=$INT_IP .* PROTO=$PROTO .* DPT=$INT_PORT "
  113.  
  114. # work files
  115. CURR_MSG="/tmp/tmp.$$.curr_msg"
  116. PREV_MSG="/tmp/tmp.$$.prev_msg"; > $PREV_MSG
  117.  
  118. # wait for *reliable* internet connection
  119. until ping -qc1 -W3 8.8.8.8 &>/dev/null; do sleep 10; done
  120.  
  121. # validate mac address
  122. if [ ! "$MAC_ADDR" ]; then
  123.     MAC_ADDR=$(get_mac $INT_IP)
  124.     if [ ! "$MAC_ADDR" ]; then
  125.         echo "fatal error: mac address not found: $INT_IP"
  126.         exit 1
  127.     fi
  128. else
  129.     if ! echo "$MAC_ADDR" | \
  130.             grep -qE '^([[:xdigit:]]{2}:){5}[[:xdigit:]]{2}$'; then
  131.         echo "fatal error: invalid/malformed mac address: $MAC_ADDR"
  132.         exit 1
  133.     fi
  134. fi
  135.  
  136. while sleep $INTERVAL; do
  137.     # extract all wol messages
  138.     dmesg | grep "$WOL_MSG_MASK" > $CURR_MSG
  139.  
  140.     # if there are any new wol messages, then wol as necessary
  141.     if [ -s $CURR_MSG ] && ! ping -qc1 -W3 $INT_IP &>/dev/null; then
  142.         if [ ! -s $PREV_MSG ] || \
  143.                 grep -m1 -Fxvf $PREV_MSG $CURR_MSG >/dev/null; then
  144.  
  145.             # try up to three (3) times to wake the device
  146.             for i in 1 2 3; do
  147.                 echo "info: waking up $MAC_ADDR (attempt #${i}) ..."
  148.                 /usr/sbin/wol -i $BCAST_IP $MAC_ADDR >/dev/null && sleep 20 || break
  149.                 if ping -qc1 -W3 $INT_IP &>/dev/null; then
  150.                     echo "info: $MAC_ADDR is alive!"
  151.                     break
  152.                 fi
  153.                 [ $i -eq 3 ] && echo "warning: $MAC_ADDR did NOT respond :("
  154.             done
  155.         fi
  156.     fi
  157.  
  158.     # remember which wol messages have already been processed
  159.     mv $CURR_MSG $PREV_MSG
  160. done
  161. ) 2>&1 | logger -t $(basename $0)[$$] &
  162. EOF
  163. [ ${DEBUG+x} ] || sed -ri 's/^(set -x)/#\1/g' $SCRIPT2
  164. sed -i "s:\$SCRIPT1:$SCRIPT1:g" $SCRIPT2
  165. chmod +x $SCRIPT2
  166. echo "installed: $SCRIPT2"
  167. # ------------------------- end ddwrt-wol-pf.startup ------------------------- #
RAW Paste Data Copied