[hamradio-commits] [ampr-ripd] 01/05: New upstream version 2.3

Ana Custura ana.c-guest at moszumanska.debian.org
Thu Aug 31 22:41:05 UTC 2017


This is an automated email from the git hooks/post-receive script.

ana.c-guest pushed a commit to branch master
in repository ampr-ripd.

commit 9bf621b45ad4d57af58bc2003d26b1056582a2a0
Author: Ana C. Custura <ana at netstat.org.uk>
Date:   Thu Aug 31 23:12:06 2017 +0100

    New upstream version 2.3
---
 Makefile                              |   6 +-
 ampr-ripd.1                           |  30 +-
 ampr-ripd.c                           | 737 +++++++++++++++++++++++++++-------
 ampr-run.sh => examples/ampr-run.sh   |   4 +-
 find_pass.sh => examples/find_pass.sh |   2 +-
 examples/interfaces                   |  25 ++
 manual.txt                            |  52 ++-
 7 files changed, 688 insertions(+), 168 deletions(-)

diff --git a/Makefile b/Makefile
index e461218..bb4dbc8 100644
--- a/Makefile
+++ b/Makefile
@@ -4,7 +4,7 @@
 
 BASEDIR = /usr
 SBINDIR = $(BASEDIR)/sbin
-MANDIR = $(BASEDIR)/man/man1
+MANDIR = $(BASEDIR)/share/man/man1
 SCACHEDIR = /var/lib/ampr-ripd
 
 # no need to run ampr-ripd as root
@@ -18,10 +18,10 @@ CC = gcc
 #
 
 # Full debug including Netlink
-#DOPT = -Wall -O2 -D HAVE_DEBUG -D NL_DEBUG
+#DOPT = -D HAVE_DEBUG -D NL_DEBUG
 
 # Full debug
-#DOPT = -Wall -O2 -D HAVE_DEBUG
+#DOPT = -D HAVE_DEBUG
 
 COPT = -Wall -O2
 LOPT =
diff --git a/ampr-ripd.1 b/ampr-ripd.1
index d702c23..5451d65 100644
--- a/ampr-ripd.1
+++ b/ampr-ripd.1
@@ -1,9 +1,9 @@
-.TH ampr-ripd "1" "September 2016" "ampr-ripd" "General Manual Commands"
+.TH ampr-ripd "1" "April 2017" "ampr-ripd" "General Manual Commands"
 .SH NAME
-ampr-ripd \- routing daemon for AMPRNet gateways
+ampr-ripd \- routing daemon for AMPRNet gateways v2.3
 .SH SYNOPSIS
 .B ampr-ripd
-[\-?|\-h] [\-d] [\-v] [\-s] [\-r] [\-i <interface>] [\-a <ip|hostname|subnet>[,<ip|hostname|subnet>...]] [\-p <password>] [\-f <interface>] [\-e <ip>] [\-x <system command>]
+[\-?|\-h] [\-d] [\-v] [\-s] [\-r] [\-i <interface>] [\-a <ip|hostname|subnet>[,<ip|hostname|subnet>...]] [\-p <password>] [\-m <metric>]  [\-w <window>] [\-f <interface>] [\-e <ip>] [\-F <interface>] [\-E <ip>] [\-x <system command>] [-g <gateway>]
 .br
 .SH DESCRIPTION
 AMPRnet is a RIPv4 Listener and route injector daemon used with AMPRnet gateways.
@@ -26,7 +26,7 @@ if this file exists, it will be loaded on startup regardless
 of this option
 .TP
 \fB\-r\fR
-Compatibility only (ignored, raw sockets are always used)
+Use a raw listening socket for systems with broken multicast support
 .TP
 \fB\-i\fR <interface>
 Tunnel interface to use, defaults to tunl0
@@ -57,13 +57,29 @@ RIPv2 password, defaults to the current valid password. Use only if the password
 Interface for RIP forwarding, defaults to none/disabled
 .TP
 \fB\-e\fR <ip>
-Forward destination IP, defaults to 224.0.0.9 if enabled
+RIP forward destination IP, defaults to 224.0.0.9 if enabled
+.TP
+\fB\-F\fR <interface>
+Interface for AMPR RIP forwarding, defaults to none/disabled
+.TP
+\fB\-E\fR <ip>
+AMPR RIP forward destination IP, defaults to 224.0.0.9 if enabled
 .TP
 \fB\-x\fR <system command>
 Execute this system command after route set/change. If the command includes white spaces, use quotes.
 .TP
+\fB\-g\fR <gateway>
+Gateway for direct 44net connections. Accepts an gateway IP or an interface name. If not set, it will be auto-detected.
+.TP
+\fB\-L\fR <callsign at locator>
+This parameter will enable the sending of a callsign at locator string (actually any string) to my home gateway (udp:44.182.21.1:59001).
+The string will be sent at starup, and then every 5 minutes. On termination, a "shutdown" string will be sent.
+On HUP, the string will be sent immediately and the cycle restarted.
+The purpose of this option is to allow the construction of a dynamic map of all ampr-ripd gateways for visual display.
+If the parameter is not set, no data will be sent.
+.TP
 .B Observation
-All routes are created with netlink protocol 44 for easy management
+All routes are created with netlink protocol 44 for easy management.
 .IP
 .SH SIGNALS
 .IP
@@ -82,3 +98,5 @@ Author: Marius Petrescu, YO2LOJ, <marius at yo2loj.ro>
 When using other table than 'main', interogating the routes via netlink does not work properly.
 This means that on any update, the route is deleted and then recreated, even if it is already set correctly.
 This should be no problem since this happen only at startup on encap loading and on route change.
