Reviewed by: julian and jhay@mikom.csir.co.za

Submitted by:	Mike Mitchell, supervisor@alb.asctmd.com

This is a bulk mport of Mike's IPX/SPX protocol stacks and all the
related gunf that goes with it..
it is not guaranteed to work 100% correctly at this time
but as we had several people trying to work on it
I figured it would be better to get it checked in so
they could all get teh same thing to work on..

Mikes been using it for a year or so
but on 2.0

more changes and stuff will be merged in from other developers now that this is in.

Mike Mitchell, Network Engineer
AMTECH Systems Corporation, Technology and Manufacturing
8600 Jefferson Street, Albuquerque, New Mexico 87113 (505) 856-8000
supervisor@alb.asctmd.com
This commit is contained in:
Julian Elischer 1995-10-26 20:31:59 +00:00
parent 059a9bc2bb
commit cc6a66f20e
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=11819
63 changed files with 7477 additions and 51 deletions

View File

@ -13,7 +13,7 @@ SUBDIR=csu/${MACHINE}
SUBDIR+= libc libcompat libcom_err libcurses libedit \
libf2c libforms \
libkvm libmd libmytinfo libncurses libpcap libresolv librpcsvc \
libscsi libskey libss libtermcap libutil libxpg4 liby
libscsi libskey libss libtermcap libutil libxpg4 liby libipx
.if !exists(../secure) || defined(NOSECURE) || defined(NOCRYPT)
SUBDIR+= libcrypt

9
lib/libipx/Makefile Normal file
View File

@ -0,0 +1,9 @@
LIB= ipx
#CFLAGS+=-DLIBC_SCCS -I/sys
SRCS= ipx_addr.c ipx_ntoa.c
MAN3= ipx.3
MLINKS+=ipx.3 ipx_addr.3 ipx.3 ipx_ntoa.3
.include <bsd.lib.mk>

127
lib/libipx/ipx.3 Normal file
View File

@ -0,0 +1,127 @@
.\" Copyright (c) 1986, 1991, 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.
.\" 3. All advertising materials mentioning features or use of this software
.\" must display the following acknowledgement:
.\" This product includes software developed by the University of
.\" California, Berkeley and its contributors.
.\" 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.
.\"
.\"
.Dd June 4, 1993
.Dt IPX 3
.Os BSD 4.3
.Sh NAME
.Nm ipx_addr ,
.Nm ipx_ntoa
.\" .Nd Novell
.Tn IPX
address conversion routines
.Sh SYNOPSIS
.Fd #include <sys/types.h>
.Fd #include <netipx/ipx.h>
.Ft struct ipx_addr
.Fn ipx_addr "char *cp"
.Ft char *
.Fn ipx_ntoa "struct ipx_addr ipx"
.Sh DESCRIPTION
The routine
.Fn ipx_addr
interprets character strings representing
.Tn IPX
addresses, returning binary information suitable
for use in system calls.
The routine
.Fn ipx_ntoa
takes
.Tn IPX
addresses and returns
.Tn ASCII
strings representing the address in a
notation in common use:
.Bd -filled -offset indent
<network number>.<host number>.<port number>
.Ed
.Pp
Trailing zero fields are suppressed, and each number is printed in hexadecimal,
in a format suitable for input to
.Fn ipx_addr .
Any fields lacking super-decimal digits will have a
trailing
.Ql H
appended.
.Pp
An effort has been made to insure that
.Fn ipx_addr
be compatible with most formats in common use.
It will first separate an address into 1 to 3 fields using a single delimiter
chosen from
period
.Ql \&. ,
colon
.Ql \&:
or pound-sign
.Ql \&# .
Each field is then examined for byte separators (colon or period).
If there are byte separators, each subfield separated is taken to be
a small hexadecimal number, and the entirety is taken as a network-byte-ordered
quantity to be zero extended in the high-network-order bytes.
Next, the field is inspected for hyphens, in which case
the field is assumed to be a number in decimal notation
with hyphens separating the millenia.
Next, the field is assumed to be a number:
It is interpreted
as hexadecimal if there is a leading
.Ql 0x
(as in C),
a trailing
.Ql H
(as in Mesa), or there are any super-decimal digits present.
It is interpreted as octal is there is a leading
.Ql 0
and there are no super-octal digits.
Otherwise, it is converted as a decimal number.
.Sh RETURN VALUES
None. (See
.Sx BUGS . )
.Sh SEE ALSO
.Xr hosts 5 ,
.Xr networks 5 ,
.Xr ns 5 ,
.Sh HISTORY
The precursor
.Fn ns_addr
and
.Fn ns_toa
functions appeared in
.Bx 4.3 .
.Sh BUGS
The string returned by
.Fn ipx_ntoa
resides in a static memory area.
The function
.Fn ipx_addr
should diagnose improperly formed input, and there should be an unambiguous
way to recognize this.

227
lib/libipx/ipx_addr.c Normal file
View File

@ -0,0 +1,227 @@
/*
* Copyright (c) 1986, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* J.Q. Johnson.
*
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 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 defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)ipx_addr.c";
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
#include <netipx/ipx.h>
#include <stdio.h>
#include <string.h>
static struct ipx_addr addr, zero_addr;
static void Field(), cvtbase();
struct ipx_addr
ipx_addr(name)
const char *name;
{
char separator;
char *hostname, *socketname, *cp;
char buf[50];
(void)strncpy(buf, name, sizeof(buf) - 1);
buf[sizeof(buf) - 1] = '\0';
/*
* First, figure out what he intends as a field separtor.
* Despite the way this routine is written, the prefered
* form 2-272.AA001234H.01777, i.e. XDE standard.
* Great efforts are made to insure backward compatability.
*/
if (hostname = strchr(buf, '#'))
separator = '#';
else {
hostname = strchr(buf, '.');
if ((cp = strchr(buf, ':')) &&
((hostname && cp < hostname) || (hostname == 0))) {
hostname = cp;
separator = ':';
} else
separator = '.';
}
if (hostname)
*hostname++ = 0;
addr = zero_addr;
Field(buf, addr.x_net.c_net, 4);
if (hostname == 0)
return (addr); /* No separator means net only */
socketname = strchr(hostname, separator);
if (socketname) {
*socketname++ = 0;
Field(socketname, (u_char *)&addr.x_port, 2);
}
Field(hostname, addr.x_host.c_host, 6);
return (addr);
}
static void
Field(buf, out, len)
char *buf;
u_char *out;
int len;
{
register char *bp = buf;
int i, ibase, base16 = 0, base10 = 0, clen = 0;
int hb[6], *hp;
char *fmt;
/*
* first try 2-273#2-852-151-014#socket
*/
if ((*buf != '-') &&
(1 < (i = sscanf(buf, "%d-%d-%d-%d-%d",
&hb[0], &hb[1], &hb[2], &hb[3], &hb[4])))) {
cvtbase(1000L, 256, hb, i, out, len);
return;
}
/*
* try form 8E1#0.0.AA.0.5E.E6#socket
*/
if (1 < (i = sscanf(buf,"%x.%x.%x.%x.%x.%x",
&hb[0], &hb[1], &hb[2], &hb[3], &hb[4], &hb[5]))) {
cvtbase(256L, 256, hb, i, out, len);
return;
}
/*
* try form 8E1#0:0:AA:0:5E:E6#socket
*/
if (1 < (i = sscanf(buf,"%x:%x:%x:%x:%x:%x",
&hb[0], &hb[1], &hb[2], &hb[3], &hb[4], &hb[5]))) {
cvtbase(256L, 256, hb, i, out, len);
return;
}
/*
* This is REALLY stretching it but there was a
* comma notation separting shorts -- definitely non standard
*/
if (1 < (i = sscanf(buf,"%x,%x,%x",
&hb[0], &hb[1], &hb[2]))) {
hb[0] = htons(hb[0]); hb[1] = htons(hb[1]);
hb[2] = htons(hb[2]);
cvtbase(65536L, 256, hb, i, out, len);
return;
}
/* Need to decide if base 10, 16 or 8 */
while (*bp) switch (*bp++) {
case '0': case '1': case '2': case '3': case '4': case '5':
case '6': case '7': case '-':
break;
case '8': case '9':
base10 = 1;
break;
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
base16 = 1;
break;
case 'x': case 'X':
*--bp = '0';
base16 = 1;
break;
case 'h': case 'H':
base16 = 1;
/* fall into */
default:
*--bp = 0; /* Ends Loop */
}
if (base16) {
fmt = "%3x";
ibase = 4096;
} else if (base10 == 0 && *buf == '0') {
fmt = "%3o";
ibase = 512;
} else {
fmt = "%3d";
ibase = 1000;
}
for (bp = buf; *bp++; ) clen++;
if (clen == 0) clen++;
if (clen > 18) clen = 18;
i = ((clen - 1) / 3) + 1;
bp = clen + buf - 3;
hp = hb + i - 1;
while (hp > hb) {
(void)sscanf(bp, fmt, hp);
bp[0] = 0;
hp--;
bp -= 3;
}
(void)sscanf(buf, fmt, hp);
cvtbase((long)ibase, 256, hb, i, out, len);
}
static void
cvtbase(oldbase,newbase,input,inlen,result,reslen)
long oldbase;
int newbase;
int input[];
int inlen;
unsigned char result[];
int reslen;
{
int d, e;
long sum;
e = 1;
while (e > 0 && reslen > 0) {
d = 0; e = 0; sum = 0;
/* long division: input=input/newbase */
while (d < inlen) {
sum = sum*oldbase + (long) input[d];
e += (sum > 0);
input[d++] = sum / newbase;
sum %= newbase;
}
result[--reslen] = sum; /* accumulate remainder */
}
for (d=0; d < reslen; d++)
result[d] = 0;
}

98
lib/libipx/ipx_ntoa.c Normal file
View File

