* [PATCH] ax25ipd
@ 2010-03-06 18:13 Bernard Pidoux
2010-03-06 19:30 ` Bernard Pidoux
0 siblings, 1 reply; 3+ messages in thread
From: Bernard Pidoux @ 2010-03-06 18:13 UTC (permalink / raw)
To: Cathryn Mataga; +Cc: linux-hams
[-- Attachment #1: Type: text/plain, Size: 913 bytes --]
Hi Cathryn,
Thanks for your excellent work on ax25ipd.
I have been using ax25-apps.0.0.8-rc2 with your ax25ipd patch for a
couple of months.
I did not notice any issue, although I use devfs legacy pseudo tty and
not Unix98 devices.
However I know there are an increasing number of AX25 ROSE FPAC nodes
using Unix98
/dev/ptmx /dev/pts devices.
I noticed that your patch included a few minor errors that I corrected.
Also you added -pthread into ax25ipd Makefile while this file does
not exist when unpacking ax25-tools-0.0.8-rc2.
Thus I moved this argument into apps configure file.
I included also a reference to Steve Fraser vk5asf work, adding
provision for dynamic dns hosts in June 2005, and changed sub
version number to 1.0.6
Patched ax25-apps package may be found here:
http://f6bvp.free.fr/logiciels/ax25/From%20other%20sources/ax25-apps-0.0.8-rc2.ax25ipd.dyndns.tar.bz2
Bernard Pidoux
[-- Attachment #2: ax25-apps-0.0.8-rc2.ax25ipd.dyndns.patch --]
[-- Type: text/plain, Size: 20442 bytes --]
diff -ruN ax25-apps-0.0.8-rc2/ax25ipd/ax25ipd.h ax25-apps-0.0.8-rc2.ax25ipd.dyndns/ax25ipd/ax25ipd.h
--- ax25-apps-0.0.8-rc2/ax25ipd/ax25ipd.h 2009-06-14 10:11:48.000000000 +0200
+++ ax25-apps-0.0.8-rc2.ax25ipd.dyndns/ax25ipd/ax25ipd.h 2010-03-06 13:58:23.000000000 +0100
@@ -25,6 +25,18 @@
* Terry Dawson, VK2KTJ, September 2001.
*/
+/*
+ Version 1.0.5
+ added provision for dynamic dns hosts
+ Steve Fraser vk5asf, June 2005
+*/
+
+/*
+ Version 1.0.6
+
+
+*/
+
/* Define the current version number
*
* The first digit represents the major release (0 is a prototype release)
@@ -37,7 +49,7 @@
*
*/
-#define VERS2 "Version 1.0.2"
+#define VERS2 "Version 1.0.6"
#define IPPROTO_AX25 93
#define DEFAULT_UDP_PORT 10093
@@ -118,6 +130,11 @@
#define AXRT_BCAST 1
#define AXRT_DEFAULT 2
+#define AXRT_PERMANENT 4
+#define AXRT_LEARN 8
+
+
+#define IPSTORAGESIZE 6 /* Bytes needed for call_to_ip */
/* start external prototypes */
/* end external prototypes */
@@ -133,12 +150,16 @@
/* routing.c */
void route_init(void);
-void route_add(unsigned char *, unsigned char *, int, unsigned int);
+void route_add(char *, unsigned char *, unsigned char *, int, unsigned int);
+int route_ipmatch(struct sockaddr_in *, unsigned char *);
+unsigned char *retrieveip(unsigned char *, unsigned char *);
+void route_process(struct sockaddr_in *, unsigned char *);
void bcast_add(unsigned char *);
-unsigned char *call_to_ip(unsigned char *);
+unsigned char *call_to_ip(unsigned char *, unsigned char *);
int is_call_bcast(unsigned char *);
void send_broadcast(unsigned char *, int);
void dump_routes(void);
+void update_dns(unsigned);
/* config.c */
void config_init(void);
@@ -151,11 +172,13 @@
/* process.c */
void process_init(void);
void from_kiss(unsigned char *, int);
-void from_ip(unsigned char *, int);
+void from_ip(unsigned char *, int, struct sockaddr_in *);
/* void do_broadcast(void); where did this go ?? xxx */
void do_beacon(void);
int addrmatch(unsigned char *, unsigned char *);
+int addrcompare(unsigned char *, unsigned char *);
unsigned char *next_addr(unsigned char *);
+unsigned char *from_addr(unsigned char *);
void add_crc(unsigned char *, int);
void dump_ax25frame(char *, unsigned char *, int);
diff -ruN ax25-apps-0.0.8-rc2/ax25ipd/config.c ax25-apps-0.0.8-rc2.ax25ipd.dyndns/ax25ipd/config.c
--- ax25-apps-0.0.8-rc2/ax25ipd/config.c 2009-06-14 10:07:11.000000000 +0200
+++ ax25-apps-0.0.8-rc2.ax25ipd.dyndns/ax25ipd/config.c 2010-03-06 11:24:05.000000000 +0100
@@ -292,6 +292,8 @@
return 0;
} else if (strcmp(p, "route") == 0) {
+ char *thost;
+
uport = 0;
flags = 0;
@@ -305,15 +307,26 @@
q = strtok(NULL, " \t\n\r");
if (q == NULL)
return -1;
- he = gethostbyname(q);
- if (he != NULL) {
- memcpy(tip, he->h_addr_list[0], 4);
- } else { /* maybe user specified a numeric addr? */
- j = inet_addr(q);
- if (j == -1)
- return -5; /* if -1, bad deal! */
+ thost = strdup(q);
+ j = inet_addr(q);
+ if (j != -1){ /* maybe user specified a numeric addr? */
+ flags |= AXRT_PERMANENT; /* Prevent useless dns check on dotted ip */
memcpy(tip, (char *) &j, 4);
+ if (!j){/* IP of 0.0.0.0. Learn from incoming packets */
+ flags |= AXRT_LEARN;
+ }
+ }
+ else {
+ he = gethostbyname(q);
+ if (he != NULL) {
+ memcpy(tip, he->h_addr_list[0], 4);
+ } else {
+ j = inet_addr("0.0.0.0");/* try to rescue this idea of checking later.*/
+ memcpy(tip, (char *) &j, 4);
+ fprintf(stderr,"ax25ipd: %s host IP address unknown - will probe it again later\n",thost);
+ }
}
+
while ((q = strtok(NULL, " \t\n\r")) != NULL) {
if (strcmp(q, "udp") == 0) {
@@ -334,9 +347,19 @@
if (strchr(q, 'd')) {
flags |= AXRT_DEFAULT;
}
+
+ /* Test for "permanent" flag */
+ if (strchr(q, 'p')) {
+ flags |= AXRT_PERMANENT;
+ }
+ /* Test for "learn" flag */
+ if (strchr(q, 'l')) {
+ flags |= AXRT_LEARN;
+ }
}
}
- route_add(tip, tcall, uport, flags);
+ route_add(thost, tip, tcall, uport, flags);
+ free(thost);
return 0;
} else if (strcmp(p, "broadcast") == 0) {
diff -ruN ax25-apps-0.0.8-rc2/ax25ipd/HISTORY.ax25ipd ax25-apps-0.0.8-rc2.ax25ipd.dyndns/ax25ipd/HISTORY.ax25ipd
--- ax25-apps-0.0.8-rc2/ax25ipd/HISTORY.ax25ipd 2005-10-30 11:31:40.000000000 +0100
+++ ax25-apps-0.0.8-rc2.ax25ipd.dyndns/ax25ipd/HISTORY.ax25ipd 2010-03-06 14:08:24.000000000 +0100
@@ -53,4 +53,54 @@
* ax25 goes directly to the bpqether interface in the kernel via
* ethertap/tuntap interfaces, which is a much better way than
* traditional kissattach to a ttyp/ptyp pair.
- */
+ *
+ 1.0.5
+ *
+ * added provision for dynamic dns hosts
+ * Steve Fraser vk5asf, June 2005
+ *
+ *
+ 1.0.6
+
+List: linux-hams
+Subject: [PATCH] ax25ipd
+From: Cathryn Mataga <cathryn () junglevision ! com>
+Date: 2009-12-15 23:14:01
+
+I've been sitting on this code for about a week, and it's
+been running fine here. I've made a few small changes, mostly
+to the comments.
+
+1. This patch adds the ability to route packets over axip
+links that are not from the gateway callsign.
+
+2. Integrates the Dynamic DNS patch and uses mutex and
+a thread as suggested.
+
+3. If DNS fails during startup for a route, the IP of a route is set
+to 0. Then later, after about an hour or so, DNS for the
+route is checked again.
+
+4. ax25ipd.conf has two new flags for routes. l and p.
+
+route KE6I-1 0.0.0.0 l
+
+The route to KE6I-1 will be updated based on the IP
+addresses of incoming packets.
+
+route KE6I-2 ke6i.ampr.org p
+
+the 'p' flag forces the code to not recheck DNS later for
+this route. If DNS fails at startup, however, DNS will
+be checked until it succeeds, and then DNS will not be checked
+again.
+
+
+ax25ipd should route as before, except in the case when packets
+not from the callsign of the route but from the same IP
+would have gone to the default route, they now will go to the
+ip from which they originate. (Ugh, that's an awkward sentence.)
+
+Anyway, let me know what you think, good or bad.
+
+*/
diff -ruN ax25-apps-0.0.8-rc2/ax25ipd/io.c ax25-apps-0.0.8-rc2.ax25ipd.dyndns/ax25ipd/io.c
--- ax25-apps-0.0.8-rc2/ax25ipd/io.c 2009-06-14 17:42:11.000000000 +0200
+++ ax25-apps-0.0.8-rc2.ax25ipd.dyndns/ax25ipd/io.c 2010-03-06 11:24:54.000000000 +0100
@@ -378,10 +378,11 @@
if (nb == 0) {
fflush(stdout);
fflush(stderr);
+ update_dns(60*60); // Once/hour
/* just so we go back to the top of the loop! */
continue;
}
-
+ update_dns(60*60); // once/hour
if (FD_ISSET(ttyfd, &readfds)) {
do {
n = read(ttyfd, buf, MAX_FRAME);
@@ -418,7 +419,7 @@
LOGL4("udpdata from=%s port=%d l=%d\n", (char *) inet_ntoa(from. sin_addr), ntohs(from. sin_port), n);
stats.udp_in++;
if (n > 0)
- from_ip(buf, n);
+ from_ip(buf, n, &from);
}
}
/* if udp_mode */
@@ -434,7 +435,7 @@
LOGL4("ipdata from=%s l=%d, hl=%d\n", (char *) inet_ntoa(from. sin_addr), n, hdr_len);
stats.ip_in++;
if (n > hdr_len)
- from_ip(buf + hdr_len, n - hdr_len);
+ from_ip(buf + hdr_len, n - hdr_len, &from);
}
#ifdef USE_ICMP
if (FD_ISSET(icmpsock, &readfds)) {
@@ -461,6 +462,9 @@
if (l <= 0)
return;
+ if (* (unsigned *) targetip == 0){ /* If the ip is set to 0 don't send anything. I'm not sure what sending to 0 does, but I don't like the idea. */
+ return;
+ }
memcpy((char *) &to.sin_addr,
targetip, 4);
memcpy((char *) &to.sin_port,
diff -ruN ax25-apps-0.0.8-rc2/ax25ipd/process.c ax25-apps-0.0.8-rc2.ax25ipd.dyndns/ax25ipd/process.c
--- ax25-apps-0.0.8-rc2/ax25ipd/process.c 2009-06-14 10:07:11.000000000 +0200
+++ ax25-apps-0.0.8-rc2.ax25ipd.dyndns/ax25ipd/process.c 2010-03-06 11:24:58.000000000 +0100
@@ -68,6 +68,7 @@
void from_kiss(unsigned char *buf, int l)
{
unsigned char *a, *ipaddr;
+ unsigned char ipstorage[IPSTORAGESIZE];// Provide storage for the IP. To keep all the locking stuff centralized.
if (l < 15) {
LOGL2("from_kiss: dumped - length wrong!\n");
@@ -105,7 +106,7 @@
} /* end of tnc mode */
/* Lookup the IP address for this route */
- ipaddr = call_to_ip(a);
+ ipaddr = call_to_ip(a, ipstorage);
if (ipaddr == NULL) {
if (is_call_bcast(a)) {
@@ -146,10 +147,11 @@
* We simply send the packet to the KISS send routine.
*/
-void from_ip(unsigned char *buf, int l)
+void from_ip(unsigned char *buf, int l, struct sockaddr_in *ip_addr)
{
int port = 0;
unsigned char *a;
+ unsigned char *f;
if (!ok_crc(buf, l)) {
stats.ip_failed_crc++;
@@ -194,6 +196,10 @@
}
#endif
} /* end of tnc mode */
+
+ f = from_addr(buf);
+ route_process(ip_addr, f);
+
if (!ttyfd_bpq)
send_kiss(port, buf, l);
else {
@@ -277,6 +283,31 @@
}
/*
+ * return 0 if the addresses supplied match
+ * return a positive or negative value otherwise
+ */
+int addrcompare(unsigned char *a, unsigned char *b)
+{
+ signed char diff;
+
+ if ((diff = (signed char )((*a++ - *b++) & 0xfe)))
+ return diff; /* "K" */
+ if ((diff = (signed char )((*a++ - *b++) & 0xfe)))
+ return diff; /* "A" */
+ if ((diff = (signed char )((*a++ - *b++) & 0xfe)))
+ return diff; /* "9" */
+ if ((diff = (signed char )((*a++ - *b++) & 0xfe)))
+ return diff; /* "W" */
+ if ((diff = (signed char )((*a++ - *b++) & 0xfe)))
+ return diff; /* "S" */
+ if ((diff = (signed char )((*a++ - *b++) & 0xfe)))
+ return diff; /* "B" */
+ if ((diff = (signed char )((*a++ - *b++) & 0xfe)))
+ return diff; /* ssid */
+ return 0;
+}
+
+/*
* return pointer to the next station to get this packet
*/
unsigned char *next_addr(unsigned char *f)
@@ -301,6 +332,32 @@
}
/*
+ * return pointer to the last station this packet came from
+ */
+unsigned char *from_addr(unsigned char *f)
+{
+ unsigned char *a;
+
+ a = f + 7;
+/* If no digis, return the source address */
+ if (NO_DIGIS(f))
+ return a;
+
+/* check each digi field. Go to last that has seen it */
+ do
+ a += 7;
+ while (NOT_LAST(a) && REPEATED(a));
+
+/* in DIGI mode: we have set REPEATED already, so the one before is it */
+ if (digi || !REPEATED(a))
+ a -= 7;
+
+/* in TNC mode: always the last is it */
+ return a;
+}
+
+
+/*
* tack on the CRC for the frame. Note we assume the buffer is long
* enough to have the two bytes tacked on.
*/
diff -ruN ax25-apps-0.0.8-rc2/ax25ipd/routing.c ax25-apps-0.0.8-rc2.ax25ipd.dyndns/ax25ipd/routing.c
--- ax25-apps-0.0.8-rc2/ax25ipd/routing.c 2009-06-14 10:07:11.000000000 +0200
+++ ax25-apps-0.0.8-rc2.ax25ipd.dyndns/ax25ipd/routing.c 2010-03-06 17:13:34.000000000 +0100
@@ -12,6 +12,8 @@
#include <netinet/in.h>
#include <memory.h>
#include <syslog.h>
+#include <string.h>
+#include <pthread.h>
/* The routing table structure is not visible outside this module. */
@@ -23,6 +25,7 @@
unsigned char pad1;
unsigned char pad2;
unsigned int flags; /* route flags */
+ char *hostnm; /* host name */
struct route_table_entry *next;
};
@@ -38,16 +41,31 @@
struct bcast_table_entry *bcast_tbl;
+struct callsign_lookup_entry {
+ unsigned char callsign[7];
+ struct route_table_entry *route;
+ struct callsign_lookup_entry *prev, *next;
+};
+
+struct callsign_lookup_entry *callsign_lookup;
+
+time_t last_dns_time;
+volatile int threadrunning;
+pthread_mutex_t dnsmutex = PTHREAD_MUTEX_INITIALIZER;
+
/* Initialize the routing module */
void route_init(void)
{
route_tbl = NULL;
default_route = NULL;
bcast_tbl = NULL;
+ callsign_lookup = NULL;
+ last_dns_time = time(NULL);
+ threadrunning = 0;
}
/* Add a new route entry */
-void route_add(unsigned char *ip, unsigned char *call, int udpport,
+void route_add(char *host, unsigned char *ip, unsigned char *call, int udpport,
unsigned int flags)
{
struct route_table_entry *rl, *rn;
@@ -75,6 +93,7 @@
rn->callsign[i] = call[i] & 0xfe;
rn->callsign[6] = (call[6] & 0x1e) | 0x60;
rn->padcall = 0;
+ rn->hostnm = strdup(host);
memcpy(rn->ip_addr, ip, 4);
rn->udp_port = htons(udpport);
rn->pad1 = 0;
@@ -100,6 +119,130 @@
return;
}
+/* For route rn, a different IP is being used. Trigger a DNS check.
+ * as long as DNS hasn't been checked within 5 minutes (300 seconds)
+ * */
+void route_updatedyndns(struct sockaddr_in *ip_addr, struct route_table_entry *rn)
+{
+ if (rn->flags & AXRT_LEARN){
+ pthread_mutex_lock(&dnsmutex);
+ * (unsigned *) rn->ip_addr = (unsigned) ip_addr->sin_addr.s_addr;
+ pthread_mutex_unlock(&dnsmutex);
+ }
+ if (!(rn->flags & AXRT_PERMANENT)){
+ LOGL4("received changed ip: %s", call_to_a(rn->callsign));
+ update_dns(300);
+ }
+}
+
+/* Save the calls in a binary tree. This code links new callsigns
+ * back to an existing route. No new routes are created. */
+void route_updatereturnpath(unsigned char *mycall, struct route_table_entry *rn)
+{
+ struct callsign_lookup_entry **clookupp = &callsign_lookup;
+ struct callsign_lookup_entry *clookup = callsign_lookup;
+ for (;;){
+ int chk;
+ if (!clookup){
+ clookup = *clookupp = calloc(sizeof(struct callsign_lookup_entry), 1);
+ memcpy(clookup->callsign, mycall, 7);
+ LOGL4("added return route: %s %s %s %d\n",
+ call_to_a(mycall),
+ (char *) inet_ntoa(*(struct in_addr *) rn->ip_addr),
+ rn->udp_port ? "udp" : "ip", ntohs(rn->udp_port));
+
+ clookup->route = rn;
+ return;
+ }
+ chk = addrcompare(mycall, clookup->callsign);
+ if (chk > 0){
+ clookupp = &clookup->next;
+ clookup = *clookupp;
+ }
+ else if (chk < 0){
+ clookupp = &clookup->prev;
+ clookup = *clookupp;
+ }
+ else{
+
+ if (clookup->route != rn){
+ clookup->route = rn;
+ }
+ return;
+ }
+ }
+
+
+}
+
+
+/* Compare ip_addr to the format used by route_table_entry */
+int route_ipmatch(struct sockaddr_in *ip_addr, unsigned char *routeip)
+{
+ unsigned char ipstorage[IPSTORAGESIZE];
+ return (unsigned) ip_addr->sin_addr.s_addr == * (unsigned *) retrieveip(routeip, ipstorage);
+}
+
+
+/* Process calls and ip addresses for routing. The idea behind
+ * this code that for the routes listed in the ax25ipd.conf file,
+ * only DNS or the given IP's should be used. But for calls
+ * that are not referenced in ax25ipd.conf that arrive using
+ * a known gateway IP, the code links them back to that gateway.
+ *
+ * No new routes are created. If a callsign comes in from an
+ * unknown gateway, it will not create an entry.
+ *
+ * if the Callsign for a known route is received, and it does
+ * not match the current ip for that route, the update_dns code
+ * is triggered, which should fix the IP based on DNS.
+ *
+ * */
+void route_process(struct sockaddr_in *ip_addr, unsigned char *call)
+{
+ struct route_table_entry *rp;
+ unsigned char mycall[7];
+ int i;
+ int isroute;
+
+ if (call == NULL)
+ return;
+
+ for (i = 0; i < 6; i++)
+ mycall[i] = call[i] & 0xfe;
+
+ mycall[6] = (call[6] & 0x1e) | 0x60;
+
+ rp = route_tbl;
+ isroute = 0;
+ while (rp) {
+ if (addrmatch(mycall, rp->callsign)) {
+ if (!route_ipmatch(ip_addr, rp->ip_addr)) {
+ route_updatedyndns(ip_addr, rp);
+ }
+ isroute = 1;
+ }
+ rp = rp->next;
+ }
+
+ // Don't use any of the ip lookup code for the routes.
+ // Also, do not set return paths for broadcast callsigns.
+ // Not sure if this ever happens. But it's no good if it does.
+ if (!isroute && !is_call_bcast(call)){
+ rp = route_tbl;
+ while (rp) {
+ // Only do this once.
+ if (route_ipmatch(ip_addr, rp->ip_addr)) {
+ route_updatereturnpath(mycall, rp);
+ break;
+ }
+ rp = rp->next;
+ }
+ }
+
+}
+
+
/* Add a new broadcast address entry */
void bcast_add(unsigned char *call)
{
@@ -136,17 +279,35 @@
}
/*
+ * It's possible that the thread will update the IP in mid
+ * memcpy of an ip address, so I changed all the references to
+ * route_table_entry->ip_addr to use this routine
+
+ * Note that the printfs don't check this
+ */
+
+unsigned char *retrieveip(unsigned char *ip, unsigned char *ipstorage)
+{
+ if (!ipstorage)return ip;
+ pthread_mutex_lock(&dnsmutex);
+ memcpy((void *) ipstorage, (void *) ip, IPSTORAGESIZE);
+ pthread_mutex_unlock(&dnsmutex);
+ return ipstorage;
+}
+
+/*
* Return an IP address and port number given a callsign.
* We return a pointer to the address; the port number can be found
* immediately following the IP address. (UGLY coding; to be fixed later!)
*/
-
-unsigned char *call_to_ip(unsigned char *call)
+
+unsigned char *call_to_ip(unsigned char *call, unsigned char *ipstorage)
{
struct route_table_entry *rp;
unsigned char mycall[7];
int i;
-
+ struct callsign_lookup_entry *clookup;
+
if (call == NULL)
return NULL;
@@ -163,11 +324,35 @@
LOGL4("found ip addr %s\n",
(char *) inet_ntoa(*(struct in_addr *)
rp->ip_addr));
- return rp->ip_addr;
+ return retrieveip(rp->ip_addr, ipstorage);
}
rp = rp->next;
}
+ /* Check for callsigns that have been heard on known routes */
+ clookup = callsign_lookup;
+ for (;;){
+ int chk;
+ if (!clookup){
+ break;
+ }
+ chk = addrcompare(mycall, clookup->callsign);
+ if (chk > 0){
+ clookup = clookup->next;
+ }
+ else if (chk < 0){
+ clookup = clookup->prev;
+ }
+ else{
+ LOGL4("found cached ip addr %s\n",
+ (char *) inet_ntoa(*(struct in_addr *)
+ clookup->route->ip_addr));
+
+ return retrieveip(clookup->route->ip_addr, ipstorage);
+ }
+ }
+
+
/*
* No match found in the routing table, use the default route if
* we have one defined.
@@ -176,7 +361,7 @@
LOGL4("failed, using default ip addr %s\n",
(char *) inet_ntoa(*(struct in_addr *)
default_route->ip_addr));
- return default_route->ip_addr;
+ return retrieveip(default_route->ip_addr, ipstorage);
}
LOGL4("failed.\n");
@@ -223,7 +408,9 @@
rp = route_tbl;
while (rp) {
if (rp->flags & AXRT_BCAST) {
- send_ip(buf, l, rp->ip_addr);
+ unsigned char ipstorage[IPSTORAGESIZE];
+
+ send_ip(buf, l, retrieveip(rp->ip_addr, ipstorage));
}
rp = rp->next;
}
@@ -242,7 +429,7 @@
rp = route_tbl;
while (rp) {
- LOGL1(" %s\t%s\t%s\t%d\t%d\n",
+ LOGL1(" %s %s %s %d %d\n",
call_to_a(rp->callsign),
(char *) inet_ntoa(*(struct in_addr *) rp->ip_addr),
rp->udp_port ? "udp" : "ip",
@@ -251,3 +438,60 @@
}
fflush(stdout);
}
+
+/* Update the IPs of DNS entries for all routes */
+void *update_dnsthread(void *arg)
+{
+ struct hostent *he;
+ struct route_table_entry *rp;
+
+ rp = route_tbl;
+ while (rp) {
+ // If IP is 0, DNS lookup failed at startup.
+ // So check DNS even though it's permanent.
+ // I think checking the lock on this ip_addr reference
+ // isn't needed since the main code doesn't change
+ // ip_addr after startup, and worst case is that it
+ // does one extra dns check
+ if ((rp->hostnm[0]) &&
+ (!(rp->flags & AXRT_PERMANENT) || ( * (unsigned *) rp->ip_addr == 0) )){
+ LOGL4("Checking DNS for %s\n", rp->hostnm);
+ he = gethostbyname(rp->hostnm);
+ if (he != NULL) {
+ pthread_mutex_lock(&dnsmutex);
+ * (unsigned *) rp->ip_addr = * (unsigned *) he->h_addr_list[0];
+ pthread_mutex_unlock(&dnsmutex);
+ LOGL4("DNS returned IP=%s\n", (char *) inet_ntoa(*(struct in_addr *) rp->ip_addr));
+ }
+ }
+ rp = rp->next;
+ }
+ threadrunning = 0;
+ pthread_exit(0);
+ return 0;
+}
+
+/* check DNS for route IPs. Packets from system whose ip
+ * has changed trigger a DNS lookup. The
+ * the timer is needed when both systems are on dynamic
+ * IPs and they both reset at about the same time. Also
+ * when the IP changes immediately, but DNS lags.
+ */
+void update_dns(unsigned wait)
+{
+ pthread_t dnspthread;
+ int rc;
+
+ if (threadrunning)return;// Don't start a thread when one is going already.
+ if (wait && (time(NULL) < last_dns_time + wait))return;
+ threadrunning = 1;
+ LOGL4("Starting DNS thread\n");
+ last_dns_time = time(NULL);
+ rc = pthread_create(&dnspthread, NULL, update_dnsthread, (void *) 0);
+ if (rc){
+ LOGL1(" Thread err%d\n", rc); // Should we exit here?
+ threadrunning = 0;
+ }
+
+}
+
diff -ruN ax25-apps-0.0.8-rc2/ax25ipd/run.bat ax25-apps-0.0.8-rc2.ax25ipd.dyndns/ax25ipd/run.bat
--- ax25-apps-0.0.8-rc2/ax25ipd/run.bat 1970-01-01 01:00:00.000000000 +0100
+++ ax25-apps-0.0.8-rc2.ax25ipd.dyndns/ax25ipd/run.bat 2010-03-06 11:24:58.000000000 +0100
@@ -0,0 +1,2 @@
+killall ax25ipd
+./ax25ipd -c /etc/ax25/ax25ipd.conf
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: [PATCH] ax25ipd
2010-03-06 18:13 [PATCH] ax25ipd Bernard Pidoux
@ 2010-03-06 19:30 ` Bernard Pidoux
0 siblings, 0 replies; 3+ messages in thread
From: Bernard Pidoux @ 2010-03-06 19:30 UTC (permalink / raw)
To: Cathryn Mataga; +Cc: linux-hams
Hi,
Sorry, I forgot to include the patch of configure file.
--- ax25-apps-0.0.8-rc2/configure 2009-06-21 20:18:29.000000000 +0200
+++ ax25-apps-0.0.8-rc2.ax25ipd.dyndns/configure 2010-03-06
13:59:19.000000000 +0100
@@ -13437,7 +13437,7 @@
if test "x$GCC" = "xyes"; then
if test -z "`echo "$CFLAGS" | grep "\-Wall" 2> /dev/null`" ; then
- CFLAGS="$CFLAGS -Wall"
+ CFLAGS="$CFLAGS -Wall -pthread"
fi
fi
Bernard Pidoux
^ permalink raw reply [flat|nested] 3+ messages in thread
[parent not found: <S1752195AbZK3HxQ/20091130075316Z+372@vger.kernel.org>]
* nr0 doesn't show up (netrom)
[not found] <S1752195AbZK3HxQ/20091130075316Z+372@vger.kernel.org>
@ 2009-11-30 20:38 ` Cathryn Mataga
2009-11-30 21:13 ` Cathryn Mataga
0 siblings, 1 reply; 3+ messages in thread
From: Cathryn Mataga @ 2009-11-30 20:38 UTC (permalink / raw)
To: Linux Hams Mailing list
On Fedora 12. Kernel 2.6.31.5-127.fc12.i686 I install
libax25,ax25-apps, and ax25-tools via yum. I created my
nrports file as follows. nrattach says it's creating
nr0, but then it says it creates nr0 again. ifconfig
never shows nr0.
(Actually, otherwise this combination of software is working
correctly so far, and I am able to connect to ax25 stations
over actual RF.)
[root@junglevision ax25]# modprobe netrom
[root@junglevision ax25]# cat nrports
netrom KE6I-10 BERK 236 Berkeley
netrom2 KE6I-11 BRKBBS 236 Berkeley BBS
[root@junglevision ax25]# nrattach -i 192.168.0.10 netrom
NET/ROM port netrom bound to device nr0
[root@junglevision ax25]# nrattach -i 192.168.0.11 netrom2
NET/ROM port netrom2 bound to device nr0
[root@junglevision ax25]# /sbin/ifconfig
eth0 Link encap:Ethernet HWaddr 00:13:20:12:68:A4
inet addr:75.101.49.34 Bcast:75.101.49.63 Mask:255.255.255.224
inet6 addr: fe80::213:20ff:fe12:68a4/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:2572078 errors:0 dropped:0 overruns:0 frame:0
TX packets:4287069 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:682027869 (650.4 MiB) TX bytes:4048632775 (3.7 GiB)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:2318600 errors:0 dropped:0 overruns:0 frame:0
TX packets:2318600 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:3228300929 (3.0 GiB) TX bytes:3228300929 (3.0 GiB)
virbr0 Link encap:Ethernet HWaddr 5A:7F:B7:E8:BC:C4
inet addr:192.168.122.1 Bcast:192.168.122.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:26 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 b) TX bytes:5517 (5.3 KiB)
[root@junglevision ax25]#
Messages doesn't show much. Just
NET: Registered protocol family 3
NET: Registered protocol family 6
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: nr0 doesn't show up (netrom)
2009-11-30 20:38 ` nr0 doesn't show up (netrom) Cathryn Mataga
@ 2009-11-30 21:13 ` Cathryn Mataga
2009-11-30 21:48 ` Cathryn Mataga
0 siblings, 1 reply; 3+ messages in thread
From: Cathryn Mataga @ 2009-11-30 21:13 UTC (permalink / raw)
To: Linux Hams Mailing list
A little bit more information.
I can bring up a nr0 device by doing
/sbin/ifconfig nr0 up 192.168.0.10
But any attempts to set the hardware address fail.
/sbin/ifconfig nr0 hw ax25 KE6I-10 192.168.0.10
Give me
SIOCSIFHWADDR: Invalid argument
I don't think it works this way, because netromd then
tells me "no NET/ROM ports defined"
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: nr0 doesn't show up (netrom)
2009-11-30 21:13 ` Cathryn Mataga
@ 2009-11-30 21:48 ` Cathryn Mataga
2009-12-01 6:05 ` Cathryn Mataga
0 siblings, 1 reply; 3+ messages in thread
From: Cathryn Mataga @ 2009-11-30 21:48 UTC (permalink / raw)
To: Linux Hams Mailing list
Oops. Looking through the proper archive of linux hams I found this.
>nrattach.c
>
>#ifndef notdef
> if (!startiface(dev, hp))
> return 1;
>#endif
> printf("NET/ROM port %s bound to device %s\n", argv[optind], dev);
>However, if notdef is defined somewhere, there will be again no netrom device
>created, but a false success message will still be displayed.
>I don't really understand the purpose of this.
I think somebody just screwed up and committed this by accident.
Just remove that ifdef and endif. (I suggest.)
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: nr0 doesn't show up (netrom)
2009-11-30 21:48 ` Cathryn Mataga
@ 2009-12-01 6:05 ` Cathryn Mataga
2009-12-07 10:30 ` ax25ipd.c routing Cathryn Mataga
0 siblings, 1 reply; 3+ messages in thread
From: Cathryn Mataga @ 2009-12-01 6:05 UTC (permalink / raw)
To: Linux Hams Mailing list
For the record, I actually managed to connect to another NETROM
site over actual RF after fixing nrattach.c and recompiling. It's acting
kind of slow but I need to do some conventional AX25 tweaking
first before I can claim anything is actually broken here. This is
a new install, using the rc2 files on the site.
I'm still dependent on the BSD style pty's, and it looks like
the utilities have been updated to get around this, so I have to
put in some time to see if I can run a completely stock
kernel from Fedora, which would be nice.
Generally, it's looking good so far though.
^ permalink raw reply [flat|nested] 3+ messages in thread
* ax25ipd.c routing
2009-12-01 6:05 ` Cathryn Mataga
@ 2009-12-07 10:30 ` Cathryn Mataga
2009-12-07 16:25 ` Thomas Osterried
0 siblings, 1 reply; 3+ messages in thread
From: Cathryn Mataga @ 2009-12-07 10:30 UTC (permalink / raw)
To: Linux Hams Mailing list
How does this work with multiple connections?
Suppose I have two incoming connections
My call is K1BBS.
route K1PAR 1.0.0.0
route K2PAR 2.0.0.0 d
Then suppose K1USR at K1PAR does a connect to K1BBS.
What seems to happen is I see packets come in from K1USR to K1BBS.
But then when packets go back out, they go back to K2PAR, even though
he's at K1PAR. At least that's what I think is happening.
Shouldn't ax25d.c keep a record of which IP callsigns came from, so that
way when it needs to send a packet back they go to the right place?
I'm not 100% sure of this, but it seems like the lookup only checks
the route commands. I only see one call to route_add in config.c.
Shouldn't it 'route_add' every time a callsign comes in axip?
Or the only way to make this work is to run a separate
ax25ipd for every connection.
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: ax25ipd.c routing
2009-12-07 10:30 ` ax25ipd.c routing Cathryn Mataga
@ 2009-12-07 16:25 ` Thomas Osterried
2009-12-07 20:02 ` Cathryn Mataga
0 siblings, 1 reply; 3+ messages in thread
From: Thomas Osterried @ 2009-12-07 16:25 UTC (permalink / raw)
To: Cathryn Mataga; +Cc: linux-hams
On 2009-12-07 02:30:27 -0800, Cathryn Mataga <cathryn@junglevision.com>
wrote in <4B1CD943.6030808@junglevision.com>:
> How does this work with multiple connections?
>
> Suppose I have two incoming connections
> My call is K1BBS.
>
> route K1PAR 1.0.0.0
> route K2PAR 2.0.0.0 d
>
> Then suppose K1USR at K1PAR does a connect to K1BBS.
>
> What seems to happen is I see packets come in from K1USR to K1BBS.
> But then when packets go back out, they go back to K2PAR, even though
> he's at K1PAR. At least that's what I think is happening.
>
> Shouldn't ax25d.c keep a record of which IP callsigns came from, so that
> way when it needs to send a packet back they go to the right place?
> I'm not 100% sure of this, but it seems like the lookup only checks
> the route commands. I only see one call to route_add in config.c.
ax25ipd in it's current version does not learn routes.
In fact, route_add() is only being called from the config file.
.../ax25-apps/ax25ipd$ grep route_add *.c
config.c: route_add(tip, tcall, uport, flags);
routing.c:void route_add(unsigned char *ip, unsigned char *call, int udpport,
.../ax25-apps/ax25ipd$
That's why your packet goes out via the default connection (route K2PAR
2.0.0.0 d).
At db0fhn we have since several years a modified version:
...ax25ipd-test/ax25ipd$ grep route_add *.c
config.c: route_add(&tip, htonl(tmask), fqdn, tcall, (flags | AXRT_FORCE_LEARN | (match_all_ssids ? AXRT_MATCH_ALL_SSIDS : 0)));
process.c: if (route_add(ip_addr, 0xffffffffUL, 0, f, 0) < 0) {
process.c:fprintf(stderr, "debug: route_add %s failed\n", call_to_a(from_addr(buf)));
process.c:fprintf(stderr, "debug: route_add %s ok\n", call_to_a(from_addr(buf)));
routing.c:int route_add(ip, netmask, fqdn, call, flags)
...ax25ipd-test/ax25ipd$
The code I wrote is highly stable. But I personaly found the code quite
ugly: ax25ipd became a monster. That's the reason why it did not enter
the main stream yet.
From the example ax25ipd.conf:
[..]
# route <destcall> [<destaddr>|<network>] [udp dst-port] [flags]
#
# Users behind NAT routers may hav a different source-port.
#
# Valid flags are:
# b - allow broadcasts to be transmitted via this route
# d - this route is the default route
# p - permanent
#
#route vk2sut-0 44.136.8.68 b
#route vk5xxx 44.136.188.221 b
#route vk2abc 44.1.1.1
#route db0aaa 127.0.0.1 p
#route db0aab 10.1.2.3 udp 20005
# For dyndns hosts: IP may change, but resolving of the hostname
# has to point to the same IP address where IP frames come from.
# If flag "p" is set, the host is static (resolved once, on startup).
#route db0abc db0abc.de
#
# Autolearn new (not configured) hosts.
# Valid flags in this case: "b", "p" (learn once).
#route db0abc db0abc.de
#
# Autolearn new (not configured) hosts.
# Valid flags in this case: "b", "p" (learn once).
#route * 0.0.0.0/0 b
#route * 10.1.0.0/16
#route * 10.2.2.2/32
# accept db0yyy only when coming vom 10.3.3.0/24
#route db0yyy 10.3.3.0/24
At db0fhn, that ax25ipd version is used for various purposes:
root 2648 0.1 0.0 1692 240 ? S Aug19 262:49 /usr/sbin/ax25ipd --nofork -c /etc/ax25/ax25ipd-xnet.conf
root 3199 0.0 0.0 3488 732 ? Ss Aug19 101:58 /usr/bin/SCREEN -dmS ax25ipd -c /etc/ax25/ax25ipd.screen
root 3201 0.0 0.0 1692 248 pts/1 Ss+ Aug19 31:42 /usr/sbin/ax25ipd --nofork -c /etc/ax25/ax25ipd-pptpvpn.conf
root 3202 0.0 0.0 1696 252 pts/2 Ss+ Aug19 68:27 /usr/sbin/ax25ipd --nofork -c /etc/ax25/ax25ipd-openvpn.conf
root 3203 0.0 0.0 1696 272 pts/3 Ss+ Aug19 120:03 /usr/sbin/ax25ipd --nofork -c /etc/ax25/ax25ipd-echolink.conf
root 3643 0.0 0.0 1692 236 pts/4 Ss+ Aug19 15:45 ax25ipd --nofork -c /etc/ax25/ax25ipd-aprs-db0vox.conf
root 3644 0.0 0.0 1692 232 pts/5 Ss+ Aug19 2:12 ax25ipd --nofork -c /etc/ax25/ax25ipd-aprs-db0sao.conf
root 3645 0.0 0.0 1692 236 pts/6 Ss+ Aug19 3:16 ax25ipd --nofork -c /etc/ax25/ax25ipd-aprs-db0prt.conf
root 3649 0.0 0.0 1692 236 pts/7 Ss+ Aug19 11:33 ax25ipd --nofork -c /etc/ax25/ax25ipd-aprs-db0zka.conf
Btw, the dyndns feature which Bernard Pidoux f6bvp reminded to a few weeks ago
is still the my queue.
I've -mostly theoretical- problems with it because it resolves on a
periodical basis, which means that if the dns currently is broken,
it even affects LAN connections served by ax25ipd by introducing periodical
delays.
Bernard changed route_add(), as also my test-version does, but in a slightly
different way.
The test-code also implements periodical dyndns resolving, but iirc, it does
not work correctly (can't remember).
For informational purpose, I did a diff between the current cvs head
and the test version. The test-version startet on an older ax25ipd
version and only fixes but no cosmetic changes have been manually applied
(also i.e. still not the unix98 pty support). Here it is:
http://db0fhn.efi.fh-nuernberg.de/~dl9sau/ax25ipd-current-to-test--2009-12-07.diff
73,
- Thomas dl9sau
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: ax25ipd.c routing
2009-12-07 16:25 ` Thomas Osterried
@ 2009-12-07 20:02 ` Cathryn Mataga
2009-12-07 20:26 ` Thomas Osterried
0 siblings, 1 reply; 3+ messages in thread
From: Cathryn Mataga @ 2009-12-07 20:02 UTC (permalink / raw)
To: Thomas Osterried; +Cc: linux-hams
> ax25ipd in it's current version does not learn routes.
> In fact, route_add() is only being called from the config file.
> .../ax25-apps/ax25ipd$ grep route_add *.c
> config.c: route_add(tip, tcall, uport, flags);
> routing.c:void route_add(unsigned char *ip, unsigned char *call, int udpport,
> .../ax25-apps/ax25ipd$
>
> That's why your packet goes out via the default connection (route K2PAR
> 2.0.0.0 d).
>
Thank you. This confirms my understanding of the current issue.
>
> Btw, the dyndns feature which Bernard Pidoux f6bvp reminded to a few weeks ago
> is still the my queue.
> I've -mostly theoretical- problems with it because it resolves on a
> periodical basis, which means that if the dns currently is broken,
> it even affects LAN connections served by ax25ipd by introducing periodical
> delays.
> Bernard changed route_add(), as also my test-version does, but in a slightly
> different way.
> The test-code also implements periodical dyndns resolving, but iirc, it does
> not work correctly (can't remember).
Hmm.
What about this for both my and Bernard's issue.
1. If a callsign is received from the ip of a known route
but is not the callsign of a known route, or the callsign
of the local station, then add this callsign
and the route pointer to a binary tree. If the callsign
was previously in the tree, then the new route replaces
the old one, if different.
2. in call_to_ip, before it checks the default route,
it checks this binary tree for this callsign, and returns the
route it came from. If the callsign is not found, the default
route is used.
3. Callsigns never expire. The tree just grows.
4. SSID's are matched as unique callsigns.
5. If the callsign is that of a ddns route,
Fork, check dns, and if the ip matches the dns,
update the route_table_entry->ip_addr
6. If a process is already forked for updating the ip of
a particular route, do not fork another one. Add
a variable to route_table_entry to verify this.
Does this make sense? Or are there other issues I'm unaware
of?
>
> For informational purpose, I did a diff between the current cvs head
> and the test version. The test-version startet on an older ax25ipd
> version and only fixes but no cosmetic changes have been manually applied
> (also i.e. still not the unix98 pty support). Here it is:
> http://db0fhn.efi.fh-nuernberg.de/~dl9sau/ax25ipd-current-to-test--2009-12-07.diff
Alright, thanks. I'll take a look.
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: ax25ipd.c routing
2009-12-07 20:02 ` Cathryn Mataga
@ 2009-12-07 20:26 ` Thomas Osterried
[not found] ` <4B1D84C4.8000206@exemail.com.au>
0 siblings, 1 reply; 3+ messages in thread
From: Thomas Osterried @ 2009-12-07 20:26 UTC (permalink / raw)
To: Cathryn Mataga; +Cc: linux-hams
Hello,
> What about this for both my and Bernard's issue.
>
> 1. If a callsign is received from the ip of a known route
> but is not the callsign of a known route, or the callsign
> of the local station, then add this callsign
> and the route pointer to a binary tree. If the callsign
> was previously in the tree, then the new route replaces
> the old one, if different.
yes. And if not set to "permanent" (p).
> 2. in call_to_ip, before it checks the default route,
> it checks this binary tree for this callsign, and returns the
> route it came from. If the callsign is not found, the default
> route is used.
yes.
> 3. Callsigns never expire. The tree just grows.
yes.
> 4. SSID's are matched as unique callsigns.
call + same-ssid unique.
If you like to route i.E. ssid 0 to 15 permanently to a specific host,
it's only 16 lines. That's ok.
> 5. If the callsign is that of a ddns route,
> Fork, check dns, and if the ip matches the dns,
> update the route_table_entry->ip_addr
No. Don't fork.
The best solution is a posix thread, which does periodicaly the resolving,
and to use a mutex-lock in the special case an IP address is currently being
looked up.
> 6. If a process is already forked for updating the ip of
> a particular route, do not fork another one. Add
> a variable to route_table_entry to verify this.
A single thread is sufficient.
73,
- Thomas
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2010-03-06 19:30 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-03-06 18:13 [PATCH] ax25ipd Bernard Pidoux
2010-03-06 19:30 ` Bernard Pidoux
[not found] <S1752195AbZK3HxQ/20091130075316Z+372@vger.kernel.org>
2009-11-30 20:38 ` nr0 doesn't show up (netrom) Cathryn Mataga
2009-11-30 21:13 ` Cathryn Mataga
2009-11-30 21:48 ` Cathryn Mataga
2009-12-01 6:05 ` Cathryn Mataga
2009-12-07 10:30 ` ax25ipd.c routing Cathryn Mataga
2009-12-07 16:25 ` Thomas Osterried
2009-12-07 20:02 ` Cathryn Mataga
2009-12-07 20:26 ` Thomas Osterried
[not found] ` <4B1D84C4.8000206@exemail.com.au>
[not found] ` <20091207235111.GS19524@x-berg.in-berlin.de>
2009-12-08 22:15 ` Cathryn Mataga
2009-12-15 23:14 ` [PATCH] ax25ipd Cathryn Mataga
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.