eibgrad

tomato-wol-port-forward.sh

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