+
+For BGP announced 44net endpoints, only a single subnet may be assigned to a given endpoint.
diff --git a/ampr-ripd.c b/ampr-ripd.c
index b9609f6..b8abec7 100644
--- a/ampr-ripd.c
+++ b/ampr-ripd.c
@@ -1,39 +1,55 @@
 /*
- * ampr-ripd.c - AMPR 44net RIPv2 Listner Version 1.15
+ * ampr-ripd.c - AMPR 44net RIPv2 Listner Version 2.3
  *
  * Author: Marius Petrescu, YO2LOJ, <marius at yo2loj.ro>
  *
- *
+ ****************************************
+ * To my son Marcel Petrescu (2005-2017)
+ ****************************************
  *
  * Compile with: gcc -O2 -o ampr-ripd ampr-ripd.c
  *
  *
- * Usage: ampr-ripd [-?|-h] [-d] [-v] [-s] [-r] [-i <interface>] [-t <table>] [-a <ip|hostname|subnet>[,<ip|hostname|subnet>...]] [-p <password>] [-m <metric>] [-w <window>] [-f <interface>] [-e <ip>] [-x <system command>]
+ * Usage: ampr-ripd [-?|-h] [-d] [-v] [-s] [-r] [-i <interface>] [-t <table>] [-a <ip|hostname|subnet>[,<ip|hostname|subnet>...]] [-p <password>]
+ *                       [-m <metric>] [-w <window>] [-f <interface>] [-e <ip>] [-F <interface>] [-E <ip>] [-x <system command>] [-g <gateway>]
+ *                       [ -L <callsign at locator>]
  *
  * Options:
- *          -?, -h                Usage info
- *          -d                    Debug mode: no daemonization, verbose output
- *          -v                    More verbose debug output
- *                                Using this option without debug leaves the console attached
- *          -s                    Save routes to /var/lib/ampr-ripd/encap.txt (encap format),
- *                                If this file exists, it will be loaded on startup regardless
- *                                of this option
- *          -r                    Compatibility only (ignored, raw sockets are always used)
- *          -i <interface>        Tunnel interface to use, defaults to 'tunl0'
- *          -t <table>            Routing table to use, defaults to 'main'
- *          -a  <ip>[,<ip>...]    Comma separated list of IPs/hostnames or encap style entries to be ignored
- *                                (max. 10 hostnames or IPs, unlimited encap entries)
- *                                The list contains local interface IPs by default
- *          -p <password>         RIPv2 password, defaults to the current valid password
- *          -m <metric>           Use given route metric to set routes, defaults to 0
- *          -w <window>           Sets TCP window size to the given value
- *                                A value of 0 skips window setting. Defaults to 840
- *          -f <interface>        Interface for RIP forwarding, defaults to none/disabled
- *          -e <ip>               Forward destination IP, defaults to 224.0.0.9 if enabled
- *          -x <system command>   Execute this system command after route set/change
+ *          -?, -h                 Usage info
+ *          -d                     Debug mode: no daemonization, verbose output
+ *          -v                     More verbose debug output
+ *                                 Using this option without debug leaves the console attached
+ *          -s                     Save routes to /var/lib/ampr-ripd/encap.txt (encap format),
+ *                                 If this file exists, it will be loaded on startup regardless
+ *                                 of this option
+ *          -r                     Enable raw interface instead of multicast socket
+ *          -i <interface>         Tunnel interface to use, defaults to 'tunl0'
+ *          -t <table>             Routing table to use, defaults to 'main'
+ *          -a  <ip>[,<ip>...]     Comma separated list of IPs/hostnames or encap style entries to be ignored
+ *                                 (max. 10 hostnames or IPs, unlimited encap entries)
+ *                                 The list contains local interface IPs by default
+ *          -p <password>          RIPv2 password, defaults to the current valid password
+ *          -m <metric>            Use given route metric to set routes, defaults to 0
+ *          -w <window>            Sets TCP window size to the given value
+ *                                 A value of 0 skips window setting. Defaults to 840
+ *          -f <interface>         Interface for RIP forwarding, defaults to none/disabled
+ *          -e <ip>                RIP forward destination IP, defaults to 224.0.0.9 if enabled
+ *          -F <interface>         Interface for raw AMPR-RIP forwarding, defaults to none/disabled
+ *          -E <ip>                AMPR-RIP Forward destination IP, defaults to 224.0.0.9 if enabled
+ *          -x <system command>    Execute this system command after route set/change
+ *          -g <gateway>           Gateway for direct 44net connections (gateway IP or interface name)
+ *                                 If not set, the default gateway will be autodetected
+ *          -L <callsign at locator>  Enable to sending of a callsign at locator string (actually any string) to
+ *                                 my home gateway (udp:44.182.21.1:59001).
+ *                                 The string will be sent at starup, and then every 5 minutes.
+ *                                 On termination, a "shutdown" string will be sent.
+ *                                 On HUP, the string will be sent immediately and the cycle restarted.
+ *                                 The purpose of this option is to allow the construction of a dynamic map of
+ *                                 all ampr-ripd gateways for visual display.
+ *                                 if the parameter is not set, no data will be sent.
  *
  *
- * Observation: All routes are created with protocol set to 44
+ * Observation: All routes are created with netlink protocol set to 44
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -52,33 +68,46 @@
  *
  * Version History
  * ---------------
- *    0.9    14.Apr.2013    Alpha release, based on Hessus's rip44d
- *    1.0     1.Aug.2013    First functional version, no tables, no tcp window setting
- *    1.1     1.Aug.2013    Fully functional version
- *    1.2     3.Aug.2013    Added option for using raw sockets instead of multicast
- *    1.3     7.Aug.2013    Minor bug fix, removed compiler warnings
- *    1.4     8.Aug.2013    Possible buffer overflow fixed
- *                          Reject metric 15 packets fixed
- *    1.5    10.Aug.2013    Corrected a stupid netmask calculation error introduced in v1.4
- *    1.6    10.Oct.2013    Changed multicast setup procedures to be interface specific (Tnx. Rob, PE1CHL)
- *    1.7     8.Feb.2014    Added support for dynamic hostnames and ampr subnets in the ignore list
- *    1.8    11.Feb.2014    Added option for route metric setting
- *    1.9    13.Feb.2014    Added window size setting option and console detaching on daemon startup
- *    1.10   14.Feb.2014    Small fixes on option and signal processing (Tnx. Demetre, SV1UY)
- *                          Use daemon() instead of fork()
- *                          Option -v without debug keeps the console attached
- *    1.11   17.Feb.2014    Changed netlink route handling to overwrite/delete only routes written by ampr-ripd
- *    1.12   16.Nov.2014    Added the execution of a system command after route setting/changing. This is done
- *                          on startup with encap file present and 30 seconds after RIP update if encap changes
- *                          (Tnx. Rob, PE1CHL for the idea)
- *    1.13   20.Nov.2014    Ignore subnets for which the gateway is inside their own subnet
- *                          Reconstruct forwarded RIP messages to be able to send them even on ampr-gw outages
- *                          Forwarded RIP messages do not use authentication anymore
- *                          Forwarded RIP messages are sent 30 seconds after a RIP update, otherwise every 29 seconds
- *    1.14   21.Sep.2016    Password is included in the daemon. Only need to set should it ever change
- *                          (OK from Brian Kantor - Tnx.)
- *                          Added man page courtesy of Ana C. Custura and the DebianHams
- *    1.15   21.Sep.2016    Removed multicast access mode, now only raw sockets are used
+ *    0.9     14.Apr.2013    Alpha release, based on Hessus's rip44d
+ *    1.0      1.Aug.2013    First functional version, no tables, no tcp window setting
+ *    1.1      1.Aug.2013    Fully functional version
+ *    1.2      3.Aug.2013    Added option for using raw sockets instead of multicast
+ *    1.3      7.Aug.2013    Minor bug fix, removed compiler warnings
+ *    1.4      8.Aug.2013    Possible buffer overflow fixed
+ *                           Reject metric 15 packets fixed
+ *    1.5     10.Aug.2013    Corrected a stupid netmask calculation error introduced in v1.4
+ *    1.6     10.Oct.2013    Changed multicast setup procedures to be interface specific (Tnx. Rob, PE1CHL)
+ *    1.7      8.Feb.2014    Added support for dynamic hostnames and ampr subnets in the ignore list
+ *    1.8     11.Feb.2014    Added option for route metric setting
+ *    1.9     13.Feb.2014    Added window size setting option and console detaching on daemon startup
+ *    1.10    14.Feb.2014    Small fixes on option and signal processing (Tnx. Demetre, SV1UY)
+ *                           Use daemon() instead of fork()
+ *                           Option -v without debug keeps the console attached
+ *    1.11    17.Feb.2014    Changed netlink route handling to overwrite/delete only routes written by ampr-ripd
+ *    1.12    16.Nov.2014    Added the execution of a system command after route setting/changing. This is done
+ *                           on startup with encap file present and 30 seconds after RIP update if encap changes
+ *                           (Tnx. Rob, PE1CHL for the idea)
+ *    1.13    20.Nov.2014    Ignore subnets for which the gateway is inside their own subnet
+ *                           Reconstruct forwarded RIP messages to be able to send them even on ampr-gw outages
+ *                           Forwarded RIP messages do not use authentication anymore
+ *                           Forwarded RIP messages are sent 30 seconds after a RIP update, otherwise every 29 seconds
+ *    1.14    21.Sep.2016    Password is included in the daemon. Only need to set should it ever change
+ *                           (OK from Brian Kantor - Tnx.)
+ *                           Added man page courtesy of Ana C. Custura and the DebianHams
+ *    1.15    21.Sep.2016    Removed multicast access mode, now only raw sockets are used
+ *    1.16     3.Apr.2017    Added support for BGP announced 44net endpoints
+ *    1.16.1   4.Apr.2017    Added SIGINT handler for CTRL-C in debug mode to clean routes on exit
+ *    1.16.2   5.Apr.2017    Reopen forward socket on RIP send fail
+ *    1.16.3  19.Apr.2017    Correction for hostroutes on big endian machines
+ *    2.0     20.May.2017    Brought -r option back to life
+ *                           Added -F and -E options for raw AMPR-RIP forwarding
+ *                           Added setting of 44.0.0.1/32 route according to RIP data
+ *    2.1     28.May.2017    Fixed a segfault if using the -F option
+ *                           Added the possibilty to use interface names for the -g option
+ *                           Interface used for raw RIP forward restarts on interface error
+ *    2.1.1   29.May.2017    Corrected a tunnel interface detection error
+ *    2.2     30.May.2017    Enable sending of call at locator to my server for dynamic map creation
+ *    2.3      4.Jun.2017    Force the use of tunnel address as source IP on call home
  */
 
 #include <stdlib.h>