@ -0,0 +1,98 @@
/*
* Copyright (c) 1986, 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 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 defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)ipx_ntoa.c";
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
#include <netipx/ipx.h>
#include <stdio.h>
char *
ipx_ntoa(addr)
struct ipx_addr addr;
{
static char obuf[40];
union { union ipx_net net_e; u_long long_e; } net;
u_short port = htons(addr.x_port);
register char *cp;
char *cp2;
register u_char *up = addr.x_host.c_host;
u_char *uplim = up + 6;
static char *spectHex();
net.net_e = addr.x_net;
sprintf(obuf, "%lx", ntohl(net.long_e));
cp = spectHex(obuf);
cp2 = cp + 1;
while (*up==0 && up < uplim) up++;
if (up == uplim) {
if (port) {
sprintf(cp, ".0");
cp += 2;
}
} else {
sprintf(cp, ".%x", *up++);
while (up < uplim) {
while (*cp) cp++;
sprintf(cp, "%02x", *up++);
}
cp = spectHex(cp2);
}
if (port) {
sprintf(cp, ".%x", port);
spectHex(cp + 1);
}
return (obuf);
}
static char *
spectHex(p0)
char *p0;
{
int ok = 0;
int nonzero = 0;
register char *p = p0;
for (; *p; p++) switch (*p) {
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
ok = 1;
case '1': case '2': case '3': case '4': case '5':
case '6': case '7': case '8': case '9':
nonzero = 1;
}
if (nonzero && !ok) { *p++ = 'H'; *p = 0; }
return (p);
}

View File

@ -50,11 +50,16 @@ static char sccsid[] = "@(#)ifconfig.c 8.2 (Berkeley) 2/16/94";
#include <netinet/in.h>
#include <netinet/in_var.h>
#include <arpa/inet.h>
#include <netdb.h>
#define IPXIP
#define IPTUNNEL
#include <netipx/ipx.h>
#include <netipx/ipx_if.h>
#define NSIP
#include <netns/ns.h>
#include <netns/ns_if.h>
#include <netdb.h>
#define EON
#include <netiso/iso.h>
@ -144,6 +149,7 @@ struct cmd {
* Maryland principally by James O'Toole and Chris Torek.
*/
int in_status(), in_getaddr();
int ipx_status(), ipx_getaddr();
int xns_status(), xns_getaddr();
int iso_status(), iso_getaddr();
int ether_status();
@ -162,6 +168,8 @@ struct afswtch {
#define C(x) ((caddr_t) &x)
{ "inet", AF_INET, in_status, in_getaddr,
SIOCDIFADDR, SIOCAIFADDR, C(ridreq), C(addreq) },
{ "ipx", AF_IPX, ipx_status, ipx_getaddr,
SIOCDIFADDR, SIOCAIFADDR, C(ridreq), C(addreq) },
{ "ns", AF_NS, xns_status, xns_getaddr,
SIOCDIFADDR, SIOCAIFADDR, C(ridreq), C(addreq) },
{ "iso", AF_ISO, iso_status, iso_getaddr,
@ -313,6 +321,16 @@ ifconfig(argc,argv,af,rafp,flag)
}
if (af == AF_ISO)
adjust_nsellength();
if (setipdst && af==AF_IPX) {
struct ipxip_req rq;
int size = sizeof(rq);
rq.rq_ipx = addreq.ifra_addr;
rq.rq_ip = addreq.ifra_dstaddr;
if (setsockopt(s, 0, SO_IPXIP_ROUTE, &rq, size) < 0)
Perror("Encapsulation Routing");
}
if (setipdst && af==AF_NS) {
struct nsip_req rq;
int size = sizeof(rq);
@ -539,6 +557,43 @@ in_status(force)
putchar('\n');
}
ipx_status(force)
int force;
{
struct sockaddr_ipx *sipx;
close(s);
s = socket(AF_IPX, SOCK_DGRAM, 0);
if (s < 0) {
if (errno == EPROTONOSUPPORT)
return;
perror("ifconfig: socket");
exit(1);
}
if (ioctl(s, SIOCGIFADDR, (caddr_t)&ifr) < 0) {
if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT) {
if (!force)
return;
bzero((char *)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
} else
perror("ioctl (SIOCGIFADDR)");
}
strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name);
sipx = (struct sockaddr_ipx *)&ifr.ifr_addr;
printf("\tipx %s ", ipx_ntoa(sipx->sipx_addr));
if (flags & IFF_POINTOPOINT) { /* by W. Nesheim@Cornell */
if (ioctl(s, SIOCGIFDSTADDR, (caddr_t)&ifr) < 0) {
if (errno == EADDRNOTAVAIL)
bzero((char *)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
else
Perror("ioctl (SIOCGIFDSTADDR)");
}
strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
sipx = (struct sockaddr_ipx *)&ifr.ifr_dstaddr;
printf("--> %s ", ipx_ntoa(sipx->sipx_addr));
}
putchar('\n');
}
xns_status(force)
int force;
@ -793,6 +848,24 @@ printb(s, v, bits)
}
}
#define SIPX(x) ((struct sockaddr_ipx *) &(x))
struct sockaddr_ipx *sipxtab[] = {
SIPX(ridreq.ifr_addr), SIPX(addreq.ifra_addr),
SIPX(addreq.ifra_mask), SIPX(addreq.ifra_broadaddr)};
ipx_getaddr(addr, which)
char *addr;
{
struct sockaddr_ipx *sipx = sipxtab[which];
struct ipx_addr ipx_addr();
sipx->sipx_family = AF_IPX;
sipx->sipx_len = sizeof(*sipx);
sipx->sipx_addr = ipx_addr(addr);
if (which == MASK)
printf("Attempt to set IPX netmask will be ineffectual\n");
}
#define SNS(x) ((struct sockaddr_ns *) &(x))
struct sockaddr_ns *snstab[] = {
SNS(ridreq.ifr_addr), SNS(addreq.ifra_addr),

View File

@ -2,7 +2,7 @@
# LINT -- config file for checking all the sources, tries to pull in
# as much of the source tree as it can.
#
# $Id: LINT,v 1.205 1995/10/10 04:03:12 bde Exp $
# $Id: LINT,v 1.206 1995/10/25 16:43:01 jkh Exp $
#
# NB: You probably don't want to try running a kernel built from this
# file. Instead, you should start from GENERIC, and add options from
@ -129,6 +129,12 @@ options INET #Internet communications protocols
options CCITT #X.25 network layer
options NS #Xerox NS communications protocols
options IPX #IPX/SPX communications protocols
options IPXIP #IPX in IP encapsulation (not available)
options IPTUNNEL #IP in IPX encapsulation (not available)
#options "IPXPRINTFS=0" #Console Debugging Information
#options "IPX_ERRPRINTFS=0" #Console Debugging Information
# These are currently broken and don't compile
#options ISO
#options TPIP #ISO TP class 4 over IP

View File

@ -208,6 +208,18 @@ netinet/tcp_subr.c optional inet
netinet/tcp_timer.c optional inet
netinet/tcp_usrreq.c optional inet
netinet/udp_usrreq.c optional inet
netipx/ipx_usrreq.c optional ipx
netipx/ipx.c optional ipx
netipx/ipx_cksum.c optional ipx
netipx/ipx_error.c optional ipx
netipx/ipx_input.c optional ipx
netipx/ipx_ip.c optional ipx
netipx/ipx_outputfl.c optional ipx
netipx/ipx_pcb.c optional ipx
netipx/ipx_proto.c optional ipx
netipx/ipx_tun.c optional ipx
netipx/spx_debug.c optional ipx
netipx/spx_usrreq.c optional ipx
netiso/clnp_debug.c optional iso
netiso/clnp_er.c optional iso
netiso/clnp_frag.c optional iso

View File

@ -13,7 +13,7 @@
* the SMC Elite Ultra (8216), the 3Com 3c503, the NE1000 and NE2000,
* and a variety of similar clones.
*
* $Id: if_ed.c,v 1.78 1995/10/13 19:47:40 wollman Exp $
* $Id: if_ed.c,v 1.79 1995/10/21 00:55:23 phk Exp $
*/
#include "ed.h"
@ -40,6 +40,11 @@
#include <netinet/if_ether.h>
#endif
#ifdef IPX
#include <netipx/ipx.h>
#include <netipx/ipx_if.h>
#endif
#ifdef NS
#include <netns/ns.h>
#include <netns/ns_if.h>
@ -2256,11 +2261,34 @@ ed_ioctl(ifp, command, data)
arp_ifinit((struct arpcom *)ifp, ifa);
break;
#endif
#ifdef NS
#ifdef IPX
/*
* XXX - This code is probably wrong
*/
case AF_IPX:
{
register struct ipx_addr *ina = &(IA_SIPX(ifa)->sipx_addr);
/*
* XXX - This code is probably wrong
*/
if (ipx_nullhost(*ina))
ina->x_host =
*(union ipx_host *) (sc->arpcom.ac_enaddr);
else {
bcopy((caddr_t) ina->x_host.c_host,
(caddr_t) sc->arpcom.ac_enaddr,
sizeof(sc->arpcom.ac_enaddr));
}
/*
* Set new address
*/
ed_init(ifp->if_unit);
break;
}
#endif
#ifdef NS
/*
* XXX - This code is probably wrong
*/
case AF_NS:
{
register struct ns_addr *ina = &(IA_SNS(ifa)->sns_addr);

View File

@ -38,7 +38,7 @@
*/
/*
* $Id: if_ep.c,v 1.30 1995/08/28 12:01:17 guido Exp $
* $Id: if_ep.c,v 1.31 1995/10/13 19:47:44 wollman Exp $
*
* Promiscuous mode added and interrupt logic slightly changed
* to reduce the number of adapter failures. Transceiver select
@ -82,6 +82,11 @@
#include <netinet/if_ether.h>
#endif
#ifdef IPX
#include <netipx/ipx.h>
#include <netipx/ipx_if.h>
#endif
#ifdef NS
#include <netns/ns.h>
#include <netns/ns_if.h>
@ -1141,6 +1146,24 @@ epioctl(ifp, cmd, data)
arp_ifinit((struct arpcom *)ifp, ifa);
break;
#endif
#ifdef IPX
case AF_IPX:
{
register struct ipx_addr *ina = &(IA_SIPX(ifa)->sipx_addr);
if (ipx_nullhost(*ina))
ina->x_host =
*(union ipx_host *) (sc->arpcom.ac_enaddr);
else {
ifp->if_flags &= ~IFF_RUNNING;
bcopy((caddr_t) ina->x_host.c_host,
(caddr_t) sc->arpcom.ac_enaddr,
sizeof(sc->arpcom.ac_enaddr));
}
epinit(ifp->if_unit);
break;
}
#endif
#ifdef NS
case AF_NS:
{

View File

@ -72,6 +72,11 @@
#include <netinet/if_ether.h>
#endif
#ifdef IPX
#include <netipx/ipx.h>
#include <netipx/ipx_if.h>
#endif
#ifdef NS
#include <netns/ns.h>
#include <netns/ns_if.h>
@ -2017,6 +2022,32 @@ fe_ioctl ( struct ifnet *ifp, int command, caddr_t data )
arp_ifinit( &sc->arpcom, ifa );
break;
#endif
#ifdef IPX
/*
* XXX - This code is probably wrong
*/
case AF_IPX:
{
register struct ipx_addr *ina
= &(IA_SIPX(ifa)->sipx_addr);
if (ipx_nullhost(*ina))
ina->x_host =
*(union ipx_host *) (sc->sc_enaddr);
else {
bcopy((caddr_t) ina->x_host.c_host,
(caddr_t) sc->sc_enaddr,
sizeof(sc->sc_enaddr));
}
/*
* Set new address
*/
fe_init(sc->sc_unit);
break;
}
#endif
#ifdef NS
/*

View File

@ -43,7 +43,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: if_ie.c,v 1.26 1995/09/19 18:55:09 bde Exp $
* $Id: if_ie.c,v 1.27 1995/10/13 19:47:47 wollman Exp $
*/
/*
@ -133,6 +133,11 @@ iomem, and to make 16-pointers, we subtract iomem and and with 0xffff.
#include <netinet/if_ether.h>
#endif
#ifdef IPX
#include <netipx/ipx.h>
#include <netipx/ipx_if.h>
#endif
#ifdef NS
#include <netns/ns.h>
#include <netns/ns_if.h>
@ -1891,6 +1896,28 @@ ieioctl(ifp, command, data)
break;
#endif /* INET */
#ifdef IPX
/* This magic copied from if_is.c; I don't use XNS, so I have no
* way of telling if this actually works or not.
*/
case AF_IPX:
{
struct ipx_addr *ina = &(IA_SIPX(ifa)->sipx_addr);
if(ipx_nullhost(*ina)) {
ina->x_host = *(union ipx_host *)(ie->arpcom.ac_enaddr);
} else {
ifp->if_flags &= ~IFF_RUNNING;
bcopy((caddr_t)ina->x_host.c_host,
(caddr_t)ie->arpcom.ac_enaddr,
sizeof ie->arpcom.ac_enaddr);
}
ieinit(ifp->if_unit);
}
break;
#endif /* IPX */
#ifdef NS
/* This magic copied from if_is.c; I don't use XNS, so I have no
* way of telling if this actually works or not.

View File

@ -2,7 +2,7 @@
# LINT -- config file for checking all the sources, tries to pull in
# as much of the source tree as it can.
#
# $Id: LINT,v 1.205 1995/10/10 04:03:12 bde Exp $
# $Id: LINT,v 1.206 1995/10/25 16:43:01 jkh Exp $
#
# NB: You probably don't want to try running a kernel built from this
# file. Instead, you should start from GENERIC, and add options from
@ -129,6 +129,12 @@ options INET #Internet communications protocols
options CCITT #X.25 network layer
options NS #Xerox NS communications protocols
options IPX #IPX/SPX communications protocols
options IPXIP #IPX in IP encapsulation (not available)
options IPTUNNEL #IP in IPX encapsulation (not available)
#options "IPXPRINTFS=0" #Console Debugging Information
#options "IPX_ERRPRINTFS=0" #Console Debugging Information
# These are currently broken and don't compile
#options ISO
#options TPIP #ISO TP class 4 over IP

View File

@ -2,7 +2,7 @@
# LINT -- config file for checking all the sources, tries to pull in
# as much of the source tree as it can.
#
# $Id: LINT,v 1.205 1995/10/10 04:03:12 bde Exp $
# $Id: LINT,v 1.206 1995/10/25 16:43:01 jkh Exp $
#
# NB: You probably don't want to try running a kernel built from this
# file. Instead, you should start from GENERIC, and add options from
@ -129,6 +129,12 @@ options INET #Internet communications protocols
options CCITT #X.25 network layer
options NS #Xerox NS communications protocols
options IPX #IPX/SPX communications protocols
options IPXIP #IPX in IP encapsulation (not available)
options IPTUNNEL #IP in IPX encapsulation (not available)
#options "IPXPRINTFS=0" #Console Debugging Information
#options "IPX_ERRPRINTFS=0" #Console Debugging Information
# These are currently broken and don't compile
#options ISO
#options TPIP #ISO TP class 4 over IP

View File

@ -13,7 +13,7 @@
* the SMC Elite Ultra (8216), the 3Com 3c503, the NE1000 and NE2000,
* and a variety of similar clones.
*
* $Id: if_ed.c,v 1.78 1995/10/13 19:47:40 wollman Exp $
* $Id: if_ed.c,v 1.79 1995/10/21 00:55:23 phk Exp $
*/
#include "ed.h"
@ -40,6 +40,11 @@
#include <netinet/if_ether.h>
#endif
#ifdef IPX
#include <netipx/ipx.h>
#include <netipx/ipx_if.h>
#endif
#ifdef NS
#include <netns/ns.h>
#include <netns/ns_if.h>
@ -2256,11 +2261,34 @@ ed_ioctl(ifp, command, data)
arp_ifinit((struct arpcom *)ifp, ifa);
break;
#endif
#ifdef NS
#ifdef IPX
/*
* XXX - This code is probably wrong
*/
case AF_IPX:
{
register struct ipx_addr *ina = &(IA_SIPX(ifa)->sipx_addr);
/*
* XXX - This code is probably wrong
*/
if (ipx_nullhost(*ina))
ina->x_host =
*(union ipx_host *) (sc->arpcom.ac_enaddr);
else {
bcopy((caddr_t) ina->x_host.c_host,
(caddr_t) sc->arpcom.ac_enaddr,
sizeof(sc->arpcom.ac_enaddr));
}
/*
* Set new address
*/
ed_init(ifp->if_unit);
break;
}
#endif
#ifdef NS
/*
* XXX - This code is probably wrong
*/
case AF_NS:
{
register struct ns_addr *ina = &(IA_SNS(ifa)->sns_addr);

View File

@ -27,7 +27,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id: if_eg.c,v 1.4 1995/05/30 08:02:02 rgrimes Exp $
* $Id: if_eg.c,v 1.5 1995/10/13 19:47:42 wollman Exp $
*/
/* To do:
@ -58,6 +58,11 @@
#include <netinet/if_ether.h>
#endif
#ifdef IPX
#include <netipx/ipx.h>
#include <netipx/ipx_if.h>
#endif
#ifdef NS
#include <netns/ns.h>
#include <netns/ns_if.h>
@ -725,6 +730,23 @@ egioctl(ifp, command, data)
arp_ifinit((struct arpcom *)ifp, ifa);
break;
#endif
#ifdef IPX
case AF_IPX:
{
register struct ipx_addr *ina = &IA_SIPX(ifa)->sipx_addr;
if (ipx_nullhost(*ina))
ina->x_host =
*(union ipx_host *)(sc->sc_arpcom.ac_enaddr);
else
bcopy(ina->x_host.c_host,
sc->sc_arpcom.ac_enaddr,
sizeof(sc->sc_arpcom.ac_enaddr));
/* Set new address. */
eginit(sc);
break;
}
#endif
#ifdef NS
case AF_NS:
{

View File

@ -6,7 +6,7 @@
*
* Questions, comments, bug reports and fixes to kimmel@cs.umass.edu.
*
* $Id: if_el.c,v 1.14 1995/06/11 19:31:25 rgrimes Exp $
* $Id: if_el.c,v 1.15 1995/10/13 19:47:43 wollman Exp $
*/
/* Except of course for the portions of code lifted from other FreeBSD
* drivers (mainly elread, elget and el_ioctl)
@ -44,6 +44,11 @@
#include <netinet/if_ether.h>
#endif
#ifdef IPX
#include <netipx/ipx.h>
#include <netipx/ipx_if.h>
#endif
#ifdef NS
#include <netns/ns.h>
#include <netns/ns_if.h>
@ -711,6 +716,32 @@ el_ioctl(ifp, command, data)
arp_ifinit((struct arpcom *)ifp, ifa);
break;
#endif
#ifdef IPX
/*
* XXX - This code is probably wrong
*/
case AF_IPX:
{
register struct ipx_addr *ina = &(IA_SIPX(ifa)->sipx_addr);
if (ipx_nullhost(*ina))
ina->x_host =
*(union ipx_host *)(sc->arpcom.ac_enaddr);
else {
/*
*
*/
bcopy((caddr_t)ina->x_host.c_host,
(caddr_t)sc->arpcom.ac_enaddr,
sizeof(sc->arpcom.ac_enaddr));
}
/*
* Set new address
*/
el_init(ifp->if_unit);
break;
}
#endif
#ifdef NS
/*
* XXX - This code is probably wrong

View File

@ -38,7 +38,7 @@
*/
/*
* $Id: if_ep.c,v 1.30 1995/08/28 12:01:17 guido Exp $
* $Id: if_ep.c,v 1.31 1995/10/13 19:47:44 wollman Exp $
*
* Promiscuous mode added and interrupt logic slightly changed
* to reduce the number of adapter failures. Transceiver select
@ -82,6 +82,11 @@
#include <netinet/if_ether.h>
#endif
#ifdef IPX
#include <netipx/ipx.h>
#include <netipx/ipx_if.h>
#endif
#ifdef NS
#include <netns/ns.h>
#include <netns/ns_if.h>
@ -1141,6 +1146,24 @@ epioctl(ifp, cmd, data)
arp_ifinit((struct arpcom *)ifp, ifa);
break;
#endif
#ifdef IPX
case AF_IPX:
{
register struct ipx_addr *ina = &(IA_SIPX(ifa)->sipx_addr);
if (ipx_nullhost(*ina))
ina->x_host =
*(union ipx_host *) (sc->arpcom.ac_enaddr);
else {
ifp->if_flags &= ~IFF_RUNNING;
bcopy((caddr_t) ina->x_host.c_host,
(caddr_t) sc->arpcom.ac_enaddr,
sizeof(sc->arpcom.ac_enaddr));
}
epinit(ifp->if_unit);
break;
}
#endif
#ifdef NS
case AF_NS:
{

View File

@ -72,6 +72,11 @@
#include <netinet/if_ether.h>
#endif
#ifdef IPX
#include <netipx/ipx.h>
#include <netipx/ipx_if.h>
#endif
#ifdef NS
#include <netns/ns.h>
#include <netns/ns_if.h>
@ -2017,6 +2022,32 @@ fe_ioctl ( struct ifnet *ifp, int command, caddr_t data )
arp_ifinit( &sc->arpcom, ifa );
break;
#endif
#ifdef IPX
/*
* XXX - This code is probably wrong
*/
case AF_IPX:
{
register struct ipx_addr *ina
= &(IA_SIPX(ifa)->sipx_addr);
if (ipx_nullhost(*ina))
ina->x_host =
*(union ipx_host *) (sc->sc_enaddr);
else {
bcopy((caddr_t) ina->x_host.c_host,
(caddr_t) sc->sc_enaddr,
sizeof(sc->sc_enaddr));
}
/*
* Set new address
*/
fe_init(sc->sc_unit);
break;
}
#endif
#ifdef NS
/*

View File

@ -43,7 +43,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: if_ie.c,v 1.26 1995/09/19 18:55:09 bde Exp $
* $Id: if_ie.c,v 1.27 1995/10/13 19:47:47 wollman Exp $
*/
/*
@ -133,6 +133,11 @@ iomem, and to make 16-pointers, we subtract iomem and and with 0xffff.
#include <netinet/if_ether.h>
#endif
#ifdef IPX
#include <netipx/ipx.h>
#include <netipx/ipx_if.h>
#endif
#ifdef NS
#include <netns/ns.h>
#include <netns/ns_if.h>
@ -1891,6 +1896,28 @@ ieioctl(ifp, command, data)
break;
#endif /* INET */
#ifdef IPX
/* This magic copied from if_is.c; I don't use XNS, so I have no
* way of telling if this actually works or not.
*/
case AF_IPX:
{
struct ipx_addr *ina = &(IA_SIPX(ifa)->sipx_addr);
if(ipx_nullhost(*ina)) {
ina->x_host = *(union ipx_host *)(ie->arpcom.ac_enaddr);
} else {
ifp->if_flags &= ~IFF_RUNNING;
bcopy((caddr_t)ina->x_host.c_host,
(caddr_t)ie->arpcom.ac_enaddr,
sizeof ie->arpcom.ac_enaddr);
}
ieinit(ifp->if_unit);
}
break;
#endif /* IPX */
#ifdef NS
/* This magic copied from if_is.c; I don't use XNS, so I have no
* way of telling if this actually works or not.

View File

@ -28,7 +28,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id: if_ix.c,v 1.9 1995/10/05 03:01:13 davidg Exp $
* $Id: if_ix.c,v 1.10 1995/10/13 19:47:48 wollman Exp $
*/
#include "ix.h"
@ -56,6 +56,11 @@
#include <netinet/if_ether.h>
#endif /* INET */
#ifdef IPX /*ZZZ no work done on this, this is just here to remind me*/
#include <netipx/ipx.h>
#include <netipx/ipx_if.h>
#endif /* IPX */
#ifdef NS /*ZZZ no work done on this, this is just here to remind me*/
#include <netns/ns.h>
#include <netns/ns_if.h>
@ -1519,6 +1524,12 @@ ixioctl(struct ifnet *ifp, int cmd, caddr_t data) {
break;
}
#endif /* INET */
#ifdef IPX
case AF_IPX: {
/*ZZZ*/printf("Address family IPX not supported by ixioctl\n");
break;
}
#endif /* IPX */
#ifdef NS
case AF_NS: {
/*ZZZ*/printf("Address family NS not supported by ixioctl\n");

View File

@ -21,7 +21,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id: if_le.c,v 1.19 1995/09/19 18:55:12 bde Exp $
* $Id: if_le.c,v 1.20 1995/10/13 19:47:49 wollman Exp $
*/
/*
@ -65,6 +65,11 @@
#include <netinet/if_ether.h>
#endif
#ifdef IPX
#include <netipx/ipx.h>
#include <netipx/ipx_if.h>
#endif
#ifdef NS
#include <netns/ns.h>
#include <netns/ns_if.h>
@ -569,7 +574,26 @@ le_ioctl(
break;
}
#endif /* INET */
#ifdef IPX
/* This magic copied from if_is.c; I don't use XNS,
* so I have no way of telling if this actually
* works or not.
*/
case AF_IPX: {
struct ipx_addr *ina = &(IA_SIPX(ifa)->sipx_addr);
if (ipx_nullhost(*ina)) {
ina->x_host = *(union ipx_host *)(sc->le_ac.ac_enaddr);
} else {
ifp->if_flags &= ~IFF_RUNNING;
bcopy((caddr_t)ina->x_host.c_host,
(caddr_t)sc->le_ac.ac_enaddr,
sizeof sc->le_ac.ac_enaddr);
}
(*ifp->if_init)(ifp->if_unit);
break;
}
#endif /* IPX */
#ifdef NS
/* This magic copied from if_is.c; I don't use XNS,
* so I have no way of telling if this actually
@ -590,7 +614,6 @@ le_ioctl(
break;
}
#endif /* NS */
default: {
(*ifp->if_init)(ifp->if_unit);
break;

View File

@ -47,7 +47,7 @@
*/
/*
* $Id: if_ze.c,v 1.20 1995/09/26 08:57:47 phk Exp $
* $Id: if_ze.c,v 1.21 1995/10/13 19:47:52 wollman Exp $
*/
#include "ze.h"
@ -75,6 +75,11 @@
#include <netinet/if_ether.h>
#endif
#ifdef IPX
#include <netipx/ipx.h>
#include <netipx/ipx_if.h>
#endif
#ifdef NS
#include <netns/ns.h>
#include <netns/ns_if.h>
@ -1349,6 +1354,32 @@ ze_ioctl(ifp, command, data)
arp_ifinit((struct arpcom*) ifp, ifa);
break;
#endif
#ifdef IPX
/*
* XXX - This code is probably wrong
*/
case AF_IPX:
{
register struct ipx_addr *ina = &(IA_SIPX(ifa)->sipx_addr);
if (ipx_nullhost(*ina))
ina->x_host =
*(union ipx_host *)(sc->arpcom.ac_enaddr);
else {
/*
*
*/
bcopy((caddr_t)ina->x_host.c_host,
(caddr_t)sc->arpcom.ac_enaddr,
sizeof(sc->arpcom.ac_enaddr));
}
/*
* Set new address
*/
ze_init(ifp->if_unit);
break;
}
#endif
#ifdef NS
/*
* XXX - This code is probably wrong

View File

@ -34,7 +34,7 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* From: if_ep.c,v 1.9 1994/01/25 10:46:29 deraadt Exp $
* $Id: if_zp.c,v 1.8 1995/08/16 23:34:28 nate Exp $
* $Id: if_zp.c,v 1.9 1995/10/13 19:47:53 wollman Exp $
*/
/*-
* TODO:
@ -166,6 +166,11 @@ enum memtype {
#include <netinet/if_ether.h>
#endif
#ifdef IPX
#include <netipx/ipx.h>
#include <netipx/ipx_if.h>
#endif
#ifdef NS
#include <netns/ns.h>
#include <netns/ns_if.h>
@ -1958,6 +1963,24 @@ zpioctl(ifp, cmd, data)
#endif
break;
#endif
#ifdef IPX
case AF_IPX:
{
register struct ipx_addr *ina = &(IA_SIPX(ifa)->sipx_addr);
if (ipx_nullhost(*ina))
ina->x_host =
*(union ipx_host *) (sc->arpcom.ac_enaddr);
else {
ifp->if_flags &= ~IFF_RUNNING;
bcopy((caddr_t) ina->x_host.c_host,
(caddr_t) sc->arpcom.ac_enaddr,
sizeof(sc->arpcom.ac_enaddr));
}
zpinit(ifp->if_unit);
break;
}
#endif
#ifdef NS
case AF_NS:
{

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)if_ethersubr.c 8.1 (Berkeley) 6/10/93
* $Id: if_ethersubr.c,v 1.8.2.1 1995/06/03 04:46:21 davidg Exp $
* $Id: if_ethersubr.c,v 1.9 1995/06/11 19:31:39 rgrimes Exp $
*/
#include <sys/param.h>
@ -60,6 +60,11 @@
#endif
#include <netinet/if_ether.h>
#ifdef IPX
#include <netipx/ipx.h>
#include <netipx/ipx_if.h>
#endif
#ifdef NS
#include <netns/ns.h>
#include <netns/ns_if.h>
@ -147,6 +152,18 @@ ether_output(ifp, m0, dst, rt0)
type = ETHERTYPE_IP;
break;
#endif
#ifdef IPX
case AF_IPX:
type = ETHERTYPE_IPX;
bcopy((caddr_t)&(((struct sockaddr_ipx *)dst)->sipx_addr.x_host),
(caddr_t)edst, sizeof (edst));
if (!bcmp((caddr_t)edst, (caddr_t)&ipx_thishost, sizeof(edst)))
return (looutput(ifp, m, dst, rt));
/* If broadcasting on a simplex interface, loopback a copy */
if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX))
mcopy = m_copy(m, 0, (int)M_COPYALL);
break;
#endif
#ifdef NS
case AF_NS:
type = ETHERTYPE_NS;
@ -342,12 +359,17 @@ ether_input(ifp, eh, m)
inq = &arpintrq;
break;
#endif
#ifdef IPX
case ETHERTYPE_IPX:
schednetisr(NETISR_IPX);
inq = &ipxintrq;
break;
#endif
#ifdef NS
case ETHERTYPE_NS:
schednetisr(NETISR_NS);
inq = &nsintrq;
break;
#endif
default:
#if defined (ISO) || defined (LLC)

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* from: if_ethersubr.c,v 1.5 1994/12/13 22:31:45 wollman Exp
* $Id: if_fddisubr.c,v 1.4 1995/05/09 13:35:40 davidg Exp $
* $Id: if_fddisubr.c,v 1.5 1995/05/30 08:08:05 rgrimes Exp $
*/
#include <sys/param.h>
@ -61,6 +61,11 @@
#include <netinet/if_ether.h>
#include <netinet/if_fddi.h>
#ifdef IPX
#include <netipx/ipx.h>
#include <netipx/ipx_if.h>
#endif
#ifdef NS
#include <netns/ns.h>
#include <netns/ns_if.h>
@ -164,6 +169,18 @@ fddi_output(ifp, m0, dst, rt0)
type = ETHERTYPE_IP;
break;
#endif
#ifdef IPX
case AF_IPX:
type = ETHERTYPE_IPX;
bcopy((caddr_t)&(((struct sockaddr_ipx *)dst)->sipx_addr.x_host),
(caddr_t)edst, sizeof (edst));
if (!bcmp((caddr_t)edst, (caddr_t)&ipx_thishost, sizeof(edst)))
return (looutput(ifp, m, dst, rt));
/* If broadcasting on a simplex interface, loopback a copy */
if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX))
mcopy = m_copy(m, 0, (int)M_COPYALL);
break;
#endif
#ifdef NS
case AF_NS:
type = ETHERTYPE_NS;

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)if_loop.c 8.1 (Berkeley) 6/10/93
* $Id: if_loop.c,v 1.12 1995/09/09 18:10:22 davidg Exp $
* $Id: if_loop.c,v 1.13 1995/09/22 17:57:48 wollman Exp $
*/
/*
@ -63,6 +63,11 @@
#include <netinet/ip.h>
#endif
#ifdef IPX
#include <netipx/ipx.h>
#include <netipx/ipx_if.h>
#endif
#ifdef NS
#include <netns/ns.h>
#include <netns/ns_if.h>
@ -169,6 +174,12 @@ looutput(ifp, m, dst, rt)
isr = NETISR_IP;
break;
#endif
#ifdef IPX
case AF_IPX:
ifq = &ipxintrq;
isr = NETISR_IPX;
break;
#endif
#ifdef NS
case AF_NS:
ifq = &nsintrq;

View File

@ -69,7 +69,7 @@
* Paul Mackerras (paulus@cs.anu.edu.au).
*/
/* $Id: if_ppp.c,v 1.21 1995/09/09 18:10:23 davidg Exp $ */
/* $Id: if_ppp.c,v 1.22 1995/10/05 00:33:27 bde Exp $ */
/* from if_sl.c,v 1.11 84/10/04 12:54:47 rick Exp */
#include "ppp.h"
@ -699,6 +699,11 @@ pppoutput(ifp, m0, dst, rt)
break;
#endif
#ifdef IPX
case AF_IPX:
protocol = PPP_IPX;
break;
#endif
#ifdef NS
case AF_NS:
protocol = PPP_XNS;

View File

