ax25-apps/0002755000000000000620000000000012143214257011427 5ustar rootstaffax25-apps/ax25rtd/0002755000000000000620000000000012143214257012720 5ustar rootstaffax25-apps/ax25rtd/cache_dump.c0000644000000000000620000000767211221516577015174 0ustar rootstaff/* $Id: cache_dump.c,v 1.4 2009/06/27 22:30:23 ralf Exp $ * * Copyright (c) 1996 Joerg Reuter (jreuter@poboxes.com) * * 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 * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include #include #include #include #include #include #include #include #include #include #include #include "ax25rtd.h" void dump_ip_routes(int fd, int cmd) { ip_rt_entry *bp; config *config; char buf[256], *dev; unsigned long ip; int len; for (bp = ip_routes; bp; bp = bp->next) { ip = htonl(bp->ip); if (cmd) { len = sprintf(buf, "add ip "); dev = bp->iface; } else { len = 0; config = dev_get_config(bp->iface); if (config != NULL) dev = config->port; else dev = bp->iface; } len += sprintf(buf + len, "%d.%d.%d.%d", (int) ((ip & 0xFF000000) >> 24), (int) ((ip & 0x00FF0000) >> 16), (int) ((ip & 0x0000FF00) >> 8), (int) (ip & 0x000000FF)); len += sprintf(buf + len, " %-4s %8.8lx %-9s ", dev, bp->timestamp, ax25_ntoa(&bp->call)); if (bp->invalid) len += sprintf(buf + len, "X\n"); else len += sprintf(buf + len, "%c\n", bp->ipmode ? 'v' : 'd'); write(fd, buf, len); } if (!cmd) write(fd, ".\n", 2); } void dump_ax25_routes(int fd, int cmd) { ax25_rt_entry *bp; config *config; char buf[256], *dev; int k, len; for (bp = ax25_routes; bp; bp = bp->next) { if (cmd) { len = sprintf(buf, "add ax25 "); dev = bp->iface; } else { len = 0; config = dev_get_config(bp->iface); if (config != NULL) dev = config->port; else dev = bp->iface; } len += sprintf(buf + len, "%-9s %-4s %8.8lx", ax25_ntoa(&bp->call), dev, bp->timestamp); for (k = 0; k < bp->ndigi; k++) len += sprintf(buf + len, " %s", ax25_ntoa(&bp->digipeater[k])); len += sprintf(buf + len, "\n"); write(fd, buf, len); } if (!cmd) write(fd, ".\n", 2); } void dump_config(int fd) { config *config; int k; fprintf(stderr, "config:\n"); for (config = Config; config; config = config->next) { fprintf(stderr, "Device = %s\n", config->dev); fprintf(stderr, "Port = %s\n", config->port); fprintf(stderr, "ax25_add_route = %d\n", config->ax25_add_route); fprintf(stderr, "ax25_for_me = %d\n", config->ax25_for_me); fprintf(stderr, "ax25_add_default = %d\n", config->ax25_add_default); fprintf(stderr, "ip_add_route = %d\n", config->ip_add_route); fprintf(stderr, "ip_add_arp = %d\n", config->ip_add_arp); fprintf(stderr, "ip_adjust_mode = %d\n", config->ip_adjust_mode); fprintf(stderr, "netmask = %8.8lx\n", config->netmask); fprintf(stderr, "ip = %8.8lx\n", config->ip); fprintf(stderr, "nmycalls = %d\n", config->nmycalls); fprintf(stderr, "calls ="); for (k = 0; k < config->nmycalls; k++) fprintf(stderr, " %s", ax25_ntoa(&config->mycalls[k])); fprintf(stderr, "\n"); fprintf(stderr, "ax25_default_path="); for (k = 0; k < config->ax25_default_path.fsa_ax25.sax25_ndigis; k++) fprintf(stderr, " %s", ax25_ntoa(&config->ax25_default_path. fsa_digipeater[k])); fprintf(stderr, "\n.\n"); } } ax25-apps/ax25rtd/listener.c0000644000000000000620000002663411221516577014730 0ustar rootstaff/* $Id: listener.c,v 1.8 2009/06/27 22:30:23 ralf Exp $ * * Copyright (c) 1996 Joerg Reuter (jreuter@poboxes.com) * * 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 * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* TODO: Should add partial path to ax25_route if we are one of the * digipeaters. */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #ifdef TIME_WITH_SYS_TIME #include #endif #include #include #include #include #include #include #include "../pathnames.h" #include "ax25rtd.h" #include /* FIXME */ static unsigned long get_from_arp(unsigned char *data, int size) { if (size < 16) return 0; return ntohl(0); } static unsigned long get_from_ip(unsigned char *data, int size) { unsigned long adr; if ((*data & 0xf) * 4 < IPLEN) return 0; adr = data[12] << 24; /* NETWORK byte order */ adr += data[13] << 16; adr += data[14] << 8; adr += data[15]; return ntohl(adr); /* HOST byte order */ } int call_is_mycall(config * config, ax25_address * call) { int k; for (k = 0; k < config->nmycalls; k++) if (!memcmp(call, &config->mycalls[k], AXLEN)) return 1; return 0; } /* * This catches *all* invalid callsigns, unlike ax25validate. */ static int check_ax25_addr(unsigned char *buf) { int k; unsigned char c; /* must start with at least one capital letter or digit */ for (k = 0; k < 6; k++) { c = buf[k] >> 1; if (c == ' ') break; if ((c < 'A' || c > 'Z') && (c < '0' || c > '9')) return 1; } /* NULL address is invalid */ if (k == 0) return 1; /* remaining fields must consist of spaces only */ for (k++; k < 6; k++) if (buf[k] >> 1 != ' ') return 1; return 0; } static inline void invert_digipeater_path(ax25_address * digipeater, int ndigi) { int k, m; ax25_address fdigi; if (ndigi == 0) return; for (m = 0, k = ndigi - 1; k > m; k--, m++) { memcpy(&fdigi, &digipeater[m], AXLEN); memcpy(&digipeater[m], &digipeater[k], AXLEN); memcpy(&digipeater[k], &fdigi, AXLEN); } } int set_arp(config * config, long ip, ax25_address * call) { struct sockaddr_in *isa; struct sockaddr_ax25 *asa; struct arpreq arp; int fds; if (!config->ip_add_arp) return 0; fds = socket(AF_INET, SOCK_DGRAM, 0); memset((char *) &arp, 0, sizeof(arp)); isa = (struct sockaddr_in *) &arp.arp_pa; asa = (struct sockaddr_ax25 *) &arp.arp_ha; isa->sin_family = AF_INET; isa->sin_port = 0; isa->sin_addr.s_addr = ip; asa->sax25_family = AF_AX25; asa->sax25_ndigis = 0; asa->sax25_call = *call; arp.arp_flags = ATF_PERM | ATF_COM; strcpy(arp.arp_dev, config->dev); if (ioctl(fds, SIOCSARP, &arp) < 0) { invalidate_ip_route(ip); perror("routspy: SIOCSARP"); close(fds); return 1; } close(fds); return 0; } /* dl9sau: use iproute2 for advanced routing. * Anyone likes to implement this directly, without system()? */ #define RT_DEL 0 #define RT_ADD 1 int iproute2(long ip, char *dev, int what) { char buffer[256]; char ipa[32]; int ret; sprintf(ipa, "%d.%d.%d.%d", (int) (ip & 0x000000FF), (int) ((ip & 0x0000FF00) >> 8), (int) ((ip & 0x00FF0000) >> 16), (int) ((ip & 0xFF000000) >> 24)); /* ip rule add table 44 */ sprintf(buffer, "/sbin/ip route %s %s dev %s table %s proto ax25rtd", (what ? "add" : "del"), ipa, dev, iproute2_table); ret = system(buffer); return ret; } int set_route(config * config, long ip) { struct rtentry rt; struct sockaddr_in *isa; char origdev[16], buf[1024]; /* modif f5lct */ long gwr; /* fin modif f5lct */ long ipr; int fds; FILE *fp; fp = fopen(PROC_IP_ROUTE_FILE, "r"); if (fp == NULL) { invalidate_ip_route(ip); return 1; } fgets(buf, sizeof(buf) - 1, fp); /* discard header */ while (fgets(buf, sizeof(buf) - 1, fp) != NULL) { /* modif f5lct */ /* sscanf(buf, "%s %lx", origdev, &ipr); */ sscanf(buf, "%s %lx %lx", origdev, &ipr, &gwr); if (ipr == ip && gwr == 00000000) /* fin modif f5lct */ { if (dev_get_config(origdev) == NULL) { invalidate_ip_route(ip); fclose(fp); return 1; } else { del_kernel_ip_route(origdev, ip); } } } fclose(fp); if (!config->ip_add_route) return 0; if (iproute2_table && *iproute2_table) return iproute2(ip, config->dev, RT_ADD); fds = socket(AF_INET, SOCK_DGRAM, 0); memset((char *) &rt, 0, sizeof(rt)); isa = (struct sockaddr_in *) &rt.rt_dst; isa->sin_family = AF_INET; isa->sin_port = 0; isa->sin_addr.s_addr = ip; rt.rt_flags = RTF_UP | RTF_HOST; rt.rt_dev = config->dev; if (config->tcp_irtt != 0) { rt.rt_irtt = config->tcp_irtt; rt.rt_flags |= RTF_IRTT; } isa = (struct sockaddr_in *) &rt.rt_genmask; isa->sin_addr.s_addr = 0xffffffff; if (ioctl(fds, SIOCADDRT, &rt) < 0) { invalidate_ip_route(ip); perror("ax25rtd: IP SIOCADDRT"); close(fds); return 1; } close(fds); return 0; } int del_kernel_ip_route(char *dev, long ip) { int fds; struct rtentry rt; struct sockaddr_in *isa; config *config; config = dev_get_config(dev); if (config == NULL || !config->ip_add_route) return 0; if (iproute2_table && *iproute2_table) return iproute2(ip, dev, RT_DEL); fds = socket(AF_INET, SOCK_DGRAM, 0); memset((char *) &rt, 0, sizeof(struct rtentry)); isa = (struct sockaddr_in *) &rt.rt_dst; isa->sin_family = AF_INET; isa->sin_addr.s_addr = ip; rt.rt_flags = RTF_UP | RTF_HOST; rt.rt_dev = dev; if (ioctl(fds, SIOCDELRT, &rt) < 0) { perror("ax25rtd: IP SIOCDELRT"); close(fds); return 1; } close(fds); return 0; } int set_ax25_route(config * config, ax25_rt_entry * rt) { struct ax25_routes_struct ax25_route; int fds, k; if (!config->ax25_add_route) return 0; ax25_route.port_addr = config->mycalls[0]; ax25_route.dest_addr = rt->call; ax25_route.digi_count = rt->ndigi; for (k = 0; k < rt->ndigi; k++) ax25_route.digi_addr[k] = rt->digipeater[k]; fds = socket(AF_AX25, SOCK_SEQPACKET, 0); if (ioctl(fds, SIOCADDRT, &ax25_route) < 0) { perror("ax25rtd: AX.25 SIOCADDRT"); close(fds); return 1; } close(fds); return 0; } int del_kernel_ax25_route(char *dev, ax25_address * call) { struct ax25_routes_struct ax25_route; int fds; config *config; config = dev_get_config(dev); if (config == NULL || !config->ax25_add_route) return 0; ax25_route.port_addr = config->mycalls[0]; ax25_route.dest_addr = *call; fds = socket(AF_AX25, SOCK_SEQPACKET, 0); if (ioctl(fds, SIOCDELRT, &ax25_route) < 0) { perror("ax25rtd: AX.25 SIOCDELRT"); close(fds); return 1; } close(fds); return 0; } int set_ipmode(config * config, ax25_address * call, int ipmode) { struct ax25_route_opt_struct ax25_opt; int fds; if (!config->ip_adjust_mode) return 0; ax25_opt.port_addr = config->mycalls[0]; ax25_opt.dest_addr = *call; ax25_opt.cmd = AX25_SET_RT_IPMODE; ax25_opt.arg = ipmode ? 'V' : 'D'; fds = socket(AF_AX25, SOCK_SEQPACKET, 0); if (ioctl(fds, SIOCAX25OPTRT, &ax25_opt) < 0) { perror("ax25rtd: SIOCAX25OPTRT"); close(fds); return 1; } close(fds); return 0; } /* Yes, the code *IS* ugly... */ #define SKIP(o) {data+=(o); size-=(o);} void ax25_receive(int sock) { unsigned char buf[1500]; unsigned char *data; unsigned long ip; struct sockaddr sa; ax25_address srccall, destcall, digipeater[AX25_MAX_DIGIS]; char extseq = 0; int size, action, ipmode, ctl, pid, ndigi, kdigi, mine; time_t stamp; config *config; ax25_rt_entry *ax25rt; socklen_t asize; asize = sizeof(sa); if ((size = recvfrom(sock, buf, sizeof(buf), 0, &sa, &asize)) < 0) { perror("recvfrom"); save_cache(); daemon_shutdown(1); } stamp = time(NULL); ip = 0; pid = ctl = 0; config = dev_get_config(sa.sa_data); if (config == NULL) return; data = buf; /* * KISS data? */ if ((*data & 0x0f) != 0) return; SKIP(1); /* valid frame? */ if (size < (2 * AXLEN + 1)) return; /* * Get destination callsign */ if (check_ax25_addr(data)) return; memcpy(&destcall, data, AXLEN); destcall.ax25_call[6] &= 0x1e; SKIP(AXLEN); mine = call_is_mycall(config, &destcall); /* * Get Source callsign */ if (check_ax25_addr(data)) return; memcpy(&srccall, data, AXLEN); srccall.ax25_call[6] &= 0x1e; SKIP(ALEN); /* * How long is our control field? */ extseq = ~(*data) & SSSID_SPARE; /* * Extract digipeaters */ ndigi = 0; while (((*data) & HDLCAEB) != HDLCAEB) { SKIP(1); if (size <= 0 || check_ax25_addr(data)) return; if (ndigi < AX25_MAX_DIGIS) memcpy(&digipeater[ndigi++], data, AXLEN); else return; SKIP(ALEN); } SKIP(1); if (size <= 0) return; /* * Get type of frame */ if ((*data & LAPB_S) == LAPB_I) ctl = LAPB_I; else { ctl = *data; if (extseq == 0) ctl &= ~LAPB_PF; } /* * Check if info frame and get PID */ if (ctl == LAPB_I || ctl == LAPB_UI) { SKIP(extseq ? 2 : 1); if (size <= 0) return; /* Get PID */ pid = *data; if (pid == PID_SEGMENT) { SKIP(1); if (size <= 0) return; pid = 0; if (*data && SEG_FIRST) { pid = *data; SKIP(1); if (size <= 0) return; } } } /* * See if it is fully digipeated (TODO: or if we are the next digipeater) */ for (kdigi = 0; kdigi < ndigi; kdigi++) { if ((digipeater[kdigi].ax25_call[6] & AX25_REPEATED) != AX25_REPEATED) return; digipeater[kdigi].ax25_call[6] &= 0x1e; } invert_digipeater_path(digipeater, ndigi); /* * Are we allowed to add it to our routing table? */ if (mine || !config->ax25_for_me) { if (!mine && ndigi == 0 && config->ax25_add_default) { ndigi = config->ax25_default_path.fsa_ax25. sax25_ndigis; for (kdigi = 0; kdigi < ndigi; kdigi++) if (!memcmp (&srccall, &config->ax25_default_path. fsa_digipeater[kdigi], AXLEN)) break; if (ndigi == kdigi) memcpy(digipeater, config->ax25_default_path. fsa_digipeater, ndigi * AXLEN); else ndigi = 0; } ax25rt = update_ax25_route(config, &srccall, ndigi, digipeater, stamp); if (ax25rt != NULL) set_ax25_route(config, ax25rt); } /* * Now see if it carries IP traffic */ switch (pid) { case PID_ARP: SKIP(1); if (size > 0) ip = get_from_arp(data, size); break; case PID_IP: if (!mine) return; SKIP(1); if (size > 0) ip = get_from_ip(data, size); break; default: return; } /* * And adjust routes/arp/ipmode if we are allowed to... */ ipmode = (ctl == LAPB_I); if (ip != 0) { if (*ip_encaps_dev && (config = dev_get_config(ip_encaps_dev)) == NULL) return; action = update_ip_route(config, ip, ipmode, &srccall, stamp); if (action & NEW_ROUTE) if (set_route(config, ip)) return; if (action & NEW_ARP) if (set_arp(config, ip, &srccall)) return; if (action & NEW_IPMODE) if (set_ipmode(config, &srccall, ipmode)) return; } } ax25-apps/ax25rtd/ip_route0000644000000000000620000000000010510716325014454 0ustar rootstaffax25-apps/ax25rtd/TODO.ax25rtd0000644000000000000620000000054107264464315014710 0ustar rootstaff What to do next? - convert the content of README to manual pages - Use partly digipeated frames for the AX.25 routing table if we are the next digipeater - A solution for IP encapsulation mode changes - Support for Flexnet routing information - Support PE1CHL's autorouter (Rob, you promised to send me the specs...) - A similar program for NET/ROM ax25-apps/ax25rtd/ax25_route0000644000000000000620000000000010510716325014623 0ustar rootstaffax25-apps/ax25rtd/ax25rtd.conf.man0000644000000000000620000001161511671232772015643 0ustar rootstaff.TH AX25RTD.CONF 5 "11 November 2003" Linux "Linux Programmer's Manual" .SH NAME ax25rtd.conf \- ax25 routing daemon configuration file .SH SYNOPSIS .B /etc/ax25/ax25rtd.conf .SH DESCRIPTION The file /etc/ax25/ax25rtd.conf is the configuration file for @@@ax25rtd@@@. The parameters of the options shown here are the default values except the ones marked with (example) .PP ax25-maxroutes 4096 .TP ip-maxroutes 4096 The maximum size of the three lists / caches. On overflow, @@@ax25rtd@@@ will substitute the oldest entry with the new one. .TP iproute2-table radio name ("radio") of the kernel routing table. This is an advanced routing feature. If you do not need it, just leave this setting as is. The current implementation depends on iproute2 (anyone like to code it directly?). If not set or empty, routes are set in the normal, default, manner. Please configure /etc/iproute2/rt_protos with 44 @@@ax25rtd@@@ and /etc/iproute2/rt_tables with 210 radio where "radio" is the name of the table, (for the configuration example above). This option is disabled by default. .TP ip-encaps-dev ipax0 This option was for a patched kernel of the 2.2.x series. Multible interfaces were aggregated to one interface when sending IP frames. This option is disabled by default. .TP [1k2] .br This marks the beginning of per-port definitions. Note that you have to use port names as defined in axports(5) here, anywhere else you may use the port or the device name. .TP ax25-learn-routes no Set this to "yes", @@@ax25rtd@@@ will add the routing information for every heard frame (with complete digipeater path) to the kernel AX.25 routing table. Note that @@@ax25rtd@@@'s internal cache will be updated anyway, regardless of this option. .TP ax25-learn-only-mine no If you set it to "yes", only frames that are sent to (1) the interface callsign, (2) any of the listeners on this device, or (3) the callsigns specified by ax25-more-mycalls will be used to update the internal cache and (depending on ax25-learn-routes) the kernel routing table. .TP ax25-add-path db0ach (example) This is useful on DAMA digipeaters. In this case, the DAMA master has to be used for _every_ AX.25 connection, thus @@@ax25rtd@@@ will add this digipeater(s) to every target we learn that has no digipeater path (yet). "db0ach" is just an example here. .TP ax25-more-mycalls dl1bke dl1bke-8 (example) You can specify more calls as calls here that belong to this interface... "dl1bke" and "dl1bke-8" are examples. .TP ip-learn-routes no If set to "yes", @@@ax25rtd@@@ will modify the IP routing table if it receives an IP frame (directed to us). This is dangerous! It should not screw up your routing table, though. @@@Ax25rtd@@@ recognizes the netmask of the device and will adjust the route only if it fits the netmask and the old route points to one of the devices @@@ax25rtd@@@ knows about (hence an AX.25 device). The problems begin if you have more than one port and a user is able to hear your outgoing traffic on at least two of them. Due to technical reasons @@@ax25rtd@@@ adjusts the route _after_ the kernel has sent the reply to the received TCP frame already. This has technical reasons. If the remote does the same both are switching between the two ports. Don't use this feature unless you know what you are doing. It _should_ be safe do enable this on one-port machines, although I strongly recommend to set a network route instead, i.e.: route add -net 44.0.0.0 scc3 Note that @@@ax25rtd@@@'s internal cache will be updated anyway, regardless of this option. .TP irtt If ip-learn-routes is enabled this will assign newly added routes an initial round trip time (IRTT) for TCP. is measured in msec, hence irtt 10000 sets the irtt to 10 seconds. A value of 0 disables this feature (default). .TP ip-adjust-mode no If you set this option to "yes" @@@ax25rtd@@@ will change the IP encapsulation mode according to the last received IP frame. The problem with this option is that the kernel AX.25 sends a received IP frame to the IP layer regardless if it was sent in UI frame encapsulation "mode datagram (dg)" or in I frame encaps, hence in an AX.25 connection, "mode virtual connect (vc)". The Linux kernel will respond to this frame before @@@ax25rtd@@@ can adjust the mode. If the remote does the same... You get the picture. Don't use this feature unless you know what you are doing. .TP arp-add no This option, if set to "yes", changes the ARP table to the source callsign of the received frame. It should be harmless, just has the the effect that if it is a new entry, the Linux ARP code will send one ARP request before @@@ax25rtd@@@ has adjust the ARP table. If there was already an existing ARP entry for this IP route, one IP datagram will be sent to the old address. Not really a problem, I hope. .SH "SEE ALSO" .BR @@@ax25rtd@@@ (8), .BR ax25rtctl (8). .LP .SH AUTHORS .nf Joerg Reuter .br Llaus Kudielka OE1KIB .fi ax25-apps/ax25rtd/Makefile.am0000644000000000000620000000664611703127704014767 0ustar rootstaff etcfiles = ax25rtd.conf varfiles = ax25_route ip_route man_MANS = ax25rtd.8 ax25rtctl.8 ax25rtd.conf.5 ax25rtd.8: ax25rtd.man name_ax25rtd=$$(echo ax25rtd | sed -e '$(transform)') \ name_Ax25rtd=$$(echo $$name_ax25rtd | sed -r 's@^(.)@\U\1\E@') && \ name_AX25RTD=$$(echo $$name_ax25rtd | sed -r 's@^(.*)@\U\1\E@') && \ name_ax25rtctl=$$(echo ax25rtctl | sed -e '$(transform)') && \ name_Ax25rtctl=$$(echo $$name_ax25rtctl | sed -r 's@^(.)@\U\1\E@') && \ name_AX25RTCTL=$$(echo $$name_ax25rtctl | sed -r 's@^(.*)@\U\1\E@') && \ sed -e "s/@@@ax25rtd@@@/$$name_ax25rtd/g" \ -e "s/@@@Ax25rtd@@@/$$name_Ax25rtd/g" \ -e "s/@@@AX25RTD@@@/$$name_AX25RTD/g" \ -e "s/@@@ax25rtctl@@@/$$name_ax25rtctl/g" \ -e "s/@@@Ax25rtctl@@@/$$name_Ax25rtctl/g" \ -e "s/@@@AX25RTCTL@@@/$$name_AX25RTCTL/g" \ ax25rtd.man > ax25rtd.8.tmp && \ mv ax25rtd.8.tmp ax25rtd.8; ax25rtctl.8: ax25rtctl.man name_ax25rtd=$$(echo ax25rtd | sed -e '$(transform)') \ name_Ax25rtd=$$(echo $$name_ax25rtd | sed -r 's@^(.)@\U\1\E@') && \ name_AX25RTD=$$(echo $$name_ax25rtd | sed -r 's@^(.*)@\U\1\E@') && \ name_ax25rtctl=$$(echo ax25rtctl | sed -e '$(transform)') && \ name_Ax25rtctl=$$(echo $$name_ax25rtctl | sed -r 's@^(.)@\U\1\E@') && \ name_AX25RTCTL=$$(echo $$name_ax25rtctl | sed -r 's@^(.*)@\U\1\E@') && \ sed -e "s/@@@ax25rtd@@@/$$name_ax25rtd/g" \ -e "s/@@@Ax25rtd@@@/$$name_Ax25rtd/g" \ -e "s/@@@AX25RTD@@@/$$name_AX25RTD/g" \ -e "s/@@@ax25rtctl@@@/$$name_ax25rtctl/g" \ -e "s/@@@Ax25rtctl@@@/$$name_Ax25rtctl/g" \ -e "s/@@@AX25RTCTL@@@/$$name_AX25RTCTL/g" \ ax25rtctl.man > ax25rtctl.8.tmp && \ mv ax25rtctl.8.tmp ax25rtctl.8; ax25rtd.conf.5: ax25rtd.conf.man name_ax25rtd=$$(echo ax25rtd | sed -e '$(transform)') \ name_Ax25rtd=$$(echo $$name_ax25rtd | sed -r 's@^(.)@\U\1\E@') && \ name_AX25RTD=$$(echo $$name_ax25rtd | sed -r 's@^(.*)@\U\1\E@') && \ name_ax25rtctl=$$(echo ax25rtctl | sed -e '$(transform)') && \ name_Ax25rtctl=$$(echo $$name_ax25rtctl | sed -r 's@^(.)@\U\1\E@') && \ name_AX25RTCTL=$$(echo $$name_ax25rtctl | sed -r 's@^(.*)@\U\1\E@') && \ sed -e "s/@@@ax25rtd@@@/$$name_ax25rtd/g" \ -e "s/@@@Ax25rtd@@@/$$name_Ax25rtd/g" \ -e "s/@@@AX25RTD@@@/$$name_AX25RTD/g" \ -e "s/@@@ax25rtctl@@@/$$name_ax25rtctl/g" \ -e "s/@@@Ax25rtctl@@@/$$name_Ax25rtctl/g" \ -e "s/@@@AX25RTCTL@@@/$$name_AX25RTCTL/g" \ ax25rtd.conf.man > ax25rtd.conf.5.tmp && \ mv ax25rtd.conf.5.tmp ax25rtd.conf.5; installconf: $(mkinstalldirs) $(DESTDIR)$(AX25_SYSCONFDIR) @list='$(etcfiles)'; for p in $$list; do \ echo " $(INSTALL_DATA) $$p $(DESTDIR)$(AX25_SYSCONFDIR)/$$p"; \ $(INSTALL_DATA) $$p $(DESTDIR)$(AX25_SYSCONFDIR)/$$p; \ done $(mkinstalldirs) $(DESTDIR)$(AX25_LOCALSTATEDIR)/ax25rtd @list='$(varfiles)'; for p in $$list; do \ echo " $(INSTALL_DATA) $$p $(DESTDIR)$(AX25_LOCALSTATEDIR)/ax25rtd/$$p"; \ $(INSTALL_DATA) $$p $(DESTDIR)$(AX25_LOCALSTATEDIR)/ax25rtd/$$p; \ done sbin_PROGRAMS = ax25rtd ax25rtctl LDADD = $(AX25_LIB) EXTRA_DIST = $(etcfiles) $(man_MANS) $(doc_DATA) docdir=${datadir}/doc/ax25-apps doc_DATA= TODO.ax25rtd README.ax25rtd ax25rtd_SOURCES = \ ax25rtd.c \ ax25rtd.h \ cache_ctl.c \ cache_dump.c \ config.c \ listener.c AX25_SYSCONFDIR=$(sysconfdir)/ax25 AX25_LOCALSTATEDIR=$(localstatedir)/ax25 INCLUDES = -DAX25_SYSCONFDIR=\""$(AX25_SYSCONFDIR)"\" \ -DAX25_LOCALSTATEDIR=\""$(AX25_LOCALSTATEDIR)"\" ax25-apps/ax25rtd/README.ax25rtd0000644000000000000620000002124007264464315015077 0ustar rootstaffax25rtd with DG2FEF/DG1KJD Linux-AX.25 Kernel NOTES: - Here is an example ax25rtd.conf file: ax25-maxroutes 256 ip-maxroutes 256 ip-encaps-dev ipax0 [sp0] ax25-learn-routes yes ax25-learn-only-mine yes ip-adjust-mode no ip-learn-routes no arp-add yes [ipax0] arp-add yes ip-learn-routes yes - ax25-learn-only-mine has to be on for now, since ax25rtd is not able to recognize digipeater paths yet when this node is part of it. - ax25rtd will be replaced as soon as possible by something reasonable, so this is only a temporary solution - ipax0 must be up when ax25rtd is startet - all other listeners (ax25d et al) must be registrated at this point of time, too - There must be an entry for ipax0 in /etc/axports, here is an example: ipax0 dg1kjd-10 76800 256 7 IP-encap device ---- Jens ***************************************************************** * Please send all comments and suggestions regarding ax25rtd to * * Klaus Kudielka (klaus.kudielka@ieee.org). * ***************************************************************** Just a quick small README... This will hopefully go into the man pages ASAP. Ax25routed ---------- /usr/sbin/ax25rtd This is a daemon that: - emulates the ceased "autorouter" of Linux Kernel AX.25 - sets up ARP entries automagically - may adjust IP routes and encapsulation mode (although I really do not recomment to use this feature...) The "autorouter" is not really an autorouter. It just listens to the AX.25 traffic on your ports and uses this information to setup AX.25 routes. This can be turned on or off by altering the configuration file /etc/ax25/ax25rtd.conf. Ax25routed provides a socket /var/ax25/ax25rtd/control which is used for runtime maintainance through ax25rtctl or to set up new routes by other daemons (a Flexnet router, perhaps?) On startup ax25rtd reads the configuration file and afterwards preloads the caches from the files /var/ax25/ax25rtd/ax25_routes and /var/ax25/ax25rtd/ip_routes. On SIGTERM or ax25rtctl --save it saves the caches to those files. ax25rtd.conf --------------- The file /etc/ax25/ax25rtd.conf is the configuration file for ax25rtd. The parameters of the options shown here are the default values except the ones marked with (example) ax25-maxroutes 256 ip-maxroutes 256 The maximum size of the three lists / caches. On overflow, ax25rtd will substitute the oldest entry with the new one. [1k2] This marks the beginning of per-port definitions. Note that you have to use port names as defined in axports(5) here, anywhere else you may use the port or the device name. ax25-learn-routes no Set this to "yes", ax25rtd will add the routing information for every heard frame (with complete digipeater path) to the kernel AX.25 routing table. Note that ax25rtd's internal cache will be updated anyway, regardless of this option. ax25-learn-only-mine no If you set it to "yes", only frames that are sent to (1) the interface callsign, (2) any of the listeners on this device, or (3) the callsigns specified by ax25-more-mycalls will be used to update the internal cache and (depending on ax25-learn-routes) the kernel routing table. ax25-add-path db0ach (example) This is useful on DAMA digipeaters. In this case, the DAMA master has to be used for _every_ AX.25 connection, thus ax25rtd will add this digipeater(s) to every target we learn that has no digipeater path (yet). "db0ach" is just an example here. ax25-more-mycalls dl1bke dl1bke-8 (example) You can specify more calls as calls here that belong to this interface... "dl1bke" and "dl1bke-8" are examples. ip-learn-routes no If set to "yes", ax25rtd will modify the IP routing table if it receives an IP frame (directed to us). This is dangerous! It should not screw up your routing table, though. Ax25rtd recognizes the netmask of the device and will adjust the route only if it fits the netmask and the old route points to one of the devices ax25rtd knows about (hence an AX.25 device). The problems begin if you have more than one port and a user is able to hear your outgoing traffic on at least two of them. Due to technical reasons ax25rtd adjusts the route _after_ the kernel has sent the reply to the received TCP frame already. This has technical reasons. If the remote does the same both are switching between the two ports. Don't use this feature unless you know what you are doing. It _should_ be safe do enable this on one-port machines, although I strongly recommend to set a network route instead, i.e.: route add -net 44.0.0.0 scc3 Note that ax25rtd's internal cache will be updated anyway, regardless of this option. irtt If ip-learn-routes is enabled this will assign newly added routes an initial round trip time (IRTT) for TCP. is measured in msec, hence irtt 10000 sets the irtt to 10 seconds. A value of 0 disables this feature (default). ip-adjust-mode no If you set this option to "yes" ax25rtd will change the IP encapsulation mode according to the last received IP frame. The problem with this option is that the kernel AX.25 sends a received IP frame to the IP layer regardless if it was sent in UI frame encapsulation "mode datagram (dg)" or in I frame encaps, hence in an AX.25 connection, "mode virtual connect (vc)". The Linux kernel will respond to this frame before ax25rtd can adjust the mode. If the remote does the same... You get the picture. Don't use this feature unless you know what you are doing. arp-add no This option, if set to "yes", changes the ARP table to the source callsign of the received frame. It should be harmless, just has the the effect that if it is a new entry, the Linux ARP code will send one ARP request before ax25rtd has adjust the ARP table. If there was already an existing ARP entry for this IP route, one IP datagram will be sent to the old address. Not really a problem, I hope. Ax25rtctl --------- /usr/sbin/ax25rtctl