@@ -105,7 +134,7 @@
 #include <time.h>
 #include <ctype.h>
 
-#define AMPR_RIPD_VERSION	"1.15"
+#define AMPR_RIPD_VERSION	"2.3"
 
 #define RTSIZE		1000	/* maximum number of route entries */
 #define EXPTIME		600	/* route expiration in seconds */
@@ -152,7 +181,8 @@ typedef enum
 {
     ROUTE_ADD,
     ROUTE_DEL,
-    ROUTE_GET
+    ROUTE_GET,
+    ROUTE_GETDEV
 } rt_actions;
 
 typedef struct __attribute__ ((__packed__))
@@ -196,12 +226,13 @@ typedef struct
 } rip_packet;
 
 
-static char *usage_string = "\nAMPR RIPv2 daemon " AMPR_RIPD_VERSION "by Marius, YO2LOJ\n\nUsage: ampr-ripd [-d] [-v] [-s] [-r] [-i <interface>]  [-t <table>] [-a <ip|hostname|subnet>[,<ip|hostname|subnet>...]] [-p <password>] [-m <metric>] [-w <window>] [-f <interface>] [-e <ip>] [-x <system command>]\n";
+static char *usage_string = "\nAMPR RIPv2 daemon " AMPR_RIPD_VERSION " by Marius, YO2LOJ\n\nUsage: ampr-ripd [-d] [-v] [-s] [-r] [-i <interface>]  [-t <table>] [-a <ip|hostname|subnet>[,<ip|hostname|subnet>...]] [-p <password>] [-m <metric>] [-w <window>] [-f <interface>] [-e <ip>] [-F <interface>] [-E <ip>] [-x <system command>] [-g <gateway>] [ -L <callsign at locator>]\n";
 
 
 int debug = FALSE;
 int verbose = FALSE;
 int save = FALSE;
+int raw = FALSE;
 char *tunif = "tunl0";
 unsigned int tunidx = 0;
 unsigned int tunaddr;
@@ -213,12 +244,35 @@ char *table = NULL;
 int nrtable;
 uint32_t rmetric = 0;
 uint32_t rwindow = 840;
+
+/* standard RIP */
 char *fwif = NULL;
 char *fwdest = "224.0.0.9";
+
+/* AMPR RIP */
+char *amprfwif = NULL;
+char *amprfwdest = "224.0.0.9";
+
+/* system command */
 char *syscmd = NULL;
 
+/* default gateway */
+char *defgw = NULL;
+uint32_t gateway = 0;
+unsigned int gwdev = 0;
+
+/* call home */
+char *homeaddr = "44.182.21.1";
+char *homeport = "59001";
+char *homedata = NULL;
+/* repetition in 30 sec steps - 10 means 5 min */
+#define HOME_REPETITION		10
+int hometimer;
+
+/* global variables */
 int tunsd;
 int fwsd;
+int amprfwsd;
 int seq;
 int updated = FALSE;
 int update_encap = FALSE;
@@ -227,8 +281,10 @@ int encap_ignore = FALSE;
 
 route_entry routes[RTSIZE];
 
+struct if_nameindex *ifnames;
 uint32_t myips[MYIPSIZE];
 