@ -16,7 +16,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: if_ppp.h,v 1.2 1994/09/23 00:13:20 wollman Exp $
* $Id: if_ppp.h,v 1.3 1995/05/30 08:08:09 rgrimes Exp $
*/
#ifndef _IF_PPP_H_
@ -45,10 +45,12 @@ struct ppp_header {
*/
#define PPP_IP 0x21 /* Internet Protocol */
#define PPP_XNS 0x25 /* Xerox NS */
#define PPP_IPX 0x2b /* IPX Datagram (RFC1552) */
#define PPP_VJC_COMP 0x2d /* VJ compressed TCP */
#define PPP_VJC_UNCOMP 0x2f /* VJ uncompressed TCP */
#define PPP_COMP 0xfd /* compressed packet */
#define PPP_LCP 0xc021 /* Link Control Protocol */
#define PPP_IPXCP 0x802b /* IPX Control Protocol (RFC1552) */
#define PPP_CCP 0x80fd /* Compression Control Protocol */
/*

View File

@ -36,6 +36,11 @@
#include <netinet/if_ether.h>
#endif
#ifdef IPX
#include <netipx/ipx.h>
#include <netipx/ipx_if.h>
#endif
#ifdef NS
#include <netns/ns.h>
#include <netns/ns_if.h>
@ -405,6 +410,12 @@ int sppp_output (struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, struct
ETHERTYPE_NS : PPP_XNS);
break;
#endif
#ifdef IPX
case AF_IPX: /* Xerox NS Protocol */
h->protocol = htons ((sp->pp_flags & PP_CISCO) ?
ETHERTYPE_IPX : PPP_XNS);
break;
#endif
#ifdef ISO
case AF_ISO: /* ISO OSI Protocol */
if (sp->pp_flags & PP_CISCO)

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)netisr.h 8.1 (Berkeley) 6/10/93
* $Id: netisr.h,v 1.5 1995/01/05 19:51:47 se Exp $
* $Id: netisr.h,v 1.6 1995/05/11 00:13:10 wollman Exp $
*/
#ifndef _NET_NETISR_H_
@ -62,6 +62,7 @@
#define NETISR_ISO 7 /* same as AF_ISO */
#define NETISR_CCITT 10 /* same as AF_CCITT */
#define NETISR_ARP 18 /* same as AF_LINK */
#define NETISR_IPX 23 /* same as AF_IPX */
#define NETISR_ISDN 26 /* same as AF_E164 */
#define schednetisr(anisr) { netisr |= 1<<(anisr); setsoftnet(); }

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)route.h 8.3 (Berkeley) 4/19/94
* $Id: route.h,v 1.15 1995/07/29 11:41:03 bde Exp $
* $Id: route.h,v 1.16 1995/10/16 20:53:55 wollman Exp $
*/
#ifndef _NET_ROUTE_H_
@ -242,6 +242,7 @@ struct rt_addrinfo {
struct route_cb {
int ip_count;
int ipx_count;
int ns_count;
int iso_count;
int any_count;

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)rtsock.c 8.5 (Berkeley) 11/2/94
* $Id: rtsock.c,v 1.14 1995/10/09 04:06:28 bde Exp $
* $Id: rtsock.c,v 1.15 1995/10/13 16:01:59 wollman Exp $
*/
#include <sys/param.h>
@ -92,12 +92,13 @@ route_usrreq(so, req, m, nam, control)
so->so_pcb = (caddr_t)rp;
if (so->so_pcb)
bzero(so->so_pcb, sizeof(*rp));
}
if (req == PRU_DETACH && rp) {
int af = rp->rcb_proto.sp_protocol;
if (af == AF_INET)
route_cb.ip_count--;
else if (af == AF_IPX)
route_cb.ipx_count--;
else if (af == AF_NS)
route_cb.ns_count--;
else if (af == AF_ISO)
@ -116,6 +117,8 @@ route_usrreq(so, req, m, nam, control)
}
if (af == AF_INET)
route_cb.ip_count++;
else if (af == AF_IPX)
route_cb.ipx_count++;
else if (af == AF_NS)
route_cb.ns_count++;
else if (af == AF_ISO)

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)if_x25subr.c 8.1 (Berkeley) 6/10/93
* $Id: if_x25subr.c,v 1.6 1995/05/30 08:08:46 rgrimes Exp $
* $Id: if_x25subr.c,v 1.7 1995/07/29 11:41:21 bde Exp $
*/
#include <sys/param.h>
@ -62,6 +62,11 @@
#include <netinet/in_var.h>
#endif
#ifdef IPX
#include <netipx/ipx.h>
#include <netipx/ipx_if.h>
#endif
#ifdef NS
#include <netns/ns.h>
#include <netns/ns_if.h>
@ -186,12 +191,17 @@ register struct mbuf *m;
break;
#endif
#ifdef IPX
case AF_IPX:
isr = NETISR_IPX;
inq = &ipxintrq;
break;
#endif
#ifdef NS
case AF_NS:
isr = NETISR_NS;
inq = &nsintrq;
break;
#endif
#ifdef ISO
case AF_ISO:

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)in_proto.c 8.2 (Berkeley) 2/9/95
* $Id: in_proto.c,v 1.17 1995/06/26 16:11:51 wollman Exp $
* $Id: in_proto.c,v 1.18 1995/09/21 17:58:07 wollman Exp $
*/
#include <sys/param.h>
@ -68,6 +68,10 @@
* TCP/IP protocol family: IP, ICMP, UDP, TCP.
*/
#ifdef IPXIP
void ipxip_input(), ipxip_ctlinput();
#endif
#ifdef NSIP
void idpip_input(), nsip_ctlinput();
#endif
@ -143,6 +147,13 @@ struct protosw inetsw[] = {
eonprotoinit, 0, 0, 0,
},
#endif
#ifdef IPXIP
{ SOCK_RAW, &inetdomain, IPPROTO_IDP, PR_ATOMIC|PR_ADDR,
ipxip_input, rip_output, ipxip_ctlinput, 0,
rip_usrreq,
0, 0, 0, 0,
},
#endif
#ifdef NSIP
{ SOCK_RAW, &inetdomain, IPPROTO_IDP, PR_ATOMIC|PR_ADDR,
idpip_input, rip_output, nsip_ctlinput, 0,

21
sys/netipx/README Normal file
View File

@ -0,0 +1,21 @@
This protocol implements IPX/SPX over Ethernet_II frame type 0x8137.
Please note: the SPX implementation may require further work and testing
to insure proper operation.
Mike Mitchell, Network Engineer
AMTECH Systems Corporation, Technology and Manufacturing
8600 Jefferson Street, Albuquerque, New Mexico 87113 (505) 856-8000
supervisor@alb.asctmd.com
John Hay
Some Company
Some Address
jhay@mikom.csir.co.za
--- Copyright Information ---
Copyright (c) 1984, 1985, 1986, 1987, 1993
The Regents of the University of California. All rights reserved.
Modifications Copyright (c) 1995, Mike Mitchell
Modifications Copyright (c) 1995, John Hay

372
sys/netipx/ipx.c Normal file
View File

@ -0,0 +1,372 @@
/*
* Copyright (c) 1995, Mike Mitchell
* Copyright (c) 1984, 1985, 1986, 1987, 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 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.
*
* @(#)ipx.c
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/ioctl.h>
#include <sys/protosw.h>
#include <sys/errno.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <net/if.h>
#include <net/route.h>
#include <netipx/ipx.h>
#include <netipx/ipx_if.h>
#ifdef IPX
struct ipx_ifaddr *ipx_ifaddr;
int ipx_interfaces;
/*
* Generic internet control operations (ioctl's).
*/
/* ARGSUSED */
int
ipx_control(so, cmd, data, ifp)
struct socket *so;
int cmd;
caddr_t data;
register struct ifnet *ifp;
{
register struct ifreq *ifr = (struct ifreq *)data;
register struct ipx_aliasreq *ifra = (struct ipx_aliasreq *)data;
register struct ipx_ifaddr *ia;
struct ifaddr *ifa;
struct ipx_ifaddr *oia;
int dstIsNew, hostIsNew;
int error = 0;
/*
* Find address for this interface, if it exists.
*/
if (ifp == 0)
return (EADDRNOTAVAIL);
for (ia = ipx_ifaddr; ia; ia = ia->ia_next)
if (ia->ia_ifp == ifp)
break;
switch (cmd) {
case SIOCGIFADDR:
if (ia == (struct ipx_ifaddr *)0)
return (EADDRNOTAVAIL);
*(struct sockaddr_ipx *)&ifr->ifr_addr = ia->ia_addr;
return (0);
case SIOCGIFBRDADDR:
if (ia == (struct ipx_ifaddr *)0)
return (EADDRNOTAVAIL);
if ((ifp->if_flags & IFF_BROADCAST) == 0)
return (EINVAL);
*(struct sockaddr_ipx *)&ifr->ifr_dstaddr = ia->ia_broadaddr;
return (0);
case SIOCGIFDSTADDR:
if (ia == (struct ipx_ifaddr *)0)
return (EADDRNOTAVAIL);
if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
return (EINVAL);
*(struct sockaddr_ipx *)&ifr->ifr_dstaddr = ia->ia_dstaddr;
return (0);
}
if ((so->so_state & SS_PRIV) == 0)
return (EPERM);
switch (cmd) {
case SIOCAIFADDR:
case SIOCDIFADDR:
if (ifra->ifra_addr.sipx_family == AF_IPX)
for (oia = ia; ia; ia = ia->ia_next) {
if (ia->ia_ifp == ifp &&
ipx_neteq(ia->ia_addr.sipx_addr,
ifra->ifra_addr.sipx_addr))
break;
}
if (cmd == SIOCDIFADDR && ia == 0)
return (EADDRNOTAVAIL);
/* FALLTHROUGH */
case SIOCSIFADDR:
case SIOCSIFDSTADDR:
if (ia == (struct ipx_ifaddr *)0) {
oia = (struct ipx_ifaddr *)
malloc(sizeof *ia, M_IFADDR, M_WAITOK);
if (oia == (struct ipx_ifaddr *)NULL)
return (ENOBUFS);
bzero((caddr_t)oia, sizeof(*oia));
if ((ia = ipx_ifaddr)) {
for ( ; ia->ia_next; ia = ia->ia_next)
;
ia->ia_next = oia;
} else
ipx_ifaddr = oia;
ia = oia;
if ((ifa = ifp->if_addrlist)) {
for ( ; ifa->ifa_next; ifa = ifa->ifa_next)
;
ifa->ifa_next = (struct ifaddr *) ia;
} else
ifp->if_addrlist = (struct ifaddr *) ia;
ia->ia_ifp = ifp;
ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr;
ia->ia_ifa.ifa_netmask =
(struct sockaddr *)&ipx_netmask;
ia->ia_ifa.ifa_dstaddr =
(struct sockaddr *)&ia->ia_dstaddr;
if (ifp->if_flags & IFF_BROADCAST) {
ia->ia_broadaddr.sipx_family = AF_IPX;
ia->ia_broadaddr.sipx_len = sizeof(ia->ia_addr);
ia->ia_broadaddr.sipx_addr.x_host = ipx_broadhost;
}
ipx_interfaces++;
}
}
switch (cmd) {
case SIOCSIFDSTADDR:
if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
return (EINVAL);
if (ia->ia_flags & IFA_ROUTE) {
rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST);
ia->ia_flags &= ~IFA_ROUTE;
}
if (ifp->if_ioctl) {
error = (*ifp->if_ioctl)(ifp, SIOCSIFDSTADDR, (void *)ia);
if (error)
return (error);
}
*(struct sockaddr *)&ia->ia_dstaddr = ifr->ifr_dstaddr;
return (0);
case SIOCSIFADDR:
return (ipx_ifinit(ifp, ia,
(struct sockaddr_ipx *)&ifr->ifr_addr, 1));
case SIOCDIFADDR:
ipx_ifscrub(ifp, ia);
if ((ifa = ifp->if_addrlist) == (struct ifaddr *)ia)
ifp->if_addrlist = ifa->ifa_next;
else {
while (ifa->ifa_next &&
(ifa->ifa_next != (struct ifaddr *)ia))
ifa = ifa->ifa_next;
if (ifa->ifa_next)
ifa->ifa_next = ((struct ifaddr *)ia)->ifa_next;
else
printf("Couldn't unlink ipxifaddr from ifp\n");
}
oia = ia;
if (oia == (ia = ipx_ifaddr)) {
ipx_ifaddr = ia->ia_next;
} else {
while (ia->ia_next && (ia->ia_next != oia)) {
ia = ia->ia_next;
}
if (ia->ia_next)
ia->ia_next = oia->ia_next;
else
printf("Didn't unlink ipxifadr from list\n");
}
IFAFREE((&oia->ia_ifa));
if (0 == --ipx_interfaces) {
/*
* We reset to virginity and start all over again
*/
ipx_thishost = ipx_zerohost;
}
return (0);
case SIOCAIFADDR:
dstIsNew = 0; hostIsNew = 1;
if (ia->ia_addr.sipx_family == AF_IPX) {
if (ifra->ifra_addr.sipx_len == 0) {
ifra->ifra_addr = ia->ia_addr;
hostIsNew = 0;
} else if (ipx_neteq(ifra->ifra_addr.sipx_addr,
ia->ia_addr.sipx_addr))
hostIsNew = 0;
}
if ((ifp->if_flags & IFF_POINTOPOINT) &&
(ifra->ifra_dstaddr.sipx_family == AF_IPX)) {
if (hostIsNew == 0)
ipx_ifscrub(ifp, ia);
ia->ia_dstaddr = ifra->ifra_dstaddr;
dstIsNew = 1;
}
if (ifra->ifra_addr.sipx_family == AF_IPX &&
(hostIsNew || dstIsNew))
error = ipx_ifinit(ifp, ia, &ifra->ifra_addr, 0);
return (error);
default:
if (ifp->if_ioctl == 0)
return (EOPNOTSUPP);
return ((*ifp->if_ioctl)(ifp, cmd, data));
}
}
/*
* Delete any previous route for an old address.
*/
void
ipx_ifscrub(ifp, ia)
register struct ifnet *ifp;
register struct ipx_ifaddr *ia;
{
if (ia->ia_flags & IFA_ROUTE) {
if (ifp->if_flags & IFF_POINTOPOINT) {
rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST);
} else
rtinit(&(ia->ia_ifa), (int)RTM_DELETE, 0);
ia->ia_flags &= ~IFA_ROUTE;
}
}
/*
* Initialize an interface's internet address
* and routing table entry.
*/
int
ipx_ifinit(ifp, ia, sipx, scrub)
register struct ifnet *ifp;
register struct ipx_ifaddr *ia;
register struct sockaddr_ipx *sipx;
int scrub;
{
struct sockaddr_ipx oldaddr;
register union ipx_host *h = &ia->ia_addr.sipx_addr.x_host;
int s = splimp(), error;
/*
* Set up new addresses.
*/
oldaddr = ia->ia_addr;
ia->ia_addr = *sipx;
/*
* The convention we shall adopt for naming is that
* a supplied address of zero means that "we don't care".
* if there is a single interface, use the address of that
* interface as our 6 byte host address.
* if there are multiple interfaces, use any address already
* used.
*
* Give the interface a chance to initialize
* if this is its first address,
* and to validate the address if necessary.
*/
if (ipx_hosteqnh(ipx_thishost, ipx_zerohost)) {
if (ifp->if_ioctl &&
(error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, (void *)ia))) {
ia->ia_addr = oldaddr;
splx(s);
return (error);
}
ipx_thishost = *h;
} else if (ipx_hosteqnh(sipx->sipx_addr.x_host, ipx_zerohost)
|| ipx_hosteqnh(sipx->sipx_addr.x_host, ipx_thishost)) {
*h = ipx_thishost;
if (ifp->if_ioctl &&
(error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, (void *)ia))) {
ia->ia_addr = oldaddr;
splx(s);
return (error);
}
if (!ipx_hosteqnh(ipx_thishost,*h)) {
ia->ia_addr = oldaddr;
splx(s);
return (EINVAL);
}
} else {
ia->ia_addr = oldaddr;
splx(s);
return (EINVAL);
}
ia->ia_ifa.ifa_metric = ifp->if_metric;
/*
* Add route for the network.
*/
if (scrub) {
ia->ia_ifa.ifa_addr = (struct sockaddr *)&oldaddr;
ipx_ifscrub(ifp, ia);
ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr;
}
if (ifp->if_flags & IFF_POINTOPOINT)
rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_HOST|RTF_UP);
else {
ia->ia_broadaddr.sipx_addr.x_net = ia->ia_addr.sipx_addr.x_net;
rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_UP);
}
ia->ia_flags |= IFA_ROUTE;
return (0);
}
/*
* Return address info for specified internet network.
*/
struct ipx_ifaddr *
ipx_iaonnetof(dst)
register struct ipx_addr *dst;
{
register struct ipx_ifaddr *ia;
register struct ipx_addr *compare;
register struct ifnet *ifp;
struct ipx_ifaddr *ia_maybe = 0;
union ipx_net net = dst->x_net;
for (ia = ipx_ifaddr; ia; ia = ia->ia_next) {
if ((ifp = ia->ia_ifp)) {
if (ifp->if_flags & IFF_POINTOPOINT) {
compare = &satoipx_addr(ia->ia_dstaddr);
if (ipx_hosteq(*dst, *compare))
return (ia);
if (ipx_neteqnn(net, ia->ia_addr.sipx_addr.x_net))
ia_maybe = ia;
} else {
if (ipx_neteqnn(net, ia->ia_addr.sipx_addr.x_net))
return (ia);
}
}
}
return (ia_maybe);
}
#endif

196
sys/netipx/ipx.h Normal file
View File

@ -0,0 +1,196 @@
/*
* Copyright (c) 1995, Mike Mitchell
* Copyright (c) 1984, 1985, 1986, 1987, 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 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.
*
* @(#)ipx.h
*/
#ifndef _NETIPX_IPX_H_
#define _NETIPX_IPX_H_
/*
* Constants and Structures
*/
/*
* Protocols
*/
#define IPXPROTO_UNKWN 0 /* Unknown */
#define IPXPROTO_RI 1 /* RIP Routing Information */
#define IPXPROTO_ECHO 2 /* Echo Protocol */
#define IPXPROTO_ERROR 3 /* Error Protocol */
#define IPXPROTO_PXP 4 /* PXP Packet Exchange */
#define IPXPROTO_SPX 5 /* SPX Sequenced Packet */
#define IPXPROTO_NCP 17 /* NCP NetWare Core */
#define IPXPROTO_RAW 255 /* Placemarker*/
#define IPXPROTO_MAX 256 /* Placemarker*/
/*
* Port/Socket numbers: network standard functions
*/
#define IPXPORT_RI 1 /* NS RIP Routing Information */
#define IPXPORT_ECHO 2 /* NS Echo */
#define IPXPORT_RE 3 /* NS Router Error */
#define IPXPORT_FSP 0x0451 /* NW FSP File Service */
#define IPXPORT_SAP 0x0452 /* NW SAP Service Advertising */
#define IPXPORT_RIP 0x0453 /* NW RIP Routing Information */
#define IPXPORT_NETBIOS 0x0455 /* NW NetBIOS */
#define IPXPORT_DIAGS 0x0456 /* NW Diagnostics */
#define IPXPORT_WDOG 0x4001 /* NW Watchdog Packets */
#define IPXPORT_SHELL 0x4003 /* NW Shell Socket */
#define IPXPORT_MAX 0x8000 /* Maximum User Addressable Port */
/* flags passed to ipx_outputfl as last parameter */
#define IPX_FORWARDING 0x1 /* most of ipx header exists */
#define IPX_ROUTETOIF 0x10 /* same as SO_DONTROUTE */
#define IPX_ALLOWBROADCAST SO_BROADCAST /* can send broadcast packets */
#define IPX_MAXHOPS 15
/* flags passed to get/set socket option */
#define SO_HEADERS_ON_INPUT 1
#define SO_HEADERS_ON_OUTPUT 2
#define SO_DEFAULT_HEADERS 3
#define SO_LAST_HEADER 4
#define SO_IPXIP_ROUTE 5
#define SO_SEQNO 6
#define SO_ALL_PACKETS 7
#define SO_MTU 8
#define SO_IPXTUN_ROUTE 9
/*
* IPX addressing
*/
union ipx_host {
u_char c_host[6];
u_short s_host[3];
};
union ipx_net {
u_char c_net[4];
u_short s_net[2];
};
union ipx_net_u {
union ipx_net net_e;
u_long long_e;
};
struct ipx_addr {
union ipx_net x_net;
union ipx_host x_host;
u_short x_port;
};
/*
* Socket address
*/
struct sockaddr_ipx {
u_char sipx_len;
u_char sipx_family;
struct ipx_addr sipx_addr;
char sipx_zero[2];
};
#define sipx_port sipx_addr.x_port
/*
* Definitions for IPX Internet Datagram Protocol
*/
struct ipx {
u_short ipx_sum; /* Checksum */
u_short ipx_len; /* Length, in bytes, including header */
u_char ipx_tc; /* Transport Crontrol (i.e. hop count) */
u_char ipx_pt; /* Packet Type (i.e. level 2 protocol) */
struct ipx_addr ipx_dna; /* Destination Network Address */
struct ipx_addr ipx_sna; /* Source Network Address */
};
#ifdef vax
#define ipx_netof(a) (*(long *) & ((a).x_net)) /* XXX - not needed */
#endif
#define ipx_neteqnn(a,b) \
(((a).s_net[0]==(b).s_net[0]) && ((a).s_net[1]==(b).s_net[1]))
#define ipx_neteq(a,b) ipx_neteqnn((a).x_net, (b).x_net)
#define satoipx_addr(sa) (((struct sockaddr_ipx *)&(sa))->sipx_addr)
#define ipx_hosteqnh(s,t) ((s).s_host[0] == (t).s_host[0] && \
(s).s_host[1] == (t).s_host[1] && (s).s_host[2] == (t).s_host[2])
#define ipx_hosteq(s,t) (ipx_hosteqnh((s).x_host,(t).x_host))
#define ipx_nullnet(x) (((x).x_net.s_net[0]==0) && ((x).x_net.s_net[1]==0))
#define ipx_nullhost(x) (((x).x_host.s_host[0]==0) && \
((x).x_host.s_host[1]==0) && ((x).x_host.s_host[2]==0))
#define ipx_wildnet(x) (((x).x_net.s_net[0]==0xffff) && \
((x).x_net.s_net[1]==0xffff))
#define ipx_wildhost(x) (((x).x_host.s_host[0]==0xffff) && \
((x).x_host.s_host[1]==0xffff) && ((x).x_host.s_host[2]==0xffff))
#ifdef KERNEL
extern int ipxcksum;
extern struct domain ipxdomain;
extern struct sockaddr_ipx ipx_netmask;
extern struct sockaddr_ipx ipx_hostmask;
extern union ipx_host ipx_thishost;
extern union ipx_net ipx_zeronet;
extern union ipx_host ipx_zerohost;
extern union ipx_net ipx_broadnet;
extern union ipx_host ipx_broadhost;
extern long ipx_pexseq;
extern u_char ipxctlerrmap[];
extern struct ipxpcb ipxrawpcb;
u_short ipx_cksum();
void ipx_input(), ipx_abort(), ipx_drop();
int ipx_output(), ipx_ctloutput(), ipx_usrreq();
int ipx_raw_usrreq(), ipx_control(), ipx_do_route();
void ipx_init(), ipxintr(), ipx_ctlinput(), ipx_forward();
void ipx_undo_route(), ipx_watch_output();
int ipx_outputfl();
int ipxip_route();
#else
#include <sys/cdefs.h>
__BEGIN_DECLS
extern struct ipx_addr ipx_addr __P((const char *));
extern char *ipx_ntoa __P((struct ipx_addr));
extern char *_ns_spectHex __P((const char *));
__END_DECLS
#endif
#endif

205
sys/netipx/ipx_cksum.c Normal file
View File

