--- /dev/null
+#
+# $Id: Makefile.Linux,v 1.2 1995/03/19 17:21:06 bdale Exp $
+#
+# Makefile for the Linux port of Mike Westerhof's ipip daemon for Unix.
+#
+# The following options are currently available.
+#
+# AMPRONLY - packets which do not have both source and
+# destination addresses in network 44 get dumped.
+#
+
+OPTIONS =
+
+CC = gcc
+RM = rm -f
+
+CFLAGS = -DLINUX -DUSE_TERMIOS -g -O2 -Wall $(OPTIONS)
+LDFLAGS =
+
+OBJS = config.o ip.o main.o route.o run.o slip.o tun.o
+
+all: ipip
+ipip: $(OBJS)
+ $(CC) $(LDFLAGS) $(CFLAGS) -o ipip $(OBJS)
+
+clean:
+ $(RM) *.o ipip
+
+config.o : config.c ipip.h
+ip.o : ip.c ipip.h
+main.o : main.c ipip.h version.h
+route.o : route.c ipip.h
+run.o : run.c ipip.h
+slip.o : slip.c ipip.h
+tun.o : tun.c ipip.h
--- /dev/null
+#
+# $Id: Makefile.BSD,v 1.8 1995/03/19 17:33:58 bdale Exp $
+#
+PROG= ipip
+BINDIR= /usr/local/etc
+SRCS= config.c ip.c main.c route.c run.c slip.c tun.c
+CFLAGS+= -DBDALE -DAMPRONLY -g
+LDFLAGS+= -g
+NOMAN=1
+
+.include <bsd.prog.mk>
--- /dev/null
+README for the ipip encapsulation daemon as distributed by Bdale Garbee N3EUA.
+
+This is a derivation of Mike Westerhof's ipip daemon for Unix machines. Mike
+provided code that worked for SunOS, I ported the daemon to HP-UX and BSD/OS,
+and Ron Atkinson N8FOW and John Paul Morrison provided the tweaks for Linux.
+I am once again actively maintaining the ipip package, and as a Debian
+GNU/Linux maintainer, that's the platform I'm doing the work on. The BSD
+support should mostly still work, but is untested by me in recent times. It
+should be trivial to unpack and build these sources on non-Debian Linux
+systems, and not hard on any system with BSD-style sockets.
+
+To build the daemon:
+
+ # you've obviously already unpacked the source distribution. On BSD
+ # systems, I like to part it in /usr/src/local/ipip, and augment the
+ # Makefiles so that the daemon becomes part of the normal full build.
+
+ # make a copy of the correct Makefile, I like to symlink them and use
+ # RCS to manage the changes, but to each his own...
+ ln -s Makefile.BSD Makefile
+ or ln -s Makefile.Linux Makefile
+
+ # edit Makefile to set desired options, as documented below
+
+ # if you're on a BSD system, issue the following four make commands...
+ make obj
+ make depend
+ make
+ make install
+
+ # if you're on a Linux system, just do
+ make all
+
+To install the daemon:
+
+ Look in the 'samples' subdirectory for examples of how to create a
+ config file, which defines interfaces, and a routes file, which sets
+ up the routing table. The 'bdale' subdirectory has a couple of
+ example configs, one very old one from Mike, one that represents
+ almost what Bdale runs today. The 'n8fow' subdirectory has Ron's
+ config files, which are perhaps more appropriate for Linux users. I
+ suggest you troll it all, though, and see what's there.
+
+ Got questions? Ask. It'll help motivate me/us to improve the docs!
+
+To re-build the daemon if you make source changes:
+
+ # if you're on BSD, just do a
+ make
+
+ # if you're on Linux, do
+ make clean ; make all
+
+Logging output is handled via syslog. We use the LOCAL0 service specifier
+in syslog's configuration file by default. As a result, make sure to look
+for errors in the /var/log/local0 (BSD) or /var/adm/local0 (Linux) or
+
+/usr/adm/local0 (HP-UX) file, and arrange for appropriate log rotation. You
+can send a SIGHUP to the daemon after rotating log files and/or loading new
+routing information to get it to "restart". You probably also need to SIGHUP
+syslogd to note the log rotation.
+
+The following options are available when running the program (yeah, there
+should be a man page, but "life is short and the ROM is full"):
+
+ Options are:
+ -help Print this summary of options
+ -v Print just the version number and exit
+ -c file Use the supplied filename as the config file
+ -r file Use the supplied filename as the route file
+ -s n Report statistics every n minutes
+ -np Don't print the ipip[1234]: prefix
+ -nts Don't include a timestamp in the statistics
+ -t Turn on tracing of incoming packets
+ -d Print out some debugging information
+
+There is one option in the Makefile. If you include -DAMPRONLY, then any
+packets which do not have both source and destination addresses in network
+44 get dropped on the floor. After we had a non-ham on the Internet attack
+one of our net-44 subnets, we implemented this firewall, and now use a mixture
+of MX records pointing via a dual-homed host and socks services to do
+everything we want from the network 44 side while presenting a blank wall to
+non-net-44 initiated connections. Ugly, but it works. Someday when I'm
+resting, I'll put screend up to manage the firewall and return the ipip
+daemon to being "transparent". But not today...
+
+If you have questions about this stuff, I can be reached as bdale@gag.com. If
+you make changes or improvements, please send them along so I can update
+the distribution.
--- /dev/null
+Outstanding issues with ipip:
+
+ - The route table has a static size. It currently has 1000 entries.
+ The ampr gateway table has approximately 700 entries as of this
+ writing.
+
--- /dev/null
+/* config.c config file reader
+ *
+ * $Id: config.c,v 1.3 1995/03/19 17:21:06 bdale Exp $
+ *
+ * Copyright 1991, Michael Westerhof, Sun Microsystems, Inc.
+ * This software may be freely used, distributed, or modified, providing
+ * this header is not removed.
+ *
+ */
+
+#include <stdio.h>
+#include <memory.h>
+#include <string.h>
+#include <ctype.h>
+#include <syslog.h>
+#include <stdlib.h>
+
+#include "ipip.h"
+
+static void cerr(); /* General error printer */
+static void init_config();
+static void c_interface();
+static void print_config();
+
+static int clineno;
+static int cerrflag;
+
+/*
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * open and read the interface config file. Also initialize the iface defs
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ */
+int
+read_config(f)
+char *f;
+{
+ FILE *cf;
+ char buf[256], *p;
+
+ init_config();
+
+/* Open the file */
+ if((cf = fopen(f,"r"))==NULL){
+ syslog(LOG_ERR, "Config file %s not found or could not be opened",f);
+ return -1;
+ }
+
+ while(fgets(buf, 255, cf)!=NULL){
+ clineno++;
+ if((p = strtok(buf, " \t\n\r")) == NULL)continue;
+ if(*p=='#' || *p==';')continue;
+
+ if(strcmp(p,"interface")==0)c_interface();
+/* else if(strcmp(p,"whatever")==0)c_dowhatever(); */
+ else cerr("Unrecognized command: %s",p);
+ }
+
+ if(ifs_top==0)cerr("No interfaces defined","");
+
+ if(debugd)print_config();
+
+ return cerrflag;
+}
+
+/*
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Initialize defaults and setup the interface structures
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ */
+static void
+init_config()
+{
+ int i;
+
+ for(i=0;i<MAX_IFACES;i++){
+ ifs[i].type = IF_TYPE_NONE;
+ ifs[i].status = 0;
+ ifs[i].id = NULL;
+ ifs[i].devname = NULL;
+ ifs[i].unit = 0;
+ ifs[i].fd = -1;
+ ifs[i].private = NULL;
+ ifs[i].ifopen = NULL;
+ ifs[i].ifread = NULL;
+ ifs[i].ifsend = NULL;
+ ifs[i].in = 0;
+ ifs[i].out = 0;
+ ifs[i].out_overruns = 0;
+ ifs[i].martians_in = 0;
+ ifs[i].bogus_in = 0;
+ ifs[i].looped_in = 0;
+ }
+ ifs_top = 0;
+
+ clineno = 0;
+ cerrflag = 0;
+}
+
+/*
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Print out the config table (DEBUG)
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ */
+static void
+print_config()
+{
+ int i;
+ char *id, *dev;
+
+ if(cerrflag==0) syslog(LOG_DEBUG, "%d interfaces:\n",ifs_top);
+ else syslog(LOG_DEBUG, "%d interfaces (there are errors):\n", ifs_top);
+ for(i=0;i<ifs_top;i++){
+
+ if(ifs[i].id == NULL) id = "(none)";
+ else id = ifs[i].id;
+
+ if(ifs[i].devname == NULL) dev = "(none)";
+ else dev = ifs[i].devname;
+
+ if(ifs[i].type == IF_TYPE_NONE){
+ syslog(LOG_DEBUG,"interface %-4s type NONE devicename %s unit %d\n",
+ id, dev, ifs[i].unit);
+ } else if(ifs[i].type == IF_TYPE_SLIP){
+ syslog(LOG_DEBUG,"interface %-4s type slip devicename %s speed %d\n",
+ id, dev, ifs[i].unit);
+ } else if(ifs[i].type == IF_TYPE_TUN){
+ syslog(LOG_DEBUG,"interface %-4s type tun devicename %s\n",
+ id, dev);
+ } else if(ifs[i].type == IF_TYPE_IPUDP){
+ syslog(LOG_DEBUG,"interface %-4s type udp port %d\n",
+ id, ifs[i].unit);
+ } else if(ifs[i].type == IF_TYPE_IPIP){
+ syslog(LOG_DEBUG,"interface %-4s type ip protocol id %d\n",
+ id, ifs[i].unit);
+ } else {
+ syslog(LOG_DEBUG,"interface %-4s type UNKNOWN devicename %s unit %d\n",
+ id, dev, ifs[i].unit);
+ }
+ }
+}
+
+/*
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Print a general config file error
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ */
+static void
+cerr(s,a)
+char *s;
+char *a;
+{
+ syslog(LOG_ERR,"Config file error at line %d:\n",clineno);
+ (void)fprintf(stderr,s,a);
+ (void)fprintf(stderr,"\n");
+ cerrflag--;
+}
+
+/*
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Handle the "define" command
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ */
+static void
+c_interface()
+{
+ int syntax;
+ char *q;
+
+ if(ifs_top>=MAX_IFACES){
+ cerr("Too many interfaces defined","");
+ return;
+ }
+
+ syntax = 0;
+
+ if((q = strtok((char *)NULL, " \t\n\r"))){
+ ifs[ifs_top].id = strdup(q);
+ } else syntax++;
+
+ if((q = strtok((char *)NULL, " \t\n\r"))){
+ if(strcmp(q,"tunnel")==0){
+ ifs[ifs_top].type = IF_TYPE_TUN;
+ ifs[ifs_top].ifopen = tun_open;
+ ifs[ifs_top].ifread = tun_read;
+ ifs[ifs_top].ifsend = tun_send;
+ } else if(strcmp(q,"slip")==0){
+ ifs[ifs_top].type = IF_TYPE_SLIP;
+ ifs[ifs_top].ifopen = slip_open;
+ ifs[ifs_top].ifread = slip_read;
+ ifs[ifs_top].ifsend = slip_send;
+ } else if(strcmp(q,"ip")==0){
+ ifs[ifs_top].type = IF_TYPE_IPIP;
+ ifs[ifs_top].ifopen = ip_open;
+ ifs[ifs_top].ifread = ip_read;
+ ifs[ifs_top].ifsend = ip_send;
+ } else if(strcmp(q,"udp")==0){
+ ifs[ifs_top].type = IF_TYPE_IPUDP;
+ ifs[ifs_top].ifopen = ip_open;
+ ifs[ifs_top].ifread = ip_read;
+ ifs[ifs_top].ifsend = ip_send;
+ } else cerr("Bad interface type: %s",q);
+ } else syntax++;
+
+ if((q = strtok((char *)NULL, " \t\n\r"))){
+ ifs[ifs_top].devname = strdup(q);
+ } else syntax++;
+
+ if((q = strtok((char *)NULL, " \t\n\r"))){
+ ifs[ifs_top].unit = atoi(q);
+ } else syntax++;
+
+ if(syntax)cerr("Syntax error (interface <name> <type> <device> <int>","");
+
+ ifs_top++;
+}
--- /dev/null
+This is the IP over IP encapsulation daemon. It is an alternative to the
+kernel's native encapsulation support when dealing with more than a few
+encapsulation pipes. It's much easier to update the ipip daemon's routing
+table than to have to configure and route a bunch of different interfaces in
+the kernel.
+
+The daemon was written by Mike Westerhof, and has been maintained since 1992
+by Bdale Garbee.
--- /dev/null
+ipip (1.1.6) unstable; urgency=low
+
+ * rebuild to reflect policy changes noted by lintian
+
+ -- Bdale Garbee <bdale@gag.com> Sun, 29 Dec 2002 14:24:50 -0700
+
+ipip (1.1.5) unstable; urgency=low
+
+ * apply patch to build well on new architectures with newer toolchains,
+ closes: #105520, #105526
+ * remove the dh_suidregister call that's obsolete from debian/rules
+
+ -- Bdale Garbee <bdale@gag.com> Mon, 16 Jul 2001 12:14:53 -0600
+
+ipip (1.1.4) unstable; urgency=low
+
+ * update to latest standards revision, add Build-Depends
+
+ -- Bdale Garbee <bdale@gag.com> Fri, 7 Jan 2000 02:41:59 -0700
+
+ipip (1.1.3) unstable; urgency=low
+
+ * lose the call to dh_du, closes: #51486
+
+ -- Bdale Garbee <bdale@gag.com> Mon, 29 Nov 1999 00:20:28 -0700
+
+ipip (1.1.2) unstable; urgency=low
+
+ * fix a couple of obvious textual errors in the man page. It still isn't
+ much of a man page, though!
+
+ -- Bdale Garbee <bdale@gag.com> Fri, 3 Sep 1999 09:24:04 -0600
+
+ipip (1.1.1) unstable; urgency=low
+
+ * fix typo in man page, closes 35144
+ * fix spelling error in control file pointed out by lintian
+
+ -- Bdale Garbee <bdale@gag.com> Sun, 30 May 1999 23:28:21 -0600
+
+ipip (1.1.0) frozen unstable; urgency=low
+
+ * as the "upstream maintainer", I'm choosing to eliminate the illusion of an
+ upstream release, and am packaging this as a "made for Debian" package.
+ It is, of course, still completely reasonable for the source to be
+ unpacked and built on non-Debian, and even non-Linux systems.
+ * integrating changes from Ron Luse KD9KX
+ - HUP signal is now honored more than once
+ - routes now matches on a most-specific basis, not first-match basis,
+ so config file route order is no longer important
+ - fixed ugly death when ip_send got host unreachable errors
+ * add an init.d script to launch the daemon
+ * fix several lintian errors and warnings
+
+ -- Bdale Garbee <bdale@gag.com> Wed, 28 Oct 1998 17:55:45 -0700
+
+ipip (1.0-1) unstable; urgency=low
+
+ * initial ipip package for Debian
+ * significant cleanup since last pre-Debian release in 1995
+
+ -- Bdale Garbee <bdale@gag.com> Wed, 21 Jan 1998 11:16:45 -0700
+
+
+ Pre-Debian History:
+
+ 0.0.12.bdale.4
+ add code to log pid at invocation, so that log rotation can
+ easily include a daemon restart
+
+ 0.0.12.bdale.3.3
+ ugly hack to turn off connectivity to all but net-44 if
+ AMPRONLY is defined.
+
+ 0.0.12.bdale.3.2
+ seems to work fine now on BSDI BSD/386. a couple of tweaks
+ to fix crashes lead to the '.2'
+
+ 0.0.12.bdale.3
+ working on switching to use of syslog() for error/warning
+ outputs. shorten the version string to just be my suffix.
+
+ 0.0.12.bdale.2
+ fixed a bunch of BSDI'isms... including modem control on a
+ serial port during open. At this point, it routes on the IP
+ side just fine, but the slip link still doesn't quite work...
+
+ 0.0.12.bdale.1
+ remove a reference to malloc.h in slip.c when compiled under
+ BSDI's BSD/386
+
+ 0.0.12.bdale.0
+ disabled the code that prevents packets from going back out
+ the same interface. need to use same interface to bounce
+ frames to/from other HP closed subnet hosts using my open
+ subnet machine as a router... this if BDALE defined.
+
+ 0.0.12 added an fflush(stdout) to the run loop. Nice to be able
+ to see what trace is putting out!
+
+ 0.0.11 progname prefix on messages is optional now; use the "-np"
+ (noprefix) flag to turn it off.
+ There are time-stamp on certain messages now; the "-nt"
+ (notimestamp) flag turns off timestamps on the stats lines.
+ The stats are a single line per interface now.
+ Moved the NO_STRTOUL ugliness to the ipip.h file. The default
+ is to try for strtoul unless the symbol "sun" is defined.
+ Fixed zero-length packets from the slip interface problem.
+
+ 0.0.10 added the statistics reporting stuff.
+
+ 0.0.9 added a very basic martian filter in hopes of catching
+ very obvious network problems. Added debug output while
+ opening the interfaces.
+
+ 0.0.8 fixed the network mask comparison -- gotta make sure we
+ convert the mask to network byte order!
+
+ 0.0.7 command line is handled better; -d and -t options separated.
+ Support for SIGTERM and SIGINT -- print a message upon
+ catching these. Re-wrote the Makefile.
+
+ 0.0.6 Improved and generalized the error handling code for the
+ drivers, and ensured all messages are preceeded by the
+ program name (nice when running in the background!)
+
+ 0.0.5 Make sure we can deal with the EINTR error code (so we can
+ handle a SIGHUP).
+
+ 0.0.4 linted, added flag so that we can handle multiple slip
+ packets in a single burst.
+
+ 0.0.3 Rewrite the config and route readers. Better error handling
+ and more flexible.
+
+ 0.0.2 Move the routines to open, read, send on an interface into
+ the interface structure. This simplifies many loops.
+
+ 0.0.1 Initial sort of functional version. (sent to bdale@gag.com)
+
+ 0.0.0 Development begins (4 Dec 91)
+
+
+Local variables:
+mode: debian-changelog
+End:
--- /dev/null
+/etc/init.d/ipip
+/etc/ipip/config
+/etc/ipip/routes
--- /dev/null
+Source: ipip
+Section: net
+Priority: extra
+Maintainer: Bdale Garbee <bdale@gag.com>
+Build-Depends: debhelper
+Standards-Version: 3.5.8.0
+
+Package: ipip
+Architecture: any
+Depends: ${shlibs:Depends}
+Description: IP over IP Encapsulation Daemon
+ This daemon provides an alternative to the kernel-resident support for IP
+ encapsulation links. It is better suited for situations where there are many
+ encapsulation connections to be managed, such as is the case for amateur
+ radio interconnection of network 44. Also, because the daemon is outside the
+ kernel, it provides an excellent environment for experimenting with alternate
+ mechanisms for distributing encapsulation routing updates.
+ .
+ If you need one encapsulation link, use the kernel's built-in support. If
+ you need a lot of encapsulation links, give this daemon a try.
--- /dev/null
+This package was originally written by Mike Westerhof for SunOS. Bdale Garbee
+ported it to HP-UX and BSD/OS. Ron Atkinson and John Paul Morrison provided
+the tweaks for Linux. The package is currently maintained by Bdale Garbee,
+both as "upstream maintainer" and as a Debian package.
+
+The original copyright from Michael states:
+
+ Copyright 1991, Michael Westerhof, Sun Microsystems, Inc.
+ This software may be freely used, distributed, or modified, providing
+ this header is not removed.
+
+This version is a derivative of Michael's work developed and maintained by
+Bdale Garbee with input from several others. It is licensed for distribution
+under the terms of the GNU General Public License, version 2 or later. A
+copy of the GPL is provided on Debian systems in the /usr/share/common-licenses
+directory.
--- /dev/null
+etc/ipip
+usr/sbin
--- /dev/null
+#! /bin/sh
+#
+
+PATH=/bin:/usr/bin:/sbin:/usr/sbin
+DAEMON=/usr/sbin/ipip
+
+FLAGS="defaults 50"
+
+test -f $DAEMON || exit 0
+
+case "$1" in
+ start)
+ start-stop-daemon --start --verbose --exec $DAEMON
+ ;;
+ stop)
+ start-stop-daemon --stop --verbose --exec $DAEMON
+ ;;
+ restart|force-reload)
+ start-stop-daemon --stop --verbose --exec $DAEMON
+ start-stop-daemon --start --verbose --exec $DAEMON
+ ;;
+ *)
+ echo "Usage: /etc/init.d/ipip {start|stop|restart|force-reload}"
+ exit 1
+ ;;
+esac
+
+exit 0
--- /dev/null
+; config file for ipip daemon
+;
+; serial line to gw.n3eua.ampr.org
+;interface gwsl slip /dev/tty01 19200
+;
+; tunnel driver to get to local protocol stack
+;interface sloop tunnel /dev/tun0 0
+;
+; the rest of the world - send on 4, accept both 4 and 94
+;interface open ip null 4
+;interface legacy ip null 94
+;
+; the end
--- /dev/null
+#
+# ipip route table built by bdale on Wed Sep 1 12:05:52 MDT 1993
+#
+# Note that needs to be most specific first to least specific last, or
+# so it seems to me...
+#
+# local routes
+#route 44.32.0.2 0xffffffff sloop
+#route 44.32.0.0 0xffff0000 gwsl
+#
+# default everything else via hpcsos, for now...
+#route 0.0.0.0 0x00000000 open 15.255.240.16
+#
+# the end
--- /dev/null
+#!/usr/bin/make -f
+# rules file for the ipip package, requires debhelper
+# copyright 1998 by Bdale Garbee, distributed under the terms of the GPL
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+build: build-stamp
+build-stamp:
+ dh_testdir
+
+ $(MAKE)
+
+ touch build-stamp
+
+clean:
+ dh_testdir
+ dh_testroot
+ rm -f build-stamp
+
+ -$(MAKE) clean
+
+ dh_clean
+
+# Build architecture-independent files here.
+binary-indep: build
+
+# Build architecture-dependent files here.
+binary-arch: build
+# dh_testversion
+ dh_testdir
+ dh_testroot
+ dh_clean -k
+ dh_installdirs
+
+ cp ipip debian/tmp/usr/sbin
+ cp debian/ipip.config debian/tmp/etc/ipip/config
+ cp debian/ipip.routes debian/tmp/etc/ipip/routes
+
+ dh_installdocs
+ dh_installexamples samples/*
+ dh_installmenu
+ dh_installinit
+ dh_installcron
+ dh_installmanpages
+# dh_undocumented
+ dh_installchangelogs
+ dh_strip
+ dh_compress
+ dh_fixperms
+ dh_installdeb
+ dh_shlibdeps
+ dh_gencontrol
+# dh_makeshlibs
+ dh_md5sums
+ dh_builddeb
+
+source diff:
+ @echo >&2 'source and diff are obsolete - use dpkg-source -b'; false
+
+binary: binary-indep binary-arch
+.PHONY: build clean binary-indep binary-arch binary
--- /dev/null
+/* ip.c system IP or UDP level stuff
+ *
+ * $Id: ip.c,v 1.4 1995/03/19 17:21:06 bdale Exp $
+ *
+ * Copyright 1991, Michael Westerhof, Sun Microsystems, Inc.
+ * This software may be freely used, distributed, or modified, providing
+ * this header is not removed.
+ *
+ * Added support for Linux - Ron Atkinson N8FOW
+ */
+
+#include "ipip.h"
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netdb.h>
+#include <fcntl.h>
+#include <memory.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <syslog.h>
+
+#ifndef FNDELAY
+#define FNDELAY O_NDELAY
+#endif
+
+extern int errno;
+
+#define IF_NAME "ip" /* for use with the error checking macros */
+
+/*
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * open and initialize the IO interface. Return -1 for error.
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ */
+int ip_open(ifp)
+struct interface *ifp;
+{
+ struct sockaddr_in ip_udpbind;
+
+ CK_IFNULL(ifp);
+ CK_IFTYPE2(ifp,IF_TYPE_IPIP,IF_TYPE_IPUDP);
+
+ if((ifp->status & IF_STAT_OPEN)) return 1;
+
+ if(ifp->type == IF_TYPE_IPUDP){
+ ifp->fd = socket(AF_INET, SOCK_DGRAM, 0);
+ } else {
+ ifp->fd = socket(AF_INET, SOCK_RAW, ifp->unit);
+ }
+ if (ifp->fd<0) {
+ PERR("opening socket");
+ return -1;
+ }
+
+ if (fcntl(ifp->fd, F_SETFL, FNDELAY) < 0) {
+ PERR("setting non-blocking I/O on raw socket");
+ return -1;
+ }
+
+ if(ifp->type == IF_TYPE_IPUDP){
+ (void)memset( (char *)&ip_udpbind, 0, sizeof(struct sockaddr) );
+ ip_udpbind.sin_addr.s_addr = INADDR_ANY;
+ ip_udpbind.sin_family = AF_INET;
+ ip_udpbind.sin_port = htons((unsigned short)ifp->unit);
+ if(bind(ifp->fd,(struct sockaddr *)&ip_udpbind,sizeof ip_udpbind)<0){
+ PERR("binding udp socket");
+ return -1;
+ }
+ }
+
+ ifp->status = IF_STAT_OPEN;
+ return 1;
+}
+
+
+/*
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Read data from the specified interface. Return a complete IP datagram.
+ * If the datagram is not complete, then don't return anything.
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ */
+int ip_read(ifp, m)
+struct interface *ifp;
+struct message *m;
+{
+ unsigned char buf[MAX_SIZE], *p;
+ int n, hdr_len, fromlen;
+#ifdef LINUX
+ struct iphdr *ipptr;
+#else
+ struct ip *ipptr;
+#endif
+ struct sockaddr_in ip_from;
+
+ CK_IFNULL(ifp);
+ CK_IFTYPE2(ifp,IF_TYPE_IPIP,IF_TYPE_IPUDP);
+ CK_IFOPEN(ifp);
+ CK_MNULL(m);
+
+ (void)memset((char *)&ip_from, 0, sizeof(struct sockaddr));
+ ip_from.sin_family = AF_INET;
+ fromlen = sizeof ip_from;
+
+ n = recvfrom(ifp->fd, (char *)buf, MAX_SIZE, 0,(struct sockaddr *)&ip_from, &fromlen);
+ if(n<0){
+ m->length = 0;
+ if(errno==EINTR)return 0;
+ if(errno==EWOULDBLOCK)return 0;
+ PERR("recvfrom: on socket");
+ return -1;
+ }
+
+ if(n==0)return 0;
+
+ if(ifp->type == IF_TYPE_IPUDP){
+ p = buf;
+ } else {
+#ifdef LINUX
+ ipptr = (struct iphdr *)buf;
+ hdr_len = 4 * ipptr->ihl;
+#else
+ ipptr = (struct ip *)buf;
+ hdr_len = 4 * ipptr->ip_hl;
+#endif
+ p = buf + hdr_len;
+ n = n - hdr_len;
+ }
+
+ (void)memcpy((char *)m->msg,(char *)p, n);
+ m->length = n;
+ (void)memcpy( (char *)&(m->fip), (char *)&ip_from.sin_addr, 4);
+ m->fport = ip_from.sin_port;
+ return n;
+}
+
+/*
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * write data from to the specified interface. Return as soon as possible.
+ * The buffer provided will be a complete IP datagram.
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ */
+int ip_send(ifp, m)
+struct interface *ifp;
+struct message *m;
+{
+ int n;
+ struct sockaddr_in ip_to;
+
+ CK_IFNULL(ifp);
+ CK_IFTYPE2(ifp,IF_TYPE_IPIP,IF_TYPE_IPUDP);
+ CK_IFOPEN(ifp);
+ CK_MNULL(m);
+
+ if(m->length<=0)return 0;
+
+ if((long)m->tip==0){
+ syslog(LOG_WARNING,"attempt to send to IP address 0.0.0.0");
+ return 0;
+ }
+
+ if((ifp->type==IF_TYPE_IPUDP)&&(m->tport==0)){
+ syslog(LOG_WARNING,"attempt to send to UDP port 0");
+ return 0;
+ }
+
+ (void)memset( (char *)&ip_to, 0, sizeof(struct sockaddr) );
+ ip_to.sin_family = AF_INET;
+ ip_to.sin_port = m->tport;
+ (void)memcpy((char *)&ip_to.sin_addr, (char *)&(m->tip), 4);
+
+ n = sendto(ifp->fd, (char *)m->msg, m->length, 0,
+ (struct sockaddr *)&ip_to, sizeof ip_to);
+ if(n<0){
+ /* Log errors but don't die, since most errors are transient */
+ char bugger[80];
+ unsigned char *p = (unsigned char *)&m->tip;
+ sprintf(bugger,
+ "ip_send(dest:%d.%d.%d.%d) sendto(): %s",
+ p[0], p[1], p[2], p[3], strerror (errno) ) ;
+ PERR(bugger);
+ return 0; /* Who cares? Continue. */
+ }
+
+ return n;
+}
--- /dev/null
+.TH IPIP 1
+.SH NAME
+ipip \- an IP over IP encapsulation daemon
+.SH SYNOPSIS
+.B ipip
+.SH DESCRIPTION
+This is a user-space daemon that supports encapsulation of IP over IP. Modern
+Linux kernels provide this ability in the kernel, but consume an interface
+per encapsulated link. This can be impractical for virtual networks built up
+of a large number of encapsulated links, such as is the case with the amateur
+radio net-44 network. The ipip daemon is often a better solution for these
+environments.
+
+There is very little documentation on the daemon at this time. Look for the
+README file in /usr/doc/ipip, and the example config files also in that tree.
+.SH AUTHOR
+This package was originally written by Mike Westerhof for SunOS. Bdale Garbee
+ported it to HP-UX and BSD/OS. Ron Atkinson and John Paul Morrison then
+provided the tweaks for Linux.
+
+The package is currently once again being maintained by Bdale Garbee, both
+as "upstream maintainer" and as maintainer of the Debian GNU/Linux ipip
+package.
+
--- /dev/null
+/* ipip.h general configuration info
+ *
+ * $Id: ipip.h,v 1.8 1995/03/19 17:21:06 bdale Exp $
+ *
+ * Copyright 1991, Michael Westerhof, Sun Microsystems, Inc.
+ * This software may be freely used, distributed, or modified, providing
+ * this header is not removed.
+ *
+ * Added support for Linux - Ron Atkinson N8FOW
+ */
+
+/* setup the log class to be used when calling syslog - probably LOG_LOCALn */
+#define IPIP_SYSLOG LOG_LOCAL0
+
+/* and the location of the file to log the daemon's pid to */
+#define PIDLOG "/var/run/ipip.pid"
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+/* The strtoul routine converts a string to a long unsigned integer.
+ * Some system (SunOS for instance) don't have this routine; they tend
+ * to allow long unsigned implicitly. If your system supports the strtoul
+ * routine, use it! Otherwise, try defining "NO_STRTOUL" below...
+ * you'll get an immediate bomb-out on execution of the resultant binary
+ * if strtol("0xffffffff",NULL,0) != 0xffffffff
+ */
+
+#ifdef sun
+#define NO_STRTOUL
+#endif
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#ifdef NO_STRTOUL
+#define strtoul(a,b,c) strtol(a,b,c)
+#endif
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#define DEFAULTCONFIG "/etc/ipip/config"
+#define DEFAULTROUTE "/etc/ipip/routes"
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#define MAX_SIZE 2048 /* largest IP packet we will handle */
+#define MAX_IFACES 8 /* Total number of interfaces we support */
+#define MAX_ROUTES 1024 /* Max entries in the route table */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+int debugd;
+int debugt;
+char progname[32];
+int no_timestamp;
+int stat_interval;
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/* The main per-interface data structure */
+
+struct interface {
+
+ int type; /* The type of interface this is */
+#define IF_TYPE_NONE 0
+#define IF_TYPE_IPIP 1
+#define IF_TYPE_IPUDP 2
+#define IF_TYPE_SLIP 3
+#define IF_TYPE_TUN 4
+
+ int status; /* status flags for this interface */
+#define IF_STAT_OPEN 1
+#define IF_STAT_CALL_AGAIN 2 /* call even though no data on the fd! */
+ char *id; /* The name assigned to this interface */
+
+ char *devname; /* (opt) the device name (/dev/ttya) */
+ int unit; /* IP prot ID, udp port, baud rate, etc */
+
+ int fd; /* the file descriptor to use */
+ char *private; /* (opt) pointer to private data struct */
+
+ int (*ifopen)(); /* routine to call to open */
+ int (*ifread)(); /* routine to call to read a packet */
+ int (*ifsend)(); /* routine to call to send a packet */
+
+ long in; /* count of packets in */
+ long out; /* count of packets out */
+ long out_overruns; /* count of output overrun errors */
+ long martians_in; /* count of bogus packets coming in */
+ long looped_in; /* count of packets looped */
+ long bogus_in; /* count of bogus packets in */
+};
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+/* Note: the ip addresses and the port numbers are always in net order */
+
+struct message {
+ int length; /* number of characters in packet */
+ struct interface *from_if; /* the interface this came from */
+ struct interface *to_if; /* the interface this goes to */
+ unsigned long fip; /* ip address from (IP/UDP only) */
+ unsigned long tip; /* ip address to (IP/UDP only) */
+ unsigned short fport; /* port number from (UDP only) */
+ unsigned short tport; /* port number to (UDP only) */
+ unsigned char msg[MAX_SIZE]; /* the packet itself */
+};
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#ifdef LINUX
+struct ipip_route {
+#else
+struct route {
+#endif
+ unsigned long ipaddr; /* the ip address (network order) */
+ unsigned long mask; /* the bit-mask to apply */
+ struct interface *destif; /* the destination interface */
+ unsigned long destaddr; /* the destination ip address */
+ unsigned short destport; /* the destination udp port */
+ long hits; /* number of times route selected */
+};
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#ifdef LINUX
+struct ipip_route rts[MAX_ROUTES];
+#else
+struct route rts[MAX_ROUTES];
+#endif
+int rts_top;
+
+struct interface ifs[MAX_IFACES];
+int ifs_top;
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+/*
+ * Our version of the perror routine... just make sure we ID things first!
+ */
+#define PERR(x) {(void)syslog(LOG_ERR,x);}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+/*
+ * Some driver routing error checking macros...
+ * Note that these require that the symbol IF_NAME be defined as the
+ * name of the driver; e.g. #define IF_NAME "slip"
+ */
+
+#define CK_MNULL(x) \
+ if((x)==NULL){ \
+ (void)fprintf(stderr,"%sInternal error: NULL message buffer passed to %s driver\n",progname,IF_NAME);\
+ return -1;\
+ }
+
+#define CK_IFNULL(x) \
+ if((x)==NULL){ \
+ (void)fprintf(stderr,"%sInternal error: NULL interface passed to %s driver\n",progname,IF_NAME);\
+ return -1;\
+ }
+
+#define CK_IFTYPE(x,y) \
+ if((x)->type != (y)){ \
+ (void)fprintf(stderr,"%sInternal error: incorrect interface type passed to %s driver\n",progname,IF_NAME);\
+ return -1;\
+ }
+
+#define CK_IFTYPE2(x,y,z) \
+ if(((x)->type != (y)) && ((x)->type != (z))){ \
+ (void)fprintf(stderr,"%sInternal error: incorrect interface type passed to %s driver\n",progname,IF_NAME);\
+ return -1;\
+ }
+
+#define CK_IFOPEN(x) \
+ if(((x)->status & IF_STAT_OPEN)==0){ \
+ (void)fprintf(stderr,"%sInternal error: interface has not been opened (%s driver)\n",progname,IF_NAME);\
+ return -1;\
+ }
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/* slip.c */
+int slip_open();
+int slip_send();
+int slip_read();
+
+/* ip.c */
+int ip_open();
+int ip_send();
+int ip_read();
+
+/* tun.c */
+int tun_open();
+int tun_send();
+int tun_read();
+
+/* route.c */
+int read_routes();
+
+/* config.c */
+int read_config();
+
+/* run.c */
+void send_stats();
+int run_it();
--- /dev/null
+/* main.c main entrypoint
+ *
+ * $Id: main.c,v 1.5 1995/03/19 17:21:06 bdale Exp $
+ *
+ * Copyright 1991, Michael Westerhof, Sun Microsystems, Inc.
+ * This software may be freely used, distributed, or modified, providing
+ * this header is not removed.
+ *
+ */
+
+#ifdef LINUX
+#define __USE_BSD_SIGNAL
+#endif
+#include "ipip.h"
+#include "version.h"
+#include <stdio.h>
+#include <time.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <signal.h>
+#include <setjmp.h>
+#include <syslog.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#ifdef LINUX
+sigjmp_buf restart_env;
+#else
+jmp_buf restart_env;
+#endif
+static void hupper(int sig);
+jmp_buf term_env;
+static void terminator();
+
+char *configfile, *routefile;
+int version_only;
+
+void
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ int n, i, oops, help;
+ time_t now;
+ FILE *pid_file;
+
+ debugd = 0;
+ debugt = 0;
+ help = 0;
+ no_timestamp = 0;
+ version_only = 0;
+ routefile = DEFAULTROUTE;
+ configfile = DEFAULTCONFIG;
+ stat_interval = -1; /* print at exit only */
+
+ /* let's use syslogd for all this junk... */
+ openlog("ipip", LOG_PID | LOG_NOWAIT, IPIP_SYSLOG);
+
+ (void)sprintf(progname,"ipip[%d]: ",getpid());
+
+ /* log our pid so that we can get kicked during log rotation */
+ if(!(pid_file = fopen(PIDLOG,"w"))) {
+ syslog(LOG_CRIT, "could not log pid to file %s",PIDLOG);
+ exit(1);
+ }
+ fprintf(pid_file,"%d\n",getpid());
+ fclose(pid_file);
+
+ /* Process arguments */
+ oops = 0;
+ for(i=1;((i<argc)&&(oops==0));i++){
+ if(strcmp(argv[i],"-c")==0){
+ i++;
+ if(i<argc)configfile = argv[i];
+ else oops++;
+ } else if(strcmp(argv[i],"-r")==0){
+ i++;
+ if(i<argc)routefile = argv[i];
+ else oops++;
+ } else if(strcmp(argv[i],"-s")==0){
+ i++;
+ if(i<argc)stat_interval = atoi(argv[i]) * 60;
+ else oops++;
+ } else if(strcmp(argv[i],"-d")==0){
+ debugd++;
+ } else if(strcmp(argv[i],"-t")==0){
+ debugt++;
+ } else if(strcmp(argv[i],"-v")==0){
+ version_only++;
+ } else if(strcmp(argv[i],"-np")==0){
+ progname[0] = '\0';
+ } else if(strcmp(argv[i],"-nts")==0){
+ no_timestamp++;
+ } else if(strcmp(argv[i],"-help")==0){
+ help++;
+ } else oops++;
+ }
+
+ if(oops){
+ (void)fprintf(stderr,"%sUsage: %s [-help] [-c <configfile>] [-r <routefile>] [-s <minutes>] [-np] [-nts] [-t] [-d] [-v]\n",
+ progname,argv[0]);
+ (void)printf("%sexit (syntax error)\n",progname);
+ exit(1);
+ }
+
+ if(help){
+ (void)printf("%s Options are:\n",progname);
+ (void)printf("%s -help Print this summary of options\n",
+ progname);
+ (void)printf("%s -v Print just the version number and exit\n",
+ progname);
+ (void)printf("%s -c file Use the supplied filename as the config file\n",
+ progname);
+ (void)printf("%s -r file Use the supplied filename as the route file\n",
+ progname);
+ (void)printf("%s -s n Report statistics every n minutes\n",
+ progname);
+ (void)printf("%s -np Don't print the ipip[1234]: prefix\n",
+ progname);
+ (void)printf("%s -nts Don't include a timestamp in the statistics\n",
+ progname);
+ (void)printf("%s -t Turn on tracing of incoming packets\n",
+ progname);
+ (void)printf("%s -d Print out some debugging information\n",
+ progname);
+ exit(0);
+ }
+
+#ifdef NO_STRTOUL
+ if(strtol("0xffffffff",NULL,0)!=0xffffffff){
+ (void)fprintf(stderr,"%sAssertion failed: this program cannot properly read\n",progname);
+ (void)fprintf(stderr,"%sunsigned numbers from the config files. See the\n",progname);
+ (void)fprintf(stderr,"%ssource code for details. ABORTED.\n",progname);
+ (void)printf("%sexit (program error)\n",progname);
+ exit(2);
+ }
+#endif
+
+ if(setjmp(term_env)!=0){
+ send_stats(1); /* force print of statistics */
+ now = time(NULL);
+ syslog(LOG_CRIT, "exit (killed)");
+ exit(0);
+ }
+
+ (void)signal(SIGTERM, terminator);
+ (void)signal(SIGINT, terminator);
+
+ /* Say hello to the world */
+ syslog(LOG_DEBUG,"version %s Copyright 1991, Michael Westerhof.",VERS);
+
+ if(version_only!=0)exit(0);
+
+ /* Read the configuration file */
+
+ if(read_config(configfile)<0){
+ syslog(LOG_CRIT, "exit (config file error)");
+ exit(1);
+ }
+
+ /* Here's where we restart when we get a SIGHUP signal */
+#ifdef LINUX
+ if(sigsetjmp(restart_env,1)==0){
+#else
+ if(setjmp(restart_env,1)==0){
+#endif
+ (void)signal(SIGHUP, hupper);
+ }
+
+ /* make sure to close and reopen the log channel if we get a SIGHUP,
+ since it might mean the log file was just rotated! */
+ closelog();
+ openlog("ipip", LOG_PID | LOG_NOWAIT, IPIP_SYSLOG);
+
+ /* Read the route tables */
+
+ if(read_routes(routefile)<0){
+ syslog(LOG_CRIT, "exit (routes file error)");
+ exit(1);
+ }
+
+ /* flush the stdout buffer before we start to run */
+/* (void)fflush(stdout); */
+
+ /* And run it! */
+
+ n = run_it();
+ if(n<0){
+ syslog(LOG_CRIT, "exit (I/O error)");
+ exit(1);
+ }
+
+ /* Should never return this way... but stuff happens... */
+ send_stats(1);
+ syslog(LOG_CRIT, "exit (no error code?)");
+ exit(0);
+}
+
+static void
+hupper(int sig)
+{
+ syslog(LOG_DEBUG, "SIGHUP received");
+#ifdef LINUX
+ siglongjmp(restart_env, 1);
+#else
+ longjmp(restart_env, 1);
+#endif
+}
+
+static void
+terminator()
+{
+ longjmp(term_env, 1);
+}
--- /dev/null
+/* route.c Route file reader
+ *
+ * $Id: route.c,v 1.3 1995/03/19 17:21:06 bdale Exp $
+ *
+ * Copyright 1991, Michael Westerhof, Sun Microsystems, Inc.
+ * This software may be freely used, distributed, or modified, providing
+ * this header is not removed.
+ *
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <memory.h>
+#include <fcntl.h>
+#include <string.h>
+#include <ctype.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <syslog.h>
+#include <stdlib.h>
+
+#include "ipip.h"
+
+static void rerr(); /* General error printer */
+static void init_route();
+static void r_route();
+static void print_routes();
+static void sort_routes();
+
+static int rlineno;
+static int rerrflag;
+
+/*
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * open and read the route file
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ */
+int
+read_routes(f)
+char *f;
+{
+ FILE *cf;
+ char buf[256], *p;
+
+ init_route();
+
+/* Open the route file */
+ if((cf = fopen(f,"r"))==NULL){
+ (void)fprintf(stderr,"%sRoute file %s not found or could not be opened\n",progname,f);
+ return -1;
+ }
+
+ while(fgets(buf, 255, cf)!=NULL){
+ rlineno++;
+ if((p = strtok(buf, " \t\n\r"))==NULL)continue;
+ if(*p=='#' || *p==';')continue;
+
+ if(strcmp(p,"route")==0)r_route();
+/* else if(strcmp(p,"whatever")==0)r_dowhatever(); */
+ else rerr("Unrecognized command: %s",p);
+ }
+
+ if(rts_top==0)rerr("No routes defined","");
+
+ if(debugd)print_routes();
+
+ sort_routes();
+
+ if(debugd)print_routes();
+
+ return rerrflag;
+}
+/*
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Initialize defaults and null route entries
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ */
+static void
+init_route()
+{
+ int i;
+
+ for(i=0;i<MAX_ROUTES;i++){
+ rts[i].ipaddr = 0;
+ rts[i].mask = 0xffffffff;
+ rts[i].destif = NULL;
+ rts[i].destaddr = 0;
+ rts[i].destport = 0;
+ rts[i].hits = 0;
+ }
+ rts_top = 0;
+
+ rlineno = 0;
+ rerrflag = 0;
+}
+
+/*
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Print out the route table (DEBUG)
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ */
+static void
+print_routes()
+{
+ int i, port, type;
+ unsigned char *p, *q;
+ char *id;
+ unsigned int m;
+
+ if(rerrflag==0)(void)syslog(LOG_DEBUG,"%d routes:", rts_top);
+ else (void)syslog(LOG_DEBUG,"%d routes (there are errors):", rts_top);
+ for(i=0;i<rts_top;i++){
+ p = (unsigned char *)&rts[i].ipaddr;
+ q = (unsigned char *)&rts[i].destaddr;
+ if(rts[i].destif != NULL){
+ id = rts[i].destif->id;
+ type = rts[i].destif->type;
+ } else {
+ id = "unknown";
+ type = IF_TYPE_NONE;
+ }
+ port = ntohs(rts[i].destport);
+ m = ntohl(rts[i].mask);
+
+ if((type == IF_TYPE_SLIP)||
+ (type == IF_TYPE_TUN)){
+ (void)syslog(LOG_DEBUG,"ip %d.%d.%d.%d mask 0x%08x interface %s\n",
+ p[0],p[1],p[2],p[3],m,id);
+ } else if(type == IF_TYPE_IPIP){
+ (void)syslog(LOG_DEBUG,"ip %d.%d.%d.%d mask 0x%08x interface %s ip %d.%d.%d.%d\n",
+ p[0],p[1],p[2],p[3],m,id,
+ q[0],q[1],q[2],q[3]);
+ } else {
+ (void)syslog(LOG_DEBUG,"ip %d.%d.%d.%d mask 0x%08x interface %s ip %d.%d.%d.%d port %d\n",
+ p[0],p[1],p[2],p[3],m,id,
+ q[0],q[1],q[2],q[3],port);
+ }
+ }
+}
+
+/*
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Print a general route file error
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ */
+static void
+rerr(s,a)
+char *s;
+char *a;
+{
+ (void)syslog(LOG_ERR,"Route file error at line %d:\n",rlineno);
+ (void)syslog(LOG_ERR,s,a);
+ rerrflag--;
+}
+
+/*
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Handle the "route" command
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ */
+static void
+r_route()
+{
+ int i, syntax;
+ char *q;
+ struct hostent *he;
+
+ if(rts_top>=MAX_ROUTES){
+ rerr("Too many routes defined","");
+ return;
+ }
+
+ syntax = 0;
+
+ if((q = strtok((char *)NULL, " \t\n\r"))){
+ if((he = gethostbyname(q))){
+ (void)memcpy((char *)&rts[rts_top].ipaddr,
+ he->h_addr_list[0], 4);
+ } else {
+ if((rts[rts_top].ipaddr = inet_addr(q)) == 0xffffffff)
+ rerr("Bad IP address: %s",q);
+ }
+ } else syntax++;
+
+ if((q = strtok((char *)NULL, " \t\n\r"))){
+ rts[rts_top].mask = htonl(strtoul(q, NULL, 0));
+ } else syntax++;
+
+ if((q = strtok((char *)NULL, " \t\n\r"))){
+ for(i=0;i<ifs_top;i++){
+ if(strcmp(q,ifs[i].id)==0)rts[rts_top].destif = &ifs[i];
+ }
+ if(rts[rts_top].destif == NULL)
+ rerr("Interface %s not defined",q);
+ } else syntax++;
+
+ if((q = strtok((char *)NULL, " \t\n\r"))){
+ if((he = gethostbyname(q))){
+ (void)memcpy((char *)&rts[rts_top].destaddr,
+ he->h_addr_list[0], 4);
+ } else {
+ if((rts[rts_top].destaddr = inet_addr(q)) == (unsigned long)-1)
+ rerr("Bad destination IP address: %s",q);
+ }
+ }
+
+ if((q = strtok((char *)NULL, " \t\n\r"))){
+ rts[rts_top].destport = htons((unsigned short)atoi(q));
+ }
+
+ if(syntax)rerr("Syntax error (route <ipaddr> <mask> <iface> [<destipaddr> [<destport>]]","");
+
+ rts_top++;
+}
+
+static void
+sort_routes()
+{
+ struct ipip_route *tmptable ;
+ static unsigned long mask_entries[] = { \
+ 0xffffffff, 0xfffffffe, 0xfffffffc, 0xfffffff8, \
+ 0xfffffff0, 0xffffffe0, 0xffffffc0, 0xffffff80, \
+ 0xffffff00, 0xfffffe00, 0xfffffc00, 0xfffff800, \
+ 0xfffff000, 0xffffe000, 0xffffc000, 0xffff8000, \
+ 0xffff0000, 0xfffe0000, 0xfffc0000, 0xfff80000, \
+ 0xfff00000, 0xffe00000, 0xffc00000, 0xff800000, \
+ 0xff000000, 0xfe000000, 0xfc000000, 0xf8000000, \
+ 0xf0000000, 0xe0000000, 0xc0000000, 0x80000000, \
+ 0x00000000 } ;
+ int i, j, newrows ;
+
+ tmptable = malloc ( (rts_top+1) * sizeof(struct ipip_route) ) ;
+
+ if (tmptable == NULL) {
+ rerr("Unable to allocate memory to resort table","");
+ return ;
+ }
+
+ /* Search the original table 32 times for each of the 32 possible */
+ /* masks. Copy the most specific routes to the tmptable first */
+ newrows = 0;
+ for ( i = 0 ; i <= 32 ; i++ )
+ for ( j = 0 ; j < rts_top ; j++ )
+ if (rts[j].mask == htonl(mask_entries[i]))
+ tmptable[newrows++] = rts[j];
+
+ /* Copy the tmptable back to original */
+ for ( i = 0 ; i < rts_top ; i++ )
+ rts[i] = tmptable[i] ;
+ free (tmptable);
+}
--- /dev/null
+/* run.c The main command loop
+ *
+ * $Id: run.c,v 1.10 1995/03/19 17:21:06 bdale Exp $
+ *
+ * Copyright 1991, Michael Westerhof, Sun Microsystems, Inc.
+ * This software may be freely used, distributed, or modified, providing
+ * this header is not removed.
+ *
+ */
+
+#include "ipip.h"
+
+#include <time.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netdb.h>
+#include <fcntl.h>
+#include <memory.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <syslog.h>
+extern int errno;
+
+static int handle();
+static int find_route();
+static void tracer();
+
+int martian_count = 3;
+unsigned int martians[] = { 0x7f000001, 0xffffffff, 0x00000000 };
+
+time_t last_send;
+/* This is a loop counter for misc stuff. We don't want to burden the
+ I/O system if we don't have to, so this is designed so that we will
+ be able to see if we have to print stats or fflush() no more often
+ than once per second if we are busy. If we are idle, the time value
+ to the select() call will bring the delay up to 10 seconds. So, the
+ stats output and the flush of stdio() should be within 10 seconds of
+ the correct time. */
+#define SEND_CHECK_CNT 100;
+
+/*
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Open all io, then start running it!
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ */
+int
+run_it()
+{
+ int i, j, nb, more_io, checker;
+ fd_set readfds;
+ struct timeval wait;
+
+ for(i=0;i<ifs_top;i++){
+ if(ifs[i].type == IF_TYPE_NONE)continue;
+ if(debugd)
+ syslog(LOG_DEBUG,"opening interface %s",ifs[i].id);
+ j = ifs[i].ifopen(&ifs[i]);
+ if(j<0)return j;
+ }
+
+ if(debugd)
+ syslog(LOG_DEBUG,"initialization complete");
+
+ last_send = time(NULL);
+ checker = 0;
+
+ for(;;){
+
+ FD_ZERO(&readfds);
+
+ more_io = 0;
+
+ for(i=0;i<ifs_top;i++){
+ if((ifs[i].type != IF_TYPE_NONE) &&
+ (ifs[i].status & IF_STAT_OPEN)){
+ FD_SET(ifs[i].fd, &readfds);
+ if(ifs[i].status & IF_STAT_CALL_AGAIN)more_io++;
+ }
+ }
+
+ if(more_io){
+ wait.tv_sec = 0; /* Don't wait long! */
+ wait.tv_usec = 10000; /* 10 msecs if chars in buffer */
+ } else {
+ wait.tv_sec = 10; /* lets keep things going... */
+ wait.tv_usec = 0; /* but slowly is ok */
+ checker = 0; /* make sure we check the time */
+ }
+
+ nb = select(FD_SETSIZE,&readfds,(fd_set *)0,(fd_set *)0,&wait);
+
+ if(nb < 0){
+ if(errno == EINTR)continue; /* Ignore this error */
+ PERR("select in run_it()");
+ return -1;
+ }
+
+ for(i=0;i<ifs_top;i++){
+ if((ifs[i].type != IF_TYPE_NONE) &&
+ (ifs[i].status & IF_STAT_OPEN)){
+ if(FD_ISSET(ifs[i].fd, &readfds) ||
+ (ifs[i].status & IF_STAT_CALL_AGAIN)){
+ if(handle(&ifs[i])<0) {
+ PERR("handle in run_it()");
+ return -1;
+ }
+ }
+ }
+ } /* for each interface */
+
+ if(checker <= 0){
+ send_stats(0); /* see if we must */
+ checker = SEND_CHECK_CNT; /* reset counter */
+ } else {
+ checker--;
+ }
+
+ } /* forever */
+}
+
+/*
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Handle the read/route/send stuff
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ */
+static int
+handle(ifp)
+struct interface *ifp;
+{
+ struct message m;
+ int n;
+#ifdef AMPRONLY
+ unsigned int srcip, dstip;
+#endif
+
+ m.length = 0;
+ m.from_if = ifp;
+ m.to_if = NULL;
+ m.fip = 0;
+ m.tip = 0;
+ m.fport = 0;
+ m.tport = 0;
+
+ n = ifp->ifread(ifp, &m);
+ if(n <= 0) return n; /* error or packet not yet complete */
+
+ m.from_if->in++;
+
+ if(find_route(&m) < 0) {
+ PERR("find_route() failed in handle()");
+ return -1;
+ }
+
+#ifdef AMPRONLY
+ /* this is a really, really rude hack... it will prevent any frames
+ from being switched that have source or destination outside of
+ net 44 */
+
+ (void)memcpy( (char *)&srcip, (char *)m.msg + 12, 4);
+ (void)memcpy( (char *)&dstip, (char *)m.msg + 16, 4);
+
+#ifdef notdef
+ syslog(LOG_DEBUG,"from ip %lx, to ip %lx", srcip, dstip);
+#endif
+
+ if ((( srcip & 0xff ) != 44) ||
+ (( dstip & 0xff ) != 44)) {
+ m.to_if=NULL; /* drop frame on the floor */
+ if(debugt)tracer(&m); /* Trace the message */
+ return 0; /* No route found */
+ }
+#endif
+
+#ifndef BDALE
+ /* if this is Bdale's compilation, we need to be able to go back out
+ the same interface! */
+ if(m.from_if==m.to_if){
+ m.to_if=NULL; /* Can't go out same iface! */
+ m.from_if->looped_in++;
+ }
+#endif
+
+ if(debugt)tracer(&m); /* Trace the message */
+
+ if(m.to_if==NULL) {
+ PERR("route not found in handle()");
+ return 0; /* No route found */
+ }
+
+ if (m.to_if->ifsend(m.to_if, &m) < 0) {
+ PERR("ifsend() failed in handle()");
+ return -1;
+ }
+ m.to_if->out++;
+
+ return 1;
+}
+
+/*
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Print a trace of a message
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ */
+static void
+tracer(m)
+struct message *m;
+{
+ char *fromid, *toid, fbuf[32], tbuf[32];
+ unsigned char *f, *t, *iphdr;
+ int ftype, ttype;
+
+ fromid = m->from_if->id;
+ ftype = m->from_if->type;
+ f = (unsigned char *)&m->fip;
+ if(ftype == IF_TYPE_IPUDP)
+ (void)sprintf(fbuf,"(%d.%d.%d.%d:%d)",f[0],f[1],f[2],f[3],ntohs(m->fport));
+ else if(ftype == IF_TYPE_IPIP)
+ (void)sprintf(fbuf, "(%d.%d.%d.%d)", f[0], f[1], f[2], f[3]);
+ else fbuf[0] = '\0';
+
+ if (m->to_if) {
+ toid = m->to_if->id;
+ ttype = m->to_if->type;
+ t = (unsigned char *)&m->tip;
+ } else {
+ toid = "BitBucket";
+ ttype = IF_TYPE_NONE;
+ t = (unsigned char *)&m->tip;
+ }
+ if(ttype == IF_TYPE_IPUDP)
+ (void)sprintf(tbuf,"(%d.%d.%d.%d:%d)",t[0],t[1],t[2],t[3],ntohs(m->tport));
+ else if(ttype == IF_TYPE_IPIP)
+ (void)sprintf(tbuf, "(%d.%d.%d.%d)",t[0],t[1],t[2],t[3]);
+ else tbuf[0] = '\0';
+
+ iphdr = m->msg;
+
+ syslog(LOG_DEBUG,"%d.%d.%d.%d->%d.%d.%d.%d len %d [%s%s->%s%s]",
+ iphdr[12], iphdr[13], iphdr[14], iphdr[15],
+ iphdr[16], iphdr[17], iphdr[18], iphdr[19],
+ m->length, fromid, fbuf, toid, tbuf);
+}
+
+/*
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * find a route for a message
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ */
+
+static int
+find_route(m)
+struct message *m;
+{
+ int i;
+ unsigned int d;
+
+ if(m==NULL) return -1; /* major internal problem :-) */
+
+ if(m->length < 20){
+ m->to_if = NULL;
+ return 0;
+ }
+
+ (void)memcpy( (char *)&d, (char *)m->msg + 16, 4);
+
+ for(i=0;i<martian_count;i++){
+ if(d == htonl(martians[i])){ /* Bad address! */
+ m->from_if->martians_in++;
+ m->to_if = NULL;
+ return 0;
+ }
+ }
+
+ for(i=0;i<rts_top;i++){
+ if((rts[i].ipaddr & rts[i].mask) == (d & rts[i].mask)){
+ m->to_if = rts[i].destif;
+ m->tip = rts[i].destaddr;
+ m->tport = rts[i].destport;
+ rts[i].hits++;
+ return 1;
+ }
+ }
+ m->to_if = NULL;
+ return 0;
+}
+
+/*
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Send the statistics if it's time to do so...
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ */
+
+void
+send_stats(force)
+int force; /* non-zero to force a stat print */
+{
+ int i;
+ time_t now;
+ struct tm *t;
+ char cnow[32];
+
+ if(stat_interval==0) return; /* no stat print at all? */
+
+ now = time(NULL);
+
+ if(force==0){ /* if not being forced */
+ if(stat_interval>0){ /* and the interval is > 0 */
+ if(now < (last_send + stat_interval)) return;
+ }
+ }
+
+ if(no_timestamp){
+ cnow[0] = '\0';
+ } else {
+ t = localtime(&now);
+ (void)sprintf(cnow,"%2d/%2d/%2d %2d:%2d:%2d ",t->tm_mon + 1,
+ t->tm_mday,t->tm_year,t->tm_hour,t->tm_min,t->tm_sec);
+ }
+
+ for(i=0;i<ifs_top;i++){
+ if(ifs[i].type == IF_TYPE_NONE)continue;
+ syslog(LOG_DEBUG,"%s%-4s in %4ld out %4ld baddr %ld loop %ld bogus %ld ovrn %ld\n",
+ cnow, ifs[i].id, ifs[i].in, ifs[i].out,
+ ifs[i].martians_in,ifs[i].looped_in,
+ ifs[i].bogus_in, ifs[i].out_overruns);
+ }
+
+ last_send = now;
+}
--- /dev/null
+The machine col.hp.com runs a "bent pipe" ipip router. The machine
+relay.code.org runs a serial link to a Gracilis switch, a tunnel driver
+interface to the local protocol stack, and ipip back to col.hp.com.
+
+The munge script in the col.hp.com directory is worth a look-see for net-44
+gateway sysops!
+
+Bdale
--- /dev/null
+; ipip config file for hpcsos.col.hp.com
+;
+; open subnet connections to neighbor wormhole sites using IP
+interface open ip null 4
+;
+; maintain ability to receive frames sent to us on 94
+interface legacy ip null 94
+;
--- /dev/null
+#!/bin/bash
+#
+# Script to process a "gateways" file into the form needed by
+# the Westerhof "ipip" daemon.
+#
+# gateway file on stdin, ipip format route file on stdout
+
+echo "#\n# ipip route table built by $LOGNAME on `date`\n#\n# local routes"
+echo "route 44.32.0.0 0xffff0000 open 192.133.104.8"
+echo "route 44.20.0.0 0xffff0000 open 192.195.73.3"
+echo "#\n# quasi-local routes - we're the open subnet relay"
+echo "route 44.130.48.0 0xffffff00 open 15.15.80.34"
+echo "#\n# remote routes"
+
+fgrep encap | grep "^route" | grep -v "15.255.240" | \
+awk '{
+ split($3, s, "/")
+ split(s[1], n,".")
+ if (n[1] == "") n[1]="0"
+ if (n[2] == "") n[2]="0"
+ if (n[3] == "") n[3]="0"
+ if (n[4] == "") n[4]="0"
+ if (s[2] == "1") mask="0x80000000"
+ else if (s[2] == "2") mask="0xc0000000"
+ else if (s[2] == "3") mask="0xe0000000"
+ else if (s[2] == "4") mask="0xf0000000"
+ else if (s[2] == "5") mask="0xf8000000"
+ else if (s[2] == "6") mask="0xfc000000"
+ else if (s[2] == "7") mask="0xfe000000"
+ else if (s[2] == "8") mask="0xff000000"
+ else if (s[2] == "9") mask="0xff800000"
+ else if (s[2] == "10") mask="0xffc00000"
+ else if (s[2] == "11") mask="0xffe00000"
+ else if (s[2] == "12") mask="0xfff00000"
+ else if (s[2] == "13") mask="0xfff80000"
+ else if (s[2] == "14") mask="0xfffc0000"
+ else if (s[2] == "15") mask="0xfffe0000"
+ else if (s[2] == "16") mask="0xffff0000"
+ else if (s[2] == "17") mask="0xffff8000"
+ else if (s[2] == "18") mask="0xffffc000"
+ else if (s[2] == "19") mask="0xffffe000"
+ else if (s[2] == "20") mask="0xfffff000"
+ else if (s[2] == "21") mask="0xfffff800"
+ else if (s[2] == "22") mask="0xfffffc00"
+ else if (s[2] == "23") mask="0xfffffe00"
+ else if (s[2] == "24") mask="0xffffff00"
+ else if (s[2] == "25") mask="0xffffff80"
+ else if (s[2] == "26") mask="0xffffffc0"
+ else if (s[2] == "27") mask="0xffffffe0"
+ else if (s[2] == "28") mask="0xfffffff0"
+ else if (s[2] == "29") mask="0xfffffff8"
+ else if (s[2] == "30") mask="0xfffffffc"
+ else if (s[2] == "31") mask="0xfffffffe"
+ else if (s[2] == "32") mask="0xffffffff"
+ printf "route %s.%s.%s.%s %s open %s\n",n[1],n[2],n[3],n[4],mask,$5 }'
+# printf "route %s %s open %s\n", subnet, mask, $5 }'
+
+echo "#\n# the world via Brian's machine at UCSD - mirrorshades.ucsd.edu"
+echo "route 0.0.0.0 0x00000000 open 128.54.16.18"
+echo "#\n# the end"
--- /dev/null
+#
+# ipip route table built by root on Sun Mar 19 00:00:17 MST 1995
+#
+# local routes
+route 44.32.0.0 0xffff0000 open 192.133.104.8
+route 44.20.0.0 0xffff0000 open 192.195.73.3
+#
+# quasi-local routes - we're the open subnet relay
+route 44.130.48.0 0xffffff00 open 15.15.80.34
+#
+# remote routes
+#
+# note: since these routes aren't normally published, I'm clipping them
+# and just showing an "example" entry... this list will normally be
+# much longer when munge does it's thing - Bdale
+#
+route 44.2.0.0 0xfffff000 open 0.0.0.0
+#
+# the world via Brian's machine at UCSD - mirrorshades.ucsd.edu
+route 0.0.0.0 0x00000000 open 128.54.16.18
+#
+# the end
--- /dev/null
+; config file for ipip daemon
+;
+; serial line to gw.n3eua.ampr.org
+interface gwsl slip /dev/tty01 19200
+;
+; tunnel driver to get to local protocol stack
+interface sloop tunnel /dev/tun0 0
+;
+; the rest of the world - send on 4, accept both 4 and 94
+interface open ip null 4
+interface legacy ip null 94
+;
+; the end
--- /dev/null
+#
+# ipip route table built by bdale on Wed Sep 1 12:05:52 MDT 1993
+#
+# Note that needs to be most specific first to least specific last, or
+# so it seems to me...
+#
+# local routes
+route 44.32.0.2 0xffffffff sloop
+route 44.32.0.0 0xffff0000 gwsl
+#
+# default everything else via hpcsos, for now...
+route 0.0.0.0 0x00000000 open 15.255.240.16
+#
+# the end
--- /dev/null
+;
+; syntax is VERY rigid:
+;
+;interface <name> udp null <udp-portnumber-on-which-to-listen>
+;interface <name> ip null <ip-protocol-id>
+;interface <name> slip </dev/ttyname> <speed>
+;interface <name> tunnel </dev/tundevicename> 0
+;
+; Open subnet connections to neighbor wormhole sites using IP
+;
+; 94 is the old one that will be phased out someday.
+; 4 is the new one. Both interfaces are defined here
+; so that the IPIP daemon can handle incoming packets
+; to either one.
+;
+interface open ip null 94
+interface new ip null 4
+;
+; SLIP link from the localhost
+;
+interface local slip /dev/ttypf 38400
+;
--- /dev/null
+#
+# ipip route table built by n8fow on Wed Oct 26 06:40:21 GMT 1994
+#
+# local routes
+route 44.102.0.0 0xffff0000 local
+route 44.135.83.0 0xffffff00 local
+#
+# quasi-local routes - we're the open subnet relay
+#
+# remote routes
+route 44.4.0.0 0xffff0000 open 192.135.76.66
+route 44.4.24.0 0xfffff800 open 36.55.0.59
+route 44.4.40.0 0xffffff00 open 198.31.4.102
+route 44.6.0.0 0xffff0000 open 128.149.37.26
+route 44.16.0.0 0xffff0000 open 128.149.37.26
+route 44.17.0.0 0xffff0000 open 128.149.37.26
+route 44.18.0.0 0xffff0000 open 128.149.37.26
+route 44.10.0.0 0xffff0000 open 131.215.67.192
+route 44.14.0.0 0xffff0000 open 128.171.41.250
+route 44.20.0.0 0xffff0000 open 15.255.240.16
+route 44.32.0.0 0xffff0000 open 15.255.240.16
+route 44.24.0.0 0xffff0000 open 192.135.191.250
+route 44.24.111.0 0xffffff00 open 198.187.188.1
+route 44.28.0.0 0xffff0000 open 129.120.67.190
+route 44.78.0.0 0xffff0000 open 129.120.67.190
+route 44.28.2.0 0xffffff00 open 161.109.160.14
+route 44.30.0.0 0xffff0000 open 128.123.9.36
+route 44.77.0.0 0xffffff00 open 128.123.9.36
+route 44.34.8.0 0xffffffc0 open 141.225.1.189
+route 44.36.0.0 0xffff0000 open 130.207.230.75
+route 44.40.0.0 0xffff0000 open 128.110.45.34
+route 44.42.0.0 0xffff0000 open 148.114.0.217
+route 44.108.0.0 0xffff0000 open 148.114.0.217
+route 44.44.0.0 0xffff0000 open 192.153.4.3
+route 44.88.1.0 0xffffff00 open 192.153.4.3
+route 44.88.2.0 0xffffff00 open 192.153.4.3
+route 44.88.3.0 0xffffff00 open 192.153.4.3
+route 44.88.7.0 0xffffff00 open 192.153.4.3
+route 44.88.9.0 0xffffff00 open 192.153.4.3
+route 44.46.0.0 0xffff8000 open 143.195.1.8
+route 44.72.0.0 0xffffc000 open 143.195.1.8
+route 44.72.248.0 0xfffff800 open 143.195.1.8
+route 44.72.75.0 0xffffff00 open 143.195.1.8
+route 44.72.90.0 0xffffff00 open 143.195.1.8
+route 44.46.128.0 0xffff8000 open 129.237.116.31
+route 44.122.1.0 0xffffff00 open 129.237.116.31
+route 44.48.0.0 0xffff0000 open 129.79.16.175
+route 44.52.0.0 0xffffff00 open 18.72.0.51
+route 44.52.2.0 0xffffff00 open 18.72.0.51
+route 44.56.0.0 0xffff0000 open 18.72.0.51
+route 44.104.0.0 0xffff0000 open 18.72.0.51
+route 44.62.0.0 0xffff0000 open 192.100.76.49
+route 44.64.0.0 0xffff0000 open 128.235.1.143
+route 44.68.16.0 0xfffff000 open 128.235.1.143
+route 44.68.32.0 0xffffe000 open 128.235.1.143
+route 44.68.64.0 0xffffc000 open 128.235.1.143
+route 44.131.224.0 0xfffffc00 open 128.235.1.143
+route 44.131.228.0 0xfffffc00 open 128.235.1.143
+route 44.131.232.0 0xfffff800 open 128.235.1.143
+route 44.131.240.0 0xfffff000 open 128.235.1.143
+route 44.65.0.0 0xffff0000 open 138.60.14.20
+route 44.66.0.0 0xffff0000 open 138.60.14.20
+route 44.80.0.0 0xffffe000 open 138.60.14.20
+route 44.68.0.0 0xfffff000 open 192.67.243.28
+route 44.88.0.0 0xffff0000 open 192.67.243.28
+route 44.69.108.0 0xffffff00 open 128.153.32.48
+route 44.69.174.0 0xffffff00 open 128.226.3.20
+route 44.69.175.0 0xffffff00 open 128.226.3.20
+route 44.69.176.0 0xffffff00 open 128.226.3.20
+route 44.69.177.0 0xffffff00 open 128.226.3.20
+route 44.69.178.0 0xffffff00 open 128.226.3.20
+route 44.69.224.0 0xfffff000 open 192.188.232.10
+route 44.70.244.0 0xfffffc00 open 150.134.40.1
+route 44.70.220.0 0xfffffc00 open 150.134.40.1
+route 44.70.225.0 0xffffff00 open 137.148.18.101
+route 44.70.248.0 0xfffff800 open 137.148.18.101
+route 44.70.241.0 0xffffff00 open 130.101.232.100
+route 44.72.0.0 0xffff0000 open 136.176.5.101
+route 44.73.0.0 0xffff0000 open 136.176.5.101
+route 44.72.123.0 0xffffff00 open 136.176.5.9
+route 44.73.10.0 0xffffff00 open 136.176.5.9
+route 44.72.18.0 0xfffffffc open 199.0.154.127
+route 44.72.18.5 0xfffffffc open 199.0.154.127
+route 44.72.18.6 0xfffffffc open 199.0.154.127
+route 44.72.18.7 0xfffffffc open 199.0.154.127
+route 44.72.18.8 0xfffffffc open 199.0.154.127
+route 44.74.1.0 0xffffff00 open 128.109.57.253
+route 44.76.0.0 0xffffff00 open 128.194.135.25
+route 44.76.1.0 0xffffff00 open 128.83.167.106
+route 44.76.2.0 0xffffff00 open 130.137.112.22
+route 44.76.6.0 0xffffff00 open 130.137.112.22
+route 44.76.4.0 0xfffffe00 open 163.185.21.60
+route 44.151.44.0 0xffffff00 open 163.185.21.60
+route 44.80.32.0 0xffffff00 open 146.186.126.62
+route 44.94.0.0 0xffff0000 open 141.224.128.8
+route 44.96.1.0 0xffffff00 open 192.107.237.232
+route 44.98.24.0 0xfffff800 open 163.125.16.254
+route 44.100.0.0 0xffff0000 open 131.204.56.97
+route 44.100.144.0 0xffffff00 open 192.129.64.55
+route 44.112.0.0 0xffff0000 open 165.190.32.18
+route 44.124.12.0 0xffffff00 open 128.196.188.123
+route 44.124.11.0 0xffffff00 open 128.196.188.123
+route 44.124.13.0 0xffffff00 open 137.80.1.23
+route 44.125.128.0 0xffff8000 open 134.197.39.252
+route 44.130.12.0 0xffffff00 open 192.129.16.99
+route 44.130.29.0 0xffffff00 open 129.13.109.160
+route 44.130.41.0 0xffffff00 open 129.13.109.160
+route 44.131.1.0 0xffffff00 open 148.88.12.208
+route 44.131.25.0 0xffffff00 open 148.88.12.208
+route 44.134.112.0 0xffffff00 open 192.106.247.17
+route 44.134.128.0 0xfffffe00 open 130.192.59.20
+route 44.134.160.0 0xffffff00 open 130.192.59.20
+route 44.134.208.0 0xffffff00 open 131.114.2.6
+route 44.135.52.0 0xffffff00 open 134.117.12.10
+route 44.135.96.0 0xffffff00 open 134.117.12.10
+route 44.135.103.0 0xffffff00 open 134.117.12.10
+route 44.135.144.0 0xfffff000 open 134.117.12.10
+route 44.135.60.0 0xfffffc00 open 142.64.52.193
+route 44.135.48.0 0xfffffc00 open 198.168.101.242
+route 44.135.54.0 0xfffffc00 open 198.168.101.242
+route 44.135.66.0 0xfffffc00 open 198.168.101.242
+route 44.135.51.0 0xffffff00 open 198.73.164.42
+route 44.135.84.0 0xffffff00 open 129.97.150.251
+route 44.135.88.69 0xffffff00 open 141.117.226.101
+route 44.135.88.0 0xfffff800 open 141.117.1.101
+route 44.135.92.0 0xffffff00 open 142.204.22.11
+route 44.135.100.0 0xffffff00 open 142.237.25.240
+route 44.135.114.0 0xffffff00 open 132.225.64.3
+route 44.135.124.0 0xffffff00 open 130.179.96.132
+route 44.135.128.0 0xfffff000 open 128.233.2.119
+route 44.135.160.0 0xffffff00 open 128.189.56.150
+route 44.135.161.0 0xffffff00 open 134.87.167.182
+route 44.135.172.0 0xffffff00 open 134.87.167.182
+route 44.135.173.0 0xffffff00 open 134.87.167.182
+route 44.135.167.0 0xffffff00 open 142.207.128.73
+route 44.135.190.0 0xffffff00 open 137.82.52.113
+route 44.136.0.0 0xfffff800 open 131.236.20.70
+route 44.136.8.0 0xfffff800 open 138.25.17.19
+route 44.136.10.0 0xffffff00 open 137.111.90.111
+route 44.136.11.0 0xffffff00 open 130.155.98.235
+route 44.136.16.0 0xfffff000 open 134.148.24.200
+route 44.136.24.0 0xffffff00 open 130.130.68.40
+route 44.136.28.0 0xffffff00 open 130.130.68.40
+route 44.136.32.0 0xffffff00 open 129.180.10.44
+route 44.136.33.0 0xffffff00 open 129.180.10.44
+route 44.136.48.0 0xffffff00 open 137.166.16.250
+route 44.136.72.0 0xfffff800 open 128.250.120.17
+route 44.136.80.0 0xfffff000 open 128.250.120.17
+route 44.136.96.0 0xffffe000 open 128.250.120.17
+route 44.136.128.0 0xfffff800 open 128.250.120.17
+route 44.136.136.0 0xfffffe00 open 128.250.120.17
+route 44.136.72.0 0xfffffc00 open 131.170.114.2
+route 44.136.92.0 0xffffff00 open 131.170.114.2
+route 44.136.138.0 0xffffff00 open 131.181.5.18
+route 44.136.139.0 0xffffff00 open 131.181.5.18
+route 44.136.141.0 0xffffff00 open 131.181.5.18
+route 44.136.143.0 0xffffff00 open 131.181.5.18
+route 44.136.145.0 0xffffff00 open 131.181.5.18
+route 44.136.171.0 0xffffff00 open 192.203.213.10
+route 44.136.172.0 0xfffffc00 open 192.203.213.10
+route 44.136.176.0 0xfffff000 open 192.203.213.10
+route 44.136.192.0 0xfffff800 open 192.203.213.10
+route 44.136.200.0 0xfffffc00 open 192.203.213.10
+route 44.137.0.0 0xfffffc00 open 130.161.188.80
+route 44.137.4.0 0xffffff00 open 193.78.122.41
+route 44.137.8.0 0xffffff00 open 131.237.9.102
+route 44.137.16.0 0xffffff00 open 131.237.9.102
+route 44.137.28.0 0xffffff00 open 131.237.9.102
+route 44.137.32.0 0xffffff00 open 131.237.9.102
+route 44.137.33.0 0xffffff00 open 131.237.0.102
+route 44.138.0.0 0xffff0000 open 192.114.201.11
+route 44.139.12.3 0xffff0000 open 130.230.101.145
+route 44.139.26.0 0xffffff00 open 192.98.22.6
+route 44.139.27.0 0xffffff00 open 192.98.22.6
+route 44.139.39.0 0xffffff00 open 192.98.38.196
+route 44.140.0.0 0xffff0000 open 130.237.40.99
+route 44.144.0.0 0xffff0000 open 134.58.250.34
+route 44.154.128.0 0xfffffe00 open 155.207.18.33
+route 44.154.0.0 0xffffe000 open 147.102.81.24
+route 44.156.0.0 0xffffe000 open 148.6.80.11
+route 44.156.32.0 0xffffe000 open 152.66.86.165
+route 44.160.1.0 0xffffff00 open 137.158.130.142
+route 44.165.32.0 0xffffff00 open 158.75.10.2
+route 44.165.35.0 0xffffff00 open 158.75.10.2
+route 44.165.38.0 0xffffff00 open 158.75.10.2
+route 44.165.53.0 0xffffff00 open 158.75.10.2
+route 44.165.80.0 0xfffff000 open 148.81.12.177
+route 44.165.152.0 0xfffff800 open 149.156.70.62
+route 44.174.0.0 0xffff0000 open 150.162.61.14
+route 44.174.4.0 0xffffff00 open 200.17.225.65
+route 44.174.7.0 0xffffff00 open 143.54.36.1
+route 44.178.0.0 0xffff0000 open 192.91.186.152
+#
+# the world via Brian's machine at UCSD - mirrorshades.ucsd.edu
+route 0.0.0.0 0x00000000 open 128.54.16.18
+#
+# the end
--- /dev/null
+#!/bin/bash
+#
+# Script to process a "gateways" file into the form needed by
+# the Westerhof "ipip" daemon.
+#
+# gateway file on stdin, ipip format route file on stdout
+
+echo "#\n# ipip route table built by $LOGNAME on `date`\n#\n# local routes"
+echo "route 44.102.0.0 0xffff0000 local"
+echo "route 44.135.83.0 0xffffff00 local"
+echo "#\n# quasi-local routes - we're the open subnet relay"
+# echo "route 44.130.48.0 0xffffff00 open 15.15.80.34"
+echo "#\n# remote routes"
+
+fgrep encap | grep "^route" | grep -v "141.217.1" | \
+awk '{
+ split($3, s, "/")
+ split(s[1], n,".")
+ if (n[1] == "") n[1]="0"
+ if (n[2] == "") n[2]="0"
+ if (n[3] == "") n[3]="0"
+ if (n[4] == "") n[4]="0"
+ if (s[2] == "1") mask="0x80000000"
+ else if (s[2] == "2") mask="0xc0000000"
+ else if (s[2] == "3") mask="0xe0000000"
+ else if (s[2] == "4") mask="0xf0000000"
+ else if (s[2] == "5") mask="0xf8000000"
+ else if (s[2] == "6") mask="0xfc000000"
+ else if (s[2] == "7") mask="0xfe000000"
+ else if (s[2] == "8") mask="0xff000000"
+ else if (s[2] == "9") mask="0xff800000"
+ else if (s[2] == "10") mask="0xffc00000"
+ else if (s[2] == "11") mask="0xffe00000"
+ else if (s[2] == "12") mask="0xfff00000"
+ else if (s[2] == "13") mask="0xfff80000"
+ else if (s[2] == "14") mask="0xfffc0000"
+ else if (s[2] == "15") mask="0xfffe0000"
+ else if (s[2] == "16") mask="0xffff0000"
+ else if (s[2] == "17") mask="0xffff8000"
+ else if (s[2] == "18") mask="0xffffc000"
+ else if (s[2] == "19") mask="0xffffe000"
+ else if (s[2] == "20") mask="0xfffff000"
+ else if (s[2] == "21") mask="0xfffff800"
+ else if (s[2] == "22") mask="0xfffffc00"
+ else if (s[2] == "23") mask="0xfffffe00"
+ else if (s[2] == "24") mask="0xffffff00"
+ else if (s[2] == "25") mask="0xffffff80"
+ else if (s[2] == "26") mask="0xffffffc0"
+ else if (s[2] == "27") mask="0xffffffe0"
+ else if (s[2] == "28") mask="0xfffffff0"
+ else if (s[2] == "29") mask="0xfffffff8"
+ else if (s[2] == "30") mask="0xfffffffc"
+ else if (s[2] == "31") mask="0xfffffffe"
+ else if (s[2] == "32") mask="0xffffffff"
+ printf "route %s.%s.%s.%s %s open %s\n",n[1],n[2],n[3],n[4],mask,$5 }'
+# printf "route %s %s open %s\n", subnet, mask, $5 }'
+
+echo "#\n# the world via Brian's machine at UCSD - mirrorshades.ucsd.edu"
+echo "route 0.0.0.0 0x00000000 open 128.54.16.18"
+echo "#\n# the end"
--- /dev/null
+#! /bin/sh
+# Put any local setup commands in here
+
+echo ""
+
+# --- slip link to IPIP daemon
+#
+echo "Configuring SLIP on ptypf --- IPIP daemon..."
+/sbin/slattach -s 38400 -p slip ptypf &
+/sbin/ifconfig sl0 44.102.48.2 netmask 255.0.0.0 mtu 1024
+/sbin/route add -net 44.0.0.0 netmask 255.0.0.0 dev sl0
+#
+
+# --- slip link to NOS
+#
+echo "Configuring SLIP on ptype --- NOS..."
+/sbin/slattach -s 38400 -p slip ptype &
+/sbin/ifconfig sl1 44.102.48.2 netmask 255.255.0.0 mtu 1024
+/sbin/route add -host 44.102.48.1 dev sl1
+/sbin/route add -net 44.102.0.0 gw 44.102.48.1 netmask 255.255.0.0 dev sl1
+/sbin/route add -net 44.135.83.0 gw 44.102.48.1 netmask 255.255.255.0 dev sl1
+#
+
+# --- local addresses to loopback
+# (not really needed, but sometimes it is)
+#
+/sbin/route add -host 141.217.1.8 dev lo
+/sbin/route add -host 44.102.48.2 dev lo
+
+# --- start IPIP daemon
+# (use the while: do; done; statement to restart the IPIP
+# daemon even if you kill the process or it crashes)
+#
+echo "Starting IPIP daemon..."
+while :;
+ do /ipip/ipip -c /ipip/ipip.config -r /ipip/ipip.routes -s 0 -np -nts ;
+done &
+
+# done
--- /dev/null
+/* slip.c SLIP interface unit
+ *
+ * $Id: slip.c,v 1.11 1995/03/19 17:21:06 bdale Exp $
+ *
+ * Copyright 1991, Michael Westerhof, Sun Microsystems, Inc.
+ * This software may be freely used, distributed, or modified, providing
+ * this header is not removed.
+ */
+
+#include "ipip.h"
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netdb.h>
+#include <fcntl.h>
+#include <memory.h>
+#include <stdio.h>
+#include <string.h>
+#ifdef __bsdi__
+# include <stdlib.h>
+#else
+# include <malloc.h>
+#endif
+#include <errno.h>
+#include <syslog.h>
+
+#ifdef __bsdi__
+#define USE_TERMIOS
+#endif
+
+#ifndef USE_TERMIOS
+#ifndef USE_TERMIO
+#define USE_SGTTY
+#endif
+#endif
+
+#ifdef USE_TERMIOS
+# include <termios.h>
+# include <unistd.h>
+#endif
+
+#ifdef USE_TERMIO
+#include <sys/termio.h>
+#endif
+
+#ifdef USE_SGTTY
+#include <sgtty.h>
+#endif
+
+#ifndef FNDELAY
+#define FNDELAY O_NDELAY
+#endif
+
+extern int errno;
+
+#define IF_NAME "slip" /* for use with the error checking macros */
+
+/*
+ * Define the special characters used by SLIP
+ */
+
+#define FEND 0xc0
+#define FESC 0xdb
+#define TFEND 0xdc
+#define TFESC 0xdd
+
+/*
+ * This is the routine that assembles a slip packet, and the private
+ * data structure we need to keep track of where we are.
+ */
+
+static int assemble_slip();
+struct slippy {
+ unsigned char buffer[MAX_SIZE]; /* buffer from the serial line */
+ int bcount; /* number of total chars in buffer */
+ int bnext; /* next character to process */
+ unsigned char ipacket[MAX_SIZE]; /* the packet we are assembling */
+ int ifcount; /* total size of assembled packet */
+ int iescaped; /* flag set if we are escaped */
+};
+
+/*
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * open and initialize the IO interface. Return -1 for error.
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ */
+int slip_open(ifp)
+struct interface *ifp;
+{
+ int baudrate;
+#ifdef USE_TERMIOS
+ struct termios nterm;
+#endif
+#ifdef USE_TERMIO
+ struct termio nterm;
+#endif
+#ifdef USE_SGTTY
+ struct sgttyb nterm;
+#endif
+
+ CK_IFNULL(ifp);
+ CK_IFTYPE(ifp,IF_TYPE_SLIP);
+
+ if((ifp->status & IF_STAT_OPEN)) return 1;
+
+#ifdef __bsdi__
+ /* BSDI cares about the modem control lines, so this won't ever
+ come back unless we do the open non-blocking, then set CLOCAL. */
+ ifp->fd = open(ifp->devname, O_RDWR | O_NONBLOCK);
+#else
+ ifp->fd = open(ifp->devname, O_RDWR);
+#endif
+ if (ifp->fd<0) {
+ PERR(ifp->devname);
+ return -1;
+ }
+
+ if (fcntl(ifp->fd, F_SETFL, FNDELAY) < 0) {
+ PERR("setting non-blocking I/O on tty device");
+ return -1;
+ }
+
+#ifdef USE_TERMIOS
+#if defined(__bsdi__) || defined(linux)
+ if(tcgetattr(ifp->fd, &nterm)<0){
+#else
+ if(ioctl(ifp->fd, TCGETS, &nterm)<0){
+#endif /* __bsdi__ */
+#endif
+#ifdef USE_TERMIO
+ if(ioctl(ifp->fd, TCGETA, &nterm)<0){
+#endif
+#ifdef USE_SGTTY
+ if(ioctl(ifp->fd, TIOCGETP, &nterm)<0){
+#endif
+ PERR("fetching tty device parameters");
+ return -1;
+ }
+
+ if(ifp->unit==50)baudrate=B50;
+ else if(ifp->unit==50)baudrate=B50;
+ else if(ifp->unit==75)baudrate=B75;
+ else if(ifp->unit==110)baudrate=B110;
+ else if(ifp->unit==134)baudrate=B134;
+ else if(ifp->unit==150)baudrate=B150;
+ else if(ifp->unit==200)baudrate=B200;
+ else if(ifp->unit==300)baudrate=B300;
+ else if(ifp->unit==600)baudrate=B600;
+ else if(ifp->unit==1200)baudrate=B1200;
+ else if(ifp->unit==1800)baudrate=B1800;
+ else if(ifp->unit==2400)baudrate=B2400;
+ else if(ifp->unit==4800)baudrate=B4800;
+ else if(ifp->unit==9600)baudrate=B9600;
+#ifdef B19200
+ else if(ifp->unit==19200)baudrate=B19200;
+#else
+#ifdef EXTA
+ else if(ifp->unit==19200)baudrate=EXTA;
+#endif
+#endif
+#ifdef B38400
+ else if(ifp->unit==38400)baudrate=B38400;
+#else
+#ifdef EXTB
+ else if(ifp->unit==38400)baudrate=EXTB;
+#endif
+#endif
+ else baudrate = B9600;
+
+#ifdef USE_SGTTY
+ nterm.sg_flags = (RAW | ANYP);
+ nterm.sg_ispeed = baudrate;
+ nterm.sg_ospeed = baudrate;
+#else
+ nterm.c_iflag = 0;
+ nterm.c_oflag = 0;
+ nterm.c_cflag = baudrate | CS8 | CREAD | CLOCAL;
+ nterm.c_lflag = 0;
+ nterm.c_cc[VMIN] = 0;
+ nterm.c_cc[VTIME] = 0;
+#endif
+
+#ifdef USE_TERMIOS
+#if defined(__bsdi__) || defined(linux)
+ if(tcsetattr(ifp->fd, TCSANOW, &nterm)<0){
+#else
+ if(ioctl(ifp->fd, TCSETS, &nterm)<0){
+#endif /* __bsdi__ */
+#endif
+#ifdef USE_TERMIO
+ if(ioctl(ifp->fd, TCSETA, &nterm)<0){
+#endif
+#ifdef USE_SGTTY
+ if(ioctl(ifp->fd, TIOCSETP, &nterm)<0){
+#endif
+ PERR("setting tty device parameters");
+ return -1;
+ }
+
+ if(ifp->private==NULL)ifp->private = malloc(sizeof(struct slippy));
+ if(ifp->private==NULL){
+ syslog(LOG_ERR,"cannot allocate private data structure (slip)");
+ return -1;
+ }
+
+ (void)memset(ifp->private, 0, sizeof(struct slippy));
+
+ ifp->status = IF_STAT_OPEN;
+ return 1;
+}
+
+/*
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Read data from the specified interface. Return a complete IP datagram.
+ * If the datagram is not complete, then don't return anything.
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ */
+int slip_read(ifp, m)
+struct interface *ifp;
+struct message *m;
+{
+ int n;
+ struct slippy *s;
+
+ CK_IFNULL(ifp);
+ CK_IFTYPE(ifp,IF_TYPE_SLIP);
+ CK_IFOPEN(ifp);
+ CK_MNULL(m);
+
+ s = (struct slippy *)ifp->private;
+ ifp->status &= ~IF_STAT_CALL_AGAIN;
+ m->length = 0;
+
+ for(;;){
+ if(s->bnext >= s->bcount){ /* we need more data! */
+ s->bnext = 0;
+ s->bcount = 0;
+ n = read(ifp->fd, (char *)s->buffer, MAX_SIZE);
+ if(n==0)return 0; /* got nothing */
+ if(n<0){
+ if(errno==EINTR)return 0; /* SIGHUP! */
+ if(errno==EWOULDBLOCK)return 0; /* got nothing */
+ PERR("read from tty device");
+ return -1;
+ }
+ s->bcount = n;
+ }
+
+ n = assemble_slip(s, s->buffer[s->bnext]);
+ s->bnext++;
+
+ if(n > 0){
+ (void)memcpy((char *)m->msg, (char *)s->ipacket, n);
+ m->length = n;
+ if(s->bnext < s->bcount)
+ ifp->status |= IF_STAT_CALL_AGAIN;
+ return n;
+ }
+ }
+}
+
+/*
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * write data from to the specified interface. Return as soon as possible.
+ * The buffer provided will be a complete IP datagram.
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ */
+
+#define SLIPEMIT(x) if(ofcount<MAX_SIZE*2){*ofptr=(x);ofptr++;ofcount++;}
+
+int slip_send(ifp, m)
+struct interface *ifp;
+struct message *m;
+{
+ int n, i, ofcount;
+ unsigned char opacket[MAX_SIZE*2], *ofptr, *mptr;
+
+ CK_IFNULL(ifp);
+ CK_IFTYPE(ifp,IF_TYPE_SLIP);
+ CK_IFOPEN(ifp);
+ CK_MNULL(m);
+
+ if(m->length<=0)return 0;
+
+ ofptr = opacket;
+ ofcount = 0;
+ mptr = m->msg;
+
+ SLIPEMIT(FEND);
+
+ for(i=0;i<m->length;i++,mptr++){
+ if(*mptr==FEND){
+ SLIPEMIT(FESC);
+ SLIPEMIT(TFEND);
+ }else if (*mptr==FESC){
+ SLIPEMIT(FESC);
+ SLIPEMIT(TFESC);
+ }else {
+ SLIPEMIT(*mptr);
+ }
+ }
+
+ SLIPEMIT(FEND);
+
+/*
+ * WARNING! It is possible for this write to actually write less data
+ * than expected if the system has, for example, no buffer space left.
+ * We ignore the error (just increment the write overrun counter),
+ * drop the current packet, and expect that the higher level protocols
+ * will recover.
+ *
+ * If we got an "interrupted system call" error we print the diagnostic
+ * and continue. (the packet gets dropped as above).
+ */
+ n = write(ifp->fd, (char *)opacket, ofcount);
+ if(n<0){
+ syslog(LOG_ERR,"slip_send(): %s",strerror(errno));
+ if((errno==EINTR) || (errno==EAGAIN)) return 0;
+ return -1;
+ }
+ if(n < ofcount)ifp->out_overruns++;
+ return n;
+}
+
+/*
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * take a character and assemble it into the buffer. Return the length
+ * of the completed packet, 0 if not yet completed. Packet can be found
+ * in the private buffer...
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ */
+static int
+assemble_slip(s, c)
+struct slippy *s;
+unsigned char c;
+{
+ int n;
+
+ if(c==FEND){
+ n = s->ifcount;
+ s->ifcount = 0;
+ s->iescaped = 0;
+ return n;
+ }
+
+ if(c==FESC){
+ s->iescaped=1;
+ return 0;
+ }
+
+ if(s->iescaped){
+ if(c==TFEND)c = FEND;
+ if(c==TFESC)c = FESC;
+ s->iescaped = 0;
+ }
+ if(s->ifcount < MAX_SIZE){
+ s->ipacket[s->ifcount] = c;
+ s->ifcount++;
+ }
+ return 0;
+}
--- /dev/null
+; test config file "A"
+;
+; syntax is VERY rigid:
+;
+;interface <name> udp null <udp-portnumber-on-which-to-listen>
+;interface <name> ip null <ip-protocol-id>
+;interface <name> slip </dev/ttyname> <speed>
+;interface <name> tunnel </dev/tundevicename> 0
+;
+;interface bletch udp null 10094
+;interface rolf slip /dev/ttya 9600
+;
+interface LAN udp null 10094
+interface SER slip /dev/ptyq0 9600
--- /dev/null
+; test route file "A"
+route 0.0.0.0 0x00000000 SER
--- /dev/null
+; test config file "B"
+;
+; syntax is VERY rigid:
+;
+;interface <name> udp null <udp-portnumber-on-which-to-listen>
+;interface <name> ip null <ip-protocol-id>
+;interface <name> slip </dev/ttyname> <speed>
+;interface <name> tunnel </dev/tundevicename> 0
+;
+;interface bletch udp null 10094
+;interface rolf slip /dev/ttya 9600
+;
+interface LAN udp null 10095
+interface SERIAL slip /dev/ttyq0 -1
--- /dev/null
+; test route file "B"
+route 44.0.0.0 0xff000000 LAN wiggle 10090
--- /dev/null
+/* udp_i.c -- inject packets into the network for test */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#define BUFSIZE 1024
+#define UDP_PORT 10094
+
+int on = 1;
+int off = 0;
+
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ int sock, portno;
+ char buf[BUFSIZE], *buftext;
+ struct sockaddr_in to;
+ struct hostent *hp, *gethostbyname();
+ int gethostname();
+ char myhost[65], *the_host;
+
+ /* Set defaults */
+ gethostname(myhost,65);
+ the_host = myhost;
+ portno = UDP_PORT;
+
+ /* Test arguments */
+ if(argc>2){
+ fprintf(stderr,"Usage: %s [<hostname> [<portnumber>]]\n",argv[0]);
+ exit(1);
+ }
+ if(argc>1)the_host = argv[1];
+ if(argc>2)portno = atoi(argv[2]);
+
+ /* Find the host number */
+ hp = gethostbyname(the_host);
+ if (hp == 0){
+ fprintf(stderr,"%s: unknown host\n",argv[1]);
+ exit(2);
+ }
+
+ /* Create socket */
+ sock = socket(AF_INET, SOCK_DGRAM, 0);
+ if (sock<0) {
+ perror("opening raw socket");
+ exit(1);
+ }
+
+/* if(setsockopt(sock, SOL_SOCKET, SO_DONTROUTE, &on, sizeof on)<0){
+ perror("setting socket options");
+ exit(1);
+ }
+*/
+ bzero((char *)&to, sizeof to);
+ bcopy(hp->h_addr_list[0], (char *)&to.sin_addr, hp->h_length);
+ to.sin_family = AF_INET;
+ to.sin_port = htons(portno);
+
+ /* give the user a prompt */
+ putchar('>');
+ fflush(stdout);
+
+ /* fill in as much of the header as we care about for now */
+ buf[12] = 44;
+ buf[13] = 72;
+ buf[14] = 6;
+ buf[15] = 134;
+ buf[16] = 44;
+ buf[17] = 72;
+ buf[18] = 6;
+ buf[19] = 131;
+
+ buftext = buf + 40;
+
+ /* Loop until we hit EOF */
+ while(fgets(buftext,BUFSIZE-40,stdin) != NULL){
+ if (sendto(sock, buf, (strlen(buftext)+40), 0, (struct sockaddr *)&to, sizeof to) < 0) {
+ perror("writing of udp socket");
+ close(sock);
+ exit(4);
+ }
+ putchar('>');
+ fflush(stdout);
+ }
+
+ /* all done, close the socket and exit */
+ close(sock);
+ exit(0);
+}
--- /dev/null
+/* udp_o.c -- read packets from the network */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+
+#define BUFSIZE 1024
+#define UDP_PORT 10094
+
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ int sock, fromlen, l, i, portno;
+ char buf[BUFSIZE], *p;
+ struct sockaddr_in from;
+
+ portno = UDP_PORT;
+
+ /* Test arguments */
+ if(argc>2){
+ fprintf(stderr,"Usage: %s [<portnumber>]\n",argv[0]);
+ exit(1);
+ }
+ if(argc>1)portno = atoi(argv[1]);
+
+ /* Create socket */
+ sock = socket(AF_INET, SOCK_DGRAM, 0);
+ if (sock<0) {
+ perror("opening raw socket");
+ exit(1);
+ }
+
+ bzero((char *)&from, sizeof from);
+ from.sin_family = AF_INET;
+ from.sin_addr.s_addr = htonl(INADDR_ANY);
+ from.sin_port = htons(portno);
+ if (bind(sock, (struct sockaddr *)&from, sizeof from) < 0){
+ perror("binding UDP socket");
+ exit(1);
+ }
+
+ l = 0;
+ while(l>-1){
+ fromlen = sizeof from;
+ l = recvfrom(sock, buf, BUFSIZE, 0,
+ (struct sockaddr *)&from, &fromlen);
+ if(l<0){
+ perror("udp socket");
+ close(sock);
+ exit(2);
+ }
+ fprintf(stdout,"---------->recv %d bytes from port %d host %s\n", l,
+ ntohs(from.sin_port),
+ (char *)inet_ntoa(from.sin_addr));
+
+ fprintf(stdout,"{%d.%d.%d.%d->%d.%d.%d.%d}\n",buf[12],buf[13],
+ buf[14],buf[15],buf[16],buf[17],buf[18],buf[19]);
+
+ for(p=buf+40,i=0;i<(l-40);i++,p++){
+ if(isprint(*p))putc(*p,stdout);
+ else putc('.',stdout);
+ }
+ putc('\n',stdout);
+ fflush(stdout);
+ }
+
+ /* all done, close the socket and exit */
+ close(sock);
+ exit(0);
+}
--- /dev/null
+/* tun.c system tunnel driver interface
+ *
+ * $Id: tun.c,v 1.3 1995/03/19 17:21:06 bdale Exp $
+ *
+ * Copyright 1991, Michael Westerhof, Sun Microsystems, Inc.
+ * This software may be freely used, distributed, or modified, providing
+ * this header is not removed.
+ *
+ */
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netdb.h>
+#include <fcntl.h>
+#include <memory.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <syslog.h>
+#include <unistd.h>
+
+#include "ipip.h"
+
+#ifndef FNDELAY
+#define FNDELAY O_NDELAY
+#endif
+
+extern int errno;
+
+#define IF_NAME "tun" /* for use with the error checking macros */
+
+/*
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * open and initialize the IO interface. Return -1 for error.
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ */
+int tun_open(ifp)
+struct interface *ifp;
+{
+ CK_IFNULL(ifp);
+ CK_IFTYPE(ifp,IF_TYPE_TUN);
+
+ if((ifp->status & IF_STAT_OPEN)) return 1;
+
+ ifp->fd = open(ifp->devname, O_RDWR);
+ if (ifp->fd<0) {
+ PERR(ifp->devname);
+ return -1;
+ }
+
+ if (fcntl(ifp->fd, F_SETFL, FNDELAY) < 0) {
+ PERR("setting non-blocking I/O on tunnel device");
+ return -1;
+ }
+
+ ifp->status = IF_STAT_OPEN;
+ return 1;
+}
+
+
+/*
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Read data from the specified interface. Return a complete IP datagram.
+ * If the packet is not complete, then don't return anything.
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ */
+int tun_read(ifp, m)
+struct interface *ifp;
+struct message *m;
+{
+ int n;
+
+ CK_IFNULL(ifp);
+ CK_IFTYPE(ifp,IF_TYPE_TUN);
+ CK_IFOPEN(ifp);
+ CK_MNULL(m);
+
+ n = read(ifp->fd, (char *)m->msg, MAX_SIZE);
+ if(n<0){
+ m->length = 0;
+ if(errno==EINTR)return 0;
+ if(errno==EWOULDBLOCK)return 0;
+ PERR("read from tunnel device");
+ return -1;
+ }
+ m->length = n;
+ return n;
+}
+
+/*
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * write data from to the specified interface. Return as soon as possible.
+ * The buffer provided will be a complete IP datagram.
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ */
+int tun_send(ifp, m)
+struct interface *ifp; /* the interface */
+struct message *m; /* the message */
+{
+ int n;
+
+
+ CK_IFNULL(ifp);
+ CK_IFTYPE(ifp,IF_TYPE_TUN);
+ CK_IFOPEN(ifp);
+ CK_MNULL(m);
+
+ if(m->length<=0)return 0;
+
+ n = write(ifp->fd, (char *)m->msg, m->length);
+ if(n<0){
+ if(errno==EINTR)return 0;
+ if(errno==EWOULDBLOCK){ /* should never happen :-) */
+ ifp->out_overruns++;
+ return 0;
+ }
+ PERR("write to tunnel device");
+ return -1;
+ }
+ if(n < m->length)ifp->out_overruns++;
+ return n;
+}
--- /dev/null
+/* version.h Define the current version number
+ *
+ * $Id: version.h,v 1.8 1995/03/19 17:21:06 bdale Exp $
+ *
+ * Copyright 1991, Michael Westerhof, Sun Microsystems, Inc.
+ * This software may be freely used, distributed, or modified, providing
+ * this header is not removed.
+ *
+ */
+
+#define VERS "1.1.0"
+