+
 char *ipv4_htoa(uint32_t ip)
 {
     static char buf[INET_ADDRSTRLEN];
@@ -523,29 +579,20 @@ void detect_myips(void)
     int i, j;
     uint32_t ipaddr;
 
-    struct if_nameindex *names;
-
     for (i=0; i<MYIPSIZE; i++) myips[i] = 0;
 
-    names = if_nameindex();
-
-    if (NULL == names)
-    {
-	return;
-    }
-
     i = 0;
-    while ((names[i].if_index != 0) && (names[i].if_name != NULL) && (i<MYIPSIZE))
+    while ((ifnames[i].if_index != 0) && (ifnames[i].if_name != NULL) && (i<MYIPSIZE))
     {
-	ipaddr = getip(names[i].if_name);
+	ipaddr = getip(ifnames[i].if_name);
 
 #ifdef HAVE_DEBUG
-	if (debug && verbose) fprintf(stderr, "Interface detected: %s, IP: %s\n", names[i].if_name, ipv4_ntoa(ipaddr));
+	if (debug && verbose) fprintf(stderr, "Interface detected: %s, IP: %s\n", ifnames[i].if_name, ipv4_ntoa(ipaddr));
 #endif
 
-	if (strcmp(names[i].if_name, tunif) == 0)
+	if (strcmp(ifnames[i].if_name, tunif) == 0)
 	{
-	    tunidx = names[i].if_index;
+	    tunidx = ifnames[i].if_index;
 #ifdef HAVE_DEBUG
 	    if (debug && verbose) fprintf(stderr, "Assigned tunnel interface index: %u\n", tunidx);
 #endif
@@ -561,8 +608,6 @@ void detect_myips(void)
 	i++;
     }
 
-    if_freenameindex(names);
-
 #ifdef HAVE_DEBUG
     if (debug && verbose)
     {
@@ -1034,28 +1079,29 @@ uint32_t route_func(rt_actions action, uint32_t address, uint32_t netmask, uint3
 
     if (NULL == table)
     {
-        req.rtm.rtm_table = RT_TABLE_MAIN;
+	req.rtm.rtm_table = RT_TABLE_MAIN;
     }
     else
     {
-        req.rtm.rtm_table = nrtable;
+	req.rtm.rtm_table = nrtable;
     }
 
     if (ROUTE_DEL == action)
     {
-        req.rtm.rtm_scope = RT_SCOPE_NOWHERE;
-        req.rtm.rtm_type = RTN_UNICAST;
-        req.hdr.nlmsg_type = RTM_DELROUTE;
-        req.hdr.nlmsg_flags |= NLM_F_CREATE;
-        result = address;
+	req.rtm.rtm_scope = RT_SCOPE_NOWHERE;
+	req.rtm.rtm_type = RTN_UNICAST;
+	req.hdr.nlmsg_type = RTM_DELROUTE;
+	req.hdr.nlmsg_flags |= NLM_F_CREATE;
+	result = address;
     }
     else if (ROUTE_ADD == action)
     {
-	req.rtm.rtm_flags |= RTNH_F_ONLINK;
+	req.rtm.rtm_scope = RT_SCOPE_UNIVERSE;
 	req.rtm.rtm_type = RTN_UNICAST;
 	req.hdr.nlmsg_type = RTM_NEWROUTE;
 	req.hdr.nlmsg_flags |= NLM_F_CREATE;
-	result = nexthop;
+	if (nexthop) result = nexthop;
+	else result = gateway;
     }
     else
     {
@@ -1067,16 +1113,29 @@ uint32_t route_func(rt_actions action, uint32_t address, uint32_t netmask, uint3
 
     if (ROUTE_ADD == action)
     {
-	if (0 != nexthop) addattr32(&req.hdr, sizeof(req), RTA_GATEWAY, nexthop); /* gateway */
-	addattr32(&req.hdr, sizeof(req), RTA_OIF, tunidx); /* dev */
-	if (rmetric>0)
+	if (0 != nexthop)
 	{
-	    addattr32(&req.hdr, sizeof(req), RTA_PRIORITY, rmetric); /* metrics */
+	    /* AMPR mesh route */
+	    req.rtm.rtm_flags |= RTNH_F_ONLINK;
+
+	    addattr32(&req.hdr, sizeof(req), RTA_GATEWAY, nexthop); /* gateway */
+	    addattr32(&req.hdr, sizeof(req), RTA_OIF, tunidx); /* dev */
+
+	    if (rmetric>0)
+	    {
+		addattr32(&req.hdr, sizeof(req), RTA_PRIORITY, rmetric); /* metrics */
+	    }
+	    if (rwindow>0)
+	    {
+		rta_addattr32(mxrta, sizeof(mxbuf), RTAX_WINDOW, rwindow);
+		addattr_len(&req.hdr, sizeof(req), RTA_METRICS, RTA_DATA(mxrta), RTA_PAYLOAD(mxrta));
+	    }
 	}
-	if (rwindow>0)
+	else
 	{
-	    rta_addattr32(mxrta, sizeof(mxbuf), RTAX_WINDOW, rwindow);
-	    addattr_len(&req.hdr, sizeof(req), RTA_METRICS, RTA_DATA(mxrta), RTA_PAYLOAD(mxrta));
+	    /* host route */
+	    addattr32(&req.hdr, sizeof(req), RTA_GATEWAY, gateway); /* gateway */
+	    addattr32(&req.hdr, sizeof(req), RTA_OIF, gwdev); /* dev */
 	}
     }
 
@@ -1138,23 +1197,70 @@ uint32_t route_func(rt_actions action, uint32_t address, uint32_t netmask, uint3
 		}
 	    }
 	}
+
+	if (ROUTE_GETDEV == action)
+	{
+	    /* parse response for ROUTE_GETDEV */
+	    for (rh = (struct nlmsghdr *)nlrxbuf; NLMSG_OK(rh, len); rh = NLMSG_NEXT(rh, len))
+	    {
+		if (rh->nlmsg_type == 24) /* route info resp */
+		{
+		    rm = NLMSG_DATA(rh);
+		    for (rtattr = (struct rtattr *)RTM_RTA(rm); RTA_OK(rtattr, len); rtattr = RTA_NEXT(rtattr, len))
+		    {
+			if (RTA_OIF == rtattr->rta_type)
+			{
+			    result = *((uint32_t *)RTA_DATA(rtattr));
+			}
+		    }
+		}
+		else if (NLMSG_ERROR == rh->nlmsg_type)
+		{
+		    result = 0;
+		}
+	    }
+	}
     }
     close(nlsd);
     return result;
 }
 
+void route_del(uint32_t address, uint32_t netmask, uint32_t nexthop)
+{
+    route_func(ROUTE_DEL, address, netmask, 0); /* fails if route does not exist - no problem */
+    if (44 == (ntohl(nexthop) >> 24))
+    {
+	route_func(ROUTE_DEL, nexthop, 32, 0);  /* fails if route does not exist - no problem */
+    }
+}
+
 void route_update(uint32_t address, uint32_t netmask, uint32_t nexthop)
 {
 	if (route_func(ROUTE_GET, address, netmask, 0) != nexthop)
 	{
-	    route_func(ROUTE_DEL, address, netmask, 0); /* fails if route does not exist - no problem */
+	    route_del(address, netmask, nexthop);
+
+	    if (44 == (ntohl(nexthop) >> 24))
+	    {
+		if (route_func(ROUTE_ADD, nexthop, 32, 0) == 0)
+		{
+#ifdef HAVE_DEBUG
+		    if (debug)
+		    {
+			fprintf(stderr, "Failed to set host route %s via ", ipv4_ntoa(nexthop));
+			fprintf(stderr, "%s\n", ipv4_ntoa(gateway));
+		    }
+#endif
+		}
+	    }
+
 	    if (route_func(ROUTE_ADD, address, netmask, nexthop) == 0)
 	    {
 #ifdef HAVE_DEBUG
 		if (debug)
 		{
 		    fprintf(stderr, "Failed to set route %s/%d via ", ipv4_ntoa(address), netmask);
-		    fprintf(stderr, "%s on dev %s. ", ipv4_ntoa(nexthop), tunif);
+		    fprintf(stderr, "%s on dev %s\n", ipv4_ntoa(nexthop), tunif);
 		}
 #endif
 	    }
@@ -1173,7 +1279,7 @@ void route_delete_all(void)
 	{
 		if (0 != routes[i].timestamp)
 		{
-			route_func(ROUTE_DEL, routes[i].address, routes[i].netmask, 0);
+			route_del(routes[i].address, routes[i].netmask, routes[i].nexthop);
 		}
 	}
 
@@ -1261,11 +1367,11 @@ void process_entry(char *buf)
 
 	for (i=0; i<32; i++)
 	{
-	    if (rip->mask & mask)
-	    {
-		netmask++;
-	    }
-	    mask <<= 1;
+		if (rip->mask & mask)
+		{
+		    netmask++;
+		}
+		mask <<= 1;
 	}
 
 #ifdef HAVE_DEBUG
@@ -1277,26 +1383,21 @@ void process_entry(char *buf)
 	}
 #endif
 
-	/* drop 44.0.0.1 */
+	/* adjust and set 44.0.0.1 entry */
 	if (rip->address == inet_addr("44.0.0.1"))
 	{
 #ifdef HAVE_DEBUG
-	    if (debug && verbose) fprintf(stderr, " - rejected\n");
+		if (debug && verbose) fprintf(stderr, " - add ampr gateway entry\n");
 #endif
-	    return;
+		/* use an /32 prefix as this is a host route */
+		route_update(rip->address, 32, rip->nexthop);
+		list_update(rip->address, 32, rip->nexthop);
+
+		return;
 	}
 
 	/* validate and update the route */
 
-	/* drop routes with gw in their own subnet */
-	if ((rip->address << (32 - netmask)) == (rip->nexthop << (32 - netmask)))
-	{
-#ifdef HAVE_DEBUG
-	    if (debug && verbose) fprintf(stderr, " - rejected\n");
-#endif
-	    return;
-	}
-
 	/* remove if unreachable and in list */
 	if (ntohl(rip->metric) > 14)
 	{
@@ -1305,7 +1406,7 @@ void process_entry(char *buf)
 #endif
 		if ((i = list_find(rip->address, netmask)) != -1)
 		{
-			route_func(ROUTE_DEL, rip->address, netmask, 0);
+			route_del(rip->address, netmask, rip->nexthop);
 			list_remove(i);
 #ifdef HAVE_DEBUG
 			if (debug && verbose) fprintf(stderr, ", removed from list");
@@ -1449,11 +1550,172 @@ int process_message(char *buf, int len)
 	return 0;
 }
 
+int create_fwsd(void)
+{
+	struct sockaddr_in sin;
+
+#ifdef HAVE_DEBUG
+	if (debug && verbose) fprintf(stderr, "Setting up forwarding interface.\n");
+#endif
+
+	/* check for the same interface as the tunnel */
+	if (strcmp(fwif, tunif) == 0)
+	{
+		fprintf(stderr, "Forward not possible on the ingress tunnel interface: forward disabled.\n");
+		fwif = NULL; /* disable forward */
+		return 1;
+	}
+
+	if ((fwsd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP)) < 0)
+	{
+		PERROR("Forward socket");
+		fwif = NULL; /* disable forward */
+		return 1;
+	}
+
+	if (setsockopt(fwsd, SOL_SOCKET, SO_BINDTODEVICE, fwif, strlen(fwif)) < 0)
+	{
+		PERROR("Forward socket: Setting SO_BINDTODEVICE");
+		close(fwsd);
+		fwif = NULL; /* disable forward */
+		return 1;
+	}
+
+	memset((char *)&sin, 0, sizeof(sin));
+	sin.sin_family = PF_INET;
+	sin.sin_addr.s_addr = INADDR_ANY;
+	sin.sin_port = htons(IPPORT_ROUTESERVER);
+
+	if (bind(fwsd, (struct sockaddr *)&sin, sizeof(sin)))
+	{
+		PERROR("Forward socket: Bind");
+		close(fwsd);
+		fwif = NULL; /* disable forward */
+		return 1;
+	}
+	return 0;
+}
+
+int create_amprfwsd(void)
+{
+	struct sockaddr_in sin;
+
+#ifdef HAVE_DEBUG
+	if (debug && verbose) fprintf(stderr, "Setting up AMPR forwarding interface.\n");
+#endif
+
+	/* check for the same interface as the tunnel */
+	if (strcmp(amprfwif, tunif) == 0)
+	{
+		fprintf(stderr, "AMPR forward not possible on the ingress tunnel interface: forward disabled.\n");
+		amprfwif = NULL; /* disable forward */
+		return 1;
+	}
+
+
+	/* check for the same interface for -e and -E */
+	if (fwif && (strcmp(amprfwif, fwif) == 0))
+	{
+		if (fwsd > 0)
+		{
+			if (debug && verbose) fprintf(stderr, "AMPR forward socket connected to forward socket.\n");
+			amprfwsd = fwsd;
+			return 0;
+		}
+		else
+		{
+			fprintf(stderr, "Connecting AMPR forward socket: Forward socket invalid.\n");
+			amprfwif = NULL; /* disble forward */
+			return 1;
+		}
+		return 0;
+	}
+
+	if ((amprfwsd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP)) < 0)
+	{
+		PERROR("AMPR Forward socket");
+		amprfwif = NULL; /* disble forward */
+		return 1;
+	}
+
+	if (setsockopt(amprfwsd, SOL_SOCKET, SO_BINDTODEVICE, amprfwif, strlen(amprfwif)) < 0)
+	{
+		PERROR("AMPR Forward socket: Setting SO_BINDTODEVICE");
+		close(amprfwsd);
+		amprfwif = NULL; /* disble forward */
+		return 1;
+	}
+
+	memset((char *)&sin, 0, sizeof(sin));
+	sin.sin_family = PF_INET;
+	sin.sin_addr.s_addr = INADDR_ANY;
+	sin.sin_port = htons(IPPORT_ROUTESERVER);
+
+	if (bind(amprfwsd, (struct sockaddr *)&sin, sizeof(sin)))
+	{
+		PERROR("AMPR Forward socket: Bind");
+		close(amprfwsd);
+		amprfwif = NULL; /* disble forward */
+		return 1;
+	}
+
+	return 0;
+}
+
+void callhome(int alive)
+{
+	struct sockaddr_in sin;
+	int hsd;
+
+	char *shutdown = "shutdown";
+
+#ifdef HAVE_DEBUG
+	if (debug && verbose) fprintf(stderr, "Setting up call home.\n");
+#endif
+
+	if ((hsd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
+	{
+		PERROR("Call home socket");
+		return;
+	}
+
+	memset((char *)&sin, 0, sizeof(sin));
+	sin.sin_family = AF_INET;
+	sin.sin_addr.s_addr = tunaddr;
+	sin.sin_port = 0;
+
+	if (bind(hsd, (struct sockaddr *)&sin, sizeof(sin)))
+	{
+		PERROR("AMPR Forward socket: Bind");
+		close(hsd);
+		return ;
+	}
+
+	memset((char *)&sin, 0, sizeof(sin));
+	sin.sin_family = AF_INET;
+	sin.sin_addr.s_addr = ns_resolv(homeaddr);
+	sin.sin_port = htons(atoi(homeport));
+
+	if (alive)
+	{
+		sendto(hsd, homedata, strlen(homedata), 0, (struct sockaddr *)&sin, sizeof(sin));
+	}
+	else
+	{
+		sendto(hsd, shutdown, strlen(shutdown), 0, (struct sockaddr *)&sin, sizeof(sin));
+	}
+
+	close(hsd);
+	return;
+}
+
 static void on_term(int sig)
 {
 #ifdef HAVE_DEBUG
 	if (debug && verbose) fprintf(stderr, "SIGTERM/SIGKILL received.\n");
 #endif
+	if (homedata) callhome(FALSE);
+	if_freenameindex(ifnames);
 	close(fwsd);
 	close(tunsd);
 	route_delete_all();
@@ -1494,7 +1756,7 @@ static void on_alarm(int sig)
 	    {
 		if ((0 != routes[i].timestamp) && ((routes[i].timestamp + EXPTIME) < time(NULL)))
 		{
-			route_func(ROUTE_DEL, routes[i].address, routes[i].netmask, 0);
+			route_del(routes[i].address, routes[i].netmask, routes[i].nexthop);
 			list_remove(i);
 			count++;
 			updated = TRUE;
@@ -1564,12 +1826,27 @@ static void on_alarm(int sig)
 		    }
 		}
 
-		sendto(fwsd, &rp, sizeof(rip_header) + size * sizeof(rip_entry), 0, (struct sockaddr *)&sin, sizeof(sin));
+		if (sendto(fwsd, &rp, sizeof(rip_header) + size * sizeof(rip_entry), 0, (struct sockaddr *)&sin, sizeof(sin)) == -1)
+		{
+		    close(fwsd);
+		    create_fwsd();
+		}
 
 	    }
 
 	}
 
+	if (homedata)
+	{
+		if (hometimer) hometimer--;
+		else
+		{
+			hometimer = HOME_REPETITION;
+			if (debug) fprintf(stderr, "Calling home\n");
+			callhome(TRUE);
+		}
+	}
+
 	/* resend local RIP data every 29 sec - this will prevent overlapping at 5 min with the AMPR RIP update */
 	alarm(29);
 }
@@ -1579,6 +1856,10 @@ static void on_hup(int sig)
 #ifdef HAVE_DEBUG
 	if (debug) fprintf(stderr, "SIGHUP received!\n");
 #endif
+	hometimer = HOME_REPETITION;
+	if (debug) fprintf(stderr, "Calling home\n");
+	callhome(TRUE);
+
 	route_delete_all();
 	list_clear();
 	updated = TRUE;
@@ -1586,16 +1867,17 @@ static void on_hup(int sig)
 
 int main(int argc, char **argv)
 {
-	int p;
+	int i,p;
 
 	struct sockaddr_in sin;
-	
+	struct group_req group;
+
 	char databuf[BUFFERSIZE];
 	char *pload;
 	int len, plen;
 	int lval;
 
-	while ((p = getopt(argc, argv, "dvsrh?i:a:p:t:m:w:f:e:x:")) != -1)
+	while ((p = getopt(argc, argv, "dvsrh?i:a:p:t:m:w:f:e:F:E:x:g:L:")) != -1)
 	{
 		switch (p)
 		{
@@ -1609,7 +1891,7 @@ int main(int argc, char **argv)
 			save = TRUE;
 			break;
 		case 'r':
-			/* ignore */
+			raw = TRUE;
 			break;
 		case 'i':
 			tunif = optarg;
@@ -1641,9 +1923,21 @@ int main(int argc, char **argv)
 		case 'e':
 			fwdest = optarg;
 			break;
+		case 'F':
+			amprfwif = optarg;
+			break;
+		case 'E':
+			amprfwdest = optarg;
+			break;
 		case 'x':
 			syscmd = optarg;
 			break;
+		case 'g':
+			defgw = optarg;
+			break;
+		case 'L':
+			homedata = optarg;
+			break;
 		case ':':
 		case 'h':
 		case '?':
@@ -1652,6 +1946,14 @@ int main(int argc, char **argv)
 		}
 	}
 
+	/* get interface list */
+	ifnames = if_nameindex();
+	if (NULL == ifnames)
+	{
+	    fprintf(stderr, "Init: Can not get interface list.\n");
+	    return 1;
+	}
+
 	if (debug && verbose)
 	{
 		fprintf(stderr, "Using metric %d for routes.\n", rmetric);
@@ -1686,53 +1988,166 @@ int main(int argc, char **argv)
 
 	detect_myips();
 
+	/* detect if default gateway is an interface name */
+	if (defgw)
+	{
+	    i = 0;
+	    while ((ifnames[i].if_index != 0) && (ifnames[i].if_name != NULL))
+	    {
+		if (strcmp(ifnames[i].if_name, defgw) == 0)
+		{
+		    /* use interface as gateway */
+		    gwdev = ifnames[i].if_index;
+		    break;
+		}
+		i++;
+	    }
+	}
+
+	/* default gateway is not an interfac name */
+	if (0 == gwdev)
+	{
+	    if (defgw)
+	    {
+		gateway = ns_resolv(defgw);
+	    }
+
+	    if (0 == gateway)
+	    {
+		if (defgw) fprintf(stderr, "Warning: gateway \"%s\" does not resolve to an valid IP address or interface name, autodetecting.\n", defgw);
+		gateway = route_func(ROUTE_GET, inet_addr("8.8.8.8"), 32, 0);
+	    }
+	    gwdev = route_func(ROUTE_GETDEV, gateway, 32, 0);
+	}
+
+	if (0 == gwdev)
+	{
+	    fprintf(stderr, "Can not detectroute for direct 44net endpoints.\n");
+	    if_freenameindex(ifnames);
+	    return 1;
+	}
+
+	if (debug)
+	{
+	    if (gateway)
+	    {
+		i = 0;
+		while ((ifnames[i].if_index != 0) && (ifnames[i].if_name != NULL))
+		{
+		    if (gwdev == ifnames[i].if_index)
+		    {
+			fprintf(stderr, "Using gateway %s for direct 44net endpoints via interface %s.\n", ipv4_ntoa(gateway), ifnames[i].if_name);
+		    }
+		    i++;
+		}
+	    }
+	    else
+		fprintf(stderr, "Using interface %s for direct 44net endpoints.\n", defgw);
+	}
+
 	route_set_all();
 
 	/* create multicast listen socket on tunnel */
 
+	if (TRUE == raw)
+	{
+		/* raw socket */
 #ifdef HAVE_DEBUG
-	if (debug) fprintf(stderr, "Creating RIP UDP listening socket.\n");
+		if (debug) fprintf(stderr, "Creating raw RIP UDP listening socket.\n");
 #endif
-
-	if ((tunsd = socket(PF_INET, SOCK_RAW, 4)) < 0)
-	{
-	    PERROR("Raw socket");
-		return 1;
+		if ((tunsd = socket(PF_INET, SOCK_RAW, 4)) < 0)
+		{
+			PERROR("Raw socket");
+			if_freenameindex(ifnames);
+			return 1;
+		}
 	}
-
-	if (NULL != fwif)
+	else
 	{
-		/* create the forward socket */
 #ifdef HAVE_DEBUG
-		if (debug && verbose) fprintf(stderr, "Setting up forwarding interface.\n");
+		if (debug) fprintf(stderr, "Creating multicast RIP UDP listening socket.\n");
+#endif
+
+		if ((tunsd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP)) < 0)
+		{
+			PERROR("Tunnel socket");
+			if_freenameindex(ifnames);
+			return 1;
+		}
+
+#ifdef HAVE_DEBUG
+		if (debug && verbose) fprintf(stderr, "Setting up multicast interface.\n");
 #endif
-		if ((fwsd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP)) < 0)
+
+		int reuse = 1;
+		if (setsockopt(tunsd, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse)) < 0)
 		{
-			PERROR("Forward socket");
+			PERROR("Tunnel socket: Setting SO_REUSEADDR");
 			close(tunsd);
+			if_freenameindex(ifnames);
 			return 1;
 		}
 
-		if (setsockopt(fwsd, SOL_SOCKET, SO_BINDTODEVICE, fwif, strlen(fwif)) < 0)
+		if (setsockopt(tunsd, SOL_SOCKET, SO_BINDTODEVICE, tunif, strlen(tunif)) < 0)
 		{
 			PERROR("Tunnel socket: Setting SO_BINDTODEVICE");
-			close(fwsd);
 			close(tunsd);
+			if_freenameindex(ifnames);
 			return 1;
 		}
 
+		set_multicast(tunsd, tunif);
+
 		memset((char *)&sin, 0, sizeof(sin));
 		sin.sin_family = PF_INET;
-		sin.sin_addr.s_addr = INADDR_ANY;
+		sin.sin_addr.s_addr = INADDR_ANY; /* mandatory INADDR_ANY for multicast */
 		sin.sin_port = htons(IPPORT_ROUTESERVER);
-		
-		if (bind(fwsd, (struct sockaddr *)&sin, sizeof(sin)))
+
+		if (bind(tunsd, (struct sockaddr *)&sin, sizeof(sin)))
 		{
-			PERROR("Forward socket: Bind");
-			close(fwsd);
+			PERROR("Tunnel socket: Bind");
 			close(tunsd);
+			if_freenameindex(ifnames);
 			return 1;
 		}
+
+		/* disable loopback */
+		int loop = 0;
+		if (setsockopt(tunsd, IPPROTO_IP, IP_MULTICAST_LOOP, (char *)&loop, sizeof(loop)) < 0)
+		{
+			PERROR("Tunnel socket: Disable loopback");
+			close(tunsd);
+			if_freenameindex(ifnames);
+			return 1;
+		}
+
+		/* join multicast group 224.0.0.9 */
+		memset((char *)&group, 0, sizeof(group));
+		memset((char *)&sin, 0, sizeof(sin));
+		sin.sin_family = AF_INET;
+		sin.sin_addr.s_addr = inet_addr("224.0.0.9");
+		memcpy(&group.gr_group, &sin, sizeof(sin));
+		group.gr_interface = tunidx;
+
+		if (setsockopt(tunsd, IPPROTO_IP, MCAST_JOIN_GROUP, (char *)&group, sizeof(group)) < 0)
+		{
+			PERROR("Tunnel socket: join multicast");
+			close(tunsd);
+			if_freenameindex(ifnames);
+			return 1;
+		}
+	}
+
+	if (NULL != fwif)
+	{
+		/* create the forward socket */
+		create_fwsd();
+	}
+
+	if (NULL != amprfwif)
+	{
+		/* create the ampr forward socket */
+		create_amprfwsd();
 	}
 
 	/* networking up and running */
@@ -1749,9 +2164,18 @@ int main(int argc, char **argv)
 
 	signal(SIGTERM, on_term);
 	signal(SIGKILL, on_term);
+	signal(SIGINT, on_term);
 	signal(SIGHUP, on_hup);
 	signal(SIGALRM, on_alarm);
 
+
+	if (homedata)
+	{
+		hometimer = HOME_REPETITION;
+		if (debug) fprintf(stderr, "Calling home\n");
+		callhome(TRUE);
+	}
+
 	alarm(30);
 
 	/* daemon or debug */
@@ -1759,6 +2183,13 @@ int main(int argc, char **argv)
 	if (debug) fprintf(stderr, "Waiting for RIPv2 broadcasts...\n");
 
 
+	if (NULL != amprfwif)
+	{
+		sin.sin_family = PF_INET;
+		sin.sin_addr.s_addr = inet_addr(amprfwdest);
+		sin.sin_port = htons(IPPORT_ROUTESERVER);
+	}
+
 	while (1)
 	{
 		if ((len = read(tunsd, databuf, BUFFERSIZE)) < 0)
@@ -1767,34 +2198,52 @@ int main(int argc, char **argv)
 		}
 		else
 		{
-			if (len >= 48 + (RIP_HDR_LEN + RIP_ENTRY_LEN))
+			if (TRUE == raw)
 			{
-				struct iphdr *iph = (struct iphdr *)(databuf + 20);
-				struct udphdr *udh = (struct udphdr *)(databuf + 40);
-			
-				if ((iph->daddr == inet_addr("224.0.0.9")) &&
-				    (iph->saddr == inet_addr("44.0.0.1")) &&
-				    (udh->dest == htons(IPPORT_ROUTESERVER)) &&
-				    (udh->source == htons(IPPORT_ROUTESERVER)))
+				if (len >= 48 + (RIP_HDR_LEN + RIP_ENTRY_LEN))
 				{
-				    pload = &databuf[48];
-				    plen = len - 48;
+					struct iphdr *iph = (struct iphdr *)(databuf + 20);
+					struct udphdr *udh = (struct udphdr *)(databuf + 40);
+			
+					if ((iph->daddr == inet_addr("224.0.0.9")) &&
+					    (iph->saddr == inet_addr("44.0.0.1")) &&
+					    (udh->dest == htons(IPPORT_ROUTESERVER)) &&
+					    (udh->source == htons(IPPORT_ROUTESERVER)))
+					{
+						pload = &databuf[48];
+						plen = len - 48;
+					}
+					else
+					{
+					    continue;
+					}
 				}
 				else
 				{
-				    continue;
+					continue;
 				}
 			}
 			else
 			{
-				continue;
+				pload = databuf;
+				plen = len;
 			}
 			
 			process_message(pload, plen);
 			
+			if (NULL != amprfwif)
+			{
+				if (sendto(amprfwsd, pload, plen, 0, (struct sockaddr *)&sin, sizeof(sin)) < 0)
+				{
+					/* reopen forward interface on error */
+					if (amprfwsd != tunsd) close(amprfwsd);
+					create_amprfwsd();
+				}
+			}
 		}
 	}
 
 	/* we never reach this */
 	return 0; 
 }