@ -0,0 +1,205 @@
/*
* Copyright (c) 1995, Mike Mitchell
* Copyright (c) 1982, 1992, 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 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.
*
* @(#)ipx_cksum.c
*/
#include <sys/param.h>
#include <sys/mbuf.h>
/*
* Checksum routine for Network Systems Protocol Packets (Big-Endian).
*
* This routine is very heavily used in the network
* code and should be modified for each CPU to be as fast as possible.
*/
#define ADDCARRY(x) { if ((x) > 65535) (x) -= 65535; }
#define FOLD(x) {l_util.l = (x); (x) = l_util.s[0] + l_util.s[1]; ADDCARRY(x);}
u_short
ipx_cksum(m, len)
register struct mbuf *m;
register int len;
{
register u_short *w;
register int sum = 0;
register int mlen = 0;
register int sum2;
union {
u_short s[2];
long l;
} l_util;
for (;m && len; m = m->m_next) {
if (m->m_len == 0)
continue;
/*
* Each trip around loop adds in
* word from one mbuf segment.
*/
w = mtod(m, u_short *);
if (mlen == -1) {
/*
* There is a byte left from the last segment;
* ones-complement add it into the checksum.
*/
#if BYTE_ORDER == BIG_ENDIAN
sum += *(u_char *)w;
#else
sum += *(u_char *)w << 8;
#endif
sum += sum;
w = (u_short *)(1 + (char *)w);
mlen = m->m_len - 1;
len--;
FOLD(sum);
} else
mlen = m->m_len;
if (len < mlen)
mlen = len;
len -= mlen;
/*
* We can do a 16 bit ones complement sum using
* 32 bit arithmetic registers for adding,
* with carries from the low added
* into the high (by normal carry-chaining)
* so long as we fold back before 16 carries have occured.
*/
if (1 & (int) w)
goto uuuuglyy;
#ifndef TINY
/* -DTINY reduces the size from 1250 to 550, but slows it down by 22% */
while ((mlen -= 32) >= 0) {
sum += w[0]; sum += sum; sum += w[1]; sum += sum;
sum += w[2]; sum += sum; sum += w[3]; sum += sum;
sum += w[4]; sum += sum; sum += w[5]; sum += sum;
sum += w[6]; sum += sum; sum += w[7]; sum += sum;
FOLD(sum);
sum += w[8]; sum += sum; sum += w[9]; sum += sum;
sum += w[10]; sum += sum; sum += w[11]; sum += sum;
sum += w[12]; sum += sum; sum += w[13]; sum += sum;
sum += w[14]; sum += sum; sum += w[15]; sum += sum;
FOLD(sum);
w += 16;
}
mlen += 32;
#endif
while ((mlen -= 8) >= 0) {
sum += w[0]; sum += sum; sum += w[1]; sum += sum;
sum += w[2]; sum += sum; sum += w[3]; sum += sum;
FOLD(sum);
w += 4;
}
mlen += 8;
while ((mlen -= 2) >= 0) {
sum += *w++; sum += sum;
}
goto commoncase;
uuuuglyy:
#if BYTE_ORDER == BIG_ENDIAN
#define ww(n) (((u_char *)w)[n + n + 1])
#define vv(n) (((u_char *)w)[n + n])
#else
#if BYTE_ORDER == LITTLE_ENDIAN
#define vv(n) (((u_char *)w)[n + n + 1])
#define ww(n) (((u_char *)w)[n + n])
#endif
#endif
sum2 = 0;
#ifndef TINY
while ((mlen -= 32) >= 0) {
sum += ww(0); sum += sum; sum += ww(1); sum += sum;
sum += ww(2); sum += sum; sum += ww(3); sum += sum;
sum += ww(4); sum += sum; sum += ww(5); sum += sum;
sum += ww(6); sum += sum; sum += ww(7); sum += sum;
FOLD(sum);
sum += ww(8); sum += sum; sum += ww(9); sum += sum;
sum += ww(10); sum += sum; sum += ww(11); sum += sum;
sum += ww(12); sum += sum; sum += ww(13); sum += sum;
sum += ww(14); sum += sum; sum += ww(15); sum += sum;
FOLD(sum);
sum2 += vv(0); sum2 += sum2; sum2 += vv(1); sum2 += sum2;
sum2 += vv(2); sum2 += sum2; sum2 += vv(3); sum2 += sum2;
sum2 += vv(4); sum2 += sum2; sum2 += vv(5); sum2 += sum2;
sum2 += vv(6); sum2 += sum2; sum2 += vv(7); sum2 += sum2;
FOLD(sum2);
sum2 += vv(8); sum2 += sum2; sum2 += vv(9); sum2 += sum2;
sum2 += vv(10); sum2 += sum2; sum2 += vv(11); sum2 += sum2;
sum2 += vv(12); sum2 += sum2; sum2 += vv(13); sum2 += sum2;
sum2 += vv(14); sum2 += sum2; sum2 += vv(15); sum2 += sum2;
FOLD(sum2);
w += 16;
}
mlen += 32;
#endif
while ((mlen -= 8) >= 0) {
sum += ww(0); sum += sum; sum += ww(1); sum += sum;
sum += ww(2); sum += sum; sum += ww(3); sum += sum;
FOLD(sum);
sum2 += vv(0); sum2 += sum2; sum2 += vv(1); sum2 += sum2;
sum2 += vv(2); sum2 += sum2; sum2 += vv(3); sum2 += sum2;
FOLD(sum2);
w += 4;
}
mlen += 8;
while ((mlen -= 2) >= 0) {
sum += ww(0); sum += sum;
sum2 += vv(0); sum2 += sum2;
w++;
}
sum += (sum2 << 8);
commoncase:
if (mlen == -1) {
#if BYTE_ORDER == BIG_ENDIAN
sum += *(u_char *)w << 8;
#else
sum += *(u_char *)w;
#endif
}
FOLD(sum);
}
if (mlen == -1) {
/* We had an odd number of bytes to sum; assume a garbage
byte of zero and clean up */
sum += sum;
FOLD(sum);
}
/*
* sum has already been kept to low sixteen bits.
* just examine result and exit.
*/
if(sum==0xffff) sum = 0;
return (sum);
}

378
sys/netipx/ipx_error.c Normal file
View File

@ -0,0 +1,378 @@
/*
* Copyright (c) 1995, Mike Mitchell
* Copyright (c) 1984, 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 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.
*
* @(#)ipx_error.c
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/protosw.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/kernel.h>
#include <net/if.h>
#include <net/route.h>
#include <netipx/ipx.h>
#include <netipx/spx.h>
#include <netipx/ipx_pcb.h>
#include <netipx/ipx_error.h>
/*
* IPX_ERR routines: error generation, receive packet processing, and
* routines to turnaround packets back to the originator.
*/
#ifndef IPX_ERRPRINTFS
#define IPX_ERRPRINTFS 0
#endif
int ipx_errprintfs = IPX_ERRPRINTFS;
struct ipx_errstat ipx_errstat;
int
ipx_err_x(c)
int c;
{
register u_short *w, *lim, *base = ipx_errstat.ipx_es_codes;
u_short x = c;
/*
* zero is a legit error code, handle specially
*/
if (x == 0)
return (0);
lim = base + IPX_ERR_MAX - 1;
for (w = base + 1; w < lim; w++) {
if (*w == 0)
*w = x;
if (*w == x)
break;
}
return (w - base);
}
/*
* Generate an error packet of type error
* in response to bad packet.
*/
void
ipx_error(om, type, param)
struct mbuf *om;
int type, param;
{
register struct ipx_epipx *ep;
struct mbuf *m;
struct ipx *nip;
register struct ipx *oip = mtod(om, struct ipx *);
/*
* If this packet was sent to the echo port,
* and nobody was there, just echo it.
* (Yes, this is a wart!)
*/
if (type == IPX_ERR_NOSOCK &&
oip->ipx_dna.x_port == htons(2) &&
(type = ipx_echo(om))==0)
return;
if (ipx_errprintfs)
printf("ipx_error(%x, %u, %d)\n", oip, type, param);
/*
* Don't Generate error packets in response to multicasts.
*/
if (oip->ipx_dna.x_host.c_host[0] & 1)
goto freeit;
ipx_errstat.ipx_es_error++;
/*
* Make sure that the old IPX packet had 30 bytes of data to return;
* if not, don't bother. Also don't EVER error if the old
* packet protocol was IPX_ERR.
*/
if (oip->ipx_len < sizeof(struct ipx)) {
ipx_errstat.ipx_es_oldshort++;
goto freeit;
}
if (oip->ipx_pt == IPXPROTO_ERROR) {
ipx_errstat.ipx_es_oldipx_err++;
goto freeit;
}
/*
* First, formulate ipx_err message
*/
m = m_gethdr(M_DONTWAIT, MT_HEADER);
if (m == NULL)
goto freeit;
m->m_len = sizeof(*ep);
MH_ALIGN(m, m->m_len);
ep = mtod(m, struct ipx_epipx *);
if ((u_int)type > IPX_ERR_TOO_BIG)
panic("ipx_err_error");
ipx_errstat.ipx_es_outhist[ipx_err_x(type)]++;
ep->ipx_ep_errp.ipx_err_num = htons((u_short)type);
ep->ipx_ep_errp.ipx_err_param = htons((u_short)param);
bcopy((caddr_t)oip, (caddr_t)&ep->ipx_ep_errp.ipx_err_ipx, 42);
nip = &ep->ipx_ep_ipx;
nip->ipx_len = sizeof(*ep);
nip->ipx_len = htons((u_short)nip->ipx_len);
nip->ipx_pt = IPXPROTO_ERROR;
nip->ipx_tc = 0;
nip->ipx_dna = oip->ipx_sna;
nip->ipx_sna = oip->ipx_dna;
if (ipxcksum) {
nip->ipx_sum = 0;
nip->ipx_sum = ipx_cksum(m, sizeof(*ep));
} else
nip->ipx_sum = 0xffff;
(void) ipx_outputfl(m, (struct route *)0, 0);
freeit:
m_freem(om);
}
void
ipx_printhost(addr)
register struct ipx_addr *addr;
{
u_short port;
struct ipx_addr work = *addr;
register char *p; register u_char *q;
register char *net = "", *host = "";
char cport[10], chost[15], cnet[15];
port = ntohs(work.x_port);
if (ipx_nullnet(work) && ipx_nullhost(work)) {
if (port)
printf("*.%x", port);
else
printf("*.*");
return;
}
if (ipx_wildnet(work))
net = "any";
else if (ipx_nullnet(work))
net = "*";
else {
q = work.x_net.c_net;
sprintf(cnet, "%x%x%x%x",
q[0], q[1], q[2], q[3]);
for (p = cnet; *p == '0' && p < cnet + 8; p++)
continue;
net = p;
}
if (ipx_wildhost(work))
host = "any";
else if (ipx_nullhost(work))
host = "*";
else {
q = work.x_host.c_host;
sprintf(chost, "%x%x%x%x%x%x",
q[0], q[1], q[2], q[3], q[4], q[5]);
for (p = chost; *p == '0' && p < chost + 12; p++)
continue;
host = p;
}
if (port) {
if (strcmp(host, "*") == 0) {
host = "";
sprintf(cport, "%x", port);
} else
sprintf(cport, ".%x", port);
} else
*cport = 0;
printf("%s.%s%s", net, host, cport);
}
/*
* Process a received IPX_ERR message.
*/
void
ipx_err_input(m)
struct mbuf *m;
{
register struct ipx_errp *ep;
register struct ipx_epipx *epipx = mtod(m, struct ipx_epipx *);
register int i;
int type, code, param;
/*
* Locate ipx_err structure in mbuf, and check
* that not corrupted and of at least minimum length.
*/
if (ipx_errprintfs) {
printf("ipx_err_input ");
ipx_printhost(&epipx->ipx_ep_ipx.ipx_sna);
printf("%d\n", ntohs(epipx->ipx_ep_ipx.ipx_len));
}
i = sizeof (struct ipx_epipx);
if (((m->m_flags & M_EXT) || m->m_len < i) &&
(m = m_pullup(m, i)) == 0) {
ipx_errstat.ipx_es_tooshort++;
return;
}
ep = &(mtod(m, struct ipx_epipx *)->ipx_ep_errp);
type = ntohs(ep->ipx_err_num);
param = ntohs(ep->ipx_err_param);
ipx_errstat.ipx_es_inhist[ipx_err_x(type)]++;
/*
* Message type specific processing.
*/
if (ipx_errprintfs)
printf("ipx_err_input, type %d param %d\n", type, param);
if (type >= IPX_ERR_TOO_BIG) {
goto badcode;
}
ipx_errstat.ipx_es_outhist[ipx_err_x(type)]++;
switch (type) {
case IPX_ERR_UNREACH_HOST:
code = PRC_UNREACH_NET;
goto deliver;
case IPX_ERR_TOO_OLD:
code = PRC_TIMXCEED_INTRANS;
goto deliver;
case IPX_ERR_TOO_BIG:
code = PRC_MSGSIZE;
goto deliver;
case IPX_ERR_FULLUP:
code = PRC_QUENCH;
goto deliver;
case IPX_ERR_NOSOCK:
code = PRC_UNREACH_PORT;
goto deliver;
case IPX_ERR_UNSPEC_T:
case IPX_ERR_BADSUM_T:
case IPX_ERR_BADSUM:
case IPX_ERR_UNSPEC:
code = PRC_PARAMPROB;
goto deliver;
deliver:
/*
* Problem with datagram; advise higher level routines.
*/
if (ipx_errprintfs)
printf("deliver to protocol %d\n",
ep->ipx_err_ipx.ipx_pt);
switch(ep->ipx_err_ipx.ipx_pt) {
case IPXPROTO_SPX:
spx_ctlinput(code, (caddr_t)ep);
break;
default:
ipx_ctlinput(code, (caddr_t)ep);
}
goto freeit;
default:
badcode:
ipx_errstat.ipx_es_badcode++;
goto freeit;
}
freeit:
m_freem(m);
}
#ifdef notdef
u_long
ipxtime()
{
int s = splclock();
u_long t;
t = (time.tv_sec % (24*60*60)) * 1000 + time.tv_usec / 1000;
splx(s);
return (htonl(t));
}
#endif
int
ipx_echo(m)
struct mbuf *m;
{
register struct ipx *ipx = mtod(m, struct ipx *);
register struct echo {
struct ipx ec_ipx;
u_short ec_op; /* Operation, 1 = request, 2 = reply */
} *ec = (struct echo *)ipx;
struct ipx_addr temp;
if (ipx->ipx_pt!=IPXPROTO_ECHO)
return(IPX_ERR_NOSOCK);
if (ec->ec_op!=htons(1))
return(IPX_ERR_UNSPEC);
ec->ec_op = htons(2);
temp = ipx->ipx_dna;
ipx->ipx_dna = ipx->ipx_sna;
ipx->ipx_sna = temp;
if (ipxcksum && ipx->ipx_sum != 0xffff) {
ipx->ipx_sum = 0;
ipx->ipx_sum = ipx_cksum(m,
(int)(((ntohs(ipx->ipx_len) - 1)|1)+1));
}
else
ipx->ipx_sum = 0xffff;
(void) ipx_outputfl(m, (struct route *)0, IPX_FORWARDING);
return(0);
}

98
sys/netipx/ipx_error.h Normal file
View File

@ -0,0 +1,98 @@
/*
* Copyright (c) 1995, Mike Mitchell
* Copyright (c) 1984, 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 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.
*
* @(#)ipx_error.h
*/
#ifndef _NETIPX_IPX_ERROR_H_
#define _NETIPX_IPX_ERROR_H_
/*
* IPX error messages
*/
struct ipx_errp {
u_short ipx_err_num; /* Error Number */
u_short ipx_err_param; /* Error Parameter */
struct ipx ipx_err_ipx; /* Initial segment of offending
packet */
u_char ipx_err_lev2[12]; /* at least this much higher
level protocol */
};
struct ipx_epipx {
struct ipx ipx_ep_ipx;
struct ipx_errp ipx_ep_errp;
};
#define IPX_ERR_UNSPEC 0 /* Unspecified Error detected at dest. */
#define IPX_ERR_BADSUM 1 /* Bad Checksum detected at dest */
#define IPX_ERR_NOSOCK 2 /* Specified socket does not exist at dest*/
#define IPX_ERR_FULLUP 3 /* Dest. refuses packet due to resource lim.*/
#define IPX_ERR_UNSPEC_T 0x200 /* Unspec. Error occured before reaching dest*/
#define IPX_ERR_BADSUM_T 0x201 /* Bad Checksum detected in transit */
#define IPX_ERR_UNREACH_HOST 0x202 /* Dest cannot be reached from here*/
#define IPX_ERR_TOO_OLD 0x203 /* Packet x'd 15 routers without delivery*/
#define IPX_ERR_TOO_BIG 0x204 /* Packet too large to be forwarded through
some intermediate gateway. The error
parameter field contains the max packet
size that can be accommodated */
#define IPX_ERR_MAX 20
/*
* Variables related to this implementation
* of the network systems error message protocol.
*/
struct ipx_errstat {
/* statistics related to ipx_err packets generated */
int ipx_es_error; /* # of calls to ipx_error */
int ipx_es_oldshort; /* no error 'cuz old ip too short */
int ipx_es_oldipx_err; /* no error 'cuz old was ipx_err */
int ipx_es_outhist[IPX_ERR_MAX];
/* statistics related to input messages processed */
int ipx_es_badcode; /* ipx_err_code out of range */
int ipx_es_tooshort; /* packet < IPX_MINLEN */
int ipx_es_checksum; /* bad checksum */
int ipx_es_badlen; /* calculated bound mismatch */
int ipx_es_reflect; /* number of responses */
int ipx_es_inhist[IPX_ERR_MAX];
u_short ipx_es_codes[IPX_ERR_MAX];/* which error code for outhist
since we might not know all */
};
#ifdef KERNEL
extern struct ipx_errstat ipx_errstat;
int ipx_err_x(), ipx_echo();
void ipx_error(), ipx_printhost(), ipx_err_input();
#endif
#endif

90
sys/netipx/ipx_if.h Normal file
View File

@ -0,0 +1,90 @@
/*
* Copyright (c) 1995, Mike Mitchell
* Copyright (c) 1984, 1985, 1986, 1987, 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 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.
*
* @(#)ipx_if.h
*/
#ifndef _NETIPX_IPX_IF_H_
#define _NETIPX_IPX_IF_H_
/*
* Interface address. One of these structures
* is allocated for each interface with an internet address.
* The ifaddr structure contains the protocol-independent part
* of the structure and is assumed to be first.
*/
struct ipx_ifaddr {
struct ifaddr ia_ifa; /* protocol-independent info */
#define ia_ifp ia_ifa.ifa_ifp
#define ia_flags ia_ifa.ifa_flags
struct ipx_ifaddr *ia_next; /* next in list of ipx addresses */
struct sockaddr_ipx ia_addr; /* reserve space for my address */
struct sockaddr_ipx ia_dstaddr; /* space for my broadcast address */
#define ia_broadaddr ia_dstaddr
struct sockaddr_ipx ia_netmask; /* space for my network mask */
};
struct ipx_aliasreq {
char ifra_name[IFNAMSIZ]; /* if name, e.g. "en0" */
struct sockaddr_ipx ifra_addr;
struct sockaddr_ipx ifra_broadaddr;
#define ifra_dstaddr ifra_broadaddr
};
/*
* Given a pointer to an ipx_ifaddr (ifaddr),
* return a pointer to the addr as a sockadd_ipx.
*/
#define IA_SIPX(ia) (&(((struct ipx_ifaddr *)(ia))->ia_addr))
/* This is not the right place for this but where is? */
#define ETHERTYPE_IPX 0x8137
#ifdef IPXIP
struct ipxip_req {
struct sockaddr rq_ipx; /* must be ipx format destination */
struct sockaddr rq_ip; /* must be ip format gateway */
short rq_flags;
};
#endif
#ifdef KERNEL
extern struct ifqueue ipxintrq; /* IPX input packet queue */
extern struct ipx_ifaddr *ipx_ifaddr;
int ipx_ifinit();
void ipx_ifscrub();
struct ipx_ifaddr *ipx_iaonnetof();
#endif
#endif

523
sys/netipx/ipx_input.c Normal file
View File

