Remove AppleTalk support.

AppleTalk was a network transport protocol for Apple Macintosh devices
in 80s and then 90s. Starting with Mac OS X in 2000 the AppleTalk was
a legacy protocol and primary networking protocol is TCP/IP. The last
Mac OS X release to support AppleTalk happened in 2009. The same year
routing equipment vendors (namely Cisco) end their support.

Thus, AppleTalk won't be supported in FreeBSD 11.0-RELEASE.
This commit is contained in:
Gleb Smirnoff 2014-03-14 06:29:43 +00:00
parent f589320a0e
commit 45c203fce2
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=263152
80 changed files with 74 additions and 5233 deletions

View file

@ -38,6 +38,18 @@
# xargs -n1 | sort | uniq -d;
# done
# 20140314: AppleTalk
OLD_DIRS+=usr/include/netatalk
OLD_FILES+=usr/include/netatalk/aarp.h
OLD_FILES+=usr/include/netatalk/at.h
OLD_FILES+=usr/include/netatalk/at_extern.h
OLD_FILES+=usr/include/netatalk/at_var.h
OLD_FILES+=usr/include/netatalk/ddp.h
OLD_FILES+=usr/include/netatalk/ddp_pcb.h
OLD_FILES+=usr/include/netatalk/ddp_var.h
OLD_FILES+=usr/include/netatalk/endian.h
OLD_FILES+=usr/include/netatalk/phase2.h
# 20140314: Remove IPX/SPX
OLD_LIBS+=lib/libipx.so.5
OLD_FILES+=usr/include/netipx/ipx.h

View file

@ -257,8 +257,6 @@
..
net80211
..
netatalk
..
netgraph
atm
..

View file

@ -36,7 +36,7 @@ PHDRS= sched.h _semaphore.h
LHDRS= aio.h errno.h fcntl.h linker_set.h poll.h stdatomic.h stdint.h \
syslog.h ucontext.h
LDIRS= bsm cam geom net net80211 netatalk netgraph netinet netinet6 \
LDIRS= bsm cam geom net net80211 netgraph netinet netinet6 \
netipsec netnatm netsmb nfs nfsclient nfsserver sys vm
LSUBDIRS= cam/ata cam/scsi \

View file

@ -21,7 +21,6 @@ SRCS+= af_inet.c # IPv4 support
.if ${MK_INET6_SUPPORT} != "no"
SRCS+= af_inet6.c # IPv6 support
.endif
SRCS+= af_atalk.c # AppleTalk support
.if ${MK_INET6_SUPPORT} != "no"
SRCS+= af_nd6.c # ND6 support
.endif

View file

@ -1,182 +0,0 @@
/*
* Copyright (c) 1983, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef lint
static const char rcsid[] =
"$FreeBSD$";
#endif /* not lint */
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include <netatalk/at.h>
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <ifaddrs.h>
#include <arpa/inet.h>
#include "ifconfig.h"
static struct netrange at_nr; /* AppleTalk net range */
static struct ifaliasreq at_addreq;
/* XXX FIXME -- should use strtoul for better parsing. */
static void
setatrange(const char *range, int dummy __unused, int s,
const struct afswtch *afp)
{
u_int first = 123, last = 123;
if (sscanf(range, "%u-%u", &first, &last) != 2
|| first == 0 || first > 0xffff
|| last == 0 || last > 0xffff || first > last)
errx(1, "%s: illegal net range: %u-%u", range, first, last);
at_nr.nr_firstnet = htons(first);
at_nr.nr_lastnet = htons(last);
}
static void
setatphase(const char *phase, int dummy __unused, int s,
const struct afswtch *afp)
{
if (!strcmp(phase, "1"))
at_nr.nr_phase = 1;
else if (!strcmp(phase, "2"))
at_nr.nr_phase = 2;
else
errx(1, "%s: illegal phase", phase);
}
static void
at_status(int s __unused, const struct ifaddrs *ifa)
{
struct sockaddr_at *sat, null_sat;
struct netrange *nr;
memset(&null_sat, 0, sizeof(null_sat));
sat = (struct sockaddr_at *)ifa->ifa_addr;
if (sat == NULL)
return;
nr = &sat->sat_range.r_netrange;
printf("\tatalk %d.%d range %d-%d phase %d",
ntohs(sat->sat_addr.s_net), sat->sat_addr.s_node,
ntohs(nr->nr_firstnet), ntohs(nr->nr_lastnet), nr->nr_phase);
if (ifa->ifa_flags & IFF_POINTOPOINT) {
sat = (struct sockaddr_at *)ifa->ifa_dstaddr;
if (sat == NULL)
sat = &null_sat;
printf("--> %d.%d",
ntohs(sat->sat_addr.s_net), sat->sat_addr.s_node);
}
if (ifa->ifa_flags & IFF_BROADCAST) {
sat = (struct sockaddr_at *)ifa->ifa_broadaddr;
if (sat != NULL)
printf(" broadcast %d.%d",
ntohs(sat->sat_addr.s_net),
sat->sat_addr.s_node);
}
putchar('\n');
}
static void
at_getaddr(const char *addr, int which)
{
struct sockaddr_at *sat = (struct sockaddr_at *) &at_addreq.ifra_addr;
u_int net, node;
sat->sat_family = AF_APPLETALK;
sat->sat_len = sizeof(*sat);
if (which == MASK)
errx(1, "AppleTalk does not use netmasks");
if (sscanf(addr, "%u.%u", &net, &node) != 2
|| net > 0xffff || node > 0xfe)
errx(1, "%s: illegal address", addr);
sat->sat_addr.s_net = htons(net);
sat->sat_addr.s_node = node;
}
static void
at_postproc(int s, const struct afswtch *afp)
{
struct sockaddr_at *sat = (struct sockaddr_at *) &at_addreq.ifra_addr;
if (at_nr.nr_phase == 0)
at_nr.nr_phase = 2; /* Default phase 2 */
if (at_nr.nr_firstnet == 0)
at_nr.nr_firstnet = /* Default range of one */
at_nr.nr_lastnet = sat->sat_addr.s_net;
printf("\tatalk %d.%d range %d-%d phase %d\n",
ntohs(sat->sat_addr.s_net), sat->sat_addr.s_node,
ntohs(at_nr.nr_firstnet), ntohs(at_nr.nr_lastnet),
at_nr.nr_phase);
if ((u_short) ntohs(at_nr.nr_firstnet) >
(u_short) ntohs(sat->sat_addr.s_net)
|| (u_short) ntohs(at_nr.nr_lastnet) <
(u_short) ntohs(sat->sat_addr.s_net))
errx(1, "AppleTalk address is not in range");
sat->sat_range.r_netrange = at_nr;
}
static struct cmd atalk_cmds[] = {
DEF_CMD_ARG("range", setatrange),
DEF_CMD_ARG("phase", setatphase),
};
static struct afswtch af_atalk = {
.af_name = "atalk",
.af_af = AF_APPLETALK,
.af_status = at_status,
.af_getaddr = at_getaddr,
.af_postproc = at_postproc,
.af_difaddr = SIOCDIFADDR,
.af_aifaddr = SIOCAIFADDR,
.af_ridreq = &at_addreq,
.af_addreq = &at_addreq,
};
static __constructor void
atalk_ctor(void)
{
#define N(a) (sizeof(a) / sizeof(a[0]))
size_t i;
for (i = 0; i < N(atalk_cmds); i++)
cmd_register(&atalk_cmds[i]);
af_register(&af_atalk);
#undef N
}

View file

@ -158,7 +158,6 @@ The address or protocol families currently
supported are
.Dq inet ,
.Dq inet6 ,
.Dq atalk ,
and
.Dq link .
The default if available is
@ -562,42 +561,6 @@ The prefix can also be specified using the slash notation after the address.
See the
.Ar address
option above for more information.
.\" see
.\" Xr eon 5 .
.\" .It Cm nsellength Ar n
.\" .Pf ( Tn ISO
.\" only)
.\" This specifies a trailing number of bytes for a received
.\" .Tn NSAP
.\" used for local identification, the remaining leading part of which is
.\" taken to be the
.\" .Tn NET
.\" (Network Entity Title).
.\" The default value is 1, which is conformant to US
.\" .Tn GOSIP .
.\" When an ISO address is set in an ifconfig command,
.\" it is really the
.\" .Tn NSAP
.\" which is being specified.
.\" For example, in
.\" .Tn US GOSIP ,
.\" 20 hex digits should be
.\" specified in the
.\" .Tn ISO NSAP
.\" to be assigned to the interface.
.\" There is some evidence that a number different from 1 may be useful
.\" for
.\" .Tn AFI
.\" 37 type addresses.
.It Cm range Ar netrange
Under appletalk, set the interface to respond to a
.Ar netrange
of the form
.Ar startnet Ns - Ns Ar endnet .
Appletalk uses this scheme instead of
netmasks though
.Fx
implements it internally as a set of netmasks.
.It Cm remove
Another name for the
.Fl alias
@ -605,10 +568,6 @@ parameter.
Introduced for compatibility
with
.Bsx .
.It Cm phase
The argument following this specifies the version (phase) of the
Appletalk network attached to the interface.
Values of 1 or 2 are permitted.
.Sm off
.It Cm link Op Cm 0 No - Cm 2
.Sm on

View file

@ -4,7 +4,6 @@
4
6
add
atalk
blackhole
change
cloning

View file

@ -144,7 +144,6 @@ will ``flush'' the routing tables of all gateway entries.
When the address family may is specified by any of the
.Fl osi ,
.Fl xns ,
.Fl atalk ,
.Fl inet6 ,
or
.Fl inet
@ -255,14 +254,12 @@ if the local or remote addresses change.
The optional modifiers
.Fl xns ,
.Fl osi ,
.Fl atalk ,
and
.Fl link
specify that all subsequent addresses are in the
.Tn XNS ,
.Tn OSI ,
.Tn XNS
or
.Tn AppleTalk
.Tn OSI
address families,
or are specified as link-level addresses,
and the names must be numeric specifications rather than

View file

@ -55,7 +55,6 @@ __FBSDID("$FreeBSD$");
#include <net/if_dl.h>
#include <netinet/in.h>
#include <netinet/if_ether.h>
#include <netatalk/at.h>
#include <arpa/inet.h>
#include <netdb.h>
@ -72,8 +71,6 @@ __FBSDID("$FreeBSD$");
#include <unistd.h>
#include <ifaddrs.h>
#define ATALK_BUF_SIZE 20
struct fibl {
TAILQ_ENTRY(fibl) fl_next;
@ -114,8 +111,6 @@ static struct {
static TAILQ_HEAD(fibl_head_t, fibl) fibl_head;
static int atalk_aton(const char *, struct at_addr *);
static char *atalk_ntoa(struct at_addr, char [ATALK_BUF_SIZE]);
static void printb(int, const char *);
static void flushroutes(int argc, char *argv[]);
static int flushroutes_fib(int);
@ -409,9 +404,6 @@ flushroutes(int argc, char *argv[])
af = AF_INET6;
break;
#endif
case K_ATALK:
af = AF_APPLETALK;
break;
case K_LINK:
af = AF_LINK;
break;
@ -526,7 +518,6 @@ routename(struct sockaddr *sa)
{
struct sockaddr_dl *sdl;
const char *cp;
char atalk_buf[ATALK_BUF_SIZE];
int n;
if (!domain_initialized) {
@ -604,12 +595,6 @@ routename(struct sockaddr *sa)
break;
}
#endif
case AF_APPLETALK:
(void)snprintf(rt_line, sizeof(rt_line), "atalk %s",
atalk_ntoa(((struct sockaddr_at *)(void *)sa)->sat_addr,
atalk_buf));
break;
case AF_LINK:
sdl = (struct sockaddr_dl *)(void *)sa;
@ -651,7 +636,6 @@ static const char *
netname(struct sockaddr *sa)
{
struct sockaddr_dl *sdl;
char atalk_buf[ATALK_BUF_SIZE];
int n;
#ifdef INET
struct netent *np = NULL;
@ -712,13 +696,6 @@ netname(struct sockaddr *sa)
return(net_line);
}
#endif
case AF_APPLETALK:
(void)snprintf(net_line, sizeof(net_line), "atalk %s",
atalk_ntoa(((struct sockaddr_at *)(void *)sa)->sat_addr,
atalk_buf));
break;
case AF_LINK:
sdl = (struct sockaddr_dl *)(void *)sa;
@ -838,10 +815,6 @@ newroute(int argc, char **argv)
aflen = sizeof(struct sockaddr_in6);
break;
#endif
case K_ATALK:
af = AF_APPLETALK;
aflen = sizeof(struct sockaddr_at);
break;
case K_SA:
af = PF_ROUTE;
aflen = sizeof(struct sockaddr_storage);
@ -1304,16 +1277,6 @@ getaddr(int idx, char *str, struct hostent **hpp, int nrflags)
return (0);
}
#endif /* INET6 */
case AF_APPLETALK:
{
struct sockaddr_at *sat = (struct sockaddr_at *)(void *)sa;
if (!atalk_aton(str, &sat->sat_addr))
errx(EX_NOHOST, "bad address: %s", str);
rtm_addrs |= RTA_NETMASK;
return(forcehost || sat->sat_addr.s_node != 0);
}
case AF_LINK:
link_addr(str, (struct sockaddr_dl *)(void *)sa);
return (1);
@ -1892,7 +1855,6 @@ keyword(const char *cp)
static void
sodump(struct sockaddr *sa, const char *which)
{
char atalk_buf[ATALK_BUF_SIZE];
#ifdef INET6
char nbuf[INET6_ADDRSTRLEN];
#endif
@ -1915,11 +1877,6 @@ sodump(struct sockaddr *sa, const char *which)
sizeof(nbuf)));
break;
#endif
case AF_APPLETALK:
(void)printf("%s: atalk %s; ", which,
atalk_ntoa(((struct sockaddr_at *)(void *)sa)->sat_addr,
atalk_buf));
break;
}
(void)fflush(stdout);
}
@ -1973,24 +1930,3 @@ sockaddr(char *addr, struct sockaddr *sa, size_t size)
} while (cp < cplim);
sa->sa_len = cp - (char *)sa;
}
static int
atalk_aton(const char *text, struct at_addr *addr)
{
u_int net, node;
if (sscanf(text, "%u.%u", &net, &node) != 2
|| net > 0xffff || node > 0xff)
return(0);
addr->s_net = htons(net);
addr->s_node = node;
return(1);
}
static char *
atalk_ntoa(struct at_addr at, char buf[ATALK_BUF_SIZE])
{
(void)snprintf(buf, ATALK_BUF_SIZE, "%u.%u", ntohs(at.s_net), at.s_node);
buf[ATALK_BUF_SIZE - 1] = '\0';
return(buf);
}

View file

@ -75,7 +75,7 @@ Encapsulated datagrams are
prepended an outer datagram and a GRE header.
The GRE header specifies
the type of the encapsulated datagram and thus allows for tunneling other
protocols than IP like e.g.\& AppleTalk.
protocols than IP.
GRE mode is also the default tunnel mode on Cisco routers.
This is also the default mode of operation of the
.Nm
@ -169,8 +169,7 @@ Get the GRE key currently used for outgoing packets.
Note that the IP addresses of the tunnel endpoints may be the same as the
ones defined with
.Xr ifconfig 8
for the interface (as if IP is encapsulated), but need not be, as e.g.\& when
encapsulating AppleTalk.
for the interface (as if IP is encapsulated), but need not be.
.Sh EXAMPLES
Configuration example:
.Bd -literal
@ -294,7 +293,6 @@ The kernel must be set to forward datagrams by setting the
.Xr sysctl 8
variable to non-zero.
.Sh SEE ALSO
.\" Xr atalk 4 ,
.Xr gif 4 ,
.Xr inet 4 ,
.Xr ip 4 ,

View file

@ -1269,8 +1269,8 @@ It allows capturing raw Ethernet frames from the network, as well as
sending frames out of the interface.
.It INTERFACE
This node is also a system networking interface.
It has hooks representing
each protocol family (IP, AppleTalk, etc.) and appears in the output of
It has hooks representing each protocol family (IP, IPv6)
and appears in the output of
.Xr ifconfig 8 .
The interfaces are named
.Dq Li ng0 ,

View file

@ -70,8 +70,7 @@ Packets transmitted via the interface flow out the corresponding
protocol-specific hook.
Similarly, packets received on a hook appear on the interface as
packets received into the corresponding protocol stack.
The currently supported protocols are IP, IPv6, AppleTalk, ATM,
NATM, and NS.
The currently supported protocols are IP, IPv6, ATM, NATM, and NS.
.Pp
An
.Nm iface
@ -88,8 +87,6 @@ This node type supports the following hooks:
Transmission and reception of IP packets.
.It Va inet6
Transmission and reception of IPv6 packets.
.It Va atalk
Transmission and reception of AppleTalk packets.
.It Va atm
Transmission and reception of ATM packets.
.It Va natm

View file

@ -279,8 +279,6 @@ mail filter API
machine-specific C include files
.It Pa net/
miscellaneous network C include files
.It Pa netatalk/
Appletalk protocol
.It Pa netinet/
C include files for Internet standard protocols;
see

View file

@ -189,19 +189,13 @@ and
variants.
.Ss Protocol number constants
The follow protocol numbers are currently defined:
.Bl -tag -width NETISR_ATALK1
.Bl -tag -width NETISR_ROUTE
.It Dv NETISR_IP
IPv4
.It Dv NETISR_IGMP
IGMPv3 loopback
.It Dv NETISR_ROUTE
Routing socket loopback
.It Dv NETISR_AARP
Appletalk AARP
.It Dv NETISR_ATALK1
Appletalk phase 1
.It Dv NETISR_ATALK2
Appletalk phase 2
.It Dv NETISR_ARP
ARP
.It Dv NETISR_IPV6

View file

@ -9,7 +9,7 @@ SUBDIR= boot
# Directories to include in cscope name file and TAGS.
CSCOPEDIRS= boot bsm cam cddl compat conf contrib crypto ddb dev fs gdb \
geom gnu isa kern libkern modules net net80211 netatalk \
geom gnu isa kern libkern modules net net80211 \
netgraph netinet netinet6 netipsec netnatm netpfil \
netsmb nfs nfsclient nfsserver nlm ofed opencrypto \
pci rpc security sys ufs vm xdr xen ${CSCOPE_ARCHDIR}

View file

@ -41,7 +41,6 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include "opt_atalk.h"
#include "opt_atpic.h"
#include "opt_compat.h"
#include "opt_cpu.h"

View file

@ -606,9 +606,6 @@ options IPSEC #IP security (requires device crypto)
#
options IPSEC_NAT_T #NAT-T support, UDP encap of ESP
options NETATALK #Appletalk communications protocols
options NETATALKDEBUG #Appletalk debugging
#
# SMB/CIFS requester
# NETSMB enables support for SMB protocol, it requires LIBMCHAIN and LIBICONV
@ -1070,7 +1067,7 @@ options MD_ROOT
options QUOTA #enable disk quotas
# If you are running a machine just as a fileserver for PC and MAC
# users, using SAMBA or Netatalk, you may consider setting this option
# users, using SAMBA, you may consider setting this option
# and keeping all those users' directories on a filesystem that is
# mounted with the suiddir option. This gives new files the same
# ownership as the directory (similar to group). It's a security hole

View file

@ -3168,14 +3168,6 @@ net80211/ieee80211_tdma.c optional wlan ieee80211_support_tdma
net80211/ieee80211_wds.c optional wlan
net80211/ieee80211_xauth.c optional wlan wlan_xauth
net80211/ieee80211_alq.c optional wlan ieee80211_alq
netatalk/aarp.c optional netatalk
netatalk/at_control.c optional netatalk
netatalk/at_proto.c optional netatalk
netatalk/at_rmx.c optional netatalk
netatalk/ddp_input.c optional netatalk
netatalk/ddp_output.c optional netatalk
netatalk/ddp_pcb.c optional netatalk
netatalk/ddp_usrreq.c optional netatalk
netgraph/atm/ccatm/ng_ccatm.c optional ngatm_ccatm \
compile-with "${NORMAL_C} -I$S/contrib/ngatm"
netgraph/atm/ng_atm.c optional ngatm_atm
@ -3775,7 +3767,6 @@ security/audit/bsm_errno.c optional audit
security/audit/bsm_fcntl.c optional audit
security/audit/bsm_socket_type.c optional audit
security/audit/bsm_token.c optional audit
security/mac/mac_atalk.c optional mac netatalk
security/mac/mac_audit.c optional mac audit
security/mac/mac_cred.c optional mac
security/mac/mac_framework.c optional mac