+
diff --git a/ampr-run.sh b/examples/ampr-run.sh
similarity index 86%
rename from ampr-run.sh
rename to examples/ampr-run.sh
index de7dfc6..7c096c9 100755
--- a/ampr-run.sh
+++ b/examples/ampr-run.sh
@@ -13,6 +13,6 @@
 #   e.g. routes aquired via other routing protocols, may be dropped if not needed)
 # - all received RIPv2 multicasts are forwarded to interface eth0 as multicasts (drop this if not needed)...
 # - all routes set by ampr-ripd are saved to /var/lib/ampr-ripd/routes (example of external system command)
-#
+# - a string "test at aa00aa" will be sent to my home gateway every 5 minutes
 
-/usr/sbin/ampr-ripd -s -i ampr0 -m 50 -a 193.0.0.1 -f eth0 -x "ip route | grep 'proto 44' >/var/lib/ampr-ripd/routes"
+/usr/sbin/ampr-ripd -s -i ampr0 -m 50 -a 193.0.0.1 -f eth0 -x "ip route | grep 'proto 44' >/var/lib/ampr-ripd/routes" -L test at aa00aa
diff --git a/find_pass.sh b/examples/find_pass.sh
similarity index 89%
rename from find_pass.sh
rename to examples/find_pass.sh
index a320363..20682ab 100755
--- a/find_pass.sh
+++ b/examples/find_pass.sh
@@ -6,4 +6,4 @@
 # You need to adapt the interface name to your setup.
 #
 