@ -0,0 +1,523 @@
/*
* Copyright (c) 1995, Mike Mitchell
* Copyright (c) 1984, 1985, 1986, 1987, 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 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.
*
* @(#)ipx_input.c
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/domain.h>
#include <sys/protosw.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/errno.h>
#include <sys/time.h>
#include <sys/kernel.h>
#include <net/if.h>
#include <net/route.h>
#include <net/netisr.h>
#include <net/raw_cb.h>
#include <netipx/ipx.h>
#include <netipx/spx.h>
#include <netipx/ipx_if.h>
#include <netipx/ipx_pcb.h>
#include <netipx/ipx_var.h>
#include <netipx/ipx_error.h>
#ifndef IPXFORWARDING
#ifdef GATEWAY
#define IPXFORWARDING 1 /* forward IPX packets not for us */
#else
#define IPXFORWARDING 0 /* don't forward IPX packets not for us */
#endif
#endif
#ifndef IPXPRINTFS
#define IPXPRINTFS 1 /* printing forwarding information */
#endif
#ifndef IPXCKSUM
#define IPXCKSUM 0 /* perform IPX checksum */
#endif
#ifndef IXDONOSOCKS
#define IPXDONOSOCKS 0 /* return no socket errors */
#endif
int ipxcksum = IPXCKSUM;
int ipxprintfs = IPXPRINTFS;
int ipxdonosocks = IPXDONOSOCKS;
int ipxforwarding = IPXFORWARDING;
union ipx_host ipx_thishost;
union ipx_net ipx_zeronet;
union ipx_host ipx_zerohost;
union ipx_net ipx_broadnet;
union ipx_host ipx_broadhost;
struct ipxstat ipxstat;
struct sockaddr_ipx ipx_netmask, ipx_hostmask;
int ipxintr_getpck = 0;
int ipxintr_swtch = 0;
static u_short allones[] = {-1, -1, -1};
struct ipxpcb ipxpcb;
struct ipxpcb ipxrawpcb;
struct ifqueue ipxintrq;
int ipxqmaxlen = IFQ_MAXLEN;
long ipx_pexseq;
NETISR_SET(NETISR_IPX, ipxintr);
/*
* IPX initialization.
*/
void
ipx_init()
{
ipx_broadnet = * (union ipx_net *) allones;
ipx_broadhost = * (union ipx_host *) allones;
ipx_pexseq = time.tv_usec;
ipxintrq.ifq_maxlen = ipxqmaxlen;
ipxpcb.ipxp_next = ipxpcb.ipxp_prev = &ipxpcb;
ipxrawpcb.ipxp_next = ipxrawpcb.ipxp_prev = &ipxrawpcb;
ipx_netmask.sipx_len = 6;
ipx_netmask.sipx_addr.x_net = ipx_broadnet;
ipx_hostmask.sipx_len = 12;
ipx_hostmask.sipx_addr.x_net = ipx_broadnet;
ipx_hostmask.sipx_addr.x_host = ipx_broadhost;
}
/*
* IPX input routine. Pass to next level.
*/
void
ipxintr()
{
register struct ipx *ipx;
register struct mbuf *m;
register struct ipxpcb *ipxp;
register int i;
int len, s, error;
char oddpacketp;
next:
/*
* Get next datagram off input queue and get IPX header
* in first mbuf.
*/
s = splimp();
IF_DEQUEUE(&ipxintrq, m);
splx(s);
ipxintr_getpck++;
if (m == 0)
return;
if ((m->m_flags & M_EXT || m->m_len < sizeof (struct ipx)) &&
(m = m_pullup(m, sizeof (struct ipx))) == 0) {
ipxstat.ipxs_toosmall++;
goto next;
}
/*
* Give any raw listeners a crack at the packet
*/
for (ipxp = ipxrawpcb.ipxp_next; ipxp != &ipxrawpcb; ipxp = ipxp->ipxp_next) {
struct mbuf *m1 = m_copy(m, 0, (int)M_COPYALL);
if (m1) ipx_input(m1, ipxp);
}
ipx = mtod(m, struct ipx *);
len = ntohs(ipx->ipx_len);
if (oddpacketp = len & 1) {
len++; /* If this packet is of odd length,
preserve garbage byte for checksum */
}
/*
* Check that the amount of data in the buffers
* is as at least much as the IPX header would have us expect.
* Trim mbufs if longer than we expect.
* Drop packet if shorter than we expect.
*/
if (m->m_pkthdr.len < len) {
ipxstat.ipxs_tooshort++;
goto bad;
}
if (m->m_pkthdr.len > len) {
if (m->m_len == m->m_pkthdr.len) {
m->m_len = len;
m->m_pkthdr.len = len;
} else
m_adj(m, len - m->m_pkthdr.len);
}
if (ipxcksum && ((i = ipx->ipx_sum)!=0xffff)) {
ipx->ipx_sum = 0;
if (i != (ipx->ipx_sum = ipx_cksum(m, len))) {
ipxstat.ipxs_badsum++;
ipx->ipx_sum = i;
if (ipx_hosteqnh(ipx_thishost, ipx->ipx_dna.x_host))
error = IPX_ERR_BADSUM;
else
error = IPX_ERR_BADSUM_T;
ipx_error(m, error, 0);
goto next;
}
}
/*
* Is this a directed broadcast?
*/
if (ipx_hosteqnh(ipx_broadhost,ipx->ipx_dna.x_host)) {
if ((!ipx_neteq(ipx->ipx_dna, ipx->ipx_sna)) &&
(!ipx_neteqnn(ipx->ipx_dna.x_net, ipx_broadnet)) &&
(!ipx_neteqnn(ipx->ipx_sna.x_net, ipx_zeronet)) &&
(!ipx_neteqnn(ipx->ipx_dna.x_net, ipx_zeronet)) ) {
/*
* Look to see if I need to eat this packet.
* Algorithm is to forward all young packets
* and prematurely age any packets which will
* by physically broadcasted.
* Any very old packets eaten without forwarding
* would die anyway.
*
* Suggestion of Bill Nesheim, Cornell U.
*/
if (ipx->ipx_tc < IPX_MAXHOPS) {
ipx_forward(m);
goto next;
}
}
/*
* Is this our packet? If not, forward.
*/
} else if (!ipx_hosteqnh(ipx_thishost,ipx->ipx_dna.x_host)) {
ipx_forward(m);
goto next;
}
/*
* Locate pcb for datagram.
*/
ipxp = ipx_pcblookup(&ipx->ipx_sna, ipx->ipx_dna.x_port, IPX_WILDCARD);
/*
* Switch out to protocol's input routine.
*/
ipxintr_swtch++;
if (ipxp) {
if (oddpacketp) {
m_adj(m, -1);
}
if ((ipxp->ipxp_flags & IPXP_ALL_PACKETS)==0)
switch (ipx->ipx_pt) {
case IPXPROTO_SPX:
spx_input(m, ipxp);
goto next;
case IPXPROTO_ERROR:
ipx_err_input(m);
goto next;
}
ipx_input(m, ipxp);
} else {
ipx_error(m, IPX_ERR_NOSOCK, 0);
}
goto next;
bad:
m_freem(m);
goto next;
}
u_char ipxctlerrmap[PRC_NCMDS] = {
ECONNABORTED, ECONNABORTED, 0, 0,
0, 0, EHOSTDOWN, EHOSTUNREACH,
ENETUNREACH, EHOSTUNREACH, ECONNREFUSED, ECONNREFUSED,
EMSGSIZE, 0, 0, 0,
0, 0, 0, 0
};
void
ipx_ctlinput(cmd, arg)
int cmd;
caddr_t arg;
{
struct ipx_addr *ipx;
struct ipxpcb *ipxp;
struct ipx_errp *errp;
int type;
if (cmd < 0 || cmd > PRC_NCMDS)
return;
if (ipxctlerrmap[cmd] == 0)
return; /* XXX */
type = IPX_ERR_UNREACH_HOST;
errp = (struct ipx_errp *)arg;
switch (cmd) {
struct sockaddr_ipx *sipx;
case PRC_IFDOWN:
case PRC_HOSTDEAD:
case PRC_HOSTUNREACH:
sipx = (struct sockaddr_ipx *)arg;
if (sipx->sipx_family != AF_IPX)
return;
ipx = &sipx->sipx_addr;
break;
default:
ipx = &errp->ipx_err_ipx.ipx_dna;
type = errp->ipx_err_num;
type = ntohs((u_short)type);
break;
}
switch (type) {
case IPX_ERR_UNREACH_HOST:
ipx_pcbnotify(ipx, (int)ipxctlerrmap[cmd], ipx_abort, (long)0);
break;
case IPX_ERR_NOSOCK:
ipxp = ipx_pcblookup(ipx, errp->ipx_err_ipx.ipx_sna.x_port,
IPX_WILDCARD);
if(ipxp && ipxdonosocks && ! ipx_nullhost(ipxp->ipxp_faddr))
(void) ipx_drop(ipxp, (int)ipxctlerrmap[cmd]);
}
}
/*
* Forward a packet. If some error occurs return the sender
* an error packet. Note we can't always generate a meaningful
* error message because the IPX errors don't have a large enough repetoire
* of codes and types.
*/
struct route ipx_droute;
struct route ipx_sroute;
void
ipx_forward(m)
struct mbuf *m;
{
register struct ipx *ipx = mtod(m, struct ipx *);
register int error, type, code;
struct mbuf *mcopy = NULL;
int agedelta = 1;
int flags = IPX_FORWARDING;
int ok_there = 0;
int ok_back = 0;
if (ipxforwarding == 0) {
/* can't tell difference between net and host */
type = IPX_ERR_UNREACH_HOST, code = 0;
goto senderror;
}
ipx->ipx_tc++;
if (ipx->ipx_tc > IPX_MAXHOPS) {
type = IPX_ERR_TOO_OLD, code = 0;
goto senderror;
}
/*
* Save at most 42 bytes of the packet in case
* we need to generate an IPX error message to the src.
*/
mcopy = m_copy(m, 0, imin((int)ntohs(ipx->ipx_len), 42));
if ((ok_there = ipx_do_route(&ipx->ipx_dna,&ipx_droute))==0) {
type = IPX_ERR_UNREACH_HOST, code = 0;
goto senderror;
}
/*
* Here we think about forwarding broadcast packets,
* so we try to insure that it doesn't go back out
* on the interface it came in on. Also, if we
* are going to physically broadcast this, let us
* age the packet so we can eat it safely the second time around.
*/
if (ipx->ipx_dna.x_host.c_host[0] & 0x1) {
struct ipx_ifaddr *ia = ipx_iaonnetof(&ipx->ipx_dna);
struct ifnet *ifp;
if (ia) {
/* I'm gonna hafta eat this packet */
agedelta += IPX_MAXHOPS - ipx->ipx_tc;
ipx->ipx_tc = IPX_MAXHOPS;
}
if ((ok_back = ipx_do_route(&ipx->ipx_sna,&ipx_sroute))==0) {
/* error = ENETUNREACH; He'll never get it! */
m_freem(m);
goto cleanup;
}
if (ipx_droute.ro_rt &&
(ifp=ipx_droute.ro_rt->rt_ifp) &&
ipx_sroute.ro_rt &&
(ifp!=ipx_sroute.ro_rt->rt_ifp)) {
flags |= IPX_ALLOWBROADCAST;
} else {
type = IPX_ERR_UNREACH_HOST, code = 0;
goto senderror;
}
}
/* need to adjust checksum */
if (ipxcksum && ipx->ipx_sum != 0xffff) {
union bytes {
u_char c[4];
u_short s[2];
long l;
} x;
register int shift;
x.l = 0; x.c[0] = agedelta;
shift = (((((int)ntohs(ipx->ipx_len))+1)>>1)-2) & 0xf;
x.l = ipx->ipx_sum + (x.s[0] << shift);
x.l = x.s[0] + x.s[1];
x.l = x.s[0] + x.s[1];
if (x.l==0xffff) ipx->ipx_sum = 0; else ipx->ipx_sum = x.l;
} else
ipx->ipx_sum = 0xffff;
error = ipx_outputfl(m, &ipx_droute, flags);
if (ipxprintfs && !error) {
printf("forward: ");
ipx_printhost(&ipx->ipx_sna);
printf(" to ");
ipx_printhost(&ipx->ipx_dna);
printf(" hops %d\n", ipx->ipx_tc);
}
if (error && mcopy != NULL) {
ipx = mtod(mcopy, struct ipx *);
type = IPX_ERR_UNSPEC_T, code = 0;
switch (error) {
case ENETUNREACH:
case EHOSTDOWN:
case EHOSTUNREACH:
case ENETDOWN:
case EPERM:
type = IPX_ERR_UNREACH_HOST;
break;
case EMSGSIZE:
type = IPX_ERR_TOO_BIG;
code = 576; /* too hard to figure out mtu here */
break;
case ENOBUFS:
type = IPX_ERR_UNSPEC_T;
break;
}
mcopy = NULL;
senderror:
ipx_error(m, type, code);
}
cleanup:
if (ok_there)
ipx_undo_route(&ipx_droute);
if (ok_back)
ipx_undo_route(&ipx_sroute);
if (mcopy != NULL)
m_freem(mcopy);
}
int
ipx_do_route(src, ro)
struct ipx_addr *src;
struct route *ro;
{
struct sockaddr_ipx *dst;
bzero((caddr_t)ro, sizeof (*ro));
dst = (struct sockaddr_ipx *)&ro->ro_dst;
dst->sipx_len = sizeof(*dst);
dst->sipx_family = AF_IPX;
dst->sipx_addr = *src;
dst->sipx_addr.x_port = 0;
rtalloc(ro);
if (ro->ro_rt == 0 || ro->ro_rt->rt_ifp == 0) {
return (0);
}
ro->ro_rt->rt_use++;
return (1);
}
void
ipx_undo_route(ro)
register struct route *ro;
{
if (ro->ro_rt) {RTFREE(ro->ro_rt);}
}
void
ipx_watch_output(m, ifp)
struct mbuf *m;
struct ifnet *ifp;
{
register struct ipxpcb *ipxp;
register struct ifaddr *ifa;
/*
* Give any raw listeners a crack at the packet
*/
for (ipxp = ipxrawpcb.ipxp_next; ipxp != &ipxrawpcb; ipxp = ipxp->ipxp_next) {
struct mbuf *m0 = m_copy(m, 0, (int)M_COPYALL);
if (m0) {
register struct ipx *ipx;
M_PREPEND(m0, sizeof (*ipx), M_DONTWAIT);
if (m0 == NULL)
continue;
ipx = mtod(m0, struct ipx *);
ipx->ipx_sna.x_net = ipx_zeronet;
ipx->ipx_sna.x_host = ipx_thishost;
if (ifp && (ifp->if_flags & IFF_POINTOPOINT))
for(ifa = ifp->if_addrlist; ifa;
ifa = ifa->ifa_next) {
if (ifa->ifa_addr->sa_family==AF_IPX) {
ipx->ipx_sna = IA_SIPX(ifa)->sipx_addr;
break;
}
}
ipx->ipx_len = ntohl(m0->m_pkthdr.len);
ipx_input(m0, ipxp);
}
}
}

452
sys/netipx/ipx_ip.c Normal file
View File

@ -0,0 +1,452 @@
/*
* Copyright (c) 1995, Mike Mitchell
* Copyright (c) 1984, 1985, 1986, 1987, 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 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.
*
* @(#)ipx_ip.c
*/
/*
* Software interface driver for encapsulating IPX in IP.
*/
#ifdef IPXIP
#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/errno.h>
#include <sys/ioctl.h>
#include <sys/protosw.h>
#include <net/if.h>
#include <net/netisr.h>
#include <net/route.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/in_var.h>
#include <netinet/ip.h>
#include <netinet/ip_var.h>
#include <machine/mtpr.h>
#include <netipx/ipx.h>
#include <netipx/ipx_if.h>
struct ifnet_en {
struct ifnet ifen_ifnet;
struct route ifen_route;
struct in_addr ifen_src;
struct in_addr ifen_dst;
struct ifnet_en *ifen_next;
};
void ipxipstart();
int ipxipoutput(), ipxipioctl();
void ipxip_input();
int ipxip_free();
void ipxip_ctlinput();
void ipxip_rtchange();
#define LOMTU (1024+512);
struct ifnet ipxipif;
struct ifnet_en *ipxip_list; /* list of all hosts and gateways or broadcast addrs */
struct ifnet_en *
ipxipattach()
{
register struct ifnet_en *m;
register struct ifnet *ifp;
if (ipxipif.if_mtu == 0) {
ifp = &ipxipif;
ifp->if_name = "ipxip";
ifp->if_mtu = LOMTU;
ifp->if_ioctl = ipxipioctl;
ifp->if_output = ipxipoutput;
ifp->if_start = ipxipstart;
ifp->if_flags = IFF_POINTOPOINT;
}
MALLOC((m), struct ifnet_en *, sizeof(*m), M_PCB, M_NOWAIT);
if (m == NULL) return (NULL);
m->ifen_next = ipxip_list;
ipxip_list = m;
ifp = &m->ifen_ifnet;
ifp->if_name = "ipxip";
ifp->if_mtu = LOMTU;
ifp->if_ioctl = ipxipioctl;
ifp->if_output = ipxipoutput;
ifp->if_start = ipxipstart;
ifp->if_flags = IFF_POINTOPOINT;
ifp->if_unit = ipxipif.if_unit++;
if_attach(ifp);
return (m);
}
/*
* Process an ioctl request.
*/
/* ARGSUSED */
int
ipxipioctl(ifp, cmd, data)
register struct ifnet *ifp;
int cmd;
caddr_t data;
{
int error = 0;
struct ifreq *ifr;
switch (cmd) {
case SIOCSIFADDR:
ifp->if_flags |= IFF_UP;
/* fall into: */
case SIOCSIFDSTADDR:
/*
* Everything else is done at a higher level.
*/
break;
case SIOCSIFFLAGS:
ifr = (struct ifreq *)data;
if ((ifr->ifr_flags & IFF_UP) == 0)
error = ipxip_free(ifp);
default:
error = EINVAL;
}
return (error);
}
struct mbuf *ipxip_badlen;
struct mbuf *ipxip_lastin;
int ipxip_hold_input;
void
ipxip_input(m, ifp)
register struct mbuf *m;
struct ifnet *ifp;
{
register struct ip *ip;
register struct ipx *ipx;
register struct ifqueue *ifq = &ipxintrq;
int len, s;
if (ipxip_hold_input) {
if (ipxip_lastin) {
m_freem(ipxip_lastin);
}
ipxip_lastin = m_copym(m, 0, (int)M_COPYALL, M_DONTWAIT);
}
/*
* Get IP and IPX header together in first mbuf.
*/
ipxipif.if_ipackets++;
s = sizeof (struct ip) + sizeof (struct ipx);
if (((m->m_flags & M_EXT) || m->m_len < s) &&
(m = m_pullup(m, s)) == 0) {
ipxipif.if_ierrors++;
return;
}
ip = mtod(m, struct ip *);
if (ip->ip_hl > (sizeof (struct ip) >> 2)) {
ip_stripoptions(m, (struct mbuf *)0);
if (m->m_len < s) {
if ((m = m_pullup(m, s)) == 0) {
ipxipif.if_ierrors++;
return;
}
ip = mtod(m, struct ip *);
}
}
/*
* Make mbuf data length reflect IPX length.
* If not enough data to reflect IPX length, drop.
*/
m->m_data += sizeof (struct ip);
m->m_len -= sizeof (struct ip);
m->m_pkthdr.len -= sizeof (struct ip);
ipx = mtod(m, struct ipx *);
len = ntohs(ipx->ipx_len);
if (len & 1) len++; /* Preserve Garbage Byte */
if (ip->ip_len != len) {
if (len > ip->ip_len) {
ipxipif.if_ierrors++;
if (ipxip_badlen) m_freem(ipxip_badlen);
ipxip_badlen = m;
return;
}
/* Any extra will be trimmed off by the IPX routines */
}
/*
* Place interface pointer before the data
* for the receiving protocol.
*/
m->m_pkthdr.rcvif = ifp;
/*
* Deliver to IPX
*/
s = splimp();
if (IF_QFULL(ifq)) {
IF_DROP(ifq);
bad:
m_freem(m);
splx(s);
return;
}
IF_ENQUEUE(ifq, m);
schednetisr(NETISR_IPX);
splx(s);
return;
}
/* ARGSUSED */
int
ipxipoutput(ifn, m, dst)
struct ifnet_en *ifn;
register struct mbuf *m;
struct sockaddr *dst;
{
register struct ip *ip;
register struct route *ro = &(ifn->ifen_route);
register int len = 0;
register struct ipx *ipx = mtod(m, struct ipx *);
int error;
ifn->ifen_ifnet.if_opackets++;
ipxipif.if_opackets++;
/*
* Calculate data length and make space
* for IP header.
*/
len = ntohs(ipx->ipx_len);
if (len & 1) len++; /* Preserve Garbage Byte */
/* following clause not necessary on vax */
if (3 & (int)m->m_data) {
/* force longword alignment of ip hdr */
struct mbuf *m0 = m_gethdr(MT_HEADER, M_DONTWAIT);
if (m0 == 0) {
m_freem(m);
return (ENOBUFS);
}
MH_ALIGN(m0, sizeof (struct ip));
m0->m_flags = m->m_flags & M_COPYFLAGS;
m0->m_next = m;
m0->m_len = sizeof (struct ip);
m0->m_pkthdr.len = m0->m_len + m->m_len;
m->m_flags &= ~M_PKTHDR;
} else {
M_PREPEND(m, sizeof (struct ip), M_DONTWAIT);
if (m == 0)
return (ENOBUFS);
}
/*
* Fill in IP header.
*/
ip = mtod(m, struct ip *);
*(long *)ip = 0;
ip->ip_p = IPPROTO_IDP;
ip->ip_src = ifn->ifen_src;
ip->ip_dst = ifn->ifen_dst;
ip->ip_len = (u_short)len + sizeof (struct ip);
ip->ip_ttl = MAXTTL;
/*
* Output final datagram.
*/
error = (ip_output(m, (struct mbuf *)0, ro, SO_BROADCAST, NULL));
if (error) {
ifn->ifen_ifnet.if_oerrors++;
ifn->ifen_ifnet.if_ierrors = error;
}
return (error);
bad:
m_freem(m);
return (ENETUNREACH);
}
void
ipxipstart(ifp)
struct ifnet *ifp;
{
panic("ipxip_start called\n");
}
struct ifreq ifr_ipxip = {"ipxip0"};
int
ipxip_route(m)
register struct mbuf *m;
{
register struct ipxip_req *rq = mtod(m, struct ipxip_req *);
struct sockaddr_ipx *ipx_dst = (struct sockaddr_ipx *)&rq->rq_ipx;
struct sockaddr_in *ip_dst = (struct sockaddr_in *)&rq->rq_ip;
struct route ro;
struct ifnet_en *ifn;
struct sockaddr_in *src;
/*
* First, make sure we already have an IPX address:
*/
if (ipx_hosteqnh(ipx_thishost, ipx_zerohost))
return (EADDRNOTAVAIL);
/*
* Now, determine if we can get to the destination
*/
bzero((caddr_t)&ro, sizeof (ro));
ro.ro_dst = *(struct sockaddr *)ip_dst;
rtalloc(&ro);
if (ro.ro_rt == 0 || ro.ro_rt->rt_ifp == 0) {
return (ENETUNREACH);
}
/*
* And see how he's going to get back to us:
* i.e., what return ip address do we use?
*/
{
register struct in_ifaddr *ia;
struct ifnet *ifp = ro.ro_rt->rt_ifp;
for (ia = in_ifaddr; ia; ia = ia->ia_next)
if (ia->ia_ifp == ifp)
break;
if (ia == 0)
ia = in_ifaddr;
if (ia == 0) {
RTFREE(ro.ro_rt);
return (EADDRNOTAVAIL);
}
src = (struct sockaddr_in *)&ia->ia_addr;
}
/*
* Is there a free (pseudo-)interface or space?
*/
for (ifn = ipxip_list; ifn; ifn = ifn->ifen_next) {
if ((ifn->ifen_ifnet.if_flags & IFF_UP) == 0)
break;
}
if (ifn == NULL)
ifn = ipxipattach();
if (ifn == NULL) {
RTFREE(ro.ro_rt);
return (ENOBUFS);
}
ifn->ifen_route = ro;
ifn->ifen_dst = ip_dst->sin_addr;
ifn->ifen_src = src->sin_addr;
/*
* now configure this as a point to point link
*/
ifr_ipxip.ifr_name[4] = '0' + ipxipif.if_unit - 1;
ifr_ipxip.ifr_dstaddr = * (struct sockaddr *) ipx_dst;
(void)ipx_control((struct socket *)0, (int)SIOCSIFDSTADDR, (caddr_t)&ifr_ipxip,
(struct ifnet *)ifn);
satoipx_addr(ifr_ipxip.ifr_addr).x_host = ipx_thishost;
return (ipx_control((struct socket *)0, (int)SIOCSIFADDR, (caddr_t)&ifr_ipxip,
(struct ifnet *)ifn));
}
int
ipxip_free(ifp)
struct ifnet *ifp;
{
register struct ifnet_en *ifn = (struct ifnet_en *)ifp;
struct route *ro = & ifn->ifen_route;
if (ro->ro_rt) {
RTFREE(ro->ro_rt);
ro->ro_rt = 0;
}
ifp->if_flags &= ~IFF_UP;
return (0);
}
void
ipxip_ctlinput(cmd, sa)
int cmd;
struct sockaddr *sa;
{
/*extern u_char inetctlerrmap[]; */ /*XXX*/ /*JRE*/
struct sockaddr_in *sin;
/* int in_rtchange(); */ /*XXX*/ /*JRE*/
if ((unsigned)cmd >= PRC_NCMDS)
return;
if (sa->sa_family != AF_INET && sa->sa_family != AF_IMPLINK)
return;
sin = (struct sockaddr_in *)sa;
if (sin->sin_addr.s_addr == INADDR_ANY)
return;
switch (cmd) {
case PRC_ROUTEDEAD:
case PRC_REDIRECT_NET:
case PRC_REDIRECT_HOST:
case PRC_REDIRECT_TOSNET:
case PRC_REDIRECT_TOSHOST:
ipxip_rtchange(&sin->sin_addr);
break;
}
}
void
ipxip_rtchange(dst)
register struct in_addr *dst;
{
register struct ifnet_en *ifn;
for (ifn = ipxip_list; ifn; ifn = ifn->ifen_next) {
if (ifn->ifen_dst.s_addr == dst->s_addr &&
ifn->ifen_route.ro_rt) {
RTFREE(ifn->ifen_route.ro_rt);
ifn->ifen_route.ro_rt = 0;
}
}
}
#endif