View file

@ -422,7 +422,6 @@ LIBMCHAIN
MBUF_PROFILING
MBUF_STRESS_TEST
MROUTING opt_mrouting.h
NETATALK opt_atalk.h
NFSLOCKD
PCBGROUP opt_pcbgroup.h
PF_DEFAULT_TO_DROP opt_pf.h
@ -548,7 +547,6 @@ VP0_DEBUG opt_vpo.h
LPT_DEBUG opt_lpt.h
PLIP_DEBUG opt_plip.h
LOCKF_DEBUG opt_debug_lockf.h
NETATALKDEBUG opt_atalk.h
SI_DEBUG opt_debug_si.h
# Fb options

View file

@ -41,7 +41,6 @@
__FBSDID("$FreeBSD$");
#include "opt_apic.h"
#include "opt_atalk.h"
#include "opt_atpic.h"
#include "opt_compat.h"
#include "opt_cpu.h"

View file

@ -36,7 +36,6 @@ COMM= ${SYS}/dev/advansys/*.[ch] \
${SYS}/geom/*.[ch] \
${SYS}/kern/*.[ch] \
${SYS}/net/*.[ch] \
${SYS}/netatalk/*.[ch] \
${SYS}/netinet/*.[ch] \
${SYS}/netinet6/*.[ch] \
${SYS}/netipsec/*.[ch] \
@ -54,7 +53,6 @@ COMMDIR1= ${SYS}/conf \
${SYS}/geom \
${SYS}/kern \
${SYS}/net \
${SYS}/netatalk \
${SYS}/netinet \
${SYS}/netinet6 \
${SYS}/netipsec \

View file

@ -3698,11 +3698,6 @@ prison_priv_check(struct ucred *cred, int priv)
#endif
#ifdef notyet
/*
* AppleTalk privileges.
*/
case PRIV_NETATALK_RESERVEDPORT:
/*
* ATM privileges.
*/

View file

