--- /dev/null
+1.5pre3cvs
--- /dev/null
+netatalk (1.5pre3cvs-1) unstable; urgency=low
+
+ * Unofficial release from CVS.
+ * Some reorganisations to allow building directly from CVS.
+ * Debian packaging is now included in upstream CVS.
+ * Modified debian/copyright to include CVS instructions.
+
+ -- Sebastian Rittau <srittau@jroger.in-berlin.de> Fri, 16 Feb 2001 14:49:03 +0100
+
+netatalk (1.5pre3-0.1) unstable; urgency=low
+
+ * This is a pre-release not for upload to Debian.
+ * New upstream version from netatalk.sourceforge.net.
+ (Closes: #69232, #78781)
+ * Essentially repackaged with debhelper.
+ * Removed some Debian specific patches integrated upstream.
+ * Updated debian/copyright.
+ * Build with libssl support. (Closes: #48871)
+ * Added libssl096-dev to Build-Depends.
+ * Changed priority from optional to extra.
+
+ -- Sebastian Rittau <srittau@jroger.in-berlin.de> Thu, 15 Feb 2001 23:40:18 +0100
+
+netatalk (1.4b2+asun2.1.3-7) unstable; urgency=low
+
+ * New maintainer. (Closes: #82386)
+ * Fixed a build problem.
+ * Strip .note and .comment sections from /usr/lib/atalk/psa.
+ * Added debhelper as build-dependency.
+ * Complies with Debian policy version 3.2.1.0.
+
+ -- Sebastian Rittau <srittau@jroger.in-berlin.de> Sun, 21 Jan 2001 15:49:11 +0100
+
+netatalk (1.4b2+asun2.1.3-6) unstable; urgency=low
+
+ * The "looks like I picked the wrong week to quit sniffing glue" release.
+ * Update the maintainer name in the control file.
+ * Move psa and etc2ps to /usr/lib/atalk, as they are not user binaries
+ (this also shuts lintian up).
+
+ -- David Huggins-Daines <dhd@debian.org> Fri, 14 Jan 2000 21:04:24 -0500
+
+netatalk (1.4b2+asun2.1.3-5) unstable; urgency=low
+
+ * New maintainer.
+ * Compensate for stupid new 'install -s' behaviour. (closes:Bug#51423)
+ * Fix psf(8) manpage. (closes:Bug#30839)
+ * Updated Standards-Version.
+ * Fixed symlinks to be relative, as per lintian's warnings.
+ * Added /usr/doc symlinks in the postinst/prerm.
+
+ -- David Huggins-Daines <dhd@debian.org> Wed, 22 Dec 1999 20:24:26 -0500
+
+netatalk (1.4b2+asun2.1.3-4) unstable; urgency=low
+
+ * Fix init script to always kill papd even if ENABLE_PAP=no (closes:Bug#48783).
+
+ -- Joel Klecker <espy@debian.org> Sun, 31 Oct 1999 07:43:29 -0800
+
+netatalk (1.4b2+asun2.1.3-3) unstable; urgency=low
+
+ * Remove libatalk1 and libatalk1-dev (I think it is a mistake to "fork" a
+ shared version of a library in Debian, if the library is static upstream
+ then upstream isn't gonna be careful with the ABI).
+ * Create netatalk-dev.
+ * netatalk.init: Use $() instead of ``.
+ Use /bin/hostname explicitly.
+ s/daemons/Daemons/g.
+ Remove module fiddling (closes:Bug#44767,#43319).
+ * Remove "glibc 2.1 fix" it's no longer needed.
+ * Compile with sendfile support.
+ * Use /usr/share/doc.
+ * Cleanup bashisms in debian/rules.
+
+ -- Joel Klecker <espy@debian.org> Sat, 23 Oct 1999 20:59:24 -0700
+
+netatalk (1.4b2+asun2.1.3-2) unstable; urgency=low
+
+ * (netatalk): Make /etc/netatalk/afpd.conf a conffile (closes:Bug#37628).
+
+ -- Joel Klecker <espy@debian.org> Thu, 13 May 1999 10:54:37 -0700
+
+netatalk (1.4b2+asun2.1.3-1) unstable; urgency=low
+
+ * New upstream release (closes:Bug#33982).
+ * Correct paths in psf.8 (closes:Bug#30839).
+ * There is now a different way to control CRLF translation on a
+ per-volume basis upstream so I have removed the patch that
+ provides the -e option to afpd.
+ * (netatalk): Depend on libpam-modules.
+ * Put man pages in /usr/share/man.
+
+ -- Joel Klecker <espy@debian.org> Tue, 30 Mar 1999 12:17:36 -0800
+
+netatalk (1.4b2+asun2.1.1-2) frozen unstable; urgency=low
+
+ * Incorporated glibc 2.1 fixes from Christian Meder.
+ * Remove explicit add-log-mailing-address from debian/changelog.
+
+ -- Joel Klecker <espy@debian.org> Fri, 15 Jan 1999 07:28:11 -0800
+
+netatalk (1.4b2+asun2.1.1-1.1) frozen unstable; urgency=low
+
+ * non maintainer, sparc only upload
+ * fix #includes for glibc2.1
+
+ -- Christian Meder <meder@isr.uni-stuttgart.de> Mon, 4 Jan 1999 12:37:13 +0100
+
+netatalk (1.4b2+asun2.1.1-1) frozen unstable; urgency=low
+
+ * New upstream bugfix release.
+ * Recompile against libc6 2.0.7u-7 to get rid of versioned
+ libc6 dependency.
+
+ -- Joel Klecker <espy@debian.org> Thu, 3 Dec 1998 07:45:42 -0800
+
+netatalk (1.4b2+asun2.1.0-5) frozen unstable; urgency=high
+
+ * [libatalk/atp/atp_rsel.c] Minor change for libnatali compatibility
+ (closes:Bug#30092).
+ * Rebuild with libc6 2.0.7u-6 for i386.
+
+ -- Joel Klecker <espy@debian.org> Fri, 27 Nov 1998 22:58:11 -0800
+
+netatalk (1.4b2+asun2.1.0-4) frozen unstable; urgency=low
+
+ * binary-arch target now depends on pre-binary (closes:Bug#29508)
+
+ -- Joel Klecker <espy@debian.org> Tue, 17 Nov 1998 04:46:50 -0800
+
+netatalk (1.4b2+asun2.1.0-3) frozen unstable; urgency=low
+
+ * Now installs /usr/lib/atalk/pagecount.ps (closes:Bug#29323)
+
+ -- Joel Klecker <espy@debian.org> Thu, 12 Nov 1998 00:30:53 -0800
+
+netatalk (1.4b2+asun2.1.0-2) frozen unstable; urgency=low
+
+ * Should build from freshly unpacked source now (Bug#28810)
+
+ -- Joel Klecker <espy@debian.org> Sun, 1 Nov 1998 19:34:52 -0800
+
+netatalk (1.4b2+asun2.1.0-1) unstable; urgency=low
+
+ * New upstream release.
+ * Incorporate megatron patch from Rob Browning (Bug#25598).
+ * Don't install /usr/include/netatalk on glibc 2.1 architectures.
+ * Fix paths in /etc/pam.d/netatalk file.
+
+ -- Joel Klecker <espy@debian.org> Thu, 29 Oct 1998 23:54:13 -0800
+
+netatalk (1.4b2+asun2.0a18.2-1) frozen unstable; urgency=low
+
+ * New "upstream" release.
+ * This does add new features, however, it also fixes at
+ least one nasty bug (Bug#13973).
+ * Applied patch which adds a command-line option to disable
+ CR/LF translation (thanks to Davide Welton and Jon Nelson).
+ (Note to release manager: this patch is applied so this
+ package has the exact functionality of netatalk-asun)
+ * Renamed libatalk-dev to libatalk1-dev.
+ * Symlinked /usr/man/man1/nbpunrgstr.1.gz to /usr/man/man1/nbprgstr.1.gz
+ to keep lintian happy.
+ * Changed the "lock directory" to /var/run and the names of the "lock files" to <foo>.pid,
+ since what the source calls locks are really the same as the .pid files other daemons
+ put in /var/run.
+ * This package provides all the functionality of netatalk-asun, and
+ it will replace netatalk-asun in the distribution.
+
+ -- Joel Klecker <jk@espy.org> Tue, 12 May 1998 19:31:54 -0700
+
+netatalk (1.4b2-5) frozen unstable; urgency=low
+
+ * New Maintainer (I can finally close bugs
+ I fixed in previous releases ;).
+ * Changed library package names again.
+ * Upgraded to Debian Policy 2.4.0.0.
+ * Moved conffiles to /etc/netatalk.
+ * Fixes almost all lintian warnings/errors.
+ * Cleaned up changelog.
+
+ -- Joel Klecker <jk@espy.org> Sun, 22 Mar 1998 21:50:00 -0800
+
+netatalk (1.4b2-4.5) unstable; urgency=low
+
+ * Non-maintainer release (again :>)
+ * Made libatalk14g-dev conflict with libc5-dev to fix overlap
+ (Bug:#17848)
+
+ -- Joel Klecker <jk@espy.org> Thu, 5 Feb 1998 20:42:51 -0800
+
+netatalk (1.4b2-4.4) unstable; urgency=low
+
+ * Yet Another non-maintainer release.
+ * Added patch to fix "dancing icon" problems with Macs running Mac OS 8.
+ * Changed comment in /etc/AppleVolumes.default (Bug:#15279)
+ * Implemented variable for "server name" in init script
+ (as suggested in Bug:#12024)
+ * Added a kluge to /etc/init.d/netatalk to remove kernel appletalk
+ module (if there is one) at stop and reinsert it at start, this
+ is needed or else netatalk will not start once stopped (Bug:#12142,11349)
+
+ -- Joel Klecker <jk@espy.org> Fri, 30 Jan 1998 07:50:00 -0800
+
+netatalk (1.4b2-4.3) unstable; urgency=low
+
+ * Non-maintainer release.
+ * Fixed dependencies.
+
+ -- Joel Klecker <jk@espy.org> Thu, 8 Jan 1998 16:14:17 -0800
+
+netatalk (1.4b2-4.2) unstable; urgency=low
+
+ * Non-maintainer release.
+ * Changed library package names.
+
+ -- Joel Klecker <jk@espy.org> Wed, 7 Jan 1998 00:00:00 -0800
+
+netatalk (1.4b2-4.1) unstable; urgency=low
+
+ * Non-maintainer libc6 compile.
+
+ -- Joel Klecker <jk@espy.org> Tue, 6 Jan 1998 00:00:00 -0800
+
+netatalk (1.4b2-4) unstable; urgency=low
+
+ * Recompiled against newer PAM libraries.
+ * Added /etc/pam.d/samba.
+
+ -- Klee Dienes <klee@debian.org> Sat, 8 Mar 1997 01:17:09 -0500
+
+netatalk (1.4b2-3) unstable; urgency=low
+
+ * Added PAM support.
+ * Split into libatalk, libatalk-dev, and netatalk.
+ * Added patch from Randy Gobbel <gobbel@cogsci.ucsd.edu> to allow case
+ translation to be specified at config-time rather than compile time.
+ Note that configuration files that make use of this feature may not
+ work with other releases of netatalk, and that this feature may be
+ removed in the future if UMich rejects the patch or implements it
+ differently.
+ * Startup messages now conform to 'Standard for Console Messages' (fixes
+ #5399).
+ * No longer creates new subdirectories (to appease dpkg-buildpackage).
+
+ -- Klee Dienes <klee@debian.org> Wed, 26 Feb 1997 21:02:02 -0500
+
+netatalk (1.4b2-2) unstable; urgency=low
+
+ * Resend_request made external for libnatali.
+ * Added shared libraries.
+ * Next revision will split into libatalk, libatalk-dev, and netatalk.
+
+ -- Klee Dienes <klee@debian.org> Fri, 24 Jan 1997 22:37:22 -0500
+
+netatalk (1.4b2-1) unstable; urgency=low
+
+ * Updated to upstream version 1.4b2.
+ * Added preliminary PAM support (currently disabled).
+ * Made /etc/init.d/netatalk a conffile.
+ * Changed /etc/init.d/netatalk to complete only once appletalk services
+ are running. Configurating an Appletalk interface can take many (> 15)
+ seconds, so the previous version would fork a process to configure the
+ interface and then start up the other Appletalk services. Although
+ possibly controversial, this change is necessary so that packages like
+ ppr can be ensured that netatalk will be started before they run
+ without undue complication.
+
+ -- Klee Dienes <klee@debian.org> Sat, 2 Nov 1996 19:42:04 -0700
+
+netatalk (1.4b1-1) unstable; urgency=low
+
+ * Updated to new upstream version.
+ * Updated to new packaging format.
+
+ -- Klee Dienes <klee@debian.org> Wed, 2 Oct 1996 10:18:14 -0700
+
+netatalk (1.3.3-3);
+
+ * Fixed location of include files.
+
+ -- Klee Dienes <klee@mit.edu> Mon Jan 8 10:46:52 MST 1996
+
+netatalk (1.3.3-2);
+
+ * Fixed bug in postrm script.
+
+ -- Klee Dienes <klee@mit.edu> Thu Dec 21 08:22:24 MST 1995
+
+netatalk (1.3.3-1);
+
+ * Initial Release.
+
+ -- Klee Dienes <klee@mit.edu> Wed Dec 13 22:58:31 MST 1995
+
+Local variables:
+mode: debian-changelog
+End:
--- /dev/null
+Source: netatalk
+Section: net
+Priority: extra
+Maintainer: Sebastian Rittau <srittau@jroger.in-berlin.de>
+Standards-Version: 3.2.1.0
+Build-Depends: debhelper, libwrap0-dev, libpam0g-dev, libssl096-dev
+
+Package: netatalk
+Architecture: any
+Depends: netbase, libpam-modules, ${shlibs:Depends}
+Conflicts: netatalk-asun, libatalk14g, libatalk1
+Replaces: netatalk-asun, libatalk14, libatalk1
+Description: Appletalk user binaries
+ Netatalk is an implementation of the AppleTalk Protocol Suite for
+ BSD-derived systems. The current release contains support for
+ EtherTalk Phase I and II, DDP, RTMP, NBP, ZIP, AEP, ATP, PAP, ASP, and
+ AFP.
+
+Package: netatalk-dev
+Architecture: any
+Section: devel
+Conflicts: libatalk14g-dev, libatalk14-dev, netatalk-asun, libatalk1-dev
+Replaces: libatalk14g-dev, libatalk14-dev, netatalk-asun, libatalk1-dev
+Description: Appletalk library and development files
+ Netatalk is an implementation of the AppleTalk Protocol Suite for
+ BSD-derived systems. The current release contains support for
+ EtherTalk Phase I and II, DDP, RTMP, NBP, ZIP, AEP, ATP, PAP, ASP, and
+ AFP.
+
--- /dev/null
+This is the Debian GNU/Linux prepackaged version of netatalk.
+
+This package was originally put together by Joel 'epsy' Klecker.
+Current maintainer is Sebastian Rittau <srittau@jroger.in-berlin.de>.
+The sources were obtained from CVS: cvs.netatalk.sourceforge.net.
+See the Netatalk homepage at <http://netatalk.sourceforge.net/> for
+anonymous CVS instructions.
+
+Changes:
+ * Added Debian GNU/Linux package maintenance system files.
+ * Fixed some build problems.
+ * Added patch for megatron.
+
+The following copyrights/licenses apply to this software:
+
+Copyright (c) 1990,1996 Regents of The University of Michigan.
+All Rights Reserved.
+
+ Permission to use, copy, modify, and distribute this software and
+ its documentation for any purpose and without fee is hereby granted,
+ provided that the above copyright notice appears in all copies and
+ that both that copyright notice and this permission notice appear
+ in supporting documentation, and that the name of The University
+ of Michigan not be used in advertising or publicity pertaining to
+ distribution of the software without specific, written prior
+ permission. This software is supplied as is without expressed or
+ implied warranties of any kind.
+
+This product includes software developed by the University of
+California, Berkeley and its contributors.
+
+Solaris code is encumbered by the following:
+ Copyright (C) 1996 by Sun Microsystems Computer Co.
+
+ Permission to use, copy, modify, and distribute this software and
+ its documentation for any purpose and without fee is hereby
+ granted, provided that the above copyright notice appear in all
+ copies and that both that copyright notice and this permission
+ notice appear in supporting documentation. This software is
+ provided "as is" without express or implied warranty.
+
+Modifications for Appleshare IP and other files copyrighted by Adrian
+Sun are under the following copyright:
+
+ Copyright (c) 1997,1998,1999,2000 Adrian Sun (asun@cobalt.com)
+ All Rights Reserved.
+
+ Permission to use, copy, modify, and distribute this software and
+ its documentation for any purpose and without fee is hereby granted,
+ provided that the above copyright notice appears in all copies and
+ that both that copyright notice and this permission notice appear
+ in supporting documentation. This software is supplied as is
+ without expressed or implied warranties of any kind.
+
+Research Systems Unix Group
+The University of Michigan
+c/o Wesley Craig
+535 W. William Street
+Ann Arbor, Michigan
++1-313-764-2278
+netatalk@umich.edu
+
+
+This product includes software developed by the OpenSSL Project
+for use in the OpenSSL Toolkit (http://www.openssl.org/)
+
+See /usr/share/doc/libssl096/copyright for more information on
+libssl and openssl.
--- /dev/null
+#!/bin/sh
+
+# Execute this script from the main
+
+set -e
+
+debiandir=distrib/debian
+
+if test ! -e README.ASUN; then
+ echo "Not in netatalk directory"
+ exit 1
+fi
+
+VERSION=`cat VERSION`
+DEBVERSION=`cat "$debiandir/VERSION"`
+DISTDIR="netatalk-$VERSION"
+DISTTGZ="netatalk_$DEBVERSION.orig.tar.gz"
+
+if test ! -x configure; then
+ ./autogen.sh
+fi
+
+if test ! -e Makefile; then
+ if test -x config.status; then
+ ./config.status
+ else
+ ./configure
+ fi
+fi
+
+make dist
+
+mv "netatalk-$VERSION.tar.gz" "$DISTTGZ"
+rm -rf "netatalk-$VERSION" || true
+tar xzf "$DISTTGZ"
+
+for FILE in `find $debiandir/patches/*.patch`; do
+ patch --dir="$DISTDIR" --strip=1 <$FILE
+done
+
+cp -a "$debiandir" "$DISTDIR"
+rm -r "$DISTDIR/debian/CVS"
+rm -r "$DISTDIR/debian/patches"
+rm "$DISTDIR/debian/cvs2deb.sh"
+rm "$DISTDIR/debian/VERSION"
+
+cd "$DISTDIR" && dpkg-buildpackage -rfakeroot
+
+cd .. && rm -r "$DISTDIR"
--- /dev/null
+netatalk_1.5pre3-1_i386.deb net optional
+netatalk-dev_1.5pre3-1_i386.deb devel optional
--- /dev/null
+usr/bin/netatalk-config
+usr/include
+usr/lib/libatalk.a
+usr/lib/libatalk.la
+usr/share/aclocal
+usr/share/man/man3
+usr/share/man/man4
--- /dev/null
+#!/bin/sh
+
+# Create /usr/doc symlinks if needed
+if [ "$1" = "configure" ]; then
+ if [ -d /usr/doc -a ! -e /usr/doc/netatalk-dev \
+ -a -d /usr/share/doc/netatalk-dev ]; then
+ ln -sf ../share/doc/netatalk-dev /usr/doc/netatalk-dev
+ fi
+fi
--- /dev/null
+#!/bin/sh
+
+if [ \( "$1" = "upgrade" -o "$1" = "remove" \) \
+ -a -L /usr/doc/netatalk-dev ]; then
+ rm -f /usr/doc/netatalk-dev
+fi
--- /dev/null
+netatalk-config.1
--- /dev/null
+Package: netatalk-dev
+Version: 1.5pre3-1
+Section: devel
+Priority: optional
+Architecture: i386
+Conflicts: libatalk14g-dev, libatalk14-dev, netatalk-asun, libatalk1-dev
+Replaces: libatalk14g-dev, libatalk14-dev, netatalk-asun, libatalk1-dev
+Installed-Size: 334
+Maintainer: Sebastian Rittau <srittau@jroger.in-berlin.de>
+Source: netatalk
+Description: Appletalk library and development files
+ Netatalk is an implementation of the AppleTalk Protocol Suite for
+ BSD-derived systems. The current release contains support for
+ EtherTalk Phase I and II, DDP, RTMP, NBP, ZIP, AEP, ATP, PAP, ASP, and
+ AFP.
--- /dev/null
+91beb8ccc093ca89f2e73a1964325b81 usr/share/doc/netatalk-dev/copyright
+bd1feda4db36ea0df6a8b8cd135aa1a5 usr/share/doc/netatalk-dev/changelog.gz
+53061e5b724f021fac66391b1a5d6c01 usr/share/doc/netatalk-dev/changelog.Debian.gz
+a46dcb28ff35e7ac2a5d7824324f00d4 usr/share/man/man3/atalk_aton.3.gz
+43760829028a29d57a3eae4977dba722 usr/share/man/man3/nbp_name.3.gz
+788e52355ee6b5fe6f126fcdfb8bc687 usr/share/man/man4/atalk.4.gz
+6726ca1c6176e6b310f264109faf38b3 usr/share/aclocal/netatalk.m4
+77ff3179ede30c3da6d7ae769fd849ab usr/bin/netatalk-config
+19d088801b01a116d18f9507f205f3ed usr/include/atalk/adouble.h
+88fd0a8df4356ca11c757efec2524fc2 usr/include/atalk/aep.h
+413e129ab9234555c5d438dfc6a15e4a usr/include/atalk/afp.h
+71163a320e0a39d342cff4828cac7cbe usr/include/atalk/asp.h
+78cca81775a8351b0b3f928e62b25cec usr/include/atalk/atp.h
+a4b43445626acaed0352ffa2a52d48c0 usr/include/atalk/cnid.h
+9d7fba91169ae54cfe6d705394a9af97 usr/include/atalk/compat.h
+99f38f0f5f767d90aad7cbc24f2b60d0 usr/include/atalk/ddp.h
+cf6426b46f0dd72b6830a289eee4a28a usr/include/atalk/dsi.h
+d52b78e8f94325d9c352507c6b04dfbc usr/include/atalk/nbp.h
+1c7b8dd51fa150808566e502204e9b56 usr/include/atalk/netddp.h
+d22efaa927c56a622c39aa586213bdd4 usr/include/atalk/pap.h
+8241b059298852f3fe887fc65bbb3ae8 usr/include/atalk/paths.h
+33fca32715ae3e7721254c2b1be918f9 usr/include/atalk/rtmp.h
+ae03409603557ebee6dc18b2efce6c36 usr/include/atalk/server_child.h
+7344ed927cd4f9c38f00977fd14de1ff usr/include/atalk/uam.h
+03a441621cea0450673051aa05219f4e usr/include/atalk/util.h
+95ca04afb116d5627dc353953bb3e312 usr/include/atalk/zip.h
+3dfab2988c69c2153e8f0d2fe3575e76 usr/include/netatalk/aarp.c
+346d358e3fb2daefa10ab97565eb5930 usr/include/netatalk/aarp.h
+50498051f863e206113b4fafd96623de usr/include/netatalk/at_control.c
+81903cc9fbaef30b993093bf6d55b341 usr/include/netatalk/at_proto.c
+17ee3b2d578d2d26dd7038483bc4b688 usr/include/netatalk/at_var.h
+6d7f3504a1b2d4a78ac5f79512b282be usr/include/netatalk/ddp.h
+d35136c585c7290a44262132ce510ef4 usr/include/netatalk/ddp_input.c
+38fcf19df69dcf29dfee4a6fb0f81e1f usr/include/netatalk/ddp_output.c
+984c8639e5881bfc75d6e1099fab4737 usr/include/netatalk/ddp_usrreq.c
+1c23c4b16a175d240775a32397e26fe1 usr/include/netatalk/ddp_var.h
+bdb2d3d3f8026c1630ce0c2d47ed6e5e usr/include/netatalk/endian.h
+c4664c01da3cc982906a8fd1306c7483 usr/include/netatalk/phase2.h
+8f21c37705c020268f742560d8af724d usr/lib/libatalk.a
+6e007ba9f18c8f62f4982b6627a6fb08 usr/lib/libatalk.la
--- /dev/null
+#!/bin/sh
+
+# Create /usr/doc symlinks if needed
+if [ "$1" = "configure" ]; then
+ if [ -d /usr/doc -a ! -e /usr/doc/netatalk-dev \
+ -a -d /usr/share/doc/netatalk-dev ]; then
+ ln -sf ../share/doc/netatalk-dev /usr/doc/netatalk-dev
+ fi
+fi
--- /dev/null
+#!/bin/sh
+
+if [ \( "$1" = "upgrade" -o "$1" = "remove" \) \
+ -a -L /usr/doc/netatalk-dev ]; then
+ rm -f /usr/doc/netatalk-dev
+fi
--- /dev/null
+#!/bin/sh
+# netatalk-config
+
+af_libs=
+af_cflags=
+prefix=/usr
+exec_prefix=${prefix}
+
+
+##
+## Define usage()
+##
+usage()
+{
+ cat <<EOF
+Usage: $0 [OPTIONS] [LIBRARIES]
+Options:
+ --cflags print pre-processor and compiler flags
+ --libs print library linking information
+ --libs-dirs only print the -L/-R part of --libs
+ --libs-names only print the -l part of --libs
+ --help display this help and exit
+ --macros print the path to m4 macros
+
+ --prefix[=DIR]
+ --exec_prefix[=DIR]
+ --version output netatalk version information
+Libraries:
+ netatalk
+EOF
+ exit $1
+}
+
+##
+## Process options
+##
+parse()
+{
+# we must be called with at least one argument
+if test $# -eq 0; then
+ usage 1 1>&2
+fi
+
+# at least one option should be selected
+case "$1" in
+ --*)
+ ;;
+ *)
+ usage 1 1>&2
+ ;;
+esac
+
+# grab all -- arguments
+while test $# -gt 0; do
+ case "$1" in
+ -*=*) af_optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) af_optarg= ;;
+ esac
+
+ case $1 in
+ --help)
+ usage 0 0>&2
+ ;;
+ --cflags)
+ af_echo_cflags=yes
+ ;;
+ --libs)
+ af_echo_libs_L=yes
+ af_echo_libs_l=yes
+ ;;
+ --libs-dirs)
+ af_echo_libs_L=yes
+ ;;
+ --libs-names)
+ af_echo_libs_l=yes
+ ;;
+ --macros*)
+
+echo -I /usr/include/netatalk/macros
+exit
+
+ ;;
+ --prefix=*)
+ prefix=$af_optarg
+ af_prefix_set=yes
+ ;;
+ --prefix)
+ af_echo_prefix=yes
+ ;;
+ --exec_prefix=*)
+ exec_prefix=$af_optarg
+ af_exec_prefix_set=yes
+ ;;
+ --exec_prefix)
+ af_echo_exec_prefix=yes
+ ;;
+ --version)
+ af_echo_version=yes
+ ;;
+ --*)
+ usage 1 1>&2
+ ;;
+ *)
+ break
+ ;;
+ esac
+ shift
+done
+
+# if we have a default library use it
+if test $# -eq 0; then
+if test "X$af_lib_default" != "X"; then
+ af_lib__AF_LIB_DEFAULT=yes
+ return
+fi
+fi
+
+while test $# -gt 0; do
+ case $1 in
+ netatalk)
+ af_lib_netatalk=yes
+ ;;
+ *)
+ usage 1 1>&2
+ ;;
+ esac
+ shift
+done
+}
+
+print_result()
+{
+if test "X$af_echo_cflags" = "Xyes"; then
+ af_all_flags="$af_cflags"
+fi
+
+if test "X$af_echo_libs_L" = "Xyes" || test "X$af_echo_libs_l" = "Xyes"; then
+ af_all_flags="$af_all_flags $af_libs"
+fi
+
+if test -z "$af_all_flags" || test "X$af_all_flags" = "X "; then
+ exit 1
+fi
+
+# Straight out any possible duplicates, but be careful to
+# get `-lfoo -lbar -lbaz' for `-lfoo -lbaz -lbar -lbaz'
+af_other_flags=
+af_lib_L_flags=
+af_rev_libs=
+for i in $af_all_flags; do
+ case "$i" in
+ # a library, save it for later, in reverse order
+ -l*) af_rev_libs="$i $af_rev_libs" ;;
+ -L*|-R*)
+ if test "X$af_echo_libs_L" = "Xyes"; then
+ case " $af_lib_L_flags " in
+ *\ $i\ *) ;; # already there
+ *) af_lib_L_flags="$af_lib_L_flags $i" ;; # add it to output
+ esac
+ fi;;
+ *)
+ case " $af_other_flags " in
+ *\ $i\ *) ;; # already there
+ *) af_other_flags="$af_other_flags $i" ;; # add it to output
+ esac ;;
+ esac
+done
+
+af_ord_libs=
+if test "X$af_echo_libs_l" = "Xyes"; then
+ for i in $af_rev_libs; do
+ case " $af_ord_libs " in
+ *\ $i\ *) ;; # already there
+ *) af_ord_libs="$i $af_ord_libs" ;; # add it to output in reverse order
+ esac
+ done
+fi
+
+echo $af_other_flags $af_lib_L_flags $af_ord_libs
+}
+
+##
+## Main Body
+##
+
+parse $*
+
+
+##
+## Initialize names
+##
+
+
+
+
+
+if test "X$af_echo_prefix" = "Xyes"; then
+ echo $prefix
+fi
+
+if test "X$af_echo_exec_prefix" = "Xyes"; then
+ echo $exec_prefix
+fi
+
+if test "X$af_echo_version" = "Xyes"; then
+ echo 1.5
+ exit 0
+fi
+
+
+##
+## Libraries
+##
+
+#dummy because this should always be selected
+
+
+if test "${prefix}/include" != /usr/include ; then
+ includes="-I${prefix}/include"
+fi
+if test "${exec_prefix}/lib" != /usr/lib ; then
+ libs="-L${exec_prefix}/lib"
+fi
+af_cflags="$af_cflags $includes"
+af_libs="$libs -latalk"
+
+
+
+
+print_result
+
+exit 0
+
--- /dev/null
+/*
+ * Copyright (c) 1990,1991 Regents of The University of Michigan.
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appears in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation, and that the name of The University
+ * of Michigan not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. This software is supplied as is without expressed or
+ * implied warranties of any kind.
+ *
+ * Research Systems Unix Group
+ * The University of Michigan
+ * c/o Mike Clark
+ * 535 W. William Street
+ * Ann Arbor, Michigan
+ * +1-313-763-0525
+ * netatalk@itd.umich.edu
+ */
+
+#ifndef _ATALK_ADOUBLE_H
+#define _ATALK_ADOUBLE_H
+
+#include <unistd.h>
+
+#if defined(sun) && defined(__svr4__)
+#include </usr/ucbinclude/sys/file.h>
+#else
+#include <sys/file.h>
+#endif
+#include <fcntl.h>
+#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <netatalk/endian.h>
+
+
+/* XXX: this is the wrong place to put this.
+ * NOTE: as of 2.2.1, linux can't do a sendfile from a socket. */
+#ifdef SENDFILE_FLAVOR_LINUX
+#define HAVE_SENDFILE_READ
+#define HAVE_SENDFILE_WRITE
+#include <asm/unistd.h>
+#ifdef __NR_sendfile
+static inline int sendfile(int fdout, int fdin, off_t *off, size_t count)
+{
+ return syscall(__NR_sendfile, fdout, fdin, off, count);
+}
+#else
+#include <sys/sendfile.h>
+#endif
+#endif
+
+#ifdef SENDFILE_FLAVOR_BSD
+#define HAVE_SENDFILE_READ
+#endif
+
+/*
+ * AppleDouble entry IDs.
+ */
+#define ADEID_DFORK 1
+#define ADEID_RFORK 2
+#define ADEID_NAME 3
+#define ADEID_COMMENT 4
+#define ADEID_ICONBW 5
+#define ADEID_ICONCOL 6
+#define ADEID_FILEI 7 /* v1, replaced by: */
+#define ADEID_FILEDATESI 8 /* this */
+#define ADEID_FINDERI 9
+#define ADEID_MACFILEI 10 /* we don't use this */
+#define ADEID_PRODOSFILEI 11 /* we store prodos info here */
+#define ADEID_MSDOSFILEI 12 /* we don't use this */
+#define ADEID_SHORTNAME 13
+#define ADEID_AFPFILEI 14 /* where the rest of the FILEI info goes */
+#define ADEID_DID 15
+
+#define ADEID_MAX 16
+
+/* magic */
+#define AD_APPLESINGLE_MAGIC 0x00051600
+#define AD_APPLEDOUBLE_MAGIC 0x00051607
+#define AD_MAGIC AD_APPLEDOUBLE_MAGIC
+
+/* version info */
+#define AD_VERSION1 0x00010000
+#define AD_VERSION2 0x00020000
+#define AD_VERSION AD_VERSION1
+
+/* sizes of relevant entry bits */
+#define ADEDLEN_MAGIC 4
+#define ADEDLEN_VERSION 4
+#define ADEDLEN_FILLER 16
+#define ADEDLEN_NENTRIES 2
+
+#define AD_HEADER_LEN (ADEDLEN_MAGIC + ADEDLEN_VERSION + \
+ ADEDLEN_FILLER + ADEDLEN_NENTRIES)
+#define AD_ENTRY_LEN 12 /* size of a single entry header */
+
+/* v1 field widths */
+#define ADEDLEN_NAME 255
+#define ADEDLEN_COMMENT 200
+#define ADEDLEN_FILEI 16
+#define ADEDLEN_FINDERI 32
+
+/* v2 field widths */
+#define ADEDLEN_FILEDATESI 16
+#define ADEDLEN_SHORTNAME 12 /* length up to 8.3 */
+#define ADEDLEN_AFPFILEI 4
+#define ADEDLEN_MACFILEI 4
+#define ADEDLEN_PRODOSFILEI 8
+#define ADEDLEN_MSDOSFILEI 2
+#define ADEDLEN_DID 4
+
+
+#define AD_DATASZ1 589
+#define AD_DATASZ2 665 /* v1 + 4 new entries (entry desc. + entry) */
+#define AD_DATASZ_MAX 1024
+#if AD_VERSION == AD_VERSION1
+#define AD_DATASZ AD_DATASZ1 /* hold enough for the entries */
+#else if AD_VERSION == AD_VERSION2
+#define AD_DATASZ AD_DATASZ2
+#endif
+
+/*
+ * some legacy defines from netatalk-990130
+ * (to keep from breaking certain packages)
+ *
+ */
+
+#define ADEDOFF_RFORK 589
+#define ADEDOFF_NAME 86
+#define ADEDOFF_COMMENT 341
+#define ADEDOFF_FINDERI 557
+#ifndef ADEDOFF_FILEI
+#define ADEDOFF_FILEI 541
+#endif
+
+/*
+ * The header of the AppleDouble Header File looks like this:
+ *
+ * NAME SIZE
+ * ==== ====
+ * Magic 4
+ * Version 4
+ * Home File System 16 (this becomes filler in ad v2)
+ * Number of Entries 2
+ * Entry Descriptors for each entry:
+ * Entry ID 4
+ * Offset 4
+ * Length 4
+ */
+
+struct ad_entry {
+ u_int32_t ade_off;
+ u_int32_t ade_len;
+};
+
+typedef struct adf_lock_t {
+ struct flock lock;
+ int user;
+ int *refcount; /* handle read locks with multiple users */
+} adf_lock_t;
+
+struct ad_fd {
+ int adf_fd;
+ off_t adf_off;
+ int adf_flags;
+ adf_lock_t *adf_lock;
+ int adf_refcount, adf_lockcount, adf_lockmax;
+};
+
+/* some header protection */
+#define AD_INITED 0xad494e54 /* ad"INT" */
+struct adouble {
+ u_int32_t ad_magic;
+ u_int32_t ad_version;
+ char ad_filler[ 16 ];
+ struct ad_entry ad_eid[ ADEID_MAX ];
+ struct ad_fd ad_df, ad_hf;
+ int ad_flags, ad_inited;
+#ifdef USE_MMAPPED_HEADERS
+ char *ad_data;
+#else
+ char ad_data[AD_DATASZ_MAX];
+#endif
+};
+
+#define ADFLAGS_DF (1<<0)
+#define ADFLAGS_HF (1<<1)
+#define ADFLAGS_DIR (1<<2)
+#define ADFLAGS_NOADOUBLE (1<<3)
+#define ADFLAGS_V1COMPAT (1<<4)
+
+/* lock flags */
+#define ADLOCK_CLR (0)
+#define ADLOCK_RD (1<<0)
+#define ADLOCK_WR (1<<1)
+#define ADLOCK_MASK (ADLOCK_RD | ADLOCK_WR)
+#define ADLOCK_UPGRADE (1<<2)
+#define ADLOCK_FILELOCK (1<<3)
+
+/* we use this so that we can use the same mechanism for both byte
+ * locks and file synchronization locks. i do this by co-opting either
+ * first bits on 32-bit machines or shifting above the last bit on
+ * 64-bit machines. this only matters for the data fork. */
+#if defined(TRY_64BITOFF_T) && (~0UL > 0xFFFFFFFFU)
+/* synchronization locks */
+#define AD_FILELOCK_BASE (0x80000000)
+#define AD_FILELOCK_WR (AD_FILELOCK_BASE + 0)
+#define AD_FILELOCK_RD (AD_FILELOCK_BASE + 1)
+#else
+#define AD_FILELOCK_BASE (0x7FFFFFFE)
+#define AD_FILELOCK_WR (AD_FILELOCK_BASE + 0)
+#define AD_FILELOCK_RD (AD_FILELOCK_BASE + 1)
+#endif
+
+/* time stuff. we overload the bits a little. */
+#define AD_DATE_CREATE 0
+#define AD_DATE_MODIFY 4
+#define AD_DATE_BACKUP 8
+#define AD_DATE_ACCESS 12
+#define AD_DATE_MASK (AD_DATE_CREATE | AD_DATE_MODIFY | \
+ AD_DATE_BACKUP | AD_DATE_ACCESS)
+#define AD_DATE_UNIX (1 << 10)
+#define AD_DATE_START htonl(0x80000000)
+#define AD_DATE_DELTA 946684800
+#define AD_DATE_FROM_UNIX(x) htonl((x) - AD_DATE_DELTA)
+#define AD_DATE_TO_UNIX(x) (ntohl(x) + AD_DATE_DELTA)
+
+/* private AFPFileInfo bits */
+#define AD_AFPFILEI_OWNER (1 << 0) /* any owner */
+#define AD_AFPFILEI_GROUP (1 << 1) /* ignore group */
+#define AD_AFPFILEI_BLANKACCESS (1 << 2) /* blank access permissions */
+
+#define ad_dfileno(ad) ((ad)->ad_df.adf_fd)
+#define ad_hfileno(ad) ((ad)->ad_hf.adf_fd)
+#define ad_getversion(ad) ((ad)->ad_version)
+
+#define ad_getentrylen(ad,eid) ((ad)->ad_eid[(eid)].ade_len)
+#define ad_setentrylen(ad,eid,len) \
+ ((ad)->ad_eid[(eid)].ade_len = (len))
+#define ad_getentryoff(ad,eid) ((ad)->ad_eid[(eid)].ade_off)
+#define ad_entry(ad,eid) ((caddr_t)(ad)->ad_data + \
+ (ad)->ad_eid[(eid)].ade_off)
+#define ad_getoflags(ad,adf) (((adf)&ADFLAGS_HF) ? \
+ (ad)->ad_hf.adf_flags : (ad)->ad_df.adf_flags)
+
+/* ad_flush.c */
+extern void ad_rebuild_header __P((struct adouble *));
+extern int ad_flush __P((struct adouble *, int));
+extern int ad_close __P((struct adouble *, int));
+
+/* ad_lock.c */
+extern int ad_flock_lock __P((struct adouble *, const u_int32_t /*eid*/,
+ const int /*type*/, const off_t /*offset*/,
+ const size_t /*len*/, const int /*user*/));
+extern int ad_fcntl_lock __P((struct adouble *, const u_int32_t /*eid*/,
+ const int /*type*/, const off_t /*offset*/,
+ const size_t /*len*/, const int /*user*/));
+extern void ad_fcntl_unlock __P((struct adouble *, const int /*user*/));
+
+extern int ad_flock_tmplock __P((struct adouble *, const u_int32_t /*eid*/,
+ const int /*type*/, const off_t /*offset*/,
+ const size_t /*len*/));
+extern int ad_fcntl_tmplock __P((struct adouble *, const u_int32_t /*eid*/,
+ const int /*type*/, const off_t /*offset*/,
+ const size_t /*len*/));
+
+#ifdef USE_FLOCK_LOCKS
+#define ad_lock ad_flock_lock
+#define ad_tmplock ad_flock_tmplock
+#define ad_unlock(a,b)
+#else
+#define ad_lock ad_fcntl_lock
+#define ad_tmplock ad_fcntl_tmplock
+#define ad_unlock ad_fcntl_unlock
+#endif
+
+/* ad_open.c */
+extern char *ad_path __P((char *, int));
+extern int ad_mode __P((char *, int));
+extern int ad_mkdir __P((char *, int));
+extern int ad_open __P((char *, int, int, int, struct adouble *));
+extern int ad_refresh __P((struct adouble *));
+
+/* ad_read.c/ad_write.c */
+extern ssize_t ad_read __P((struct adouble *, const u_int32_t,
+ const off_t, char *, const size_t));
+extern ssize_t ad_write __P((struct adouble *, const u_int32_t, off_t,
+ const int, const char *, const size_t));
+extern int ad_dtruncate __P((struct adouble *, const size_t));
+extern int ad_rtruncate __P((struct adouble *, const size_t));
+
+/* ad_size.c */
+extern off_t ad_size __P((const struct adouble *, const u_int32_t ));
+
+/* ad_mmap.c */
+extern void *ad_mmapread __P((struct adouble *, const u_int32_t,
+ const off_t, const size_t));
+extern void *ad_mmapwrite __P((struct adouble *, const u_int32_t,
+ const off_t, const int, const size_t));
+#define ad_munmap(buf, len) (munmap((buf), (len)))
+
+/* ad_date.c */
+extern int ad_setdate __P((const struct adouble *, unsigned int, u_int32_t));
+extern int ad_getdate __P((const struct adouble *, unsigned int, u_int32_t *));
+
+/* ad_attr.c */
+extern int ad_setattr __P((const struct adouble *, const u_int16_t));
+extern int ad_getattr __P((const struct adouble *, u_int16_t *));
+
+#ifdef HAVE_SENDFILE_READ
+extern ssize_t ad_readfile __P((const struct adouble *, const int,
+ const int, off_t, const size_t));
+#endif
+
+#if 0
+#ifdef HAVE_SENDFILE_WRITE
+extern ssize_t ad_writefile __P((struct adouble *, const int,
+ const int, off_t, const int, const size_t));
+#endif
+#endif
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 1990,1991 Regents of The University of Michigan.
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appears in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation, and that the name of The University
+ * of Michigan not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. This software is supplied as is without expressed or
+ * implied warranties of any kind.
+ *
+ * Research Systems Unix Group
+ * The University of Michigan
+ * c/o Mike Clark
+ * 535 W. William Street
+ * Ann Arbor, Michigan
+ * +1-313-763-0525
+ * netatalk@itd.umich.edu
+ */
+
+#ifndef _ATALK_AEP_H
+#define _ATALK_AEP_H 1
+
+#define AEPOP_REQUEST 1
+#define AEPOP_REPLY 2
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 1990,1991 Regents of The University of Michigan.
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appears in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation, and that the name of The University
+ * of Michigan not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. This software is supplied as is without expressed or
+ * implied warranties of any kind.
+ *
+ * Research Systems Unix Group
+ * The University of Michigan
+ * c/o Mike Clark
+ * 535 W. William Street
+ * Ann Arbor, Michigan
+ * +1-313-763-0525
+ * netatalk@itd.umich.edu
+ */
+
+#ifndef _ATALK_AFP_H
+#define _ATALK_AFP_H 1
+
+#include <sys/types.h>
+#include <netatalk/endian.h>
+
+typedef u_int16_t AFPUserBytes;
+
+/* protocols */
+#define AFPPROTO_ASP 1
+#define AFPPROTO_DSI 2
+
+/* actual transports. the DSI ones (tcp right now) need to be
+ * kept in sync w/ <atalk/dsi.h>.
+ * convention: AFPTRANS_* = (1 << DSI_*)
+ */
+#define AFPTRANS_NONE 0
+#define AFPTRANS_DDP (1 << 0)
+#define AFPTRANS_TCP (1 << 1)
+#define AFPTRANS_ALL (AFPTRANS_DDP | AFPTRANS_TCP)
+
+/* server flags */
+#define AFPSRVRINFO_COPY (1<<0) /* supports copyfile */
+#define AFPSRVRINFO_PASSWD (1<<1) /* supports change password */
+#define AFPSRVRINFO_NOSAVEPASSWD (1<<2) /* don't allow save password */
+#define AFPSRVRINFO_SRVMSGS (1<<3) /* supports server messages */
+#define AFPSRVRINFO_SRVSIGNATURE (1<<4) /* supports server signature */
+#define AFPSRVRINFO_TCPIP (1<<5) /* supports tcpip */
+#define AFPSRVRINFO_SRVNOTIFY (1<<6) /* supports server notifications */
+#define AFPSRVRINFO_FASTBOZO (1<<15) /* fast copying */
+
+#define AFP_OK 0
+#define AFPERR_ACCESS -5000 /* permission denied */
+#define AFPERR_AUTHCONT -5001 /* logincont */
+#define AFPERR_BADUAM -5002 /* uam doesn't exist */
+#define AFPERR_BADVERS -5003 /* bad afp version number */
+#define AFPERR_BITMAP -5004 /* invalid bitmap */
+#define AFPERR_CANTMOVE -5005 /* can't move file */
+#define AFPERR_DENYCONF -5006 /* file synchronization locks conflict */
+#define AFPERR_DIRNEMPT -5007 /* directory not empty */
+#define AFPERR_DFULL -5008 /* disk full */
+#define AFPERR_EOF -5009 /* end of file -- catsearch and afp_read */
+#define AFPERR_BUSY -5010 /* FileBusy */
+#define AFPERR_FLATVOL -5011 /* volume doesn't support directories */
+#define AFPERR_NOITEM -5012 /* ItemNotFound */
+#define AFPERR_LOCK -5013 /* LockErr */
+#define AFPERR_MISC -5014 /* misc. err */
+#define AFPERR_NLOCK -5015 /* no more locks */
+#define AFPERR_NOSRVR -5016 /* no response by server at that address */
+#define AFPERR_EXIST -5017 /* object already exists */
+#define AFPERR_NOOBJ -5018 /* object not found */
+#define AFPERR_PARAM -5019 /* parameter error */
+#define AFPERR_NORANGE -5020 /* no range lock */
+#define AFPERR_RANGEOVR -5021 /* range overlap */
+#define AFPERR_SESSCLOS -5022 /* session closed */
+#define AFPERR_NOTAUTH -5023 /* user not authenticated */
+#define AFPERR_NOOP -5024 /* command not supported */
+#define AFPERR_BADTYPE -5025 /* object is the wrong type */
+#define AFPERR_NFILE -5026 /* too many files open */
+#define AFPERR_SHUTDOWN -5027 /* server is going down */
+#define AFPERR_NORENAME -5028 /* can't rename */
+#define AFPERR_NODIR -5029 /* couldn't find directory */
+#define AFPERR_ITYPE -5030 /* wrong icon type */
+#define AFPERR_VLOCK -5031 /* volume locked */
+#define AFPERR_OLOCK -5032 /* object locked */
+#define AFPERR_CTNSHRD -5033 /* share point contains a share point */
+#define AFPERR_NOID -5034 /* file thread not found */
+#define AFPERR_EXISTID -5035 /* file already has an id */
+#define AFPERR_DIFFVOL -5036 /* different volume */
+#define AFPERR_CATCHNG -5037 /* catalog has changed */
+#define AFPERR_SAMEOBJ -5038 /* source file == destination file */
+#define AFPERR_BADID -5039 /* non-existent file id */
+#define AFPERR_PWDSAME -5040 /* same password/can't change password */
+#define AFPERR_PWDSHORT -5041 /* password too short */
+#define AFPERR_PWDEXPR -5042 /* password expired */
+#define AFPERR_INSHRD -5043 /* folder being shared is inside a
+ shared folder. may be returned by
+ afpMoveAndRename. */
+#define AFPERR_INTRASH -5044 /* shared folder in trash. */
+#define AFPERR_PWDCHNG -5045 /* password needs to be changed */
+#define AFPERR_PWDPOLCY -5046 /* password fails policy check */
+#define AFPERR_USRLOGIN -5047 /* user already logged on */
+
+/* AFP Attention Codes -- 4 bits */
+#define AFPATTN_SHUTDOWN (1 << 15) /* shutdown/disconnect */
+#define AFPATTN_CRASH (1 << 14) /* server crashed */
+#define AFPATTN_MESG (1 << 13) /* server has message */
+#define AFPATTN_NORECONNECT (1 << 12) /* don't reconnect */
+/* server notification */
+#define AFPATTN_NOTIFY (AFPATTN_MESG | AFPATTN_NORECONNECT)
+
+/* extended bitmap -- 12 bits. volchanged is only useful w/ a server
+ * notification, and time is only useful for shutdown. */
+#define AFPATTN_VOLCHANGED (1 << 0) /* volume has changed */
+#define AFPATTN_TIME(x) ((x) & 0xfff) /* time in minutes */
+
+typedef enum {
+ AFPMESG_LOGIN = 0,
+ AFPMESG_SERVER = 1
+} afpmessage_t;
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 1990,1991 Regents of The University of Michigan.
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appears in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation, and that the name of The University
+ * of Michigan not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. This software is supplied as is without expressed or
+ * implied warranties of any kind.
+ *
+ * Research Systems Unix Group
+ * The University of Michigan
+ * c/o Mike Clark
+ * 535 W. William Street
+ * Ann Arbor, Michigan
+ * +1-313-763-0525
+ * netatalk@itd.umich.edu
+ */
+
+#ifndef _ATALK_ASP_H
+#define _ATALK_ASP_H 1
+
+#include <sys/types.h>
+#include <sys/cdefs.h>
+#include <netatalk/endian.h>
+#include <netatalk/at.h>
+#include <atalk/atp.h>
+#include <atalk/afp.h>
+#include <atalk/server_child.h>
+
+#define ASP_HDRSIZ 4
+#define ASP_CMDSIZ 578
+
+#define ASP_MAXPACKETS 8
+#define ASP_CMDMAXSIZ (ASP_CMDSIZ + ASP_HDRSIZ)
+#define ASP_DATASIZ (ASP_CMDSIZ*ASP_MAXPACKETS)
+#define ASP_DATAMAXSIZ ((ASP_CMDSIZ + ASP_HDRSIZ)*ASP_MAXPACKETS)
+
+typedef struct ASP {
+ ATP asp_atp;
+ struct sockaddr_at asp_sat;
+ u_int8_t asp_wss;
+ u_int8_t asp_sid;
+ union {
+ struct {
+ char *as_status;
+ int as_slen;
+ } asu_status;
+ u_int16_t asu_seq;
+ } asp_u;
+#define asp_status asp_u.asu_status.as_status
+#define asp_slen asp_u.asu_status.as_slen
+#define asp_seq asp_u.asu_seq
+ int asp_flags;
+ char child, inited, *commands;
+ char cmdbuf[ASP_CMDMAXSIZ];
+ char data[ASP_DATAMAXSIZ];
+ int cmdlen, datalen;
+ size_t read_count, write_count;
+} *ASP;
+
+#define ASPFL_SLS 1
+#define ASPFL_SSS 2
+
+#define ASPFUNC_CLOSE 1
+#define ASPFUNC_CMD 2
+#define ASPFUNC_STAT 3
+#define ASPFUNC_OPEN 4
+#define ASPFUNC_TICKLE 5
+#define ASPFUNC_WRITE 6
+#define ASPFUNC_WRTCONT 7
+#define ASPFUNC_ATTN 8
+
+#define ASPERR_OK 0x0000
+#define ASPERR_BADVERS 0xfbd6
+#define ASPERR_BUFSMALL 0xfbd5
+#define ASPERR_NOSESS 0xfbd4
+#define ASPERR_NOSERV 0xfbd3
+#define ASPERR_PARM 0xfbd2
+#define ASPERR_SERVBUSY 0xfbd1
+#define ASPERR_SESSCLOS 0xfbd0
+#define ASPERR_SIZERR 0xfbcf
+#define ASPERR_TOOMANY 0xfbce
+#define ASPERR_NOACK 0xfbcd
+
+extern ASP asp_init __P((ATP));
+extern void asp_setstatus __P((ASP, char *, const int));
+extern ASP asp_getsession __P((ASP, server_child *, const int));
+extern int asp_close __P((ASP));
+extern int asp_shutdown __P((ASP));
+extern int asp_attention __P((ASP, AFPUserBytes));
+extern int asp_getrequest __P((ASP));
+extern int asp_cmdreply __P((ASP, int));
+extern int asp_wrtcont __P((ASP, char *, int *));
+#define asp_wrtreply(a,b) asp_cmdreply((a), (b))
+extern void asp_kill __P((int));
+extern void asp_tickle __P((ASP, const u_int8_t, struct sockaddr_at *));
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 1990,1991 Regents of The University of Michigan.
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appears in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation, and that the name of The University
+ * of Michigan not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. This software is supplied as is without expressed or
+ * implied warranties of any kind.
+ *
+ * Research Systems Unix Group
+ * The University of Michigan
+ * c/o Mike Clark
+ * 535 W. William Street
+ * Ann Arbor, Michigan
+ * +1-313-763-0525
+ * netatalk@itd.umich.edu
+ */
+
+#ifndef _ATALK_ATP_H
+#define _ATALK_ATP_H 1
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <netatalk/at.h>
+#include <netatalk/endian.h>
+
+/* ATP packet format
+
+ |----------------|
+ | link header |
+ | ... |
+ |----------------|
+ | DDP header |
+ | ... |
+ | type = 3 |
+ |----------------|
+ | control info | --> bits 7,6: function code
+ |----------------| 5: XO bit
+ | bitmap/seq no. | 4: EOM bit
+ |----------------| 3: STS bit
+ | TID (MSB) | 2,1,0: release timer code (ignored under phase I)
+ |----------------|
+ | TID (LSB) |
+ |----------------|
+ | user bytes (4) |
+ |----------------|
+ | data (0-578) |
+ | ... |
+ |----------------|
+*/
+struct atphdr {
+ u_int8_t atphd_ctrlinfo; /* control information */
+ u_int8_t atphd_bitmap; /* bitmap or sequence number */
+ u_int16_t atphd_tid; /* transaction id. */
+};
+
+/* ATP protocol parameters
+*/
+#define ATP_MAXDATA (578+4) /* maximum ATP data size */
+#define ATP_BUFSIZ 587 /* maximum packet size */
+#define ATP_HDRSIZE 5 /* includes DDP type field */
+
+#define ATP_TRELMASK 0x07 /* mask all but TREL */
+#define ATP_RELTIME 30 /* base release timer (in secs) */
+
+#define ATP_TREL30 0x0 /* release time codes */
+#define ATP_TREL1M 0x1 /* these are passed in flags of */
+#define ATP_TREL2M 0x2 /* atp_sreq call, and set in the */
+#define ATP_TREL4M 0x3 /* packet control info. */
+#define ATP_TREL8M 0x4
+
+#define ATP_TRIES_INFINITE -1 /* for atp_sreq, etc */
+
+struct atpxobuf {
+ u_int16_t atpxo_tid;
+ struct timeval atpxo_tv;
+ int atpxo_reltime;
+ struct atpbuf *atpxo_packet[8];
+};
+
+struct atpbuf {
+ struct atpbuf *atpbuf_next; /* next buffer in chain */
+ short atpbuf_dlen; /* data length <= ATP_BUFSIZ */
+ struct sockaddr_at atpbuf_addr; /* net address sent/recvd */
+ union {
+ char atpbuf_data[ ATP_BUFSIZ ]; /* the data */
+ struct atpxobuf atpbuf_xo; /* for XO requests */
+ } atpbuf_info;
+};
+
+struct atp_handle {
+ int atph_socket; /* ddp socket */
+ struct sockaddr_at atph_saddr; /* address */
+ u_int16_t atph_tid; /* last tid used */
+ u_int16_t atph_rtid; /* last received (rreq) */
+ u_int8_t atph_rxo; /* XO flag from last rreq */
+ int atph_rreltime; /* release time (secs) */
+ struct atpbuf *atph_sent; /* packets we send (XO) */
+ struct atpbuf *atph_queue; /* queue of pending packets */
+ int atph_reqtries; /* retry count for request */
+ int atph_reqto; /* retry timeout for request */
+ int atph_rrespcount; /* expected # of responses */
+ u_int8_t atph_rbitmap; /* bitmap for request */
+ struct atpbuf *atph_reqpkt; /* last request packet */
+ struct timeval atph_reqtv; /* when we last sent request */
+ struct atpbuf *atph_resppkt[8]; /* response to request */
+};
+
+typedef struct atp_handle *ATP;
+
+#define atp_sockaddr( h ) (&(h)->atph_saddr)
+#define atp_fileno(x) ((x)->atph_socket)
+
+struct sreq_st {
+ char *atpd_data; /* request data */
+ int atpd_dlen;
+ int atpd_tries; /* max. retry count */
+ int atpd_to; /* retry interval */
+};
+
+struct rres_st {
+ struct iovec *atpd_iov; /* for response */
+ int atpd_iovcnt;
+};
+
+struct rreq_st {
+ char *atpd_data; /* request data */
+ int atpd_dlen;
+};
+
+struct sres_st {
+ struct iovec *atpd_iov; /* for response */
+ int atpd_iovcnt;
+};
+
+struct atp_block {
+ struct sockaddr_at *atp_saddr; /* from/to address */
+ union {
+ struct sreq_st sreqdata;
+#define atp_sreqdata atp_data.sreqdata.atpd_data
+#define atp_sreqdlen atp_data.sreqdata.atpd_dlen
+#define atp_sreqtries atp_data.sreqdata.atpd_tries
+#define atp_sreqto atp_data.sreqdata.atpd_to
+
+ struct rres_st rresdata;
+#define atp_rresiov atp_data.rresdata.atpd_iov
+#define atp_rresiovcnt atp_data.rresdata.atpd_iovcnt
+
+ struct rreq_st rreqdata;
+#define atp_rreqdata atp_data.rreqdata.atpd_data
+#define atp_rreqdlen atp_data.rreqdata.atpd_dlen
+
+ struct sres_st sresdata;
+#define atp_sresiov atp_data.sresdata.atpd_iov
+#define atp_sresiovcnt atp_data.sresdata.atpd_iovcnt
+ } atp_data;
+ u_int8_t atp_bitmap; /* response buffer bitmap */
+};
+
+
+/* flags for ATP options (and control byte)
+*/
+#define ATP_STS (1<<3) /* Send Transaction Status */
+#define ATP_EOM (1<<4) /* End Of Message */
+#define ATP_XO (1<<5) /* eXactly Once mode */
+
+/* function codes
+*/
+#define ATP_FUNCMASK (3<<6) /* mask all but function */
+
+#define ATP_TREQ (1<<6) /* Trans. REQuest */
+#define ATP_TRESP (2<<6) /* Trans. RESPonse */
+#define ATP_TREL (3<<6) /* Trans. RELease */
+
+extern ATP atp_open __P((const u_int8_t,
+ const struct at_addr *));
+extern int atp_close __P((ATP));
+extern int atp_sreq __P((ATP, struct atp_block *, int,
+ u_int8_t));
+extern int atp_rresp __P((ATP, struct atp_block *));
+extern int atp_rsel __P((ATP, struct sockaddr_at *, int));
+extern int atp_rreq __P((ATP, struct atp_block *));
+extern int atp_sresp __P((ATP, struct atp_block *));
+
+#endif
--- /dev/null
+/*
+ * interface for database access to cnids. i do it this way to abstract
+ * things a bit in case we want to change the underlying implementation.
+ */
+
+#ifndef _ATALK_CNID_H
+#define _ATALK_CNID_H 1
+
+#include <sys/cdefs.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <netatalk/endian.h>
+
+typedef u_int32_t cnid_t;
+
+/* cnid_open.c */
+extern void *cnid_open __P((const char *));
+
+/* cnid_close.c */
+extern void cnid_close __P((void *));
+
+/* cnid_add.c */
+extern cnid_t cnid_add __P((void *, const struct stat *, const cnid_t,
+ const char *, const int, cnid_t));
+
+/* cnid_get.c */
+extern cnid_t cnid_get __P((void *, const cnid_t, const char *, const int));
+extern char *cnid_resolve __P((void *, cnid_t *));
+extern cnid_t cnid_lookup __P((void *, const struct stat *, const cnid_t,
+ const char *, const int));
+
+/* cnid_update.c */
+extern int cnid_update __P((void *, const cnid_t, const struct stat *,
+ const cnid_t, const char *, int));
+
+/* cnid_delete.c */
+extern int cnid_delete __P((void *, const cnid_t));
+
+/* cnid_nextid.c */
+extern cnid_t cnid_nextid __P((void *));
+
+#endif /* include/atalk/cnid.h */
--- /dev/null
+/*
+ * Copyright (c) 1996 Regents of The University of Michigan.
+ * All Rights Reserved. See COPYRIGHT.
+ *
+ * NOTE: SunOS 4 and ultrix are pretty much the only reason why there
+ * are checks for EINTR everywhere.
+ */
+
+#include <sys/cdefs.h>
+#include <signal.h>
+
+#ifdef __svr4__
+/*
+ * SunOS 5 (solaris) has SA_RESTART, but no SA_INTERRUPT.
+ */
+#ifndef SA_INTERRUPT
+#define SA_INTERRUPT 0
+#endif
+
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+extern int flock __P((int, int));
+extern int inet_aton __P((const char *, struct in_addr *));
+#else /* __svr4__ */
+
+#ifdef sun
+/*
+ * SunOS 4 has SA_INTERRUPT, but no SA_RESTART.
+ */
+#ifndef SA_RESTART
+#define SA_RESTART 0
+#endif
+#endif /* sun */
+
+#endif /* __svr4__ */
+
+#ifdef linux
+/*
+ * Linux has SA_RESTART, but no SA_INTERRUPT. Note that the documentation
+ * seems to be wrong on several counts. First, SA_ONESHOT is not the default,
+ * and second, SA_RESTART does what you'd expect (the same as svr4) and has
+ * nothing to do with SA_ONESHOT.
+ */
+#ifndef SA_INTERRUPT
+#define SA_INTERRUPT 0
+#endif /* SA_INTERRUPT */
+#endif /* linux */
+
+#ifdef ultrix
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+/*
+ * Here's the really confusing one... Under Ultrix, sigaction() works just
+ * like sigvec(), except that SV_INTERRUPT is always set. Hence, there is
+ * no SA_INTERRUPT flag. Unfortunately, there's also no SA_RESTART, so
+ * there's no way to suppress the interrupt. Sigh.
+ */
+#ifndef SA_INTERRUPT
+#define SA_INTERRUPT 0
+#endif
+#ifndef SA_RESTART
+#define SA_RESTART 0
+#endif
+
+extern char *strdup __P((const char *));
+extern int inet_aton __P((const char *, struct in_addr *));
+#endif /* ultrix */
+
+#ifdef BSD4_4
+#ifndef SA_INTERRUPT
+#define SA_INTERRUPT 0
+#endif
+#endif /* BSD4_4 */
+
+#if defined(ultrix) || defined(_IBMR2) || defined(NEED_GETUSERSHELL)
+extern char *getusershell __P((void));
+#endif
--- /dev/null
+/*
+ * Copyright (c) 1990,1991 Regents of The University of Michigan.
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appears in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation, and that the name of The University
+ * of Michigan not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. This software is supplied as is without expressed or
+ * implied warranties of any kind.
+ *
+ * Research Systems Unix Group
+ * The University of Michigan
+ * c/o Mike Clark
+ * 535 W. William Street
+ * Ann Arbor, Michigan
+ * +1-313-763-0525
+ * netatalk@itd.umich.edu
+ */
+
+#ifndef _ATALK_DDP_H
+#define _ATALK_DDP_H 1
+
+#define DDPTYPE_RTMPRD 1
+#define DDPTYPE_NBP 2
+#define DDPTYPE_ATP 3
+#define DDPTYPE_AEP 4
+#define DDPTYPE_RTMPR 5
+#define DDPTYPE_ZIP 6
+#define DDPTYPE_ADSP 7
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 1997 Adrian Sun (asun@zoology.washington.edu)
+ * All rights reserved.
+ */
+
+#ifndef _ATALK_DSI_H
+#define _ATALK_DSI_H
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <signal.h>
+
+#include <netinet/in.h>
+#include <atalk/afp.h>
+#include <atalk/server_child.h>
+#include <netatalk/endian.h>
+
+/* What a DSI packet looks like:
+ 0 32
+ |-------------------------------|
+ |flags |command| requestID |
+ |-------------------------------|
+ |error code/enclosed data offset|
+ |-------------------------------|
+ |total data length |
+ |-------------------------------|
+ |reserved field |
+ |-------------------------------|
+
+ CONVENTION: anything with a dsi_ prefix is kept in network byte order.
+*/
+
+/* these need to be kept in sync w/ AFPTRANS_* in <atalk/afp.h>.
+ * convention: AFPTRANS_* = (1 << DSI_*) */
+typedef enum {
+ DSI_MIN = 1,
+ DSI_TCPIP = 1,
+ DSI_MAX = 1
+} dsi_proto;
+
+#define DSI_BLOCKSIZ 16
+struct dsi_block {
+ u_int8_t dsi_flags; /* packet type: request or reply */
+ u_int8_t dsi_command; /* command */
+ u_int16_t dsi_requestID; /* request ID */
+ u_int32_t dsi_code; /* error code or data offset */
+ u_int32_t dsi_len; /* total data length */
+ u_int32_t dsi_reserved; /* reserved field */
+};
+
+#define DSI_CMDSIZ 800
+#define DSI_DATASIZ 8192
+/* child and parent processes might interpret a couple of these
+ * differently. */
+typedef struct DSI {
+ dsi_proto protocol;
+ struct dsi_block header;
+ struct sockaddr_in server, client;
+ sigset_t sigblockset;
+ struct itimerval timer, savetimer;
+ u_int32_t attn_quantum, datasize, server_quantum;
+ u_int16_t serverID, clientID;
+ u_int8_t *status, commands[DSI_CMDSIZ], data[DSI_DATASIZ];
+ int statuslen, datalen, cmdlen;
+ size_t read_count, write_count;
+ /* inited = initialized?, child = a child?, noreply = send reply? */
+ char child, inited, noreply;
+ const char *program;
+ int socket, serversock;
+
+ /* protocol specific open/close, send/receive
+ * send/receive fill in the header and use dsi->commands.
+ * write/read just write/read data */
+ pid_t (*proto_open)(struct DSI *);
+ void (*proto_close)(struct DSI *);
+} DSI;
+
+/* DSI flags */
+#define DSIFL_REQUEST 0x00
+#define DSIFL_REPLY 0x01
+#define DSIFL_MAX 0x01
+
+/* DSI session options */
+#define DSIOPT_SERVQUANT 0x00 /* server request quantum */
+#define DSIOPT_ATTNQUANT 0x01 /* attention quantum */
+
+/* DSI Commands */
+#define DSIFUNC_CLOSE 1 /* DSICloseSession */
+#define DSIFUNC_CMD 2 /* DSICommand */
+#define DSIFUNC_STAT 3 /* DSIGetStatus */
+#define DSIFUNC_OPEN 4 /* DSIOpenSession */
+#define DSIFUNC_TICKLE 5 /* DSITickle */
+#define DSIFUNC_WRITE 6 /* DSIWrite */
+#define DSIFUNC_ATTN 8 /* DSIAttention */
+#define DSIFUNC_MAX 8 /* largest command */
+
+/* DSI Error codes: most of these aren't used. */
+#define DSIERR_OK 0x0000
+#define DSIERR_BADVERS 0xfbd6
+#define DSIERR_BUFSMALL 0xfbd5
+#define DSIERR_NOSESS 0xfbd4
+#define DSIERR_NOSERV 0xfbd3
+#define DSIERR_PARM 0xfbd2
+#define DSIERR_SERVBUSY 0xfbd1
+#define DSIERR_SESSCLOS 0xfbd0
+#define DSIERR_SIZERR 0xfbcf
+#define DSIERR_TOOMANY 0xfbce
+#define DSIERR_NOACK 0xfbcd
+
+/* server and client quanta */
+#define DSI_DEFQUANT 2 /* default attention quantum size */
+#define DSI_SERVQUANT_MAX 0xffffffffL /* server quantum */
+#define DSI_SERVQUANT_MIN 0x0004A2E0L /* minimum server quantum */
+#define DSI_SERVQUANT_DEF DSI_SERVQUANT_MIN /* default server quantum */
+
+/* default port number */
+#define DSI_AFPOVERTCP_PORT 548
+
+/* basic initialization: dsi_init.c */
+extern DSI *dsi_init __P((const dsi_proto /*protocol*/,
+ const char * /*program*/,
+ const char * /*host*/, const char * /*address*/,
+ const int /*port*/, const int /*proxy*/,
+ const u_int32_t /* server quantum */));
+extern void dsi_setstatus __P((DSI *, u_int8_t *, const int));
+
+/* in dsi_getsess.c */
+extern DSI *dsi_getsession __P((DSI *, server_child *, const int));
+extern void dsi_kill __P((int));
+
+
+/* DSI Commands: individual files */
+extern void dsi_opensession __P((DSI *));
+extern int dsi_attention __P((DSI *, AFPUserBytes));
+extern int dsi_cmdreply __P((DSI *, const int));
+extern void dsi_tickle __P((DSI *));
+extern void dsi_getstatus __P((DSI *));
+extern void dsi_close __P((DSI *));
+
+/* low-level stream commands -- in dsi_stream.c */
+extern size_t dsi_stream_write __P((DSI *, void *, const size_t));
+extern size_t dsi_stream_read __P((DSI *, void *, const size_t));
+extern int dsi_stream_send __P((DSI *, void *, size_t));
+extern int dsi_stream_receive __P((DSI *, void *, const int, int *));
+
+/* client writes -- dsi_write.c */
+extern size_t dsi_writeinit __P((DSI *, void *, const size_t));
+extern size_t dsi_write __P((DSI *, void *, const size_t));
+extern void dsi_writeflush __P((DSI *));
+#define dsi_wrtreply(a,b) dsi_cmdreply(a,b)
+
+/* client reads -- dsi_read.c */
+extern ssize_t dsi_readinit __P((DSI *, void *, const size_t, const size_t,
+ const int));
+extern ssize_t dsi_read __P((DSI *, void *, const size_t));
+extern void dsi_readdone __P((DSI *));
+
+/* some useful macros */
+#define dsi_serverID(x) ((x)->serverID++)
+#define dsi_send(x) do { \
+ (x)->header.dsi_len = htonl((x)->cmdlen); \
+ dsi_stream_send((x), (x)->commands, (x)->cmdlen); \
+} while (0)
+#define dsi_receive(x) (dsi_stream_receive((x), (x)->commands, \
+ DSI_CMDSIZ, &(x)->cmdlen))
+#endif /* atalk/dsi.h */
--- /dev/null
+/*
+ * Copyright (c) 1990,1991 Regents of The University of Michigan.
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appears in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation, and that the name of The University
+ * of Michigan not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. This software is supplied as is without expressed or
+ * implied warranties of any kind.
+ *
+ * Research Systems Unix Group
+ * The University of Michigan
+ * c/o Mike Clark
+ * 535 W. William Street
+ * Ann Arbor, Michigan
+ * +1-313-763-0525
+ * netatalk@itd.umich.edu
+ */
+
+#ifndef _ATALK_NBP_H
+#define _ATALK_NBP_H 1
+#define NBP_UNRGSTR_4ARGS 1
+#define ATP_OPEN_2ARGS 1
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <netatalk/at.h>
+#include <netatalk/endian.h>
+
+struct nbphdr {
+#if BYTE_ORDER == BIG_ENDIAN
+ unsigned nh_op : 4,
+ nh_cnt : 4,
+#else BYTE_ORDER
+ unsigned nh_cnt : 4,
+ nh_op : 4,
+#endif BYTE_ORDER
+ nh_id : 8;
+};
+
+#define SZ_NBPHDR 2
+
+struct nbptuple {
+ u_int16_t nt_net;
+ u_int8_t nt_node;
+ u_int8_t nt_port;
+ u_int8_t nt_enum;
+};
+#define SZ_NBPTUPLE 5
+
+#define NBPSTRLEN 32
+/*
+ * Name Binding Protocol Network Visible Entity
+ */
+struct nbpnve {
+ struct sockaddr_at nn_sat;
+ u_char nn_objlen;
+ char nn_obj[ NBPSTRLEN ];
+ u_char nn_typelen;
+ char nn_type[ NBPSTRLEN ];
+ u_char nn_zonelen;
+ char nn_zone[ NBPSTRLEN ];
+};
+
+/*
+ * Note that NBPOP_ERROR is not standard. As Apple adds more NBPOPs,
+ * we need to check for collisions with our extra values. */
+#define NBPOP_BRRQ 0x1
+#define NBPOP_LKUP 0x2
+#define NBPOP_LKUPREPLY 0x3
+#define NBPOP_FWD 0x4
+#define NBPOP_RGSTR 0x7
+#define NBPOP_UNRGSTR 0x8
+#define NBPOP_CONFIRM 0x9
+#define NBPOP_OK 0xa /* NBPOP_STATUS_REPLY */
+#define NBPOP_CLOSE_NOTE 0xb
+
+#define NBPOP_ERROR 0xf
+
+#define NBPMATCH_NOGLOB (1<<1)
+#define NBPMATCH_NOZONE (1<<2)
+
+extern int nbp_name __P((const char *, char **, char **, char **));
+extern int nbp_lookup __P((const char *, const char *, const char *,
+ struct nbpnve *, const int,
+ const struct at_addr *));
+extern int nbp_rgstr __P((struct sockaddr_at *,
+ const char *, const char *, const char *));
+extern int nbp_unrgstr __P((const char *, const char *, const char *,
+ const struct at_addr *));
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 1999 Adrian Sun (asun@zoology.washington.edu)
+ * All Rights Reserved. See COPYRIGHT.
+ *
+ * this provides a generic interface to the ddp layer. with this, we
+ * should be able to interact with any appletalk stack that allows
+ * direct access to the ddp layer. right now, only os x server's ddp
+ * layer and the generic socket based interfaces are understood.
+ */
+
+#ifndef _ATALK_NETDDP_H
+#define _ATALK_NETDDP_H 1
+
+#include <sys/cdefs.h>
+#include <sys/socket.h>
+#include <netatalk/at.h>
+
+extern int netddp_open __P((struct sockaddr_at *, struct sockaddr_at *));
+
+#if !defined(NO_DDP) && defined(MACOSX_SERVER)
+extern int netddp_sendto __P((int, void *, int, unsigned int,
+ const struct sockaddr *, unsigned int));
+extern int netddp_recvfrom __P((int, void *, int, unsigned int,
+ struct sockaddr *, unsigned int *));
+#define netddp_close(a) ddp_close(a)
+#else
+#include <unistd.h>
+#include <sys/types.h>
+
+#define netddp_close(a) close(a)
+#define netddp_sendto sendto
+#define netddp_recvfrom recvfrom
+#endif
+
+#endif /* netddp.h */
+
--- /dev/null
+/*
+ * Copyright (c) 1990,1991 Regents of The University of Michigan.
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appears in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation, and that the name of The University
+ * of Michigan not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. This software is supplied as is without expressed or
+ * implied warranties of any kind.
+ *
+ * Research Systems Unix Group
+ * The University of Michigan
+ * c/o Mike Clark
+ * 535 W. William Street
+ * Ann Arbor, Michigan
+ * +1-313-763-0525
+ * netatalk@itd.umich.edu
+ */
+
+#ifndef _ATALK_PAP_H
+#define _ATALK_PAP_H 1
+
+#define PAP_OPEN 1
+#define PAP_OPENREPLY 2
+#define PAP_READ 3
+#define PAP_DATA 4
+#define PAP_TICKLE 5
+#define PAP_CLOSE 6
+#define PAP_CLOSEREPLY 7
+#define PAP_SENDSTATUS 8
+#define PAP_STATUS 9
+
+#define PAP_MAXDATA 512
+#define PAP_MAXQUANTUM 8
+
+#endif
--- /dev/null
+#ifndef ATALK_PATHS_H
+#define ATALK_PATHS_H 1
+
+/* we need a way of concatenating strings */
+#ifdef __STDC__
+#ifdef HAVE_BROKEN_CPP
+#define BROKEN_ECHO(a) a
+#define ATALKPATHCAT(a,b) BROKEN_ECHO(a)##BROKEN_ECHO(b)
+#else
+#define ATALKPATHCAT(a,b) a##b
+#endif
+#else
+#define ATALKPATHCAT(a,b) a/**/b
+#endif
+
+
+/* lock file path. this should be re-organized a bit. */
+#ifndef _PATH_LOCKDIR
+#ifdef BSD4_4
+#ifdef MACOSX_SERVER
+#define _PATH_LOCKDIR "/var/run/"
+#else
+#define _PATH_LOCKDIR "/var/spool/lock/"
+#endif
+#else
+#ifdef linux
+#define _PATH_LOCKDIR "/var/run/"
+#else
+#define _PATH_LOCKDIR "/var/spool/locks/"
+#endif /* linux */
+#endif /* BSD4_4 */
+#endif
+
+/*
+ * papd paths
+ */
+#define _PATH_PAPDPRINTCAP "/etc/printcap"
+#ifdef ultrix
+#define _PATH_PAPDSPOOLDIR "/usr/spool/lpd"
+#else ultrix
+#define _PATH_PAPDSPOOLDIR "/var/spool/lpd"
+#endif ultrix
+#ifdef BSD4_4
+#define _PATH_DEVPRINTER "/var/run/printer"
+#else BSD4_4
+#define _PATH_DEVPRINTER "/dev/printer"
+#endif BSD4_4
+
+/*
+ * atalkd paths
+ */
+#define _PATH_ATALKDEBUG "/tmp/atalkd.debug"
+#define _PATH_ATALKDTMP "atalkd.tmp"
+#define _PATH_ATALKDLOCK ATALKPATHCAT(_PATH_LOCKDIR,"atalkd.pid")
+
+/*
+ * psorder paths
+ */
+#define _PATH_TMPPAGEORDER "/tmp/psorderXXXXXX"
+#define _PATH_PAPDLOCK ATALKPATHCAT(_PATH_LOCKDIR,"papd.pid")
+
+/*
+ * afpd paths
+ */
+#define _PATH_AFPTKT "/tmp/AFPtktXXXXXX"
+#define _PATH_AFPDLOCK ATALKPATHCAT(_PATH_LOCKDIR,"afpd.pid")
+
+#endif /* atalk/paths.h */
--- /dev/null
+/*
+ * Copyright (c) 1990,1991 Regents of The University of Michigan.
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appears in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation, and that the name of The University
+ * of Michigan not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. This software is supplied as is without expressed or
+ * implied warranties of any kind.
+ *
+ * Research Systems Unix Group
+ * The University of Michigan
+ * c/o Mike Clark
+ * 535 W. William Street
+ * Ann Arbor, Michigan
+ * +1-313-763-0525
+ * netatalk@itd.umich.edu
+ */
+
+#ifndef _ATALK_RTMP_H
+#define _ATALK_RTMP_H 1
+
+#include <netatalk/endian.h>
+
+#define RTMPROP_REQUEST 1
+
+struct rtmpent {
+ u_int16_t re_net;
+ u_int8_t re_hops;
+};
+
+#define RTMPHOPS_MAX 15
+#define RTMPHOPS_POISON 31
+
+struct rtmprdhdr {
+ u_int16_t rrdh_snet;
+ u_int8_t rrdh_idlen;
+ u_int8_t rrdh_id;
+};
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 1997 Adrian Sun (asun@zoology.washington.edu)
+ * All rights reserved.
+ */
+
+#ifndef _ATALK_SERVER_CHILD_H
+#define _ATALK_SERVER_CHILD_H 1
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <netatalk/endian.h>
+
+/* useful stuff for child processes. most of this is hidden in
+ * server_child.c to ease changes in implementation */
+
+#define CHILD_NFORKS 2
+#define CHILD_ASPFORK 0
+#define CHILD_PAPFORK 0
+#define CHILD_DSIFORK 1
+
+typedef struct server_child {
+ void *fork;
+ int count, nsessions, nforks;
+} server_child;
+
+/* server_child.c */
+extern server_child *server_child_alloc __P((const int, const int));
+extern int server_child_add __P((server_child *, const int, const pid_t));
+extern int server_child_remove __P((server_child *, const int, const pid_t));
+extern void server_child_free __P((server_child *));
+
+extern void server_child_kill __P((server_child *, const int, const int));
+extern void server_child_setup __P((server_child *, const int, void (*)()));
+extern void server_child_handler __P((server_child *));
+
+#endif
--- /dev/null
+/* Copyright (c) 1999 Adrian Sun (asun@zoology.washington.edu)
+ * All Rights Reserved. See COPYRIGHT.
+ */
+
+#ifndef UAM_H
+#define UAM_H 1
+
+#include <sys/cdefs.h>
+#include <pwd.h>
+#include <stdarg.h>
+
+/* just a label for exported bits */
+#define UAM_MODULE_EXPORT
+
+/* type of uam */
+#define UAM_MODULE_SERVER 1
+#define UAM_MODULE_CLIENT 2
+
+/* in case something drastic has to change */
+#define UAM_MODULE_VERSION 1
+
+/* things for which we can have uams */
+#define UAM_SERVER_LOGIN (1 << 0)
+#define UAM_SERVER_CHANGEPW (1 << 1)
+#define UAM_SERVER_PRINTAUTH (1 << 2)
+
+/* options */
+#define UAM_OPTION_USERNAME (1 << 0) /* get space for username */
+#define UAM_OPTION_GUEST (1 << 1) /* get guest user */
+#define UAM_OPTION_PASSWDOPT (1 << 2) /* get the password file */
+#define UAM_OPTION_SIGNATURE (1 << 3) /* get server signature */
+#define UAM_OPTION_RANDNUM (1 << 4) /* request a random number */
+#define UAM_OPTION_HOSTNAME (1 << 5) /* get host name */
+#define UAM_OPTION_COOKIE (1 << 6) /* cookie handle */
+
+/* some password options. you pass these in the length parameter and
+ * get back the corresponding option. not all of these are implemented. */
+#define UAM_PASSWD_FILENAME (1 << 0)
+#define UAM_PASSWD_MINLENGTH (1 << 1)
+#define UAM_PASSWD_MAXFAIL (1 << 2) /* not implemented yet. */
+#define UAM_PASSWD_EXPIRETIME (1 << 3) /* not implemented yet. */
+
+/* i'm doing things this way because os x server's dynamic linker
+ * support is braindead. it also allows me to do a little versioning. */
+struct uam_export {
+ int uam_type, uam_version;
+ int (*uam_setup)(const char *);
+ void (*uam_cleanup)(void);
+};
+
+/* register and unregister uams with these functions */
+extern int uam_register __P((const int, const char *, const char *, ...));
+extern void uam_unregister __P((const int, const char *));
+
+/* helper functions */
+extern struct passwd *uam_getname __P((char *, const int));
+extern int uam_checkuser __P((const struct passwd *));
+
+/* afp helper functions */
+extern int uam_afp_read __P((void *, char *, int *,
+ int (*)(void *, void *, const int)));
+extern int uam_afpserver_option __P((void *, const int, void *, int *));
+
+/* switch.c */
+#define UAM_AFPSERVER_PREAUTH (0)
+#define UAM_AFPSERVER_POSTAUTH (1 << 0)
+
+extern int uam_afpserver_action __P((const int /*id*/, const int /*switch*/,
+ int (**)(), int (**)()));
+
+#endif
--- /dev/null
+#ifndef _ATALK_UTIL_H
+#define _ATALK_UTIL_H 1
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <netatalk/at.h>
+
+extern unsigned const char _diacasemap[], _dialowermap[];
+
+extern char **getifacelist(void);
+extern void freeifacelist(char **);
+
+
+#define diatolower(x) _dialowermap[(x)]
+#define diatoupper(x) _diacasemap[(x)]
+extern int atalk_aton __P((char *, struct at_addr *));
+extern void bprint __P((char *, int));
+extern int strdiacasecmp __P((const unsigned char *, const unsigned char *));
+extern int strndiacasecmp __P((const unsigned char *, const unsigned char *,
+ int));
+extern pid_t server_lock __P((char * /*program*/, char * /*file*/,
+ int /*debug*/));
+#define server_unlock(x) (unlink(x))
+
+#ifdef NO_DLFCN_H
+extern void *mod_open __P((const char *));
+extern void *mod_symbol __P((void *, const char *));
+extern void mod_close __P((void *));
+#define mod_error() ""
+#else
+#include <dlfcn.h>
+#ifndef RTLD_NOW
+#define RTLD_NOW 1
+#endif
+#define mod_open(a) dlopen(a, RTLD_NOW)
+#ifndef DLSYM_PREPEND_UNDERSCORE
+#define mod_symbol(a, b) dlsym(a, b)
+#else
+extern void *mod_symbol __P((void *, const char *));
+#endif
+#define mod_error() dlerror()
+#define mod_close(a) dlclose(a)
+#endif
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 1990,1991 Regents of The University of Michigan.
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appears in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation, and that the name of The University
+ * of Michigan not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. This software is supplied as is without expressed or
+ * implied warranties of any kind.
+ *
+ * Research Systems Unix Group
+ * The University of Michigan
+ * c/o Mike Clark
+ * 535 W. William Street
+ * Ann Arbor, Michigan
+ * +1-313-763-0525
+ * netatalk@itd.umich.edu
+ */
+
+
+#ifndef _ATALK_ZIP_H
+#define _ATALK_ZIP_H 1
+
+#include <netatalk/endian.h>
+
+struct ziphdr {
+ u_int8_t zh_op;
+ u_int8_t zh_cnt;
+#define zh_count zh_cnt
+#define zh_zero zh_cnt
+#define zh_flags zh_cnt
+};
+
+struct zipreplent {
+ u_int16_t zre_net;
+ u_int8_t zre_zonelen;
+};
+
+#define ZIPOP_QUERY 1
+#define ZIPOP_REPLY 2
+#define ZIPOP_TAKEDOWN 3 /* XXX */
+#define ZIPOP_BRINGUP 4 /* XXX */
+#define ZIPOP_GNI 5
+#define ZIPOP_GNIREPLY 6
+#define ZIPOP_NOTIFY 7
+#define ZIPOP_EREPLY 8
+#define ZIPOP_GETMYZONE 7
+#define ZIPOP_GETZONELIST 8
+#define ZIPOP_GETLOCALZONES 9
+
+#define ZIPGNI_INVALID 0x80
+#define ZIPGNI_ONEZONE 0x20
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 1990,1991 Regents of The University of Michigan.
+ * All Rights Reserved.
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/syslog.h>
+#include <sys/param.h>
+#include <sys/mbuf.h>
+#include <sys/time.h>
+#ifndef _IBMR2
+#include <sys/kernel.h>
+#endif _IBMR2
+#include <net/if.h>
+#include <net/route.h>
+#include <net/af.h>
+#include <netinet/in.h>
+#undef s_net
+#include <netinet/if_ether.h>
+#ifdef _IBMR2
+#include <netinet/in_netarp.h>
+#include <net/spl.h>
+#include <sys/errno.h>
+#include <sys/err_rec.h>
+#endif _IBMR2
+
+#include "at.h"
+#include "at_var.h"
+#include "aarp.h"
+#include "ddp_var.h"
+#include "endian.h"
+#include "phase2.h"
+
+#ifdef GATEWAY
+#define AARPTAB_BSIZ 16
+#define AARPTAB_NB 37
+#else
+#define AARPTAB_BSIZ 9
+#define AARPTAB_NB 19
+#endif GATEWAY
+#define AARPTAB_SIZE (AARPTAB_BSIZ * AARPTAB_NB)
+struct aarptab aarptab[AARPTAB_SIZE];
+int aarptab_size = AARPTAB_SIZE;
+
+#define AARPTAB_HASH(a) \
+ ((((a).s_net << 8 ) + (a).s_node ) % AARPTAB_NB )
+
+#define AARPTAB_LOOK(aat,addr) { \
+ int n; \
+ aat = &aarptab[ AARPTAB_HASH(addr) * AARPTAB_BSIZ ]; \
+ for ( n = 0; n < AARPTAB_BSIZ; n++, aat++ ) \
+ if ( aat->aat_ataddr.s_net == (addr).s_net && \
+ aat->aat_ataddr.s_node == (addr).s_node ) \
+ break; \
+ if ( n >= AARPTAB_BSIZ ) \
+ aat = 0; \
+}
+
+#define AARPT_AGE (60 * 1)
+#define AARPT_KILLC 20
+#define AARPT_KILLI 3
+
+#ifdef sun
+extern struct ether_addr etherbroadcastaddr;
+#else sun
+extern u_char etherbroadcastaddr[6];
+#endif sun
+
+u_char atmulticastaddr[ 6 ] = {
+ 0x09, 0x00, 0x07, 0xff, 0xff, 0xff,
+};
+
+u_char at_org_code[ 3 ] = {
+ 0x08, 0x00, 0x07,
+};
+u_char aarp_org_code[ 3 ] = {
+ 0x00, 0x00, 0x00,
+};
+
+aarptimer()
+{
+ struct aarptab *aat;
+ int i, s;
+
+ timeout( aarptimer, (caddr_t)0, AARPT_AGE * hz );
+ aat = aarptab;
+ for ( i = 0; i < AARPTAB_SIZE; i++, aat++ ) {
+ if ( aat->aat_flags == 0 || ( aat->aat_flags & ATF_PERM ))
+ continue;
+ if ( ++aat->aat_timer < (( aat->aat_flags & ATF_COM ) ?
+ AARPT_KILLC : AARPT_KILLI ))
+ continue;
+ s = splimp();
+ aarptfree( aat );
+ splx( s );
+ }
+}
+
+struct ifaddr *
+at_ifawithnet( sat, ifa )
+ struct sockaddr_at *sat;
+ struct ifaddr *ifa;
+{
+ struct at_ifaddr *aa;
+
+ for (; ifa; ifa = ifa->ifa_next ) {
+#ifdef BSD4_4
+ if ( ifa->ifa_addr->sa_family != AF_APPLETALK ) {
+ continue;
+ }
+ if ( satosat( ifa->ifa_addr )->sat_addr.s_net ==
+ sat->sat_addr.s_net ) {
+ break;
+ }
+#else BSD4_4
+ if ( ifa->ifa_addr.sa_family != AF_APPLETALK ) {
+ continue;
+ }
+ aa = (struct at_ifaddr *)ifa;
+ if ( ntohs( sat->sat_addr.s_net ) >= ntohs( aa->aa_firstnet ) &&
+ ntohs( sat->sat_addr.s_net ) <= ntohs( aa->aa_lastnet )) {
+ break;
+ }
+#endif BSD4_4
+ }
+ return( ifa );
+}
+
+aarpwhohas( ac, sat )
+ struct arpcom *ac;
+ struct sockaddr_at *sat;
+{
+ struct mbuf *m;
+ struct ether_header *eh;
+ struct ether_aarp *ea;
+ struct at_ifaddr *aa;
+ struct llc *llc;
+ struct sockaddr sa;
+
+#ifdef BSD4_4
+ if (( m = m_gethdr( M_DONTWAIT, MT_DATA )) == NULL ) {
+ return;
+ }
+ m->m_len = sizeof( *ea );
+ m->m_pkthdr.len = sizeof( *ea );
+ MH_ALIGN( m, sizeof( *ea ));
+#else BSD4_4
+ if (( m = m_get( M_DONTWAIT, MT_DATA )) == NULL ) {
+ return;
+ }
+ m->m_len = sizeof( *ea );
+ m->m_off = MMAXOFF - sizeof( *ea );
+#endif BSD4_4
+
+ ea = mtod( m, struct ether_aarp *);
+ bzero((caddr_t)ea, sizeof( *ea ));
+
+ ea->aarp_hrd = htons( AARPHRD_ETHER );
+ ea->aarp_pro = htons( ETHERTYPE_AT );
+ ea->aarp_hln = sizeof( ea->aarp_sha );
+ ea->aarp_pln = sizeof( ea->aarp_spu );
+ ea->aarp_op = htons( AARPOP_REQUEST );
+#ifdef sun
+ bcopy((caddr_t)&ac->ac_enaddr, (caddr_t)ea->aarp_sha,
+ sizeof( ea->aarp_sha ));
+#else sun
+ bcopy((caddr_t)ac->ac_enaddr, (caddr_t)ea->aarp_sha,
+ sizeof( ea->aarp_sha ));
+#endif sun
+
+ /*
+ * We need to check whether the output ethernet type should
+ * be phase 1 or 2. We have the interface that we'll be sending
+ * the aarp out. We need to find an AppleTalk network on that
+ * interface with the same address as we're looking for. If the
+ * net is phase 2, generate an 802.2 and SNAP header.
+ */
+ if (( aa = (struct at_ifaddr *)at_ifawithnet( sat, ac->ac_if.if_addrlist ))
+ == NULL ) {
+ m_freem( m );
+ return;
+ }
+
+ eh = (struct ether_header *)sa.sa_data;
+
+ if ( aa->aa_flags & AFA_PHASE2 ) {
+#ifdef sun
+ bcopy((caddr_t)atmulticastaddr, (caddr_t)&eh->ether_dhost,
+ sizeof( eh->ether_dhost ));
+#else sun
+ bcopy((caddr_t)atmulticastaddr, (caddr_t)eh->ether_dhost,
+ sizeof( eh->ether_dhost ));
+#endif sun
+#if defined( sun ) && defined( i386 )
+ eh->ether_type = htons( sizeof( struct llc ) +
+ sizeof( struct ether_aarp ));
+#else sun i386
+ eh->ether_type = sizeof( struct llc ) + sizeof( struct ether_aarp );
+#endif sun i386
+#ifdef BSD4_4
+ M_PREPEND( m, sizeof( struct llc ), M_WAIT );
+#else BSD4_4
+ m->m_len += sizeof( struct llc );
+ m->m_off -= sizeof( struct llc );
+#endif BSD4_4
+ llc = mtod( m, struct llc *);
+ llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP;
+ llc->llc_control = LLC_UI;
+ bcopy( aarp_org_code, llc->llc_org_code, sizeof( aarp_org_code ));
+ llc->llc_ether_type = htons( ETHERTYPE_AARP );
+
+
+ bcopy( &AA_SAT( aa )->sat_addr.s_net, ea->aarp_spnet,
+ sizeof( ea->aarp_spnet ));
+ ea->aarp_spnode = AA_SAT( aa )->sat_addr.s_node;
+ bcopy( &sat->sat_addr.s_net, ea->aarp_tpnet,
+ sizeof( ea->aarp_tpnet ));
+ ea->aarp_tpnode = sat->sat_addr.s_node;
+ } else {
+#ifdef sun
+ bcopy((caddr_t)ðerbroadcastaddr, (caddr_t)&eh->ether_dhost,
+ sizeof( eh->ether_dhost ));
+#else sun
+ bcopy((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost,
+ sizeof( eh->ether_dhost ));
+#endif sun
+#if defined( sun ) && defined( i386 )
+ eh->ether_type = htons( ETHERTYPE_AARP );
+#else sun i386
+ eh->ether_type = ETHERTYPE_AARP;
+#endif sun i386
+
+ ea->aarp_spa = AA_SAT( aa )->sat_addr.s_node;
+ ea->aarp_tpa = sat->sat_addr.s_node;
+ }
+
+#ifdef BSD4_4
+ sa.sa_len = sizeof( struct sockaddr );
+#endif BSD4_4
+ sa.sa_family = AF_UNSPEC;
+ (*ac->ac_if.if_output)(&ac->ac_if, m, &sa );
+}
+
+aarpresolve( ac, m, destsat, desten )
+ struct arpcom *ac;
+ struct mbuf *m;
+ struct sockaddr_at *destsat;
+#ifdef sun
+ struct ether_addr *desten;
+#else sun
+ u_char *desten;
+#endif sun
+{
+ struct at_ifaddr *aa;
+ struct ifaddr ifa;
+ struct aarptab *aat;
+ int s;
+
+ if ( at_broadcast( destsat )) {
+ if (( aa = (struct at_ifaddr *)at_ifawithnet( destsat,
+ ((struct ifnet *)ac)->if_addrlist )) == NULL ) {
+ m_freem( m );
+ return( 0 );
+ }
+ if ( aa->aa_flags & AFA_PHASE2 ) {
+ bcopy( (caddr_t)atmulticastaddr, (caddr_t)desten,
+ sizeof( atmulticastaddr ));
+ } else {
+#ifdef sun
+ bcopy( (caddr_t)ðerbroadcastaddr, (caddr_t)desten,
+ sizeof( etherbroadcastaddr ));
+#else sun
+ bcopy( (caddr_t)etherbroadcastaddr, (caddr_t)desten,
+ sizeof( etherbroadcastaddr ));
+#endif sun
+ }
+ return( 1 );
+ }
+
+ s = splimp();
+ AARPTAB_LOOK( aat, destsat->sat_addr );
+ if ( aat == 0 ) { /* No entry */
+ aat = aarptnew( &destsat->sat_addr );
+ if ( aat == 0 ) {
+ panic( "aarpresolve: no free entry" );
+ }
+ aat->aat_hold = m;
+ aarpwhohas( ac, destsat );
+ splx( s );
+ return( 0 );
+ }
+ /* found an entry */
+ aat->aat_timer = 0;
+ if ( aat->aat_flags & ATF_COM ) { /* entry is COMplete */
+ bcopy( (caddr_t)aat->aat_enaddr, (caddr_t)desten,
+ sizeof( aat->aat_enaddr ));
+ splx( s );
+ return( 1 );
+ }
+ /* entry has not completed */
+ if ( aat->aat_hold ) {
+ m_freem( aat->aat_hold );
+ }
+ aat->aat_hold = m;
+ aarpwhohas( ac, destsat );
+ splx( s );
+ return( 0 );
+}
+
+aarpinput( ac, m )
+ struct arpcom *ac;
+ struct mbuf *m;
+{
+ struct arphdr *ar;
+
+ if ( ac->ac_if.if_flags & IFF_NOARP )
+ goto out;
+
+#ifndef BSD4_4
+ IF_ADJ( m );
+#endif BSD4_4
+
+ if ( m->m_len < sizeof( struct arphdr )) {
+ goto out;
+ }
+
+ ar = mtod( m, struct arphdr *);
+ if ( ntohs( ar->ar_hrd ) != AARPHRD_ETHER ) {
+ goto out;
+ }
+
+ if ( m->m_len < sizeof( struct arphdr ) + 2 * ar->ar_hln +
+ 2 * ar->ar_pln ) {
+ goto out;
+ }
+
+ switch( ntohs( ar->ar_pro )) {
+ case ETHERTYPE_AT :
+ at_aarpinput( ac, m );
+ return;
+
+ default:
+ break;
+ }
+
+out:
+ m_freem( m );
+}
+
+
+at_aarpinput( ac, m )
+ struct arpcom *ac;
+ struct mbuf *m;
+{
+ struct mbuf *m0;
+ struct ether_aarp *ea;
+ struct at_ifaddr *aa;
+ struct aarptab *aat;
+ struct ether_header *eh;
+ struct llc *llc;
+ struct sockaddr_at sat;
+ struct sockaddr sa;
+ struct at_addr spa, tpa, ma;
+ int op, s;
+ u_short net;
+
+ ea = mtod( m, struct ether_aarp *);
+
+ /* Check to see if from my hardware address */
+#ifdef sun
+ if ( !bcmp(( caddr_t )ea->aarp_sha, ( caddr_t )&ac->ac_enaddr,
+ sizeof( ac->ac_enaddr ))) {
+ m_freem( m );
+ return;
+ }
+#else sun
+ if ( !bcmp(( caddr_t )ea->aarp_sha, ( caddr_t )ac->ac_enaddr,
+ sizeof( ac->ac_enaddr ))) {
+ m_freem( m );
+ return;
+ }
+#endif sun
+
+ /*
+ * Check if from broadcast address. This could be a more robust
+ * check, since we could look for multicasts.
+ */
+#ifdef sun
+ if ( !bcmp(( caddr_t )ea->aarp_sha, ( caddr_t )ðerbroadcastaddr,
+ sizeof( etherbroadcastaddr ))) {
+ log( LOG_ERR, "aarp: source is broadcast!\n" );
+ m_freem( m );
+ return;
+ }
+#else sun
+ if ( !bcmp(( caddr_t )ea->aarp_sha, ( caddr_t )etherbroadcastaddr,
+ sizeof( etherbroadcastaddr ))) {
+#ifndef _IBMR2
+#ifdef ultrix
+ mprintf( LOG_ERR,
+#else ultrix
+ log( LOG_ERR,
+#endif ultrix
+ "aarp: source is broadcast!\n" );
+#endif _IBMR2
+ m_freem( m );
+ return;
+ }
+#endif sun
+
+ op = ntohs( ea->aarp_op );
+ bcopy( ea->aarp_tpnet, &net, sizeof( net ));
+
+ if ( net != 0 ) {
+ sat.sat_family = AF_APPLETALK;
+ sat.sat_addr.s_net = net;
+ if (( aa = (struct at_ifaddr *)at_ifawithnet( &sat,
+ ac->ac_if.if_addrlist )) == NULL ) {
+ m_freem( m );
+ return;
+ }
+ bcopy( ea->aarp_spnet, &spa.s_net, sizeof( spa.s_net ));
+ bcopy( ea->aarp_tpnet, &tpa.s_net, sizeof( tpa.s_net ));
+ } else {
+ /*
+ * Since we don't know the net, we just look for the first
+ * phase 1 address on the interface.
+ */
+ for ( aa = (struct at_ifaddr *)ac->ac_if.if_addrlist; aa;
+ aa = (struct at_ifaddr *)aa->aa_ifa.ifa_next ) {
+ if ( AA_SAT( aa )->sat_family == AF_APPLETALK &&
+ ( aa->aa_flags & AFA_PHASE2 ) == 0 ) {
+ break;
+ }
+ }
+ if ( aa == NULL ) {
+ m_freem( m );
+ return;
+ }
+ tpa.s_net = spa.s_net = AA_SAT( aa )->sat_addr.s_net;
+ }
+
+ spa.s_node = ea->aarp_spnode;
+ tpa.s_node = ea->aarp_tpnode;
+ ma.s_net = AA_SAT( aa )->sat_addr.s_net;
+ ma.s_node = AA_SAT( aa )->sat_addr.s_node;
+
+ /*
+ * This looks like it's from us.
+ */
+ if ( spa.s_net == ma.s_net && spa.s_node == ma.s_node ) {
+ if ( aa->aa_flags & AFA_PROBING ) {
+ /*
+ * We're probing, someone either responded to our probe, or
+ * probed for the same address we'd like to use. Change the
+ * address we're probing for.
+ */
+ untimeout( aarpprobe, ac );
+ wakeup( aa );
+ m_freem( m );
+ return;
+ } else if ( op != AARPOP_PROBE ) {
+ /*
+ * This is not a probe, and we're not probing. This means
+ * that someone's saying they have the same source address
+ * as the one we're using. Get upset...
+ */
+#ifndef _IBMR2
+#ifdef ultrix
+ mprintf( LOG_ERR,
+#else ultrix
+ log( LOG_ERR,
+#endif ultrix
+ "aarp: duplicate AT address!! %x:%x:%x:%x:%x:%x\n",
+ ea->aarp_sha[ 0 ], ea->aarp_sha[ 1 ], ea->aarp_sha[ 2 ],
+ ea->aarp_sha[ 3 ], ea->aarp_sha[ 4 ], ea->aarp_sha[ 5 ]);
+#endif _IBMR2
+ m_freem( m );
+ return;
+ }
+ }
+
+ AARPTAB_LOOK( aat, spa );
+ if ( aat ) {
+ if ( op == AARPOP_PROBE ) {
+ /*
+ * Someone's probing for spa, dealocate the one we've got,
+ * so that if the prober keeps the address, we'll be able
+ * to arp for him.
+ */
+ aarptfree( aat );
+ m_freem( m );
+ return;
+ }
+
+ bcopy(( caddr_t )ea->aarp_sha, ( caddr_t )aat->aat_enaddr,
+ sizeof( ea->aarp_sha ));
+ aat->aat_flags |= ATF_COM;
+ if ( aat->aat_hold ) {
+#ifdef _IBMR2
+ /*
+ * Like in ddp_output(), we can't rely on the if_output
+ * routine to resolve AF_APPLETALK addresses, on the rs6k.
+ * So, we fill the destination ethernet address here.
+ *
+ * This should really be replaced with something like
+ * rsif_output(). XXX Will have to be for phase 2.
+ */
+ /* XXX maybe fill in the rest of the frame header */
+ sat.sat_family = AF_UNSPEC;
+ bcopy( aat->aat_enaddr, (*(struct sockaddr *)&sat).sa_data,
+ sizeof( aat->aat_enaddr ));
+#else _IBMR2
+ sat.sat_family = AF_APPLETALK;
+ sat.sat_addr = spa;
+#endif _IBMR2
+ (*ac->ac_if.if_output)( &ac->ac_if, aat->aat_hold,
+ (struct sockaddr *)&sat );
+ aat->aat_hold = 0;
+ }
+ }
+
+ if ( aat == 0 && tpa.s_net == ma.s_net && tpa.s_node == ma.s_node
+ && op != AARPOP_PROBE ) {
+ if ( aat = aarptnew( &spa )) {
+ bcopy(( caddr_t )ea->aarp_sha, ( caddr_t )aat->aat_enaddr,
+ sizeof( ea->aarp_sha ));
+ aat->aat_flags |= ATF_COM;
+ }
+ }
+
+ /*
+ * Don't respond to responses, and never respond if we're
+ * still probing.
+ */
+ if ( tpa.s_net != ma.s_net || tpa.s_node != ma.s_node ||
+ op == AARPOP_RESPONSE || ( aa->aa_flags & AFA_PROBING )) {
+ m_freem( m );
+ return;
+ }
+
+ bcopy(( caddr_t )ea->aarp_sha, ( caddr_t )ea->aarp_tha,
+ sizeof( ea->aarp_sha ));
+#ifdef sun
+ bcopy(( caddr_t )&ac->ac_enaddr, ( caddr_t )ea->aarp_sha,
+ sizeof( ea->aarp_sha ));
+#else sun
+ bcopy(( caddr_t )ac->ac_enaddr, ( caddr_t )ea->aarp_sha,
+ sizeof( ea->aarp_sha ));
+#endif sun
+
+ eh = (struct ether_header *)sa.sa_data;
+#ifdef sun
+ bcopy(( caddr_t )ea->aarp_tha, ( caddr_t )&eh->ether_dhost,
+ sizeof( eh->ether_dhost ));
+#else sun
+ bcopy(( caddr_t )ea->aarp_tha, ( caddr_t )eh->ether_dhost,
+ sizeof( eh->ether_dhost ));
+#endif sun
+
+ if ( aa->aa_flags & AFA_PHASE2 ) {
+#if defined( sun ) && defined( i386 )
+ eh->ether_type = htons( sizeof( struct llc ) +
+ sizeof( struct ether_aarp ));
+#else sun i386
+ eh->ether_type = sizeof( struct llc ) + sizeof( struct ether_aarp );
+#endif sun i386
+#ifdef BSD4_4
+ M_PREPEND( m, sizeof( struct llc ), M_DONTWAIT );
+ if ( m == NULL ) {
+ m_freem( m );
+ return;
+ }
+#else BSD4_4
+ MGET( m0, M_DONTWAIT, MT_HEADER );
+ if ( m0 == NULL ) {
+ m_freem( m );
+ return;
+ }
+ m0->m_next = m;
+ m = m0;
+ m->m_off = MMAXOFF - sizeof( struct llc );
+ m->m_len = sizeof ( struct llc );
+#endif BSD4_4
+ llc = mtod( m, struct llc *);
+ llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP;
+ llc->llc_control = LLC_UI;
+ bcopy( aarp_org_code, llc->llc_org_code, sizeof( aarp_org_code ));
+ llc->llc_ether_type = htons( ETHERTYPE_AARP );
+
+ bcopy( ea->aarp_spnet, ea->aarp_tpnet, sizeof( ea->aarp_tpnet ));
+ bcopy( &ma.s_net, ea->aarp_spnet, sizeof( ea->aarp_spnet ));
+ } else {
+#if defined( sun ) && defined( i386 )
+ eh->ether_type = htons( ETHERTYPE_AARP );
+#else sun i386
+ eh->ether_type = ETHERTYPE_AARP;
+#endif sun i386
+ }
+
+ ea->aarp_tpnode = ea->aarp_spnode;
+ ea->aarp_spnode = ma.s_node;
+ ea->aarp_op = htons( AARPOP_RESPONSE );
+
+#ifdef BSD4_4
+ sa.sa_len = sizeof( struct sockaddr );
+#endif BSD4_4
+ sa.sa_family = AF_UNSPEC;
+ (*ac->ac_if.if_output)( &ac->ac_if, m, &sa );
+ return;
+}
+
+aarptfree( aat )
+ struct aarptab *aat;
+{
+
+ if ( aat->aat_hold )
+ m_freem( aat->aat_hold );
+ aat->aat_hold = 0;
+ aat->aat_timer = aat->aat_flags = 0;
+ aat->aat_ataddr.s_net = 0;
+ aat->aat_ataddr.s_node = 0;
+}
+
+ struct aarptab *
+aarptnew( addr )
+ struct at_addr *addr;
+{
+ int n;
+ int oldest = -1;
+ struct aarptab *aat, *aato = NULL;
+ static int first = 1;
+
+ if ( first ) {
+ first = 0;
+ timeout( aarptimer, (caddr_t)0, hz );
+ }
+ aat = &aarptab[ AARPTAB_HASH( *addr ) * AARPTAB_BSIZ ];
+ for ( n = 0; n < AARPTAB_BSIZ; n++, aat++ ) {
+ if ( aat->aat_flags == 0 )
+ goto out;
+ if ( aat->aat_flags & ATF_PERM )
+ continue;
+ if ((int) aat->aat_timer > oldest ) {
+ oldest = aat->aat_timer;
+ aato = aat;
+ }
+ }
+ if ( aato == NULL )
+ return( NULL );
+ aat = aato;
+ aarptfree( aat );
+out:
+ aat->aat_ataddr = *addr;
+ aat->aat_flags = ATF_INUSE;
+ return( aat );
+}
+
+aarpprobe( ac )
+ struct arpcom *ac;
+{
+ struct mbuf *m;
+ struct ether_header *eh;
+ struct ether_aarp *ea;
+ struct at_ifaddr *aa;
+ struct llc *llc;
+ struct sockaddr sa;
+
+ /*
+ * We need to check whether the output ethernet type should
+ * be phase 1 or 2. We have the interface that we'll be sending
+ * the aarp out. We need to find an AppleTalk network on that
+ * interface with the same address as we're looking for. If the
+ * net is phase 2, generate an 802.2 and SNAP header.
+ */
+ for ( aa = (struct at_ifaddr *)ac->ac_if.if_addrlist; aa;
+ aa = (struct at_ifaddr *)aa->aa_ifa.ifa_next ) {
+ if ( AA_SAT( aa )->sat_family == AF_APPLETALK &&
+ ( aa->aa_flags & AFA_PROBING )) {
+ break;
+ }
+ }
+ if ( aa == NULL ) { /* serious error XXX */
+ printf( "aarpprobe why did this happen?!\n" );
+ return;
+ }
+
+ if ( aa->aa_probcnt <= 0 ) {
+ aa->aa_flags &= ~AFA_PROBING;
+ wakeup( aa );
+ return;
+ } else {
+ timeout( aarpprobe, (caddr_t)ac, hz / 5 );
+ }
+
+#ifdef BSD4_4
+ if (( m = m_gethdr( M_DONTWAIT, MT_DATA )) == NULL ) {
+ return;
+ }
+ m->m_len = sizeof( *ea );
+ m->m_pkthdr.len = sizeof( *ea );
+ MH_ALIGN( m, sizeof( *ea ));
+#else BSD4_4
+ if (( m = m_get( M_DONTWAIT, MT_DATA )) == NULL ) {
+ return;
+ }
+ m->m_len = sizeof( *ea );
+ m->m_off = MMAXOFF - sizeof( *ea );
+#endif BSD4_4
+
+ ea = mtod( m, struct ether_aarp *);
+ bzero((caddr_t)ea, sizeof( *ea ));
+
+ ea->aarp_hrd = htons( AARPHRD_ETHER );
+ ea->aarp_pro = htons( ETHERTYPE_AT );
+ ea->aarp_hln = sizeof( ea->aarp_sha );
+ ea->aarp_pln = sizeof( ea->aarp_spu );
+ ea->aarp_op = htons( AARPOP_PROBE );
+#ifdef sun
+ bcopy((caddr_t)&ac->ac_enaddr, (caddr_t)ea->aarp_sha,
+ sizeof( ea->aarp_sha ));
+#else sun
+ bcopy((caddr_t)ac->ac_enaddr, (caddr_t)ea->aarp_sha,
+ sizeof( ea->aarp_sha ));
+#endif sun
+
+ eh = (struct ether_header *)sa.sa_data;
+
+ if ( aa->aa_flags & AFA_PHASE2 ) {
+#ifdef sun
+ bcopy((caddr_t)atmulticastaddr, (caddr_t)&eh->ether_dhost,
+ sizeof( eh->ether_dhost ));
+#else sun
+ bcopy((caddr_t)atmulticastaddr, (caddr_t)eh->ether_dhost,
+ sizeof( eh->ether_dhost ));
+#endif sun
+#if defined( sun ) && defined( i386 )
+ eh->ether_type = htons( sizeof( struct llc ) +
+ sizeof( struct ether_aarp ));
+#else sun i386
+ eh->ether_type = sizeof( struct llc ) + sizeof( struct ether_aarp );
+#endif sun i386
+#ifdef BSD4_4
+ M_PREPEND( m, sizeof( struct llc ), M_WAIT );
+#else BSD4_4
+ m->m_len += sizeof( struct llc );
+ m->m_off -= sizeof( struct llc );
+#endif BSD4_4
+ llc = mtod( m, struct llc *);
+ llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP;
+ llc->llc_control = LLC_UI;
+ bcopy( aarp_org_code, llc->llc_org_code, sizeof( aarp_org_code ));
+ llc->llc_ether_type = htons( ETHERTYPE_AARP );
+
+ bcopy( &AA_SAT( aa )->sat_addr.s_net, ea->aarp_spnet,
+ sizeof( ea->aarp_spnet ));
+ bcopy( &AA_SAT( aa )->sat_addr.s_net, ea->aarp_tpnet,
+ sizeof( ea->aarp_tpnet ));
+ ea->aarp_spnode = ea->aarp_tpnode = AA_SAT( aa )->sat_addr.s_node;
+ } else {
+#ifdef sun
+ bcopy((caddr_t)ðerbroadcastaddr, (caddr_t)&eh->ether_dhost,
+ sizeof( eh->ether_dhost ));
+#else sun
+ bcopy((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost,
+ sizeof( eh->ether_dhost ));
+#endif sun
+#if defined( sun ) && defined( i386 )
+ eh->ether_type = htons( ETHERTYPE_AARP );
+#else sun i386
+ eh->ether_type = ETHERTYPE_AARP;
+#endif sun i386
+ ea->aarp_spa = ea->aarp_tpa = AA_SAT( aa )->sat_addr.s_node;
+ }
+
+#ifdef BSD4_4
+ sa.sa_len = sizeof( struct sockaddr );
+#endif BSD4_4
+ sa.sa_family = AF_UNSPEC;
+ (*ac->ac_if.if_output)(&ac->ac_if, m, &sa );
+ aa->aa_probcnt--;
+}
+
+aarp_clean()
+{
+ struct aarptab *aat;
+ int i;
+
+ untimeout( aarptimer, 0 );
+ for ( i = 0, aat = aarptab; i < AARPTAB_SIZE; i++, aat++ ) {
+ if ( aat->aat_hold ) {
+ m_freem( aat->aat_hold );
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 1990,1991 Regents of The University of Michigan.
+ * All Rights Reserved.
+ */
+
+/*
+ * This structure is used for both phase 1 and 2. Under phase 1
+ * the net is not filled in. It is in phase 2. In both cases, the
+ * hardware address length is (for some unknown reason) 4. If
+ * anyone at Apple could program their way out of paper bag, it
+ * would be 1 and 3 respectively for phase 1 and 2.
+ */
+union aapa {
+ u_char ap_pa[4];
+ struct ap_node {
+ u_char an_zero;
+ u_char an_net[2];
+ u_char an_node;
+ } ap_node;
+};
+
+struct ether_aarp {
+ struct arphdr eaa_hdr;
+ u_char aarp_sha[6];
+ union aapa aarp_spu;
+ u_char aarp_tha[6];
+ union aapa aarp_tpu;
+};
+#define aarp_hrd eaa_hdr.ar_hrd
+#define aarp_pro eaa_hdr.ar_pro
+#define aarp_hln eaa_hdr.ar_hln
+#define aarp_pln eaa_hdr.ar_pln
+#define aarp_op eaa_hdr.ar_op
+#define aarp_spa aarp_spu.ap_node.an_node
+#define aarp_tpa aarp_tpu.ap_node.an_node
+#define aarp_spnet aarp_spu.ap_node.an_net
+#define aarp_tpnet aarp_tpu.ap_node.an_net
+#define aarp_spnode aarp_spu.ap_node.an_node
+#define aarp_tpnode aarp_tpu.ap_node.an_node
+
+struct aarptab {
+ struct at_addr aat_ataddr;
+ u_char aat_enaddr[ 6 ];
+ u_char aat_timer;
+ u_char aat_flags;
+ struct mbuf *aat_hold;
+};
+
+#define AARPHRD_ETHER 0x0001
+
+#define AARPOP_REQUEST 0x01
+#define AARPOP_RESPONSE 0x02
+#define AARPOP_PROBE 0x03
+
+#ifdef KERNEL
+struct aarptab *aarptnew();
+int aarpprobe();
+#endif
--- /dev/null
+/*
+ * Copyright (c) 1990,1991 Regents of The University of Michigan.
+ * All Rights Reserved.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#ifdef ibm032
+#include <sys/dir.h>
+#endif ibm032
+#include <sys/user.h>
+#include <sys/types.h>
+#include <sys/errno.h>
+#include <sys/ioctl.h>
+#include <sys/mbuf.h>
+#ifndef _IBMR2
+#include <sys/kernel.h>
+#endif _IBMR2
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <net/if.h>
+#include <net/af.h>
+#include <net/route.h>
+#include <netinet/in.h>
+#undef s_net
+#include <netinet/if_ether.h>
+#ifdef _IBMR2
+#include <net/spl.h>
+#endif _IBMR2
+
+#include "at.h"
+#include "at_var.h"
+#include "aarp.h"
+#include "phase2.h"
+
+#ifdef BSD4_4
+# define sateqaddr(a,b) ((a)->sat_len == (b)->sat_len && \
+ (a)->sat_family == (b)->sat_family && \
+ (a)->sat_addr.s_net == (b)->sat_addr.s_net && \
+ (a)->sat_addr.s_node == (b)->sat_addr.s_node )
+#else BSD4_4
+atalk_hash( sat, hp )
+ struct sockaddr_at *sat;
+ struct afhash *hp;
+{
+ hp->afh_nethash = sat->sat_addr.s_net;
+ hp->afh_hosthash = ( sat->sat_addr.s_net << 8 ) +
+ sat->sat_addr.s_node;
+}
+
+/*
+ * Note the magic to get ifa_ifwithnet() to work without adding an
+ * ifaddr entry for each net in our local range.
+ */
+atalk_netmatch( sat1, sat2 )
+ struct sockaddr_at *sat1, *sat2;
+{
+ struct at_ifaddr *aa;
+
+ for ( aa = at_ifaddr; aa; aa = aa->aa_next ) {
+ if ( AA_SAT( aa ) == sat1 ) {
+ break;
+ }
+ }
+ if ( aa ) {
+ return( ntohs( aa->aa_firstnet ) <= ntohs( sat2->sat_addr.s_net ) &&
+ ntohs( aa->aa_lastnet ) >= ntohs( sat2->sat_addr.s_net ));
+ }
+ return( sat1->sat_addr.s_net == sat2->sat_addr.s_net );
+}
+#endif BSD4_4
+
+at_control( cmd, data, ifp )
+ int cmd;
+ caddr_t data;
+ struct ifnet *ifp;
+{
+ struct ifreq *ifr = (struct ifreq *)data;
+ struct sockaddr_at *sat;
+ struct netrange *nr;
+#ifdef BSD4_4
+ struct at_aliasreq *ifra = (struct at_aliasreq *)data;
+ struct at_ifaddr *aa0;
+#endif BSD4_4
+ struct at_ifaddr *aa = 0;
+ struct mbuf *m;
+ struct ifaddr *ifa;
+
+ if ( ifp ) {
+ for ( aa = at_ifaddr; aa; aa = aa->aa_next ) {
+ if ( aa->aa_ifp == ifp ) break;
+ }
+ }
+
+ switch ( cmd ) {
+#ifdef BSD4_4
+ case SIOCAIFADDR:
+ case SIOCDIFADDR:
+ if ( ifra->ifra_addr.sat_family == AF_APPLETALK ) {
+ for ( ; aa; aa = aa->aa_next ) {
+ if ( aa->aa_ifp == ifp &&
+ sateqaddr( &aa->aa_addr, &ifra->ifra_addr )) {
+ break;
+ }
+ }
+ }
+ if ( cmd == SIOCDIFADDR && aa == 0 ) {
+ return( EADDRNOTAVAIL );
+ }
+ /*FALLTHROUGH*/
+#endif BSD4_4
+
+ case SIOCSIFADDR:
+#ifdef BSD4_4
+ /*
+ * What a great idea this is: Let's reverse the meaning of
+ * the return...
+ */
+ if ( suser( u.u_cred, &u.u_acflag )) {
+ return( EPERM );
+ }
+#else BSD4_4
+ if ( !suser()) {
+ return( EPERM );
+ }
+#endif BSD4_4
+
+ sat = satosat( &ifr->ifr_addr );
+ nr = (struct netrange *)sat->sat_zero;
+ if ( nr->nr_phase == 1 ) {
+ for ( ; aa; aa = aa->aa_next ) {
+ if ( aa->aa_ifp == ifp &&
+ ( aa->aa_flags & AFA_PHASE2 ) == 0 ) {
+ break;
+ }
+ }
+ } else { /* default to phase 2 */
+ for ( ; aa; aa = aa->aa_next ) {
+ if ( aa->aa_ifp == ifp && ( aa->aa_flags & AFA_PHASE2 )) {
+ break;
+ }
+ }
+ }
+
+ if ( ifp == 0 )
+ panic( "at_control" );
+
+ if ( aa == (struct at_ifaddr *) 0 ) {
+ m = m_getclr( M_WAIT, MT_IFADDR );
+ if ( m == (struct mbuf *)NULL ) {
+ return( ENOBUFS );
+ }
+
+ if (( aa = at_ifaddr ) != NULL ) {
+ /*
+ * Don't let the loopback be first, since the first
+ * address is the machine's default address for
+ * binding.
+ */
+ if ( at_ifaddr->aa_ifp->if_flags & IFF_LOOPBACK ) {
+ aa = mtod( m, struct at_ifaddr *);
+ aa->aa_next = at_ifaddr;
+ at_ifaddr = aa;
+ } else {
+ for ( ; aa->aa_next; aa = aa->aa_next )
+ ;
+ aa->aa_next = mtod( m, struct at_ifaddr *);
+ }
+ } else {
+ at_ifaddr = mtod( m, struct at_ifaddr *);
+ }
+
+ aa = mtod( m, struct at_ifaddr *);
+
+ if (( ifa = ifp->if_addrlist ) != NULL ) {
+ for ( ; ifa->ifa_next; ifa = ifa->ifa_next )
+ ;
+ ifa->ifa_next = (struct ifaddr *)aa;
+ } else {
+ ifp->if_addrlist = (struct ifaddr *)aa;
+ }
+
+#ifdef BSD4_4
+ aa->aa_ifa.ifa_addr = (struct sockaddr *)&aa->aa_addr;
+ aa->aa_ifa.ifa_dstaddr = (struct sockaddr *)&aa->aa_addr;
+ aa->aa_ifa.ifa_netmask = (struct sockaddr *)&aa->aa_netmask;
+#endif BSD4_4
+
+ /*
+ * Set/clear the phase 2 bit.
+ */
+ if ( nr->nr_phase == 1 ) {
+ aa->aa_flags &= ~AFA_PHASE2;
+ } else {
+ aa->aa_flags |= AFA_PHASE2;
+ }
+ aa->aa_ifp = ifp;
+ } else {
+ at_scrub( ifp, aa );
+ }
+ break;
+
+ case SIOCGIFADDR :
+ sat = satosat( &ifr->ifr_addr );
+ nr = (struct netrange *)sat->sat_zero;
+ if ( nr->nr_phase == 1 ) {
+ for ( ; aa; aa = aa->aa_next ) {
+ if ( aa->aa_ifp == ifp &&
+ ( aa->aa_flags & AFA_PHASE2 ) == 0 ) {
+ break;
+ }
+ }
+ } else { /* default to phase 2 */
+ for ( ; aa; aa = aa->aa_next ) {
+ if ( aa->aa_ifp == ifp && ( aa->aa_flags & AFA_PHASE2 )) {
+ break;
+ }
+ }
+ }
+
+ if ( aa == (struct at_ifaddr *) 0 )
+ return( EADDRNOTAVAIL );
+ break;
+ }
+
+ switch ( cmd ) {
+ case SIOCGIFADDR:
+#ifdef BSD4_4
+ *(struct sockaddr_at *)&ifr->ifr_addr = aa->aa_addr;
+#else BSD4_4
+ ifr->ifr_addr = aa->aa_addr;
+#endif BSD4_4
+ break;
+
+ case SIOCSIFADDR:
+ return( at_ifinit( ifp, aa, (struct sockaddr_at *)&ifr->ifr_addr ));
+
+#ifdef BSD4_4
+ case SIOCAIFADDR:
+ if ( sateqaddr( &ifra->ifra_addr, &aa->aa_addr )) {
+ return( 0 );
+ }
+ return( at_ifinit( ifp, aa, (struct sockaddr_at *)&ifr->ifr_addr ));
+
+ case SIOCDIFADDR:
+ at_scrub( ifp, aa );
+ if (( ifa = ifp->if_addrlist ) == (struct ifaddr *)aa ) {
+ ifp->if_addrlist = ifa->ifa_next;
+ } else {
+ while ( ifa->ifa_next && ( ifa->ifa_next != (struct ifaddr *)aa )) {
+ ifa = ifa->ifa_next;
+ }
+ if ( ifa->ifa_next ) {
+ ifa->ifa_next = ((struct ifaddr *)aa)->ifa_next;
+ } else {
+ panic( "at_control" );
+ }
+ }
+
+ aa0 = aa;
+ if ( aa0 == ( aa = at_ifaddr )) {
+ at_ifaddr = aa->aa_next;
+ } else {
+ while ( aa->aa_next && ( aa->aa_next != aa0 )) {
+ aa = aa->aa_next;
+ }
+ if ( aa->aa_next ) {
+ aa->aa_next = aa0->aa_next;
+ } else {
+ panic( "at_control" );
+ }
+ }
+ m_free( dtom( aa0 ));
+ break;
+#endif BSD4_4
+
+ default:
+ if ( ifp == 0 || ifp->if_ioctl == 0 )
+ return( EOPNOTSUPP );
+ return( (*ifp->if_ioctl)( ifp, cmd, data ));
+ }
+ return( 0 );
+}
+
+at_scrub( ifp, aa )
+ struct ifnet *ifp;
+ struct at_ifaddr *aa;
+{
+#ifndef BSD4_4
+ struct sockaddr_at netsat;
+ int error;
+ u_short net;
+#endif BSD4_4
+
+ if ( aa->aa_flags & AFA_ROUTE ) {
+#ifdef BSD4_4
+ if (( error = rtinit( &(aa->aa_ifa), RTM_DELETE,
+ ( ifp->if_flags & IFF_LOOPBACK ) ? RTF_HOST : 0 )) != 0 ) {
+ return( error );
+ }
+ aa->aa_ifa.ifa_flags &= ~IFA_ROUTE;
+#else BSD4_4
+ if ( ifp->if_flags & IFF_LOOPBACK ) {
+ rtinit( &aa->aa_addr, &aa->aa_addr, SIOCDELRT, RTF_HOST );
+ } else {
+ bzero( &netsat, sizeof( struct sockaddr_at ));
+ netsat.sat_family = AF_APPLETALK;
+ netsat.sat_addr.s_node = ATADDR_ANYNODE;
+
+ /*
+ * If the range is the full 0-fffe range, just use
+ * the default route.
+ */
+ if ( aa->aa_firstnet == htons( 0x0000 ) &&
+ aa->aa_lastnet == htons( 0xfffe )) {
+ netsat.sat_addr.s_net = 0;
+ rtinit((struct sockaddr *)&netsat, &aa->aa_addr,
+ (int)SIOCDELRT, 0 );
+ } else {
+ for ( net = ntohs( aa->aa_firstnet );
+ net <= ntohs( aa->aa_lastnet ); net++ ) {
+ netsat.sat_addr.s_net = htons( net );
+ rtinit((struct sockaddr *)&netsat, &aa->aa_addr,
+ (int)SIOCDELRT, 0 );
+ }
+ }
+ }
+#endif BSD4_4
+ aa->aa_flags &= ~AFA_ROUTE;
+ }
+ return( 0 );
+}
+
+extern struct timeval time;
+
+at_ifinit( ifp, aa, sat )
+ struct ifnet *ifp;
+ struct at_ifaddr *aa;
+ struct sockaddr_at *sat;
+{
+ struct netrange nr, onr;
+#ifdef BSD4_4
+ struct sockaddr_at oldaddr;
+#else BSD4_4
+ struct sockaddr oldaddr;
+#endif BSD4_4
+ struct sockaddr_at netaddr;
+ int s = splimp(), error = 0, i, j, netinc, nodeinc, nnets;
+ u_short net;
+
+ oldaddr = aa->aa_addr;
+ bzero( AA_SAT( aa ), sizeof( struct sockaddr_at ));
+ bcopy( sat->sat_zero, &nr, sizeof( struct netrange ));
+ nnets = ntohs( nr.nr_lastnet ) - ntohs( nr.nr_firstnet ) + 1;
+
+ onr.nr_firstnet = aa->aa_firstnet;
+ onr.nr_lastnet = aa->aa_lastnet;
+ aa->aa_firstnet = nr.nr_firstnet;
+ aa->aa_lastnet = nr.nr_lastnet;
+
+ /*
+ * We could eliminate the need for a second phase 1 probe (post
+ * autoconf) if we check whether we're resetting the node. Note
+ * that phase 1 probes use only nodes, not net.node pairs. Under
+ * phase 2, both the net and node must be the same.
+ */
+ if ( ifp->if_flags & IFF_LOOPBACK ) {
+#ifdef BSD4_4
+ AA_SAT( aa )->sat_len = sat->sat_len;
+#endif BSD4_4
+ AA_SAT( aa )->sat_family = AF_APPLETALK;
+ AA_SAT( aa )->sat_addr.s_net = sat->sat_addr.s_net;
+ AA_SAT( aa )->sat_addr.s_node = sat->sat_addr.s_node;
+ } else {
+ aa->aa_flags |= AFA_PROBING;
+ AA_SAT( aa )->sat_family = AF_APPLETALK;
+ if ( aa->aa_flags & AFA_PHASE2 ) {
+ if ( sat->sat_addr.s_net == ATADDR_ANYNET ) {
+ if ( nnets != 1 ) {
+ net = ntohs( nr.nr_firstnet ) + time.tv_sec % ( nnets - 1 );
+ } else {
+ net = ntohs( nr.nr_firstnet );
+ }
+ } else {
+ if ( ntohs( sat->sat_addr.s_net ) < ntohs( nr.nr_firstnet ) ||
+ ntohs( sat->sat_addr.s_net ) > ntohs( nr.nr_lastnet )) {
+ aa->aa_addr = oldaddr;
+ aa->aa_firstnet = onr.nr_firstnet;
+ aa->aa_lastnet = onr.nr_lastnet;
+ return( EINVAL );
+ }
+ net = ntohs( sat->sat_addr.s_net );
+ }
+ } else {
+ net = ntohs( sat->sat_addr.s_net );
+ }
+
+ if ( sat->sat_addr.s_node == ATADDR_ANYNODE ) {
+ AA_SAT( aa )->sat_addr.s_node = time.tv_sec;
+ } else {
+ AA_SAT( aa )->sat_addr.s_node = sat->sat_addr.s_node;
+ }
+
+ for ( i = nnets, netinc = 1; i > 0; net = ntohs( nr.nr_firstnet ) +
+ (( net - ntohs( nr.nr_firstnet ) + netinc ) % nnets ), i-- ) {
+ AA_SAT( aa )->sat_addr.s_net = htons( net );
+
+ for ( j = 0, nodeinc = time.tv_sec | 1; j < 256;
+ j++, AA_SAT( aa )->sat_addr.s_node += nodeinc ) {
+ if ( AA_SAT( aa )->sat_addr.s_node > 253 ||
+ AA_SAT( aa )->sat_addr.s_node < 1 ) {
+ continue;
+ }
+ aa->aa_probcnt = 10;
+ timeout( aarpprobe, (caddr_t)ifp, hz / 5 );
+ splx( s );
+ if ( sleep( aa, PSLEP|PCATCH )) {
+ printf( "at_ifinit why did this happen?!\n" );
+ aa->aa_addr = oldaddr;
+ aa->aa_firstnet = onr.nr_firstnet;
+ aa->aa_lastnet = onr.nr_lastnet;
+ return( EINTR );
+ }
+ s = splimp();
+ if (( aa->aa_flags & AFA_PROBING ) == 0 ) {
+ break;
+ }
+ }
+ if (( aa->aa_flags & AFA_PROBING ) == 0 ) {
+ break;
+ }
+ /* reset node for next network */
+ AA_SAT( aa )->sat_addr.s_node = time.tv_sec;
+ }
+
+ if ( aa->aa_flags & AFA_PROBING ) {
+ aa->aa_addr = oldaddr;
+ aa->aa_firstnet = onr.nr_firstnet;
+ aa->aa_lastnet = onr.nr_lastnet;
+ splx( s );
+ return( EADDRINUSE );
+ }
+ }
+
+ if ( ifp->if_ioctl &&
+ ( error = (*ifp->if_ioctl)( ifp, SIOCSIFADDR, aa ))) {
+ splx( s );
+ aa->aa_addr = oldaddr;
+ aa->aa_firstnet = onr.nr_firstnet;
+ aa->aa_lastnet = onr.nr_lastnet;
+ return( error );
+ }
+
+#ifdef BSD4_4
+ aa->aa_netmask.sat_len = 6;
+ aa->aa_netmask.sat_family = AF_APPLETALK;
+ aa->aa_netmask.sat_addr.s_net = 0xffff;
+ aa->aa_netmask.sat_addr.s_node = 0;
+#endif BSD4_4
+
+ if ( ifp->if_flags & IFF_LOOPBACK ) {
+#ifndef BSD4_4
+ rtinit( &aa->aa_addr, &aa->aa_addr, (int)SIOCADDRT,
+ RTF_HOST|RTF_UP );
+#else BSD4_4
+ error = rtinit( &(aa->aa_ifa), (int)RTM_ADD, RTF_HOST|RTF_UP );
+#endif BSD4_4
+ } else {
+#ifndef BSD4_4
+ /*
+ * rtrequest looks for point-to-point links first. The
+ * broadaddr is in the same spot as the destaddr. So, if
+ * ATADDR_ANYNET is 0, and we don't fill in the broadaddr, we
+ * get 0.0 routed out the ether interface. So, initialize the
+ * broadaddr, even tho we don't use it.
+ *
+ * We *could* use the broadaddr field to reduce some of the
+ * sockaddr_at overloading that we've done. E.g. Just send
+ * to INTERFACE-NET.255, and have the kernel reroute that
+ * to broadaddr, which would be 0.255 for phase 2 interfaces,
+ * and IFACE-NET.255 for phase 1 interfaces.
+ */
+ ((struct sockaddr_at *)&aa->aa_broadaddr)->sat_addr.s_net =
+ sat->sat_addr.s_net;
+ ((struct sockaddr_at *)&aa->aa_broadaddr)->sat_addr.s_node =
+ ATADDR_BCAST;
+
+ bzero( &netaddr, sizeof( struct sockaddr_at ));
+ netaddr.sat_family = AF_APPLETALK;
+ netaddr.sat_addr.s_node = ATADDR_ANYNODE;
+ if (( aa->aa_flags & AFA_PHASE2 ) == 0 ) {
+ netaddr.sat_addr.s_net = AA_SAT( aa )->sat_addr.s_net;
+ rtinit((struct sockaddr *)&netaddr, &aa->aa_addr,
+ (int)SIOCADDRT, RTF_UP );
+ } else {
+ /*
+ * If the range is the full 0-fffe range, just use
+ * the default route.
+ */
+ if ( aa->aa_firstnet == htons( 0x0000 ) &&
+ aa->aa_lastnet == htons( 0xfffe )) {
+ netaddr.sat_addr.s_net = 0;
+ rtinit((struct sockaddr *)&netaddr, &aa->aa_addr,
+ (int)SIOCADDRT, RTF_UP );
+ } else {
+ for ( net = ntohs( aa->aa_firstnet );
+ net <= ntohs( aa->aa_lastnet ); net++ ) {
+ netaddr.sat_addr.s_net = htons( net );
+ rtinit((struct sockaddr *)&netaddr, &aa->aa_addr,
+ (int)SIOCADDRT, RTF_UP );
+ }
+ }
+ }
+#else BSD4_4
+ error = rtinit( &(aa->aa_ifa), (int)RTM_ADD, RTF_UP );
+#endif BSD4_4
+ }
+ if ( error ) {
+ aa->aa_addr = oldaddr;
+ aa->aa_firstnet = onr.nr_firstnet;
+ aa->aa_lastnet = onr.nr_lastnet;
+ splx( s );
+ return( error );
+ }
+
+#ifdef BSD4_4
+ aa->aa_ifa.ifa_flags |= IFA_ROUTE;
+#endif BSD4_4
+ aa->aa_flags |= AFA_ROUTE;
+ splx( s );
+ return( 0 );
+}
+
+at_broadcast( sat )
+ struct sockaddr_at *sat;
+{
+ struct at_ifaddr *aa;
+
+ if ( sat->sat_addr.s_node != ATADDR_BCAST ) {
+ return( 0 );
+ }
+ if ( sat->sat_addr.s_net == 0 ) {
+ return( 1 );
+ } else {
+ for ( aa = at_ifaddr; aa; aa = aa->aa_next ) {
+ if (( aa->aa_ifp->if_flags & IFF_BROADCAST ) &&
+ ( ntohs( sat->sat_addr.s_net ) >= ntohs( aa->aa_firstnet ) &&
+ ntohs( sat->sat_addr.s_net ) <= ntohs( aa->aa_lastnet ))) {
+ return( 1 );
+ }
+ }
+ }
+ return( 0 );
+}
+
+aa_clean()
+{
+ struct at_ifaddr *aa;
+ struct ifaddr *ifa;
+ struct ifnet *ifp;
+
+ while ( aa = at_ifaddr ) {
+ ifp = aa->aa_ifp;
+ at_scrub( ifp, aa );
+ at_ifaddr = aa->aa_next;
+ if (( ifa = ifp->if_addrlist ) == (struct ifaddr *)aa ) {
+ ifp->if_addrlist = ifa->ifa_next;
+ } else {
+ while ( ifa->ifa_next &&
+ ( ifa->ifa_next != (struct ifaddr *)aa )) {
+ ifa = ifa->ifa_next;
+ }
+ if ( ifa->ifa_next ) {
+ ifa->ifa_next = ((struct ifaddr *)aa)->ifa_next;
+ } else {
+ panic( "at_entry" );
+ }
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 1990,1991 Regents of The University of Michigan.
+ *
+ * All Rights Reserved. See COPYRIGHT.
+ */
+
+#include <sys/protosw.h>
+#include <sys/domain.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include "at.h"
+
+extern int ddp_usrreq();
+extern int ddp_output();
+extern int ddp_init();
+
+#ifdef ultrix
+extern int ddp_ifoutput();
+extern int ddp_ifinput();
+extern int ddp_ifioctl();
+#endif ultrix
+
+struct protosw atalksw[] = {
+ {
+ /* Identifiers */
+ SOCK_DGRAM, &atalkdomain, ATPROTO_DDP, PR_ATOMIC|PR_ADDR,
+ /*
+ * protocol-protocol interface.
+ * fields are pr_input, pr_output, pr_ctlinput, and pr_ctloutput.
+ * pr_input can be called from the udp protocol stack for iptalk
+ * packets bound for a local socket.
+ * pr_output can be used by higher level appletalk protocols, should
+ * they be included in the kernel.
+ */
+ 0, ddp_output, 0, 0,
+ /* socket-protocol interface. */
+ ddp_usrreq,
+ /* utility routines. */
+ ddp_init, 0, 0, 0,
+#ifdef ultrix
+ /* interface hooks */
+ ddp_ifoutput, ddp_ifinput, ddp_ifioctl, 0,
+#endif ultrix
+ },
+};
+
+struct domain atalkdomain = {
+ AF_APPLETALK, "appletalk", 0, 0, 0, atalksw,
+ &atalksw[ sizeof( atalksw ) / sizeof( atalksw[ 0 ] ) ]
+};
--- /dev/null
+/*
+ * Copyright (c) 1990,1991 Regents of The University of Michigan.
+ *
+ * All Rights Reserved. See COPYRIGHT.
+ */
+
+/*
+ * For phase2, we need to keep not only our address on an interface,
+ * but also the legal networks on the interface.
+ */
+struct at_ifaddr {
+ struct ifaddr aa_ifa;
+# define aa_ifp aa_ifa.ifa_ifp
+#ifdef BSD4_4
+ struct sockaddr_at aa_addr;
+ struct sockaddr_at aa_broadaddr;
+ struct sockaddr_at aa_netmask;
+#else BSD4_4
+# define aa_addr aa_ifa.ifa_addr
+# define aa_broadaddr aa_ifa.ifa_broadaddr
+# define aa_dstaddr aa_ifa.ifa_dstaddr
+#endif BSD4_4
+ int aa_flags;
+ u_short aa_firstnet, aa_lastnet;
+ int aa_probcnt;
+ struct at_ifaddr *aa_next;
+};
+
+#ifdef BSD4_4
+struct at_aliasreq {
+ char ifra_name[IFNAMSIZ]; /* if name, e.g. "en0" */
+ struct sockaddr_at ifra_addr;
+ struct sockaddr_at ifra_broadaddr;
+#define ifra_dstaddr ifra_broadaddr
+ struct sockaddr_at ifra_mask;
+};
+#endif BSD4_4
+
+#define AA_SAT(aa) \
+ ((struct sockaddr_at *)&((struct at_ifaddr *)(aa))->aa_addr)
+#define satosat(sa) ((struct sockaddr_at *)(sa))
+
+#define AFA_ROUTE 0x0001
+#define AFA_PROBING 0x0002
+#define AFA_PHASE2 0x0004
+
+#ifdef KERNEL
+struct at_ifaddr *at_ifaddr;
+struct ifqueue atintrq1, atintrq2;
+int atdebug;
+#endif
--- /dev/null
+/*
+ * Copyright (c) 1990,1991 Regents of The University of Michigan.
+ * All Rights Reserved. See COPYRIGHT.
+ *
+ */
+
+/*
+ * <-1byte(8bits) ->
+ * +---------------+
+ * | 0 | hopc |len|
+ * +---------------+
+ * | len (cont) |
+ * +---------------+
+ * | |
+ * +- DDP csum -+
+ * | |
+ * +---------------+
+ * | |
+ * +- Dest NET -+
+ * | |
+ * +---------------+
+ * | |
+ * +- Src NET -+
+ * | |
+ * +---------------+
+ * | Dest NODE |
+ * +---------------+
+ * | Src NODE |
+ * +---------------+
+ * | Dest PORT |
+ * +---------------+
+ * | Src PORT |
+ * +---------------+
+ *
+ * On Apples, there is also a ddp_type field, after src_port. However,
+ * under this unix implementation, user level processes need to be able
+ * to set the ddp_type. In later revisions, the ddp_type may only be
+ * available in a raw_appletalk interface.
+ */
+
+#ifndef _NETATALK_DDP_H
+#define _NETATALK_DDP_H 1
+
+#include <netatalk/endian.h>
+
+struct elaphdr {
+ u_char el_dnode;
+ u_char el_snode;
+ u_char el_type;
+};
+
+#define SZ_ELAPHDR 3
+
+#define ELAP_DDPSHORT 0x01
+#define ELAP_DDPEXTEND 0x02
+
+/*
+ * Extended DDP header. Includes sickness for dealing with arbitrary
+ * bitfields on a little-endian arch.
+ */
+struct ddpehdr {
+ union {
+ struct {
+#if BYTE_ORDER == BIG_ENDIAN
+ unsigned dub_pad:2;
+ unsigned dub_hops:4;
+ unsigned dub_len:10;
+ unsigned dub_sum:16;
+#else
+#if BYTE_ORDER == LITTLE_ENDIAN
+ unsigned dub_sum:16;
+ unsigned dub_len:10;
+ unsigned dub_hops:4;
+ unsigned dub_pad:2;
+#else
+ OOPS!
+#endif
+#endif
+ } du_bits;
+ unsigned du_bytes;
+ } deh_u;
+#define deh_pad deh_u.du_bits.dub_pad
+#define deh_hops deh_u.du_bits.dub_hops
+#define deh_len deh_u.du_bits.dub_len
+#define deh_sum deh_u.du_bits.dub_sum
+#define deh_bytes deh_u.du_bytes
+ u_short deh_dnet;
+ u_short deh_snet;
+ u_char deh_dnode;
+ u_char deh_snode;
+ u_char deh_dport;
+ u_char deh_sport;
+};
+
+#define SZ_DDPEHDR 12
+
+#define DDP_MAXHOPS 15
+
+struct ddpshdr {
+ union {
+ struct {
+#if BYTE_ORDER == BIG_ENDIAN
+ unsigned dub_pad:6;
+ unsigned dub_len:10;
+ unsigned dub_dport:8;
+ unsigned dub_sport:8;
+#endif
+#if BYTE_ORDER == LITTLE_ENDIAN
+ unsigned dub_sport:8;
+ unsigned dub_dport:8;
+ unsigned dub_len:10;
+ unsigned dub_pad:6;
+#endif
+ } du_bits;
+ unsigned du_bytes;
+ } dsh_u;
+#define dsh_pad dsh_u.du_bits.dub_pad
+#define dsh_len dsh_u.du_bits.dub_len
+#define dsh_dport dsh_u.du_bits.dub_dport
+#define dsh_sport dsh_u.du_bits.dub_sport
+#define dsh_bytes dsh_u.du_bytes
+};
+#define SZ_DDPSHDR 4
+
+#endif /* netatalk/ddp.h */
--- /dev/null
+/*
+ * Copyright (c) 1990,1994 Regents of The University of Michigan.
+ * All Rights Reserved. See COPYRIGHT.
+ */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/syslog.h>
+#include <net/if.h>
+#include <net/route.h>
+#ifdef _IBMR2
+#include <net/spl.h>
+#endif _IBMR2
+
+#include "at.h"
+#include "at_var.h"
+#include "endian.h"
+#include "ddp.h"
+#include "ddp_var.h"
+
+int ddp_forward = 1;
+int ddp_firewall = 0;
+extern int ddp_cksum;
+extern u_short at_cksum();
+
+/*
+ * Could probably merge these two code segments a little better...
+ */
+atintr()
+{
+ struct elaphdr *elhp, elh;
+ struct ifnet *ifp;
+ struct mbuf *m;
+ struct at_ifaddr *aa;
+ int s;
+
+ for (;;) {
+#ifndef _IBMR2
+ s = splimp();
+#endif _IBMR2
+
+#ifdef BSD4_4
+ IF_DEQUEUE( &atintrq2, m );
+#else BSD4_4
+ IF_DEQUEUEIF( &atintrq2, m, ifp );
+#endif BSD4_4
+
+#ifndef _IBMR2
+ splx( s );
+#endif _IBMR2
+
+ if ( m == 0 ) { /* no more queued packets */
+ break;
+ }
+
+#ifdef BSD4_4
+ ifp = m->m_pkthdr.rcvif;
+#endif BSD4_4
+ for ( aa = at_ifaddr; aa; aa = aa->aa_next ) {
+ if ( aa->aa_ifp == ifp && ( aa->aa_flags & AFA_PHASE2 )) {
+ break;
+ }
+ }
+ if ( aa == NULL ) { /* ifp not an appletalk interface */
+ m_freem( m );
+ continue;
+ }
+
+ ddp_input( m, ifp, (struct elaphdr *)NULL, 2 );
+ }
+
+ for (;;) {
+#ifndef _IBMR2
+ s = splimp();
+#endif _IBMR2
+
+#ifdef BSD4_4
+ IF_DEQUEUE( &atintrq1, m );
+#else BSD4_4
+ IF_DEQUEUEIF( &atintrq1, m, ifp );
+#endif BSD4_4
+
+#ifndef _IBMR2
+ splx( s );
+#endif _IBMR2
+
+ if ( m == 0 ) { /* no more queued packets */
+ break;
+ }
+
+#ifdef BSD4_4
+ ifp = m->m_pkthdr.rcvif;
+#endif BSD4_4
+ for ( aa = at_ifaddr; aa; aa = aa->aa_next ) {
+ if ( aa->aa_ifp == ifp && ( aa->aa_flags & AFA_PHASE2 ) == 0 ) {
+ break;
+ }
+ }
+ if ( aa == NULL ) { /* ifp not an appletalk interface */
+ m_freem( m );
+ continue;
+ }
+
+ if ( m->m_len < SZ_ELAPHDR &&
+ (( m = m_pullup( m, SZ_ELAPHDR )) == 0 )) {
+ ddpstat.ddps_tooshort++;
+ continue;
+ }
+
+ elhp = mtod( m, struct elaphdr *);
+ m_adj( m, SZ_ELAPHDR );
+
+ if ( elhp->el_type == ELAP_DDPEXTEND ) {
+ ddp_input( m, ifp, (struct elaphdr *)NULL, 1 );
+ } else {
+ bcopy((caddr_t)elhp, (caddr_t)&elh, SZ_ELAPHDR );
+ ddp_input( m, ifp, &elh, 1 );
+ }
+ }
+ return;
+}
+
+struct route forwro;
+
+ddp_input( m, ifp, elh, phase )
+ struct mbuf *m;
+ struct ifnet *ifp;
+ struct elaphdr *elh;
+ int phase;
+{
+ struct sockaddr_at from, to;
+ struct ddpshdr *dsh, ddps;
+ struct at_ifaddr *aa;
+ struct ddpehdr *deh, ddpe;
+#ifndef BSD4_4
+ struct mbuf *mp;
+#endif BSD4_4
+ struct ddpcb *ddp;
+ int dlen, mlen;
+ u_short cksum;
+
+ bzero( (caddr_t)&from, sizeof( struct sockaddr_at ));
+ if ( elh ) {
+ ddpstat.ddps_short++;
+
+ if ( m->m_len < sizeof( struct ddpshdr ) &&
+ (( m = m_pullup( m, sizeof( struct ddpshdr ))) == 0 )) {
+ ddpstat.ddps_tooshort++;
+ return;
+ }
+
+ dsh = mtod( m, struct ddpshdr *);
+ bcopy( (caddr_t)dsh, (caddr_t)&ddps, sizeof( struct ddpshdr ));
+ ddps.dsh_bytes = ntohl( ddps.dsh_bytes );
+ dlen = ddps.dsh_len;
+
+ to.sat_addr.s_net = 0;
+ to.sat_addr.s_node = elh->el_dnode;
+ to.sat_port = ddps.dsh_dport;
+ from.sat_addr.s_net = 0;
+ from.sat_addr.s_node = elh->el_snode;
+ from.sat_port = ddps.dsh_sport;
+
+ for ( aa = at_ifaddr; aa; aa = aa->aa_next ) {
+ if ( aa->aa_ifp == ifp && ( aa->aa_flags & AFA_PHASE2 ) == 0 &&
+ ( AA_SAT( aa )->sat_addr.s_node == to.sat_addr.s_node ||
+ to.sat_addr.s_node == ATADDR_BCAST )) {
+ break;
+ }
+ }
+ if ( aa == NULL ) {
+ m_freem( m );
+ return;
+ }
+ } else {
+ ddpstat.ddps_long++;
+
+ if ( m->m_len < sizeof( struct ddpehdr ) &&
+ (( m = m_pullup( m, sizeof( struct ddpehdr ))) == 0 )) {
+ ddpstat.ddps_tooshort++;
+ return;
+ }
+
+ deh = mtod( m, struct ddpehdr *);
+ bcopy( (caddr_t)deh, (caddr_t)&ddpe, sizeof( struct ddpehdr ));
+ ddpe.deh_bytes = ntohl( ddpe.deh_bytes );
+ dlen = ddpe.deh_len;
+
+ if (( cksum = ddpe.deh_sum ) == 0 ) {
+ ddpstat.ddps_nosum++;
+ }
+
+ from.sat_addr.s_net = ddpe.deh_snet;
+ from.sat_addr.s_node = ddpe.deh_snode;
+ from.sat_port = ddpe.deh_sport;
+ to.sat_addr.s_net = ddpe.deh_dnet;
+ to.sat_addr.s_node = ddpe.deh_dnode;
+ to.sat_port = ddpe.deh_dport;
+
+ if ( to.sat_addr.s_net == 0 ) {
+ for ( aa = at_ifaddr; aa; aa = aa->aa_next ) {
+ if ( phase == 1 && ( aa->aa_flags & AFA_PHASE2 )) {
+ continue;
+ }
+ if ( phase == 2 && ( aa->aa_flags & AFA_PHASE2 ) == 0 ) {
+ continue;
+ }
+ if ( aa->aa_ifp == ifp &&
+ ( AA_SAT( aa )->sat_addr.s_node == to.sat_addr.s_node ||
+ to.sat_addr.s_node == ATADDR_BCAST ||
+ ( ifp->if_flags & IFF_LOOPBACK ))) {
+ break;
+ }
+ }
+ } else {
+ for ( aa = at_ifaddr; aa; aa = aa->aa_next ) {
+ if ( to.sat_addr.s_net == aa->aa_firstnet &&
+ to.sat_addr.s_node == 0 ) {
+ break;
+ }
+ if (( ntohs( to.sat_addr.s_net ) < ntohs( aa->aa_firstnet ) ||
+ ntohs( to.sat_addr.s_net ) > ntohs( aa->aa_lastnet )) &&
+ ( ntohs( to.sat_addr.s_net ) < 0xff00 ||
+ ntohs( to.sat_addr.s_net ) > 0xfffe)) {
+ continue;
+ }
+ if ( to.sat_addr.s_node != AA_SAT( aa )->sat_addr.s_node &&
+ to.sat_addr.s_node != ATADDR_BCAST ) {
+ continue;
+ }
+ break;
+ }
+ }
+ }
+
+ /*
+ * Adjust the length, removing any padding that may have been added
+ * at a link layer. We do this before we attempt to forward a packet,
+ * possibly on a different media.
+ */
+#ifdef BSD4_4
+ mlen = m->m_pkthdr.len;
+#else BSD4_4
+ for ( mlen = 0, mp = m; mp; mp = mp->m_next ) {
+ mlen += mp->m_len;
+ }
+#endif BSD4_4
+ if ( mlen < dlen ) {
+ ddpstat.ddps_toosmall++;
+ m_freem( m );
+ return;
+ }
+ if ( mlen > dlen ) {
+ m_adj( m, dlen - mlen );
+ }
+
+ /*
+ * XXX Should we deliver broadcasts locally, also, or rely on the
+ * link layer to give us a copy? For the moment, the latter.
+ */
+ if ( aa == NULL || ( to.sat_addr.s_node == ATADDR_BCAST &&
+ aa->aa_ifp != ifp && ( ifp->if_flags & IFF_LOOPBACK ) == 0 )) {
+ if ( ddp_forward == 0 ) {
+ m_freem( m );
+ return;
+ }
+ if ( forwro.ro_rt && ( satosat( &forwro.ro_dst )->sat_addr.s_net !=
+ to.sat_addr.s_net ||
+ satosat( &forwro.ro_dst )->sat_addr.s_node !=
+ to.sat_addr.s_node )) {
+#ifdef ultrix
+ rtfree( forwro.ro_rt );
+#else ultrix
+ RTFREE( forwro.ro_rt );
+#endif ultrix
+ forwro.ro_rt = (struct rtentry *)0;
+ }
+ if ( forwro.ro_rt == (struct rtentry *)0 ||
+ forwro.ro_rt->rt_ifp == (struct ifnet *)0 ) {
+#ifdef BSD4_4
+ forwro.ro_dst.sa_len = sizeof( struct sockaddr_at );
+#endif BSD4_4
+ forwro.ro_dst.sa_family = AF_APPLETALK;
+ satosat( &forwro.ro_dst )->sat_addr.s_net = to.sat_addr.s_net;
+ satosat( &forwro.ro_dst )->sat_addr.s_node = to.sat_addr.s_node;
+ rtalloc( &forwro );
+ }
+
+ if ( to.sat_addr.s_net != satosat( &forwro.ro_dst )->sat_addr.s_net &&
+ ddpe.deh_hops == DDP_MAXHOPS ) {
+ m_freem( m );
+ return;
+ }
+
+ if ( ddp_firewall &&
+ ( forwro.ro_rt == NULL || ( forwro.ro_rt->rt_ifp != ifp &&
+ forwro.ro_rt->rt_ifp != at_ifaddr->aa_ifp ))) {
+ m_freem( m );
+ return;
+ }
+
+ ddpe.deh_hops++;
+ ddpe.deh_bytes = htonl( ddpe.deh_bytes );
+ bcopy( (caddr_t)&ddpe, (caddr_t)deh, sizeof( u_short ));
+ if ( ddp_route( m, &forwro )) {
+ ddpstat.ddps_cantforward++;
+ } else {
+ ddpstat.ddps_forward++;
+ }
+ return;
+ }
+
+#ifdef BSD4_4
+ from.sat_len = sizeof( struct sockaddr_at );
+#endif BSD4_4
+ from.sat_family = AF_APPLETALK;
+
+ if ( elh ) {
+ m_adj( m, sizeof( struct ddpshdr ));
+ } else {
+ if ( ddp_cksum && cksum && cksum != at_cksum( m, sizeof( int ))) {
+ ddpstat.ddps_badsum++;
+ m_freem( m );
+ return;
+ }
+ m_adj( m, sizeof( struct ddpehdr ));
+ }
+
+ if (( ddp = ddp_search( &from, &to, aa )) == NULL ) {
+ m_freem( m );
+ return;
+ }
+
+ if ( sbappendaddr( &ddp->ddp_socket->so_rcv, (struct sockaddr *)&from,
+ m, (struct mbuf *)0 ) == 0 ) {
+ ddpstat.ddps_nosockspace++;
+ m_freem( m );
+ return;
+ }
+ sorwakeup( ddp->ddp_socket );
+}
+
+m_printm( m )
+ struct mbuf *m;
+{
+ for (; m; m = m->m_next ) {
+ bprint( mtod( m, char * ), m->m_len );
+ }
+}
+
+#define BPXLEN 48
+#define BPALEN 16
+#include <ctype.h>
+char hexdig[] = "0123456789ABCDEF";
+
+bprint( data, len )
+ char *data;
+ int len;
+{
+ char xout[ BPXLEN ], aout[ BPALEN ];
+ int i = 0;
+
+ bzero( xout, BPXLEN );
+ bzero( aout, BPALEN );
+
+ for ( ;; ) {
+ if ( len < 1 ) {
+ if ( i != 0 ) {
+ printf( "%s\t%s\n", xout, aout );
+ }
+ printf( "%s\n", "(end)" );
+ break;
+ }
+
+ xout[ (i*3) ] = hexdig[ ( *data & 0xf0 ) >> 4 ];
+ xout[ (i*3) + 1 ] = hexdig[ *data & 0x0f ];
+
+ if ( (u_char)*data < 0x7f && (u_char)*data > 0x20 ) {
+ aout[ i ] = *data;
+ } else {
+ aout[ i ] = '.';
+ }
+
+ xout[ (i*3) + 2 ] = ' ';
+
+ i++;
+ len--;
+ data++;
+
+ if ( i > BPALEN - 2 ) {
+ printf( "%s\t%s\n", xout, aout );
+ bzero( xout, BPXLEN );
+ bzero( aout, BPALEN );
+ i = 0;
+ continue;
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 1990,1991 Regents of The University of Michigan.
+ * All Rights Reserved. See COPYRIGHT.
+ */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <sys/errno.h>
+#include <sys/syslog.h>
+
+#include <net/if.h>
+#include <net/route.h>
+
+#include <netinet/in.h>
+#undef s_net
+#include <netinet/if_ether.h>
+
+#include "at.h"
+#include "at_var.h"
+#include "endian.h"
+#include "ddp.h"
+#include "ddp_var.h"
+
+u_short at_cksum();
+int ddp_cksum = 1;
+
+ddp_output( ddp, m )
+ struct ddpcb *ddp;
+ struct mbuf *m;
+{
+#ifndef BSD4_4
+ struct mbuf *m0;
+ int len;
+#endif BSD4_4
+ struct ifnet *ifp;
+ struct at_ifaddr *aa = NULL;
+ struct ddpehdr *deh;
+ u_short net;
+
+#ifdef BSD4_4
+ M_PREPEND( m, sizeof( struct ddpehdr ), M_WAIT );
+#else BSD4_4
+ for ( len = 0, m0 = m; m; m = m->m_next ) {
+ len += m->m_len;
+ }
+ MGET( m, M_WAIT, MT_HEADER );
+ if ( m == 0 ) {
+ m_freem( m0 );
+ return( ENOBUFS );
+ }
+ m->m_next = m0;
+#endif BSD4_4
+
+#ifndef BSD4_4
+# define align(a) (((a)+3)&0xfc)
+ m->m_off = MMINOFF + align( SZ_ELAPHDR );
+ m->m_len = sizeof( struct ddpehdr );
+#endif BSD4_4
+
+ deh = mtod( m, struct ddpehdr *);
+ deh->deh_pad = 0;
+ deh->deh_hops = 0;
+
+#ifdef BSD4_4
+ deh->deh_len = m->m_pkthdr.len;
+#else BSD4_4
+ deh->deh_len = len + sizeof( struct ddpehdr );
+#endif BSD4_4
+
+ deh->deh_dnet = ddp->ddp_fsat.sat_addr.s_net;
+ deh->deh_dnode = ddp->ddp_fsat.sat_addr.s_node;
+ deh->deh_dport = ddp->ddp_fsat.sat_port;
+ deh->deh_snet = ddp->ddp_lsat.sat_addr.s_net;
+ deh->deh_snode = ddp->ddp_lsat.sat_addr.s_node;
+ deh->deh_sport = ddp->ddp_lsat.sat_port;
+
+ /*
+ * The checksum calculation is done after all of the other bytes have
+ * been filled in.
+ */
+ if ( ddp_cksum ) {
+ deh->deh_sum = at_cksum( m, sizeof( int ));
+ } else {
+ deh->deh_sum = 0;
+ }
+ deh->deh_bytes = htonl( deh->deh_bytes );
+
+ return( ddp_route( m, &ddp->ddp_route ));
+}
+
+ u_short
+at_cksum( m, skip )
+ struct mbuf *m;
+ int skip;
+{
+ u_char *data, *end;
+ u_int32_t cksum = 0;
+
+ for (; m; m = m->m_next ) {
+ for ( data = mtod( m, u_char * ), end = data + m->m_len; data < end;
+ data++ ) {
+ if ( skip ) {
+ skip--;
+ continue;
+ }
+ cksum = ( cksum + *data ) << 1;
+ if ( cksum & 0x00010000 ) {
+ cksum++;
+ }
+ cksum &= 0x0000ffff;
+ }
+ }
+
+ if ( cksum == 0 ) {
+ cksum = 0x0000ffff;
+ }
+ return( (u_short)cksum );
+}
+
+ddp_route( m, ro )
+ struct mbuf *m;
+ struct route *ro;
+{
+ struct sockaddr_at gate;
+ struct elaphdr *elh;
+ struct mbuf *m0;
+ struct at_ifaddr *aa = NULL;
+ struct ifnet *ifp;
+ int mlen;
+ u_short net;
+
+ if ( ro->ro_rt && ( ifp = ro->ro_rt->rt_ifp )) {
+#ifdef BSD4_4
+ net = satosat( ro->ro_rt->rt_gateway )->sat_addr.s_net;
+#else BSD4_4
+ net = satosat( &ro->ro_rt->rt_gateway )->sat_addr.s_net;
+#endif BSD4_4
+ for ( aa = at_ifaddr; aa; aa = aa->aa_next ) {
+ if ( aa->aa_ifp == ifp &&
+ ntohs( net ) >= ntohs( aa->aa_firstnet ) &&
+ ntohs( net ) <= ntohs( aa->aa_lastnet )) {
+ break;
+ }
+ }
+ }
+ if ( aa == NULL ) {
+ m_freem( m );
+ return( EINVAL );
+ }
+
+ /*
+ * There are several places in the kernel where data is added to
+ * an mbuf without ensuring that the mbuf pointer is aligned.
+ * This is bad for transition routing, since phase 1 and phase 2
+ * packets end up poorly aligned due to the three byte elap header.
+ */
+ if ( aa->aa_flags & AFA_PHASE2 ) {
+ for ( mlen = 0, m0 = m; m0; m0 = m0->m_next ) {
+ mlen += m0->m_len;
+ }
+ if (( m = m_pullup( m, MIN( MLEN, mlen ))) == 0 ) {
+ return( ENOBUFS );
+ }
+ } else {
+# ifdef notdef
+#ifdef BSD4_4
+ M_PREPEND( m, SZ_ELAPHDR, M_DONTWAIT );
+ if ( m == NULL ) {
+ return( ENOBUFS );
+ }
+#else BSD4_4
+ m->m_off -= SZ_ELAPHDR;
+ m->m_len += SZ_ELAPHDR;
+#endif BSD4_4
+# endif notdef
+
+ MGET( m0, M_WAIT, MT_HEADER );
+ if ( m0 == 0 ) {
+ m_freem( m );
+ return( ENOBUFS );
+ }
+ m0->m_next = m;
+ m0->m_off = MMINOFF + align( sizeof( struct ether_header ));
+ m0->m_len = SZ_ELAPHDR;
+ m = m0;
+
+ elh = mtod( m, struct elaphdr *);
+ elh->el_snode = satosat( &aa->aa_addr )->sat_addr.s_node;
+ elh->el_type = ELAP_DDPEXTEND;
+ if ( ntohs( satosat( &ro->ro_dst )->sat_addr.s_net ) >=
+ ntohs( aa->aa_firstnet ) &&
+ ntohs( satosat( &ro->ro_dst )->sat_addr.s_net ) <=
+ ntohs( aa->aa_lastnet )) {
+ elh->el_dnode = satosat( &ro->ro_dst )->sat_addr.s_node;
+ } else {
+#ifdef BSD4_4
+ elh->el_dnode = satosat( ro->ro_rt->rt_gateway )->sat_addr.s_node;
+#else BSD4_4
+ elh->el_dnode = satosat( &ro->ro_rt->rt_gateway )->sat_addr.s_node;
+#endif BSD4_4
+ }
+ }
+
+ if ( ntohs( satosat( &ro->ro_dst )->sat_addr.s_net ) >=
+ ntohs( aa->aa_firstnet ) &&
+ ntohs( satosat( &ro->ro_dst )->sat_addr.s_net ) <=
+ ntohs( aa->aa_lastnet )) {
+ gate = *satosat( &ro->ro_dst );
+ } else {
+#ifdef BSD4_4
+ gate = *satosat( ro->ro_rt->rt_gateway );
+#else BSD4_4
+ gate = *satosat( &ro->ro_rt->rt_gateway );
+#endif BSD4_4
+ }
+ ro->ro_rt->rt_use++;
+
+#ifdef ultrix
+ /*
+ * SAIEW: We can't make changes to net/if_loop.c, so we don't route
+ * further than this: if it's going to go through the lookback,
+ * short-circuit to ddp_input(). Who needs queuing?
+ *
+ * Note: Passing NULL for the elaphdr is cool, since we'll only ever
+ * try to send long form ddp throught the loopback.
+ */
+ if ( ifp->if_flags & IFF_LOOPBACK ) {
+#ifdef notdef
+ m->m_off += SZ_ELAPHDR;
+ m->m_len -= SZ_ELAPHDR;
+#endif notdef
+ ddp_input( m, ifp, (struct elaphdr *)NULL, 2 );
+ return( 0 );
+ }
+#endif ultrix
+
+#ifdef _IBMR2
+ /*
+ * We can't make changes to the interface routines on RS6ks, and
+ * they don't provide hooks for if_output, so we just resolve
+ * our address here, and pass the packet as a raw ethernet packet.
+ * This doesn't work particularly well, if we aren't *on* ethernet,
+ * but it's ok for the moment.
+ */
+ if ( ! ( ifp->if_flags & IFF_LOOPBACK )) {
+ struct ether_header eh;
+
+ if ( !aarpresolve(( struct arpcom *)ifp, m,
+ &gate, eh.ether_dhost )) {
+ return( 0 );
+ }
+ eh.ether_type = htons( ETHERTYPE_AT );
+ gate.sat_family = AF_UNSPEC;
+ bcopy( &eh, (*(struct sockaddr *)&gate).sa_data,
+ sizeof( (*(struct sockaddr *)&gate).sa_data ));
+ }
+#endif _IBMR2
+ return((*ifp->if_output)( ifp, m, &gate ));
+}
--- /dev/null
+/*
+ * Copyright (c) 1990,1994 Regents of The University of Michigan.
+ * All Rights Reserved. See COPYRIGHT.
+ */
+
+#include <sys/errno.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#ifdef ibm032
+#include <sys/dir.h>
+#endif ibm032
+#include <sys/user.h>
+#include <sys/mbuf.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/protosw.h>
+#include <net/if.h>
+#include <net/route.h>
+#ifdef _IBMR2
+#include <net/spl.h>
+#endif _IBMR2
+
+#include "at.h"
+#include "at_var.h"
+#include "ddp_var.h"
+#include "endian.h"
+
+struct ddpcb *ddpcb = NULL;
+u_int32_t ddp_sendspace = DDP_MAXSZ; /* Max ddp size + 1 (ddp_type) */
+u_int32_t ddp_recvspace = 10 * ( 587 + sizeof( struct sockaddr_at ));
+
+/*ARGSUSED*/
+ddp_usrreq( so, req, m, addr, rights )
+ struct socket *so;
+ int req;
+ struct mbuf *m, *addr, *rights;
+{
+ struct ddpcb *ddp;
+ int error = 0;
+
+ ddp = sotoddpcb( so );
+
+ if ( req == PRU_CONTROL ) {
+ return( at_control( (int) m, (caddr_t) addr,
+ (struct ifnet *) rights ));
+ }
+
+ if ( rights && rights->m_len ) {
+ error = EINVAL;
+ goto release;
+ }
+
+ if ( ddp == NULL && req != PRU_ATTACH ) {
+ error = EINVAL;
+ goto release;
+ }
+
+ switch ( req ) {
+ case PRU_ATTACH :
+ if ( ddp != NULL ) {
+ error = EINVAL;
+ break;
+ }
+ if (( error = at_pcballoc( so )) != 0 ) {
+ break;
+ }
+ error = soreserve( so, ddp_sendspace, ddp_recvspace );
+ break;
+
+ case PRU_DETACH :
+ at_pcbdetach( so, ddp );
+ break;
+
+ case PRU_BIND :
+ error = at_pcbsetaddr( ddp, addr );
+ break;
+
+ case PRU_SOCKADDR :
+ at_sockaddr( ddp, addr );
+ break;
+
+ case PRU_CONNECT:
+ if ( ddp->ddp_fsat.sat_port != ATADDR_ANYPORT ) {
+ error = EISCONN;
+ break;
+ }
+
+ error = at_pcbconnect( ddp, addr );
+ if ( error == 0 )
+ soisconnected( so );
+ break;
+
+ case PRU_DISCONNECT:
+ if ( ddp->ddp_fsat.sat_addr.s_node == ATADDR_ANYNODE ) {
+ error = ENOTCONN;
+ break;
+ }
+ at_pcbdisconnect( ddp );
+ soisdisconnected( so );
+ break;
+
+ case PRU_SHUTDOWN:
+ socantsendmore( so );
+ break;
+
+ case PRU_SEND: {
+ int s;
+
+ if ( addr ) {
+ if ( ddp->ddp_fsat.sat_port != ATADDR_ANYPORT ) {
+ error = EISCONN;
+ break;
+ }
+
+ s = splnet();
+ error = at_pcbconnect( ddp, addr );
+ if ( error ) {
+ splx( s );
+ break;
+ }
+ } else {
+ if ( ddp->ddp_fsat.sat_port == ATADDR_ANYPORT ) {
+ error = ENOTCONN;
+ break;
+ }
+ }
+
+ error = ddp_output( ddp, m );
+ m = NULL;
+ if ( addr ) {
+ at_pcbdisconnect( ddp );
+ splx( s );
+ }
+ }
+ break;
+
+ case PRU_ABORT:
+ soisdisconnected( so );
+ at_pcbdetach( so, ddp );
+ break;
+
+ case PRU_LISTEN:
+ case PRU_CONNECT2:
+ case PRU_ACCEPT:
+ case PRU_SENDOOB:
+ case PRU_FASTTIMO:
+ case PRU_SLOWTIMO:
+ case PRU_PROTORCV:
+ case PRU_PROTOSEND:
+ error = EOPNOTSUPP;
+ break;
+
+ case PRU_RCVD:
+ case PRU_RCVOOB:
+ /*
+ * Don't mfree. Good architecture...
+ */
+ return( EOPNOTSUPP );
+
+ case PRU_SENSE:
+ /*
+ * 1. Don't return block size.
+ * 2. Don't mfree.
+ */
+ return( 0 );
+
+ default:
+ error = EOPNOTSUPP;
+ }
+
+release:
+ if ( m != NULL ) {
+ m_freem( m );
+ }
+ return( error );
+}
+
+at_sockaddr( ddp, addr )
+ struct ddpcb *ddp;
+ struct mbuf *addr;
+{
+ struct sockaddr_at *sat;
+
+ addr->m_len = sizeof( struct sockaddr_at );
+ sat = mtod( addr, struct sockaddr_at *);
+ *sat = ddp->ddp_lsat;
+}
+
+at_pcbsetaddr( ddp, addr )
+ struct ddpcb *ddp;
+ struct mbuf *addr;
+{
+ struct sockaddr_at lsat, *sat;
+ struct at_ifaddr *aa;
+ struct ddpcb *ddpp;
+
+ if ( ddp->ddp_lsat.sat_port != ATADDR_ANYPORT ) { /* shouldn't be bound */
+ return( EINVAL );
+ }
+
+ if ( addr != 0 ) { /* validate passed address */
+ sat = mtod( addr, struct sockaddr_at *);
+ if ( addr->m_len != sizeof( *sat )) {
+ return( EINVAL );
+ }
+ if ( sat->sat_family != AF_APPLETALK ) {
+ return( EAFNOSUPPORT );
+ }
+
+ if ( sat->sat_addr.s_node != ATADDR_ANYNODE ||
+ sat->sat_addr.s_net != ATADDR_ANYNET ) {
+ for ( aa = at_ifaddr; aa; aa = aa->aa_next ) {
+ if (( sat->sat_addr.s_net == AA_SAT( aa )->sat_addr.s_net ) &&
+ ( sat->sat_addr.s_node == AA_SAT( aa )->sat_addr.s_node )) {
+ break;
+ }
+ }
+ if ( !aa ) {
+ return( EADDRNOTAVAIL );
+ }
+ }
+
+ if ( sat->sat_port != ATADDR_ANYPORT ) {
+ if ( sat->sat_port < ATPORT_FIRST ||
+ sat->sat_port >= ATPORT_LAST ) {
+ return( EINVAL );
+ }
+#ifdef BSD4_4
+ if ( sat->sat_port < ATPORT_RESERVED &&
+ suser( u.u_cred, &u.u_acflag )) {
+ return( EACCES );
+ }
+#else BSD4_4
+ if ( sat->sat_port < ATPORT_RESERVED && ( !suser())) {
+ return( EACCES );
+ }
+#endif BSD4_4
+ }
+ } else {
+ bzero( (caddr_t)&lsat, sizeof( struct sockaddr_at ));
+ lsat.sat_family = AF_APPLETALK;
+ sat = &lsat;
+ }
+
+ if ( sat->sat_addr.s_node == ATADDR_ANYNODE &&
+ sat->sat_addr.s_net == ATADDR_ANYNET ) {
+ if ( at_ifaddr == NULL ) {
+ return( EADDRNOTAVAIL );
+ }
+ sat->sat_addr = AA_SAT( at_ifaddr )->sat_addr;
+ }
+ ddp->ddp_lsat = *sat;
+
+ /*
+ * Choose port.
+ */
+ if ( sat->sat_port == ATADDR_ANYPORT ) {
+ for ( sat->sat_port = ATPORT_RESERVED;
+ sat->sat_port < ATPORT_LAST; sat->sat_port++ ) {
+ if ( ddp_ports[ sat->sat_port - 1 ] == 0 ) {
+ break;
+ }
+ }
+ if ( sat->sat_port == ATPORT_LAST ) {
+ return( EADDRNOTAVAIL );
+ }
+ ddp->ddp_lsat.sat_port = sat->sat_port;
+ ddp_ports[ sat->sat_port - 1 ] = ddp;
+ } else {
+ for ( ddpp = ddp_ports[ sat->sat_port - 1 ]; ddpp;
+ ddpp = ddpp->ddp_pnext ) {
+ if ( ddpp->ddp_lsat.sat_addr.s_net == sat->sat_addr.s_net &&
+ ddpp->ddp_lsat.sat_addr.s_node == sat->sat_addr.s_node ) {
+ break;
+ }
+ }
+ if ( ddpp != NULL ) {
+ return( EADDRINUSE );
+ }
+ ddp->ddp_pnext = ddp_ports[ sat->sat_port - 1 ];
+ ddp_ports[ sat->sat_port - 1 ] = ddp;
+ if ( ddp->ddp_pnext ) {
+ ddp->ddp_pnext->ddp_pprev = ddp;
+ }
+ }
+
+ return( 0 );
+}
+
+at_pcbconnect( ddp, addr )
+ struct ddpcb *ddp;
+ struct mbuf *addr;
+{
+ struct sockaddr_at *sat = mtod( addr, struct sockaddr_at *);
+ struct route *ro;
+ struct at_ifaddr *aa = 0;
+ struct ifnet *ifp;
+ u_short hintnet = 0, net;
+
+ if ( addr->m_len != sizeof( *sat ))
+ return( EINVAL );
+ if ( sat->sat_family != AF_APPLETALK ) {
+ return( EAFNOSUPPORT );
+ }
+
+ /*
+ * Under phase 2, network 0 means "the network". We take "the
+ * network" to mean the network the control block is bound to.
+ * If the control block is not bound, there is an error.
+ */
+ if ( sat->sat_addr.s_net == 0 && sat->sat_addr.s_node != ATADDR_ANYNODE ) {
+ if ( ddp->ddp_lsat.sat_port == ATADDR_ANYPORT ) {
+ return( EADDRNOTAVAIL );
+ }
+ hintnet = ddp->ddp_lsat.sat_addr.s_net;
+ }
+
+ ro = &ddp->ddp_route;
+ /*
+ * If we've got an old route for this pcb, check that it is valid.
+ * If we've changed our address, we may have an old "good looking"
+ * route here. Attempt to detect it.
+ */
+ if ( ro->ro_rt ) {
+ if ( hintnet ) {
+ net = hintnet;
+ } else {
+ net = sat->sat_addr.s_net;
+ }
+ aa = 0;
+ if ( ifp = ro->ro_rt->rt_ifp ) {
+ for ( aa = at_ifaddr; aa; aa = aa->aa_next ) {
+ if ( aa->aa_ifp == ifp &&
+ ntohs( net ) >= ntohs( aa->aa_firstnet ) &&
+ ntohs( net ) <= ntohs( aa->aa_lastnet )) {
+ break;
+ }
+ }
+ }
+ if ( aa == NULL || ( satosat( &ro->ro_dst )->sat_addr.s_net !=
+ ( hintnet ? hintnet : sat->sat_addr.s_net ) ||
+ satosat( &ro->ro_dst )->sat_addr.s_node !=
+ sat->sat_addr.s_node )) {
+#ifdef ultrix
+ rtfree( ro->ro_rt );
+#else ultrix
+ RTFREE( ro->ro_rt );
+#endif ultrix
+ ro->ro_rt = (struct rtentry *)0;
+ }
+ }
+
+ /*
+ * If we've got no route for this interface, try to find one.
+ */
+ if ( ro->ro_rt == (struct rtentry *)0 ||
+ ro->ro_rt->rt_ifp == (struct ifnet *)0 ) {
+#ifdef BSD4_4
+ ro->ro_dst.sa_len = sizeof( struct sockaddr_at );
+#endif BSD4_4
+ ro->ro_dst.sa_family = AF_APPLETALK;
+ if ( hintnet != 0 ) {
+ satosat( &ro->ro_dst )->sat_addr.s_net = hintnet;
+ } else {
+ satosat( &ro->ro_dst )->sat_addr.s_net = sat->sat_addr.s_net;
+ }
+ satosat( &ro->ro_dst )->sat_addr.s_node = sat->sat_addr.s_node;
+ rtalloc( ro );
+ }
+
+ /*
+ * Make sure any route that we have has a valid interface.
+ */
+ aa = 0;
+ if ( ro->ro_rt && ( ifp = ro->ro_rt->rt_ifp )) {
+ for ( aa = at_ifaddr; aa; aa = aa->aa_next ) {
+ if ( aa->aa_ifp == ifp ) {
+ break;
+ }
+ }
+ }
+ if ( aa == 0 ) {
+ return( ENETUNREACH );
+ }
+
+ ddp->ddp_fsat = *sat;
+ if ( ddp->ddp_lsat.sat_port == ATADDR_ANYPORT ) {
+ return( at_pcbsetaddr( ddp, (struct mbuf *)0 ));
+ }
+ return( 0 );
+}
+
+at_pcbdisconnect( ddp )
+ struct ddpcb *ddp;
+{
+ ddp->ddp_fsat.sat_addr.s_net = ATADDR_ANYNET;
+ ddp->ddp_fsat.sat_addr.s_node = ATADDR_ANYNODE;
+ ddp->ddp_fsat.sat_port = ATADDR_ANYPORT;
+}
+
+at_pcballoc( so )
+ struct socket *so;
+{
+ struct ddpcb *ddp;
+ struct mbuf *m;
+
+ m = m_getclr( M_WAIT, MT_PCB );
+ ddp = mtod( m, struct ddpcb * );
+ ddp->ddp_lsat.sat_port = ATADDR_ANYPORT;
+
+ ddp->ddp_next = ddpcb;
+ ddp->ddp_prev = NULL;
+ ddp->ddp_pprev = NULL;
+ ddp->ddp_pnext = NULL;
+ if ( ddpcb ) {
+ ddpcb->ddp_prev = ddp;
+ }
+ ddpcb = ddp;
+
+ ddp->ddp_socket = so;
+ so->so_pcb = (caddr_t)ddp;
+ return( 0 );
+}
+
+at_pcbdetach( so, ddp )
+ struct socket *so;
+ struct ddpcb *ddp;
+{
+ soisdisconnected( so );
+ so->so_pcb = 0;
+ sofree( so );
+
+ /* remove ddp from ddp_ports list */
+ if ( ddp->ddp_lsat.sat_port != ATADDR_ANYPORT &&
+ ddp_ports[ ddp->ddp_lsat.sat_port - 1 ] != NULL ) {
+ if ( ddp->ddp_pprev != NULL ) {
+ ddp->ddp_pprev->ddp_pnext = ddp->ddp_pnext;
+ } else {
+ ddp_ports[ ddp->ddp_lsat.sat_port - 1 ] = ddp->ddp_pnext;
+ }
+ if ( ddp->ddp_pnext != NULL ) {
+ ddp->ddp_pnext->ddp_pprev = ddp->ddp_pprev;
+ }
+ }
+
+ if ( ddp->ddp_route.ro_rt ) {
+ rtfree( ddp->ddp_route.ro_rt );
+ }
+
+ if ( ddp->ddp_prev ) {
+ ddp->ddp_prev->ddp_next = ddp->ddp_next;
+ } else {
+ ddpcb = ddp->ddp_next;
+ }
+ if ( ddp->ddp_next ) {
+ ddp->ddp_next->ddp_prev = ddp->ddp_prev;
+ }
+
+ (void) m_free( dtom( ddp ));
+}
+
+/*
+ * For the moment, this just find the pcb with the correct local address.
+ * In the future, this will actually do some real searching, so we can use
+ * the sender's address to do de-multiplexing on a single port to many
+ * sockets (pcbs).
+ */
+ struct ddpcb *
+ddp_search( from, to, aa )
+ struct sockaddr_at *from, *to;
+ struct at_ifaddr *aa;
+{
+ struct ddpcb *ddp;
+
+ /*
+ * Check for bad ports.
+ */
+ if ( to->sat_port < ATPORT_FIRST || to->sat_port >= ATPORT_LAST ) {
+ return( NULL );
+ }
+
+ /*
+ * Make sure the local address matches the sent address. What about
+ * the interface?
+ */
+ for ( ddp = ddp_ports[ to->sat_port - 1 ]; ddp; ddp = ddp->ddp_pnext ) {
+ /* XXX should we handle 0.YY? */
+
+ /* XXXX.YY to socket on destination interface */
+ if ( to->sat_addr.s_net == ddp->ddp_lsat.sat_addr.s_net &&
+ to->sat_addr.s_node == ddp->ddp_lsat.sat_addr.s_node ) {
+ break;
+ }
+
+ /* 0.255 to socket on receiving interface */
+ if ( to->sat_addr.s_node == ATADDR_BCAST && ( to->sat_addr.s_net == 0 ||
+ to->sat_addr.s_net == ddp->ddp_lsat.sat_addr.s_net ) &&
+ ddp->ddp_lsat.sat_addr.s_net == AA_SAT( aa )->sat_addr.s_net ) {
+ break;
+ }
+
+ /* XXXX.0 to socket on destination interface */
+ if ( to->sat_addr.s_net == aa->aa_firstnet &&
+ to->sat_addr.s_node == 0 &&
+ ntohs( ddp->ddp_lsat.sat_addr.s_net ) >=
+ ntohs( aa->aa_firstnet ) &&
+ ntohs( ddp->ddp_lsat.sat_addr.s_net ) <=
+ ntohs( aa->aa_lastnet )) {
+ break;
+ }
+ }
+ return( ddp );
+}
+
+ddp_init()
+{
+ atintrq1.ifq_maxlen = IFQ_MAXLEN;
+ atintrq2.ifq_maxlen = IFQ_MAXLEN;
+}
+
+ddp_clean()
+{
+ struct ddpcb *ddp;
+
+ for ( ddp = ddpcb; ddp; ddp = ddp->ddp_next ) {
+ at_pcbdetach( ddp->ddp_socket, ddp );
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 1990,1994 Regents of The University of Michigan.
+ * All Rights Reserved. See COPYRIGHT.
+ */
+
+#ifndef _NETATALK_DDP_VAR_H
+#define _NETATALK_DDP_VAR_H 1
+
+#include <netatalk/endian.h>
+
+struct ddpcb {
+ struct sockaddr_at ddp_fsat, ddp_lsat;
+ struct route ddp_route;
+ struct socket *ddp_socket;
+ struct ddpcb *ddp_prev, *ddp_next;
+ struct ddpcb *ddp_pprev, *ddp_pnext;
+};
+
+#define sotoddpcb(so) ((struct ddpcb *)(so)->so_pcb)
+
+struct ddpstat {
+ u_int32_t ddps_short; /* short header packets received */
+ u_int32_t ddps_long; /* long header packets received */
+ u_int32_t ddps_nosum; /* no checksum */
+ u_int32_t ddps_badsum; /* bad checksum */
+ u_int32_t ddps_tooshort; /* packet too short */
+ u_int32_t ddps_toosmall; /* not enough data */
+ u_int32_t ddps_forward; /* packets forwarded */
+ u_int32_t ddps_encap; /* packets encapsulated */
+ u_int32_t ddps_cantforward; /* packets rcvd for unreachable dest */
+ u_int32_t ddps_nosockspace; /* no space in sockbuf for packet */
+};
+
+#ifdef KERNEL
+struct ddpcb *ddp_ports[ ATPORT_LAST ];
+struct ddpcb *ddpcb;
+struct ddpstat ddpstat;
+struct ddpcb *ddp_search();
+#endif
+
+#endif /* netatalk/ddp_var.h */
--- /dev/null
+/*
+ * Copyright (c) 1990,1991 Regents of The University of Michigan.
+ * All Rights Reserved. See COPYRIGHT.
+ *
+ * This file handles both byte ordering and integer sizes.
+ */
+
+# ifndef _ATALK_ENDIAN_H_
+#define _ATALK_ENDIAN_H_
+
+#include <sys/types.h>
+#include <netinet/in.h>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef _IBMR2
+#include <sys/machine.h>
+#endif /*_IBMR2*/
+
+#ifdef _ISOC9X_SOURCE
+#include <inttypes.h>
+typedef uint8_t u_int8_t;
+typedef uint16_t u_int16_t;
+typedef uint32_t u_int32_t;
+typedef uint64_t u_int64_t;
+#else
+
+/* handle sunos and solaris */
+#ifdef sun
+#ifdef BSD4_3
+#include <sys/bitypes.h>
+#else
+/* solaris and sunos don't consistently define u_int*_t. */
+typedef unsigned char u_int8_t;
+typedef unsigned short u_int16_t;
+typedef unsigned int u_int32_t;
+typedef int int32_t;
+#endif
+
+typedef unsigned long long u_int64_t;
+
+#ifndef _SSIZE_T
+#define _SSIZE_T
+typedef int ssize_t;
+#endif /* ssize_t */
+
+#else /* sun */
+
+/* luckily ultrix is dead. as a result, we know what the sizes of
+ * various types are forever. this makes some assumptions about integer
+ * sizes. */
+#if defined (ultrix) || defined(HAVE_32BIT_LONGS) || defined(HAVE_64BIT_LONGS)
+typedef unsigned char u_int8_t;
+typedef unsigned short u_int16_t;
+typedef unsigned int u_int32_t;
+typedef int int32_t;
+#endif
+
+#ifdef ultrix
+typedef int ssize_t;
+#endif
+
+#ifdef HAVE_64BIT_LONGS
+typedef unsigned long u_int64_t;
+#else
+/* check for long long support. currently, i assume that if 64-bit
+ * ints exist that their made available via long long */
+#ifdef linux
+#include <endian.h> /* i think this is here for libc4 */
+#else
+#if defined(HAVE_32BIT_LONGS) && !(defined(BSD4_4) || \
+ defined(NO_LARGE_VOL_SUPPORT))
+typedef unsigned long long u_int64_t;
+#endif
+#endif /* linux */
+#endif /* HAVE_64BIT_LONGS */
+#endif /* sun */
+#endif /* ISOC9X */
+
+# ifndef BYTE_ORDER
+#define LITTLE_ENDIAN 1234
+#define BIG_ENDIAN 4321
+#define PDP_ENDIAN 3412
+
+#ifdef sun
+#if defined(i386) || defined(_LITTLE_ENDIAN)
+#define BYTE_ORDER LITTLE_ENDIAN
+#else /*i386*/
+#define BYTE_ORDER BIG_ENDIAN
+#endif /*i386*/
+#else
+#ifdef MIPSEB
+#define BYTE_ORDER BIG_ENDIAN
+#else
+#ifdef MIPSEL
+#define BYTE_ORDER LITTLE_ENDIAN
+#else
+#error Like, what is your byte order, man?
+#endif /*MIPSEL*/
+#endif /*MIPSEB*/
+#endif /*sun*/
+# endif /*BYTE_ORDER*/
+
+# ifndef ntohl
+# if defined( sun ) || defined( ultrix ) || defined( _IBMR2 )
+#if BYTE_ORDER == BIG_ENDIAN
+#define ntohl(x) (x)
+#define ntohs(x) (x)
+#define htonl(x) (x)
+#define htons(x) (x)
+
+#else
+#if defined( mips ) && defined( KERNEL )
+#define ntohl(x) nuxi_l(x)
+#define ntohs(x) nuxi_s(x)
+#define htonl(x) nuxi_l(x)
+#define htons(x) nuxi_s(x)
+
+#else /*mips KERNEL*/
+
+#if !( defined( sun ) && defined( i386 ))
+unsigned short ntohs(), htons();
+unsigned int ntohl(), htonl();
+#endif
+
+#endif /*mips KERNEL*/
+#endif /*BYTE_ORDER*/
+# endif /*sun ultrix _IBMR2*/
+# endif /*ntohl*/
+
+# endif /*_ATALK_ENDIAN_H_*/
--- /dev/null
+/*
+ * Copyright (c) 1990,1991 Regents of The University of Michigan.
+ * All Rights Reserved.
+ */
+
+# if defined( ultrix ) || defined( BSD4_4 )
+#include <net/if_llc.h>
+# else ultrix BSD4_4
+
+#if defined( sun ) && !defined( __svr4__ )
+#include <net/if_ieee802.h>
+#endif sun __svr4__
+
+/*
+ * Copyright (c) 1988 Regents of the University of California.
+ * All rights reserved.
+ *
+ * @(#)if_llc.h 7.2 (Berkeley) 6/28/90
+ */
+
+/*
+ * IEEE 802.2 Link Level Control headers, for use in conjunction with
+ * 802.{3,4,5} media access control methods.
+ *
+ * Headers here do not use bit fields due to shortcommings in many
+ * compilers.
+ */
+
+struct llc {
+ u_char llc_dsap;
+ u_char llc_ssap;
+ union {
+ struct {
+ u_char control;
+ u_char format_id;
+ u_char class;
+ u_char window_x2;
+ } type_u;
+ struct {
+ u_char num_snd_x2;
+ u_char num_rcv_x2;
+ } type_i;
+ struct {
+ u_char control;
+ u_char num_rcv_x2;
+ } type_s;
+ struct {
+ u_char control;
+ u_char org_code[3];
+ u_short ether_type;
+ } type_snap;
+ } llc_un;
+};
+#define llc_control llc_un.type_u.control
+#define llc_fid llc_un.type_u.format_id
+#define llc_class llc_un.type_u.class
+#define llc_window llc_un.type_u.window_x2
+#define llc_org_code llc_un.type_snap.org_code
+#define llc_ether_type llc_un.type_snap.ether_type
+
+#define LLC_UI 0x3
+#define LLC_UI_P 0x13
+#define LLC_XID 0xaf
+#define LLC_XID_P 0xbf
+#define LLC_TEST 0xe3
+#define LLC_TEST_P 0xf3
+
+#define LLC_ISO_LSAP 0xfe
+#define LLC_SNAP_LSAP 0xaa
+
+# endif ultrix BSD4_4
+
+#if defined( sun ) || defined( ibm032 )
+#define SIOCPHASE1 _IOW(i, 100, struct ifreq) /* AppleTalk phase 1 */
+#define SIOCPHASE2 _IOW(i, 101, struct ifreq) /* AppleTalk phase 2 */
+#endif sun ibm032
+
+#if defined( ultrix ) || defined( BSD4_4 ) || defined( _IBMR2 )
+#define SIOCPHASE1 _IOW('i', 100, struct ifreq) /* AppleTalk phase 1 */
+#define SIOCPHASE2 _IOW('i', 101, struct ifreq) /* AppleTalk phase 2 */
+#endif ultrix BSD4_4 _IBMR2
--- /dev/null
+# libatalk.la - a libtool library file
+# Generated by ltmain.sh - GNU libtool 1.3.5 (1.385.2.206 2000/05/27 11:12:27)
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# The name that we can dlopen(3).
+dlname=''
+
+# Names of this library.
+library_names=''
+
+# The name of the static archive.
+old_library='libatalk.a'
+
+# Libraries that this one depends upon.
+dependency_libs=' -L../libatalk/ -L/usr/lib -L/usr -L../../libatalk/ -lcrypto -lrpcsvc -lresolv -lnsl -ldl -ldb -lcrypt -lpam -lwrap -lcrypto -lrpcsvc -lresolv -lnsl -ldl -ldb -lcrypt -lpam -lwrap -lcrypto -lrpcsvc -lresolv -lnsl -ldl -ldb -lcrypt -lpam -lwrap -lcrypto -lrpcsvc -lresolv -lnsl -ldl -ldb -lcrypt -lpam -lwrap -lcrypto -lrpcsvc -lresolv -lnsl -ldl -ldb -lcrypt -lpam -lwrap -lcrypto -lrpcsvc -lresolv -lnsl -ldl -ldb -lcrypt -lpam -lwrap -lcrypto -lrpcsvc -lresolv -lnsl -ldl -ldb -lcrypt -lpam -lwrap -lcrypto -lrpcsvc -lresolv -lnsl -ldl -ldb -lcrypt -lpam -lwrap -lcrypto -lrpcsvc -lresolv -lnsl -ldl -ldb -lcrypt -lpam -lwrap -lcrypto -lrpcsvc -lresolv -lnsl -ldl -ldb -lcrypt -lpam -lwrap'
+
+# Version information for libatalk.
+current=0
+age=0
+revision=0
+
+# Is this an already installed library?
+installed=yes
+
+# Directory that this library needs to be installed in:
+libdir='/usr/lib'
--- /dev/null
+# Configure paths for netatalk
+# Based on libsigc++ script by Karl Nelson
+# Modified by jeff b (jeff@univrel.pr.uconn.edu)
+
+dnl Test for netatalk, and define NETATALK_CFLAGS and NETATALK_LIBS
+dnl to be used as follows:
+dnl AM_PATH_NETATALK(MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]])
+dnl
+AC_DEFUN(AM_PATH_NETATALK,
+[dnl
+dnl Get the cflags and libraries from the netatalk-config script
+dnl
+
+dnl
+dnl Prefix options
+dnl
+AC_ARG_WITH(netatalk-prefix,
+[ --with-netatalk-prefix=PREFIX
+ Prefix where netatalk is installed (optional)]
+, netatalk_config_prefix="$withval", netatalk_config_prefix="")
+
+AC_ARG_WITH(netatalk-exec-prefix,
+[ --with-netatalk-exec-prefix=PREFIX
+ Exec prefix where netatalk is installed (optional)]
+, netatalk_config_exec_prefix="$withval", netatalk_config_exec_prefix="")
+
+AC_ARG_ENABLE(netatalktest,
+[ --disable-netatalktest Do not try to compile and run a test netatalk
+ program],
+, enable_netatalktest=yes)
+
+dnl
+dnl Prefix handling
+dnl
+ if test x$netatalk_config_exec_prefix != x ; then
+ netatalk_config_args="$netatalk_config_args --exec-prefix=$netatalk_config_exec_prefix"
+ if test x${NETATALK_CONFIG+set} != xset ; then
+ NETATALK_CONFIG=$netatalk_config_exec_prefix/bin/netatalk-config
+ fi
+ fi
+ if test x$netatalk_config_prefix != x ; then
+ netatalk_config_args="$netatalk_config_args --prefix=$netatalk_config_prefix"
+ if test x${NETATALK_CONFIG+set} != xset ; then
+ NETATALK_CONFIG=$netatalk_config_prefix/bin/netatalk-config
+ fi
+ fi
+
+dnl
+dnl See if netatalk-config is alive
+dnl
+ AC_PATH_PROG(NETATALK_CONFIG, netatalk-config, no)
+ netatalk_version_min=$1
+
+dnl
+dnl Version check
+dnl
+ AC_MSG_CHECKING(for netatalk - version >= $netatalk_version_min)
+ no_netatalk=""
+ if test "$NETATALK_CONFIG" = "no" ; then
+ no_netatalk=yes
+ else
+ netatalk_version=`$NETATALK_CONFIG --version`
+
+ NETATALK_CFLAGS=`$NETATALK_CONFIG $netatalk_config_args --cflags`
+ NETATALK_LIBS=`$NETATALK_CONFIG $netatalk_config_args --libs`
+
+ netatalk_major_version=`echo $netatalk_version | \
+ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
+ netatalk_minor_version=`echo $netatalk_version | \
+ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
+ netatalk_micro_version=`echo $netatalk_version | \
+ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
+
+ netatalk_major_min=`echo $netatalk_major_version | \
+ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
+ netatalk_minor_min=`echo $netatalk_minor_version | \
+ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
+ netatalk_micro_min=`echo $netatalk_micro_version | \
+ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
+
+ netatalk_version_proper=`expr \
+ $netatalk_major_version \> $netatalk_major_min \| \
+ $netatalk_major_version \= $netatalk_major_min \& \
+ $netatalk_minor_version \> $netatalk_minor_min \| \
+ $netatalk_major_version \= $netatalk_major_min \& \
+ $netatalk_minor_version \= $netatalk_minor_min \& \
+ $netatalk_micro_version \>= $netatalk_micro_min `
+
+ if test "$netatalk_version_proper" = "1" ; then
+ AC_MSG_RESULT([$netatalk_major_version.$netatalk_minor_version.$netatalk_micro_version])
+ else
+ AC_MSG_RESULT(no)
+ no_netatalk=yes
+ fi
+
+ if test "X$no_netatalk" = "Xyes" ; then
+ enable_netatalktest=no
+ fi
+
+ AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+
+dnl
+dnl
+dnl
+ if test "x$enable_netatalktest" = "xyes" ; then
+ AC_MSG_CHECKING(if netatalk sane)
+ ac_save_CXXFLAGS="$CXXFLAGS"
+ ac_save_LIBS="$LIBS"
+ CXXFLAGS="$CXXFLAGS $NETATALK_CFLAGS"
+ LIBS="$LIBS $NETATALK_LIBS"
+
+ rm -f conf.netatalktest
+
+ AC_TRY_RUN([
+#include <stdio.h>
+#include <libatalk/version.h>
+
+int main(int argc,char **argv)
+ {
+ if (netatalk_major_version!=$netatalk_major_version ||
+ netatalk_minor_version!=$netatalk_minor_version ||
+ netatalk_micro_version!=$netatalk_micro_version)
+ { printf("(%d.%d.%d) ",
+ netatalk_major_version,netatalk_minor_version,netatalk_micro_version);
+ return 1;
+ }
+ }
+
+],[
+ AC_MSG_RESULT(yes)
+],[
+ AC_MSG_RESULT(no)
+ no_netatalk=yes
+]
+,[echo $ac_n "cross compiling; assumed OK... $ac_c"])
+
+ CXXFLAGS="$ac_save_CXXFLAGS"
+ LIBS="$ac_save_LIBS"
+ fi
+ fi
+
+ dnl
+ dnl
+ if test "x$no_netatalk" = x ; then
+ ifelse([$2], , :, [$2])
+ else
+ NETATALK_CFLAGS=""
+ NETATALK_LIBS=""
+ ifelse([$3], , :, [$3])
+ fi
+
+ AC_LANG_RESTORE
+
+ AC_SUBST(NETATALK_CFLAGS)
+ AC_SUBST(NETATALK_LIBS)
+])
+
--- /dev/null
+This is the Debian GNU/Linux prepackaged version of netatalk.
+
+This package was originally put together by Joel 'epsy' Klecker.
+Current maintainer is Sebastian Rittau <srittau@jroger.in-berlin.de>.
+The sources were obtained from:
+<http://netatalk.sourceforge.net/>
+
+Changes:
+ * Added Debian GNU/Linux package maintenance system files.
+ * Fixed some build problems.
+ * Added patch for megatron.
+
+The following copyrights/licenses apply to this software:
+
+Copyright (c) 1990,1996 Regents of The University of Michigan.
+All Rights Reserved.
+
+ Permission to use, copy, modify, and distribute this software and
+ its documentation for any purpose and without fee is hereby granted,
+ provided that the above copyright notice appears in all copies and
+ that both that copyright notice and this permission notice appear
+ in supporting documentation, and that the name of The University
+ of Michigan not be used in advertising or publicity pertaining to
+ distribution of the software without specific, written prior
+ permission. This software is supplied as is without expressed or
+ implied warranties of any kind.
+
+This product includes software developed by the University of
+California, Berkeley and its contributors.
+
+Solaris code is encumbered by the following:
+ Copyright (C) 1996 by Sun Microsystems Computer Co.
+
+ Permission to use, copy, modify, and distribute this software and
+ its documentation for any purpose and without fee is hereby
+ granted, provided that the above copyright notice appear in all
+ copies and that both that copyright notice and this permission
+ notice appear in supporting documentation. This software is
+ provided "as is" without express or implied warranty.
+
+Modifications for Appleshare IP and other files copyrighted by Adrian
+Sun are under the following copyright:
+
+ Copyright (c) 1997,1998,1999,2000 Adrian Sun (asun@cobalt.com)
+ All Rights Reserved.
+
+ Permission to use, copy, modify, and distribute this software and
+ its documentation for any purpose and without fee is hereby granted,
+ provided that the above copyright notice appears in all copies and
+ that both that copyright notice and this permission notice appear
+ in supporting documentation. This software is supplied as is
+ without expressed or implied warranties of any kind.
+
+Research Systems Unix Group
+The University of Michigan
+c/o Wesley Craig
+535 W. William Street
+Ann Arbor, Michigan
++1-313-764-2278
+netatalk@umich.edu
+
+
+This product includes software developed by the OpenSSL Project
+for use in the OpenSSL Toolkit (http://www.openssl.org/)
+
+See /usr/share/doc/libssl096/copyright for more information on
+libssl and openssl.
--- /dev/null
+/etc/netatalk/papd.conf
+/etc/netatalk/afpd.conf
+/etc/netatalk/atalkd.conf
+/etc/netatalk/netatalk.conf
+/etc/netatalk/AppleVolumes.system
+/etc/netatalk/AppleVolumes.default
+/etc/init.d/netatalk
+/etc/pam.d/netatalk
--- /dev/null
+BUGS
+CHANGES
+CONTRIBUTORS
+README
+README.ASUN
+README.MORGAN
+TODO
--- /dev/null
+#!/bin/sh
+
+test -x /usr/sbin/atalkd || exit 0
+
+servername=$(/bin/hostname --short)
+
+# Enable PAP (AppleTalk Printer Access Protocol) daemon
+# (default yes)
+ENABLE_PAP=yes
+
+case "$1" in
+ start)
+ echo -n "Starting AppleTalk Daemons (this will take a while):"
+ /usr/sbin/atalkd
+ echo -n " atalkd"
+
+ /usr/bin/nbprgstr -p 4 "$servername:Workstation"
+ /usr/bin/nbprgstr -p 4 "$servername:netatalk"
+
+ /usr/sbin/afpd -n "$servername"
+ echo -n " afpd"
+
+ if [ "$ENABLE_PAP" = "yes" ]; then
+ /usr/sbin/papd
+ echo -n " papd"
+ fi
+
+ echo "."
+ ;;
+
+ stop)
+ echo -n "Stopping AppleTalk Daemons:"
+ echo -n " afpd"; \
+ start-stop-daemon --stop --quiet --oknodo --exec /usr/sbin/afpd
+
+ if [ -f /var/run/papd.pid ]; then
+ echo -n " papd"; \
+ start-stop-daemon --stop --quiet --oknodo --exec /usr/sbin/papd
+ fi
+
+ echo -n " atalkd"; \
+ start-stop-daemon --stop --quiet --oknodo --exec /usr/sbin/atalkd
+
+ echo "."
+ ;;
+
+ restart)
+ $0 force-reload
+ ;;
+
+ force-reload)
+ echo -n "Restarting AppleTalk Daemons (this will take a while)"
+ /etc/init.d/netatalk stop > /dev/null 2>&1
+ echo -n "."
+ sleep 2
+ echo -n "."
+ if /etc/init.d/netatalk start > /dev/null 2>&1
+ then
+ echo "done."
+ fi
+ ;;
+
+ *)
+ echo "Usage: /etc/init.d/netatalk {start|stop|restart|force-reload}" >&2
+ exit 1
+ ;;
+esac
+
--- /dev/null
+#!/bin/sh
+set -e
+
+if [ "$1" = "configure" ]; then
+ if [ -d /usr/doc -a ! -e /usr/doc/netatalk -a -d /usr/share/doc/netatalk ]; then
+ ln -sf ../share/doc/netatalk /usr/doc/netatalk
+ fi
+ update-rc.d netatalk defaults 50 >/dev/null
+# update-rc.d afpd defaults 51 >/dev/null
+# update-rc.d papd defaults 52 >/dev/null
+ /etc/init.d/netatalk start
+# /etc/init.d/afpd start
+# /etc/init.d/papd start
+fi
+exit 0
+
--- /dev/null
+#!/bin/sh
+set -e
+
+if [ $1 = "purge" ]; then
+ update-rc.d netatalk remove > /dev/null
+# update-rc.d afpd remove > /dev/null
+# update-rc.d papd remove > /dev/null
+fi
--- /dev/null
+#!/bin/sh
+set -e
+
+if [ $1 = "upgrade" ];
+then
+ if dpkg --compare-versions $2 lt 1.4b2-5
+ then
+ if [ ! -d /etc/netatalk ]; then
+ mkdir /etc/netatalk
+ cd /etc
+ for file in AppleVolumes.* atalkd.conf* papd.conf*
+ do
+ if [ -f $i ]; then
+ mv $file netatalk > /dev/null 2>&1; cd $OLDPWD
+ fi
+ done
+ fi
+ fi
+ if dpkg --compare-versions "$2" lt 1.4b2+asun2.1.3-1
+ then
+ cat <<EOF
+WARNING: The handling of CRLF translation of text files has changed.
+It is now off by default and must be explicitly enabled on a per volume basis.
+If you wish to use CRLF translation, you must edit /etc/netatalk/AppleVolumes.default and add
+\`options=crlf' where appropriate (e.g. \`~ "Home Directory" options=crlf')."
+If users have AppleVolumes files in their home directories, you should advise them of the change.
+EOF
+ echo -n "Press [enter] to continue."
+ read nl
+ fi
+fi
--- /dev/null
+#!/bin/sh
+set -e
+
+if [ \( "$1" = "upgrade" -o "$1" = "remove" \) -a -L /usr/doc/netatalk ]; then
+ rm -f /usr/doc/netatalk
+fi
+
+/etc/init.d/netatalk stop || true
+#/etc/init.d/afpd stop || true
+#/etc/init.d/papd stop || true
--- /dev/null
+add_netatalk_printer.1
+apple_cp.1
+apple_mv.1
+apple_rm.1
+lp2pap.sh.1
+makecode.1
+nu.1
+parsecode.1
+psa.8
+timelord.8
+timeout.1
--- /dev/null
+--- netatalk.cvs/etc/psf/Makefile.am
++++ netatalk.debian/etc/psf/Makefile.am
+@@ -1,7 +1,11 @@
+ # Makefile.am for etc/psf/
+
++filterdir = $(libdir)/atalk/filters
++
+ sbin_PROGRAMS = psf psa
+
++filter_SCRIPTS = etc2ps.sh
++
+ psf_SOURCES = psf.c
+ psa_SOURCES = psa.c
+
+@@ -24,9 +28,11 @@
+ # install sections for links
+ #
+
+-install-data-local:
++# srittau: We do some dirty hard-coding for Debian to maintain compability.
++install-exec-local:
++ mkdir -p $(DESTDIR)$(filterdir)
+ @list='$(psf_LINKS)'; for l in $$list; do \
+- $(LN_S) -f psf $(DESTDIR)$(sbindir)/$$l; \
++ $(LN_S) -f ../../../sbin/psf $(DESTDIR)$(filterdir)/$$l; \
+ done
+
+ #
--- /dev/null
+--- netatalk.cvs/bin/afile/Makefile.am
++++ netatalk.debian/bin/afile/Makefile.am
+@@ -8,6 +8,4 @@
+ afile_SOURCES = afile.c
+ afile_LDADD = $(top_builddir)/libatalk/libatalk.la
+
+-LIBS = @LIBS@ -L$(top_builddir)/libatalk/ -latalk
+-
+ EXTRA_DIST = README acleandir.rc
+--- netatalk.cvs/contrib/timelord/Makefile.am
++++ netatalk.debian/contrib/timelord/Makefile.am
+@@ -5,6 +5,4 @@
+ timelord_SOURCES = timelord.c
+ timelord_LDADD = $(top_builddir)/libatalk/libatalk.la
+
+-LIBS = @LIBS@ -latalk
+-
+ EXTRA_DIST = COPYRIGHT README VERSION
+diff -u -r1.11 Makefile.am
+--- netatalk.cvs/etc/afpd/Makefile.am
++++ netatalk.debian/etc/afpd/Makefile.am
+@@ -9,7 +9,7 @@
+ afp_options.c afp_asp.c afp_dsi.c messages.c afp_config.c nfsquota.c \
+ codepage.c quota.c uam.c afs.c uid.c
+
+-afpd_LDADD = $(top_builddir)/libatalk/libatalk.a -latalk
++afpd_LDADD = $(top_builddir)/libatalk/libatalk.la
+ afpd_LDFLAGS = -rdynamic
+
+ noinst_HEADERS = auth.h codepage.h afp_config.h desktop.h directory.h file.h \
+--- netatalk.cvs/etc/papd/Makefile.am
++++ netatalk.debian/etc/papd/Makefile.am
+@@ -4,11 +4,11 @@
+ #bin_PROGRAMS = showppd
+
+ papd_SOURCES = main.c printcap.c session.c file.c comment.c lp.c ppd.c magics.c headers.c queries.c auth.c uam.c
+-papd_LDADD = $(top_builddir)/libatalk/libatalk.la -latalk
++papd_LDADD = $(top_builddir)/libatalk/libatalk.la
+ papd_LDFLAGS = -rdynamic
+
+ #showppd_SOURCES = showppd.c ppd.c
+-#showppd_LDADD = $(top_builddir)/libatalk/libatalk.la -latalk
++#showppd_LDADD = $(top_builddir)/libatalk/libatalk.la
+
+ noinst_HEADERS = comment.h file.h ppd.h printer.h uam_auth.h
+
--- /dev/null
+--- netatalk.cvs/libatalk/dummy.c
++++ netatalk.debian/libatalk/dummy.c
+@@ -0,0 +1,1 @@
++
+--- netatalk.cvs/libatalk/Makefile.am
++++ netatalk.debian/libatalk/Makefile.am
+@@ -1,19 +1,11 @@
+ # Makefile.am for libatalk/
+
+-# FIXME: Included manually, because for some strange reason automake doesn't.
+-# (srittau)
+-CCLD = $(CC)
+-LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+-
+ SUBDIRS = adouble asp atp compat dsi nbp netddp util
+
+ lib_LTLIBRARIES = libatalk.la
+
+ LIBATALK_DEPS = asp/libasp.la atp/libatp.la nbp/libnbp.la adouble/libadouble.la dsi/libdsi.la util/libutil.la compat/libcompat.la netddp/libnetddp.la asp/libasp.la
+
+-libatalk_la_SOURCES =
++libatalk_la_SOURCES = dummy.c
+ libatalk_la_LIBADD = ${LIBATALK_DEPS}
+ libatalk_la_LDFLAGS = -static
+-
+-#libatalk.a: ${LIBATALK_DEPS}
+-# ${LIBTOOL} --mode=link ${LIBATALK_DEPS} -o libatalk.a
--- /dev/null
+--- netatalk.cvs/bin/megatron/macbin.c
++++ netatalk.debian/bin/megatron/macbin.c
+@@ -18,6 +18,12 @@
+ #include <netatalk/endian.h>
+ #include "megatron.h"
+
++/* This allows megatron to generate .bin files that won't choke other
++ well-known converter apps. It also makes sure that checksums
++ always match. (RLB) */
++#define MACBINARY_PLAY_NICE_WITH_OTHERS
++
++
+ /* String used to indicate standard input instead of a disk
+ file. Should be a string not normally used for a file
+ */
+@@ -237,7 +243,10 @@
+ int writelen;
+ int cc = 0;
+ off_t pos;
+- u_char padchar = 0;
++ u_char padchar = 0x7f; /* Not sure why, but it seems
++ this must be 0x7f to match
++ other converters, not
++ 0. (RLB) */
+
+ #if DEBUG >= 3
+ fprintf( stderr, "bin_write: fork is %s\n", forkname[ fork ] );
+@@ -352,8 +361,14 @@
+ fh->mod_date = AD_DATE_FROM_UNIX(fh->mod_date);
+ fh->backup_date = AD_DATE_START;
+ memcpy( &fh->finder_info, head_buf + 65, 8 );
++
++#ifndef MACBINARY_PLAY_NICE_WITH_OTHERS /* (RLB) */
+ memcpy( &fh->finder_info.fdFlags, head_buf + 73, 1 );
+ fh->finder_info.fdFlags &= mask;
++#else
++ memcpy( &fh->finder_info.fdFlags, head_buf + 73, 2 );
++#endif
++
+ memcpy(&fh->finder_info.fdLocation, head_buf + 75, 4 );
+ memcpy(&fh->finder_info.fdFldr, head_buf + 79, 2 );
+ memcpy(&fh->forklen[ DATA ], head_buf + 83, 4 );
+@@ -370,6 +385,7 @@
+ #if DEBUG >= 5
+ {
+ short flags;
++ long flags_long;
+
+ fprintf( stderr, "Values read by bin_header_read\n" );
+ fprintf( stderr, "name length\t\t%d\n", head_buf[ 1 ] );
+@@ -383,6 +399,13 @@
+ memcpy( &flags, &fh->finder_info.fdFlags, sizeof( flags ));
+ flags = ntohs( flags );
+ fprintf( stderr, "flags\t\t\t%x\n", flags );
++
++ /* Show fdLocation too (RLB) */
++ memcpy( &flags_long, &fh->finder_info.fdLocation,
++ sizeof( flags_long ));
++ flags_long = ntohl( flags_long );
++ fprintf( stderr, "location flags\t\t%lx\n", flags_long );
++
+ fprintf( stderr, "data fork length\t%ld\n", bin.forklen[DATA] );
+ fprintf( stderr, "resource fork length\t%ld\n", bin.forklen[RESOURCE] );
+ fprintf( stderr, "\n" );
+@@ -411,7 +434,13 @@
+ head_buf[ 1 ] = (u_char)strlen( fh->name );
+ memcpy( head_buf + 2, fh->name, head_buf[ 1 ] );
+ memcpy( head_buf + 65, &fh->finder_info, 8 );
+- memcpy( head_buf + 73, &fh->finder_info.fdFlags, 1);
++
++#ifndef MACBINARY_PLAY_NICE_WITH_OTHERS /* (RLB) */
++ memcpy( head_buf + 73, &fh->finder_info.fdFlags, 1 );
++#else
++ memcpy( head_buf + 73, &fh->finder_info.fdFlags, 2 );
++#endif
++
+ memcpy( head_buf + 75, &fh->finder_info.fdLocation, 4 );
+ memcpy( head_buf + 79, &fh->finder_info.fdFldr, 2 );
+ memcpy( head_buf + 83, &fh->forklen[ DATA ], 4 );
+@@ -440,11 +469,25 @@
+
+ #if DEBUG >= 5
+ {
++ short flags;
++ long flags_long;
++
+ fprintf( stderr, "Values written by bin_header_write\n" );
+ fprintf( stderr, "name length\t\t%d\n", head_buf[ 1 ] );
+ fprintf( stderr, "file name\t\t%s\n", (char *)&head_buf[ 2 ] );
+ fprintf( stderr, "type\t\t\t%.4s\n", (char *)&head_buf[ 65 ] );
+ fprintf( stderr, "creator\t\t\t%.4s\n", (char *)&head_buf[ 69 ] );
++
++ memcpy( &flags, &fh->finder_info.fdFlags, sizeof( flags ));
++ flags = ntohs( flags );
++ fprintf( stderr, "flags\t\t\t%x\n", flags );
++
++ /* Show fdLocation too (RLB) */
++ memcpy( &flags_long, &fh->finder_info.fdLocation,
++ sizeof( flags_long ));
++ flags_long = ntohl( flags_long );
++ fprintf( stderr, "location flags\t\t%lx\n", flags_long );
++
+ fprintf( stderr, "data fork length\t%ld\n", bin.forklen[DATA] );
+ fprintf( stderr, "resource fork length\t%ld\n", bin.forklen[RESOURCE] );
+ fprintf( stderr, "\n" );
--- /dev/null
+--- netatalk.cvs/include/atalk/paths.h
++++ netatalk.debian/include/atalk/paths.h
+@@ -24,7 +24,7 @@
+ #endif
+ #else
+ #ifdef linux
+-#define _PATH_LOCKDIR "/var/lock/"
++#define _PATH_LOCKDIR "/var/run/"
+ #else
+ #define _PATH_LOCKDIR "/var/spool/locks/"
+ #endif /* linux */
+@@ -51,18 +51,18 @@
+ */
+ #define _PATH_ATALKDEBUG "/tmp/atalkd.debug"
+ #define _PATH_ATALKDTMP "atalkd.tmp"
+-#define _PATH_ATALKDLOCK ATALKPATHCAT(_PATH_LOCKDIR,"atalkd")
++#define _PATH_ATALKDLOCK ATALKPATHCAT(_PATH_LOCKDIR,"atalkd.pid")
+
+ /*
+ * psorder paths
+ */
+ #define _PATH_TMPPAGEORDER "/tmp/psorderXXXXXX"
+-#define _PATH_PAPDLOCK ATALKPATHCAT(_PATH_LOCKDIR,"papd")
++#define _PATH_PAPDLOCK ATALKPATHCAT(_PATH_LOCKDIR,"papd.pid")
+
+ /*
+ * afpd paths
+ */
+ #define _PATH_AFPTKT "/tmp/AFPtktXXXXXX"
+-#define _PATH_AFPDLOCK ATALKPATHCAT(_PATH_LOCKDIR,"afpd")
++#define _PATH_AFPDLOCK ATALKPATHCAT(_PATH_LOCKDIR,"afpd.pid")
+
+ #endif /* atalk/paths.h */
--- /dev/null
+--- netatalk.cvs/man/man8/psf.8
++++ netatalk.debian/man/man8/psf.8
+@@ -90,13 +90,13 @@
+ .RS
+ .nf
+ laser|lp|LaserWriter Plus on AppleTalk:\\
+- :sd=/usr/spool/lpd/laser:\\
+- :lp=/usr/spool/lpd/laser/null:\\
+- :lf=/var/adm/lpd-errs:pw#80:hl:\\
+- :of=/usr/lib/filters/ofpap:\\
+- :if=/usr/lib/filters/ifpaprev:\\
+- :tf=/usr/lib/filters/tfpaprev:\\
+- :df=/usr/lib/filters/dfpaprev:
++ :sd=/var/spool/lpd/laser:\\
++ :lp=/var/spool/lpd/laser/null:\\
++ :lf=/var/log/lpd-errs:pw#80:hl:\\
++ :of=/usr/lib/atalk/filters/ofpap:\\
++ :if=/usr/lib/atalk/filters/ifpaprev:\\
++ :tf=/usr/lib/atalk/filters/tfpaprev:\\
++ :df=/usr/lib/atalk/filters/dfpaprev:
+ .fi
+ .RE
+ .sp
--- /dev/null
+--- netatalk.cvs/distrib/initscripts/Makefile.am
++++ netatalk.debian/distrib/initscripts/Makefile.am
+@@ -8,7 +8,7 @@
+ -e s@:ETCDIR:@${CONFIG_DIR}@ \
+ <$^ >$@
+
+-sysvdir = /etc/rc.d/init.d
++sysvdir = /etc/init.d
+
+ CLEANFILES = rc.atalk.redhat atalk
+
--- /dev/null
+#! /usr/bin/make -f
+
+#export DH_VERBOSE=1
+
+build: build-stamp
+build-stamp:
+ dh_testdir
+
+ ./configure --prefix=/usr --with-config-dir=/etc/netatalk \
+ --with-pam --with-tcp-wrappers --mandir=/usr/share/man \
+ --with-uams-path=/usr/lib/netatalk \
+ --with-cflags=-O2
+ $(MAKE)
+
+ touch build-stamp
+
+clean:
+ dh_testdir
+ rm -f build-stamp
+ -$(MAKE) distclean
+ dh_clean
+
+binary: binary-arch binary-indep
+
+binary-indep: build
+
+binary-arch: build
+ dh_testdir
+ dh_testroot
+ dh_clean -k
+ dh_installdirs
+
+ $(MAKE) install DESTDIR="`pwd`/debian/tmp" # CFLAGS="-Wall -O2"
+
+ dh_installdocs
+ dh_installinit --update-rcd-params="defaults 50 50"
+ dh_installmanpages -pnetatalk man/man5/*.tmpl man/man8/*.tmpl
+ dh_undocumented
+ dh_installchangelogs ChangeLog
+
+ # Move PAM config file to PAM directory.
+ mv debian/tmp/etc/netatalk/netatalk.pamd debian/tmp/etc/pam.d/netatalk
+
+ # Manually remove a header file that is shipped with glibc and
+ # the Linux Kernel.
+ rm debian/tmp/usr/include/netatalk/at.h
+
+ dh_movefiles
+ rmdir debian/tmp/usr/include/atalk debian/tmp/usr/include/netatalk
+ rmdir debian/tmp/usr/include
+ rmdir debian/tmp/usr/share/aclocal
+ rmdir debian/tmp/usr/share/man/man3 debian/tmp/usr/share/man/man4
+
+ dh_strip
+ dh_compress
+ dh_fixperms
+ dh_installdeb
+ dh_shlibdeps
+ dh_gencontrol
+ dh_md5sums
+ dh_builddeb
+
+.PHONY: clean binary binary-arch binary-indep
--- /dev/null
+#!/bin/sh
+
+test -x /usr/sbin/afpd || exit 0
+
+servername=$(hostname)
+
+case "$1" in
+start)
+ echo -n "Starting AppleTalk Filing Protocol Daemon: "
+ start-stop-daemon --start --exec /usr/sbin/afpd -- -n $servername
+ echo "afpd."
+ ;;
+
+stop)
+ echo -n "Stopping AppleTalk Filing Protocol Daemon: "
+ start-stop-daemon --stop --quiet --oknodo --exec /usr/sbin/afpd
+ echo "afpd."
+ ;;
+
+restart)
+ $0 force-reload
+ ;;
+
+force-reload)
+ echo -n "Restarting AppleTalk Filing Protocol Daemon: "
+ $0 stop > /dev/null 2>&1
+ echo -n "."
+ sleep 2
+ echo -n "."
+ $0 start > /dev/null 2>&1
+ echo "afpd."
+ ;;
+
+*)
+ echo "Usage: /etc/init.d/afpd {start|stop|restart|force-reload}" >&2
+ exit 1
+ ;;
+esac
+
--- /dev/null
+#!/bin/sh
+
+test -x /usr/sbin/atalkd || exit 0
+
+servername=$(hostname)
+
+case "$1" in
+start)
+ echo -n "Starting AppleTalk daemon: "
+ if modprobe -r appletalk > /dev/null 2>&1; then
+ sleep 5
+ fi
+ if modprobe appletalk.o > /dev/null 2>&1; then
+ sleep 5
+ fi
+ /usr/sbin/atalkd
+ echo -n "atalkd."
+
+ /usr/bin/nbprgstr -p 4 "$servername:Workstation"
+ /usr/bin/nbprgstr -p 4 "$servername:netatalk"
+ ;;
+
+stop)
+ echo -n "Stopping AppleTalk Daemon: "
+ start-stop-daemon --stop --quiet --oknodo --exec /usr/sbin/atalkd
+ echo "atalkd."
+ sleep 5
+ modprobe -r appletalk > /dev/null 2>&1
+ ;;
+
+restart)
+ $0 force-reload
+ ;;
+
+force-reload)
+ echo -n "Restarting AppleTalk Daemon: "
+ $0 stop > /dev/null 2>&1
+ echo -n "."
+ sleep 2
+ echo -n "."
+ $0 start > /dev/null 2>&1
+ echo "afpd."
+ ;;
+
+*)
+ echo "Usage: /etc/init.d/netatalk {start|stop|restart|force-reload}" >&2
+ exit 1
+ ;;
+esac
+
--- /dev/null
+#!/bin/sh
+
+test -x /usr/sbin/papd || exit 0
+
+case "$1" in
+start)
+ echo -n "Starting AppleTalk Printer Access Protocol Daemon: "
+ start-stop-daemon --start --exec /usr/sbin/papd
+ echo "papd."
+ ;;
+
+stop)
+ echo -n "Stopping AppleTalk Printer Access Protocol Daemon: "
+ start-stop-daemon --stop --quiet --oknodo --exec /usr/sbin/papd
+ echo "papd."
+ ;;
+
+restart)
+ $0 force-reload
+ ;;
+
+force-reload)
+ echo -n "Restarting AppleTalk Printer Access Protocol Daemon: "
+ $0 stop > /dev/null 2>&1
+ echo -n "."
+ sleep 2
+ echo -n "."
+ $0 start > /dev/null 2>&1
+ echo "afpd."
+ ;;
+
+*)
+ echo "Usage: /etc/init.d/papd {start|stop|restart|force-reload}" >&2
+ exit 1
+ ;;
+esac
+