159
sys/netipx/ipx_outputfl.c Normal file
View File

@ -0,0 +1,159 @@
/*
* Copyright (c) 1995, Mike Mitchell
* Copyright (c) 1984, 1985, 1986, 1987, 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 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.
*
* @(#)ipx_outputfl.c
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/errno.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <net/if.h>
#include <net/route.h>
#include <netipx/ipx.h>
#include <netipx/ipx_if.h>
#include <netipx/ipx_var.h>
#ifdef vax
#include <machine/mtpr.h>
#endif
int ipx_hold_output = 0;
int ipx_copy_output = 0;
int ipx_outputfl_cnt = 0;
struct mbuf *ipx_lastout;
int
ipx_outputfl(m0, ro, flags)
struct mbuf *m0;
struct route *ro;
int flags;
{
register struct ipx *ipx = mtod(m0, struct ipx *);
register struct ifnet *ifp = 0;
int error = 0;
struct sockaddr_ipx *dst;
struct route ipxroute;
if (ipx_hold_output) {
if (ipx_lastout) {
(void)m_free(ipx_lastout);
}
ipx_lastout = m_copy(m0, 0, (int)M_COPYALL);
}
/*
* Route packet.
*/
if (ro == 0) {
ro = &ipxroute;
bzero((caddr_t)ro, sizeof (*ro));
}
dst = (struct sockaddr_ipx *)&ro->ro_dst;
if (ro->ro_rt == 0) {
dst->sipx_family = AF_IPX;
dst->sipx_len = sizeof (*dst);
dst->sipx_addr = ipx->ipx_dna;
dst->sipx_addr.x_port = 0;
/*
* If routing to interface only,
* short circuit routing lookup.
*/
if (flags & IPX_ROUTETOIF) {
struct ipx_ifaddr *ia = ipx_iaonnetof(&ipx->ipx_dna);
if (ia == 0) {
error = ENETUNREACH;
goto bad;
}
ifp = ia->ia_ifp;
goto gotif;
}
rtalloc(ro);
} else if ((ro->ro_rt->rt_flags & RTF_UP) == 0) {
/*
* The old route has gone away; try for a new one.
*/
rtfree(ro->ro_rt);
ro->ro_rt = NULL;
rtalloc(ro);
}
if (ro->ro_rt == 0 || (ifp = ro->ro_rt->rt_ifp) == 0) {
error = ENETUNREACH;
goto bad;
}
ro->ro_rt->rt_use++;
if (ro->ro_rt->rt_flags & (RTF_GATEWAY|RTF_HOST))
dst = (struct sockaddr_ipx *)ro->ro_rt->rt_gateway;
gotif:
/*
* Look for multicast addresses and
* and verify user is allowed to send
* such a packet.
*/
if (dst->sipx_addr.x_host.c_host[0]&1) {
if ((ifp->if_flags & IFF_BROADCAST) == 0) {
error = EADDRNOTAVAIL;
goto bad;
}
if ((flags & IPX_ALLOWBROADCAST) == 0) {
error = EACCES;
goto bad;
}
}
if (htons(ipx->ipx_len) <= ifp->if_mtu) {
ipx_outputfl_cnt++;
if (ipx_copy_output) {
ipx_watch_output(m0, ifp);
}
error = (*ifp->if_output)(ifp, m0,
(struct sockaddr *)dst, ro->ro_rt);
goto done;
} else error = EMSGSIZE;
bad:
if (ipx_copy_output) {
ipx_watch_output(m0, ifp);
}
m_freem(m0);
done:
if (ro == &ipxroute && (flags & IPX_ROUTETOIF) == 0 && ro->ro_rt) {
RTFREE(ro->ro_rt);
ro->ro_rt = 0;
}
return (error);
}

373
sys/netipx/ipx_pcb.c Normal file
View File

@ -0,0 +1,373 @@
/*
* Copyright (c) 1995, Mike Mitchell
* Copyright (c) 1984, 1985, 1986, 1987, 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 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.
*
* @(#)ipx_pcb.c
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/errno.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/protosw.h>
#include <net/if.h>
#include <net/route.h>
#include <netipx/ipx.h>
#include <netipx/ipx_if.h>
#include <netipx/ipx_pcb.h>
struct ipx_addr zeroipx_addr;
int
ipx_pcballoc(so, head)
struct socket *so;
struct ipxpcb *head;
{
struct mbuf *m;
register struct ipxpcb *ipxp;
m = m_getclr(M_DONTWAIT, MT_PCB);
if (m == NULL)
return (ENOBUFS);
ipxp = mtod(m, struct ipxpcb *);
ipxp->ipxp_socket = so;
insque(ipxp, head);
so->so_pcb = (caddr_t)ipxp;
return (0);
}
int
ipx_pcbbind(ipxp, nam)
register struct ipxpcb *ipxp;
struct mbuf *nam;
{
register struct sockaddr_ipx *sipx;
u_short lport = 0;
if (ipxp->ipxp_lport || !ipx_nullhost(ipxp->ipxp_laddr))
return (EINVAL);
if (nam == 0)
goto noname;
sipx = mtod(nam, struct sockaddr_ipx *);
if (nam->m_len != sizeof (*sipx))
return (EINVAL);
if (!ipx_nullhost(sipx->sipx_addr)) {
int tport = sipx->sipx_port;
sipx->sipx_port = 0; /* yech... */
if (ifa_ifwithaddr((struct sockaddr *)sipx) == 0)
return (EADDRNOTAVAIL);
sipx->sipx_port = tport;
}
lport = sipx->sipx_port;
if (lport) {
u_short aport = ntohs(lport);
if (aport < IPXPORT_MAX &&
(ipxp->ipxp_socket->so_state & SS_PRIV) == 0)
return (EACCES);
if (ipx_pcblookup(&zeroipx_addr, lport, 0))
return (EADDRINUSE);
}
ipxp->ipxp_laddr = sipx->sipx_addr;
noname:
if (lport == 0)
do {
if (ipxpcb.ipxp_lport++ < IPXPORT_MAX)
ipxpcb.ipxp_lport = IPXPORT_MAX;
lport = htons(ipxpcb.ipxp_lport);
} while (ipx_pcblookup(&zeroipx_addr, lport, 0));
ipxp->ipxp_lport = lport;
return (0);
}
/*
* Connect from a socket to a specified address.
* Both address and port must be specified in argument sipx.
* If don't have a local address for this socket yet,
* then pick one.
*/
int
ipx_pcbconnect(ipxp, nam)
struct ipxpcb *ipxp;
struct mbuf *nam;
{
struct ipx_ifaddr *ia;
register struct sockaddr_ipx *sipx = mtod(nam, struct sockaddr_ipx *);
register struct ipx_addr *dst;
register struct route *ro;
struct ifnet *ifp;
if (nam->m_len != sizeof (*sipx))
return (EINVAL);
if (sipx->sipx_family != AF_IPX)
return (EAFNOSUPPORT);
if (sipx->sipx_port==0 || ipx_nullhost(sipx->sipx_addr))
return (EADDRNOTAVAIL);
/*
* If we haven't bound which network number to use as ours,
* we will use the number of the outgoing interface.
* This depends on having done a routing lookup, which
* we will probably have to do anyway, so we might
* as well do it now. On the other hand if we are
* sending to multiple destinations we may have already
* done the lookup, so see if we can use the route
* from before. In any case, we only
* chose a port number once, even if sending to multiple
* destinations.
*/
ro = &ipxp->ipxp_route;
dst = &satoipx_addr(ro->ro_dst);
if (ipxp->ipxp_socket->so_options & SO_DONTROUTE)
goto flush;
if (!ipx_neteq(ipxp->ipxp_lastdst, sipx->sipx_addr))
goto flush;
if (!ipx_hosteq(ipxp->ipxp_lastdst, sipx->sipx_addr)) {
if (ro->ro_rt && ! (ro->ro_rt->rt_flags & RTF_HOST)) {
/* can patch route to avoid rtalloc */
*dst = sipx->sipx_addr;
} else {
flush:
if (ro->ro_rt)
RTFREE(ro->ro_rt);
ro->ro_rt = (struct rtentry *)0;
ipxp->ipxp_laddr.x_net = ipx_zeronet;
}
}/* else cached route is ok; do nothing */
ipxp->ipxp_lastdst = sipx->sipx_addr;
if ((ipxp->ipxp_socket->so_options & SO_DONTROUTE) == 0 && /*XXX*/
(ro->ro_rt == (struct rtentry *)0 ||
ro->ro_rt->rt_ifp == (struct ifnet *)0)) {
/* No route yet, so try to acquire one */
ro->ro_dst.sa_family = AF_IPX;
ro->ro_dst.sa_len = sizeof(ro->ro_dst);
*dst = sipx->sipx_addr;
dst->x_port = 0;
rtalloc(ro);
}
if (ipx_neteqnn(ipxp->ipxp_laddr.x_net, ipx_zeronet)) {
/*
* If route is known or can be allocated now,
* our src addr is taken from the i/f, else punt.
*/
ia = (struct ipx_ifaddr *)0;
/*
* If we found a route, use the address
* corresponding to the outgoing interface
*/
if (ro->ro_rt && (ifp = ro->ro_rt->rt_ifp))
for (ia = ipx_ifaddr; ia; ia = ia->ia_next)
if (ia->ia_ifp == ifp)
break;
if (ia == 0) {
u_short fport = sipx->sipx_addr.x_port;
sipx->sipx_addr.x_port = 0;
ia = (struct ipx_ifaddr *)
ifa_ifwithdstaddr((struct sockaddr *)sipx);
sipx->sipx_addr.x_port = fport;
if (ia == 0)
ia = ipx_iaonnetof(&sipx->sipx_addr);
if (ia == 0)
ia = ipx_ifaddr;
if (ia == 0)
return (EADDRNOTAVAIL);
}
ipxp->ipxp_laddr.x_net = satoipx_addr(ia->ia_addr).x_net;
}
if (ipx_pcblookup(&sipx->sipx_addr, ipxp->ipxp_lport, 0))
return (EADDRINUSE);
if (ipx_nullhost(ipxp->ipxp_laddr)) {
if (ipxp->ipxp_lport == 0)
(void) ipx_pcbbind(ipxp, (struct mbuf *)0);
ipxp->ipxp_laddr.x_host = ipx_thishost;
}
ipxp->ipxp_faddr = sipx->sipx_addr;
/* Includes ipxp->ipxp_fport = sipx->sipx_port; */
return (0);
}
void
ipx_pcbdisconnect(ipxp)
struct ipxpcb *ipxp;
{
ipxp->ipxp_faddr = zeroipx_addr;
if (ipxp->ipxp_socket->so_state & SS_NOFDREF)
ipx_pcbdetach(ipxp);
}
void
ipx_pcbdetach(ipxp)
struct ipxpcb *ipxp;
{
struct socket *so = ipxp->ipxp_socket;
so->so_pcb = 0;
sofree(so);
if (ipxp->ipxp_route.ro_rt)
rtfree(ipxp->ipxp_route.ro_rt);
remque(ipxp);
(void) m_free(dtom(ipxp));
}
void
ipx_setsockaddr(ipxp, nam)
register struct ipxpcb *ipxp;
struct mbuf *nam;
{
register struct sockaddr_ipx *sipx = mtod(nam, struct sockaddr_ipx *);
nam->m_len = sizeof (*sipx);
sipx = mtod(nam, struct sockaddr_ipx *);
bzero((caddr_t)sipx, sizeof (*sipx));
sipx->sipx_len = sizeof(*sipx);
sipx->sipx_family = AF_IPX;
sipx->sipx_addr = ipxp->ipxp_laddr;
}
void
ipx_setpeeraddr(ipxp, nam)
register struct ipxpcb *ipxp;
struct mbuf *nam;
{
register struct sockaddr_ipx *sipx = mtod(nam, struct sockaddr_ipx *);
nam->m_len = sizeof (*sipx);
sipx = mtod(nam, struct sockaddr_ipx *);
bzero((caddr_t)sipx, sizeof (*sipx));
sipx->sipx_len = sizeof(*sipx);
sipx->sipx_family = AF_IPX;
sipx->sipx_addr = ipxp->ipxp_faddr;
}
/*
* Pass some notification to all connections of a protocol
* associated with address dst. Call the
* protocol specific routine to handle each connection.
* Also pass an extra paramter via the ipxpcb. (which may in fact
* be a parameter list!)
*/
void
ipx_pcbnotify(dst, errno, notify, param)
register struct ipx_addr *dst;
long param;
int errno, (*notify)();
{
register struct ipxpcb *ipxp, *oinp;
int s = splimp();
for (ipxp = (&ipxpcb)->ipxp_next; ipxp != (&ipxpcb);) {
if (!ipx_hosteq(*dst,ipxp->ipxp_faddr)) {
next:
ipxp = ipxp->ipxp_next;
continue;
}
if (ipxp->ipxp_socket == 0)
goto next;
if (errno)
ipxp->ipxp_socket->so_error = errno;
oinp = ipxp;
ipxp = ipxp->ipxp_next;
oinp->ipxp_notify_param = param;
(*notify)(oinp);
}
splx(s);
}
#ifdef notdef
/*
* After a routing change, flush old routing
* and allocate a (hopefully) better one.
*/
ipx_rtchange(ipxp)
struct ipxpcb *ipxp;
{
if (ipxp->ipxp_route.ro_rt) {
rtfree(ipxp->ipxp_route.ro_rt);
ipxp->ipxp_route.ro_rt = 0;
/*
* A new route can be allocated the next time
* output is attempted.
*/
}
/* SHOULD NOTIFY HIGHER-LEVEL PROTOCOLS */
}
#endif
struct ipxpcb *
ipx_pcblookup(faddr, lport, wildp)
struct ipx_addr *faddr;
u_short lport;
int wildp;
{
register struct ipxpcb *ipxp, *match = 0;
int matchwild = 3, wildcard;
u_short fport;
fport = faddr->x_port;
for (ipxp = (&ipxpcb)->ipxp_next; ipxp != (&ipxpcb); ipxp = ipxp->ipxp_next) {
if (ipxp->ipxp_lport != lport)
continue;
wildcard = 0;
if (ipx_nullhost(ipxp->ipxp_faddr)) {
if (!ipx_nullhost(*faddr))
wildcard++;
} else {
if (ipx_nullhost(*faddr))
wildcard++;
else {
if (!ipx_hosteq(ipxp->ipxp_faddr, *faddr))
continue;
if (ipxp->ipxp_fport != fport) {
if (ipxp->ipxp_fport != 0)
continue;
else
wildcard++;
}
}
}
if (wildcard && wildp==0)
continue;
if (wildcard < matchwild) {
match = ipxp;
matchwild = wildcard;
if (wildcard == 0)
break;
}
}
return (match);
}

88
sys/netipx/ipx_pcb.h Normal file
View File

@ -0,0 +1,88 @@
/*
* Copyright (c) 1995, Mike Mitchell
* Copyright (c) 1984, 1985, 1986, 1987, 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 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.
*
* @(#)ipx_pcb.h
*/
#ifndef _NETIPX_IPX_PCB_H_
#define _NETIPX_IPX_PCB_H_
/*
* IPX protocol interface control block.
*/
struct ipxpcb {
struct ipxpcb *ipxp_next; /* doubly linked list */
struct ipxpcb *ipxp_prev;
struct ipxpcb *ipxp_head;
struct socket *ipxp_socket; /* back pointer to socket */
struct ipx_addr ipxp_faddr; /* destination address */
struct ipx_addr ipxp_laddr; /* socket's address */
caddr_t ipxp_pcb; /* protocol specific stuff */
struct route ipxp_route; /* routing information */
struct ipx_addr ipxp_lastdst; /* validate cached route for dg socks*/
long ipxp_notify_param; /* extra info passed via ipx_pcbnotify*/
short ipxp_flags;
u_char ipxp_dpt; /* default packet type for ipx_output */
u_char ipxp_rpt; /* last received packet type by ipx_input() */
};
/* possible flags */
#define IPXP_IN_ABORT 0x1 /* calling abort through socket */
#define IPXP_RAWIN 0x2 /* show headers on input */
#define IPXP_RAWOUT 0x4 /* show header on output */
#define IPXP_ALL_PACKETS 0x8 /* Turn off higher proto processing */
#define IPX_WILDCARD 1
#define ipxp_lport ipxp_laddr.x_port
#define ipxp_fport ipxp_faddr.x_port
#define sotoipxpcb(so) ((struct ipxpcb *)((so)->so_pcb))
/*
* Nominal space allocated to a IPX socket.
*/
#define IPXSNDQ 2048
#define IPXRCVQ 2048
#ifdef KERNEL
extern struct ipxpcb ipxpcb; /* head of list */
int ipx_pcballoc(), ipx_pcbbind(), ipx_pcbconnect();
void ipx_pcbdisconnect(), ipx_pcbdetach(), ipx_setsockaddr();
void ipx_setpeeraddr(), ipx_pcbnotify();
struct ipxpcb *ipx_pcblookup();
#endif
#endif

100
sys/netipx/ipx_proto.c Normal file
View File

@ -0,0 +1,100 @@
/*
* Copyright (c) 1995, Mike Mitchell
* Copyright (c) 1984, 1985, 1986, 1987, 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 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.
*
* @(#)ipx_proto.c
*/
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/protosw.h>
#include <sys/domain.h>
#include <sys/kernel.h>
#include <sys/mbuf.h>
#include <net/radix.h>
#include <netipx/ipx.h>
#include <netipx/spx.h>
/*
* IPX protocol family: IPX, ERR, PXP, SPX, ROUTE.
*/
struct protosw ipxsw[] = {
{ 0, &ipxdomain, 0, 0,
0, ipx_output, 0, 0,
0,
ipx_init, 0, 0, 0
},
{ SOCK_DGRAM, &ipxdomain, 0, PR_ATOMIC|PR_ADDR,
0, 0, ipx_ctlinput, ipx_ctloutput,
ipx_usrreq,
0, 0, 0, 0
},
{ SOCK_STREAM, &ipxdomain, IPXPROTO_SPX, PR_CONNREQUIRED|PR_WANTRCVD,
spx_input, 0, spx_ctlinput, spx_ctloutput,
spx_usrreq,
spx_init, spx_fasttimo, spx_slowtimo, 0
},
{ SOCK_SEQPACKET,&ipxdomain, IPXPROTO_SPX, PR_CONNREQUIRED|PR_WANTRCVD|PR_ATOMIC,
spx_input, 0, spx_ctlinput, spx_ctloutput,
spx_usrreq_sp,
0, 0, 0, 0
},
{ SOCK_RAW, &ipxdomain, IPXPROTO_RAW, PR_ATOMIC|PR_ADDR,
ipx_input, ipx_output, 0, ipx_ctloutput,
ipx_raw_usrreq,
0, 0, 0, 0
},
{ SOCK_RAW, &ipxdomain, IPXPROTO_ERROR, PR_ATOMIC|PR_ADDR,
ipx_ctlinput, ipx_output, 0, ipx_ctloutput,
ipx_raw_usrreq,
0, 0, 0, 0
},
#ifdef IPTUNNEL
#if 0
{ SOCK_RAW, &ipxdomain, IPPROTO_IPX, PR_ATOMIC|PR_ADDR,
iptun_input, rip_output, iptun_ctlinput, 0,
rip_usrreq,
0, 0, 0, 0,
},
#endif
#endif
};
struct domain ipxdomain =
{ AF_IPX, "network systems", 0, 0, 0,
ipxsw, &ipxsw[sizeof(ipxsw)/sizeof(ipxsw[0])], 0,
rn_inithead, 16, sizeof(struct sockaddr_ipx)};
DOMAIN_SET(ipx);

67
sys/netipx/ipx_tun.c Normal file
View File

@ -0,0 +1,67 @@
/*
* Modifications Copyright (c) 1995, Mike Mitchell
* Copyright (c) 1984, 1985, 1986, 1987, 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 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.
*
* @(#)ipx_tun.c
*/
/*
* Software interface driver for encapsulating IP in IPX.
*/
#ifdef IPTUNNEL
#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/errno.h>
#include <sys/ioctl.h>
#include <sys/protosw.h>
#include <net/if.h>
#include <net/netisr.h>
#include <net/route.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/in_var.h>
#include <netinet/ip.h>
#include <netinet/ip_var.h>
#include <machine/mtpr.h>
#include <netipx/ipx.h>
#include <netipx/ipx_if.h>
#endif

577
sys/netipx/ipx_usrreq.c Normal file
View File