@ -546,12 +546,6 @@ static struct witness_order_list_entry order_lists[] = {
{ "tcpinp", &lock_class_rw },
{ "so_snd", &lock_class_mtx_sleep },
{ NULL, NULL },
/*
* netatalk
*/
{ "ddp_list_mtx", &lock_class_mtx_sleep },
{ "ddp_mtx", &lock_class_mtx_sleep },
{ NULL, NULL },
/*
* BPF
*/

View file

@ -3,7 +3,7 @@
.PATH: ${.CURDIR}/../../net ${.CURDIR}/../../netinet ${.CURDIR}/../../netinet6
KMOD= if_gre
SRCS= if_gre.c ip_gre.c opt_inet.h opt_inet6.h opt_atalk.h
SRCS= if_gre.c ip_gre.c opt_inet.h opt_inet6.h
.if !defined(KERNBUILDDIR)
opt_inet.h:
@ -11,9 +11,6 @@ opt_inet.h:
opt_inet6.h:
echo "#define INET6 1" > ${.TARGET}
opt_atalk.h:
echo "#define NETATALK 1" > ${.TARGET}
.endif
.include <bsd.kmod.mk>

View file

@ -3,12 +3,9 @@
.PATH: ${.CURDIR}/../../net
KMOD= if_tun
SRCS= if_tun.c opt_atalk.h opt_inet.h opt_inet6.h
SRCS= if_tun.c opt_inet.h opt_inet6.h
.if !defined(KERNBUILDDIR)
opt_atalk.h:
echo "#define NETATALK 1" > ${.TARGET}
opt_inet.h:
echo "#define INET 1" > ${.TARGET}

View file

@ -2,12 +2,9 @@
# $Whistle: Makefile,v 1.2 1999/01/19 19:39:21 archie Exp $
KMOD= ng_iface
SRCS= ng_iface.c opt_atalk.h opt_inet.h opt_inet6.h
SRCS= ng_iface.c opt_inet.h opt_inet6.h
.if !defined(KERNBUILDDIR)
opt_atalk.h:
echo "#define NETATALK 1" > ${.TARGET}
opt_inet.h:
echo "#define INET 1" > ${.TARGET}

View file

@ -30,7 +30,6 @@
* $FreeBSD$
*/
#include "opt_atalk.h"
#include "opt_inet.h"
#include "opt_inet6.h"
#include "opt_netgraph.h"
@ -82,18 +81,6 @@ int (*ef_inputp)(struct ifnet*, struct ether_header *eh, struct mbuf *m);
int (*ef_outputp)(struct ifnet *ifp, struct mbuf **mp,
const struct sockaddr *dst, short *tp, int *hlen);
#ifdef NETATALK
#include <netatalk/at.h>
#include <netatalk/at_var.h>
#include <netatalk/at_extern.h>
#define llc_snap_org_code llc_un.type_snap.org_code
#define llc_snap_ether_type llc_un.type_snap.ether_type
extern u_char at_org_code[3];
extern u_char aarp_org_code[3];
#endif /* NETATALK */
#include <security/mac/mac_framework.h>
#ifdef CTASSERT
@ -243,42 +230,6 @@ ether_output(struct ifnet *ifp, struct mbuf *m,
type = htons(ETHERTYPE_IPV6);
break;
#endif
#ifdef NETATALK
case AF_APPLETALK:
{
struct at_ifaddr *aa;
if ((aa = at_ifawithnet((const struct sockaddr_at *)dst)) == NULL)
senderr(EHOSTUNREACH); /* XXX */
if (!aarpresolve(ifp, m, (const struct sockaddr_at *)dst, edst)) {
ifa_free(&aa->aa_ifa);
return (0);
}
/*
* In the phase 2 case, need to prepend an mbuf for the llc header.
*/
if ( aa->aa_flags & AFA_PHASE2 ) {
struct llc llc;
ifa_free(&aa->aa_ifa);
M_PREPEND(m, LLC_SNAPFRAMELEN, M_NOWAIT);
if (m == NULL)
senderr(ENOBUFS);
llc.llc_dsap = llc.llc_ssap = LLC_SNAP_LSAP;
llc.llc_control = LLC_UI;
bcopy(at_org_code, llc.llc_snap_org_code, sizeof(at_org_code));
llc.llc_snap_ether_type = htons( ETHERTYPE_AT );
bcopy(&llc, mtod(m, caddr_t), LLC_SNAPFRAMELEN);
type = htons(m->m_pkthdr.len);
hlen = LLC_SNAPFRAMELEN + ETHER_HDR_LEN;
} else {
ifa_free(&aa->aa_ifa);
type = htons(ETHERTYPE_AT);
}
break;
}
#endif /* NETATALK */
case pseudo_AF_HDRCMPLT:
{
const struct ether_header *eh;
@ -720,9 +671,6 @@ ether_demux(struct ifnet *ifp, struct mbuf *m)
struct ether_header *eh;
int i, isr;
u_short ether_type;
#if defined(NETATALK)
struct llc *l;
#endif
KASSERT(ifp != NULL, ("%s: NULL interface pointer", __func__));
@ -798,38 +746,7 @@ ether_demux(struct ifnet *ifp, struct mbuf *m)
isr = NETISR_IPV6;
break;
#endif
#ifdef NETATALK
case ETHERTYPE_AT:
isr = NETISR_ATALK1;
break;
case ETHERTYPE_AARP:
isr = NETISR_AARP;
break;
#endif /* NETATALK */
default:
#if defined(NETATALK)
if (ether_type > ETHERMTU)
goto discard;
l = mtod(m, struct llc *);
if (l->llc_dsap == LLC_SNAP_LSAP &&
l->llc_ssap == LLC_SNAP_LSAP &&
l->llc_control == LLC_UI) {
if (bcmp(&(l->llc_snap_org_code)[0], at_org_code,
sizeof(at_org_code)) == 0 &&
ntohs(l->llc_snap_ether_type) == ETHERTYPE_AT) {
m_adj(m, LLC_SNAPFRAMELEN);
isr = NETISR_ATALK2;
break;
}
if (bcmp(&(l->llc_snap_org_code)[0], aarp_org_code,
sizeof(aarp_org_code)) == 0 &&
ntohs(l->llc_snap_ether_type) == ETHERTYPE_AARP) {
m_adj(m, LLC_SNAPFRAMELEN);
isr = NETISR_AARP;
break;
}
}
#endif /* NETATALK */
goto discard;
}
netisr_dispatch(isr, m);

View file

@ -36,7 +36,6 @@
* $FreeBSD$
*/
#include "opt_atalk.h"
#include "opt_inet.h"
#include "opt_inet6.h"
@ -75,15 +74,6 @@
#include <netdnet/dn.h>
#endif
#ifdef NETATALK
#include <netatalk/at.h>
#include <netatalk/at_var.h>
#include <netatalk/at_extern.h>
extern u_char at_org_code[ 3 ];
extern u_char aarp_org_code[ 3 ];
#endif /* NETATALK */
#include <security/mac/mac_framework.h>
static const u_char fddibroadcastaddr[FDDI_ADDR_LEN] =
@ -178,40 +168,6 @@ fddi_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
type = htons(ETHERTYPE_IPV6);
break;
#endif /* INET6 */
#ifdef NETATALK
case AF_APPLETALK: {
struct at_ifaddr *aa;
if (!aarpresolve(ifp, m, (const struct sockaddr_at *)dst, edst))
return (0);
/*
* ifaddr is the first thing in at_ifaddr
*/
if ((aa = at_ifawithnet((const struct sockaddr_at *)dst)) == 0)
goto bad;
/*
* In the phase 2 case, we need to prepend an mbuf for the llc header.
* Since we must preserve the value of m, which is passed to us by
* value, we m_copy() the first mbuf, and use it for our llc header.
*/
if (aa->aa_flags & AFA_PHASE2) {
struct llc llc;
M_PREPEND(m, LLC_SNAPFRAMELEN, M_WAITOK);
llc.llc_dsap = llc.llc_ssap = LLC_SNAP_LSAP;
llc.llc_control = LLC_UI;
bcopy(at_org_code, llc.llc_snap.org_code, sizeof(at_org_code));
llc.llc_snap.ether_type = htons(ETHERTYPE_AT);
bcopy(&llc, mtod(m, caddr_t), LLC_SNAPFRAMELEN);
type = 0;
} else {
type = htons(ETHERTYPE_AT);
}
ifa_free(&aa->aa_ifa);
break;
}
#endif /* NETATALK */
case pseudo_AF_HDRCMPLT:
{
const struct ether_header *eh;
@ -459,23 +415,6 @@ fddi_input(ifp, m)
ifp->if_noproto++;
goto dropanyway;
}
#ifdef NETATALK
if (bcmp(&(l->llc_snap.org_code)[0], at_org_code,
sizeof(at_org_code)) == 0 &&
ntohs(l->llc_snap.ether_type) == ETHERTYPE_AT) {
isr = NETISR_ATALK2;
m_adj(m, LLC_SNAPFRAMELEN);
break;
}
if (bcmp(&(l->llc_snap.org_code)[0], aarp_org_code,
sizeof(aarp_org_code)) == 0 &&
ntohs(l->llc_snap.ether_type) == ETHERTYPE_AARP) {
m_adj(m, LLC_SNAPFRAMELEN);
isr = NETISR_AARP;
break;
}
#endif /* NETATALK */
if (l->llc_snap.org_code[0] != 0 ||
l->llc_snap.org_code[1] != 0 ||
l->llc_snap.org_code[2] != 0) {
@ -510,14 +449,6 @@ fddi_input(ifp, m)
isr = NETISR_DECNET;
break;
#endif
#ifdef NETATALK
case ETHERTYPE_AT:
isr = NETISR_ATALK1;
break;
case ETHERTYPE_AARP:
isr = NETISR_AARP;
break;
#endif /* NETATALK */
default:
/* printf("fddi_input: unknown protocol 0x%x\n", type); */
ifp->if_noproto++;

View file

@ -41,7 +41,6 @@
* Also supported: IP in IP encaps (proto 55) as of RFC 2004
*/
#include "opt_atalk.h"
#include "opt_inet.h"
#include "opt_inet6.h"
@ -439,11 +438,6 @@ gre_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
gre_ip_id = ip_newid();
etype = ETHERTYPE_IPV6;
break;
#endif
#ifdef NETATALK
case AF_APPLETALK:
etype = ETHERTYPE_ATALK;
break;
#endif
default:
_IF_DROP(&ifp->if_snd);

View file

@ -34,7 +34,6 @@
* Loopback interface driver for protocol testing and timing.
*/
#include "opt_atalk.h"
#include "opt_inet.h"
#include "opt_inet6.h"
@ -71,11 +70,6 @@
#include <netinet/ip6.h>
#endif
#ifdef NETATALK
#include <netatalk/at.h>
#include <netatalk/at_var.h>
#endif
#include <security/mac/mac_framework.h>
#ifdef TINY_LOMTU
@ -267,8 +261,6 @@ looutput(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
#endif
m->m_pkthdr.csum_flags &= ~LO_CSUM_FEATURES6;
break;
case AF_APPLETALK:
break;
default:
printf("looutput: af=%d unexpected\n", af);
m_freem(m);
@ -360,11 +352,6 @@ if_simloop(struct ifnet *ifp, struct mbuf *m, int af, int hlen)
m->m_flags |= M_LOOP;
isr = NETISR_IPV6;
break;
#endif
#ifdef NETATALK
case AF_APPLETALK:
isr = NETISR_ATALK2;
break;
#endif
default:
printf("if_simloop: can't handle af=%d\n", af);

View file

@ -259,11 +259,6 @@ drop: ++ifp->if_ierrors;
case ETHERTYPE_IP:
isr = NETISR_IP;
break;
#endif
#ifdef NETATALK
case ETHERTYPE_AT:
isr = NETISR_ATALK;
break;
#endif
}
@ -338,11 +333,6 @@ struct mbuf *sppp_fr_header (struct sppp *sp, struct mbuf *m,
case AF_NS:
type = 0x8137;
break;
#endif
#ifdef NETATALK
case AF_APPLETALK:
type = ETHERTYPE_AT;
break;
#endif
}
h[3] = FR_PADDING;

View file

@ -16,7 +16,6 @@
* $FreeBSD$
*/
#include "opt_atalk.h"
#include "opt_inet.h"
#include "opt_inet6.h"
@ -904,11 +903,6 @@ tunwrite(struct cdev *dev, struct uio *uio, int flag)
case AF_INET6:
isr = NETISR_IPV6;
break;
#endif
#ifdef NETATALK
case AF_APPLETALK:
isr = NETISR_ATALK2;
break;
#endif
default:
m_freem(m);

View file

@ -52,15 +52,11 @@
#define NETISR_IP 1
#define NETISR_IGMP 2 /* IGMPv3 output queue */
#define NETISR_ROUTE 3 /* routing socket */
#define NETISR_AARP 4 /* Appletalk ARP */
#define NETISR_ATALK2 5 /* Appletalk phase 2 */
#define NETISR_ATALK1 6 /* Appletalk phase 1 */
#define NETISR_ARP 7 /* same as AF_LINK */
/* 8 was IPX */
#define NETISR_ETHER 9 /* ethernet input */
#define NETISR_IPV6 10
#define NETISR_NATM 11
#define NETISR_EPAIR 12 /* if_epair(4) */
#define NETISR_ARP 4 /* same as AF_LINK */
#define NETISR_ETHER 5 /* ethernet input */
#define NETISR_IPV6 6
#define NETISR_NATM 7
#define NETISR_EPAIR 8 /* if_epair(4) */
/*
* Protocol ordering and affinity policy constants. See the detailed

View file

@ -1,50 +0,0 @@
/*-
* Copyright (c) 2004-2009 Robert N. M. Watson
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Copyright (c) 1990,1994 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.
*
* 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
* $FreeBSD$
*/

View file

@ -1,725 +0,0 @@
/*-
* Copyright (c) 2004-2009 Robert N. M. Watson
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Copyright (c) 1990,1991,1994 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.
*
* 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
*
* $FreeBSD$
*/
#include "opt_atalk.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/kernel.h>
#include <sys/socket.h>
#include <sys/syslog.h>
#include <net/if.h>
#include <net/if_var.h>
#include <net/if_dl.h>
#include <netinet/in.h>
#undef s_net
#include <netinet/if_ether.h>
#include <netatalk/at.h>
#include <netatalk/at_var.h>
#include <netatalk/aarp.h>
#include <netatalk/phase2.h>
#include <netatalk/at_extern.h>
#include <security/mac/mac_framework.h>
static void aarptfree(struct aarptab *aat);
static void at_aarpinput(struct ifnet *ifp, struct mbuf *m);
#define AARPTAB_BSIZ 9
#define AARPTAB_NB 19
#define AARPTAB_SIZE (AARPTAB_BSIZ * AARPTAB_NB)
static struct aarptab aarptab[AARPTAB_SIZE];
struct mtx aarptab_mtx;
MTX_SYSINIT(aarptab_mtx, &aarptab_mtx, "aarptab_mtx", MTX_DEF);
#define AARPTAB_HASH(a) ((((a).s_net << 8) + (a).s_node) % AARPTAB_NB)
#define AARPTAB_LOOK(aat, addr) do { \
int n; \
\
AARPTAB_LOCK_ASSERT(); \
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 = NULL; \
} while (0)
#define AARPT_AGE (60 * 1)
#define AARPT_KILLC 20
#define AARPT_KILLI 3
static const u_char atmulticastaddr[6] = {
0x09, 0x00, 0x07, 0xff, 0xff, 0xff,
};
u_char at_org_code[3] = {
0x08, 0x00, 0x07,
};
const u_char aarp_org_code[3] = {
0x00, 0x00, 0x00,
};
static struct callout_handle aarptimer_ch =
CALLOUT_HANDLE_INITIALIZER(&aarptimer_ch);
static void
aarptimer(void *ignored)
{
struct aarptab *aat;
int i;
aarptimer_ch = timeout(aarptimer, NULL, AARPT_AGE * hz);
aat = aarptab;
AARPTAB_LOCK();
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;
aarptfree(aat);
}
AARPTAB_UNLOCK();
}
/*
* Search through the network addresses to find one that includes the given
* network. Remember to take netranges into consideration.
*
* The _locked variant relies on the caller holding the at_ifaddr lock; the
* unlocked variant returns a reference that the caller must dispose of.
*/
struct at_ifaddr *
at_ifawithnet_locked(const struct sockaddr_at *sat)
{
struct at_ifaddr *aa;
struct sockaddr_at *sat2;
AT_IFADDR_LOCK_ASSERT();
TAILQ_FOREACH(aa, &at_ifaddrhead, aa_link) {
sat2 = &(aa->aa_addr);
if (sat2->sat_addr.s_net == sat->sat_addr.s_net)
break;
if ((aa->aa_flags & AFA_PHASE2) &&
(ntohs(aa->aa_firstnet) <= ntohs(sat->sat_addr.s_net)) &&
(ntohs(aa->aa_lastnet) >= ntohs(sat->sat_addr.s_net)))
break;
}
return (aa);
}
struct at_ifaddr *
at_ifawithnet(const struct sockaddr_at *sat)
{
struct at_ifaddr *aa;
AT_IFADDR_RLOCK();
aa = at_ifawithnet_locked(sat);
if (aa != NULL)
ifa_ref(&aa->aa_ifa);
AT_IFADDR_RUNLOCK();
return (aa);
}
static void
aarpwhohas(struct ifnet *ifp, const 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;
AARPTAB_UNLOCK_ASSERT();
m = m_gethdr(M_NOWAIT, MT_DATA);
if (m == NULL)
return;
#ifdef MAC
mac_netatalk_aarp_send(ifp, m);
#endif
m->m_len = sizeof(*ea);
m->m_pkthdr.len = sizeof(*ea);
MH_ALIGN(m, sizeof(*ea));
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);
bcopy(IF_LLADDR(ifp), (caddr_t)ea->aarp_sha, sizeof(ea->aarp_sha));
/*
* 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.
*/
aa = at_ifawithnet(sat);
if (aa == NULL) {
m_freem(m);
return;
}
eh = (struct ether_header *)sa.sa_data;
if (aa->aa_flags & AFA_PHASE2) {
bcopy(atmulticastaddr, eh->ether_dhost,
sizeof(eh->ether_dhost));
eh->ether_type = htons(sizeof(struct llc) +
sizeof(struct ether_aarp));
M_PREPEND(m, sizeof(struct llc), M_NOWAIT);
if (m == NULL) {
ifa_free(&aa->aa_ifa);
return;
}
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(&sat->sat_addr.s_net, ea->aarp_tpnet,
sizeof(ea->aarp_tpnet));
ea->aarp_spnode = AA_SAT(aa)->sat_addr.s_node;
ea->aarp_tpnode = sat->sat_addr.s_node;
} else {
bcopy(ifp->if_broadcastaddr, (caddr_t)eh->ether_dhost,
sizeof(eh->ether_dhost));
eh->ether_type = htons(ETHERTYPE_AARP);
ea->aarp_spa = AA_SAT(aa)->sat_addr.s_node;
ea->aarp_tpa = sat->sat_addr.s_node;
}
#ifdef NETATALKDEBUG
printf("aarp: sending request for %u.%u\n",
ntohs(AA_SAT(aa)->sat_addr.s_net), AA_SAT(aa)->sat_addr.s_node);
#endif /* NETATALKDEBUG */
ifa_free(&aa->aa_ifa);
sa.sa_len = sizeof(struct sockaddr);
sa.sa_family = AF_UNSPEC;
ifp->if_output(ifp, m, &sa, NULL);
}
int
aarpresolve(struct ifnet *ifp, struct mbuf *m,
const struct sockaddr_at *destsat, u_char *desten)
{
struct at_ifaddr *aa;
struct aarptab *aat;
AT_IFADDR_RLOCK();
if (at_broadcast(destsat)) {
m->m_flags |= M_BCAST;
if ((aa = at_ifawithnet_locked(destsat)) == NULL) {
AT_IFADDR_RUNLOCK();
m_freem(m);
return (0);
}
if (aa->aa_flags & AFA_PHASE2)
bcopy(atmulticastaddr, (caddr_t)desten,
sizeof(atmulticastaddr));
else
bcopy(ifp->if_broadcastaddr, (caddr_t)desten,
sizeof(ifp->if_addrlen));
AT_IFADDR_RUNLOCK();
return (1);
}
AT_IFADDR_RUNLOCK();
AARPTAB_LOCK();
AARPTAB_LOOK(aat, destsat->sat_addr);
if (aat == NULL) {
/* No entry. */
aat = aarptnew(&destsat->sat_addr);
/* We should fail more gracefully. */
if (aat == NULL)
panic("aarpresolve: no free entry");
goto done;
}
/* 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));
AARPTAB_UNLOCK();
return (1);
}
/* Entry has not completed. */
if (aat->aat_hold)
m_freem(aat->aat_hold);
done:
aat->aat_hold = m;
AARPTAB_UNLOCK();
aarpwhohas(ifp, destsat);
return (0);
}
void
aarpintr(struct mbuf *m)
{
struct arphdr *ar;
struct ifnet *ifp;
ifp = m->m_pkthdr.rcvif;
if (ifp->if_flags & IFF_NOARP)
goto out;
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(ifp, m);
return;
default:
break;
}
out:
m_freem(m);
}
static void
at_aarpinput(struct ifnet *ifp, struct mbuf *m)
{
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;
u_short net;
ea = mtod(m, struct ether_aarp *);
/* Check to see if from my hardware address. */
if (!bcmp((caddr_t)ea->aarp_sha, IF_LLADDR(ifp), ETHER_ADDR_LEN)) {
m_freem(m);
return;
}
/* Don't accept requests from broadcast address. */
if (!bcmp(ea->aarp_sha, ifp->if_broadcastaddr, ifp->if_addrlen)) {
log(LOG_ERR, "aarp: source link address is broadcast\n");
m_freem(m);
return;
}
op = ntohs(ea->aarp_op);
bcopy(ea->aarp_tpnet, &net, sizeof(net));
if (net != 0) {
/* Should be ATADDR_ANYNET? */
sat.sat_len = sizeof(struct sockaddr_at);
sat.sat_family = AF_APPLETALK;
sat.sat_addr.s_net = net;
aa = at_ifawithnet(&sat);
if (aa == 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.
*/
IF_ADDR_RLOCK(ifp);
for (aa = (struct at_ifaddr *)TAILQ_FIRST(&ifp->if_addrhead);
aa;
aa = (struct at_ifaddr *)aa->aa_ifa.ifa_link.tqe_next) {
if (AA_SAT(aa)->sat_family == AF_APPLETALK &&
(aa->aa_flags & AFA_PHASE2) == 0) {
break;
}
}
if (aa == NULL) {
IF_ADDR_RUNLOCK(ifp);
m_freem(m);
return;
}
ifa_ref(&aa->aa_ifa);
IF_ADDR_RUNLOCK(ifp);
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.
*/
callout_stop(&aa->aa_callout);
wakeup(aa);
ifa_free(&aa->aa_ifa);
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.
*/
ifa_free(&aa->aa_ifa);
log(LOG_ERR,
"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]);
m_freem(m);
return;
}
}
AARPTAB_LOCK();
AARPTAB_LOOK(aat, spa);
if (aat != NULL) {
if (op == AARPOP_PROBE) {
/*
* Someone's probing for spa, deallocate the one we've
* got, so that if the prober keeps the address,
* we'll be able to arp for him.
*/
aarptfree(aat);
AARPTAB_UNLOCK();
ifa_free(&aa->aa_ifa);
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) {
struct mbuf *mhold = aat->aat_hold;
aat->aat_hold = NULL;
AARPTAB_UNLOCK();
sat.sat_len = sizeof(struct sockaddr_at);
sat.sat_family = AF_APPLETALK;
sat.sat_addr = spa;
(*ifp->if_output)(ifp, mhold,
(struct sockaddr *)&sat, NULL); /* XXX */
} else
AARPTAB_UNLOCK();
} else if ((tpa.s_net == ma.s_net) && (tpa.s_node == ma.s_node)
&& (op != AARPOP_PROBE) && ((aat = aarptnew(&spa)) != NULL)) {
bcopy((caddr_t)ea->aarp_sha, (caddr_t)aat->aat_enaddr,
sizeof(ea->aarp_sha));
aat->aat_flags |= ATF_COM;
AARPTAB_UNLOCK();
} else
AARPTAB_UNLOCK();
/*
* 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)) {
ifa_free(&aa->aa_ifa);
m_freem(m);
return;
}
bcopy((caddr_t)ea->aarp_sha, (caddr_t)ea->aarp_tha,
sizeof(ea->aarp_sha));
bcopy(IF_LLADDR(ifp), (caddr_t)ea->aarp_sha, sizeof(ea->aarp_sha));
/* XXX */
eh = (struct ether_header *)sa.sa_data;
bcopy((caddr_t)ea->aarp_tha, (caddr_t)eh->ether_dhost,
sizeof(eh->ether_dhost));
if (aa->aa_flags & AFA_PHASE2) {
eh->ether_type = htons(sizeof(struct llc) +
sizeof(struct ether_aarp));
M_PREPEND(m, sizeof(struct llc), M_NOWAIT);
if (m == NULL) {
ifa_free(&aa->aa_ifa);
return;
}
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
eh->ether_type = htons(ETHERTYPE_AARP);
ifa_free(&aa->aa_ifa);
ea->aarp_tpnode = ea->aarp_spnode;
ea->aarp_spnode = ma.s_node;
ea->aarp_op = htons(AARPOP_RESPONSE);
sa.sa_len = sizeof(struct sockaddr);
sa.sa_family = AF_UNSPEC;
(*ifp->if_output)(ifp, m, &sa, NULL); /* XXX */
return;
}
static void
aarptfree(struct aarptab *aat)
{
AARPTAB_LOCK_ASSERT();
if (aat->aat_hold)
m_freem(aat->aat_hold);
aat->aat_hold = NULL;
aat->aat_timer = aat->aat_flags = 0;
aat->aat_ataddr.s_net = 0;
aat->aat_ataddr.s_node = 0;
}
struct aarptab *
aarptnew(const struct at_addr *addr)
{
int n;
int oldest = -1;
struct aarptab *aat, *aato = NULL;
static int first = 1;
AARPTAB_LOCK_ASSERT();
if (first) {
first = 0;
aarptimer_ch = 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);
}
void
aarpprobe(void *arg)
{
struct ifnet *ifp = arg;
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.
*/
AARPTAB_LOCK();
for (aa = (struct at_ifaddr *)TAILQ_FIRST(&ifp->if_addrhead); aa;
aa = (struct at_ifaddr *)aa->aa_ifa.ifa_link.tqe_next) {
if (AA_SAT(aa)->sat_family == AF_APPLETALK &&
(aa->aa_flags & AFA_PROBING))
break;
}
if (aa == NULL) {
/* Serious error XXX. */
AARPTAB_UNLOCK();
printf("aarpprobe why did this happen?!\n");
return;
}
if (aa->aa_probcnt <= 0) {
aa->aa_flags &= ~AFA_PROBING;
wakeup(aa);
AARPTAB_UNLOCK();
return;
} else
callout_reset(&aa->aa_callout, hz / 5, aarpprobe, ifp);
ifa_ref(&aa->aa_ifa);
AARPTAB_UNLOCK();
m = m_gethdr(M_NOWAIT, MT_DATA);
if (m == NULL) {
ifa_free(&aa->aa_ifa);
return;
}
#ifdef MAC
mac_netatalk_aarp_send(ifp, m);
#endif
m->m_len = sizeof(*ea);
m->m_pkthdr.len = sizeof(*ea);
MH_ALIGN(m, sizeof(*ea));
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);
bcopy(IF_LLADDR(ifp), (caddr_t)ea->aarp_sha,
sizeof(ea->aarp_sha));
eh = (struct ether_header *)sa.sa_data;
if (aa->aa_flags & AFA_PHASE2) {
bcopy(atmulticastaddr, eh->ether_dhost,
sizeof(eh->ether_dhost));
eh->ether_type = htons(sizeof(struct llc) +
sizeof(struct ether_aarp));
M_PREPEND(m, sizeof(struct llc), M_WAITOK);
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 {
bcopy(ifp->if_broadcastaddr, (caddr_t)eh->ether_dhost,
sizeof(eh->ether_dhost));
eh->ether_type = htons(ETHERTYPE_AARP);
ea->aarp_spa = ea->aarp_tpa = AA_SAT(aa)->sat_addr.s_node;
}
#ifdef NETATALKDEBUG
printf("aarp: sending probe for %u.%u\n",
ntohs(AA_SAT(aa)->sat_addr.s_net), AA_SAT(aa)->sat_addr.s_node);
#endif /* NETATALKDEBUG */
ifa_free(&aa->aa_ifa);
sa.sa_len = sizeof(struct sockaddr);
sa.sa_family = AF_UNSPEC;
(*ifp->if_output)(ifp, m, &sa, NULL); /* XXX */
aa->aa_probcnt--;
}
void
aarp_clean(void)
{
struct aarptab *aat;
int i;
untimeout(aarptimer, 0, aarptimer_ch);
AARPTAB_LOCK();
for (i = 0, aat = aarptab; i < AARPTAB_SIZE; i++, aat++) {
if (aat->aat_hold) {
m_freem(aat->aat_hold);
aat->aat_hold = NULL;
}
}
AARPTAB_UNLOCK();
}

View file

@ -1,86 +0,0 @@
/*-
* 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.
*
* This product includes software developed by the University of
* California, Berkeley and its contributors.
*
* 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
*
* $FreeBSD$
*/
#ifndef _NETATALK_AARP_H_
#define _NETATALK_AARP_H_
/*
* 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;
} __packed 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;
} __packed;
#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(const struct at_addr *);
#endif
#endif /* _NETATALK_AARP_H_ */

View file

@ -1,86 +0,0 @@
/*-
* 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
*
* $FreeBSD$
*/
#ifndef _NETATALK_AT_H_
#define _NETATALK_AT_H_
/*
* Supported protocols
*/
#define ATPROTO_DDP 0
#define ATPROTO_AARP 254
#define DDP_MAXSZ 587
/*
* If ATPORT_FIRST <= Port < ATPORT_RESERVED, the port was created by a
* privileged process.
*
* If ATPORT_RESERVED <= Port < ATPORT_LAST, the port was not necessarily
* created by a privileged process.
*/
#define ATPORT_FIRST 1
#define ATPORT_RESERVED 128
#define ATPORT_LAST 255
/*
* AppleTalk address.
*/
struct at_addr {
u_short s_net;
u_char s_node;
};
#define ATADDR_ANYNET (u_short)0x0000
#define ATADDR_ANYNODE (u_char)0x00
#define ATADDR_ANYPORT (u_char)0x00
#define ATADDR_BCAST (u_char)0xff /* There is no BCAST for NET. */
struct netrange {
u_char nr_phase;
u_short nr_firstnet;
u_short nr_lastnet;
};
/*
* Socket address, AppleTalk style. We keep magic information in the zero
* bytes. There are three types, NONE, CONFIG which has the phase and a net
* range, and IFACE which has the network address of an interface. IFACE may
* be filled in by the client, and is filled in by the kernel.
*/
struct sockaddr_at {
u_char sat_len;
u_char sat_family;
u_char sat_port;
struct at_addr sat_addr;
union {
struct netrange r_netrange;
char r_zero[8]; /* Hide struct netrange here. */
} sat_range;
};
#define sat_zero sat_range.r_zero
#endif /* !_NETATALK_AT_H_ */

View file

@ -1,881 +0,0 @@
/*-
* Copyright (c) 1990,1991 Regents of The University of Michigan.
* Copyright (c) 2009 Robert N. M. Watson
* 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.
*
* 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
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/sockio.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/kernel.h>
#include <sys/priv.h>
#include <sys/rwlock.h>
#include <sys/socket.h>
#include <net/if.h>
#include <net/if_var.h>
#include <net/route.h>
#include <netinet/in.h>
#undef s_net
#include <netinet/if_ether.h>
#include <netatalk/at.h>
#include <netatalk/at_var.h>
#include <netatalk/at_extern.h>
struct rwlock at_ifaddr_rw;
struct at_ifaddrhead at_ifaddrhead;
RW_SYSINIT(at_ifaddr_rw, &at_ifaddr_rw, "at_ifaddr_rw");
static int aa_dorangeroute(struct ifaddr *ifa, u_int first, u_int last,
int cmd);
static int aa_addsingleroute(struct ifaddr *ifa, struct at_addr *addr,
struct at_addr *mask);
static int aa_delsingleroute(struct ifaddr *ifa, struct at_addr *addr,
struct at_addr *mask);
static int aa_dosingleroute(struct ifaddr *ifa, struct at_addr *addr,
struct at_addr *mask, int cmd, int flags);
static int at_scrub(struct ifnet *ifp, struct at_ifaddr *aa);
static int at_ifinit(struct ifnet *ifp, struct at_ifaddr *aa,
struct sockaddr_at *sat);
static int aa_claim_addr(struct ifaddr *ifa, struct sockaddr *gw);
#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)
int
at_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp,
struct thread *td)
{
struct ifreq *ifr = (struct ifreq *)data;
struct sockaddr_at *sat;
struct netrange *nr;
struct at_aliasreq *ifra = (struct at_aliasreq *)data;
struct at_ifaddr *aa;
struct ifaddr *ifa;
int error;
/*
* If we have an ifp, then find the matching at_ifaddr if it exists
*/
aa = NULL;
AT_IFADDR_RLOCK();
if (ifp != NULL) {
TAILQ_FOREACH(aa, &at_ifaddrhead, aa_link) {
if (aa->aa_ifp == ifp)
break;
}
}
if (aa != NULL)
ifa_ref(&aa->aa_ifa);
AT_IFADDR_RUNLOCK();
/*
* In this first switch table we are basically getting ready for
* the second one, by getting the atalk-specific things set up
* so that they start to look more similar to other protocols etc.
*/
error = 0;
switch (cmd) {
case SIOCAIFADDR:
case SIOCDIFADDR:
/*
* If we have an appletalk sockaddr, scan forward of where we
* are now on the at_ifaddr list to find one with a matching
* address on this interface. This may leave aa pointing to
* the first address on the NEXT interface!
*/
if (ifra->ifra_addr.sat_family == AF_APPLETALK) {
struct at_ifaddr *oaa;
AT_IFADDR_RLOCK();
for (oaa = aa; aa; aa = TAILQ_NEXT(aa, aa_link)) {
if (aa->aa_ifp == ifp &&
sateqaddr(&aa->aa_addr, &ifra->ifra_addr))
break;
}
if (oaa != NULL && oaa != aa)
ifa_free(&oaa->aa_ifa);
if (aa != NULL && oaa != aa)
ifa_ref(&aa->aa_ifa);
AT_IFADDR_RUNLOCK();
}
/*
* If we a retrying to delete an addres but didn't find such,
* then rewurn with an error
*/
if (cmd == SIOCDIFADDR && aa == NULL) {
error = EADDRNOTAVAIL;
goto out;
}
/*FALLTHROUGH*/
case SIOCSIFADDR:
/*
* If we are not superuser, then we don't get to do these ops.
*
* XXXRW: Layering?
*/
if (priv_check(td, PRIV_NET_ADDIFADDR)) {
error = EPERM;
goto out;
}
sat = satosat(&ifr->ifr_addr);
nr = (struct netrange *)sat->sat_zero;
if (nr->nr_phase == 1) {
struct at_ifaddr *oaa;
/*
* Look for a phase 1 address on this interface.
* This may leave aa pointing to the first address on
* the NEXT interface!
*/
AT_IFADDR_RLOCK();
for (oaa = aa; aa; aa = TAILQ_NEXT(aa, aa_link)) {
if (aa->aa_ifp == ifp &&
(aa->aa_flags & AFA_PHASE2) == 0)
break;
}
if (oaa != NULL && oaa != aa)
ifa_free(&oaa->aa_ifa);
if (aa != NULL && oaa != aa)
ifa_ref(&aa->aa_ifa);
AT_IFADDR_RUNLOCK();
} else { /* default to phase 2 */
struct at_ifaddr *oaa;
/*
* Look for a phase 2 address on this interface.
* This may leave aa pointing to the first address on
* the NEXT interface!
*/
AT_IFADDR_RLOCK();
for (oaa = aa; aa; aa = TAILQ_NEXT(aa, aa_link)) {
if (aa->aa_ifp == ifp && (aa->aa_flags &
AFA_PHASE2))
break;
}
if (oaa != NULL && oaa != aa)
ifa_free(&oaa->aa_ifa);
if (aa != NULL && oaa != aa)
ifa_ref(&aa->aa_ifa);
AT_IFADDR_RUNLOCK();
}
if (ifp == NULL)
panic("at_control");
/*
* If we failed to find an existing at_ifaddr entry, then we
* allocate a fresh one.
*/
if (aa == NULL) {
ifa = ifa_alloc(sizeof(struct at_ifaddr), M_WAITOK);
aa = (struct at_ifaddr *)ifa;
callout_init(&aa->aa_callout, CALLOUT_MPSAFE);
/*
* As the at_ifaddr contains the actual sockaddrs,
* and the ifaddr itself, link them all together
* correctly.
*/
ifa->ifa_addr = (struct sockaddr *)&aa->aa_addr;
ifa->ifa_dstaddr = (struct sockaddr *)&aa->aa_addr;
ifa->ifa_netmask = (struct sockaddr *)&aa->aa_netmask;
/*
* Set/clear the phase 2 bit.
*/
if (nr->nr_phase == 1)
aa->aa_flags &= ~AFA_PHASE2;
else
aa->aa_flags |= AFA_PHASE2;
ifa_ref(&aa->aa_ifa); /* at_ifaddrhead */
AT_IFADDR_WLOCK();
if (!TAILQ_EMPTY(&at_ifaddrhead)) {
/*
* Don't let the loopback be first, since the
* first address is the machine's default
* address for binding. If it is, stick
* ourself in front, otherwise go to the back
* of the list.
*/
if (TAILQ_FIRST(&at_ifaddrhead)->aa_ifp->
if_flags & IFF_LOOPBACK)
TAILQ_INSERT_HEAD(&at_ifaddrhead, aa,
aa_link);
else
TAILQ_INSERT_TAIL(&at_ifaddrhead, aa,
aa_link);
} else
TAILQ_INSERT_HEAD(&at_ifaddrhead, aa,
aa_link);
AT_IFADDR_WUNLOCK();
/*
* and link it all together
*/
aa->aa_ifp = ifp;
ifa_ref(&aa->aa_ifa); /* if_addrhead */
IF_ADDR_WLOCK(ifp);
TAILQ_INSERT_TAIL(&ifp->if_addrhead, ifa, ifa_link);
IF_ADDR_WUNLOCK(ifp);
} else {
/*
* If we DID find one then we clobber any routes
* dependent on it..
*/
at_scrub(ifp, aa);
}
break;
case SIOCGIFADDR :
sat = satosat(&ifr->ifr_addr);
nr = (struct netrange *)sat->sat_zero;
if (nr->nr_phase == 1) {
struct at_ifaddr *oaa;
/*
* If the request is specifying phase 1, then
* only look at a phase one address
*/
AT_IFADDR_RLOCK();
for (oaa = aa; aa; aa = TAILQ_NEXT(aa, aa_link)) {
if (aa->aa_ifp == ifp &&
(aa->aa_flags & AFA_PHASE2) == 0)
break;
}
if (oaa != NULL && oaa != aa)
ifa_free(&oaa->aa_ifa);
if (aa != NULL && oaa != aa)
ifa_ref(&aa->aa_ifa);
AT_IFADDR_RUNLOCK();
} else {
struct at_ifaddr *oaa;
/*
* default to phase 2
*/
AT_IFADDR_RLOCK();
for (oaa = aa; aa; aa = TAILQ_NEXT(aa, aa_link)) {
if (aa->aa_ifp == ifp && (aa->aa_flags &
AFA_PHASE2))
break;
}
if (oaa != NULL && oaa != aa)
ifa_free(&oaa->aa_ifa);
if (aa != NULL && oaa != aa)
ifa_ref(&aa->aa_ifa);
AT_IFADDR_RUNLOCK();
}
if (aa == NULL) {
error = EADDRNOTAVAIL;
goto out;
}
break;
}
/*
* By the time this switch is run we should be able to assume that
* the "aa" pointer is valid when needed.
*/
switch (cmd) {
case SIOCGIFADDR:
/*
* copy the contents of the sockaddr blindly.
*/
sat = (struct sockaddr_at *)&ifr->ifr_addr;
*sat = aa->aa_addr;
/*
* and do some cleanups
*/
((struct netrange *)&sat->sat_zero)->nr_phase
= (aa->aa_flags & AFA_PHASE2) ? 2 : 1;
((struct netrange *)&sat->sat_zero)->nr_firstnet =
aa->aa_firstnet;
((struct netrange *)&sat->sat_zero)->nr_lastnet =
aa->aa_lastnet;
break;
case SIOCSIFADDR:
error = at_ifinit(ifp, aa,
(struct sockaddr_at *)&ifr->ifr_addr);
goto out;
case SIOCAIFADDR:
if (sateqaddr(&ifra->ifra_addr, &aa->aa_addr)) {
error = 0;
goto out;
}
error = at_ifinit(ifp, aa,
(struct sockaddr_at *)&ifr->ifr_addr);
goto out;
case SIOCDIFADDR:
/*
* remove the ifaddr from the interface
*/
ifa = (struct ifaddr *)aa;
IF_ADDR_WLOCK(ifp);
TAILQ_REMOVE(&ifp->if_addrhead, ifa, ifa_link);
IF_ADDR_WUNLOCK(ifp);
ifa_free(ifa); /* if_addrhead */
/*
* Now remove the at_ifaddr from the parallel structure
* as well, or we'd be in deep trouble
*/
AT_IFADDR_WLOCK();
TAILQ_REMOVE(&at_ifaddrhead, aa, aa_link);
AT_IFADDR_WUNLOCK();
ifa_free(ifa); /* at_ifaddrhead */
break;
default:
if (ifp == NULL || ifp->if_ioctl == NULL) {
error = EOPNOTSUPP;
goto out;
}
error = ((*ifp->if_ioctl)(ifp, cmd, data));
}
out:
if (aa != NULL)
ifa_free(&aa->aa_ifa);
return (error);
}
/*
* Given an interface and an at_ifaddr (supposedly on that interface)
* remove any routes that depend on this.
* Why ifp is needed I'm not sure,
* as aa->at_ifaddr.ifa_ifp should be the same.
*/
static int
at_scrub(struct ifnet *ifp, struct at_ifaddr *aa)
{
int error;
if (aa->aa_flags & AFA_ROUTE) {
if (ifp->if_flags & IFF_LOOPBACK) {
if ((error = aa_delsingleroute(&aa->aa_ifa,
&aa->aa_addr.sat_addr, &aa->aa_netmask.sat_addr))
!= 0)
return (error);
} else if (ifp->if_flags & IFF_POINTOPOINT) {
if ((error = rtinit(&aa->aa_ifa, RTM_DELETE,
RTF_HOST)) != 0)
return (error);
} else if (ifp->if_flags & IFF_BROADCAST) {
error = aa_dorangeroute(&aa->aa_ifa,
ntohs(aa->aa_firstnet), ntohs(aa->aa_lastnet),
RTM_DELETE);
}
aa->aa_ifa.ifa_flags &= ~IFA_ROUTE;
aa->aa_flags &= ~AFA_ROUTE;
}
return (0);
}
/*
* given an at_ifaddr,a sockaddr_at and an ifp,
* bang them all together at high speed and see what happens
*/
static int
at_ifinit(struct ifnet *ifp, struct at_ifaddr *aa, struct sockaddr_at *sat)
{
struct netrange nr, onr;
struct sockaddr_at oldaddr;
int error = 0, i, j;
int netinc, nodeinc, nnets;
u_short net;
/*
* save the old addresses in the at_ifaddr just in case we need them.
*/
oldaddr = aa->aa_addr;
onr.nr_firstnet = aa->aa_firstnet;
onr.nr_lastnet = aa->aa_lastnet;
/*
* take the address supplied as an argument, and add it to the
* at_ifnet (also given). Remember ing to update
* those parts of the at_ifaddr that need special processing
*/
bzero(AA_SAT(aa), sizeof(struct sockaddr_at));
bcopy(sat->sat_zero, &nr, sizeof(struct netrange));
bcopy(sat->sat_zero, AA_SAT(aa)->sat_zero, sizeof(struct netrange));
nnets = ntohs(nr.nr_lastnet) - ntohs(nr.nr_firstnet) + 1;
aa->aa_firstnet = nr.nr_firstnet;
aa->aa_lastnet = nr.nr_lastnet;
/* XXX ALC */
#if 0
printf("at_ifinit: %s: %u.%u range %u-%u phase %d\n",
ifp->if_name,
ntohs(sat->sat_addr.s_net), sat->sat_addr.s_node,
ntohs(aa->aa_firstnet), ntohs(aa->aa_lastnet),
(aa->aa_flags & AFA_PHASE2) ? 2 : 1);
#endif
/*
* 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) {
AA_SAT(aa)->sat_len = sat->sat_len;
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;
#if 0
} else if (fp->if_flags & IFF_POINTOPOINT) {
/* unimplemented */
/*
* we'd have to copy the dstaddr field over from the sat
* but it's not clear that it would contain the right info..
*/
#endif
} else {
/*
* We are a normal (probably ethernet) interface.
* apply the new address to the interface structures etc.
* We will probe this address on the net first, before
* applying it to ensure that it is free.. If it is not, then
* we will try a number of other randomly generated addresses
* in this net and then increment the net. etc.etc. until
* we find an unused address.
*/
aa->aa_flags |= AFA_PROBING; /* not loopback we Must probe? */
AA_SAT(aa)->sat_len = sizeof(struct sockaddr_at);
AA_SAT(aa)->sat_family = AF_APPLETALK;
if (aa->aa_flags & AFA_PHASE2) {
if (sat->sat_addr.s_net == ATADDR_ANYNET) {
/*
* If we are phase 2, and the net was not
* specified then we select a random net
* within the supplied netrange.
* XXX use /dev/random?
*/
if (nnets != 1)
net = ntohs(nr.nr_firstnet) +
time_second % (nnets - 1);
else
net = ntohs(nr.nr_firstnet);
} else {
/*
* if a net was supplied, then check that it
* is within the netrange. If it is not then
* replace the old values and return an error
*/
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);
}
/*
* otherwise just use the new net number..
*/
net = ntohs(sat->sat_addr.s_net);
}
} else {
/*
* we must be phase one, so just use whatever we were
* given. I guess it really isn't going to be
* used... RIGHT?
*/
net = ntohs(sat->sat_addr.s_net);
}
/*
* set the node part of the address into the ifaddr.
* If it's not specified, be random about it...
* XXX use /dev/random?
*/
if (sat->sat_addr.s_node == ATADDR_ANYNODE)
AA_SAT(aa)->sat_addr.s_node = time_second;
else
AA_SAT(aa)->sat_addr.s_node = sat->sat_addr.s_node;
/*
* Copy the phase.
*/
AA_SAT(aa)->sat_range.r_netrange.nr_phase =
((aa->aa_flags & AFA_PHASE2) ? 2:1);
/*
* step through the nets in the range
* starting at the (possibly random) start point.
*/
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);
/*
* using a rather strange stepping method,
* stagger through the possible node addresses
* Once again, starting at the (possibly random)
* initial node address.
*/
for (j = 0, nodeinc = time_second | 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;
/*
* start off the probes as an asynchronous
* activity. though why wait 200mSec?
*/
AARPTAB_LOCK();
callout_reset(&aa->aa_callout, hz / 5,
aarpprobe, ifp);
if (msleep(aa, &aarptab_mtx, PPAUSE|PCATCH,
"at_ifinit", 0)) {
AARPTAB_UNLOCK();
/*
* theoretically we shouldn't time
* out here so if we returned with an
* error..
*/
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);
}
AARPTAB_UNLOCK();
/*
* The async activity should have woken us
* up. We need to see if it was successful
* in finding a free spot, or if we need to
* iterate to the next address to try.
*/
if ((aa->aa_flags & AFA_PROBING) == 0)
break;
}
/*
* of course we need to break out through two loops...
*/
if ((aa->aa_flags & AFA_PROBING) == 0)
break;
/* reset node for next network */
AA_SAT(aa)->sat_addr.s_node = time_second;
}
/*
* if we are still trying to probe, then we have finished all
* the possible addresses, so we need to give up
*/
if (aa->aa_flags & AFA_PROBING) {
aa->aa_addr = oldaddr;
aa->aa_firstnet = onr.nr_firstnet;
aa->aa_lastnet = onr.nr_lastnet;
return (EADDRINUSE);
}
}
/*
* Now that we have selected an address, we need to tell the interface
* about it, just in case it needs to adjust something.
*/
if (ifp->if_ioctl != NULL &&
(error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, (caddr_t)aa))) {
/*
* of course this could mean that it objects violently
* so if it does, we back out again..
*/
aa->aa_addr = oldaddr;
aa->aa_firstnet = onr.nr_firstnet;
aa->aa_lastnet = onr.nr_lastnet;
return (error);
}
/*
* set up the netmask part of the at_ifaddr
* and point the appropriate pointer in the ifaddr to it.
* probably pointless, but what the heck.. XXX
*/
bzero(&aa->aa_netmask, sizeof(aa->aa_netmask));
aa->aa_netmask.sat_len = sizeof(struct sockaddr_at);
aa->aa_netmask.sat_family = AF_APPLETALK;
aa->aa_netmask.sat_addr.s_net = 0xffff;
aa->aa_netmask.sat_addr.s_node = 0;
aa->aa_ifa.ifa_netmask =(struct sockaddr *) &(aa->aa_netmask); /* XXX */
/*
* Initialize broadcast (or remote p2p) address
*/
bzero(&aa->aa_broadaddr, sizeof(aa->aa_broadaddr));
aa->aa_broadaddr.sat_len = sizeof(struct sockaddr_at);
aa->aa_broadaddr.sat_family = AF_APPLETALK;
aa->aa_ifa.ifa_metric = ifp->if_metric;
if (ifp->if_flags & IFF_BROADCAST) {
aa->aa_broadaddr.sat_addr.s_net = htons(0);
aa->aa_broadaddr.sat_addr.s_node = 0xff;
aa->aa_ifa.ifa_broadaddr = (struct sockaddr *)
&aa->aa_broadaddr;
/* add the range of routes needed */
error = aa_dorangeroute(&aa->aa_ifa, ntohs(aa->aa_firstnet),
ntohs(aa->aa_lastnet), RTM_ADD);
} else if (ifp->if_flags & IFF_POINTOPOINT) {
struct at_addr rtaddr, rtmask;
bzero(&rtaddr, sizeof(rtaddr));
bzero(&rtmask, sizeof(rtmask));
/* fill in the far end if we know it here XXX */
aa->aa_ifa.ifa_dstaddr = (struct sockaddr *) &aa->aa_dstaddr;
error = aa_addsingleroute(&aa->aa_ifa, &rtaddr, &rtmask);
} else if (ifp->if_flags & IFF_LOOPBACK) {
struct at_addr rtaddr, rtmask;
bzero(&rtaddr, sizeof(rtaddr));
bzero(&rtmask, sizeof(rtmask));
rtaddr.s_net = AA_SAT(aa)->sat_addr.s_net;
rtaddr.s_node = AA_SAT(aa)->sat_addr.s_node;
rtmask.s_net = 0xffff;
/* XXX should not be so.. should be HOST route */
rtmask.s_node = 0x0;
error = aa_addsingleroute(&aa->aa_ifa, &rtaddr, &rtmask);
}
/*
* set the address of our "check if this addr is ours" routine.
*/
aa->aa_ifa.ifa_claim_addr = aa_claim_addr;
/*
* of course if we can't add these routes we back out, but it's
* getting risky by now XXX
*/
if (error) {
at_scrub(ifp, aa);
aa->aa_addr = oldaddr;
aa->aa_firstnet = onr.nr_firstnet;
aa->aa_lastnet = onr.nr_lastnet;
return (error);
}
/*
* note that the address has a route associated with it....
*/
aa->aa_ifa.ifa_flags |= IFA_ROUTE;
aa->aa_flags |= AFA_ROUTE;
return (0);
}
/*
* check whether a given address is a broadcast address for us..
*/
int
at_broadcast(const struct sockaddr_at *sat)
{
struct at_ifaddr *aa;
AT_IFADDR_LOCK_ASSERT();
/*
* If the node is not right, it can't be a broadcast
*/
if (sat->sat_addr.s_node != ATADDR_BCAST)
return (0);
/*
* If the node was right then if the net is right, it's a broadcast
*/
if (sat->sat_addr.s_net == ATADDR_ANYNET)
return (1);
/*
* failing that, if the net is one we have, it's a broadcast as well.
*/
TAILQ_FOREACH(aa, &at_ifaddrhead, aa_link) {
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_dorangeroute()
*
* Add a route for a range of networks from bot to top - 1.
* Algorithm:
*
* Split the range into two subranges such that the middle
* of the two ranges is the point where the highest bit of difference
* between the two addresses makes its transition.
* Each of the upper and lower ranges might not exist, or might be
* representable by 1 or more netmasks. In addition, if both
* ranges can be represented by the same netmask, then they can be merged
* by using the next higher netmask..
*/
static int
aa_dorangeroute(struct ifaddr *ifa, u_int bot, u_int top, int cmd)
{
u_int mask1;
struct at_addr addr;
struct at_addr mask;
int error;
/*
* slight sanity check
*/
if (bot > top) return (EINVAL);
addr.s_node = 0;
mask.s_node = 0;
/*
* just start out with the lowest boundary
* and keep extending the mask till it's too big.
*/
while (bot <= top) {
mask1 = 1;
while (((bot & ~mask1) >= bot) && ((bot | mask1) <= top)) {
mask1 <<= 1;
mask1 |= 1;
}
mask1 >>= 1;
mask.s_net = htons(~mask1);
addr.s_net = htons(bot);
if (cmd == RTM_ADD) {
error = aa_addsingleroute(ifa,&addr,&mask);
if (error) {
/* XXX clean up? */
return (error);
}
} else
error = aa_delsingleroute(ifa,&addr,&mask);
bot = (bot | mask1) + 1;
}
return (0);
}
static int
aa_addsingleroute(struct ifaddr *ifa, struct at_addr *addr,
struct at_addr *mask)
{
#if 0
printf("aa_addsingleroute: %x.%x mask %x.%x ...\n",
ntohs(addr->s_net), addr->s_node, ntohs(mask->s_net),
mask->s_node);
#endif
return (aa_dosingleroute(ifa, addr, mask, RTM_ADD, RTF_UP));
}
static int
aa_delsingleroute(struct ifaddr *ifa, struct at_addr *addr,
struct at_addr *mask)
{
return (aa_dosingleroute(ifa, addr, mask, RTM_DELETE, 0));
}
static int
aa_dosingleroute(struct ifaddr *ifa, struct at_addr *at_addr,
struct at_addr *at_mask, int cmd, int flags)
{
struct sockaddr_at addr, mask;
bzero(&addr, sizeof(addr));
bzero(&mask, sizeof(mask));
addr.sat_family = AF_APPLETALK;
addr.sat_len = sizeof(struct sockaddr_at);
addr.sat_addr.s_net = at_addr->s_net;
addr.sat_addr.s_node = at_addr->s_node;
mask.sat_family = AF_APPLETALK;
mask.sat_len = sizeof(struct sockaddr_at);
mask.sat_addr.s_net = at_mask->s_net;
mask.sat_addr.s_node = at_mask->s_node;
if (at_mask->s_node)
flags |= RTF_HOST;
return (rtrequest(cmd, (struct sockaddr *) &addr,
(flags & RTF_HOST)?(ifa->ifa_dstaddr):(ifa->ifa_addr),
(struct sockaddr *) &mask, flags, NULL));
}
static int
aa_claim_addr(struct ifaddr *ifa, struct sockaddr *gw0)
{
struct sockaddr_at *addr = (struct sockaddr_at *)ifa->ifa_addr;
struct sockaddr_at *gw = (struct sockaddr_at *)gw0;
switch (gw->sat_range.r_netrange.nr_phase) {
case 1:
if(addr->sat_range.r_netrange.nr_phase == 1)
return (1);
case 0:
case 2:
/*
* if it's our net (including 0),
* or netranges are valid, and we are in the range,
* then it's ours.
*/
if ((addr->sat_addr.s_net == gw->sat_addr.s_net)
|| ((addr->sat_range.r_netrange.nr_lastnet)
&& (ntohs(gw->sat_addr.s_net) >=
ntohs(addr->sat_range.r_netrange.nr_firstnet))
&& (ntohs(gw->sat_addr.s_net) <=
ntohs(addr->sat_range.r_netrange.nr_lastnet))))
return (1);
break;
default:
printf("atalk: bad phase\n");
}
return (0);
}

View file

@ -1,67 +0,0 @@
/*-
* Copyright (c) 1990,1994 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.
*
* 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
*
* $FreeBSD$
*/
#ifndef _NETATALK_AT_EXTERN_H_
#define _NETATALK_AT_EXTERN_H_
extern struct mtx aarptab_mtx;
#define AARPTAB_LOCK() mtx_lock(&aarptab_mtx)
#define AARPTAB_UNLOCK() mtx_unlock(&aarptab_mtx)
#define AARPTAB_LOCK_ASSERT() mtx_assert(&aarptab_mtx, MA_OWNED)
#define AARPTAB_UNLOCK_ASSERT() mtx_assert(&aarptab_mtx, MA_NOTOWNED)
struct at_ifaddr;
struct ifnet;
struct mbuf;
struct route;
struct thread;
struct sockaddr_at;
struct socket;
void aarpintr(struct mbuf *);
void aarpprobe(void *arg);
int aarpresolve(struct ifnet *, struct mbuf *,
const struct sockaddr_at *, u_char *);
void aarp_clean(void);
void at1intr(struct mbuf *);
void at2intr(struct mbuf *);
int at_broadcast(const struct sockaddr_at *);
u_short at_cksum(struct mbuf *m, int skip);
int at_control(struct socket *so, u_long cmd, caddr_t data,
struct ifnet *ifp, struct thread *td);
struct at_ifaddr *at_ifawithnet(const struct sockaddr_at *);
struct at_ifaddr *at_ifawithnet_locked(const struct sockaddr_at *sat);
int at_inithead(void**, int);
void ddp_init(void);
int ddp_output(struct mbuf *m, struct socket *so);
int ddp_route(struct mbuf *m, struct route *ro);
struct ddpcb *ddp_search(struct sockaddr_at *, struct sockaddr_at *,
struct at_ifaddr *);
#endif /* !_NETATALK_AT_EXTERN_H_ */

View file

@ -1,65 +0,0 @@
/*-
* 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
*
* $FreeBSD$
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/protosw.h>
#include <sys/domain.h>
#include <sys/socket.h>
#include <sys/kernel.h>
#include <net/route.h>
#include <netatalk/at.h>
#include <netatalk/ddp_var.h>
#include <netatalk/at_extern.h>
static struct domain atalkdomain;
static struct protosw atalksw[] = {
{
/* Identifiers */
.pr_type = SOCK_DGRAM,
.pr_domain = &atalkdomain,
.pr_protocol = ATPROTO_DDP,
.pr_flags = PR_ATOMIC|PR_ADDR,
.pr_output = ddp_output,
.pr_init = ddp_init,
.pr_usrreqs = &ddp_usrreqs,
},
};
static struct domain atalkdomain = {
.dom_family = AF_APPLETALK,
.dom_name = "appletalk",
.dom_protosw = atalksw,
.dom_protoswNPROTOSW = &atalksw[sizeof(atalksw)/sizeof(atalksw[0])],
.dom_rtattach = at_inithead,
.dom_rtoffset = offsetof(struct sockaddr_at, sat_addr) << 3,
.dom_maxrtkey = sizeof(struct sockaddr_at),
};
DOMAIN_SET(atalk);