-./ampr-ripd -d -i ampr0
+./ampr-ripd -d -v -i ampr0
diff --git a/examples/interfaces b/examples/interfaces
new file mode 100644
index 0000000..00dc6ca
--- /dev/null
+++ b/examples/interfaces
@@ -0,0 +1,25 @@
+#
+# IPIP tunnel & ampr-ripd startup example via /etc/network/interfaces
+#
+#
+# - Tunnel interface is named 'ampr0'
+# - Local WAN IP is 192.168.0.2 on eth1
+# - AMPR routing table used is table 'default'
+# - gateway IP is 44.128.0.1
+#
+
+auto ampr0
+iface ampr0 inet static
+address 44.128.0.1
+netmask 255.255.255.255
+metric 100
+pre-up ip tun add ampr0 mode ipip ttl 64 local 192.168.0.2 dev eth1
+up ip route add default via 169.228.34.84 dev ampr0 onlink table default
+up ip rule add from 44.128.0.1 table default
+up ampr-ripd -s -t default -i ampr0 -m 90 -a 44.128.0.0/24
+up ping -c 1 -I ampr0 44.0.0.1 > /dev/null 2>&1
+pre-down ip route del default via 169.228.34.84 dev ampr0 onlink table default
+post-down killall ampr-ripd
+post-down ip rule del from 44.128.0.1 table default
+post-down ip tunnel del ampr0
+post-down rmmod ipip
diff --git a/manual.txt b/manual.txt
index 71fba6d..7cde0c0 100644
--- a/manual.txt
+++ b/manual.txt
@@ -1,13 +1,14 @@
- ***************************************************************
- *                                                             *
- *  ampr-ripd.c - AMPR 44net RIPv2 Listner and Route Injector  *
- *                                                             *
- ***************************************************************
+ ********************************************************************
+ *                                                                  *
+ *  ampr-ripd.c - AMPR 44net RIPv2 Listner and Route Injector v2.3  *
+ *                                                                  *
+ ********************************************************************
 
  Author: Marius Petrescu, YO2LOJ, <marius at yo2loj.ro>
 
 