@ -0,0 +1,577 @@
/*
* Copyright (c) 1995, Mike Mitchell
* Copyright (c) 1984, 1985, 1986, 1987, 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 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.
*
* @(#)ipx_usrreq.c
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/protosw.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/errno.h>
#include <sys/stat.h>
#include <net/if.h>
#include <net/route.h>
#include <netipx/ipx.h>
#include <netipx/ipx_pcb.h>
#include <netipx/ipx_if.h>
#include <netipx/ipx_var.h>
#include <netipx/ipx_error.h>
/*
* IPX protocol implementation.
*/
int noipxRoute;
/*
* This may also be called for raw listeners.
*/
void
ipx_input(m, ipxp)
struct mbuf *m;
register struct ipxpcb *ipxp;
{
register struct ipx *ipx = mtod(m, struct ipx *);
struct ifnet *ifp = m->m_pkthdr.rcvif;
struct sockaddr_ipx ipx_ipx = { sizeof(ipx_ipx), AF_IPX };
if (ipxp==0)
panic("No ipxpcb");
/*
* Construct sockaddr format source address.
* Stuff source address and datagram in user buffer.
*/
ipx_ipx.sipx_addr = ipx->ipx_sna;
if (ipx_neteqnn(ipx->ipx_sna.x_net, ipx_zeronet) && ifp) {
register struct ifaddr *ifa;
for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) {
if (ifa->ifa_addr->sa_family == AF_IPX) {
ipx_ipx.sipx_addr.x_net =
IA_SIPX(ifa)->sipx_addr.x_net;
break;
}
}
}
ipxp->ipxp_rpt = ipx->ipx_pt;
if ( ! (ipxp->ipxp_flags & IPXP_RAWIN) ) {
m->m_len -= sizeof (struct ipx);
m->m_pkthdr.len -= sizeof (struct ipx);
m->m_data += sizeof (struct ipx);
}
if (sbappendaddr(&ipxp->ipxp_socket->so_rcv, (struct sockaddr *)&ipx_ipx,
m, (struct mbuf *)0) == 0)
goto bad;
sorwakeup(ipxp->ipxp_socket);
return;
bad:
m_freem(m);
}
void
ipx_abort(ipxp)
struct ipxpcb *ipxp;
{
struct socket *so = ipxp->ipxp_socket;
ipx_pcbdisconnect(ipxp);
soisdisconnected(so);
}
/*
* Drop connection, reporting
* the specified error.
*/
/* struct ipxpcb * DELETE THIS */
void
ipx_drop(ipxp, errno)
register struct ipxpcb *ipxp;
int errno;
{
struct socket *so = ipxp->ipxp_socket;
/*
* someday, in the xerox world
* we will generate error protocol packets
* announcing that the socket has gone away.
*/
/*if (TCPS_HAVERCVDSYN(tp->t_state)) {
tp->t_state = TCPS_CLOSED;
(void) tcp_output(tp);
}*/
so->so_error = errno;
ipx_pcbdisconnect(ipxp);
soisdisconnected(so);
}
int
ipx_output(ipxp, m0)
struct ipxpcb *ipxp;
struct mbuf *m0;
{
register struct mbuf *m;
register struct ipx *ipx;
register struct socket *so;
register int len = 0;
register struct route *ro;
struct mbuf *mprev = NULL;
/*
* Calculate data length.
*/
for (m = m0; m; m = m->m_next) {
mprev = m;
len += m->m_len;
}
/*
* Make sure packet is actually of even length.
*/
if (len & 1) {
m = mprev;
if ((m->m_flags & M_EXT) == 0 &&
(m->m_len + m->m_data < &m->m_dat[MLEN])) {
m->m_len++;
} else {
struct mbuf *m1 = m_get(M_DONTWAIT, MT_DATA);
if (m1 == 0) {
m_freem(m0);
return (ENOBUFS);
}
m1->m_len = 1;
* mtod(m1, char *) = 0;
m->m_next = m1;
}
m0->m_pkthdr.len++;
}
/*
* Fill in mbuf with extended IPX header
* and addresses and length put into network format.
*/
m = m0;
if (ipxp->ipxp_flags & IPXP_RAWOUT) {
ipx = mtod(m, struct ipx *);
} else {
M_PREPEND(m, sizeof (struct ipx), M_DONTWAIT);
if (m == 0)
return (ENOBUFS);
ipx = mtod(m, struct ipx *);
ipx->ipx_tc = 0;
ipx->ipx_pt = ipxp->ipxp_dpt;
ipx->ipx_sna = ipxp->ipxp_laddr;
ipx->ipx_dna = ipxp->ipxp_faddr;
len += sizeof (struct ipx);
}
ipx->ipx_len = htons((u_short)len);
if (ipxcksum) {
ipx->ipx_sum = 0;
len = ((len - 1) | 1) + 1;
ipx->ipx_sum = ipx_cksum(m, len);
} else
ipx->ipx_sum = 0xffff;
/*
* Output datagram.
*/
so = ipxp->ipxp_socket;
if (so->so_options & SO_DONTROUTE)
return (ipx_outputfl(m, (struct route *)0,
(so->so_options & SO_BROADCAST) | IPX_ROUTETOIF));
/*
* Use cached route for previous datagram if
* possible. If the previous net was the same
* and the interface was a broadcast medium, or
* if the previous destination was identical,
* then we are ok.
*
* NB: We don't handle broadcasts because that
* would require 3 subroutine calls.
*/
ro = &ipxp->ipxp_route;
#ifdef ancient_history
/*
* I think that this will all be handled in ipx_pcbconnect!
*/
if (ro->ro_rt) {
if(ipx_neteq(ipxp->ipxp_lastdst, ipx->ipx_dna)) {
/*
* This assumes we have no GH type routes
*/
if (ro->ro_rt->rt_flags & RTF_HOST) {
if (!ipx_hosteq(ipxp->ipxp_lastdst, ipx->ipx_dna))
goto re_route;
}
if ((ro->ro_rt->rt_flags & RTF_GATEWAY) == 0) {
register struct ipx_addr *dst =
&satoipx_addr(ro->ro_dst);
dst->x_host = ipx->ipx_dna.x_host;
}
/*
* Otherwise, we go through the same gateway
* and dst is already set up.
*/
} else {
re_route:
RTFREE(ro->ro_rt);
ro->ro_rt = (struct rtentry *)0;
}
}
ipxp->ipxp_lastdst = ipx->ipx_dna;
#endif /* ancient_history */
if (noipxRoute) ro = 0;
return (ipx_outputfl(m, ro, so->so_options & SO_BROADCAST));
}
/* ARGSUSED */
int
ipx_ctloutput(req, so, level, name, value)
int req, level;
struct socket *so;
int name;
struct mbuf **value;
{
register struct mbuf *m;
struct ipxpcb *ipxp = sotoipxpcb(so);
int mask, error = 0;
/*extern long ipx_pexseq;*/ /*XXX*//*JRE*/
if (ipxp == NULL)
return (EINVAL);
switch (req) {
case PRCO_GETOPT:
if (value==NULL)
return (EINVAL);
m = m_get(M_DONTWAIT, MT_DATA);
if (m==NULL)
return (ENOBUFS);
switch (name) {
case SO_ALL_PACKETS:
mask = IPXP_ALL_PACKETS;
goto get_flags;
case SO_HEADERS_ON_INPUT:
mask = IPXP_RAWIN;
goto get_flags;
case SO_HEADERS_ON_OUTPUT:
mask = IPXP_RAWOUT;
get_flags:
m->m_len = sizeof(short);
*mtod(m, short *) = ipxp->ipxp_flags & mask;
break;
case SO_DEFAULT_HEADERS:
m->m_len = sizeof(struct ipx);
{
register struct ipx *ipx = mtod(m, struct ipx *);
ipx->ipx_len = 0;
ipx->ipx_sum = 0;
ipx->ipx_tc = 0;
ipx->ipx_pt = ipxp->ipxp_dpt;
ipx->ipx_dna = ipxp->ipxp_faddr;
ipx->ipx_sna = ipxp->ipxp_laddr;
}
break;
case SO_SEQNO:
m->m_len = sizeof(long);
*mtod(m, long *) = ipx_pexseq++;
break;
default:
error = EINVAL;
}
*value = m;
break;
case PRCO_SETOPT:
switch (name) {
int *ok;
case SO_ALL_PACKETS:
mask = IPXP_ALL_PACKETS;
goto set_head;
case SO_HEADERS_ON_INPUT:
mask = IPXP_RAWIN;
goto set_head;
case SO_HEADERS_ON_OUTPUT:
mask = IPXP_RAWOUT;
set_head:
if (value && *value) {
ok = mtod(*value, int *);
if (*ok)
ipxp->ipxp_flags |= mask;
else
ipxp->ipxp_flags &= ~mask;
} else error = EINVAL;
break;
case SO_DEFAULT_HEADERS:
{
register struct ipx *ipx
= mtod(*value, struct ipx *);
ipxp->ipxp_dpt = ipx->ipx_pt;
}
break;
#ifdef IPXIP
case SO_IPXIP_ROUTE:
error = ipxip_route(*value);
break;
#endif /* IPXIP */
#ifdef IPXTUNNEL
case SO_IPXTUNNEL_ROUTE
error = ipxtun_route(*value);
break;
#endif
default:
error = EINVAL;
}
if (value && *value)
m_freem(*value);
break;
}
return (error);
}
/*ARGSUSED*/
int
ipx_usrreq(so, req, m, nam, control)
struct socket *so;
int req;
struct mbuf *m, *nam, *control;
{
struct ipxpcb *ipxp = sotoipxpcb(so);
int error = 0;
if (req == PRU_CONTROL)
return (ipx_control(so, (int)m, (caddr_t)nam,
(struct ifnet *)control));
if (control && control->m_len) {
error = EINVAL;
goto release;
}
if (ipxp == NULL && req != PRU_ATTACH) {
error = EINVAL;
goto release;
}
switch (req) {
case PRU_ATTACH:
if (ipxp != NULL) {
error = EINVAL;
break;
}
error = ipx_pcballoc(so, &ipxpcb);
if (error)
break;
error = soreserve(so, (u_long) 2048, (u_long) 2048);
if (error)
break;
break;
case PRU_DETACH:
if (ipxp == NULL) {
error = ENOTCONN;
break;
}
ipx_pcbdetach(ipxp);
break;
case PRU_BIND:
error = ipx_pcbbind(ipxp, nam);
break;
case PRU_LISTEN:
error = EOPNOTSUPP;
break;
case PRU_CONNECT:
if (!ipx_nullhost(ipxp->ipxp_faddr)) {
error = EISCONN;
break;
}
error = ipx_pcbconnect(ipxp, nam);
if (error == 0)
soisconnected(so);
break;
case PRU_CONNECT2:
error = EOPNOTSUPP;
break;
case PRU_ACCEPT:
error = EOPNOTSUPP;
break;
case PRU_DISCONNECT:
if (ipx_nullhost(ipxp->ipxp_faddr)) {
error = ENOTCONN;
break;
}
ipx_pcbdisconnect(ipxp);
soisdisconnected(so);
break;
case PRU_SHUTDOWN:
socantsendmore(so);
break;
case PRU_SEND:
{
struct ipx_addr laddr;
int s = 0;
if (nam) {
laddr = ipxp->ipxp_laddr;
if (!ipx_nullhost(ipxp->ipxp_faddr)) {
error = EISCONN;
break;
}
/*
* Must block input while temporarily connected.
*/
s = splnet();
error = ipx_pcbconnect(ipxp, nam);
if (error) {
splx(s);
break;
}
} else {
if (ipx_nullhost(ipxp->ipxp_faddr)) {
error = ENOTCONN;
break;
}
}
error = ipx_output(ipxp, m);
m = NULL;
if (nam) {
ipx_pcbdisconnect(ipxp);
splx(s);
ipxp->ipxp_laddr.x_host = laddr.x_host;
ipxp->ipxp_laddr.x_port = laddr.x_port;
}
}
break;
case PRU_ABORT:
ipx_pcbdetach(ipxp);
sofree(so);
soisdisconnected(so);
break;
case PRU_SOCKADDR:
ipx_setsockaddr(ipxp, nam);
break;
case PRU_PEERADDR:
ipx_setpeeraddr(ipxp, nam);
break;
case PRU_SENSE:
/*
* stat: don't bother with a blocksize.
*/
return (0);
case PRU_SENDOOB:
case PRU_FASTTIMO:
case PRU_SLOWTIMO:
case PRU_PROTORCV:
case PRU_PROTOSEND:
error = EOPNOTSUPP;
break;
case PRU_CONTROL:
case PRU_RCVD:
case PRU_RCVOOB:
return (EOPNOTSUPP); /* do not free mbuf's */
default:
panic("ipx_usrreq");
}
release:
if (control != NULL)
m_freem(control);
if (m != NULL)
m_freem(m);
return (error);
}
/*ARGSUSED*/
int
ipx_raw_usrreq(so, req, m, nam, control)
struct socket *so;
int req;
struct mbuf *m, *nam, *control;
{
int error = 0;
struct ipxpcb *ipxp = sotoipxpcb(so);
/*extern struct ipxpcb ipxrawpcb;*//*XXX*//*JRE*/
switch (req) {
case PRU_ATTACH:
if (!(so->so_state & SS_PRIV) || (ipxp != NULL)) {
error = EINVAL;
break;
}
error = ipx_pcballoc(so, &ipxrawpcb);
if (error)
break;
error = soreserve(so, (u_long) 2048, (u_long) 2048);
if (error)
break;
ipxp = sotoipxpcb(so);
ipxp->ipxp_faddr.x_host = ipx_broadhost;
ipxp->ipxp_flags = IPXP_RAWIN | IPXP_RAWOUT;
break;
default:
error = ipx_usrreq(so, req, m, nam, control);
}
return (error);
}

55
sys/netipx/ipx_var.h Normal file
View File

@ -0,0 +1,55 @@
/*
* Copyright (c) 1995, Mike Mitchell
* Copyright (c) 1984, 1985, 1986, 1987, 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 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.
*
* @(#)ipx_var.h
*/
#ifndef _NETIPX_IPX_VAR_H_
#define _NETIPX_IPX_VAR_H_
/*
* IPX Kernel Structures and Variables
*/
struct ipxstat {
int ipxs_badsum; /* checksum bad */
int ipxs_tooshort; /* packet too short */
int ipxs_toosmall; /* not enough data */
int ipxs_badhlen; /* ip header length < data size */
int ipxs_badlen; /* ip length < ip header length */
};
#ifdef KERNEL
extern struct ipxstat ipxstat;
#endif
#endif

97
sys/netipx/spx.h Normal file
View File

@ -0,0 +1,97 @@
/*
* Copyright (c) 1995, Mike Mitchell
* Copyright (c) 1984, 1985, 1986, 1987, 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 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.
*
* @(#)spx.h
*/
#ifndef _NETIPX_SPX_H_
#define _NETIPX_SPX_H_
/*
* Definitions for IPX style Sequenced Packet Protocol
*/
struct spxhdr {
u_char spx_cc; /* connection control */
u_char spx_dt; /* datastream type */
#define SPX_SP 0x80 /* system packet */
#define SPX_SA 0x40 /* send acknowledgement */
#define SPX_OB 0x20 /* attention (out of band data) */
#define SPX_EM 0x10 /* end of message */
u_short spx_sid; /* source connection identifier */
u_short spx_did; /* destination connection identifier */
u_short spx_seq; /* sequence number */
u_short spx_ack; /* acknowledge number */
u_short spx_alo; /* allocation number */
};
/*
* Definitions for NS(tm) Internet Datagram Protocol
* containing a Sequenced Packet Protocol packet.
*/
struct spx {
struct ipx si_i;
struct spxhdr si_s;
};
struct spx_q {
struct spx_q *si_next;
struct spx_q *si_prev;
};
#define SI(x) ((struct spx *)x)
#define si_sum si_i.ipx_sum
#define si_len si_i.ipx_len
#define si_tc si_i.ipx_tc
#define si_pt si_i.ipx_pt
#define si_dna si_i.ipx_dna
#define si_sna si_i.ipx_sna
#define si_sport si_i.ipx_sna.x_port
#define si_cc si_s.spx_cc
#define si_dt si_s.spx_dt
#define si_sid si_s.spx_sid
#define si_did si_s.spx_did
#define si_seq si_s.spx_seq
#define si_ack si_s.spx_ack
#define si_alo si_s.spx_alo
#ifdef KERNEL
int spx_reass(), spx_output();
int spx_usrreq(), spx_usrreq_sp(), spx_ctloutput();
void spx_input(), spx_ctlinput();
void spx_init(), spx_fasttimo(), spx_slowtimo();
void spx_quench(), spx_setpersist(), spx_template(), spx_abort();
struct spxpcb *spx_close(), *spx_usrclosed();
struct spxpcb *spx_disconnect(), *spx_drop();
struct spxpcb *spx_timers();
#endif
#endif

168
sys/netipx/spx_debug.c Normal file
View File

@ -0,0 +1,168 @@
/*
* Copyright (c) 1995, Mike Mitchell
* Copyright (c) 1984, 1985, 1986, 1987, 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 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.
*
* @(#)spx_debug.c
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/protosw.h>
#include <sys/errno.h>
#include <net/route.h>
#include <net/if.h>
#include <netinet/in_systm.h>
#include <netinet/tcp_fsm.h>
#include <netipx/ipx.h>
#include <netipx/ipx_error.h>
#include <netipx/ipx_pcb.h>
#include <netipx/ipx.h>
#include <netipx/ipx_var.h>
#include <netipx/spx.h>
#define SPXTIMERS
#include <netipx/spx_timer.h>
#include <netipx/spx_var.h>
#define SANAMES
#include <netipx/spx_debug.h>
int spxconsdebug = 0;
/*
* spx debug routines
*/
void
spx_trace(act, ostate, sp, si, req)
short act;
u_char ostate;
struct spxpcb *sp;
struct spx *si;
int req;
{
#ifdef INET
#ifdef TCPDEBUG
u_short seq, ack, len, alo;
int flags;
struct spx_debug *sd = &spx_debug[spx_debx++];
if (spx_debx == SPX_NDEBUG)
spx_debx = 0;
sd->sd_time = iptime();
sd->sd_act = act;
sd->sd_ostate = ostate;
sd->sd_cb = (caddr_t)sp;
if (sp)
sd->sd_sp = *sp;
else
bzero((caddr_t)&sd->sd_sp, sizeof (*sp));
if (si)
sd->sd_si = *si;
else
bzero((caddr_t)&sd->sd_si, sizeof (*si));
sd->sd_req = req;
if (spxconsdebug == 0)
return;
if (ostate >= TCP_NSTATES) ostate = 0;
if (act >= SA_DROP) act = SA_DROP;
if (sp)
printf("%x %s:", sp, tcpstates[ostate]);
else
printf("???????? ");
printf("%s ", sanames[act]);
switch (act) {
case SA_RESPOND:
case SA_INPUT:
case SA_OUTPUT:
case SA_DROP:
if (si == 0)
break;
seq = si->si_seq;
ack = si->si_ack;
alo = si->si_alo;
len = si->si_len;
if (act == SA_OUTPUT) {
seq = ntohs(seq);
ack = ntohs(ack);
alo = ntohs(alo);
len = ntohs(len);
}
#ifndef lint
#define p1(f) { printf("%s = %x, ", "f", f); }
p1(seq); p1(ack); p1(alo); p1(len);
#endif
flags = si->si_cc;
if (flags) {
char *cp = "<";
#ifndef lint
#define pf(f) { if (flags & SPX_ ## f) { printf("%s%s", cp, "f"); cp = ","; } }
pf(SP); pf(SA); pf(OB); pf(EM);
#else
cp = cp;
#endif
printf(">");
}
#ifndef lint
#define p2(f) { printf("%s = %x, ", "f", si->si_ ## f); }
p2(sid);p2(did);p2(dt);p2(pt);
#endif
ipx_printhost(&si->si_sna);
ipx_printhost(&si->si_dna);
if (act==SA_RESPOND) {
printf("ipx_len = %x, ",
((struct ipx *)si)->ipx_len);
}
break;
case SA_USER:
printf("%s", prurequests[req&0xff]);
if ((req & 0xff) == PRU_SLOWTIMO)
printf("<%s>", spxtimers[req>>8]);
break;
}
if (sp)
printf(" -> %s", tcpstates[sp->s_state]);
/* print out internal state of sp !?! */
printf("\n");
if (sp == 0)
return;
#ifndef lint
#define p3(f) { printf("%s = %x, ", "f", sp->s_ ## f); }
printf("\t"); p3(rack);p3(ralo);p3(smax);p3(flags); printf("\n");
#endif
#endif
#endif
}

75
sys/netipx/spx_debug.h Normal file
View File

@ -0,0 +1,75 @@
/*
* Copyright (c) 1995, Mike Mitchell
* Copyright (c) 1984, 1985, 1986, 1987, 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 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.
*
* @(#)spx_debug.h
*/
#ifndef _NETIPX_SPX_DEBUG_H_
#define _NETIPX_SPX_DEBUG_H_
struct spx_debug {
u_long sd_time;
short sd_act;
short sd_ostate;
caddr_t sd_cb;
short sd_req;
struct spx sd_si;
struct spxpcb sd_sp;
};
#define SA_INPUT 0
#define SA_OUTPUT 1
#define SA_USER 2
#define SA_RESPOND 3
#define SA_DROP 4
#ifdef SANAMES
char *spxnames[] =
{ "input", "output", "user", "respond", "drop" };
#endif
#define SPX_NDEBUG 100
struct spx_debug spx_debug[SPX_NDEBUG];
int spx_debx;
#ifdef KERNEL
void spx_trace();
extern char *prurequests[];
extern char *sanames[];
extern char *tcpstates[];
#endif
#endif

128
sys/netipx/spx_timer.h Normal file
View File