View file

@ -1,117 +0,0 @@
/*-
* Copyright 1994, 1995 Massachusetts Institute of Technology
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby
* granted, provided that both the above copyright notice and this
* permission notice appear in all copies, that both the above
* copyright notice and this permission notice appear in all
* supporting documentation, and that the name of M.I.T. not be used
* in advertising or publicity pertaining to distribution of the
* software without specific, written prior permission. M.I.T. makes
* no representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied
* warranty.
*
* THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS
* ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
* SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* at_rmx.c,v 1.13 1995/05/30 08:09:31 rgrimes Exp
* $FreeBSD$
*/
/* This code generates debugging traces to the radix code. */
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/socket.h>
#include <net/route.h>
int at_inithead(void **head, int off);
#if 0
#define HEXBUF_LEN 256
static const char *
prsockaddr(void *v, char *hexbuf)
{
char *bp = &hexbuf[0];
u_char *cp = v;
if (v != NULL) {
int len = *cp;
u_char *cplim = cp + len;
/* return: "(len) hexdump" */
bp += sprintf(bp, "(%d)", len);
for (cp++; cp < cplim && bp < hexbuf + (HEXBUF_LEN - 4);
cp++) {
*bp++ = "0123456789abcdef"[*cp / 16];
*bp++ = "0123456789abcdef"[*cp % 16];
}
} else
bp+= sprintf(bp, "null");
*bp = '\0';
return (hexbuf);
}
#endif
static struct radix_node *
at_addroute(void *v_arg, void *n_arg, struct radix_node_head *head,
struct radix_node *treenodes)
{
return (rn_addroute(v_arg, n_arg, head, treenodes));
}
static struct radix_node *
at_matroute(void *v_arg, struct radix_node_head *head)
{
return (rn_match(v_arg, head));
}
static struct radix_node *
at_lookup(void *v_arg, void *m_arg, struct radix_node_head *head)
{
return (rn_lookup(v_arg, m_arg, head));
}
static struct radix_node *
at_delroute(void *v_arg, void *netmask_arg, struct radix_node_head *head)
{
return (rn_delete(v_arg, netmask_arg, head));
}
/*
* Initialize our routing tree with debugging hooks.
*/
int
at_inithead(void **head, int off)
{
struct radix_node_head *rnh;
if (!rn_inithead(head, off))
return (0);
rnh = *head;
rnh->rnh_addaddr = at_addroute;
rnh->rnh_deladdr = at_delroute;
rnh->rnh_matchaddr = at_matroute;
rnh->rnh_lookup = at_lookup;
return (1);
}

