#!/bin/bash

# manual-ampr-start.sh

# 08/03/20
# dranch at trinnet dot net


# This script is intended to be a simple AMPR startup script to enable IPIP tunneling
# and the RIP44 service to learn of other AMPR IPIP stations out on the Internet
# 
#  NOTE:  Your AMPR IP address must have:
#         1. The "tunnel" attribute in ithe home --> Allocations --> networks --> allocated IP
#         2. Gateways --> Manage --> allocated IP --> gateway hostname entry
#         
#         Change the IP addresses below to reflect your setup

# Changes:
# 08/13/20 - Added other known good hosts
# 08/03/20 - Added comments on eventually moving over to newer "ip" commands
# 01/25/20 - minor syntax and cosmetic fixes
# 07/20/19 - Updated to only allow new reduced AMPR address range
# 02/25/19 - Added a whois test at the end of the scripr execution
# 02/19/19 - Added a section0 on discussing what is AMPR, how to test proto4 makes it to your
#            destination IP address; mention that this script requires the net-tools package; 
#            added a URL for example iptables rules; added a sleep for ampr-ripd cleanup
#            added a ping check for 44.0.0.1; noted a URL for NAT breaking AMPR proto4
# 09/21/18 - Added a comment about the -x option to run a system command when a route change occurs
# 09/08/18 - updated to new static IP; Added some alternative use cases as comments; formatting cleanups
# 04/22/18 - Noted cached ampr-ripd loads a saved encap.txt file upon start
# 06/06/17 - switch to the new AMPR DGW IP; improved comments on test IPs
# 06/05/17 - New ampr-ripd 2.3, removed RIP password from command line (it's default and it's an
#            information leak
# 05/31/17 - Added new ampr-ripd 2.2 with location beacons
# 05/29/17 - More comments, cleanups, troubleshooting and new version of ampr-ripd (2.1.1)
# 05/26/17 - changed AMPRGW to new UCSD IP
# 03/23/17 - if tunl0 already exists, exit
# 02/17/16 - dranch - some cleanup
# 12/17/16 - dranch - original version
# 12/17/16 - Added ampr-ripd support
# 12/13/16 - original version


# -----------------------------------------------------------------------------
# Helpful URLs
# -----------------------------------------------------------------------------
#  Recommended: Dynamic route Ampr-ripd daemon to learn RIP44 routes from the RIP 
#               routing packets coming from UCSD
#     http://www.yo2loj.ro/hamprojects/ and select the newest ampr-ripd daemon
#
#  NOT recommended: Static route script to import AMPR Encaps script into Linux 
#                   net-44 table:
#     Option 1: This script works fine: http://www.qsl.net/kb9mwr/wapr/tcpip/iproute2_ampr_munge
#     Option 2: This script requires other Perl CPAN modules: http://www.qsl.net/kb9mwr/wapr/tcpip/amprroutes.pl.txt
#
#  Good resource page - http://www.qsl.net/kb9mwr/wapr/tcpip/
#
#  ampr-ripd map: http://yo2tm.ampr.org/ampr-map/


# -----------------------------------------------------------------------------
# Script Variables
# -----------------------------------------------------------------------------
#What is your Internet external IP address - should be a STATIC IP
#  if not, this variable must be changed every time your IP changes and the script rerun
EXTIP="98.78.144.186"

#What is your allocated AMPR IP or AMPR gateway IP address and netmask
AMPRIP="44.4.10.41"
# This is a /29
AMPRMASK="255.255.255.248"
#  Alternative syntax when using the "ip" command
CIDRNM="29"

#UCSD AMPR gateway
#  This IP must be enabled in any firewall filters
#  new gateway of 169.228.34.84 was activated on 06/06/2017
#  Old gateway of 169.228.66.251 was deprecated on 6/6/17
AMPRGW="169.228.34.84"

#ampr-ripd daemon - must be build and installed per URL above
AMPRRIPD="/usr/src/archive/ampr-ripd/ampr-ripd-current/ampr-ripd"

#Your call and maiden grid locator
AMPRIDENT="ki6zhd@cm97ai"


# -----------------------------------------------------------------------------
# Requirements
# -----------------------------------------------------------------------------
#  This script requires the following packages or programs
#
#   1. net-tools from the distro repo for programs like ifconfig, etc
#   2. ampr-ripd from http://www.yo2loj.ro/hamprojects/ to install RIP heard routes 