- Usage: ampr-ripd [-?|-h] [-d] [-v] [-s] [-r] [-i <interface>] [-a <ip|hostname|subnet>[,<ip|hostname|subnet>...]] [-p <password>] [-f <interface>] [-e <ip>] [-x <system command>]
+ Usage: ampr-ripd [-?|-h] [-d] [-v] [-s] [-r] [-i <interface>] [-a <ip|hostname|subnet>[,<ip|hostname|subnet>...]] [-p <password>]
+                           [-m <metric>] [-w <window>] [-f <interface>] [-e <ip>] [-x <system command>] [-g <gateway>]
 
  Options:
           -?, -h                Usage info
@@ -32,10 +33,24 @@
                                 A value of 0 diables setting the window size (not recommended, default value should be ok)
           -p <password>         RIPv2 password, defaults to the current valid password
           -f <interface>        Interface for RIP forwarding, defaults to none/disabled
-          -e <ip>               Forward destination IP, defaults to 224.0.0.9 if enabled
-          -x <system command>   Execute this system command after route set/change. If the command includes white spaces, use quotes.
-
- Observation: All routes are created with protocol 44 for easy management
+          -e <ip>               RIP forward destination IP, defaults to 224.0.0.9 if enabled
+          -F <interface>        Interface for AMPR RIP forwarding, defaults to none/disabled
+          -E <ip>               AMPR RIP forward destination IP, defaults to 224.0.0.9 if enabled
+          -x <system command>   Execute this system command after route set/change
+                                If the command includes white spaces, use quotes.
+          -g <gateway>          Gateway for direct 44net connections (gateway IP or interface name).
+                                If not set, the default gateway will be autodetected.
+          -L <callsign at locator> Enable to sending of a callsign at locator string (actually any string) to
+                                my home gateway (udp:44.182.21.1:59001).
+                                The string will be sent at starup, and then every 5 minutes.
+                                On termination, a "shutdown" string will be sent.
+                                On HUP, the string will be sent immediately and the cycle restarted.
+                                The purpose of this option is to allow the construction of a dynamic map of
+                                all ampr-ripd gateways for visual display.
+                                if the parameter is not set, no data will be sent.
+
+
+ Observation: All routes are created with netlink protocol 44 for easy management
 
 
  Signal handling:
@@ -98,6 +113,19 @@
  *                             (OK from Brian Kantor - Tnx.)
  *                             Added man page courtesy of Ana C. Custura and the DebianHams
  *    1.15    21.Sep.2016      Removed multicast access mode, now only raw sockets are used
+ *    1.16     3.Apr.2017      Added support for BGP announced 44net endpoints
+ *    1.16.1   4.Apr.2017      Added SIGINT handler for CTRL-C in debug mode to clean routes on exit
+ *    1.16.2   5.Apr.2017      Reopen forward socket on RIP send fail
+ *    1.16.4  19.Apr.2017      Correction for hostroutes on big endian machines
+ *    2.0     20.May.2017      Brought -r option back to life
+ *                             Added -F and -E options for raw AMPR-RIPD forwarding
+ *                             Added setting of 44.0.0.1/32 route according to RIP data
+ *    2.1     28.May.2017      Fixed a segfault if using the -F option
+ *                             Added the possibility to use interface names for the -g option
+ *                             Interface used for raw RIP forward restarts on interface error
+ *    2.1.1   29.May.2017      Corrected a tunnel interface detection error
+ *    2.2     30.May.2017      Enable sending of call at locator to my gateway server for dynamic map creation
+ *    2.3      4.Jun.2017      Force the use of funnel address as source IP on call home
 
  INSTALLATION
  ------------
@@ -111,7 +139,7 @@ Or:
 
  KNOWN ISSUES
  ------------
- - when using other table than 'main', interogating the routes via netlink does not work properly.
+ - When using other table than 'main', interogating the routes via netlink does not work properly.
    This means that on any update, the route is deleted and then recreated, even if it is already set correctly.
    This should be no problem since this happen only at startup on encap loading and on route change.
-
+ - For BGP announced 44net endpoints, only a single subnet may be assigned to a given endpoint.

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-hamradio/ampr-ripd.git



More information about the pkg-hamradio-commits mailing list