View file

@ -1,77 +0,0 @@
/*-
* 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
*
* $FreeBSD$
*/
#ifndef _NETATALK_AT_VAR_H_
#define _NETATALK_AT_VAR_H_
/*
* 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;
struct sockaddr_at aa_addr;
struct sockaddr_at aa_broadaddr;
struct sockaddr_at aa_netmask;
int aa_flags;
u_short aa_firstnet;
u_short aa_lastnet;
int aa_probcnt;
struct callout aa_callout;
TAILQ_ENTRY(at_ifaddr) aa_link;
};
#define aa_ifp aa_ifa.ifa_ifp
#define aa_dstaddr aa_broadaddr;
TAILQ_HEAD(at_ifaddrhead, at_ifaddr);
struct at_aliasreq {
char ifra_name[IFNAMSIZ];
struct sockaddr_at ifra_addr;
struct sockaddr_at ifra_broadaddr;
struct sockaddr_at ifra_mask;
};
#define ifra_dstaddr ifra_broadaddr
#define AA_SAT(aa) (&(aa->aa_addr))
#define satosat(sa) ((struct sockaddr_at *)(sa))
#define AFA_ROUTE 0x0001
#define AFA_PROBING 0x0002
#define AFA_PHASE2 0x0004
#ifdef _KERNEL
extern struct rwlock at_ifaddr_rw;
extern struct at_ifaddrhead at_ifaddrhead;
#define AT_IFADDR_LOCK_INIT() rw_init(&at_ifaddr_rw, "at_ifaddr_rw")
#define AT_IFADDR_LOCK_ASSERT() rw_assert(&at_ifaddr_rw, RA_LOCKED)
#define AT_IFADDR_RLOCK() rw_rlock(&at_ifaddr_rw)
#define AT_IFADDR_RUNLOCK() rw_runlock(&at_ifaddr_rw)
#define AT_IFADDR_WLOCK() rw_wlock(&at_ifaddr_rw)
#define AT_IFADDR_WUNLOCK() rw_wunlock(&at_ifaddr_rw)
#endif
#endif /* _NETATALK_AT_VAR_H_ */

View file

@ -1,137 +0,0 @@
/*-
* 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
*
* $FreeBSD$
*/
#ifndef _NETATALK_DDP_H_
#define _NETATALK_DDP_H_
/*-
* <-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.
*/
struct elaphdr {
u_char el_dnode;
u_char el_snode;
u_char el_type;
} __packed;
#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;
#endif
#if BYTE_ORDER == LITTLE_ENDIAN
unsigned dub_sum:16;
unsigned dub_len:10;
unsigned dub_hops:4;
unsigned dub_pad:2;
#endif
} __packed du_bits;
unsigned du_bytes;
} deh_u;
u_short deh_dnet;
u_short deh_snet;
u_char deh_dnode;
u_char deh_snode;
u_char deh_dport;
u_char deh_sport;
} __packed;
#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
#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
} __packed du_bits;
unsigned du_bytes;
} dsh_u;
} __packed;
#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
#endif /* _NETATALK_DDP_H_ */

View file