# -----------------------------------------------------------------------------
# Script body
# -----------------------------------------------------------------------------
#   Some manual lines are commented below as part of an initial troubleshooting
#   process.  You can try running them youself or if you want a clean script,
#   just delete those lines
# -----------------------------------------------------------------------------

#Step0
#-----
#  - What is AMPR and how do you get an IP subnetc, etc.  Please read this section#
#
#    http://www.trinityos.com/HAM/CentosDigitalModes/hampacketizing-centos.html#5a.ampraddr
#
#    It's important to know that many ISPs *block* the protocol 4 (akal IPIP) traffic 
#    going through their network.  The above URL gives hints to how to do some testing
#    before trying to setup a AMPR connection to only find out your ISP filters it out.
#    See the bottom of this script for the Troubleshooting section that also talks about 
#    problematic router/nat devices.


#Step1
#-----
# - make sure to allow IPIP traffic in your firewall rules 
#   This script uses IPTABLES today which is compatible with Rasbian Buster but Buster
#   has now moved to nftables.  This script will be enhanced to natively support nftables 
#   in the future
#   
#   IPTABLES support: /etc/iptables/rules.v4
#   Email KI6ZHD for a copy of his rules.v4 file for a more complete example and you can 
#   see an example setup here:  
#   http://www.trinityos.com/HAM/CentosDigitalModes/RPi/rpi2-setup.html#3b.initial-security-iptables

#   #Allow AMPR IPIP traffic via iptables
#   -A INPUT -p 4 -j ACCEPT
#   iptables -A INPUT -p udp --dport 520 -j ACCEPT
#   iptables -A INPUT -i ampr0 -j DROP

#Alternatively, use table support in IPTABLES to put all AMPR routes into it's 
#  own unique table
#
#   ftp://n1uro.ampr.org/pub/hamradio/packet/dotun.sh


#Step2
#-----
# - Random noise.. ignore this step for now
#
#   Ignore these top comments and skip down to the uncommented items
#     comments to be cleaned up later

#ip tunnel add ampr0 mode ipip ttl 64 local $EXTIP

#optional changes for your interface (integrated elsewhere in this script)
#ifconfig ampr0 $AMPRIP netmask 255.255.255.255



#Step3
#-----
# Allow ip forwarding from amprnet to your ethernet interface if your AMPR system
#   is going to be a router vs. just a host on the AMPR network
#
#   I leave this OFF by default
#
#        echo "1" > /proc/sys/net/ipv4/ip_forward


#Step4
#-----
# - Bring up the IPIP tunnel support
#
#  08/03/20 - I need to transition this script to use "ip" instead of legacy commands:
#
#    ip addr add $AMPRIP/$AMPRMASK dev tunl0
#    ip link set dev tunl0 up
#    # Allow traceroute support
#    ip tunnel change tunl0 mode ipip ttl 64 pmtudisc
#    ifconfig tunl0 mtu 1480
#    ip route add default via 169.228.34.84 dev tunl0 src $AMPRIP onlink table 44
#    ip rule add from 44.0.0.0/9 pref 1 table 44
#    ip rule add from 44.128.0.0/10 pref 1 table 44
#    ip rule add to 44.0.0.0/9 pref 1 table 44
#    ip rule add to 44.128.0.0/10 pref 1 table 44


#Test to see if an AMPR tunnel is already configured
if [ -z "`ifconfig | grep -v grep | grep tunl0`" ]; then
   # Configure your ipencap tunnel interface - required for the amprnet
   echo -e "\nCreating tunl0 interface"
   ifconfig tunl0 $AMPRIP netmask $AMPRMASK up
  else
   echo -e "\ntunl0 interface already exists.  Aborting"
   exit 1
fi

# You can also do this via the newer "ip" command
#   ip addr add $AMPRIP/$CIDRNM dev tunl0
#   ip link set dev tunl0 up


#step5
#-----
# Allow traceroutes to work on the amprnet

echo "allowing TTL of 64 for traceroute support and Path-MTU discovery"
ip tunnel change tunl0 mode ipip ttl 64 pmtudisc

#  You can also force the MTU if you wish subtracting away the IPIP header overhead
#  ifconfig tunl0 mtu 1480


#step6
#------
# Optionally give the 44net IP on tunl0 or any assigned forwarded interface for 
# traceroute replies
# generally not needed
#echo 1 > /proc/sys/net/ipv4/icmp_errors_use_inbound_ifaddr


