diff -ruN ax25-tools-0.0.8/AUTHORS ax25-tools-0.0.8.rxq/AUTHORS --- ax25-tools-0.0.8/AUTHORS Tue Apr 10 04:03:52 2001 +++ ax25-tools-0.0.8.rxq/AUTHORS Thu Oct 25 23:49:46 2001 @@ -20,6 +20,7 @@ ttylinkd Craig Small VK2XLZ dmascc_cfg Klaus Kudielka yamcfg Jean-Paul Roubelat F6FBB +nrbridge Jeroen Vreeken PE1RXQ All others Jonathon Naylor G4KLX diff -ruN ax25-tools-0.0.8/Makefile.am ax25-tools-0.0.8.rxq/Makefile.am --- ax25-tools-0.0.8/Makefile.am Thu May 10 12:46:01 2001 +++ ax25-tools-0.0.8.rxq/Makefile.am Thu Oct 25 23:50:58 2001 @@ -2,7 +2,7 @@ installconf: @for app in $(SUBDIRS); do $(MAKE) -C $$app installconf; done -SUBDIRS = ax25 hdlcutil kiss netrom rose tcpip user_call yamdrv dmascc +SUBDIRS = ax25 hdlcutil kiss netrom rose tcpip user_call yamdrv dmascc nrbridge EXTRA_DIST = pathnames.h diff -ruN ax25-tools-0.0.8/Makefile.in ax25-tools-0.0.8.rxq/Makefile.in --- ax25-tools-0.0.8/Makefile.in Thu Oct 25 23:54:24 2001 +++ ax25-tools-0.0.8.rxq/Makefile.in Thu Oct 25 23:51:32 2001 @@ -70,7 +70,7 @@ VERSION = @VERSION@ Z_LIB = @Z_LIB@ -SUBDIRS = ax25 hdlcutil kiss netrom rose tcpip user_call yamdrv dmascc +SUBDIRS = ax25 hdlcutil kiss netrom rose tcpip user_call yamdrv dmascc nrbridge EXTRA_DIST = pathnames.h diff -ruN ax25-tools-0.0.8/configure ax25-tools-0.0.8.rxq/configure --- ax25-tools-0.0.8/configure Wed May 16 14:15:57 2001 +++ ax25-tools-0.0.8.rxq/configure Thu Oct 25 23:51:32 2001 @@ -3423,7 +3423,7 @@ ac_given_srcdir=$srcdir ac_given_INSTALL="$INSTALL" -trap 'rm -fr `echo "netrom/Makefile tcpip/Makefile ax25/Makefile Makefile rose/Makefile user_call/Makefile kiss/Makefile hdlcutil/Makefile hdlcutil/fl/Makefile yamdrv/Makefile dmascc/Makefile config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 +trap 'rm -fr `echo "netrom/Makefile tcpip/Makefile ax25/Makefile Makefile rose/Makefile user_call/Makefile kiss/Makefile hdlcutil/Makefile hdlcutil/fl/Makefile yamdrv/Makefile nrbridge/Makefile dmascc/Makefile config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 EOF cat >> $CONFIG_STATUS <> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then diff -ruN ax25-tools-0.0.8/configure.in ax25-tools-0.0.8.rxq/configure.in --- ax25-tools-0.0.8/configure.in Wed May 16 14:15:05 2001 +++ ax25-tools-0.0.8.rxq/configure.in Thu Oct 25 23:49:46 2001 @@ -76,4 +76,4 @@ fi fi -AC_OUTPUT(netrom/Makefile tcpip/Makefile ax25/Makefile Makefile rose/Makefile user_call/Makefile kiss/Makefile hdlcutil/Makefile hdlcutil/fl/Makefile yamdrv/Makefile dmascc/Makefile) +AC_OUTPUT(netrom/Makefile tcpip/Makefile ax25/Makefile Makefile rose/Makefile user_call/Makefile kiss/Makefile hdlcutil/Makefile hdlcutil/fl/Makefile yamdrv/Makefile nrbridge/Makefile dmascc/Makefile) diff -ruN ax25-tools-0.0.8/netrom/nrattach.8 ax25-tools-0.0.8.rxq/netrom/nrattach.8 --- ax25-tools-0.0.8/netrom/nrattach.8 Tue Apr 10 04:18:30 2001 +++ ax25-tools-0.0.8.rxq/netrom/nrattach.8 Thu Oct 25 23:49:46 2001 @@ -1,4 +1,4 @@ -.TH NRATTACH 8 "21 May 1996" Linux "Linux System Managers Manual" +.TH NRATTACH 8 "24 October 2001" Linux "Linux System Managers Manual" .SH NAME nrattach \- Start a NET/ROM interface .SH SYNOPSIS @@ -15,6 +15,13 @@ tries to find the first free NET/ROM device in the system. The devices checked are nr0, nr1, nr2 and nr3 in that order. If no free NET/ROM device is available an error is generated and the program terminates. +.LP +If your kernel also supports INP3 +.B nrattach +will also set the interface mnemonic. +The INP3 implementation needs it for the l3rtt frames it sends out. +Some implementations depend on the mnemonic being in these frames. +(The Linux implementation however does not) .SH OPTIONS .TP 16 .BI "\-i inetaddr" @@ -37,3 +44,5 @@ instances of the same attributes on different devices. Not a good idea. .SH AUTHOR Jonathan Naylor G4KLX +.LP +Jeroen Vreeken PE1RXQ diff -ruN ax25-tools-0.0.8/netrom/nrattach.c ax25-tools-0.0.8.rxq/netrom/nrattach.c --- ax25-tools-0.0.8/netrom/nrattach.c Tue Apr 10 04:18:30 2001 +++ ax25-tools-0.0.8.rxq/netrom/nrattach.c Thu Oct 25 23:49:46 2001 @@ -39,6 +39,7 @@ #include "../pathnames.h" char *callsign; +char *mnemonic; int mtu = 0; int readconfig(char *port) @@ -80,6 +81,8 @@ fprintf(stderr, "nrattach: unable to parse line %d of the nrports file\n", n); return FALSE; } + + mnemonic = strdup(s); if ((s = strtok(NULL, " \t\r\n")) == NULL) { fprintf(stderr, "nrattach: unable to parse line %d of the nrports file\n", n); @@ -203,6 +206,36 @@ return TRUE; } +void inp3mnemonic(char *dev) +{ + int s; + struct nr_route_struct nr_node; + + if ((s=socket(AF_NETROM, SOCK_SEQPACKET, 0)) < 0) { + perror("socket()"); + return; + } + + nr_node.ndigis=0; + strcpy(nr_node.device, dev); + nr_node.quality=0; + nr_node.obs_count=1; + + if (ax25_aton_entry(callsign, nr_node.callsign.ax25_call)!=0) { + perror("invalid callsign"); + close(s); + return; + } + + strncpy(nr_node.mnemonic, mnemonic, 6); + nr_node.mnemonic[6]='\0'; + + if (ioctl(s, SIOCADDRT, &nr_node) != -1) + printf("INP3 support detected, node mnemonic set\n"); + + close(s); + return; +} int main(int argc, char *argv[]) { @@ -251,6 +284,8 @@ return 1; printf("NET/ROM port %s bound to device %s\n", argv[optind], dev); + + inp3mnemonic(dev); return 0; } diff -ruN ax25-tools-0.0.8/nrbridge/Makefile.am ax25-tools-0.0.8.rxq/nrbridge/Makefile.am --- ax25-tools-0.0.8/nrbridge/Makefile.am Thu Jan 1 01:00:00 1970 +++ ax25-tools-0.0.8.rxq/nrbridge/Makefile.am Thu Oct 25 23:49:46 2001 @@ -0,0 +1,13 @@ + +sbin_PROGRAMS = nrbridge + +LDADD = $(AX25_LIB) +#axspawn_LDADD = $(AX25_LIB) $(UTIL_LIB) + +man_MANS = nrbridge.8 + +EXTRA_DIST = $(man_MANS) + +nrbridge_SOURCES = nrbridge.c + +instalconf: diff -ruN ax25-tools-0.0.8/nrbridge/Makefile.in ax25-tools-0.0.8.rxq/nrbridge/Makefile.in --- ax25-tools-0.0.8/nrbridge/Makefile.in Thu Jan 1 01:00:00 1970 +++ ax25-tools-0.0.8.rxq/nrbridge/Makefile.in Thu Oct 25 23:51:06 2001 @@ -0,0 +1,374 @@ +# Makefile.in generated automatically by automake 1.4 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = .. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +AWK = @AWK@ +AX25IO_LIB = @AX25IO_LIB@ +AX25_LIB = @AX25_LIB@ +CC = @CC@ +CXX = @CXX@ +FLTK_LIB = @FLTK_LIB@ +MAKEINFO = @MAKEINFO@ +NCURSES_LIB = @NCURSES_LIB@ +PACKAGE = @PACKAGE@ +UTIL_LIB = @UTIL_LIB@ +VERSION = @VERSION@ +Z_LIB = @Z_LIB@ + +sbin_PROGRAMS = nrbridge + +LDADD = $(AX25_LIB) +#axspawn_LDADD = $(AX25_LIB) $(UTIL_LIB) + +man_MANS = nrbridge.8 + +EXTRA_DIST = $(man_MANS) + +nrbridge_SOURCES = nrbridge.c +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = ../config.h +CONFIG_CLEAN_FILES = +PROGRAMS = $(sbin_PROGRAMS) + + +DEFS = @DEFS@ -I. -I$(srcdir) -I.. +CPPFLAGS = @CPPFLAGS@ +LDFLAGS = @LDFLAGS@ +LIBS = @LIBS@ +X_CFLAGS = @X_CFLAGS@ +X_LIBS = @X_LIBS@ +X_EXTRA_LIBS = @X_EXTRA_LIBS@ +X_PRE_LIBS = @X_PRE_LIBS@ +nrbridge_OBJECTS = nrbridge.o +nrbridge_LDADD = $(LDADD) +nrbridge_DEPENDENCIES = +nrbridge_LDFLAGS = +CFLAGS = @CFLAGS@ +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ +man8dir = $(mandir)/man8 +MANS = $(man_MANS) + +NROFF = nroff +DIST_COMMON = Makefile.am Makefile.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = tar +GZIP_ENV = --best +DEP_FILES = .deps/nrbridge.P +SOURCES = $(nrbridge_SOURCES) +OBJECTS = $(nrbridge_OBJECTS) + +all: all-redirect +.SUFFIXES: +.SUFFIXES: .S .c .o .s +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu nrbridge/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES) + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + + +mostlyclean-sbinPROGRAMS: + +clean-sbinPROGRAMS: + -test -z "$(sbin_PROGRAMS)" || rm -f $(sbin_PROGRAMS) + +distclean-sbinPROGRAMS: + +maintainer-clean-sbinPROGRAMS: + +install-sbinPROGRAMS: $(sbin_PROGRAMS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(sbindir) + @list='$(sbin_PROGRAMS)'; for p in $$list; do \ + if test -f $$p; then \ + echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(sbindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \ + $(INSTALL_PROGRAM) $$p $(DESTDIR)$(sbindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ + else :; fi; \ + done + +uninstall-sbinPROGRAMS: + @$(NORMAL_UNINSTALL) + list='$(sbin_PROGRAMS)'; for p in $$list; do \ + rm -f $(DESTDIR)$(sbindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ + done + +.s.o: + $(COMPILE) -c $< + +.S.o: + $(COMPILE) -c $< + +mostlyclean-compile: + -rm -f *.o core *.core + +clean-compile: + +distclean-compile: + -rm -f *.tab.c + +maintainer-clean-compile: + +nrbridge: $(nrbridge_OBJECTS) $(nrbridge_DEPENDENCIES) + @rm -f nrbridge + $(LINK) $(nrbridge_LDFLAGS) $(nrbridge_OBJECTS) $(nrbridge_LDADD) $(LIBS) + +install-man8: + $(mkinstalldirs) $(DESTDIR)$(man8dir) + @list='$(man8_MANS)'; \ + l2='$(man_MANS)'; for i in $$l2; do \ + case "$$i" in \ + *.8*) list="$$list $$i" ;; \ + esac; \ + done; \ + for i in $$list; do \ + if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \ + else file=$$i; fi; \ + ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man8dir)/$$inst"; \ + $(INSTALL_DATA) $$file $(DESTDIR)$(man8dir)/$$inst; \ + done + +uninstall-man8: + @list='$(man8_MANS)'; \ + l2='$(man_MANS)'; for i in $$l2; do \ + case "$$i" in \ + *.8*) list="$$list $$i" ;; \ + esac; \ + done; \ + for i in $$list; do \ + ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " rm -f $(DESTDIR)$(man8dir)/$$inst"; \ + rm -f $(DESTDIR)$(man8dir)/$$inst; \ + done +install-man: $(MANS) + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) install-man8 +uninstall-man: + @$(NORMAL_UNINSTALL) + $(MAKE) $(AM_MAKEFLAGS) uninstall-man8 + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $$unique $(LISP) + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = nrbridge + +distdir: $(DISTFILES) + here=`cd $(top_builddir) && pwd`; \ + top_distdir=`cd $(top_distdir) && pwd`; \ + distdir=`cd $(distdir) && pwd`; \ + cd $(top_srcdir) \ + && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu nrbridge/Makefile + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done + +DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :) + +-include $(DEP_FILES) + +mostlyclean-depend: + +clean-depend: + +distclean-depend: + -rm -rf .deps + +maintainer-clean-depend: + +%.o: %.c + @echo '$(COMPILE) -c $<'; \ + $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $< + @-cp .deps/$(*F).pp .deps/$(*F).P; \ + tr ' ' '\012' < .deps/$(*F).pp \ + | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \ + >> .deps/$(*F).P; \ + rm .deps/$(*F).pp + +%.lo: %.c + @echo '$(LTCOMPILE) -c $<'; \ + $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $< + @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \ + < .deps/$(*F).pp > .deps/$(*F).P; \ + tr ' ' '\012' < .deps/$(*F).pp \ + | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \ + >> .deps/$(*F).P; \ + rm -f .deps/$(*F).pp +info-am: +info: info-am +dvi-am: +dvi: dvi-am +check-am: all-am +check: check-am +installcheck-am: +installcheck: installcheck-am +install-exec-am: install-sbinPROGRAMS +install-exec: install-exec-am + +install-data-am: install-man +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: uninstall-sbinPROGRAMS uninstall-man +uninstall: uninstall-am +all-am: Makefile $(PROGRAMS) $(MANS) +all-redirect: all-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: + $(mkinstalldirs) $(DESTDIR)$(sbindir) $(DESTDIR)$(mandir)/man8 + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-sbinPROGRAMS mostlyclean-compile \ + mostlyclean-tags mostlyclean-depend mostlyclean-generic + +mostlyclean: mostlyclean-am + +clean-am: clean-sbinPROGRAMS clean-compile clean-tags clean-depend \ + clean-generic mostlyclean-am + +clean: clean-am + +distclean-am: distclean-sbinPROGRAMS distclean-compile distclean-tags \ + distclean-depend distclean-generic clean-am + +distclean: distclean-am + +maintainer-clean-am: maintainer-clean-sbinPROGRAMS \ + maintainer-clean-compile maintainer-clean-tags \ + maintainer-clean-depend maintainer-clean-generic \ + distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-am + +.PHONY: mostlyclean-sbinPROGRAMS distclean-sbinPROGRAMS \ +clean-sbinPROGRAMS maintainer-clean-sbinPROGRAMS uninstall-sbinPROGRAMS \ +install-sbinPROGRAMS mostlyclean-compile distclean-compile \ +clean-compile maintainer-clean-compile install-man8 uninstall-man8 \ +install-man uninstall-man tags mostlyclean-tags distclean-tags \ +clean-tags maintainer-clean-tags distdir mostlyclean-depend \ +distclean-depend clean-depend maintainer-clean-depend info-am info \ +dvi-am dvi check check-am installcheck-am installcheck install-exec-am \ +install-exec install-data-am install-data install-am install \ +uninstall-am uninstall all-redirect all-am all installdirs \ +mostlyclean-generic distclean-generic clean-generic \ +maintainer-clean-generic clean mostlyclean distclean maintainer-clean + + +instalconf: + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff -ruN ax25-tools-0.0.8/nrbridge/nrbridge.8 ax25-tools-0.0.8.rxq/nrbridge/nrbridge.8 --- ax25-tools-0.0.8/nrbridge/nrbridge.8 Thu Jan 1 01:00:00 1970 +++ ax25-tools-0.0.8.rxq/nrbridge/nrbridge.8 Thu Oct 25 23:49:46 2001 @@ -0,0 +1,26 @@ +.TH NRBRIDGE 8 "23 October 2001" Linux "Linux System Managers Manual" +.SH NAME +nrbridge \- AX.25 to NET/ROM bridge +.SH SYNOPSIS +.B nrbridge port +.SH DESCRIPTION +.LP +.B nrbridge +is a deamon that listens on an AX.25 port for connect attempts to known +NET/ROM node calls and opens listen sockets for these calls. +Connects on these sockets are piped to the destination using the NET/ROM +system. For each connect a new child process is spawned. +Listen sockets are removed if they are not used for six hours. +.sp 1 +.B port +has to be a valid and active AX.25 port. +.sp 1 +.B nrbridge +is intended to run on local access ports of a node. +For a user of this port the entire NET/ROM network becomes available as if +it were local AX.25 services. +.SH "SEE ALSO" +.BR ax25 (4), +.BR netrom (4), +.SH AUTHOR +Jeroen Vreeken PE1RXQ diff -ruN ax25-tools-0.0.8/nrbridge/nrbridge.c ax25-tools-0.0.8.rxq/nrbridge/nrbridge.c --- ax25-tools-0.0.8/nrbridge/nrbridge.c Thu Jan 1 01:00:00 1970 +++ ax25-tools-0.0.8.rxq/nrbridge/nrbridge.c Thu Oct 25 23:49:46 2001 @@ -0,0 +1,439 @@ +/* + * nrbridge.c + * + * AX.25 to NET/ROM bridge + * + * Copyright (C) 2001 by Jeroen Vreeken (pe1rxq@amsat.org) + * + * 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 + +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_NETAX25_AX25_H +#include +#else +#include +#endif +#ifdef HAVE_NETROM_NETROM_H +#include +#else +#include +#endif +#ifdef HAVE_NETROSE_ROSE_H +#include +#else +#include +#endif + +#include +#include + +#include +#include +#include +#include +#include + +#include "../pathnames.h" + + +/* Keep a socket open for 6 hours after usage */ +#define OBS_INIT 6*60 +/* Decrease obs once every minute */ +#define OBS_TIME 60 + +struct axsocket { + struct axsocket *next; + + char node[10]; /* callsign of this node */ + int s; /* listen socket */ + int obs; /* used to check if still needed */ +}; + +struct axsocket *axsocket_list=NULL; +char *port=NULL; +char *addr=NULL; +char *dev=NULL; + +char *pax25(char *buf, unsigned char *data) +{ + int i, ssid; + char *s; + char c; + + s=buf; + + for(i=0; i<6; i++) { + c=(data[i]>>1) & 0x7f; + if (!isalnum(c) && c != ' ') { + strcpy(buf, "[invalid]"); + return buf; + } + if (c != ' ') *s++=c; + } + if ((ssid=(data[6] & 0x1e)) != 0) + sprintf(s, "-%d", ssid >> 1); + else + *s='\0'; + + return buf; +} + +void usage(void) +{ + printf("nrbridge " VERSION ", Copyright (C) 2001 Jeroen Vreeken (pe1rxq@amsat.org)\n"); + printf("nrbridge is published under the GNU General Public License\n"); + printf("\n"); + printf("Usage: nrbridge port\n"); + printf("\n"); +} + +int axsocket_open(char *node) +{ + struct full_sockaddr_ax25 sockaddr; + int s, i; + + sockaddr.fsa_ax25.sax25_family = AF_AX25; + sockaddr.fsa_ax25.sax25_ndigis = 1; + ax25_aton_entry(node, sockaddr.fsa_ax25.sax25_call.ax25_call); + ax25_aton_entry(addr, sockaddr.fsa_digipeater[0].ax25_call); + + if ((s=socket(AF_AX25, SOCK_SEQPACKET, 0)) < 0) { + perror("socket()"); + return -1; + } + if (bind(s, (struct sockaddr *)&sockaddr, sizeof(struct full_sockaddr_ax25)) < 0) { + perror("bind()"); + close(s); + return -1; + } + if (listen(s, SOMAXCONN) < 0) { + perror("listen()"); + close(s); + return -1; + } + i=TRUE; + ioctl(s, FIONBIO, &i); + + return s; +} + +int axsocket_exists (char *node) +{ + struct axsocket *axsocket; + + for (axsocket=axsocket_list; axsocket!=NULL; axsocket=axsocket->next) { + if (!strcasecmp(node, axsocket->node)) { + return 1; + } + } + return 0; +} + +void axsocket_add (char *node) +{ + struct axsocket *axsocket; + + for (axsocket=axsocket_list; axsocket!=NULL; axsocket=axsocket->next) { + if (!strcasecmp(node, axsocket->node)) { + axsocket->obs=OBS_INIT; + return; + } + } + axsocket=malloc(sizeof(struct axsocket)); + strcpy(axsocket->node, node); + axsocket->s=axsocket_open(node); + axsocket->obs=OBS_INIT; + axsocket->next=axsocket_list; + axsocket_list=axsocket; +} + +void axsocket_del (char *node) +{ + struct axsocket *axsocket; + struct axsocket *last; + + if (!axsocket_list) + return; + + axsocket=axsocket_list; + if (!strcasecmp(node, axsocket_list->node)) { + axsocket_list=axsocket_list->next; + } else { + while (axsocket->next) { + if (!strcasecmp(node, axsocket->next->node)) { + last=axsocket; + axsocket=axsocket->next; + last->next=axsocket->next; + break; + } + axsocket=axsocket->next; + } + } + if (axsocket) { + if (axsocket->s>=0) + close(axsocket->s); + free(axsocket); + } +} + +void axsocket_clean (void) +{ + struct axsocket *axsocket; + struct axsocket *next; + + axsocket=axsocket_list; + while (axsocket) { + next=axsocket->next; + if (--axsocket->obs<1) { + axsocket_del(axsocket->node); + } + axsocket=next; + } +} + +void axsocket_accept(struct axsocket *axsocket) +{ + int sax, snr; + int addrlen; + struct full_sockaddr_ax25 sockaddr; + struct full_sockaddr_ax25 nrsockaddr; + char buffer[236]; + int size, success; + char user[10]; + fd_set fdread; + int maxfd, i; + + if (!fork()) { + struct axsocket *ax; + struct axsocket *next; + + setpgrp(); + + addrlen=sizeof(struct full_sockaddr_ax25); + sax=accept(axsocket->s, (struct sockaddr *)&sockaddr, &addrlen); + + if (sax < 0) + exit(1); + + strcpy(user, ax25_ntoa(&sockaddr.fsa_ax25.sax25_call)); + + sprintf(buffer, "Building bridge to %s for %s...\n", + axsocket->node, user); + write (sax, buffer, strlen(buffer)); + fflush(0); + + if ((snr=socket(AF_NETROM, SOCK_SEQPACKET, 0)) < 0) { + exit(1); + } + nr_config_get_next(NULL); + sprintf(buffer, "%s %s", nr_config_get_addr(NULL), user); + ax25_aton(buffer, &nrsockaddr); + nrsockaddr.fsa_ax25.sax25_family=AF_NETROM; + addrlen=sizeof(struct full_sockaddr_ax25); + if (bind(snr, (struct sockaddr *)&nrsockaddr, addrlen) == -1) { + exit(1); + } + ax25_aton(axsocket->node, &nrsockaddr); + nrsockaddr.fsa_ax25.sax25_family=AF_NETROM; + addrlen=sizeof(struct sockaddr_ax25); + + if (connect(snr, (struct sockaddr *)&nrsockaddr, addrlen) == -1) { + exit(1); + } + + sprintf(buffer, "Connected\n"); + write (sax, buffer, strlen(buffer)); + fflush(0); + + ax=axsocket_list; + while (ax) { + next=ax->next; + axsocket_del(ax->node); + ax=next; + } + + i=TRUE; + ioctl(sax, FIONBIO, &i); + i=TRUE; + ioctl(snr, FIONBIO, &i); + while (1) { + FD_ZERO(&fdread); + maxfd=snr; + if (sax>snr) + maxfd=sax; + FD_SET(snr, &fdread); + FD_SET(sax, &fdread); + + select(maxfd+1, &fdread, NULL, NULL, NULL); + + success=0; + while((size=read(sax, buffer, 236))>0) { + if (size>0) { + success=1; + send(snr, buffer, size, 0); + } + } + while((size=read(snr, buffer, 236))>0) { + if (size>0) { + success=1; + send(sax, buffer, size, 0); + } + } + fflush(0); + if (!success) + break; + } + + close(snr); + close(sax); + exit(0); + } +} + +int axlisten_open(void) +{ + int s, i; + + if ((s=socket(AF_PACKET, SOCK_PACKET, htons(ETH_P_AX25)))==-1) { + perror("listen socket()"); + exit(1); + } + i=TRUE; + ioctl(s, FIONBIO, &i); + + return s; +} + +void node_check(char *node) +{ + /* First check if we already have this node */ + if (axsocket_exists(node)) { + /* reset its obs counter */ + axsocket_add(node); + return; + } + if (find_node(node, NULL)!=NULL) { + axsocket_add(node); + } + return; +} + +void axlisten_read(int s) +{ + int size, sasize; + char buffer[20]; + char tmp[15]; + struct sockaddr sa; + + sasize=sizeof(sa); + if ((size=recvfrom(s, buffer, sizeof(buffer), 0, &sa, &sasize))==-1) { + perror("recv"); + return; + } + if (strcmp(dev, sa.sa_data) != 0) + return; + + pax25(tmp, buffer+1); + node_check(tmp); + return; +} + +int main (int argc, char **argv) +{ + int listensock; + fd_set fdread; + int maxfd; + int prevtime=time(NULL); + struct axsocket *axsocket; + + if (argc<2) { + usage(); + exit(1); + } + + if (ax25_config_load_ports()==0) { + fprintf(stderr, "no AX.25 port data configured\n"); + exit(1); + } + if (nr_config_load_ports()==0) { + perror("no NET/ROM port data configured\n"); + exit(1); + } + port=argv[1]; + if ((addr=ax25_config_get_addr(port))==NULL) { + fprintf(stderr, "invalid AX.25 port '%s'\n", port); + usage(); + exit(1); + } + if ((dev=ax25_config_get_dev(port))==NULL) { + perror("get dev()"); + exit(1); + } + + listensock=axlisten_open(); + + daemon_start(1); + + while (1) { + FD_ZERO(&fdread); + maxfd=listensock; + FD_SET(listensock, &fdread); + for (axsocket=axsocket_list; axsocket!=NULL; axsocket=axsocket->next) { + FD_SET(axsocket->s, &fdread); + if (axsocket->s >maxfd) + maxfd=axsocket->s; + } + if (select(maxfd+1, &fdread, NULL, NULL, NULL) <=0) { + perror("select()"); + continue; + } + if (FD_ISSET(listensock, &fdread)) { + axlisten_read(listensock); + } + for (axsocket=axsocket_list; axsocket!=NULL; axsocket=axsocket->next) { + if (FD_ISSET(axsocket->s, &fdread)) { + axsocket_accept(axsocket); + } + } + if (prevtime+OBS_TIME < time(NULL)) { + prevtime+=OBS_TIME; + axsocket_clean(); + } + } + + return 0; +}