@ -1,441 +0,0 @@
/*-
* Copyright (c) 2004-2009 Robert N. M. Watson
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Copyright (c) 1990, 1994 Regents of The University of Michigan.
*
* 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.
*
* 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
*
* $FreeBSD$
*/
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/mbuf.h>
#include <sys/signalvar.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/sx.h>
#include <sys/systm.h>
#include <net/if.h>
#include <net/if_var.h>
#include <net/route.h>
#include <netatalk/at.h>
#include <netatalk/at_var.h>
#include <netatalk/ddp.h>
#include <netatalk/ddp_var.h>
#include <netatalk/ddp_pcb.h>
#include <netatalk/at_extern.h>
#include <security/mac/mac_framework.h>
static volatile int ddp_forward = 1;
static volatile int ddp_firewall = 0;
static struct ddpstat ddpstat;
static struct route forwro;
static void ddp_input(struct mbuf *, struct ifnet *, struct elaphdr *, int);
/*
* Could probably merge these two code segments a little better...
*/
void
at2intr(struct mbuf *m)
{
/*
* Phase 2 packet handling .
*/
ddp_input(m, m->m_pkthdr.rcvif, NULL, 2);
}
void
at1intr(struct mbuf *m)
{
struct elaphdr *elhp, elh;
/*
* Phase 1 packet handling
*/
if (m->m_len < SZ_ELAPHDR && ((m = m_pullup(m, SZ_ELAPHDR)) ==
NULL)) {
ddpstat.ddps_tooshort++;
return;
}
/*
* This seems a little dubious, but I don't know phase 1 so leave it.
*/
elhp = mtod(m, struct elaphdr *);
m_adj(m, SZ_ELAPHDR);
if (elhp->el_type != ELAP_DDPEXTEND) {
bcopy((caddr_t)elhp, (caddr_t)&elh, SZ_ELAPHDR);
ddp_input(m, m->m_pkthdr.rcvif, &elh, 1);
} else
ddp_input(m, m->m_pkthdr.rcvif, NULL, 1);
}
static void
ddp_input(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 = NULL, ddpe;
struct ddpcb *ddp;
int dlen, mlen;
u_short cksum = 0;
bzero((caddr_t)&from, sizeof(struct sockaddr_at));
bzero((caddr_t)&to, sizeof(struct sockaddr_at));
if (elh != NULL) {
/*
* Extract the information in the short header. Network
* information is defaulted to ATADDR_ANYNET and node
* information comes from the elh info. We must be phase 1.
*/
ddpstat.ddps_short++;
if (m->m_len < sizeof(struct ddpshdr) &&
((m = m_pullup(m, sizeof(struct ddpshdr))) == NULL)) {
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 = ATADDR_ANYNET;
to.sat_addr.s_node = elh->el_dnode;
to.sat_port = ddps.dsh_dport;
from.sat_addr.s_net = ATADDR_ANYNET;
from.sat_addr.s_node = elh->el_snode;
from.sat_port = ddps.dsh_sport;
/*
* Make sure that we point to the phase1 ifaddr info and that
* it's valid for this packet.
*/
AT_IFADDR_RLOCK();
TAILQ_FOREACH(aa, &at_ifaddrhead, aa_link) {
if ((aa->aa_ifp == ifp)
&& ((aa->aa_flags & AFA_PHASE2) == 0)
&& ((to.sat_addr.s_node ==
AA_SAT(aa)->sat_addr.s_node) ||
(to.sat_addr.s_node == ATADDR_BCAST)))
break;
}
/*
* maybe we got a broadcast not meant for us.. ditch it.
*/
if (aa == NULL) {
AT_IFADDR_RUNLOCK();
m_freem(m);
return;
}
} else {
/*
* There was no 'elh' passed on. This could still be either
* phase1 or phase2. We have a long header, but we may be
* running on a phase 1 net. Extract out all the info
* regarding this packet's src & dst.
*/
ddpstat.ddps_long++;
if (m->m_len < sizeof(struct ddpehdr) &&
((m = m_pullup(m, sizeof(struct ddpehdr))) == NULL)) {
AT_IFADDR_RUNLOCK();
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;
AT_IFADDR_RLOCK();
if (to.sat_addr.s_net == ATADDR_ANYNET) {
/*
* The TO address doesn't specify a net, so by
* definition it's for this net. Try find ifaddr
* info with the right phase, the right interface,
* and either to our node, a broadcast, or looped
* back (though that SHOULD be covered in the other
* cases).
*
* XXX If we have multiple interfaces, then the first
* with this node number will match (which may NOT be
* what we want, but it's probably safe in 99.999% of
* cases.
*/
TAILQ_FOREACH(aa, &at_ifaddrhead, aa_link) {
if (phase == 1 && (aa->aa_flags &
AFA_PHASE2))
continue;
if (phase == 2 && (aa->aa_flags &
AFA_PHASE2) == 0)
continue;
if ((aa->aa_ifp == ifp) &&
((to.sat_addr.s_node ==
AA_SAT(aa)->sat_addr.s_node) ||
(to.sat_addr.s_node == ATADDR_BCAST) ||
(ifp->if_flags & IFF_LOOPBACK)))
break;
}
} else {
/*
* A destination network was given. We just try to
* find which ifaddr info matches it.
*/
TAILQ_FOREACH(aa, &at_ifaddrhead, aa_link) {
/*
* This is a kludge. Accept packets that are
* for any router on a local netrange.
*/
if (to.sat_addr.s_net == aa->aa_firstnet &&
to.sat_addr.s_node == 0)
break;
/*
* Don't use ifaddr info for which we are
* totally outside the netrange, and it's not
* a startup packet. Startup packets are
* always implicitly allowed on to the next
* test.
*/
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;
/*
* Don't record a match either if we just
* don't have a match in the node address.
* This can have if the interface is in
* promiscuous mode for example.
*/
if ((to.sat_addr.s_node !=
AA_SAT(aa)->sat_addr.s_node) &&
(to.sat_addr.s_node != ATADDR_BCAST))
continue;
break;
}
}
}
if (aa != NULL)
ifa_ref(&aa->aa_ifa);
AT_IFADDR_RUNLOCK();
/*
* 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.
*/
mlen = m->m_pkthdr.len;
if (mlen < dlen) {
ddpstat.ddps_toosmall++;
goto out;
}
if (mlen > dlen)
m_adj(m, dlen - mlen);
/*
* If it isn't for a net on any of our interfaces, or it IS for a net
* on a different interface than it came in on, (and it is not looped
* back) then consider if we should forward it. As we are not really
* a router this is a bit cheeky, but it may be useful some day.
*/
if ((aa == NULL) || ((to.sat_addr.s_node == ATADDR_BCAST) &&
(aa->aa_ifp != ifp) && ((ifp->if_flags & IFF_LOOPBACK) == 0))) {
/*
* If we've explicitly disabled it, don't route anything.
*/
if (ddp_forward == 0)
goto out;
/*
* If the cached forwarding route is still valid, use it.
*
* XXXRW: Access to the cached route may not be properly
* synchronized for parallel input handling.
*/
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)) {
RTFREE(forwro.ro_rt);
forwro.ro_rt = NULL;
}
/*
* If we don't have a cached one (any more) or it's useless,
* then get a new route.
*
* XXX this could cause a 'route leak'. Check this!
*/
if (forwro.ro_rt == NULL || forwro.ro_rt->rt_ifp == NULL) {
forwro.ro_dst.sa_len = sizeof(struct sockaddr_at);
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 it's not going to get there on this hop, and it's
* already done too many hops, then throw it away.
*/
if ((to.sat_addr.s_net !=
satosat(&forwro.ro_dst)->sat_addr.s_net) &&
(ddpe.deh_hops == DDP_MAXHOPS))
goto out;
/*
* A ddp router might use the same interface to forward the
* packet, which this would not effect. Don't allow packets
* to cross from one interface to another however.
*/
if (ddp_firewall && ((forwro.ro_rt == NULL) ||
(forwro.ro_rt->rt_ifp != ifp)))
goto out;
/*
* Adjust the header. If it was a short header then it would
* have not gotten here, so we can assume there is room to
* drop the header in.
*
* XXX what about promiscuous mode, etc...
*/
ddpe.deh_hops++;
ddpe.deh_bytes = htonl(ddpe.deh_bytes);
/* XXX deh? */
bcopy((caddr_t)&ddpe, (caddr_t)deh, sizeof(u_short));
if (ddp_route(m, &forwro))
ddpstat.ddps_cantforward++;
else
ddpstat.ddps_forward++;
if (aa != NULL)
ifa_free(&aa->aa_ifa);
return;
}
/*
* It was for us, and we have an ifaddr to use with it.
*/
from.sat_len = sizeof(struct sockaddr_at);
from.sat_family = AF_APPLETALK;
/*
* We are no longer interested in the link layer so cut it off.
*/
if (elh == NULL) {
if (ddp_cksum && cksum && cksum !=
at_cksum(m, sizeof(int))) {
ddpstat.ddps_badsum++;
goto out;
}
m_adj(m, sizeof(struct ddpehdr));
} else
m_adj(m, sizeof(struct ddpshdr));
/*
* Search for ddp protocol control blocks that match these addresses.
*/
DDP_LIST_SLOCK();
if ((ddp = ddp_search(&from, &to, aa)) == NULL)
goto out_unlock;
#ifdef MAC
if (mac_socket_check_deliver(ddp->ddp_socket, m) != 0)
goto out_unlock;
#endif
/*
* If we found one, deliver the packet to the socket
*/
SOCKBUF_LOCK(&ddp->ddp_socket->so_rcv);
if (sbappendaddr_locked(&ddp->ddp_socket->so_rcv,
(struct sockaddr *)&from, m, NULL) == 0) {
SOCKBUF_UNLOCK(&ddp->ddp_socket->so_rcv);
/*
* If the socket is full (or similar error) dump the packet.
*/
ddpstat.ddps_nosockspace++;
goto out_unlock;
}
/*
* And wake up whatever might be waiting for it
*/
sorwakeup_locked(ddp->ddp_socket);
m = NULL;
out_unlock:
DDP_LIST_SUNLOCK();
out:
if (aa != NULL)
ifa_free(&aa->aa_ifa);
if (m != NULL)
m_freem(m);
}

View file

@ -1,248 +0,0 @@
/*-
* 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
*/
/* $FreeBSD$ */
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <net/if.h>
#include <net/if_var.h>
#include <net/route.h>
#undef s_net
#include <netatalk/at.h>
#include <netatalk/at_var.h>
#include <netatalk/ddp.h>
#include <netatalk/ddp_var.h>
#include <netatalk/at_extern.h>
#include <security/mac/mac_framework.h>
int ddp_cksum = 1;
int
ddp_output(struct mbuf *m, struct socket *so)
{
struct ddpehdr *deh;
struct ddpcb *ddp = sotoddpcb(so);
#ifdef MAC
mac_socket_create_mbuf(so, m);
#endif
M_PREPEND(m, sizeof(struct ddpehdr), M_NOWAIT);
if (m == NULL)
return (ENOBUFS);
deh = mtod(m, struct ddpehdr *);
deh->deh_pad = 0;
deh->deh_hops = 0;
deh->deh_len = m->m_pkthdr.len;
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);
#ifdef NETATALK_DEBUG
printf ("ddp_output: from %d.%d:%d to %d.%d:%d\n",
ntohs(deh->deh_snet), deh->deh_snode, deh->deh_sport,
ntohs(deh->deh_dnet), deh->deh_dnode, deh->deh_dport);
#endif
return (ddp_route(m, &ddp->ddp_route));
}
u_short
at_cksum(struct mbuf *m, int skip)
{
u_char *data, *end;
u_long 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);
}
int
ddp_route(struct mbuf *m, struct route *ro)
{
struct sockaddr_at gate;
struct elaphdr *elh;
struct mbuf *m0;
struct at_ifaddr *aa = NULL;
struct ifnet *ifp = NULL;
u_short net;
#if 0
/* Check for net zero, node zero ("myself") */
if (satosat(&ro->ro_dst)->sat_addr.s_net == ATADDR_ANYNET
&& satosat(&ro->ro_dst)->sat_addr.s_node == ATADDR_ANYNODE) {
/* Find the loopback interface */
}
#endif
/*
* If we have a route, find the ifa that refers to this route. I.e
* the ifa used to get to the gateway.
*/
if ((ro->ro_rt == NULL) || (ro->ro_rt->rt_ifa == NULL) ||
((ifp = ro->ro_rt->rt_ifa->ifa_ifp) == NULL))
rtalloc(ro);
if ((ro->ro_rt != NULL) && (ro->ro_rt->rt_ifa) &&
(ifp = ro->ro_rt->rt_ifa->ifa_ifp)) {
net = ntohs(satosat(ro->ro_rt->rt_gateway)->sat_addr.s_net);
AT_IFADDR_RLOCK();
TAILQ_FOREACH(aa, &at_ifaddrhead, aa_link) {
if (((net == 0) || (aa->aa_ifp == ifp)) &&
net >= ntohs(aa->aa_firstnet) &&
net <= ntohs(aa->aa_lastnet))
break;
}
if (aa != NULL)
ifa_ref(&aa->aa_ifa);
AT_IFADDR_RUNLOCK();
} else {
m_freem(m);
#ifdef NETATALK_DEBUG
if (ro->ro_rt == NULL)
printf ("ddp_route: no ro_rt.\n");
else if (ro->ro_rt->rt_ifa == NULL)
printf ("ddp_route: no ro_rt->rt_ifa\n");
else
printf ("ddp_route: no ro_rt->rt_ifa->ifa_ifp\n");
#endif
return (ENETUNREACH);
}
if (aa == NULL) {
#ifdef NETATALK_DEBUG
printf("ddp_route: no atalk address found for %s\n",
ifp->if_xname);
#endif
m_freem(m);
return (ENETUNREACH);
}
/*
* If the destination address is on a directly attached node use
* that, else use the official gateway.
*/
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
gate = *satosat(ro->ro_rt->rt_gateway);
/*
* 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.
*
* XXXRW: kern/4184 suggests that an m_pullup() of (m) should take
* place here to address possible alignment issues.
*
* XXXRW: This appears not to handle M_PKTHDR properly, as it doesn't
* move the existing header from the old packet to the new one.
* Posibly should call M_MOVE_PKTHDR()? This would also allow
* removing mac_mbuf_copy().
*/
if (!(aa->aa_flags & AFA_PHASE2)) {
MGET(m0, M_NOWAIT, MT_DATA);
if (m0 == NULL) {
ifa_free(&aa->aa_ifa);
m_freem(m);
printf("ddp_route: no buffers\n");
return (ENOBUFS);
}
#ifdef MAC
mac_mbuf_copy(m, m0);
#endif
m0->m_next = m;
/* XXX perhaps we ought to align the 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;
elh->el_dnode = gate.sat_addr.s_node;
}
counter_u64_add(ro->ro_rt->rt_pksent, 1);
#ifdef NETATALK_DEBUG
printf ("ddp_route: from %d.%d to %d.%d, via %d.%d (%s)\n",
ntohs(satosat(&aa->aa_addr)->sat_addr.s_net),
satosat(&aa->aa_addr)->sat_addr.s_node,
ntohs(satosat(&ro->ro_dst)->sat_addr.s_net),
satosat(&ro->ro_dst)->sat_addr.s_node,
ntohs(gate.sat_addr.s_net), gate.sat_addr.s_node, ifp->if_xname);
#endif
/* Short-circuit the output if we're sending this to ourself. */
if ((satosat(&aa->aa_addr)->sat_addr.s_net ==
satosat(&ro->ro_dst)->sat_addr.s_net) &&
(satosat(&aa->aa_addr)->sat_addr.s_node ==
satosat(&ro->ro_dst)->sat_addr.s_node)) {
ifa_free(&aa->aa_ifa);
return (if_simloop(ifp, m, gate.sat_family, 0));
}
ifa_free(&aa->aa_ifa);
/* XXX */
return ((*ifp->if_output)(ifp, m, (struct sockaddr *)&gate, NULL));
}

View file

@ -1,417 +0,0 @@
/*-
* Copyright (c) 2004-2009 Robert N. M. Watson
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Copyright (c) 1990, 1994 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.
*
* 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
* $FreeBSD$
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/priv.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/protosw.h>
#include <net/if.h>
#include <net/if_var.h>
#include <net/route.h>
#include <net/netisr.h>
#include <netatalk/at.h>
#include <netatalk/at_var.h>
#include <netatalk/ddp_var.h>
#include <netatalk/ddp_pcb.h>
#include <netatalk/at_extern.h>
struct mtx ddp_list_mtx;
static struct ddpcb *ddp_ports[ATPORT_LAST];
struct ddpcb *ddpcb_list = NULL;
void
at_sockaddr(struct ddpcb *ddp, struct sockaddr **addr)
{
/*
* Prevent modification of ddp during copy of addr.
*/
DDP_LOCK_ASSERT(ddp);
*addr = sodupsockaddr((struct sockaddr *)&ddp->ddp_lsat, M_NOWAIT);
}
int
at_pcbsetaddr(struct ddpcb *ddp, struct sockaddr *addr, struct thread *td)
{
struct sockaddr_at lsat, *sat;
struct at_ifaddr *aa;
struct ddpcb *ddpp;
/*
* We read and write both the ddp passed in, and also ddp_ports.
*/
DDP_LIST_XLOCK_ASSERT();
DDP_LOCK_ASSERT(ddp);
/*
* Shouldn't be bound.
*/
if (ddp->ddp_lsat.sat_port != ATADDR_ANYPORT)
return (EINVAL);
/*
* Validate passed address.
*/
aa = NULL;
if (addr != NULL) {
sat = (struct sockaddr_at *)addr;
if (sat->sat_family != AF_APPLETALK)
return (EAFNOSUPPORT);
if (sat->sat_addr.s_node != ATADDR_ANYNODE ||
sat->sat_addr.s_net != ATADDR_ANYNET) {
AT_IFADDR_RLOCK();
TAILQ_FOREACH(aa, &at_ifaddrhead, aa_link) {
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;
}
AT_IFADDR_RUNLOCK();
if (aa == NULL)
return (EADDRNOTAVAIL);
}
if (sat->sat_port != ATADDR_ANYPORT) {
if (sat->sat_port < ATPORT_FIRST ||
sat->sat_port >= ATPORT_LAST)
return (EINVAL);
if (sat->sat_port < ATPORT_RESERVED &&
priv_check(td, PRIV_NETATALK_RESERVEDPORT))
return (EACCES);
}
} else {
bzero((caddr_t)&lsat, sizeof(struct sockaddr_at));
lsat.sat_len = sizeof(struct sockaddr_at);
lsat.sat_addr.s_node = ATADDR_ANYNODE;
lsat.sat_addr.s_net = ATADDR_ANYNET;
lsat.sat_family = AF_APPLETALK;
sat = &lsat;
}
if (sat->sat_addr.s_node == ATADDR_ANYNODE &&
sat->sat_addr.s_net == ATADDR_ANYNET) {
AT_IFADDR_RLOCK();
if (TAILQ_EMPTY(&at_ifaddrhead)) {
AT_IFADDR_RUNLOCK();
return (EADDRNOTAVAIL);
}
sat->sat_addr = AA_SAT(TAILQ_FIRST(&at_ifaddrhead))->sat_addr;
AT_IFADDR_RUNLOCK();
}
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] == NULL)
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 != NULL)
ddp->ddp_pnext->ddp_pprev = ddp;
}
return (0);
}
int
at_pcbconnect(struct ddpcb *ddp, struct sockaddr *addr, struct thread *td)
{
struct sockaddr_at *sat = (struct sockaddr_at *)addr;
struct route *ro;
struct at_ifaddr *aa = NULL;
struct ifnet *ifp;
u_short hintnet = 0, net;
DDP_LIST_XLOCK_ASSERT();
DDP_LOCK_ASSERT(ddp);
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 == ATADDR_ANYNET &&
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 = NULL;
AT_IFADDR_RLOCK();
if ((ifp = ro->ro_rt->rt_ifp) != NULL) {
TAILQ_FOREACH(aa, &at_ifaddrhead, aa_link) {
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)) {
RTFREE(ro->ro_rt);
ro->ro_rt = NULL;
}
AT_IFADDR_RUNLOCK();
}
/*
* If we've got no route for this interface, try to find one.
*/
if (ro->ro_rt == NULL || ro->ro_rt->rt_ifp == NULL) {
ro->ro_dst.sa_len = sizeof(struct sockaddr_at);
ro->ro_dst.sa_family = AF_APPLETALK;
if (hintnet)
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 = NULL;
if (ro->ro_rt && (ifp = ro->ro_rt->rt_ifp)) {
AT_IFADDR_RLOCK();
TAILQ_FOREACH(aa, &at_ifaddrhead, aa_link) {
if (aa->aa_ifp == ifp)
break;
}
AT_IFADDR_RUNLOCK();
}
if (aa == NULL)
return (ENETUNREACH);
ddp->ddp_fsat = *sat;
if (ddp->ddp_lsat.sat_port == ATADDR_ANYPORT)
return (at_pcbsetaddr(ddp, NULL, td));
return (0);
}
void
at_pcbdisconnect(struct ddpcb *ddp)
{
DDP_LOCK_ASSERT(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;
}
int
at_pcballoc(struct socket *so)
{
struct ddpcb *ddp;
DDP_LIST_XLOCK_ASSERT();
ddp = malloc(sizeof *ddp, M_PCB, M_NOWAIT | M_ZERO);
if (ddp == NULL)
return (ENOBUFS);
DDP_LOCK_INIT(ddp);
ddp->ddp_lsat.sat_port = ATADDR_ANYPORT;
ddp->ddp_socket = so;
so->so_pcb = (caddr_t)ddp;
ddp->ddp_next = ddpcb_list;
ddp->ddp_prev = NULL;
ddp->ddp_pprev = NULL;
ddp->ddp_pnext = NULL;
if (ddpcb_list != NULL)
ddpcb_list->ddp_prev = ddp;
ddpcb_list = ddp;
return(0);
}
void
at_pcbdetach(struct socket *so, struct ddpcb *ddp)
{
/*
* We modify ddp, ddp_ports, and the global list.
*/
DDP_LIST_XLOCK_ASSERT();
DDP_LOCK_ASSERT(ddp);
KASSERT(so->so_pcb != NULL, ("at_pcbdetach: so_pcb == NULL"));
so->so_pcb = NULL;
/* 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_list = ddp->ddp_next;
if (ddp->ddp_next)
ddp->ddp_next->ddp_prev = ddp->ddp_prev;
DDP_UNLOCK(ddp);
DDP_LOCK_DESTROY(ddp);
free(ddp, M_PCB);
}
/*
* 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(struct sockaddr_at *from, struct sockaddr_at *to,
struct at_ifaddr *aa)
{
struct ddpcb *ddp;
DDP_LIST_SLOCK_ASSERT();
/*
* 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) {
DDP_LOCK(ddp);
/* 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) {
DDP_UNLOCK(ddp);
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) {
DDP_UNLOCK(ddp);
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)) {
DDP_UNLOCK(ddp);
break;
}
DDP_UNLOCK(ddp);
}
return (ddp);
}

View file

@ -1,84 +0,0 @@
/*-
* Copyright (c) 2004 Robert N. M. Watson
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Copyright (c) 1990, 1994 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.
*
* 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
*
* $FreeBSD$
*/
#ifndef _NETATALK_DDP_PCB_H_
#define _NETATALK_DDP_PCB_H_
int at_pcballoc(struct socket *so);
int at_pcbconnect(struct ddpcb *ddp, struct sockaddr *addr,
struct thread *td);
void at_pcbdetach(struct socket *so, struct ddpcb *ddp);
void at_pcbdisconnect(struct ddpcb *ddp);
int at_pcbsetaddr(struct ddpcb *ddp, struct sockaddr *addr,
struct thread *td);
void at_sockaddr(struct ddpcb *ddp, struct sockaddr **addr);
/* Lock macros for per-pcb locks. */
#define DDP_LOCK_INIT(ddp) mtx_init(&(ddp)->ddp_mtx, "ddp_mtx", \
NULL, MTX_DEF)
#define DDP_LOCK_DESTROY(ddp) mtx_destroy(&(ddp)->ddp_mtx)
#define DDP_LOCK(ddp) mtx_lock(&(ddp)->ddp_mtx)
#define DDP_UNLOCK(ddp) mtx_unlock(&(ddp)->ddp_mtx)
#define DDP_LOCK_ASSERT(ddp) mtx_assert(&(ddp)->ddp_mtx, MA_OWNED)
/* Lock macros for global pcb list lock. */
#define DDP_LIST_LOCK_INIT() mtx_init(&ddp_list_mtx, "ddp_list_mtx", \
NULL, MTX_DEF)
#define DDP_LIST_LOCK_DESTROY() mtx_destroy(&ddp_list_mtx)
#define DDP_LIST_XLOCK() mtx_lock(&ddp_list_mtx)
#define DDP_LIST_XUNLOCK() mtx_unlock(&ddp_list_mtx)
#define DDP_LIST_XLOCK_ASSERT() mtx_assert(&ddp_list_mtx, MA_OWNED)
#define DDP_LIST_SLOCK() mtx_lock(&ddp_list_mtx)
#define DDP_LIST_SUNLOCK() mtx_unlock(&ddp_list_mtx)
#define DDP_LIST_SLOCK_ASSERT() mtx_assert(&ddp_list_mtx, MA_OWNED)
#endif /* !_NETATALK_DDP_PCB_H_ */

View file

@ -1,332 +0,0 @@
/*-
* Copyright (c) 2004-2009 Robert N. M. Watson
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Copyright (c) 1990, 1994 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.
*
* 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
*
* $FreeBSD$
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/protosw.h>
#include <net/if.h>
#include <net/if_var.h>
#include <net/route.h>
#include <net/netisr.h>
#include <netatalk/at.h>
#include <netatalk/at_var.h>
#include <netatalk/ddp_var.h>
#include <netatalk/ddp_pcb.h>
#include <netatalk/at_extern.h>
static u_long ddp_sendspace = DDP_MAXSZ; /* Max ddp size + 1 (ddp_type) */
static u_long ddp_recvspace = 10 * (587 + sizeof(struct sockaddr_at));
static const struct netisr_handler atalk1_nh = {
.nh_name = "atalk1",
.nh_handler = at1intr,
.nh_proto = NETISR_ATALK1,
.nh_policy = NETISR_POLICY_SOURCE,
};
static const struct netisr_handler atalk2_nh = {
.nh_name = "atalk2",
.nh_handler = at2intr,
.nh_proto = NETISR_ATALK2,
.nh_policy = NETISR_POLICY_SOURCE,
};
static const struct netisr_handler aarp_nh = {
.nh_name = "aarp",
.nh_handler = aarpintr,
.nh_proto = NETISR_AARP,
.nh_policy = NETISR_POLICY_SOURCE,
};
static int
ddp_attach(struct socket *so, int proto, struct thread *td)
{
int error = 0;
KASSERT(sotoddpcb(so) == NULL, ("ddp_attach: ddp != NULL"));
/*
* Allocate socket buffer space first so that it's present
* before first use.
*/
error = soreserve(so, ddp_sendspace, ddp_recvspace);
if (error)
return (error);
DDP_LIST_XLOCK();
error = at_pcballoc(so);
DDP_LIST_XUNLOCK();
return (error);
}
static void
ddp_detach(struct socket *so)
{
struct ddpcb *ddp;
ddp = sotoddpcb(so);
KASSERT(ddp != NULL, ("ddp_detach: ddp == NULL"));
DDP_LIST_XLOCK();
DDP_LOCK(ddp);
at_pcbdetach(so, ddp);
DDP_LIST_XUNLOCK();
}
static int
ddp_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
{
struct ddpcb *ddp;
int error = 0;
ddp = sotoddpcb(so);
KASSERT(ddp != NULL, ("ddp_bind: ddp == NULL"));
DDP_LIST_XLOCK();
DDP_LOCK(ddp);
error = at_pcbsetaddr(ddp, nam, td);
DDP_UNLOCK(ddp);
DDP_LIST_XUNLOCK();
return (error);
}
static int
ddp_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
{
struct ddpcb *ddp;
int error = 0;
ddp = sotoddpcb(so);
KASSERT(ddp != NULL, ("ddp_connect: ddp == NULL"));
DDP_LIST_XLOCK();
DDP_LOCK(ddp);
if (ddp->ddp_fsat.sat_port != ATADDR_ANYPORT) {
DDP_UNLOCK(ddp);
DDP_LIST_XUNLOCK();
return (EISCONN);
}
error = at_pcbconnect( ddp, nam, td );
DDP_UNLOCK(ddp);
DDP_LIST_XUNLOCK();
if (error == 0)
soisconnected(so);
return (error);
}
static int
ddp_disconnect(struct socket *so)
{
struct ddpcb *ddp;
ddp = sotoddpcb(so);
KASSERT(ddp != NULL, ("ddp_disconnect: ddp == NULL"));
DDP_LOCK(ddp);
if (ddp->ddp_fsat.sat_addr.s_node == ATADDR_ANYNODE) {
DDP_UNLOCK(ddp);
return (ENOTCONN);
}
at_pcbdisconnect(ddp);
ddp->ddp_fsat.sat_addr.s_node = ATADDR_ANYNODE;
DDP_UNLOCK(ddp);
soisdisconnected(so);
return (0);
}
static int
ddp_shutdown(struct socket *so)
{
KASSERT(sotoddpcb(so) != NULL, ("ddp_shutdown: ddp == NULL"));
socantsendmore(so);
return (0);
}
static int
ddp_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
struct mbuf *control, struct thread *td)
{
struct ddpcb *ddp;
int error = 0;
ddp = sotoddpcb(so);
KASSERT(ddp != NULL, ("ddp_send: ddp == NULL"));
if (control && control->m_len)
return (EINVAL);
if (addr != NULL) {
DDP_LIST_XLOCK();
DDP_LOCK(ddp);
if (ddp->ddp_fsat.sat_port != ATADDR_ANYPORT) {
error = EISCONN;
goto out;
}
error = at_pcbconnect(ddp, addr, td);
if (error == 0) {
error = ddp_output(m, so);
at_pcbdisconnect(ddp);
}
out:
DDP_UNLOCK(ddp);
DDP_LIST_XUNLOCK();
} else {
DDP_LOCK(ddp);
if (ddp->ddp_fsat.sat_port == ATADDR_ANYPORT)
error = ENOTCONN;
else
error = ddp_output(m, so);
DDP_UNLOCK(ddp);
}
return (error);
}
/*
* XXXRW: This is never called because we only invoke abort on stream
* protocols.
*/
static void
ddp_abort(struct socket *so)
{
struct ddpcb *ddp;
ddp = sotoddpcb(so);
KASSERT(ddp != NULL, ("ddp_abort: ddp == NULL"));
DDP_LOCK(ddp);
at_pcbdisconnect(ddp);
DDP_UNLOCK(ddp);
soisdisconnected(so);
}
static void
ddp_close(struct socket *so)
{
struct ddpcb *ddp;
ddp = sotoddpcb(so);
KASSERT(ddp != NULL, ("ddp_close: ddp == NULL"));
DDP_LOCK(ddp);
at_pcbdisconnect(ddp);
DDP_UNLOCK(ddp);
soisdisconnected(so);
}
void
ddp_init(void)
{
DDP_LIST_LOCK_INIT();
TAILQ_INIT(&at_ifaddrhead);
netisr_register(&atalk1_nh);
netisr_register(&atalk2_nh);
netisr_register(&aarp_nh);
}
#if 0
static void
ddp_clean(void)
{
struct ddpcp *ddp;
for (ddp = ddpcb_list; ddp != NULL; ddp = ddp->ddp_next)
at_pcbdetach(ddp->ddp_socket, ddp);
DDP_LIST_LOCK_DESTROY();
}
#endif
static int
at_getpeeraddr(struct socket *so, struct sockaddr **nam)
{
return (EOPNOTSUPP);
}
static int
at_getsockaddr(struct socket *so, struct sockaddr **nam)
{
struct ddpcb *ddp;
ddp = sotoddpcb(so);
KASSERT(ddp != NULL, ("at_getsockaddr: ddp == NULL"));
DDP_LOCK(ddp);
at_sockaddr(ddp, nam);
DDP_UNLOCK(ddp);
return (0);
}
struct pr_usrreqs ddp_usrreqs = {
.pru_abort = ddp_abort,
.pru_attach = ddp_attach,
.pru_bind = ddp_bind,
.pru_connect = ddp_connect,
.pru_control = at_control,
.pru_detach = ddp_detach,
.pru_disconnect = ddp_disconnect,
.pru_peeraddr = at_getpeeraddr,
.pru_send = ddp_send,
.pru_shutdown = ddp_shutdown,
.pru_sockaddr = at_getsockaddr,
.pru_close = ddp_close,
};