#step7
#-----
# If you run a xNOS system (JNOS, etc), also configure a "tun" interface:
#   Notice this is new interface called "tun" and not "tunl"
#
# ifconfig tun0 $AMPRIP pointopoint $NOSIP up


#step8
#-----
# Configure routing accordingly:
# NOTE: if this node is behind an existing gw on your lan, change the "via" IP 
#       address below in the default line to reflect the lan IP of your gateway 
#       and add a route in table 1 on your gateway to this node.
#          ip route add $NOSIP dev tun0 table 1 src $AMPRIP
#
echo "adding default AMPR route to $AMPRGW"
ip route add default via $AMPRGW dev tunl0 src $AMPRIP onlink table 44



#view routes in table
echo -e "\nCurrent number of routes in AMPR44 route table: `ip route show table 44 | wc --lines`"
echo -e "-----------------------------------------------------------------------"
ip route list table 44
echo -e "-----------------------------------------------------------------------"


#step9
#-----
# configure policy routing so that frames from/to your 44-net IP
# know how to route ON/OUT accordingly:
echo "Enable Policy routing for traffic from 44 goes back to 44"
ip rule add from 44.0.0.0/9 pref 1 table 44
ip rule add from 44.128.0.0/10 pref 1 table 44
ip rule add to 44.0.0.0/9 pref 1 table 44
ip rule add to 44.128.0.0/10 pref 1 table 44

# I've also seen examples where people are setting route priorities.  Not sure the 
#  benefit here
#
#   ip rule add from $AMPRIP/$CIDRNM table 44 priority 45
#   ip rule add to 44.0.0.0/8 table 44 priority 44 

#Also seen some people explicitly set a route for their own IP and forward traffic
#  to their own IP to then gateway out.  Seems like an unnessisary doublehop
#
#   ip route add 44.4.28.50/32 dev tunl0 table 44
#   ip route add 44.0.0.0/8 via $AMPRIP dev tunl0 



#step10
#-----
#Manual tests to known working and reliable AMPR destinations as of 06/06/17
#  NOTE:  AMPR partisipation and their reflected IPs can change from time to time 
#         so the used GW IPs listed here might become stale.  Refer to the encaps.txt 
#         file for the newest IPs
#
echo -en "Adding specific static AMPR routes to:"
# 01/25/20: remote IP changed for n1uro
echo -en "[n1uro] "
ip route replace 44.88.0.0/27 via 24.34.225.54 dev tunl0 proto static onlink table 44
echo -en "[n6mef] "
ip route replace 44.4.2.152/29 via 173.167.109.217 dev tunl0 proto static onlink table 44
echo -en "[lu9dce] "
ip route replace 44.153.32.97/32 via 181.16.42.162 dev tunl0 proto static onlink table 44

#Test network - usually down
#echo -en "[ki6zhd-2] "
#ip route replace 44.4.10.48/32 via 24.4.6.65 dev tunl0 proto static onlink table 44

#view routes in table
echo -e "\nCurrent number of routes in AMPR44 route table: `ip route show table 44 | wc --lines`"
echo -e "-----------------------------------------------------------------------"
ip route list table 44
echo -e "-----------------------------------------------------------------------"


#step11
#-----
echo -e "\n\nPing tests for specific AMPR hosts: (known previously working hosts)"
echo -e "\nAMPR GW:"
echo -e "-------------------------------"
ping -c 5 -w 5 44.0.0.1
echo -e "\nn1uro:"
echo -e "-------------------------------"
ping -c 5 -w 5 44.88.0.9
echo -e "\nn6mef"
echo -e "-------------------------------"
ping -c 5 -w 5 44.4.2.153
echo -e "\nVE4KLM - Jnos"
echo -e "-------------------------------"
ping -c 5 -w 5 ve4klm.ampr.org


#step12
#------
echo -e "\nChecking AMPR whois for our allocation"
whois -h whois.ampr.org $AMPRIP


#step13
#-----
# Assuming you had your AMPR coordinator set a DNS entry for your external public
# Internet IP address (not your AMPR 44.x.y.z address), you'll be now receiving periodic
# RIP route updates.  To process these routes, start up the dynamic ampr-ripd service 
# instead of using static routes by downloading the newest ampr-ripd from 
# http://www.yo2loj.ro/hamprojects/
#
#  Upon start, ampr-ripd will load previously saved routes from:
#     /var/lib/ampr-ripd/encap.txt
#
#  below is following setting recommendations from ftp://ftp.n1uro.com/pub/hamradio/packet/dotun.sh
#
# -t 1 : routing table
# -a $COMMIP : your external IP
# -i tunl0 : IPIP interface to hear the RIPv2 packets
# -v : verbose output to view on the console;
# -d : debug mode - no daemonization
# -s : save learned routes to /var/lib/ampr-ripd/encap.txt
# -r : compatibility mode
# -L : callsign and postion reported to http://yo2tm.ampr.org/ampr-map/
# -x : Execute following system command after route set/change
# removed option
# -p pLaInTeXtpAsSwD : password to decode the RIP packets (this is the default passwd used)