@ -0,0 +1,128 @@
/*
* Copyright (c) 1995, Mike Mitchell
* Copyright (c) 1982, 1986, 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 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.
*
* @(#)spx_timer.h
*/
#ifndef _NETIPX_SPX_TIMER_H_
#define _NETIPX_SPX_TIMER_H_
/*
* Definitions of the SPX timers. These timers are counted
* down PR_SLOWHZ times a second.
*/
#define SPXT_NTIMERS 4
#define SPXT_REXMT 0 /* retransmit */
#define SPXT_PERSIST 1 /* retransmit persistance */
#define SPXT_KEEP 2 /* keep alive */
#define SPXT_2MSL 3 /* 2*msl quiet time timer */
/*
* The SPXT_REXMT timer is used to force retransmissions.
* The SPX has the SPXT_REXMT timer set whenever segments
* have been sent for which ACKs are expected but not yet
* received. If an ACK is received which advances tp->snd_una,
* then the retransmit timer is cleared (if there are no more
* outstanding segments) or reset to the base value (if there
* are more ACKs expected). Whenever the retransmit timer goes off,
* we retransmit one unacknowledged segment, and do a backoff
* on the retransmit timer.
*
* The SPXT_PERSIST timer is used to keep window size information
* flowing even if the window goes shut. If all previous transmissions
* have been acknowledged (so that there are no retransmissions in progress),
* and the window is too small to bother sending anything, then we start
* the SPXT_PERSIST timer. When it expires, if the window is nonzero,
* we go to transmit state. Otherwise, at intervals send a single byte
* into the peer's window to force him to update our window information.
* We do this at most as often as SPXT_PERSMIN time intervals,
* but no more frequently than the current estimate of round-trip
* packet time. The SPXT_PERSIST timer is cleared whenever we receive
* a window update from the peer.
*
* The SPXT_KEEP timer is used to keep connections alive. If an
* connection is idle (no segments received) for SPXTV_KEEP amount of time,
* but not yet established, then we drop the connection. If the connection
* is established, then we force the peer to send us a segment by sending:
* <SEQ=SND.UNA-1><ACK=RCV.NXT><CTL=ACK>
* This segment is (deliberately) outside the window, and should elicit
* an ack segment in response from the peer. If, despite the SPXT_KEEP
* initiated segments we cannot elicit a response from a peer in SPXT_MAXIDLE
* amount of time, then we drop the connection.
*/
#define SPX_TTL 30 /* default time to live for SPX segs */
/*
* Time constants.
*/
#define SPXTV_MSL ( 15*PR_SLOWHZ) /* max seg lifetime */
#define SPXTV_SRTTBASE 0 /* base roundtrip time;
if 0, no idea yet */
#define SPXTV_SRTTDFLT ( 3*PR_SLOWHZ) /* assumed RTT if no info */
#define SPXTV_PERSMIN ( 5*PR_SLOWHZ) /* retransmit persistance */
#define SPXTV_PERSMAX ( 60*PR_SLOWHZ) /* maximum persist interval */
#define SPXTV_KEEP ( 75*PR_SLOWHZ) /* keep alive - 75 secs */
#define SPXTV_MAXIDLE ( 8*SPXTV_KEEP) /* maximum allowable idle
time before drop conn */
#define SPXTV_MIN ( 1*PR_SLOWHZ) /* minimum allowable value */
#define SPXTV_REXMTMAX ( 64*PR_SLOWHZ) /* max allowable REXMT value */
#define SPX_LINGERTIME 120 /* linger at most 2 minutes */
#define SPX_MAXRXTSHIFT 12 /* maximum retransmits */
#ifdef SPXTIMERS
char *spxtimers[] =
{ "REXMT", "PERSIST", "KEEP", "2MSL" };
#endif
/*
* Force a time value to be in a certain range.
*/
#define SPXT_RANGESET(tv, value, tvmin, tvmax) { \
(tv) = (value); \
if ((tv) < (tvmin)) \
(tv) = (tvmin); \
else if ((tv) > (tvmax)) \
(tv) = (tvmax); \
}
#ifdef KERNEL
extern int spx_backoff[];
#endif
#endif

1815
sys/netipx/spx_usrreq.c Normal file

File diff suppressed because it is too large Load Diff

211
sys/netipx/spx_var.h Normal file
View File

@ -0,0 +1,211 @@
/*
* Copyright (c) 1995, Mike Mitchell
* Copyright (c) 1984, 1985, 1986, 1987, 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 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.
*
* @(#)spx_var.h
*/
#ifndef _NETIPX_SPX_VAR_H_
#define _NETIPX_SPX_VAR_H_
/*
* SPX control block, one per connection
*/
struct spxpcb {
struct spx_q s_q; /* queue for out-of-order receipt */
struct ipxpcb *s_ipxpcb; /* backpointer to internet pcb */
u_char s_state;
u_char s_flags;
#define SF_ACKNOW 0x01 /* Ack peer immediately */
#define SF_DELACK 0x02 /* Ack, but try to delay it */
#define SF_HI 0x04 /* Show headers on input */
#define SF_HO 0x08 /* Show headers on output */
#define SF_PI 0x10 /* Packet (datagram) interface */
#define SF_WIN 0x20 /* Window info changed */
#define SF_RXT 0x40 /* Rxt info changed */
#define SF_RVD 0x80 /* Calling from read usrreq routine */
u_short s_mtu; /* Max packet size for this stream */
/* use sequence fields in headers to store sequence numbers for this
connection */
struct ipx *s_ipx;
struct spxhdr s_shdr; /* prototype header to transmit */
#define s_cc s_shdr.spx_cc /* connection control (for EM bit) */
#define s_dt s_shdr.spx_dt /* datastream type */
#define s_sid s_shdr.spx_sid /* source connection identifier */
#define s_did s_shdr.spx_did /* destination connection identifier */
#define s_seq s_shdr.spx_seq /* sequence number */
#define s_ack s_shdr.spx_ack /* acknowledge number */
#define s_alo s_shdr.spx_alo /* allocation number */
#define s_dport s_ipx->ipx_dna.x_port /* where we are sending */
struct spxhdr s_rhdr; /* last received header (in effect!)*/
u_short s_rack; /* their acknowledge number */
u_short s_ralo; /* their allocation number */
u_short s_smax; /* highest packet # we have sent */
u_short s_snxt; /* which packet to send next */
/* congestion control */
#define CUNIT 1024 /* scaling for ... */
int s_cwnd; /* Congestion-controlled window */
/* in packets * CUNIT */
short s_swnd; /* == tcp snd_wnd, in packets */
short s_smxw; /* == tcp max_sndwnd */
/* difference of two spx_seq's can be
no bigger than a short */
u_short s_swl1; /* == tcp snd_wl1 */
u_short s_swl2; /* == tcp snd_wl2 */
int s_cwmx; /* max allowable cwnd */
int s_ssthresh; /* s_cwnd size threshhold for
* slow start exponential-to-
* linear switch */
/* transmit timing stuff
* srtt and rttvar are stored as fixed point, for convenience in smoothing.
* srtt has 3 bits to the right of the binary point, rttvar has 2.
*/
short s_idle; /* time idle */
short s_timer[SPXT_NTIMERS]; /* timers */
short s_rxtshift; /* log(2) of rexmt exp. backoff */
short s_rxtcur; /* current retransmit value */
u_short s_rtseq; /* packet being timed */
short s_rtt; /* timer for round trips */
short s_srtt; /* averaged timer */
short s_rttvar; /* variance in round trip time */
char s_force; /* which timer expired */
char s_dupacks; /* counter to intuit xmt loss */
/* out of band data */
char s_oobflags;
#define SF_SOOB 0x08 /* sending out of band data */
#define SF_IOOB 0x10 /* receiving out of band data */
char s_iobc; /* input characters */
/* debug stuff */
u_short s_want; /* Last candidate for sending */
char s_outx; /* exit taken from spx_output */
char s_inx; /* exit taken from spx_input */
u_short s_flags2; /* more flags for testing */
#define SF_NEWCALL 0x100 /* for new_recvmsg */
#define SO_NEWCALL 10 /* for new_recvmsg */
};
#define ipxtospxpcb(np) ((struct spxpcb *)(np)->ipxp_pcb)
#define sotospxpcb(so) (ipxtospxpcb(sotoipxpcb(so)))
struct spxstat {
long spxs_connattempt; /* connections initiated */
long spxs_accepts; /* connections accepted */
long spxs_connects; /* connections established */
long spxs_drops; /* connections dropped */
long spxs_conndrops; /* embryonic connections dropped */
long spxs_closed; /* conn. closed (includes drops) */
long spxs_segstimed; /* segs where we tried to get rtt */
long spxs_rttupdated; /* times we succeeded */
long spxs_delack; /* delayed acks sent */
long spxs_timeoutdrop; /* conn. dropped in rxmt timeout */
long spxs_rexmttimeo; /* retransmit timeouts */
long spxs_persisttimeo; /* persist timeouts */
long spxs_keeptimeo; /* keepalive timeouts */
long spxs_keepprobe; /* keepalive probes sent */
long spxs_keepdrops; /* connections dropped in keepalive */
long spxs_sndtotal; /* total packets sent */
long spxs_sndpack; /* data packets sent */
long spxs_sndbyte; /* data bytes sent */
long spxs_sndrexmitpack; /* data packets retransmitted */
long spxs_sndrexmitbyte; /* data bytes retransmitted */
long spxs_sndacks; /* ack-only packets sent */
long spxs_sndprobe; /* window probes sent */
long spxs_sndurg; /* packets sent with URG only */
long spxs_sndwinup; /* window update-only packets sent */
long spxs_sndctrl; /* control (SYN|FIN|RST) packets sent */
long spxs_sndvoid; /* couldn't find requested packet*/
long spxs_rcvtotal; /* total packets received */
long spxs_rcvpack; /* packets received in sequence */
long spxs_rcvbyte; /* bytes received in sequence */
long spxs_rcvbadsum; /* packets received with ccksum errs */
long spxs_rcvbadoff; /* packets received with bad offset */
long spxs_rcvshort; /* packets received too short */
long spxs_rcvduppack; /* duplicate-only packets received */
long spxs_rcvdupbyte; /* duplicate-only bytes received */
long spxs_rcvpartduppack; /* packets with some duplicate data */
long spxs_rcvpartdupbyte; /* dup. bytes in part-dup. packets */
long spxs_rcvoopack; /* out-of-order packets received */
long spxs_rcvoobyte; /* out-of-order bytes received */
long spxs_rcvpackafterwin; /* packets with data after window */
long spxs_rcvbyteafterwin; /* bytes rcvd after window */
long spxs_rcvafterclose; /* packets rcvd after "close" */
long spxs_rcvwinprobe; /* rcvd window probe packets */
long spxs_rcvdupack; /* rcvd duplicate acks */
long spxs_rcvacktoomuch; /* rcvd acks for unsent data */
long spxs_rcvackpack; /* rcvd ack packets */
long spxs_rcvackbyte; /* bytes acked by rcvd acks */
long spxs_rcvwinupd; /* rcvd window update packets */
};
struct spx_istat {
short hdrops;
short badsum;
short badlen;
short slotim;
short fastim;
short nonucn;
short noconn;
short notme;
short wrncon;
short bdreas;
short gonawy;
short notyet;
short lstdup;
struct spxstat newstats;
};
#ifdef KERNEL
extern struct spx_istat spx_istat;
extern u_short spx_iss;
/* Following was struct spxstat spxstat; */
#ifndef spxstat
#define spxstat spx_istat.newstats
#endif
#endif
#define SPX_ISSINCR 128
/*
* spx sequence numbers are 16 bit integers operated
* on with modular arithmetic. These macros can be
* used to compare such integers.
*/
#define SSEQ_LT(a,b) (((short)((a)-(b))) < 0)
#define SSEQ_LEQ(a,b) (((short)((a)-(b))) <= 0)
#define SSEQ_GT(a,b) (((short)((a)-(b))) > 0)
#define SSEQ_GEQ(a,b) (((short)((a)-(b))) >= 0)
#endif

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)ns.h 8.1 (Berkeley) 6/10/93
* $Id: ns.h,v 1.3 1994/08/21 06:22:07 paul Exp $
* $Id: ns.h,v 1.4 1995/07/29 11:41:49 bde Exp $
*/
#ifndef _NETNS_NS_H_
@ -150,6 +150,7 @@ u_short ns_cksum();
__BEGIN_DECLS
extern struct ns_addr ns_addr __P((const char *));
extern char *ns_ntoa __P((struct ns_addr));
extern char *_ns_spectHex __P((const char *));
__END_DECLS
#endif

View File

@ -1,9 +1,9 @@
# @(#)Makefile 8.1 (Berkeley) 6/12/93
PROG= netstat
SRCS= if.c inet.c iso.c main.c mbuf.c mroute.c ns.c route.c \
SRCS= if.c inet.c iso.c main.c mbuf.c mroute.c ipx.c ns.c route.c \
tp_astring.c unix.c
CFLAGS+=-I/sys
CFLAGS+=-I/sys # -g
.PATH: ${.CURDIR}/../../sys/netiso
BINGRP= kmem
BINMODE=2555

View File

@ -43,6 +43,8 @@ static char sccsid[] = "@(#)if.c 8.2 (Berkeley) 2/21/94";
#include <net/if_dl.h>
#include <netinet/in.h>
#include <netinet/in_var.h>
#include <netipx/ipx.h>
#include <netipx/ipx_if.h>
#include <netns/ns.h>
#include <netns/ns_if.h>
#include <netiso/iso.h>
@ -74,6 +76,7 @@ intpr(interval, ifnetaddr)
union {
struct ifaddr ifa;
struct in_ifaddr in;
struct ipx_ifaddr ipx;
struct ns_ifaddr ns;
struct iso_ifaddr iso;
} ifaddr;
@ -91,7 +94,7 @@ intpr(interval, ifnetaddr)
}
if (kread(ifnetaddr, (char *)&ifnetaddr, sizeof ifnetaddr))
return;
printf("%-5.5s %-5.5s %-11.11s %-15.15s %8.8s %5.5s",
printf("%-5.5s %-5.5s %-13.13s %-15.15s %8.8s %5.5s",
"Name", "Mtu", "Network", "Address", "Ipkts", "Ierrs");
if (bflag)
printf(" %10.10s","Ibytes");
@ -127,7 +130,7 @@ intpr(interval, ifnetaddr)
}
printf("%-5.5s %-5d ", name, ifnet.if_mtu);
if (ifaddraddr == 0) {
printf("%-11.11s ", "none");
printf("%-13.13s ", "none");
printf("%-15.15s ", "none");
} else {
if (kread(ifaddraddr, (char *)&ifaddr, sizeof ifaddr)) {
@ -139,7 +142,7 @@ intpr(interval, ifnetaddr)
CP(&ifaddr); sa = (struct sockaddr *)cp;
switch (sa->sa_family) {
case AF_UNSPEC:
printf("%-11.11s ", "none");
printf("%-13.13s ", "none");
printf("%-15.15s ", "none");
break;
case AF_INET:
@ -160,12 +163,27 @@ intpr(interval, ifnetaddr)
printf("%-15.15s ",
routename(sin->sin_addr.s_addr));
break;
case AF_IPX:
{
struct sockaddr_ipx *sipx =
(struct sockaddr_ipx *)sa;
u_long net;
char netnum[10];
*(union ipx_net *) &net = sipx->sipx_addr.x_net;
sprintf(netnum, "%lx", ntohl(net));
printf("ipx:%-8s ", netnum);
/* printf("ipx:%-8s ", netname(net, 0L)); */
printf("%-15s ",
ipx_phost((struct sockaddr *)sipx));
}
break;
case AF_NS:
{
struct sockaddr_ns *sns =
(struct sockaddr_ns *)sa;
u_long net;
char netnum[8];
char netnum[10];
*(union ns_net *) &net = sns->sns_addr.x_net;
sprintf(netnum, "%lxH", ntohl(net));
@ -194,7 +212,7 @@ intpr(interval, ifnetaddr)
while (--n >= 0)
m += printf("%02x%c", *cp++ & 0xff,
n > 0 ? '.' : ' ');
m = 28 - m;
m = 30 - m;
while (m-- > 0)
putchar(' ');
break;

View File

@ -125,6 +125,14 @@ struct nlist nl[] = {
{ "_mfctable" },
#define N_VIFTABLE 30
{ "_viftable" },
#define N_IPX 31
{ "_ipxpcb"},
#define N_IPXSTAT 32
{ "_ipxstat"},
#define N_SPXSTAT 33
{ "_spx_istat"},
#define N_IPXERR 34
{ "_ipx_errstat"},
"",
};
@ -150,6 +158,17 @@ struct protox {
0, 0 }
};
struct protox ipxprotox[] = {
{ N_IPX, N_IPXSTAT, 1, ipxprotopr,
ipx_stats, "ipx" },
{ N_IPX, N_SPXSTAT, 1, ipxprotopr,
spx_stats, "spx" },
{ -1, N_IPXERR, 1, 0,
ipxerr_stats, "ipx_err" },
{ -1, -1, 0, 0,
0, 0 }
};
struct protox nsprotox[] = {
{ N_IDP, N_IDPSTAT, 1, nsprotopr,
idp_stats, "idp" },
@ -174,7 +193,7 @@ struct protox isoprotox[] = {
0, 0 }
};
struct protox *protoprotox[] = { protox, nsprotox, isoprotox, NULL };
struct protox *protoprotox[] = { protox, ipxprotox, nsprotox, isoprotox, NULL };
static void printproto __P((struct protox *, char *));
static void usage __P((void));
@ -221,6 +240,8 @@ main(argc, argv)
case 'f':
if (strcmp(optarg, "ns") == 0)
af = AF_NS;
else if (strcmp(optarg, "ipx") == 0)
af = AF_IPX;
else if (strcmp(optarg, "inet") == 0)
af = AF_INET;
else if (strcmp(optarg, "unix") == 0)
@ -384,6 +405,9 @@ main(argc, argv)
}
endprotoent();
}
if (af == AF_IPX || af == AF_UNSPEC)
for (tp = ipxprotox; tp->pr_name; tp++)
printproto(tp, tp->pr_name);
if (af == AF_NS || af == AF_UNSPEC)
for (tp = nsprotox; tp->pr_name; tp++)
printproto(tp, tp->pr_name);

View File

@ -80,14 +80,22 @@ void intpr __P((int, u_long));
void pr_rthdr __P(());
void pr_family __P((int));
void rt_stats __P((u_long));
char *ipx_pnet __P((struct sockaddr *));
char *ipx_phost __P((struct sockaddr *));
char *ns_phost __P((struct sockaddr *));
void upHex __P((char *));
char *routename __P((u_long));
char *netname __P((u_long, u_long));
char *ipx_print __P((struct sockaddr *));
char *ns_print __P((struct sockaddr *));
void routepr __P((u_long));
void ipxprotopr __P((u_long, char *));
void spx_stats __P((u_long, char *));
void ipx_stats __P((u_long, char *));
void ipxerr_stats __P((u_long, char *));
void nsprotopr __P((u_long, char *));
void spp_stats __P((u_long, char *));
void idp_stats __P((u_long, char *));

View File

@ -36,7 +36,7 @@
static char sccsid[] = "From: @(#)route.c 8.3 (Berkeley) 3/9/94";
#endif
static const char rcsid[] =
"$Id: route.c,v 1.5 1995/05/30 06:32:53 rgrimes Exp $";
"$Id: route.c,v 1.6 1995/07/12 19:21:36 bde Exp $";
#endif /* not lint */
#include <sys/param.h>
@ -52,6 +52,8 @@ static const char rcsid[] =
#undef KERNEL
#include <netinet/in.h>
#include <netipx/ipx.h>
#include <netns/ns.h>
#include <sys/sysctl.h>
@ -169,6 +171,9 @@ pr_family(af)
case AF_INET:
afname = "Internet";
break;
case AF_IPX:
afname = "IPX";
break;
case AF_NS:
afname = "XNS";
break;
@ -198,7 +203,6 @@ pr_family(af)
void
pr_rthdr()
{
if (Aflag)
printf("%-8.8s ","Address");
printf("%-*.*s %-*.*s %-6.6s %6.6s%8.8s %8.8s %6s\n",
@ -379,6 +383,16 @@ p_sockaddr(sa, flags, width)
break;
}
case AF_IPX:
{
struct ipx_addr work = ((struct sockaddr_ipx *)sa)->sipx_addr;
if (ipx_nullhost(satoipx_addr(work)))
cp = "default";
else
cp = ipx_print(sa);
break;
}
case AF_NS:
cp = ns_print(sa);
break;
@ -575,7 +589,8 @@ netname(in, mask)
net = i & mask;
while ((mask & 1) == 0)
mask >>= 1, net >>= 1;
np = getnetbyaddr(net, AF_INET);
if (!(np = getnetbyaddr(net, AF_INET)))
np = getnetbyaddr(i, AF_INET);
if (np)
cp = np->n_name;
}
@ -619,6 +634,101 @@ rt_stats(off)
printf("\t%u use%s of a wildcard route\n",
rtstat.rts_wildcard, plural(rtstat.rts_wildcard));
}
char *
ipx_print(sa)
register struct sockaddr *sa;
{
u_short port;
struct netent *np = 0;
struct hostent *hp = 0;
struct servent *sp = 0;
char *net = "", *host = "";
register char *p; register u_char *q;
struct ipx_addr work = ((struct sockaddr_ipx *)sa)->sipx_addr;
static char mybuf[50];
char cport[10], chost[15], cnet[15];
sp = getservbyport(work.x_port, "ipx");
port = ntohs(work.x_port);
if (ipx_nullnet(work) && ipx_nullhost(work)) {
if (port) {
if (sp) sprintf(mybuf, "*.%s", sp->s_name);
else sprintf(mybuf, "*.%x", port);
} else
sprintf(mybuf, "*.*");
return (mybuf);
}
if (np = getnetbyaddr(*(u_long *)&work.x_net, AF_IPX))
net = np->n_name;
else if (ipx_wildnet(work))
net = "any";
else if (ipx_nullnet(work))
net = "*";
else {
q = work.x_net.c_net;
sprintf(cnet, "%02x%02x%02x%02x",
q[0], q[1], q[2], q[3]);
for (p = cnet; *p == '0' && p < cnet + 8; p++)
continue;
net = p;
}
if (hp = gethostbyaddr((char *)&work.x_host, 6, AF_IPX))
host = hp->h_name;
else if (ipx_wildhost(work))
host = "any";
else if (ipx_nullhost(work))
host = "*";
else {
q = work.x_host.c_host;
sprintf(chost, "%02x%02x%02x%02x%02x%02x",
q[0], q[1], q[2], q[3], q[4], q[5]);
for (p = chost; *p == '0' && p < chost + 12; p++)
continue;
host = p;
}
if (port) {
if (strcmp(host, "*") == 0) host = "";
if (sp) sprintf(cport, "%s%s", *host ? "." : "", sp->s_name);
else sprintf(cport, "%s%x", *host ? "." : "", port);
} else
*cport = 0;
sprintf(mybuf,"%s.%s%s", net, host, cport);
return(mybuf);
}
char *
ipx_phost(sa)
struct sockaddr *sa;
{
register struct sockaddr_ipx *sipx = (struct sockaddr_ipx *)sa;
struct sockaddr_ipx work;
static union ipx_net ipx_zeronet;
char *p;
struct ipx_addr in;
struct hostent *hp;
work = *sipx;
in = work.sipx_addr;
hp = gethostbyaddr((char *)&in, sizeof(struct ipx_addr), AF_IPX);
if (hp) return (hp->h_name);
work.sipx_addr.x_port = 0;
work.sipx_addr.x_net = ipx_zeronet;
p = ipx_print((struct sockaddr *)&work);
if (strncmp("*.", p, 2) == 0) p += 2;
return(p);
}
short ns_nullh[] = {0,0,0};
short ns_bh[] = {-1,-1,-1};