View file

@ -1,63 +0,0 @@
/*-
* Copyright (c) 1990, 1994 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.
*
* 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
*
* $FreeBSD$
*/
#ifndef _NETATALK_DDP_VAR_H_
#define _NETATALK_DDP_VAR_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;
struct mtx ddp_mtx;
};
#define sotoddpcb(so) ((struct ddpcb *)(so)->so_pcb)
struct ddpstat {
long ddps_short; /* short header packets received */
long ddps_long; /* long header packets received */
long ddps_nosum; /* no checksum */
long ddps_badsum; /* bad checksum */
long ddps_tooshort; /* packet too short */
long ddps_toosmall; /* not enough data */
long ddps_forward; /* packets forwarded */
long ddps_encap; /* packets encapsulated */
long ddps_cantforward; /* packets rcvd for unreachable dest */
long ddps_nosockspace; /* no space in sockbuf for packet */
};
#ifdef _KERNEL
extern int ddp_cksum;
extern struct ddpcb *ddpcb_list;
extern struct pr_usrreqs ddp_usrreqs;
extern struct mtx ddp_list_mtx;
#endif
#endif /* _NETATALK_DDP_VAR_H_ */

View file

@ -1,31 +0,0 @@
/*-
* 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
*
* $FreeBSD$
*/
#ifndef _ATALK_ENDIAN_H_
#define _ATALK_ENDIAN_H_
#include <machine/endian.h>
#endif /* !_ATALK_ENDIAN_H_ */

View file

@ -1,34 +0,0 @@
/*-
* 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.
*
* This product includes software developed by the University of
* California, Berkeley and its contributors.
*
* 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
* $FreeBSD$
*/
#include <net/if_llc.h>
#define llc_org_code llc_un.type_snap.org_code
#define llc_ether_type llc_un.type_snap.ether_type
#define SIOCPHASE1 _IOW('i', 100, struct ifreq) /* AppleTalk phase 1 */
#define SIOCPHASE2 _IOW('i', 101, struct ifreq) /* AppleTalk phase 2 */

View file

@ -55,8 +55,6 @@
#include <netinet/in.h>
#include <netinet/if_ether.h>
#include <netatalk/at.h>
#include <netgraph/ng_message.h>
#include <netgraph/netgraph.h>
#include <netgraph/ng_parse.h>

View file

@ -52,7 +52,6 @@
* This node also includes Berkeley packet filter support.
*/
#include "opt_atalk.h"
#include "opt_inet.h"
#include "opt_inet6.h"
@ -103,7 +102,6 @@ typedef const struct iffam *iffam_p;
const static struct iffam gFamilies[] = {
{ AF_INET, NG_IFACE_HOOK_INET },
{ AF_INET6, NG_IFACE_HOOK_INET6 },
{ AF_APPLETALK, NG_IFACE_HOOK_ATALK },
{ AF_ATM, NG_IFACE_HOOK_ATM },
{ AF_NATM, NG_IFACE_HOOK_NATM },
};
@ -758,11 +756,6 @@ ng_iface_rcvdata(hook_p hook, item_p item)
case AF_INET6:
isr = NETISR_IPV6;
break;
#endif
#ifdef NETATALK
case AF_APPLETALK:
isr = NETISR_ATALK2;
break;
#endif
default:
m_freem(m);

View file

@ -54,7 +54,6 @@
/* My hook names */
#define NG_IFACE_HOOK_INET "inet"
#define NG_IFACE_HOOK_INET6 "inet6"
#define NG_IFACE_HOOK_ATALK "atalk" /* AppleTalk phase 2 */
#define NG_IFACE_HOOK_ATM "atm"
#define NG_IFACE_HOOK_NATM "natm"

View file

@ -67,7 +67,6 @@
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netatalk/at.h>
#ifdef NG_SEPARATE_MALLOC
static MALLOC_DEFINE(M_NETGRAPH_KSOCKET, "netgraph_ksock",
@ -121,7 +120,6 @@ static const struct ng_ksocket_alias ng_ksocket_families[] = {
{ "local", PF_LOCAL },
{ "inet", PF_INET },
{ "inet6", PF_INET6 },
{ "atalk", PF_APPLETALK },
{ "atm", PF_ATM },
{ NULL, -1 },
};
@ -151,8 +149,6 @@ static const struct ng_ksocket_alias ng_ksocket_protos[] = {
{ "encap", IPPROTO_ENCAP, PF_INET },
{ "divert", IPPROTO_DIVERT, PF_INET },
{ "pim", IPPROTO_PIM, PF_INET },
{ "ddp", ATPROTO_DDP, PF_APPLETALK },
{ "aarp", ATPROTO_AARP, PF_APPLETALK },
{ NULL, -1 },
};
@ -300,8 +296,7 @@ ng_ksocket_sockaddr_parse(const struct ng_parse_type *type,
}
#if 0
case PF_APPLETALK: /* XXX implement these someday */
case PF_INET6:
case PF_INET6: /* XXX implement this someday */
#endif
default:
@ -363,8 +358,7 @@ ng_ksocket_sockaddr_unparse(const struct ng_parse_type *type,
}
#if 0
case PF_APPLETALK: /* XXX implement these someday */
case PF_INET6:
case PF_INET6: /* XXX implement this someday */
#endif
default:

View file

@ -41,7 +41,6 @@
__FBSDID("$FreeBSD$");
#include "opt_inet.h"
#include "opt_atalk.h"
#include "opt_inet6.h"
#include <sys/param.h>
@ -74,12 +73,6 @@ __FBSDID("$FreeBSD$");
#error "ip_gre requires INET"
#endif
#ifdef NETATALK
#include <netatalk/at.h>
#include <netatalk/at_var.h>
#include <netatalk/at_extern.h>
#endif
/* Needs IP headers. */
#include <net/if_gre.h>
@ -178,12 +171,6 @@ gre_input2(struct mbuf *m ,int hlen, u_char proto)
isr = NETISR_IPV6;
af = AF_INET6;
break;
#endif
#ifdef NETATALK
case ETHERTYPE_ATALK:
isr = NETISR_ATALK1;
af = AF_APPLETALK;
break;
#endif
default:
/* Others not yet supported. */

View file

@ -41,7 +41,6 @@
__FBSDID("$FreeBSD$");
#include "opt_apic.h"
#include "opt_atalk.h"
#include "opt_atpic.h"
#include "opt_compat.h"
#include "opt_cpu.h"

View file

@ -1,73 +0,0 @@
/*-
* Copyright (c) 2007-2009 Robert N. M. Watson
* All rights reserved.
*
* This software was developed by Robert Watson for the TrustedBSD Project.
*
* This software was developed at the University of Cambridge Computer
* Laboratory with support from a grant from Google, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include "opt_mac.h"
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mutex.h>
#include <sys/sbuf.h>
#include <sys/systm.h>
#include <sys/mount.h>
#include <sys/file.h>
#include <sys/namei.h>
#include <sys/protosw.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/sysctl.h>
#include <net/if.h>
#include <net/if_var.h>
#include <security/mac/mac_framework.h>
#include <security/mac/mac_internal.h>
#include <security/mac/mac_policy.h>
void
mac_netatalk_aarp_send(struct ifnet *ifp, struct mbuf *m)
{
struct label *mlabel;
if (mac_policy_count == 0)
return;
mlabel = mac_mbuf_to_label(m);
MAC_IFNET_LOCK(ifp);
MAC_POLICY_PERFORM_NOSLEEP(netatalk_aarp_send, ifp, ifp->if_label, m,
mlabel);
MAC_IFNET_UNLOCK(ifp);
}

View file

@ -195,8 +195,6 @@ void mac_mount_create(struct ucred *cred, struct mount *mp);
void mac_mount_destroy(struct mount *);
void mac_mount_init(struct mount *);
void mac_netatalk_aarp_send(struct ifnet *ifp, struct mbuf *m);
void mac_netinet_arp_send(struct ifnet *ifp, struct mbuf *m);
void mac_netinet_firewall_reply(struct mbuf *mrecv, struct mbuf *msend);
void mac_netinet_firewall_send(struct mbuf *m);

View file

@ -271,10 +271,6 @@ typedef void (*mpo_mount_create_t)(struct ucred *cred, struct mount *mp,
typedef void (*mpo_mount_destroy_label_t)(struct label *label);
typedef void (*mpo_mount_init_label_t)(struct label *label);
typedef void (*mpo_netatalk_aarp_send_t)(struct ifnet *ifp,
struct label *ifplabel, struct mbuf *m,
struct label *mlabel);
typedef void (*mpo_netinet_arp_send_t)(struct ifnet *ifp,
struct label *ifplabel, struct mbuf *m,
struct label *mlabel);
@ -782,8 +778,6 @@ struct mac_policy_ops {
mpo_mount_destroy_label_t mpo_mount_destroy_label;
mpo_mount_init_label_t mpo_mount_init_label;
mpo_netatalk_aarp_send_t mpo_netatalk_aarp_send;
mpo_netinet_arp_send_t mpo_netinet_arp_send;
mpo_netinet_firewall_reply_t mpo_netinet_firewall_reply;
mpo_netinet_firewall_send_t mpo_netinet_firewall_send;

View file

@ -1357,17 +1357,6 @@ biba_mount_create(struct ucred *cred, struct mount *mp,
biba_copy_effective(source, dest);
}
static void
biba_netatalk_aarp_send(struct ifnet *ifp, struct label *ifplabel,
struct mbuf *m, struct label *mlabel)
{
struct mac_biba *dest;
dest = SLOT(mlabel);
biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
}
static void
biba_netinet_arp_send(struct ifnet *ifp, struct label *ifplabel,
struct mbuf *m, struct label *mlabel)
@ -2065,7 +2054,6 @@ biba_priv_check(struct ucred *cred, int priv)
* Allow some but not all network privileges. In general, dont allow
* reconfiguring the network stack, just normal use.
*/
case PRIV_NETATALK_RESERVEDPORT:
case PRIV_NETINET_RESERVEDPORT:
case PRIV_NETINET_RAW:
case PRIV_NETINET_REUSEPORT:
@ -3652,8 +3640,6 @@ static struct mac_policy_ops mac_biba_ops =
.mpo_mount_destroy_label = biba_destroy_label,
.mpo_mount_init_label = biba_init_label,
.mpo_netatalk_aarp_send = biba_netatalk_aarp_send,
.mpo_netinet_arp_send = biba_netinet_arp_send,
.mpo_netinet_firewall_reply = biba_netinet_firewall_reply,
.mpo_netinet_firewall_send = biba_netinet_firewall_send,

View file

@ -1448,17 +1448,6 @@ lomac_mount_create(struct ucred *cred, struct mount *mp,
lomac_copy_single(source, dest);
}
static void
lomac_netatalk_aarp_send(struct ifnet *ifp, struct label *ifplabel,
struct mbuf *m, struct label *mlabel)
{
struct mac_lomac *dest;
dest = SLOT(mlabel);
lomac_set_single(dest, MAC_LOMAC_TYPE_EQUAL, 0);
}
static void
lomac_netinet_arp_send(struct ifnet *ifp, struct label *ifplabel,
struct mbuf *m, struct label *mlabel)
@ -1832,7 +1821,6 @@ lomac_priv_check(struct ucred *cred, int priv)
* Allow some but not all network privileges. In general, dont allow
* reconfiguring the network stack, just normal use.
*/
case PRIV_NETATALK_RESERVEDPORT:
case PRIV_NETINET_RESERVEDPORT:
case PRIV_NETINET_RAW:
case PRIV_NETINET_REUSEPORT:
@ -2987,8 +2975,6 @@ static struct mac_policy_ops lomac_ops =
.mpo_mount_destroy_label = lomac_destroy_label,
.mpo_mount_init_label = lomac_init_label,
.mpo_netatalk_aarp_send = lomac_netatalk_aarp_send,
.mpo_netinet_arp_send = lomac_netinet_arp_send,
.mpo_netinet_firewall_reply = lomac_netinet_firewall_reply,
.mpo_netinet_firewall_send = lomac_netinet_firewall_send,

View file

@ -1249,17 +1249,6 @@ mls_mount_create(struct ucred *cred, struct mount *mp, struct label *mplabel)
mls_copy_effective(source, dest);
}
static void
mls_netatalk_aarp_send(struct ifnet *ifp, struct label *ifplabel,
struct mbuf *m, struct label *mlabel)
{
struct mac_mls *dest;
dest = SLOT(mlabel);
mls_set_effective(dest, MAC_MLS_TYPE_EQUAL, 0, NULL);
}
static void
mls_netinet_arp_send(struct ifnet *ifp, struct label *ifplabel,
struct mbuf *m, struct label *mlabel)
@ -3277,8 +3266,6 @@ static struct mac_policy_ops mls_ops =
.mpo_mount_destroy_label = mls_destroy_label,
.mpo_mount_init_label = mls_init_label,
.mpo_netatalk_aarp_send = mls_netatalk_aarp_send,
.mpo_netinet_arp_send = mls_netinet_arp_send,
.mpo_netinet_firewall_reply = mls_netinet_firewall_reply,
.mpo_netinet_firewall_send = mls_netinet_firewall_send,

View file

@ -533,13 +533,6 @@ stub_mount_create(struct ucred *cred, struct mount *mp,
}
static void
stub_netatalk_aarp_send(struct ifnet *ifp, struct label *iflpabel,
struct mbuf *m, struct label *mlabel)
{
}
static void
stub_netinet_arp_send(struct ifnet *ifp, struct label *iflpabel,
struct mbuf *m, struct label *mlabel)
@ -1756,8 +1749,6 @@ static struct mac_policy_ops stub_ops =
.mpo_mount_destroy_label = stub_destroy_label,
.mpo_mount_init_label = stub_init_label,
.mpo_netatalk_aarp_send = stub_netatalk_aarp_send,
.mpo_netinet_arp_send = stub_netinet_arp_send,
.mpo_netinet_firewall_reply = stub_netinet_firewall_reply,
.mpo_netinet_firewall_send = stub_netinet_firewall_send,

View file