echo -e "\nEnabling ampr-ripd for route learning [daemon mode] and loading cached 44.x.x.x routes"
if [ -z "`ps aux |grep -v grep | grep ampr-ripd`" ]; then
   $AMPRRIPD -t 44 -a $EXTIP -i tunl0 -v -r -s -L $AMPRIDENT
  else
   echo -e "\nampr-ripd already running; killing and restarting"
   killall ampr-ripd
   sleep 1
   if [ -z "`ps aux |grep -v grep | grep ampr-ripd`" ]; then
      echo -e "It wont die.. error!"
      exit 1
   fi
   $AMPRRIPD -t 44 -a $EXTIP -i tunl0 -v -r -s -L $AMPRIDENT
fi


#step14
#-----
#ALTERNATIVE #2 - Preload route table from older encaps file
#
#  Disabled - use ampr-ripd
#
#        #For manual route updates:
#           #1. On other computer (hampacket2) that has the most recent encaps file
#           /usr/src/archive/Ampr/Scripts/iproute2_ampr_munge.sh add < encap_20161213010101.txt
#
#           #Copy resulting script over to desired AMPR IPIP host and run
#           /usr/local/sbin/ampr_add-121316.sh
#
#        # show the loaded routes
#        ip route show table 44


#Troubleshooting notes
#-----
#
#  A. Bi-directional traffic issues:
#     If you have problems with remote AMPR systems being able to ping you, you might be
#     suffering from a NAT issue with your home "router".  This situation shows up when YOU 
#     initiate a AMPR ping (packets that will get IPIP / Proto 4 encapsulated to some known 
#     destination say ki6zhd.ampr.org and it works fine.  Then that remote destination 
#     (ki6zhd.ampr.org) can then also ping your station.  Then wait say 20 minutes and have
#     that remote destination try pinging you again and it doesn't work anymore.  What's 
#     happenen is your upstream router/nat gateway has closed down it's NAT translation for
#     protocol 4.  This URL describes the situation as well:
#
#         https://uronode.n1uro.com/linux/amprcable.html
#
#     There is generally only two things you can do here:
#
#       1. Reconfigure your upstream router/nat device enable it's DMZ mode.  This is
#          where the router will send all unrecognized traffic to a specific internal 
#          port.  BE SURE YOU'VE ENABLED FIREWALLING on all internal devices as you're
#          dramatically increasing your Internet exposure 
#
#       2. Put your home router/nat device into bridge mode.  This mode disables most
#          of the functionality from your router and it then just relays traffic.  This
#          is good for AMPR traffic but it can also disable the device's Wifi, DHCP server,
#          NAS and DLNA features, etc.  BE SURE YOU'VE ENABLED FIREWALLING on the internal 
#          devices as you're dramatically increasing your Internet exposure
#
#
#  B.  useful command line for debugging AMPR IPIP traffic
#
#      #monitor tunl0 traffic
#         tcpdump -ni tunl0 not port 22 and not arp | grep --line-buffered "IP 44"
#
#      Leave this running for like 20min and if you had your AMPR coordinator set a DNS
#      entry for your AMPR IP, you should see incoming routes like the following
#      --
#      10:55:03.631963 IP 44.0.0.1.520 > 224.0.0.9.520: RIPv2, Response, length: 504
#      10:55:03.691904 IP 44.0.0.1.520 > 224.0.0.9.520: RIPv2, Response, length: 504
#      10:55:03.738171 IP 44.0.0.1.520 > 224.0.0.9.520: RIPv2, Response, length: 504
#      10:55:03.799765 IP 44.0.0.1.520 > 224.0.0.9.520: RIPv2, Response, length: 504
#      --
#
#  C.  View ampr-ripd learned routes
#
#         grep -c addprivate /var/lib/ampr-ripd/encap.txt
#
#
#  D. Confirm the ampr-ripd daemon is saving new encaps.txt static route files
#      ls -la /var/lib/ampr-ripd
#

echo -e "\nDone\n"