@ -1018,17 +1018,6 @@ test_mount_init_label(struct label *label)
COUNTER_INC(mount_init_label);
}
COUNTER_DECL(netatalk_aarp_send);
static void
test_netatalk_aarp_send(struct ifnet *ifp, struct label *ifplabel,
struct mbuf *m, struct label *mlabel)
{
LABEL_CHECK(ifplabel, MAGIC_IFNET);
LABEL_CHECK(mlabel, MAGIC_MBUF);
COUNTER_INC(netatalk_aarp_send);
}
COUNTER_DECL(netinet_arp_send);
static void
test_netinet_arp_send(struct ifnet *ifp, struct label *ifplabel,
@ -3104,8 +3093,6 @@ static struct mac_policy_ops test_ops =
.mpo_mount_destroy_label = test_mount_destroy_label,
.mpo_mount_init_label = test_mount_init_label,
.mpo_netatalk_aarp_send = test_netatalk_aarp_send,
.mpo_netinet_arp_send = test_netinet_arp_send,
.mpo_netinet_fragment = test_netinet_fragment,
.mpo_netinet_icmp_reply = test_netinet_icmp_reply,

View file

@ -58,7 +58,7 @@
* in the range 5 to 9.
*/
#undef __FreeBSD_version
#define __FreeBSD_version 1100012 /* Master, propagated to newvers */
#define __FreeBSD_version 1100013 /* Master, propagated to newvers */
/*
* __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,

View file

@ -346,11 +346,6 @@
#define PRIV_NET80211_GETKEY 440 /* Query 802.11 keys. */
#define PRIV_NET80211_MANAGE 441 /* Administer 802.11. */
/*
* AppleTalk privileges.
*/
#define PRIV_NETATALK_RESERVEDPORT 450 /* Bind low port number. */
/*
* ATM privileges.
*/

View file

@ -28,11 +28,11 @@ considered to be the name of the test. Naming tests is optional, but
encouraged.
A test may be written which is conditional, and may need to be skipped.
For example, the netatalk tests require 'options NETATALK' in the kernel.
For example, the netinet tests require 'options INET' in the kernel.
A test may be skipped by printing '# skip Reason for skipping' after the
test name. For example,
ok 1 - netatalk # skip 'options NETATALK' not compiled in
ok 1 - netinet # skip 'options INET' not compiled in
A test may be flagged as 'todo'. This indicates that you expect the test
to fail (perhaps because the necessary functionality hasn't been written

View file

@ -1,8 +0,0 @@
#
# $FreeBSD$
#
PROG= simple_send
NO_MAN=
.include <bsd.prog.mk>

View file

@ -1,162 +0,0 @@
/*-
* Copyright (c) 2004 Robert N. M. Watson
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netatalk/at.h>
#include <err.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
/*
* This is a simple test tool to bind netatalk SOCK_DGRAM sockets and perform
* simple send operations that exercise each combination of bound and
* connected endpoints, with the intent of exercising the various kernel send
* case.
*
* In order to run this test, configure NETATALK into the kernel. Use
* ifconfig to set an appletalk address on an interface. Run this tool with
* two arguments: a local address and port number, and a remote address and
* port number.
*
* It is recommended that you try running it with some interesting address
* and port thresholds, including ATADDR_ANYNET, ATADDR_ANYNODE,
* ATADDR_ANYPORT, and ATADDR_ANYBCAST. Try both remote unicast addresses
* and the local address, which will help to test local delivery (although
* not socket receive).
*/
/*
* Create a netatalk socket with specified source and destination, if
* desired. If a source is specified, bind it. If a destination is
* specified, connect it.
*/
static int
socket_between(struct sockaddr_at *from, struct sockaddr_at *to)
{
int s;
s = socket(PF_APPLETALK, SOCK_DGRAM, ATPROTO_DDP);
if (s == -1)
errx(1, "socket: %s\n", strerror(errno));
if (from != NULL) {
if (bind(s, (struct sockaddr *)from, sizeof(*from)) != 0)
errx(1, "bind: %u.%u returned %s\n",
ntohs(from->sat_addr.s_net), from->sat_addr.s_node,
strerror(errno));
}
if (to != NULL) {
if (connect(s, (struct sockaddr *)to, sizeof(*to)) != 0)
errx(1, "connect: %u.%u returned %s\n",
ntohs(to->sat_addr.s_net), to->sat_addr.s_node,
strerror(errno));
}
return (s);
}
int
main(int argc, char *argv[])
{
struct sockaddr_at sat_from, sat_to;
char *addr_from, *addr_to;
u_int net, node, port;
char msg[] = "TEST";
ssize_t len;
int s;
if (argc != 3)
errx(1, "simple_send from_addr to_addr");
addr_from = argv[1];
sat_from.sat_family = AF_APPLETALK;
sat_from.sat_len = sizeof(sat_from);
if (sscanf(addr_from, "%u.%u:%u", &net, &node, &port) != 3 ||
net > 0xfff || node > 0xfe)
errx(1, "%s: illegal address", addr_from);
sat_from.sat_addr.s_net = htons(net);
sat_from.sat_addr.s_node = node;
sat_from.sat_port = port;
addr_to = argv[2];
sat_to.sat_family = AF_APPLETALK;
sat_to.sat_len = sizeof(sat_to);
if (sscanf(addr_to, "%u.%u:%u", &net, &node, &port) != 3 ||
net > 0xffff || node > 0xfe)
errx(1, "%s: illegal address", addr_to);
sat_to.sat_addr.s_net = htons(net);
sat_to.sat_addr.s_node = node;
sat_from.sat_port = port;
printf("Address source is %u.%u:%u, address destination is %u.%u:%u\n",
ntohs(sat_from.sat_addr.s_net), sat_from.sat_addr.s_node,
sat_from.sat_port,
ntohs(sat_to.sat_addr.s_net), sat_to.sat_addr.s_node,
sat_to.sat_port);
/*
* First, create a socket and use explicit sendto() to specify
* destination.
*/
s = socket_between(NULL, NULL);
len = sendto(s, msg, sizeof(msg), 0, (struct sockaddr *)&sat_to,
sizeof(sat_to));
close(s);
/*
* Next, specify the destination for a connect() but not the source.
*/
s = socket_between(NULL, &sat_to);
len = send(s, msg, sizeof(msg), 0);
close(s);
/*
* Now, bind the source, but not connect the destination.
*/
s = socket_between(&sat_from, NULL);
len = sendto(s, msg, sizeof(msg), 0, (struct sockaddr *)&sat_to,
sizeof(sat_to));
close(s);
/*
* Finally, bind and connect.
*/
s = socket_between(&sat_from, &sat_to);
len = send(s, msg, sizeof(msg), 0);
close(s);
exit(0);
}

View file

@ -45,7 +45,6 @@
#include <net/if_dl.h>
#include <netinet/in.h>
#include <netinet/if_ether.h>
#include <netatalk/at.h>
#ifdef __NetBSD__
#include <net80211/ieee80211_netbsd.h>
#elif __FreeBSD__

View file

@ -50,7 +50,6 @@
#include <net/if_dl.h>
#include <netinet/in.h>
#include <netinet/if_ether.h>
#include <netatalk/at.h>
#include "net80211/ieee80211_ioctl.h"
#include "net80211/ieee80211_freebsd.h"
#include <arpa/inet.h>

View file

@ -60,9 +60,6 @@ extern int errno;
#include <sys/un.h>
#include <sys/queue.h>
#include <sys/wait.h>
#ifdef NETATALK
#include <netatalk/at.h>
#endif
#include <arpa/inet.h>
#include <netinet/in.h>
#include <ctype.h>
@ -1656,21 +1653,6 @@ ktrsockaddr(struct sockaddr *sa)
printf("%s:%u", addr, ntohs(sa_in.sin_port));
break;
}
#ifdef NETATALK
case AF_APPLETALK: {
struct sockaddr_at sa_at;
struct netrange *nr;
memset(&sa_at, 0, sizeof(sa_at));
memcpy(&sa_at, sa, sa->sa_len);
check_sockaddr_len(at);
nr = &sa_at.sat_range.r_netrange;
printf("%d.%d, %d-%d, %d", ntohs(sa_at.sat_addr.s_net),
sa_at.sat_addr.s_node, ntohs(nr->nr_firstnet),
ntohs(nr->nr_lastnet), nr->nr_phase);
break;
}
#endif
case AF_INET6: {
struct sockaddr_in6 sa_in6;

View file

@ -5,7 +5,7 @@
PROG= netstat
SRCS= if.c inet.c main.c mbuf.c mroute.c netisr.c route.c \
unix.c atalk.c mroute6.c ipsec.c bpf.c pfkey.c sctp.c \
unix.c mroute6.c ipsec.c bpf.c pfkey.c sctp.c \
flowtable.c
WARNS?= 3

View file

@ -1,285 +0,0 @@
/*-
* Copyright (c) 1983, 1988, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if 0
#ifndef lint
static char sccsid[] = "@(#)atalk.c 1.1 (Whistle) 6/6/96";
#endif /* not lint */
#endif
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/queue.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/protosw.h>
#include <arpa/inet.h>
#include <net/route.h>
#include <netatalk/at.h>
#include <netatalk/ddp_var.h>
#include <errno.h>
#include <nlist.h>
#include <netdb.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "netstat.h"
struct ddpcb ddpcb;
struct socket sockb;
static int first = 1;
/*
* Print a summary of connections related to a Network Systems
* protocol. For XXX, also give state of connection.
* Listening processes (aflag) are suppressed unless the
* -a (all) flag is specified.
*/
static const char *
at_pr_net(struct sockaddr_at *sat, int numeric)
{
static char mybuf[50];
if (!numeric) {
switch(sat->sat_addr.s_net) {
case 0xffff:
return "????";
case ATADDR_ANYNET:
return("*");
}
}
sprintf(mybuf,"%hu",ntohs(sat->sat_addr.s_net));
return mybuf;
}
static const char *
at_pr_host(struct sockaddr_at *sat, int numeric)
{
static char mybuf[50];
if (!numeric) {
switch(sat->sat_addr.s_node) {
case ATADDR_BCAST:
return "bcast";
case ATADDR_ANYNODE:
return("*");
}
}
sprintf(mybuf,"%d",(unsigned int)sat->sat_addr.s_node);
return mybuf;
}
static const char *
at_pr_port(struct sockaddr_at *sat)
{
static char mybuf[50];
struct servent *serv;
switch(sat->sat_port) {
case ATADDR_ANYPORT:
return("*");
case 0xff:
return "????";
default:
if (numeric_port) {
(void)snprintf(mybuf, sizeof(mybuf), "%d",
(unsigned int)sat->sat_port);
} else {
serv = getservbyport(sat->sat_port, "ddp");
if (serv == NULL)
(void)snprintf(mybuf, sizeof(mybuf), "%d",
(unsigned int) sat->sat_port);
else
(void) snprintf(mybuf, sizeof(mybuf), "%s",
serv->s_name);
}
}
return mybuf;
}
static char *
at_pr_range(struct sockaddr_at *sat)
{
static char mybuf[50];
if(sat->sat_range.r_netrange.nr_firstnet
!= sat->sat_range.r_netrange.nr_lastnet) {
sprintf(mybuf,"%d-%d",
ntohs(sat->sat_range.r_netrange.nr_firstnet),
ntohs(sat->sat_range.r_netrange.nr_lastnet));
} else {
sprintf(mybuf,"%d",
ntohs(sat->sat_range.r_netrange.nr_firstnet));
}
return mybuf;
}
/* what == 0 for addr only == 3 */
/* 1 for net */
/* 2 for host */
/* 4 for port */
/* 8 for numeric only */
char *
atalk_print(struct sockaddr *sa, int what)
{
struct sockaddr_at *sat = (struct sockaddr_at *)sa;
static char mybuf[50];
int numeric = (what & 0x08);
mybuf[0] = 0;
switch (what & 0x13) {
case 0:
mybuf[0] = 0;
break;
case 1:
sprintf(mybuf,"%s",at_pr_net(sat, numeric));
break;
case 2:
sprintf(mybuf,"%s",at_pr_host(sat, numeric));
break;
case 3:
sprintf(mybuf,"%s.%s",
at_pr_net(sat, numeric),
at_pr_host(sat, numeric));
break;
case 0x10:
sprintf(mybuf,"%s", at_pr_range(sat));
}
if (what & 4) {
sprintf(mybuf+strlen(mybuf),".%s",at_pr_port(sat));
}
return mybuf;
}
char *
atalk_print2(struct sockaddr *sa, struct sockaddr *mask, int what)
{
int n;
static char buf[100];
struct sockaddr_at *sat1, *sat2;
struct sockaddr_at thesockaddr;
struct sockaddr *sa2;
sat1 = (struct sockaddr_at *)sa;
sat2 = (struct sockaddr_at *)mask;
sa2 = (struct sockaddr *)&thesockaddr;
thesockaddr.sat_addr.s_net = sat1->sat_addr.s_net & sat2->sat_addr.s_net;
snprintf(buf, sizeof(buf), "%s", atalk_print(sa2, 1 |(what & 8)));
if(sat2->sat_addr.s_net != 0xFFFF) {
thesockaddr.sat_addr.s_net = sat1->sat_addr.s_net | ~sat2->sat_addr.s_net;
n = strlen(buf);
snprintf(buf + n, sizeof(buf) - n, "-%s", atalk_print(sa2, 1 |(what & 8)));
}
if(what & 2) {
n = strlen(buf);
snprintf(buf + n, sizeof(buf) - n, ".%s", atalk_print(sa, what & (~1)));
}
return(buf);
}
void
atalkprotopr(u_long off __unused, const char *name, int af1 __unused,
int proto __unused)
{
struct ddpcb *this, *next;
if (off == 0)
return;
kread(off, (char *)&this, sizeof (struct ddpcb *));
for ( ; this != NULL; this = next) {
kread((u_long)this, (char *)&ddpcb, sizeof (ddpcb));
next = ddpcb.ddp_next;
#if 0
if (!aflag && atalk_nullhost(ddpcb.ddp_lsat) ) {
continue;
}
#endif
kread((u_long)ddpcb.ddp_socket, (char *)&sockb, sizeof (sockb));
if (first) {
printf("Active ATALK connections");
if (aflag)
printf(" (including servers)");
putchar('\n');
if (Aflag)
printf("%-8.8s ", "PCB");
printf(Aflag ?
"%-5.5s %-6.6s %-6.6s %-18.18s %-18.18s %s\n" :
"%-5.5s %-6.6s %-6.6s %-22.22s %-22.22s %s\n",
"Proto", "Recv-Q", "Send-Q",
"Local Address", "Foreign Address", "(state)");
first = 0;
}
if (Aflag)
printf("%8lx ", (u_long) this);
printf("%-5.5s %6u %6u ", name, sockb.so_rcv.sb_cc,
sockb.so_snd.sb_cc);
printf(Aflag?" %-18.18s":" %-22.22s", atalk_print(
(struct sockaddr *)&ddpcb.ddp_lsat,7));
printf(Aflag?" %-18.18s":" %-22.22s", atalk_print(
(struct sockaddr *)&ddpcb.ddp_fsat,7));
putchar('\n');
}
}
#define ANY(x,y,z) if (x || sflag <= 1) \
printf("\t%lu %s%s%s\n",x,y,plural(x),z)
/*
* Dump DDP statistics structure.
*/
void
ddp_stats(u_long off __unused, const char *name, int af1 __unused,
int proto __unused)
{
struct ddpstat ddpstat;
if (off == 0)
return;
kread(off, (char *)&ddpstat, sizeof (ddpstat));
printf("%s:\n", name);
ANY(ddpstat.ddps_short, "packet", " with short headers ");
ANY(ddpstat.ddps_long, "packet", " with long headers ");
ANY(ddpstat.ddps_nosum, "packet", " with no checksum ");
ANY(ddpstat.ddps_tooshort, "packet", " too short ");
ANY(ddpstat.ddps_badsum, "packet", " with bad checksum ");
ANY(ddpstat.ddps_toosmall, "packet", " with not enough data ");
ANY(ddpstat.ddps_forward, "packet", " forwarded ");
ANY(ddpstat.ddps_encap, "packet", " encapsulated ");
ANY(ddpstat.ddps_cantforward, "packet", " rcvd for unreachable dest ");
ANY(ddpstat.ddps_nosockspace, "packet", " dropped due to no socket space ");
}

View file

@ -323,12 +323,6 @@ intpr(int interval, void (*pfunc)(char *), int af)
break;
}
#endif /* INET6 */
case AF_APPLETALK:
printf("atalk:%-12.12s ",
atalk_print(ifa->ifa_addr, 0x10));
printf("%-11.11s ",
atalk_print(ifa->ifa_addr, 0x0b));
break;
case AF_LINK:
{
struct sockaddr_dl *sdl;

View file

@ -80,81 +80,77 @@ static struct nlist nl[] = {
{ .n_name = "_mfchashtbl" },
#define N_VIFTABLE 4
{ .n_name = "_viftable" },
#define N_DDPSTAT 5
{ .n_name = "_ddpstat"},
#define N_DDPCB 6
{ .n_name = "_ddpcb"},
#define N_NGSOCKS 7
#define N_NGSOCKS 5
{ .n_name = "_ngsocklist"},
#define N_IP6STAT 8
#define N_IP6STAT 6
{ .n_name = "_ip6stat" },
#define N_ICMP6STAT 9
#define N_ICMP6STAT 7
{ .n_name = "_icmp6stat" },
#define N_IPSECSTAT 10
#define N_IPSECSTAT 8
{ .n_name = "_ipsec4stat" },
#define N_IPSEC6STAT 11
#define N_IPSEC6STAT 9
{ .n_name = "_ipsec6stat" },
#define N_PIM6STAT 12
#define N_PIM6STAT 10
{ .n_name = "_pim6stat" },
#define N_MRT6STAT 13
#define N_MRT6STAT 11
{ .n_name = "_mrt6stat" },
#define N_MF6CTABLE 14
#define N_MF6CTABLE 12
{ .n_name = "_mf6ctable" },
#define N_MIF6TABLE 15
#define N_MIF6TABLE 13
{ .n_name = "_mif6table" },
#define N_PFKEYSTAT 16
#define N_PFKEYSTAT 14
{ .n_name = "_pfkeystat" },
#define N_RTTRASH 17
#define N_RTTRASH 15
{ .n_name = "_rttrash" },
#define N_CARPSTAT 18
#define N_CARPSTAT 16
{ .n_name = "_carpstats" },
#define N_PFSYNCSTAT 19
#define N_PFSYNCSTAT 17
{ .n_name = "_pfsyncstats" },
#define N_AHSTAT 20
#define N_AHSTAT 18
{ .n_name = "_ahstat" },
#define N_ESPSTAT 21
#define N_ESPSTAT 19
{ .n_name = "_espstat" },
#define N_IPCOMPSTAT 22
#define N_IPCOMPSTAT 20
{ .n_name = "_ipcompstat" },
#define N_TCPSTAT 23
#define N_TCPSTAT 21
{ .n_name = "_tcpstat" },
#define N_UDPSTAT 24
#define N_UDPSTAT 22
{ .n_name = "_udpstat" },
#define N_IPSTAT 25
#define N_IPSTAT 23
{ .n_name = "_ipstat" },
#define N_ICMPSTAT 26
#define N_ICMPSTAT 24
{ .n_name = "_icmpstat" },
#define N_IGMPSTAT 27
#define N_IGMPSTAT 25
{ .n_name = "_igmpstat" },
#define N_PIMSTAT 28
#define N_PIMSTAT 26
{ .n_name = "_pimstat" },
#define N_TCBINFO 29
#define N_TCBINFO 27
{ .n_name = "_tcbinfo" },
#define N_UDBINFO 30
#define N_UDBINFO 28
{ .n_name = "_udbinfo" },
#define N_DIVCBINFO 31
#define N_DIVCBINFO 29
{ .n_name = "_divcbinfo" },
#define N_RIPCBINFO 32
#define N_RIPCBINFO 30
{ .n_name = "_ripcbinfo" },
#define N_UNP_COUNT 33
#define N_UNP_COUNT 31
{ .n_name = "_unp_count" },
#define N_UNP_GENCNT 34
#define N_UNP_GENCNT 32
{ .n_name = "_unp_gencnt" },
#define N_UNP_DHEAD 35
#define N_UNP_DHEAD 33
{ .n_name = "_unp_dhead" },
#define N_UNP_SHEAD 36
#define N_UNP_SHEAD 34
{ .n_name = "_unp_shead" },
#define N_RIP6STAT 37
#define N_RIP6STAT 36
{ .n_name = "_rip6stat" },
#define N_SCTPSTAT 38
#define N_SCTPSTAT 36
{ .n_name = "_sctpstat" },
#define N_MFCTABLESIZE 39
#define N_MFCTABLESIZE 37
{ .n_name = "_mfctablesize" },
#define N_ARPSTAT 40
#define N_ARPSTAT 38
{ .n_name = "_arpstat" },
#define N_UNP_SPHEAD 41
#define N_UNP_SPHEAD 39
{ .n_name = "unp_sphead" },
#define N_SFSTAT 42
#define N_SFSTAT 40
{ .n_name = "_sfstat"},
{ .n_name = NULL },
};
@ -254,12 +250,6 @@ struct protox pfkeyprotox[] = {
};
#endif
struct protox atalkprotox[] = {
{ N_DDPCB, N_DDPSTAT, 1, atalkprotopr,
ddp_stats, NULL, "ddp", 0, 0 },
{ -1, -1, 0, NULL,
NULL, NULL, NULL, 0, 0 }
};
#ifdef NETGRAPH
struct protox netgraphprotox[] = {
{ N_NGSOCKS, -1, 1, netgraphprotopr,
@ -279,7 +269,7 @@ struct protox *protoprotox[] = {
#ifdef IPSEC
pfkeyprotox,
#endif
atalkprotox, NULL };
NULL };
static void printproto(struct protox *, const char *);
static void usage(void);
@ -380,8 +370,6 @@ main(int argc, char *argv[])
#endif
else if (strcmp(optarg, "unix") == 0)
af = AF_UNIX;
else if (strcmp(optarg, "atalk") == 0)
af = AF_APPLETALK;
#ifdef NETGRAPH
else if (strcmp(optarg, "ng") == 0
|| strcmp(optarg, "netgraph") == 0)
@ -595,9 +583,6 @@ main(int argc, char *argv[])
for (tp = pfkeyprotox; tp->pr_name; tp++)
printproto(tp, tp->pr_name);
#endif /*IPSEC*/
if (af == AF_APPLETALK || af == AF_UNSPEC)
for (tp = atalkprotox; tp->pr_name; tp++)
printproto(tp, tp->pr_name);
#ifdef NETGRAPH
if (af == AF_NETGRAPH || af == AF_UNSPEC)
for (tp = netgraphprotox; tp->pr_name; tp++)

View file

@ -350,8 +350,6 @@ The following address families and protocols are recognized:
.Cm icmp6 , ip6 , ipsec6 , rip6 , tcp , udp
.It Cm pfkey Pq Dv PF_KEY
.Cm pfkey
.It Cm atalk Pq Dv AF_APPLETALK
.Cm ddp
.It Cm netgraph , ng Pq Dv AF_NETGRAPH
.Cm ctrl , data
.It Cm unix Pq Dv AF_UNIX

View file

@ -130,8 +130,6 @@ void flowtable_stats(void);
char *routename(in_addr_t);
char *netname(in_addr_t, in_addr_t);
char *atalk_print(struct sockaddr *, int);
char *atalk_print2(struct sockaddr *, struct sockaddr *, int);
char *ns_print(struct sockaddr *);
void routepr(int, int);
@ -140,9 +138,6 @@ void spp_stats(u_long, const char *, int, int);
void idp_stats(u_long, const char *, int, int);
void nserr_stats(u_long, const char *, int, int);
void atalkprotopr(u_long, const char *, int, int);
void ddp_stats(u_long, const char *, int, int);
#ifdef NETGRAPH
void netgraphprotopr(u_long, const char *, int, int);
#endif

View file

@ -52,7 +52,6 @@ __FBSDID("$FreeBSD$");
#include <net/route.h>
#include <netinet/in.h>
#include <netatalk/at.h>
#include <netgraph/ng_socket.h>
#include <sys/sysctl.h>
@ -218,9 +217,6 @@ pr_family(int af1)
case AF_ISO:
afname = "ISO";
break;
case AF_APPLETALK:
afname = "AppleTalk";
break;
case AF_CCITT:
afname = "X.25";
break;
@ -750,14 +746,6 @@ fmt_sockaddr(struct sockaddr *sa, struct sockaddr *mask, int flags)
}
#endif /*INET6*/
case AF_APPLETALK:
{
if (!(flags & RTF_HOST) && mask)
cp = atalk_print2(sa,mask,9);
else
cp = atalk_print(sa,11);
break;
}
case AF_NETGRAPH:
{
strlcpy(workbuf, ((struct sockaddr_ng *)sa)->sg_data,