diff options
Diffstat (limited to 'sys/netipx')
-rw-r--r-- | sys/netipx/README | 41 | ||||
-rw-r--r-- | sys/netipx/ipx.c | 457 | ||||
-rw-r--r-- | sys/netipx/ipx.h | 194 | ||||
-rw-r--r-- | sys/netipx/ipx_cksum.c | 140 | ||||
-rw-r--r-- | sys/netipx/ipx_if.h | 129 | ||||
-rw-r--r-- | sys/netipx/ipx_input.c | 469 | ||||
-rw-r--r-- | sys/netipx/ipx_outputfl.c | 288 | ||||
-rw-r--r-- | sys/netipx/ipx_pcb.c | 429 | ||||
-rw-r--r-- | sys/netipx/ipx_pcb.h | 150 | ||||
-rw-r--r-- | sys/netipx/ipx_proto.c | 159 | ||||
-rw-r--r-- | sys/netipx/ipx_usrreq.c | 687 | ||||
-rw-r--r-- | sys/netipx/ipx_var.h | 129 | ||||
-rw-r--r-- | sys/netipx/spx.h | 210 | ||||
-rw-r--r-- | sys/netipx/spx_debug.c | 196 | ||||
-rw-r--r-- | sys/netipx/spx_debug.h | 103 | ||||
-rw-r--r-- | sys/netipx/spx_reass.c | 451 | ||||
-rw-r--r-- | sys/netipx/spx_timer.h | 149 | ||||
-rw-r--r-- | sys/netipx/spx_usrreq.c | 1793 | ||||
-rw-r--r-- | sys/netipx/spx_var.h | 160 |
19 files changed, 0 insertions, 6334 deletions
diff --git a/sys/netipx/README b/sys/netipx/README deleted file mode 100644 index f324d9d..0000000 --- a/sys/netipx/README +++ /dev/null @@ -1,41 +0,0 @@ -$FreeBSD$ - -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 - -Adapted for multi-processor, multi-threaded network stack by Robert N. M. -Watson, Computer Laboratory, University of Cambridge. - ---- 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 -Modifications Copyright (c) 2004-2009 Robert N. M. Watson - -*/ - ---- TODO --- - -(1) netipx default socket buffer sizes are very small by contemporary - standards, and should be increased following testing and measurement. - -(2) SPX will free the PCB and socket buffer memory on close(), which means - close() in effects terminates the transfer of any outstanding buffered - but unsent data. As with TCP, it should instead grab its own - reference to the socket so that it is not released, as hold onto it - until the data transfer is complete. diff --git a/sys/netipx/ipx.c b/sys/netipx/ipx.c deleted file mode 100644 index 987a267..0000000 --- a/sys/netipx/ipx.c +++ /dev/null @@ -1,457 +0,0 @@ -/*- - * Copyright (c) 1984, 1985, 1986, 1987, 1993 - * The Regents of the University of California. - * Copyright (c) 2009 Robert N. M. Watson - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 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. - * - * Copyright (c) 1995, Mike Mitchell - * - * 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/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/param.h> -#include <sys/kernel.h> -#include <sys/systm.h> -#include <sys/lock.h> -#include <sys/malloc.h> -#include <sys/priv.h> -#include <sys/rwlock.h> -#include <sys/sockio.h> -#include <sys/socket.h> - -#include <net/if.h> -#include <net/if_var.h> -#include <net/route.h> - -#include <netipx/ipx.h> -#include <netipx/ipx_if.h> -#include <netipx/ipx_var.h> - -/* - * The IPX-layer address list is protected by ipx_ifaddr_rw. - */ -struct rwlock ipx_ifaddr_rw; -struct ipx_ifaddrhead ipx_ifaddrhead; - -static void ipx_ifscrub(struct ifnet *ifp, struct ipx_ifaddr *ia); -static int ipx_ifinit(struct ifnet *ifp, struct ipx_ifaddr *ia, - struct sockaddr_ipx *sipx, int scrub); - -/* - * Generic internet control operations (ioctl's). - */ -int -ipx_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp, - struct thread *td) -{ - struct ifreq *ifr = (struct ifreq *)data; - struct ipx_aliasreq *ifra = (struct ipx_aliasreq *)data; - struct ipx_ifaddr *ia; - struct ifaddr *ifa; - int dstIsNew, hostIsNew; - int error, priv; - - /* - * Find address for this interface, if it exists. - */ - if (ifp == NULL) - return (EADDRNOTAVAIL); - - IPX_IFADDR_RLOCK(); - TAILQ_FOREACH(ia, &ipx_ifaddrhead, ia_link) { - if (ia->ia_ifp == ifp) - break; - } - if (ia != NULL) - ifa_ref(&ia->ia_ifa); - IPX_IFADDR_RUNLOCK(); - - error = 0; - switch (cmd) { - case SIOCGIFADDR: - if (ia == NULL) { - error = EADDRNOTAVAIL; - goto out; - } - *(struct sockaddr_ipx *)&ifr->ifr_addr = ia->ia_addr; - goto out; - - case SIOCGIFBRDADDR: - if (ia == NULL) { - error = EADDRNOTAVAIL; - goto out; - } - if ((ifp->if_flags & IFF_BROADCAST) == 0) { - error = EINVAL; - goto out; - } - *(struct sockaddr_ipx *)&ifr->ifr_dstaddr = ia->ia_broadaddr; - goto out; - - case SIOCGIFDSTADDR: - if (ia == NULL) { - error = EADDRNOTAVAIL; - goto out; - } - if ((ifp->if_flags & IFF_POINTOPOINT) == 0) { - error = EINVAL; - goto out; - } - *(struct sockaddr_ipx *)&ifr->ifr_dstaddr = ia->ia_dstaddr; - goto out; - } - - switch (cmd) { - case SIOCAIFADDR: - case SIOCDIFADDR: - priv = (cmd == SIOCAIFADDR) ? PRIV_NET_ADDIFADDR : - PRIV_NET_DELIFADDR; - if (td && (error = priv_check(td, priv)) != 0) - goto out; - - IPX_IFADDR_RLOCK(); - if (ifra->ifra_addr.sipx_family == AF_IPX) { - struct ipx_ifaddr *oia; - - for (oia = ia; ia; ia = TAILQ_NEXT(ia, ia_link)) { - if (ia->ia_ifp == ifp && - ipx_neteq(ia->ia_addr.sipx_addr, - ifra->ifra_addr.sipx_addr)) - break; - } - if (oia != NULL && oia != ia) - ifa_free(&oia->ia_ifa); - if (ia != NULL && oia != ia) - ifa_ref(&ia->ia_ifa); - } - IPX_IFADDR_RUNLOCK(); - if (cmd == SIOCDIFADDR && ia == NULL) { - error = EADDRNOTAVAIL; - goto out; - } - /* FALLTHROUGH */ - - case SIOCSIFADDR: - case SIOCSIFDSTADDR: - if (td && (error = priv_check(td, PRIV_NET_SETLLADDR)) != 0) - goto out; - if (ia == NULL) { - ifa = ifa_alloc(sizeof(struct ipx_ifaddr), M_WAITOK); - ia = (struct ipx_ifaddr *)ifa; - ia->ia_ifp = ifp; - ifa->ifa_addr = (struct sockaddr *)&ia->ia_addr; - ifa->ifa_netmask = (struct sockaddr *)&ipx_netmask; - 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; - } - ifa_ref(&ia->ia_ifa); /* ipx_ifaddrhead */ - IPX_IFADDR_WLOCK(); - TAILQ_INSERT_TAIL(&ipx_ifaddrhead, ia, ia_link); - IPX_IFADDR_WUNLOCK(); - - ifa_ref(&ia->ia_ifa); /* if_addrhead */ - IF_ADDR_WLOCK(ifp); - TAILQ_INSERT_TAIL(&ifp->if_addrhead, ifa, ifa_link); - IF_ADDR_WUNLOCK(ifp); - } - break; - - default: - if (td && (error = priv_check(td, PRIV_NET_HWIOCTL)) != 0) - goto out; - } - - switch (cmd) { - case SIOCSIFDSTADDR: - if ((ifp->if_flags & IFF_POINTOPOINT) == 0) { - error = EINVAL; - goto out; - } - 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) - goto out; - } - *(struct sockaddr *)&ia->ia_dstaddr = ifr->ifr_dstaddr; - goto out; - - case SIOCSIFADDR: - error = ipx_ifinit(ifp, ia, - (struct sockaddr_ipx *)&ifr->ifr_addr, 1); - goto out; - - case SIOCDIFADDR: - ipx_ifscrub(ifp, ia); - ifa = (struct ifaddr *)ia; - - IF_ADDR_WLOCK(ifp); - TAILQ_REMOVE(&ifp->if_addrhead, ifa, ifa_link); - IF_ADDR_WUNLOCK(ifp); - ifa_free(ifa); /* if_addrhead */ - - IPX_IFADDR_WLOCK(); - TAILQ_REMOVE(&ipx_ifaddrhead, ia, ia_link); - IPX_IFADDR_WUNLOCK(); - ifa_free(&ia->ia_ifa); /* ipx_ifaddrhead */ - goto out; - - 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); - goto out; - - default: - if (ifp->if_ioctl == NULL) { - error = EOPNOTSUPP; - goto out; - } - error = ((*ifp->if_ioctl)(ifp, cmd, data)); - } - -out: - if (ia != NULL) - ifa_free(&ia->ia_ifa); - return (error); -} - -/* - * Delete any previous route for an old address. - */ -static void -ipx_ifscrub(struct ifnet *ifp, 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. - */ -static int -ipx_ifinit(struct ifnet *ifp, struct ipx_ifaddr *ia, - struct sockaddr_ipx *sipx, int scrub) -{ - struct sockaddr_ipx oldaddr; - 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". Use the MAC address - * of the interface. If it is an interface without a MAC address, - * like a serial line, the address must be supplied. - * - * Give the interface a chance to initialize if this is its first - * address, and to validate the address if necessary. - */ - if (ifp->if_ioctl != NULL && - (error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, (void *)ia))) { - ia->ia_addr = oldaddr; - splx(s); - return (error); - } - splx(s); - 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(struct ipx_addr *dst) -{ - struct ipx_ifaddr *ia; - struct ipx_addr *compare; - struct ifnet *ifp; - struct ipx_ifaddr *ia_maybe = NULL; - union ipx_net net = dst->x_net; - - IPX_IFADDR_LOCK_ASSERT(); - - TAILQ_FOREACH(ia, &ipx_ifaddrhead, ia_link) { - if ((ifp = ia->ia_ifp) != NULL) { - 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); -} - -void -ipx_printhost(struct ipx_addr *addr) -{ - u_short port; - struct ipx_addr work = *addr; - char *p; u_char *q; - 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; - snprintf(cnet, sizeof(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; - snprintf(chost, sizeof(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 = ""; - snprintf(cport, sizeof(cport), "%x", port); - } else - snprintf(cport, sizeof(cport), ".%x", port); - } else - *cport = 0; - - printf("%s.%s%s", net, host, cport); -} diff --git a/sys/netipx/ipx.h b/sys/netipx/ipx.h deleted file mode 100644 index 77022b2..0000000 --- a/sys/netipx/ipx.h +++ /dev/null @@ -1,194 +0,0 @@ -/*- - * 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. - * 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. - * - * Copyright (c) 1995, Mike Mitchell - * - * 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 - * - * $FreeBSD$ - */ - -#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_PXP 4 /* IPX Packet Exchange Protocol */ -#define IPXPROTO_SPX 5 /* SPX Sequenced Packet */ -#define IPXPROTO_NCP 17 /* NCP NetWare Core */ -#define IPXPROTO_NETBIOS 20 /* Propagated Packet */ -#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_NCP 0x0451 /* NW NCP Core Protocol */ -#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 */ -/* - * Ports < IPXPORT_RESERVED are reserved for privileged - */ -#define IPXPORT_RESERVED 0x4000 -/* - * Ports > IPXPORT_WELLKNOWN are reserved for privileged - * processes (e.g. root). - */ -#define IPXPORT_WELLKNOWN 0x6000 - -/* 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 /* No longer implemented. */ -#define SO_SEQNO 6 -#define SO_ALL_PACKETS 7 -#define SO_MTU 8 -#define SO_IPXTUN_ROUTE 9 -#define SO_IPX_CHECKSUM 10 - -/* - * 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 Internetwork Packet Exchange Protocol - */ -struct ipx { - u_short ipx_sum; /* Checksum */ - u_short ipx_len; /* Length, in bytes, including header */ - u_char ipx_tc; /* Transport Control (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 */ -} __packed; - -#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)) - -#include <sys/cdefs.h> - -__BEGIN_DECLS -struct ipx_addr ipx_addr(const char *); -char *ipx_ntoa(struct ipx_addr); -__END_DECLS - -#endif /* !_NETIPX_IPX_H_ */ diff --git a/sys/netipx/ipx_cksum.c b/sys/netipx/ipx_cksum.c deleted file mode 100644 index 6aa87fb..0000000 --- a/sys/netipx/ipx_cksum.c +++ /dev/null @@ -1,140 +0,0 @@ -/*- - * 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. - * 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. - * - * Copyright (c) 1995, Mike Mitchell - * - * 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/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/param.h> -#include <sys/mbuf.h> -#include <sys/libkern.h> - -#include <netipx/ipx.h> -#include <netipx/ipx_var.h> - - -#define SUMADV sum += *w++ - -u_short -ipx_cksum(struct mbuf *m, int len) -{ - u_int32_t sum = 0; - u_char *w; - u_char oldtc; - int mlen, words; - struct ipx *ipx; - union { - u_char b[2]; - u_short w; - } buf; - - ipx = mtod(m, struct ipx*); - oldtc = ipx->ipx_tc; - ipx->ipx_tc = 0; - w = (u_char *)&ipx->ipx_len; - len -= 2; - mlen = 2; - - for(;;) { - mlen = imin(m->m_len - mlen, len); - words = mlen / 2; - len -= mlen & ~1; - while (words >= 16) { - SUMADV; SUMADV; SUMADV; SUMADV; - SUMADV; SUMADV; SUMADV; SUMADV; - SUMADV; SUMADV; SUMADV; SUMADV; - SUMADV; SUMADV; SUMADV; SUMADV; - words -= 16; - } - while (words--) - SUMADV; - if (len == 0) - break; - mlen &= 1; - if (mlen) { - buf.b[0] = *w; - if (--len == 0) { - buf.b[1] = 0; - sum += buf.w; - break; - } - } - m = m->m_next; - if (m == NULL) - break; - w = mtod(m, u_char *); - if (mlen) { - buf.b[1] = *w; - sum += buf.w; - w++; - if (--len == 0) - break; - } - } - - ipx->ipx_tc = oldtc; - - sum = (sum & 0xffff) + (sum >> 16); - if (sum >= 0x10000) - sum++; - if (sum) - sum = ~sum; - return (sum); -} diff --git a/sys/netipx/ipx_if.h b/sys/netipx/ipx_if.h deleted file mode 100644 index 7725b4a..0000000 --- a/sys/netipx/ipx_if.h +++ /dev/null @@ -1,129 +0,0 @@ -/*- - * 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. - * 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. - - * Copyright (c) 1995, Mike Mitchell - * - * 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 - * - * $FreeBSD$ - */ - -#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. - */ -#ifdef _KERNEL -struct ipx_ifaddr { - struct ifaddr ia_ifa; /* protocol-independent info */ -#define ia_ifp ia_ifa.ifa_ifp -#define ia_flags ia_ifa.ifa_flags - TAILQ_ENTRY(ipx_ifaddr) ia_link; /* list of IPv6 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 */ -}; -#endif /* _KERNEL */ - -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 -}; - -/* - * List of ipx_ifaddr's. - */ -TAILQ_HEAD(ipx_ifaddrhead, ipx_ifaddr); - -/* - * 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_8022 0x00e0 /* Ethernet_802.2 */ -#define ETHERTYPE_IPX_8023 0x0000 /* Ethernet_802.3 */ -#define ETHERTYPE_IPX_II 0x8137 /* Ethernet_II */ -#define ETHERTYPE_IPX_SNAP 0x8137 /* Ethernet_SNAP */ - -#define ETHERTYPE_IPX 0x8137 /* Only Ethernet_II Available */ - -#ifdef _KERNEL -extern struct rwlock ipx_ifaddr_rw; -extern struct ipx_ifaddrhead ipx_ifaddrhead; - -#define IPX_IFADDR_LOCK_INIT() rw_init(&ipx_ifaddr_rw, "ipx_ifaddr_rw") -#define IPX_IFADDR_LOCK_ASSERT() rw_assert(&ipx_ifaddr_rw, RA_LOCKED) -#define IPX_IFADDR_RLOCK() rw_rlock(&ipx_ifaddr_rw) -#define IPX_IFADDR_RUNLOCK() rw_runlock(&ipx_ifaddr_rw) -#define IPX_IFADDR_WLOCK() rw_wlock(&ipx_ifaddr_rw) -#define IPX_IFADDR_WUNLOCK() rw_wunlock(&ipx_ifaddr_rw) -#define IPX_IFADDR_RLOCK_ASSERT() rw_assert(&ipx_ifaddr_rw, RA_WLOCKED) - -struct ipx_ifaddr *ipx_iaonnetof(struct ipx_addr *dst); -#endif - -#endif /* !_NETIPX_IPX_IF_H_ */ diff --git a/sys/netipx/ipx_input.c b/sys/netipx/ipx_input.c deleted file mode 100644 index 353e440..0000000 --- a/sys/netipx/ipx_input.c +++ /dev/null @@ -1,469 +0,0 @@ -/*- - * Copyright (c) 1984, 1985, 1986, 1987, 1993 - * The Regents of the University of California. - * Copyright (c) 2004-2009 Robert N. M. Watson - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 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. - * - * Copyright (c) 1995, Mike Mitchell - * 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/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/mbuf.h> -#include <sys/protosw.h> -#include <sys/socket.h> -#include <sys/kernel.h> -#include <sys/random.h> -#include <sys/lock.h> -#include <sys/rwlock.h> -#include <sys/sysctl.h> - -#include <net/if.h> -#include <net/if_var.h> -#include <net/route.h> -#include <net/netisr.h> - -#include <netipx/ipx.h> -#include <netipx/spx.h> -#include <netipx/ipx_if.h> -#include <netipx/ipx_pcb.h> -#include <netipx/ipx_var.h> - -int ipxcksum = 0; -SYSCTL_INT(_net_ipx_ipx, OID_AUTO, checksum, CTLFLAG_RW, - &ipxcksum, 0, "Compute ipx checksum"); - -static int ipxprintfs = 0; /* printing forwarding information */ -SYSCTL_INT(_net_ipx_ipx, OID_AUTO, ipxprintfs, CTLFLAG_RW, - &ipxprintfs, 0, "Printing forwarding information"); - -static int ipxforwarding = 0; -SYSCTL_INT(_net_ipx_ipx, OID_AUTO, ipxforwarding, CTLFLAG_RW, - &ipxforwarding, 0, "Enable ipx forwarding"); - -static int ipxnetbios = 0; -SYSCTL_INT(_net_ipx, OID_AUTO, ipxnetbios, CTLFLAG_RW, - &ipxnetbios, 0, "Propagate netbios over ipx"); - -static int ipx_do_route(struct ipx_addr *src, struct route *ro); -static void ipx_undo_route(struct route *ro); -static void ipx_forward(struct mbuf *m); -static void ipxintr(struct mbuf *m); - -const union ipx_net ipx_zeronet; - -const union ipx_net ipx_broadnet = { .s_net[0] = 0xffff, - .s_net[1] = 0xffff }; -const union ipx_host ipx_broadhost = { .s_host[0] = 0xffff, - .s_host[1] = 0xffff, - .s_host[2] = 0xffff }; - -struct ipxstat ipxstat; -struct sockaddr_ipx ipx_netmask, ipx_hostmask; - -/* - * IPX protocol control block (pcb) lists. - */ -struct mtx ipxpcb_list_mtx; -struct ipxpcbhead ipxpcb_list; -struct ipxpcbhead ipxrawpcb_list; - -static struct netisr_handler ipx_nh = { - .nh_name = "ipx", - .nh_handler = ipxintr, - .nh_proto = NETISR_IPX, - .nh_policy = NETISR_POLICY_SOURCE, -}; - -long ipx_pexseq; /* Locked with ipxpcb_list_mtx. */ - -/* - * IPX initialization. - */ - -void -ipx_init(void) -{ - - read_random(&ipx_pexseq, sizeof ipx_pexseq); - - LIST_INIT(&ipxpcb_list); - LIST_INIT(&ipxrawpcb_list); - TAILQ_INIT(&ipx_ifaddrhead); - - IPX_LIST_LOCK_INIT(); - IPX_IFADDR_LOCK_INIT(); - - 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; - - netisr_register(&ipx_nh); -} - -/* - * IPX input routine. Pass to next level. - */ -static void -ipxintr(struct mbuf *m) -{ - struct ipx *ipx; - struct ipxpcb *ipxp; - struct ipx_ifaddr *ia; - int len; - - /* - * If no IPX addresses have been set yet but the interfaces - * are receiving, can't do anything with incoming packets yet. - */ - if (TAILQ_EMPTY(&ipx_ifaddrhead)) { - m_freem(m); - return; - } - - ipxstat.ipxs_total++; - - if ((m->m_flags & M_EXT || m->m_len < sizeof(struct ipx)) && - (m = m_pullup(m, sizeof(struct ipx))) == NULL) { - ipxstat.ipxs_toosmall++; - return; - } - - /* - * Give any raw listeners a crack at the packet - */ - IPX_LIST_LOCK(); - LIST_FOREACH(ipxp, &ipxrawpcb_list, ipxp_list) { - struct mbuf *m1 = m_copy(m, 0, (int)M_COPYALL); - if (m1 != NULL) { - IPX_LOCK(ipxp); - ipx_input(m1, ipxp); - IPX_UNLOCK(ipxp); - } - } - IPX_LIST_UNLOCK(); - - ipx = mtod(m, struct ipx *); - len = ntohs(ipx->ipx_len); - /* - * 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++; - m_freem(m); - return; - } - 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 && ipx->ipx_sum != 0xffff) { - if (ipx->ipx_sum != ipx_cksum(m, len)) { - ipxstat.ipxs_badsum++; - m_freem(m); - return; - } - } - - /* - * Propagated (Netbios) packets (type 20) has to be handled - * different. :-( - */ - if (ipx->ipx_pt == IPXPROTO_NETBIOS) { - if (ipxnetbios) { - ipx_output_type20(m); - return; - } else { - m_freem(m); - return; - } - } - - /* - * 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)) ) { - /* - * If it is a broadcast to the net where it was - * received from, treat it as ours. - */ - IPX_IFADDR_RLOCK(); - TAILQ_FOREACH(ia, &ipx_ifaddrhead, ia_link) { - if ((ia->ia_ifa.ifa_ifp == m->m_pkthdr.rcvif) - && ipx_neteq(ia->ia_addr.sipx_addr, - ipx->ipx_dna)) { - IPX_IFADDR_RUNLOCK(); - goto ours; - } - } - IPX_IFADDR_RUNLOCK(); - - /* - * 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); - return; - } - } - /* - * Is this our packet? If not, forward. - */ - } else { - IPX_IFADDR_RLOCK(); - TAILQ_FOREACH(ia, &ipx_ifaddrhead, ia_link) { - if (ipx_hosteq(ipx->ipx_dna, ia->ia_addr.sipx_addr) && - (ipx_neteq(ipx->ipx_dna, ia->ia_addr.sipx_addr) || - ipx_neteqnn(ipx->ipx_dna.x_net, ipx_zeronet))) - break; - } - IPX_IFADDR_RUNLOCK(); - if (ia == NULL) { - ipx_forward(m); - return; - } - } -ours: - /* - * Locate pcb for datagram. - */ - IPX_LIST_LOCK(); - ipxp = ipx_pcblookup(&ipx->ipx_sna, ipx->ipx_dna.x_port, IPX_WILDCARD); - /* - * Switch out to protocol's input routine. - */ - if (ipxp != NULL) { - ipxstat.ipxs_delivered++; - if ((ipxp->ipxp_flags & IPXP_ALL_PACKETS) == 0) - switch (ipx->ipx_pt) { - case IPXPROTO_SPX: - IPX_LOCK(ipxp); - /* Will release both locks. */ - spx_input(m, ipxp); - return; - } - IPX_LOCK(ipxp); - ipx_input(m, ipxp); - IPX_UNLOCK(ipxp); - } else - m_freem(m); - IPX_LIST_UNLOCK(); -} - -void -ipx_ctlinput(cmd, arg_as_sa, dummy) - int cmd; - struct sockaddr *arg_as_sa; /* XXX should be swapped with dummy */ - void *dummy; -{ - - /* Currently, nothing. */ -} - -/* - * Forward a packet. If some error occurs drop the packet. IPX don't - * have a way to return errors to the sender. - */ - -static struct route ipx_droute; -static struct route ipx_sroute; - -static void -ipx_forward(struct mbuf *m) -{ - struct ipx *ipx = mtod(m, struct ipx *); - int error; - 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 */ - ipxstat.ipxs_cantforward++; - m_freem(m); - goto cleanup; - } - ipx->ipx_tc++; - if (ipx->ipx_tc > IPX_MAXHOPS) { - ipxstat.ipxs_cantforward++; - m_freem(m); - goto cleanup; - } - - if ((ok_there = ipx_do_route(&ipx->ipx_dna,&ipx_droute)) == 0) { - ipxstat.ipxs_noroute++; - m_freem(m); - goto cleanup; - } - /* - * 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; - struct ifnet *ifp; - - IPX_IFADDR_RLOCK(); - ia = ipx_iaonnetof(&ipx->ipx_dna); - if (ia != NULL) { - /* I'm gonna hafta eat this packet */ - agedelta += IPX_MAXHOPS - ipx->ipx_tc; - ipx->ipx_tc = IPX_MAXHOPS; - } - IPX_IFADDR_RUNLOCK(); - if ((ok_back = ipx_do_route(&ipx->ipx_sna,&ipx_sroute)) == 0) { - /* error = ENETUNREACH; He'll never get it! */ - ipxstat.ipxs_noroute++; - 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 { - ipxstat.ipxs_noroute++; - m_freem(m); - goto cleanup; - } - } - /* - * We don't need to recompute checksum because ipx_tc field - * is ignored by checksum calculation routine, however - * it may be desirable to reset checksum if ipxcksum == 0 - */ -#if 0 - if (!ipxcksum) - ipx->ipx_sum = 0xffff; -#endif - - error = ipx_outputfl(m, &ipx_droute, flags); - if (error == 0) { - ipxstat.ipxs_forward++; - - if (ipxprintfs) { - printf("forward: "); - ipx_printhost(&ipx->ipx_sna); - printf(" to "); - ipx_printhost(&ipx->ipx_dna); - printf(" hops %d\n", ipx->ipx_tc); - } - } -cleanup: - if (ok_there) - ipx_undo_route(&ipx_droute); - if (ok_back) - ipx_undo_route(&ipx_sroute); -} - -static int -ipx_do_route(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_ign(ro, 0); - if (ro->ro_rt == NULL || ro->ro_rt->rt_ifp == NULL) { - return (0); - } - counter_u64_add(ro->ro_rt->rt_pksent, 1); - return (1); -} - -static void -ipx_undo_route(struct route *ro) -{ - - if (ro->ro_rt != NULL) { - RTFREE(ro->ro_rt); - } -} diff --git a/sys/netipx/ipx_outputfl.c b/sys/netipx/ipx_outputfl.c deleted file mode 100644 index e92542e..0000000 --- a/sys/netipx/ipx_outputfl.c +++ /dev/null @@ -1,288 +0,0 @@ -/*- - * 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. - * 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. - * - * Copyright (c) 1995, Mike Mitchell - * - * 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/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/mbuf.h> -#include <sys/socket.h> - -#include <net/if.h> -#include <net/if_var.h> -#include <net/route.h> - -#include <netipx/ipx.h> -#include <netipx/ipx_if.h> -#include <netipx/ipx_var.h> - -int -ipx_outputfl(struct mbuf *m0, struct route *ro, int flags) -{ - struct ipx *ipx = mtod(m0, struct ipx *); - struct ifnet *ifp = NULL; - int error = 0; - struct sockaddr_ipx *dst; - struct route ipxroute; - - /* - * Route packet. - */ - if (ro == NULL) { - ro = &ipxroute; - bzero((caddr_t)ro, sizeof(*ro)); - } - dst = (struct sockaddr_ipx *)&ro->ro_dst; - if (ro->ro_rt == NULL) { - 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_IFADDR_RLOCK(); - ia = ipx_iaonnetof(&ipx->ipx_dna); - if (ia == NULL) { - IPX_IFADDR_RUNLOCK(); - ipxstat.ipxs_noroute++; - error = ENETUNREACH; - goto bad; - } - ifp = ia->ia_ifp; - IPX_IFADDR_RUNLOCK(); - goto gotif; - } - rtalloc_ign(ro, 0); - } 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_ign(ro, 0); - } - if (ro->ro_rt == NULL || (ifp = ro->ro_rt->rt_ifp) == NULL) { - ipxstat.ipxs_noroute++; - error = ENETUNREACH; - goto bad; - } - counter_u64_add(ro->ro_rt->rt_pksent, 1); - 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 | IFF_LOOPBACK)) == 0) { - error = EADDRNOTAVAIL; - goto bad; - } - if ((flags & IPX_ALLOWBROADCAST) == 0) { - error = EACCES; - goto bad; - } - m0->m_flags |= M_BCAST; - } - - if (htons(ipx->ipx_len) <= ifp->if_mtu) { - ipxstat.ipxs_localout++; - error = (*ifp->if_output)(ifp, m0, - (struct sockaddr *)dst, ro); - goto done; - } else { - ipxstat.ipxs_mtutoosmall++; - error = EMSGSIZE; - } -bad: - m_freem(m0); -done: - if (ro == &ipxroute && (flags & IPX_ROUTETOIF) == 0 && - ro->ro_rt != NULL) { - RTFREE(ro->ro_rt); - ro->ro_rt = NULL; - } - return (error); -} - -/* - * This will broadcast the type 20 (Netbios) packet to all the interfaces - * that have ipx configured and isn't in the list yet. - */ -int -ipx_output_type20(struct mbuf *m) -{ - struct ipx *ipx; - union ipx_net *nbnet; - struct ipx_ifaddr *ia, *tia; - int error = 0; - struct mbuf *m1; - int i; - struct ifnet *ifp; - struct sockaddr_ipx dst; - - /* - * We have to get to the 32 bytes after the ipx header also, so - * that we can fill in the network address of the receiving - * interface. - */ - if ((m->m_flags & M_EXT || m->m_len < (sizeof(struct ipx) + 32)) && - (m = m_pullup(m, sizeof(struct ipx) + 32)) == NULL) { - ipxstat.ipxs_toosmall++; - return (0); - } - ipx = mtod(m, struct ipx *); - nbnet = (union ipx_net *)(ipx + 1); - - if (ipx->ipx_tc >= 8) - goto bad; - /* - * Now see if we have already seen this. - */ - tia = NULL; - IPX_IFADDR_RLOCK(); - TAILQ_FOREACH(ia, &ipx_ifaddrhead, ia_link) { - if (ia->ia_ifa.ifa_ifp == m->m_pkthdr.rcvif) { - if (tia == NULL) - tia = ia; - for (i=0; i < ipx->ipx_tc; i++, nbnet++) { - if (ipx_neteqnn(ia->ia_addr.sipx_addr.x_net, - *nbnet)) { - IPX_IFADDR_RUNLOCK(); - goto bad; - } - } - } - } - - /* - * Don't route the packet if the interface where it come from - * does not have an IPX address. - */ - if (tia == NULL) { - IPX_IFADDR_RUNLOCK(); - goto bad; - } - - /* - * Add our receiving interface to the list. - */ - nbnet = (union ipx_net *)(ipx + 1); - nbnet += ipx->ipx_tc; - *nbnet = tia->ia_addr.sipx_addr.x_net; - - /* - * Increment the hop count. - */ - ipx->ipx_tc++; - ipxstat.ipxs_forward++; - - /* - * Send to all directly connected ifaces not in list and - * not to the one it came from. - */ - m->m_flags &= ~M_BCAST; - bzero(&dst, sizeof(dst)); - dst.sipx_family = AF_IPX; - dst.sipx_len = 12; - dst.sipx_addr.x_host = ipx_broadhost; - - TAILQ_FOREACH(ia, &ipx_ifaddrhead, ia_link) { - if (ia->ia_ifa.ifa_ifp != m->m_pkthdr.rcvif) { - nbnet = (union ipx_net *)(ipx + 1); - for (i=0; i < ipx->ipx_tc; i++, nbnet++) - if (ipx_neteqnn(ia->ia_addr.sipx_addr.x_net, - *nbnet)) - goto skip_this; - - /* - * Insert the net address of the dest net and - * calculate the new checksum if needed. - */ - ifp = ia->ia_ifa.ifa_ifp; - dst.sipx_addr.x_net = ia->ia_addr.sipx_addr.x_net; - ipx->ipx_dna.x_net = dst.sipx_addr.x_net; - if(ipx->ipx_sum != 0xffff) - ipx->ipx_sum = ipx_cksum(m, ntohs(ipx->ipx_len)); - - m1 = m_copym(m, 0, M_COPYALL, M_NOWAIT); - if(m1) { - error = (*ifp->if_output)(ifp, m1, - (struct sockaddr *)&dst, NULL); - /* XXX ipxstat.ipxs_localout++; */ - } -skip_this: ; - } - } - IPX_IFADDR_RUNLOCK(); - -bad: - m_freem(m); - return (error); -} diff --git a/sys/netipx/ipx_pcb.c b/sys/netipx/ipx_pcb.c deleted file mode 100644 index 61510bb..0000000 --- a/sys/netipx/ipx_pcb.c +++ /dev/null @@ -1,429 +0,0 @@ -/*- - * Copyright (c) 1984, 1985, 1986, 1987, 1993 - * The Regents of the University of California. - * Copyright (c) 2004-2009 Robert N. M. Watson - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 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. - * - * Copyright (c) 1995, Mike Mitchell - * 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/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/malloc.h> -#include <sys/priv.h> -#include <sys/socket.h> -#include <sys/socketvar.h> - -#include <net/if.h> -#include <net/if_var.h> -#include <net/route.h> - -#include <netipx/ipx.h> -#include <netipx/ipx_if.h> -#include <netipx/ipx_pcb.h> -#include <netipx/ipx_var.h> - -static struct ipx_addr zeroipx_addr; -static u_short ipxpcb_lport_cache; - -int -ipx_pcballoc(struct socket *so, struct ipxpcbhead *head, struct thread *td) -{ - struct ipxpcb *ipxp; - - KASSERT(so->so_pcb == NULL, ("ipx_pcballoc: so_pcb != NULL")); - IPX_LIST_LOCK_ASSERT(); - - ipxp = malloc(sizeof *ipxp, M_PCB, M_NOWAIT | M_ZERO); - if (ipxp == NULL) - return (ENOBUFS); - IPX_LOCK_INIT(ipxp); - ipxp->ipxp_socket = so; - if (ipxcksum) - ipxp->ipxp_flags |= IPXP_CHECKSUM; - LIST_INSERT_HEAD(head, ipxp, ipxp_list); - so->so_pcb = (caddr_t)ipxp; - return (0); -} - -int -ipx_pcbbind(struct ipxpcb *ipxp, struct sockaddr *nam, struct thread *td) -{ - struct sockaddr_ipx *sipx; - u_short lport = 0; - - IPX_LIST_LOCK_ASSERT(); - IPX_LOCK_ASSERT(ipxp); - - if (ipxp->ipxp_lport || !ipx_nullhost(ipxp->ipxp_laddr)) - return (EINVAL); - if (nam == NULL) - goto noname; - sipx = (struct sockaddr_ipx *)nam; - if (!ipx_nullhost(sipx->sipx_addr)) { - int tport = sipx->sipx_port; - - sipx->sipx_port = 0; /* yech... */ - if (ifa_ifwithaddr_check((struct sockaddr *)sipx) == 0) - return (EADDRNOTAVAIL); - sipx->sipx_port = tport; - } - lport = sipx->sipx_port; - if (lport) { - u_short aport = ntohs(lport); - - if (aport < IPXPORT_RESERVED && td != NULL && - priv_check(td, PRIV_NETIPX_RESERVEDPORT)) - return (EACCES); - if (ipx_pcblookup(&zeroipx_addr, lport, 0)) - return (EADDRINUSE); - } - ipxp->ipxp_laddr = sipx->sipx_addr; -noname: - if (lport == 0) - do { - ipxpcb_lport_cache++; - if ((ipxpcb_lport_cache < IPXPORT_RESERVED) || - (ipxpcb_lport_cache >= IPXPORT_WELLKNOWN)) - ipxpcb_lport_cache = IPXPORT_RESERVED; - lport = htons(ipxpcb_lport_cache); - } 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(struct ipxpcb *ipxp, struct sockaddr *nam, struct thread *td) -{ - struct sockaddr_ipx *sipx = (struct sockaddr_ipx *)nam; - struct ipx_addr *dst; - struct route *ro; - struct ifnet *ifp; - - IPX_LIST_LOCK_ASSERT(); - IPX_LOCK_ASSERT(ipxp); - - 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 != NULL && !(ro->ro_rt->rt_flags & RTF_HOST)) { - /* can patch route to avoid rtalloc */ - *dst = sipx->sipx_addr; - } else { - flush: - if (ro->ro_rt != NULL) - RTFREE(ro->ro_rt); - ro->ro_rt = NULL; - } - }/* 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 == NULL || ro->ro_rt->rt_ifp == NULL)) { - /* 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_ign(ro, 0); - } - if (ipx_neteqnn(ipxp->ipxp_laddr.x_net, ipx_zeronet)) { - struct ipx_ifaddr *ia = NULL; - - /* - * If route is known or can be allocated now, - * our src addr is taken from the i/f, else punt. - */ - - /* - * If we found a route, use the address - * corresponding to the outgoing interface - */ - if (ro->ro_rt != NULL && (ifp = ro->ro_rt->rt_ifp) != NULL) { - IPX_IFADDR_RLOCK(); - TAILQ_FOREACH(ia, &ipx_ifaddrhead, ia_link) { - if (ia->ia_ifp == ifp) { - ifa_ref(&ia->ia_ifa); - break; - } - } - IPX_IFADDR_RUNLOCK(); - } - if (ia == NULL) { - 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 == NULL) { - IPX_IFADDR_RLOCK(); - ia = ipx_iaonnetof(&sipx->sipx_addr); - if (ia != NULL) - ifa_ref(&ia->ia_ifa); - IPX_IFADDR_RUNLOCK(); - } - if (ia == NULL) { - IPX_IFADDR_RLOCK(); - ia = TAILQ_FIRST(&ipx_ifaddrhead); - if (ia != NULL) - ifa_ref(&ia->ia_ifa); - IPX_IFADDR_RUNLOCK(); - } - if (ia == NULL) - return (EADDRNOTAVAIL); - } - ipxp->ipxp_laddr.x_net = satoipx_addr(ia->ia_addr).x_net; - ifa_free(&ia->ia_ifa); - } - if (ipx_nullhost(ipxp->ipxp_laddr)) { - struct ipx_ifaddr *ia = NULL; - /* - * If route is known or can be allocated now, - * our src addr is taken from the i/f, else punt. - */ - - /* - * If we found a route, use the address - * corresponding to the outgoing interface - */ - if (ro->ro_rt != NULL && (ifp = ro->ro_rt->rt_ifp) != NULL) { - IPX_IFADDR_RLOCK(); - TAILQ_FOREACH(ia, &ipx_ifaddrhead, ia_link) { - if (ia->ia_ifp == ifp) { - ifa_ref(&ia->ia_ifa); - break; - } - } - IPX_IFADDR_RUNLOCK(); - } - if (ia == NULL) { - 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 == NULL) { - IPX_IFADDR_RLOCK(); - ia = ipx_iaonnetof(&sipx->sipx_addr); - if (ia != NULL) - ifa_ref(&ia->ia_ifa); - IPX_IFADDR_RUNLOCK(); - } - if (ia == NULL) { - IPX_IFADDR_RLOCK(); - ia = TAILQ_FIRST(&ipx_ifaddrhead); - if (ia != NULL) - ifa_ref(&ia->ia_ifa); - IPX_IFADDR_RUNLOCK(); - } - if (ia == NULL) - return (EADDRNOTAVAIL); - } - ipxp->ipxp_laddr.x_host = satoipx_addr(ia->ia_addr).x_host; - ifa_free(&ia->ia_ifa); - } - if (ipx_pcblookup(&sipx->sipx_addr, ipxp->ipxp_lport, 0)) - return (EADDRINUSE); - if (ipxp->ipxp_lport == 0) - ipx_pcbbind(ipxp, (struct sockaddr *)NULL, td); - - /* XXX just leave it zero if we can't find a route */ - - ipxp->ipxp_faddr = sipx->sipx_addr; - /* Includes ipxp->ipxp_fport = sipx->sipx_port; */ - return (0); -} - -void -ipx_pcbdisconnect(struct ipxpcb *ipxp) -{ - - IPX_LIST_LOCK_ASSERT(); - IPX_LOCK_ASSERT(ipxp); - - ipxp->ipxp_faddr = zeroipx_addr; -} - -void -ipx_pcbdetach(struct ipxpcb *ipxp) -{ - struct socket *so = ipxp->ipxp_socket; - - IPX_LIST_LOCK_ASSERT(); - IPX_LOCK_ASSERT(ipxp); - - so->so_pcb = NULL; - ipxp->ipxp_socket = NULL; -} - -void -ipx_pcbfree(struct ipxpcb *ipxp) -{ - - KASSERT(ipxp->ipxp_socket == NULL, - ("ipx_pcbfree: ipxp_socket != NULL")); - IPX_LIST_LOCK_ASSERT(); - IPX_LOCK_ASSERT(ipxp); - - if (ipxp->ipxp_route.ro_rt != NULL) - RTFREE(ipxp->ipxp_route.ro_rt); - LIST_REMOVE(ipxp, ipxp_list); - IPX_LOCK_DESTROY(ipxp); - free(ipxp, M_PCB); -} - -void -ipx_getsockaddr(struct ipxpcb *ipxp, struct sockaddr **nam) -{ - struct sockaddr_ipx *sipx, ssipx; - - sipx = &ssipx; - bzero((caddr_t)sipx, sizeof(*sipx)); - sipx->sipx_len = sizeof(*sipx); - sipx->sipx_family = AF_IPX; - IPX_LOCK(ipxp); - sipx->sipx_addr = ipxp->ipxp_laddr; - IPX_UNLOCK(ipxp); - *nam = sodupsockaddr((struct sockaddr *)sipx, M_WAITOK); -} - -void -ipx_getpeeraddr(struct ipxpcb *ipxp, struct sockaddr **nam) -{ - struct sockaddr_ipx *sipx, ssipx; - - sipx = &ssipx; - bzero(sipx, sizeof(*sipx)); - sipx->sipx_len = sizeof(*sipx); - sipx->sipx_family = AF_IPX; - IPX_LOCK(ipxp); - sipx->sipx_addr = ipxp->ipxp_faddr; - IPX_UNLOCK(ipxp); - *nam = sodupsockaddr((struct sockaddr *)sipx, M_WAITOK); -} - -struct ipxpcb * -ipx_pcblookup(struct ipx_addr *faddr, u_short lport, int wildp) -{ - struct ipxpcb *ipxp, *match = NULL; - int matchwild = 3, wildcard; - u_short fport; - - IPX_LIST_LOCK_ASSERT(); - - fport = faddr->x_port; - LIST_FOREACH(ipxp, &ipxpcb_list, ipxp_list) { - 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); -} diff --git a/sys/netipx/ipx_pcb.h b/sys/netipx/ipx_pcb.h deleted file mode 100644 index 4ef6011..0000000 --- a/sys/netipx/ipx_pcb.h +++ /dev/null @@ -1,150 +0,0 @@ -/*- - * Copyright (c) 1984, 1985, 1986, 1987, 1993 - * The Regents of the University of California. - * Copyright (c) 2004-2006 Robert N. M. Watson - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 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. - * - * Copyright (c) 1995, Mike Mitchell - * 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 - * - * $FreeBSD$ - */ - -#ifndef _NETIPX_IPX_PCB_H_ -#define _NETIPX_IPX_PCB_H_ - -/* - * IPX protocol interface control block. - */ -struct ipxpcb { - LIST_ENTRY(ipxpcb) ipxp_list; - 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*/ - short ipxp_flags; - u_char ipxp_dpt; /* default packet type for ipx_output */ - u_char ipxp_rpt; /* last received packet type by ipx_input() */ - struct mtx ipxp_mtx; -}; - -/* - * Additional IPX pcb-related types and variables. - */ -LIST_HEAD(ipxpcbhead, ipxpcb); -extern struct ipxpcbhead ipxpcb_list; -extern struct ipxpcbhead ipxrawpcb_list; - -#ifdef _KERNEL -extern struct mtx ipxpcb_list_mtx; -#endif - -/* - * IPX/SPX PCB 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 IPXP_CHECKSUM 0x10 /* Use checksum on this socket. */ -#define IPXP_DROPPED 0x20 /* Connection dropped. */ -#define IPXP_SPX 0x40 /* SPX PCB. */ - -#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 an IPX socket. - */ -#define IPXSNDQ 16384 -#define IPXRCVQ 40960 - -#ifdef _KERNEL -int ipx_pcballoc(struct socket *so, struct ipxpcbhead *head, - struct thread *p); -int ipx_pcbbind(struct ipxpcb *ipxp, struct sockaddr *nam, - struct thread *p); -int ipx_pcbconnect(struct ipxpcb *ipxp, struct sockaddr *nam, - struct thread *p); -void ipx_pcbdetach(struct ipxpcb *ipxp); -void ipx_pcbdisconnect(struct ipxpcb *ipxp); -void ipx_pcbfree(struct ipxpcb *ipxp); -struct ipxpcb *ipx_pcblookup(struct ipx_addr *faddr, u_short lport, int wildp); -void ipx_getpeeraddr(struct ipxpcb *ipxp, struct sockaddr **nam); -void ipx_getsockaddr(struct ipxpcb *ipxp, struct sockaddr **nam); - -#define IPX_LIST_LOCK_INIT() mtx_init(&ipxpcb_list_mtx, "ipx_list_mtx", \ - NULL, MTX_DEF | MTX_RECURSE) -#define IPX_LIST_LOCK() mtx_lock(&ipxpcb_list_mtx) -#define IPX_LIST_UNLOCK() mtx_unlock(&ipxpcb_list_mtx) -#define IPX_LIST_LOCK_ASSERT() mtx_assert(&ipxpcb_list_mtx, MA_OWNED) - -#define IPX_LOCK_INIT(ipx) mtx_init(&(ipx)->ipxp_mtx, "ipx_mtx", NULL, \ - MTX_DEF) -#define IPX_LOCK_DESTROY(ipx) mtx_destroy(&(ipx)->ipxp_mtx) -#define IPX_LOCK(ipx) mtx_lock(&(ipx)->ipxp_mtx) -#define IPX_UNLOCK(ipx) mtx_unlock(&(ipx)->ipxp_mtx) -#define IPX_LOCK_ASSERT(ipx) mtx_assert(&(ipx)->ipxp_mtx, MA_OWNED) -#endif /* _KERNEL */ - -#endif /* !_NETIPX_IPX_PCB_H_ */ diff --git a/sys/netipx/ipx_proto.c b/sys/netipx/ipx_proto.c deleted file mode 100644 index 36215da..0000000 --- a/sys/netipx/ipx_proto.c +++ /dev/null @@ -1,159 +0,0 @@ -/*- - * 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. - * 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. - * - * Copyright (c) 1995, Mike Mitchell - * - * 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/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include "opt_ipx.h" - -#include <sys/param.h> -#include <sys/socket.h> -#include <sys/protosw.h> -#include <sys/domain.h> -#include <sys/kernel.h> -#include <sys/queue.h> -#include <sys/sysctl.h> - -#include <net/radix.h> - -#include <netipx/ipx.h> -#include <netipx/ipx_var.h> -#include <netipx/spx.h> - -static struct pr_usrreqs nousrreqs; - -/* - * IPX protocol family: IPX, ERR, PXP, SPX, ROUTE. - */ - -static struct domain ipxdomain; - -static struct protosw ipxsw[] = { -{ - .pr_domain = &ipxdomain, - .pr_init = ipx_init, - .pr_usrreqs = &nousrreqs -}, -{ - .pr_type = SOCK_DGRAM, - .pr_domain = &ipxdomain, - .pr_flags = PR_ATOMIC|PR_ADDR, - .pr_ctlinput = ipx_ctlinput, - .pr_ctloutput = ipx_ctloutput, - .pr_usrreqs = &ipx_usrreqs -}, -{ - .pr_type = SOCK_STREAM, - .pr_domain = &ipxdomain, - .pr_protocol = IPXPROTO_SPX, - .pr_flags = PR_CONNREQUIRED|PR_WANTRCVD, - .pr_ctlinput = spx_ctlinput, - .pr_ctloutput = spx_ctloutput, - .pr_init = spx_init, - .pr_fasttimo = spx_fasttimo, - .pr_slowtimo = spx_slowtimo, - .pr_usrreqs = &spx_usrreqs -}, -{ - .pr_type = SOCK_SEQPACKET, - .pr_domain = &ipxdomain, - .pr_protocol = IPXPROTO_SPX, - .pr_flags = PR_CONNREQUIRED|PR_WANTRCVD|PR_ATOMIC, - .pr_ctlinput = spx_ctlinput, - .pr_ctloutput = spx_ctloutput, - .pr_usrreqs = &spx_usrreq_sps -}, -{ - .pr_type = SOCK_RAW, - .pr_domain = &ipxdomain, - .pr_protocol = IPXPROTO_RAW, - .pr_flags = PR_ATOMIC|PR_ADDR, - .pr_ctloutput = ipx_ctloutput, - .pr_usrreqs = &ripx_usrreqs -}, -}; - -extern int ipx_inithead(void **, int); - -static struct domain ipxdomain = { - .dom_family = AF_IPX, - .dom_name = "network systems", - .dom_protosw = ipxsw, - .dom_protoswNPROTOSW = &ipxsw[sizeof(ipxsw)/sizeof(ipxsw[0])], - .dom_rtattach = ipx_inithead, - .dom_rtoffset = 16, - .dom_maxrtkey = sizeof(struct sockaddr_ipx) -}; - - -/* shim to adapt arguments */ -int -ipx_inithead(void **head, int offset) -{ - return rn_inithead(head, offset); -} - -DOMAIN_SET(ipx); -SYSCTL_NODE(_net, PF_IPX, ipx, CTLFLAG_RW, 0, - "IPX/SPX"); - -SYSCTL_NODE(_net_ipx, IPXPROTO_RAW, ipx, CTLFLAG_RW, 0, "IPX"); -static SYSCTL_NODE(_net_ipx, IPXPROTO_SPX, spx, CTLFLAG_RW, 0, "SPX"); diff --git a/sys/netipx/ipx_usrreq.c b/sys/netipx/ipx_usrreq.c deleted file mode 100644 index f2f96eb..0000000 --- a/sys/netipx/ipx_usrreq.c +++ /dev/null @@ -1,687 +0,0 @@ -/*- - * Copyright (c) 1984, 1985, 1986, 1987, 1993 - * The Regents of the University of California. - * Copyright (c) 2004-2006 Robert N. M. Watson - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 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. - * - * Copyright (c) 1995, Mike Mitchell - * 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/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include "opt_ipx.h" - -#include <sys/param.h> -#include <sys/kernel.h> -#include <sys/lock.h> -#include <sys/mbuf.h> -#include <sys/priv.h> -#include <sys/protosw.h> -#include <sys/signalvar.h> -#include <sys/socket.h> -#include <sys/socketvar.h> -#include <sys/sx.h> -#include <sys/sysctl.h> -#include <sys/systm.h> - -#include <net/if.h> -#include <net/if_var.h> -#include <net/route.h> - -#include <netinet/in.h> - -#include <netipx/ipx.h> -#include <netipx/ipx_if.h> -#include <netipx/ipx_pcb.h> -#include <netipx/ipx_var.h> - -#include <security/mac/mac_framework.h> - -/* - * IPX protocol implementation. - */ - -static int ipxsendspace = IPXSNDQ; -SYSCTL_INT(_net_ipx_ipx, OID_AUTO, ipxsendspace, CTLFLAG_RW, - &ipxsendspace, 0, "Send buffer space"); -static int ipxrecvspace = IPXRCVQ; -SYSCTL_INT(_net_ipx_ipx, OID_AUTO, ipxrecvspace, CTLFLAG_RW, - &ipxrecvspace, 0, "Receive buffer space"); - -static void ipx_usr_abort(struct socket *so); -static int ipx_attach(struct socket *so, int proto, struct thread *td); -static int ipx_bind(struct socket *so, struct sockaddr *nam, struct thread *td); -static int ipx_connect(struct socket *so, struct sockaddr *nam, - struct thread *td); -static void ipx_detach(struct socket *so); -static int ipx_disconnect(struct socket *so); -static int ipx_send(struct socket *so, int flags, struct mbuf *m, - struct sockaddr *addr, struct mbuf *control, - struct thread *td); -static int ipx_shutdown(struct socket *so); -static int ripx_attach(struct socket *so, int proto, struct thread *td); -static int ipx_output(struct ipxpcb *ipxp, struct mbuf *m0); -static void ipx_usr_close(struct socket *so); - -struct pr_usrreqs ipx_usrreqs = { - .pru_abort = ipx_usr_abort, - .pru_attach = ipx_attach, - .pru_bind = ipx_bind, - .pru_connect = ipx_connect, - .pru_control = ipx_control, - .pru_detach = ipx_detach, - .pru_disconnect = ipx_disconnect, - .pru_peeraddr = ipx_peeraddr, - .pru_send = ipx_send, - .pru_shutdown = ipx_shutdown, - .pru_sockaddr = ipx_sockaddr, - .pru_close = ipx_usr_close, -}; - -struct pr_usrreqs ripx_usrreqs = { - .pru_abort = ipx_usr_abort, - .pru_attach = ripx_attach, - .pru_bind = ipx_bind, - .pru_connect = ipx_connect, - .pru_control = ipx_control, - .pru_detach = ipx_detach, - .pru_disconnect = ipx_disconnect, - .pru_peeraddr = ipx_peeraddr, - .pru_send = ipx_send, - .pru_shutdown = ipx_shutdown, - .pru_sockaddr = ipx_sockaddr, - .pru_close = ipx_usr_close, -}; - -/* - * This may also be called for raw listeners. - */ -void -ipx_input(struct mbuf *m, struct ipxpcb *ipxp) -{ - struct ipx *ipx = mtod(m, struct ipx *); - struct ifnet *ifp = m->m_pkthdr.rcvif; - struct sockaddr_ipx ipx_ipx; - - KASSERT(ipxp != NULL, ("ipx_input: NULL ipxpcb")); - IPX_LOCK_ASSERT(ipxp); - /* - * Construct sockaddr format source address. - * Stuff source address and datagram in user buffer. - */ - ipx_ipx.sipx_len = sizeof(ipx_ipx); - ipx_ipx.sipx_family = AF_IPX; - ipx_ipx.sipx_addr = ipx->ipx_sna; - ipx_ipx.sipx_zero[0] = '\0'; - ipx_ipx.sipx_zero[1] = '\0'; - if (ipx_neteqnn(ipx->ipx_sna.x_net, ipx_zeronet) && ifp != NULL) { - struct ifaddr *ifa; - - for (ifa = TAILQ_FIRST(&ifp->if_addrhead); ifa != NULL; - ifa = TAILQ_NEXT(ifa, ifa_link)) { - 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) == 0) { - m->m_len -= sizeof(struct ipx); - m->m_pkthdr.len -= sizeof(struct ipx); - m->m_data += sizeof(struct ipx); - } -#ifdef MAC - if (mac_socket_check_deliver(ipxp->ipxp_socket, m) != 0) { - m_freem(m); - return; - } -#endif - if (sbappendaddr(&ipxp->ipxp_socket->so_rcv, - (struct sockaddr *)&ipx_ipx, m, NULL) == 0) - m_freem(m); - else - sorwakeup(ipxp->ipxp_socket); -} - -/* - * Drop connection, reporting - * the specified error. - */ -void -ipx_drop(struct ipxpcb *ipxp, int errno) -{ - struct socket *so = ipxp->ipxp_socket; - - IPX_LIST_LOCK_ASSERT(); - IPX_LOCK_ASSERT(ipxp); - - /* - * someday, in the IPX world - * we will generate error protocol packets - * announcing that the socket has gone away. - * - * XXX Probably never. IPX does not have error packets. - */ - /*if (TCPS_HAVERCVDSYN(tp->t_state)) { - tp->t_state = TCPS_CLOSED; - tcp_output(tp); - }*/ - so->so_error = errno; - ipx_pcbdisconnect(ipxp); - soisdisconnected(so); -} - -static int -ipx_output(struct ipxpcb *ipxp, struct mbuf *m0) -{ - struct ipx *ipx; - struct socket *so; - int len = 0; - struct route *ro; - struct mbuf *m; - struct mbuf *mprev = NULL; - - IPX_LOCK_ASSERT(ipxp); - - /* - * Calculate data length. - */ - for (m = m0; m != NULL; 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])) { - mtod(m, char*)[m->m_len++] = 0; - } else { - struct mbuf *m1 = m_get(M_NOWAIT, MT_DATA); - - if (m1 == NULL) { - 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_NOWAIT); - if (m == NULL) - 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 (ipxp->ipxp_flags & IPXP_CHECKSUM) { - 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 *)NULL, - (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 != NULL) { - 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) { - 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 = NULL; - } - } - ipxp->ipxp_lastdst = ipx->ipx_dna; -#endif /* ancient_history */ - return (ipx_outputfl(m, ro, so->so_options & SO_BROADCAST)); -} - -int -ipx_ctloutput(struct socket *so, struct sockopt *sopt) -{ - struct ipxpcb *ipxp = sotoipxpcb(so); - int mask, error, optval; - short soptval; - struct ipx ioptval; - long seq; - - KASSERT(ipxp != NULL, ("ipx_ctloutput: ipxp == NULL")); - error = 0; - - switch (sopt->sopt_dir) { - case SOPT_GET: - switch (sopt->sopt_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_IPX_CHECKSUM: - mask = IPXP_CHECKSUM; - goto get_flags; - - case SO_HEADERS_ON_OUTPUT: - mask = IPXP_RAWOUT; - get_flags: - /* Unlocked read. */ - soptval = ipxp->ipxp_flags & mask; - error = sooptcopyout(sopt, &soptval, sizeof soptval); - break; - - case SO_DEFAULT_HEADERS: - ioptval.ipx_len = 0; - ioptval.ipx_sum = 0; - ioptval.ipx_tc = 0; - IPX_LOCK(ipxp); - ioptval.ipx_pt = ipxp->ipxp_dpt; - ioptval.ipx_dna = ipxp->ipxp_faddr; - ioptval.ipx_sna = ipxp->ipxp_laddr; - IPX_UNLOCK(ipxp); - error = sooptcopyout(sopt, &soptval, sizeof soptval); - break; - - case SO_SEQNO: - IPX_LIST_LOCK(); - seq = ipx_pexseq; - ipx_pexseq++; - IPX_LIST_UNLOCK(); - error = sooptcopyout(sopt, &seq, sizeof seq); - break; - - default: - error = EINVAL; - } - break; - - case SOPT_SET: - switch (sopt->sopt_name) { - case SO_ALL_PACKETS: - mask = IPXP_ALL_PACKETS; - goto set_head; - - case SO_HEADERS_ON_INPUT: - mask = IPXP_RAWIN; - goto set_head; - - case SO_IPX_CHECKSUM: - mask = IPXP_CHECKSUM; - goto set_head; - - case SO_HEADERS_ON_OUTPUT: - mask = IPXP_RAWOUT; - set_head: - error = sooptcopyin(sopt, &optval, sizeof optval, - sizeof optval); - if (error) - break; - IPX_LOCK(ipxp); - if (optval) - ipxp->ipxp_flags |= mask; - else - ipxp->ipxp_flags &= ~mask; - IPX_UNLOCK(ipxp); - break; - - case SO_DEFAULT_HEADERS: - error = sooptcopyin(sopt, &ioptval, sizeof ioptval, - sizeof ioptval); - if (error) - break; - /* Unlocked write. */ - ipxp->ipxp_dpt = ioptval.ipx_pt; - break; - default: - error = EINVAL; - } - break; - } - return (error); -} - -static void -ipx_usr_abort(struct socket *so) -{ - - /* XXXRW: Possibly ipx_disconnect() here? */ - soisdisconnected(so); -} - -static int -ipx_attach(struct socket *so, int proto, struct thread *td) -{ -#ifdef INVARIANTS - struct ipxpcb *ipxp = sotoipxpcb(so); -#endif - int error; - - KASSERT(ipxp == NULL, ("ipx_attach: ipxp != NULL")); - error = soreserve(so, ipxsendspace, ipxrecvspace); - if (error != 0) - return (error); - IPX_LIST_LOCK(); - error = ipx_pcballoc(so, &ipxpcb_list, td); - IPX_LIST_UNLOCK(); - return (error); -} - -static int -ipx_bind(struct socket *so, struct sockaddr *nam, struct thread *td) -{ - struct ipxpcb *ipxp = sotoipxpcb(so); - int error; - - KASSERT(ipxp != NULL, ("ipx_bind: ipxp == NULL")); - IPX_LIST_LOCK(); - IPX_LOCK(ipxp); - error = ipx_pcbbind(ipxp, nam, td); - IPX_UNLOCK(ipxp); - IPX_LIST_UNLOCK(); - return (error); -} - -static void -ipx_usr_close(struct socket *so) -{ - - /* XXXRW: Possibly ipx_disconnect() here? */ - soisdisconnected(so); -} - -static int -ipx_connect(struct socket *so, struct sockaddr *nam, struct thread *td) -{ - struct ipxpcb *ipxp = sotoipxpcb(so); - int error; - - KASSERT(ipxp != NULL, ("ipx_connect: ipxp == NULL")); - IPX_LIST_LOCK(); - IPX_LOCK(ipxp); - if (!ipx_nullhost(ipxp->ipxp_faddr)) { - error = EISCONN; - goto out; - } - error = ipx_pcbconnect(ipxp, nam, td); - if (error == 0) - soisconnected(so); -out: - IPX_UNLOCK(ipxp); - IPX_LIST_UNLOCK(); - return (error); -} - -static void -ipx_detach(struct socket *so) -{ - struct ipxpcb *ipxp = sotoipxpcb(so); - - /* XXXRW: Should assert detached. */ - KASSERT(ipxp != NULL, ("ipx_detach: ipxp == NULL")); - IPX_LIST_LOCK(); - IPX_LOCK(ipxp); - ipx_pcbdetach(ipxp); - ipx_pcbfree(ipxp); - IPX_LIST_UNLOCK(); -} - -static int -ipx_disconnect(struct socket *so) -{ - struct ipxpcb *ipxp = sotoipxpcb(so); - int error; - - KASSERT(ipxp != NULL, ("ipx_disconnect: ipxp == NULL")); - IPX_LIST_LOCK(); - IPX_LOCK(ipxp); - error = 0; - if (ipx_nullhost(ipxp->ipxp_faddr)) { - error = ENOTCONN; - goto out; - } - ipx_pcbdisconnect(ipxp); - soisdisconnected(so); -out: - IPX_UNLOCK(ipxp); - IPX_LIST_UNLOCK(); - return (0); -} - -int -ipx_peeraddr(struct socket *so, struct sockaddr **nam) -{ - struct ipxpcb *ipxp = sotoipxpcb(so); - - KASSERT(ipxp != NULL, ("ipx_peeraddr: ipxp == NULL")); - ipx_getpeeraddr(ipxp, nam); - return (0); -} - -static int -ipx_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam, - struct mbuf *control, struct thread *td) -{ - int error; - struct ipxpcb *ipxp = sotoipxpcb(so); - struct ipx_addr laddr; - - KASSERT(ipxp != NULL, ("ipxp_send: ipxp == NULL")); - /* - * Attempt to only acquire the necessary locks: if the socket is - * already connected, we don't need to hold the IPX list lock to be - * used by ipx_pcbconnect() and ipx_pcbdisconnect(), just the IPX - * pcb lock. - */ -#ifdef MAC - mac_socket_create_mbuf(so, m); -#endif - if (nam != NULL) { - IPX_LIST_LOCK(); - IPX_LOCK(ipxp); - laddr = ipxp->ipxp_laddr; - if (!ipx_nullhost(ipxp->ipxp_faddr)) { - IPX_UNLOCK(ipxp); - IPX_LIST_UNLOCK(); - error = EISCONN; - goto send_release; - } - /* - * Must block input while temporarily connected. - */ - error = ipx_pcbconnect(ipxp, nam, td); - if (error) { - IPX_UNLOCK(ipxp); - IPX_LIST_UNLOCK(); - goto send_release; - } - } else { - IPX_LOCK(ipxp); - if (ipx_nullhost(ipxp->ipxp_faddr)) { - IPX_UNLOCK(ipxp); - error = ENOTCONN; - goto send_release; - } - } - error = ipx_output(ipxp, m); - m = NULL; - if (nam != NULL) { - ipx_pcbdisconnect(ipxp); - ipxp->ipxp_laddr = laddr; - IPX_UNLOCK(ipxp); - IPX_LIST_UNLOCK(); - } else - IPX_UNLOCK(ipxp); - -send_release: - if (m != NULL) - m_freem(m); - return (error); -} - -static int -ipx_shutdown(so) - struct socket *so; -{ - - KASSERT(so->so_pcb != NULL, ("ipx_shutdown: so_pcb == NULL")); - socantsendmore(so); - return (0); -} - -int -ipx_sockaddr(struct socket *so, struct sockaddr **nam) -{ - struct ipxpcb *ipxp = sotoipxpcb(so); - - KASSERT(ipxp != NULL, ("ipx_sockaddr: ipxp == NULL")); - ipx_getsockaddr(ipxp, nam); - return (0); -} - -static int -ripx_attach(struct socket *so, int proto, struct thread *td) -{ - int error = 0; - struct ipxpcb *ipxp = sotoipxpcb(so); - - KASSERT(ipxp == NULL, ("ripx_attach: ipxp != NULL")); - - if (td != NULL) { - error = priv_check(td, PRIV_NETIPX_RAW); - if (error) - return (error); - } - - /* - * We hold the IPX list lock for the duration as address parameters - * of the IPX pcb are changed. Since no one else holds a reference - * to the ipxpcb yet, we don't need the ipxpcb lock here. - */ - IPX_LIST_LOCK(); - error = ipx_pcballoc(so, &ipxrawpcb_list, td); - if (error) - goto out; - ipxp = sotoipxpcb(so); - error = soreserve(so, ipxsendspace, ipxrecvspace); - if (error) - goto out; - ipxp->ipxp_faddr.x_host = ipx_broadhost; - ipxp->ipxp_flags = IPXP_RAWIN | IPXP_RAWOUT; -out: - IPX_LIST_UNLOCK(); - return (error); -} diff --git a/sys/netipx/ipx_var.h b/sys/netipx/ipx_var.h deleted file mode 100644 index 304630d..0000000 --- a/sys/netipx/ipx_var.h +++ /dev/null @@ -1,129 +0,0 @@ -/*- - * 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. - * 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. - * - * Copyright (c) 1995, Mike Mitchell - * - * 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 - * - * $FreeBSD$ - */ - -#ifndef _NETIPX_IPX_VAR_H_ -#define _NETIPX_IPX_VAR_H_ - -/* - * IPX Kernel Structures and Variables - */ -struct ipxstat { - u_long ipxs_total; /* total packets received */ - u_long ipxs_badsum; /* checksum bad */ - u_long ipxs_tooshort; /* packet too short */ - u_long ipxs_toosmall; /* not enough data */ - u_long ipxs_forward; /* packets forwarded */ - u_long ipxs_cantforward; /* packets rcvd for unreachable dest */ - u_long ipxs_delivered; /* datagrams delivered to upper level*/ - u_long ipxs_localout; /* total ipx packets generated here */ - u_long ipxs_odropped; /* lost packets due to nobufs, etc. */ - u_long ipxs_noroute; /* packets discarded due to no route */ - u_long ipxs_mtutoosmall; /* the interface mtu is too small */ -}; - -#ifdef _KERNEL - -#ifdef SYSCTL_DECL -SYSCTL_DECL(_net_ipx); -SYSCTL_DECL(_net_ipx_ipx); -#endif - -extern int ipxcksum; -extern long ipx_pexseq; -extern struct ipxstat ipxstat; -extern struct pr_usrreqs ipx_usrreqs; -extern struct pr_usrreqs ripx_usrreqs; -extern struct sockaddr_ipx ipx_netmask; -extern struct sockaddr_ipx ipx_hostmask; - -extern const union ipx_net ipx_zeronet; -extern const union ipx_net ipx_broadnet; -extern const union ipx_host ipx_broadhost; - -struct ifnet; -struct ipx_addr; -struct ipxpcb; -struct mbuf; -struct thread; -struct route; -struct sockaddr; -struct socket; -struct sockopt; - -u_short ipx_cksum(struct mbuf *m, int len); -int ipx_control(struct socket *so, u_long cmd, caddr_t data, - struct ifnet *ifp, struct thread *td); -void ipx_ctlinput(int cmd, struct sockaddr *arg_as_sa, void *dummy); -int ipx_ctloutput(struct socket *so, struct sockopt *sopt); -void ipx_drop(struct ipxpcb *ipxp, int errno); -void ipx_init(void); -void ipx_input(struct mbuf *m, struct ipxpcb *ipxp); -int ipx_outputfl(struct mbuf *m0, struct route *ro, int flags); -int ipx_output_type20(struct mbuf *); -int ipx_peeraddr(struct socket *so, struct sockaddr **nam); -void ipx_printhost(struct ipx_addr *addr); -int ipx_sockaddr(struct socket *so, struct sockaddr **nam); - -#endif /* _KERNEL */ - -#endif /* !_NETIPX_IPX_VAR_H_ */ diff --git a/sys/netipx/spx.h b/sys/netipx/spx.h deleted file mode 100644 index d356bff..0000000 --- a/sys/netipx/spx.h +++ /dev/null @@ -1,210 +0,0 @@ -/*- - * 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. - * 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. - * - * Copyright (c) 1995, Mike Mitchell - * - * 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 - * - * $FreeBSD$ - */ - -#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 */ -} __packed; - -/* - * Definitions for NS(tm) Internet Datagram Protocol - * containing a Sequenced Packet Protocol packet. - */ -struct spx { - struct ipx si_i; - struct spxhdr si_s; -} __packed; -struct spx_q { - struct mbuf *sq_msi; - struct spx *sq_si; - LIST_ENTRY(spx_q) sq_entry; -}; -#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 - -/* - * SPX control block, one per connection - */ -struct spxpcb { - LIST_HEAD(, 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 threshold 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 */ -#define SPXT_NTIMERS 4 - 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))) - -#ifdef _KERNEL - -extern struct pr_usrreqs spx_usrreqs; -extern struct pr_usrreqs spx_usrreq_sps; - -void spx_ctlinput(int cmd, struct sockaddr *arg_as_sa, void *dummy); -int spx_ctloutput(struct socket *so, struct sockopt *sopt); -void spx_fasttimo(void); -void spx_init(void); -void spx_input(struct mbuf *m, struct ipxpcb *ipxp); -void spx_slowtimo(void); - -#endif /* _KERNEL */ - -#endif /* !_NETIPX_SPX_H_ */ diff --git a/sys/netipx/spx_debug.c b/sys/netipx/spx_debug.c deleted file mode 100644 index 0d3f65f..0000000 --- a/sys/netipx/spx_debug.c +++ /dev/null @@ -1,196 +0,0 @@ -/*- - * 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. - * 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. - * - * Copyright (c) 1995, Mike Mitchell - * - * 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/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include "opt_inet.h" -#include "opt_tcpdebug.h" - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/protosw.h> - -#define TCPSTATES /* for logging */ - -#include <netinet/in_systm.h> -#include <netinet/tcp_fsm.h> - -#include <netipx/ipx.h> -#include <netipx/ipx_var.h> -#include <netipx/spx.h> -#define SPXTIMERS -#include <netipx/spx_timer.h> -#define SANAMES -#include <netipx/spx_debug.h> - -#ifdef INET -#ifdef TCPDEBUG -static int spxconsdebug = 0; -static struct spx_debug spx_debug[SPX_NDEBUG]; -static int spx_debx; -#endif -#endif - -/* - * spx debug routines - */ -void -spx_trace(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 != NULL) - sd->sd_sp = *sp; - else - bzero((caddr_t)&sd->sd_sp, sizeof(*sp)); - if (si != NULL) - 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 != NULL) - printf("%p %s:", (void *)sp, tcpstates[ostate]); - else - printf("???????? "); - printf("%s ", spxnames[act]); - switch (act) { - - case SA_RESPOND: - case SA_INPUT: - case SA_OUTPUT: - case SA_DROP: - if (si == NULL) - 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 -} diff --git a/sys/netipx/spx_debug.h b/sys/netipx/spx_debug.h deleted file mode 100644 index 24405bc..0000000 --- a/sys/netipx/spx_debug.h +++ /dev/null @@ -1,103 +0,0 @@ -/*- - * 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. - * 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. - * - * Copyright (c) 1995, Mike Mitchell - * - * 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 - * - * $FreeBSD$ - */ - -#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 -const char *spxnames[] = - { "input", "output", "user", "respond", "drop" }; -#endif - -#define SPX_NDEBUG 100 -#ifndef _KERNEL -/* XXX common variables for broken applications. */ -struct spx_debug spx_debug[SPX_NDEBUG]; -int spx_debx; -#endif - -#ifdef _KERNEL -extern char *prurequests[]; -extern char *sanames[]; - -void spx_trace(short act, u_char ostate, struct spxpcb *sp, struct spx *si, - int req); -#endif - -#endif /* !_NETIPX_SPX_DEBUG_H_ */ diff --git a/sys/netipx/spx_reass.c b/sys/netipx/spx_reass.c deleted file mode 100644 index 2479ae1..0000000 --- a/sys/netipx/spx_reass.c +++ /dev/null @@ -1,451 +0,0 @@ -/*- - * Copyright (c) 1984, 1985, 1986, 1987, 1993 - * The Regents of the University of California. - * Copyright (c) 2004-2009 Robert N. M. Watson - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 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. - * - * Copyright (c) 1995, Mike Mitchell - * 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_usrreq.h - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/param.h> -#include <sys/lock.h> -#include <sys/kernel.h> -#include <sys/malloc.h> -#include <sys/mbuf.h> -#include <sys/mutex.h> -#include <sys/proc.h> -#include <sys/protosw.h> -#include <sys/signalvar.h> -#include <sys/socket.h> -#include <sys/socketvar.h> -#include <sys/sx.h> -#include <sys/systm.h> - -#include <net/route.h> -#include <netinet/tcp_fsm.h> - -#include <netipx/ipx.h> -#include <netipx/ipx_pcb.h> -#include <netipx/ipx_var.h> -#include <netipx/spx.h> -#include <netipx/spx_debug.h> -#include <netipx/spx_timer.h> -#include <netipx/spx_var.h> - -static int spx_use_delack = 0; -static int spxrexmtthresh = 3; - -static MALLOC_DEFINE(M_SPXREASSQ, "spxreassq", "SPX reassembly queue entry"); - -/* - * Flesh pending queued segments on SPX close. - */ -void -spx_reass_flush(struct spxpcb *cb) -{ - struct spx_q *q; - - while ((q = LIST_FIRST(&cb->s_q)) != NULL) { - LIST_REMOVE(q, sq_entry); - m_freem(q->sq_msi); - free(q, M_SPXREASSQ); - } -} - -/* - * Initialize SPX segment reassembly queue on SPX socket open. - */ -void -spx_reass_init(struct spxpcb *cb) -{ - - LIST_INIT(&cb->s_q); -} - -/* - * This is structurally similar to the tcp reassembly routine but its - * function is somewhat different: it merely queues packets up, and - * suppresses duplicates. - */ -int -spx_reass(struct spxpcb *cb, struct mbuf *msi, struct spx *si) -{ - struct spx_q *q, *q_new, *q_temp; - struct mbuf *m; - struct socket *so = cb->s_ipxpcb->ipxp_socket; - char packetp = cb->s_flags & SF_HI; - int incr; - char wakeup = 0; - - IPX_LOCK_ASSERT(cb->s_ipxpcb); - - if (si == SI(0)) - goto present; - - /* - * Update our news from them. - */ - if (si->si_cc & SPX_SA) - cb->s_flags |= (spx_use_delack ? SF_DELACK : SF_ACKNOW); - if (SSEQ_GT(si->si_alo, cb->s_ralo)) - cb->s_flags |= SF_WIN; - if (SSEQ_LEQ(si->si_ack, cb->s_rack)) { - if ((si->si_cc & SPX_SP) && cb->s_rack != (cb->s_smax + 1)) { - spxstat.spxs_rcvdupack++; - - /* - * If this is a completely duplicate ack and other - * conditions hold, we assume a packet has been - * dropped and retransmit it exactly as in - * tcp_input(). - */ - if (si->si_ack != cb->s_rack || - si->si_alo != cb->s_ralo) - cb->s_dupacks = 0; - else if (++cb->s_dupacks == spxrexmtthresh) { - u_short onxt = cb->s_snxt; - int cwnd = cb->s_cwnd; - - cb->s_snxt = si->si_ack; - cb->s_cwnd = CUNIT; - cb->s_force = 1 + SPXT_REXMT; - spx_output(cb, NULL); - cb->s_timer[SPXT_REXMT] = cb->s_rxtcur; - cb->s_rtt = 0; - if (cwnd >= 4 * CUNIT) - cb->s_cwnd = cwnd / 2; - if (SSEQ_GT(onxt, cb->s_snxt)) - cb->s_snxt = onxt; - return (1); - } - } else - cb->s_dupacks = 0; - goto update_window; - } - cb->s_dupacks = 0; - - /* - * If our correspondent acknowledges data we haven't sent TCP would - * drop the packet after acking. We'll be a little more permissive. - */ - if (SSEQ_GT(si->si_ack, (cb->s_smax + 1))) { - spxstat.spxs_rcvacktoomuch++; - si->si_ack = cb->s_smax + 1; - } - spxstat.spxs_rcvackpack++; - - /* - * If transmit timer is running and timed sequence number was acked, - * update smoothed round trip time. See discussion of algorithm in - * tcp_input.c - */ - if (cb->s_rtt && SSEQ_GT(si->si_ack, cb->s_rtseq)) { - spxstat.spxs_rttupdated++; - if (cb->s_srtt != 0) { - short delta; - delta = cb->s_rtt - (cb->s_srtt >> 3); - if ((cb->s_srtt += delta) <= 0) - cb->s_srtt = 1; - if (delta < 0) - delta = -delta; - delta -= (cb->s_rttvar >> 2); - if ((cb->s_rttvar += delta) <= 0) - cb->s_rttvar = 1; - } else { - /* - * No rtt measurement yet. - */ - cb->s_srtt = cb->s_rtt << 3; - cb->s_rttvar = cb->s_rtt << 1; - } - cb->s_rtt = 0; - cb->s_rxtshift = 0; - SPXT_RANGESET(cb->s_rxtcur, - ((cb->s_srtt >> 2) + cb->s_rttvar) >> 1, - SPXTV_MIN, SPXTV_REXMTMAX); - } - - /* - * If all outstanding data is acked, stop retransmit timer and - * remember to restart (more output or persist). If there is more - * data to be acked, restart retransmit timer, using current - * (possibly backed-off) value; - */ - if (si->si_ack == cb->s_smax + 1) { - cb->s_timer[SPXT_REXMT] = 0; - cb->s_flags |= SF_RXT; - } else if (cb->s_timer[SPXT_PERSIST] == 0) - cb->s_timer[SPXT_REXMT] = cb->s_rxtcur; - - /* - * When new data is acked, open the congestion window. If the window - * gives us less than ssthresh packets in flight, open exponentially - * (maxseg at a time). Otherwise open linearly (maxseg^2 / cwnd at a - * time). - */ - incr = CUNIT; - if (cb->s_cwnd > cb->s_ssthresh) - incr = max(incr * incr / cb->s_cwnd, 1); - cb->s_cwnd = min(cb->s_cwnd + incr, cb->s_cwmx); - - /* - * Trim Acked data from output queue. - */ - SOCKBUF_LOCK(&so->so_snd); - while ((m = so->so_snd.sb_mb) != NULL) { - if (SSEQ_LT((mtod(m, struct spx *))->si_seq, si->si_ack)) - sbdroprecord_locked(&so->so_snd); - else - break; - } - sowwakeup_locked(so); - cb->s_rack = si->si_ack; -update_window: - if (SSEQ_LT(cb->s_snxt, cb->s_rack)) - cb->s_snxt = cb->s_rack; - if (SSEQ_LT(cb->s_swl1, si->si_seq) || ((cb->s_swl1 == si->si_seq && - (SSEQ_LT(cb->s_swl2, si->si_ack))) || - (cb->s_swl2 == si->si_ack && SSEQ_LT(cb->s_ralo, si->si_alo)))) { - /* keep track of pure window updates */ - if ((si->si_cc & SPX_SP) && cb->s_swl2 == si->si_ack - && SSEQ_LT(cb->s_ralo, si->si_alo)) { - spxstat.spxs_rcvwinupd++; - spxstat.spxs_rcvdupack--; - } - cb->s_ralo = si->si_alo; - cb->s_swl1 = si->si_seq; - cb->s_swl2 = si->si_ack; - cb->s_swnd = (1 + si->si_alo - si->si_ack); - if (cb->s_swnd > cb->s_smxw) - cb->s_smxw = cb->s_swnd; - cb->s_flags |= SF_WIN; - } - - /* - * If this packet number is higher than that which we have allocated - * refuse it, unless urgent. - */ - if (SSEQ_GT(si->si_seq, cb->s_alo)) { - if (si->si_cc & SPX_SP) { - spxstat.spxs_rcvwinprobe++; - return (1); - } else - spxstat.spxs_rcvpackafterwin++; - if (si->si_cc & SPX_OB) { - if (SSEQ_GT(si->si_seq, cb->s_alo + 60)) - return (1); /* else queue this packet; */ - } else { -#ifdef BROKEN - /* - * XXXRW: This is broken on at least one count: - * spx_close() will free the ipxp and related parts, - * which are then touched by spx_input() after the - * return from spx_reass(). - */ - /*struct socket *so = cb->s_ipxpcb->ipxp_socket; - if (so->so_state && SS_NOFDREF) { - spx_close(cb); - } else - would crash system*/ -#endif - spx_istat.notyet++; - return (1); - } - } - - /* - * If this is a system packet, we don't need to queue it up, and - * won't update acknowledge #. - */ - if (si->si_cc & SPX_SP) - return (1); - - /* - * We have already seen this packet, so drop. - */ - if (SSEQ_LT(si->si_seq, cb->s_ack)) { - spx_istat.bdreas++; - spxstat.spxs_rcvduppack++; - if (si->si_seq == cb->s_ack - 1) - spx_istat.lstdup++; - return (1); - } - - /* - * Loop through all packets queued up to insert in appropriate - * sequence. - */ - q_new = malloc(sizeof(*q_new), M_SPXREASSQ, M_NOWAIT | M_ZERO); - if (q_new == NULL) - return (1); - q_new->sq_si = si; - q_new->sq_msi = msi; - LIST_FOREACH(q, &cb->s_q, sq_entry) { - if (si->si_seq == q->sq_si->si_seq) { - free(q_new, M_SPXREASSQ); - spxstat.spxs_rcvduppack++; - return (1); - } - if (SSEQ_LT(si->si_seq, q->sq_si->si_seq)) { - spxstat.spxs_rcvoopack++; - break; - } - } - if (q != NULL) - LIST_INSERT_BEFORE(q, q_new, sq_entry); - else - LIST_INSERT_HEAD(&cb->s_q, q_new, sq_entry); - - /* - * If this packet is urgent, inform process - */ - if (si->si_cc & SPX_OB) { - cb->s_iobc = ((char *)si)[1 + sizeof(*si)]; - sohasoutofband(so); - cb->s_oobflags |= SF_IOOB; - } -present: -#define SPINC sizeof(struct spxhdr) - SOCKBUF_LOCK(&so->so_rcv); - - /* - * Loop through all packets queued up to update acknowledge number, - * and present all acknowledged data to user; if in packet interface - * mode, show packet headers. - */ - LIST_FOREACH_SAFE(q, &cb->s_q, sq_entry, q_temp) { - struct spx *qsi; - struct mbuf *mqsi; - - qsi = q->sq_si; - mqsi = q->sq_msi; - if (qsi->si_seq == cb->s_ack) { - cb->s_ack++; - if (qsi->si_cc & SPX_OB) { - cb->s_oobflags &= ~SF_IOOB; - if (so->so_rcv.sb_cc) - so->so_oobmark = so->so_rcv.sb_cc; - else - so->so_rcv.sb_state |= SBS_RCVATMARK; - } - LIST_REMOVE(q, sq_entry); - free(q, M_SPXREASSQ); - wakeup = 1; - spxstat.spxs_rcvpack++; -#ifdef SF_NEWCALL - if (cb->s_flags2 & SF_NEWCALL) { - struct spxhdr *sp = - mtod(mqsi, struct spxhdr *); - u_char dt = sp->spx_dt; - - spx_newchecks[4]++; - if (dt != cb->s_rhdr.spx_dt) { - struct mbuf *mm = - m_getclr(M_NOWAIT, MT_CONTROL); - spx_newchecks[0]++; - if (mm != NULL) { - u_short *s = - mtod(mm, u_short *); - cb->s_rhdr.spx_dt = dt; - mm->m_len = 5; /*XXX*/ - s[0] = 5; - s[1] = 1; - *(u_char *)(&s[2]) = dt; - sbappend_locked(&so->so_rcv, mm); - } - } - if (sp->spx_cc & SPX_OB) { - MCHTYPE(mqsi, MT_OOBDATA); - spx_newchecks[1]++; - so->so_oobmark = 0; - so->so_rcv.sb_state &= ~SBS_RCVATMARK; - } - if (packetp == 0) { - mqsi->m_data += SPINC; - mqsi->m_len -= SPINC; - mqsi->m_pkthdr.len -= SPINC; - } - if ((sp->spx_cc & SPX_EM) || packetp) { - sbappendrecord_locked(&so->so_rcv, - mqsi); - spx_newchecks[9]++; - } else - sbappend_locked(&so->so_rcv, mqsi); - } else -#endif - if (packetp) - sbappendrecord_locked(&so->so_rcv, mqsi); - else { - cb->s_rhdr = *mtod(mqsi, struct spxhdr *); - mqsi->m_data += SPINC; - mqsi->m_len -= SPINC; - mqsi->m_pkthdr.len -= SPINC; - sbappend_locked(&so->so_rcv, mqsi); - } - } else - break; - } - if (wakeup) - sorwakeup_locked(so); - else - SOCKBUF_UNLOCK(&so->so_rcv); - return (0); -} diff --git a/sys/netipx/spx_timer.h b/sys/netipx/spx_timer.h deleted file mode 100644 index eda949d..0000000 --- a/sys/netipx/spx_timer.h +++ /dev/null @@ -1,149 +0,0 @@ -/*- - * 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. - * 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. - * - * Copyright (c) 1995, Mike Mitchell - * - * 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 - * - * $FreeBSD$ - */ - -#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_REXMT 0 /* retransmit */ -#define SPXT_PERSIST 1 /* retransmit persistence */ -#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 persistence */ -#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); \ -} - -#endif /* !_NETIPX_SPX_TIMER_H_ */ diff --git a/sys/netipx/spx_usrreq.c b/sys/netipx/spx_usrreq.c deleted file mode 100644 index 9d00d10..0000000 --- a/sys/netipx/spx_usrreq.c +++ /dev/null @@ -1,1793 +0,0 @@ -/*- - * Copyright (c) 1984, 1985, 1986, 1987, 1993 - * The Regents of the University of California. - * Copyright (c) 2004-2009 Robert N. M. Watson - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 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. - * - * Copyright (c) 1995, Mike Mitchell - * 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_usrreq.h - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/param.h> -#include <sys/lock.h> -#include <sys/malloc.h> -#include <sys/mbuf.h> -#include <sys/mutex.h> -#include <sys/proc.h> -#include <sys/protosw.h> -#include <sys/signalvar.h> -#include <sys/socket.h> -#include <sys/socketvar.h> -#include <sys/sx.h> -#include <sys/systm.h> - -#include <net/route.h> -#include <netinet/tcp_fsm.h> - -#include <netipx/ipx.h> -#include <netipx/ipx_pcb.h> -#include <netipx/ipx_var.h> -#include <netipx/spx.h> -#include <netipx/spx_debug.h> -#include <netipx/spx_timer.h> -#include <netipx/spx_var.h> - -#include <security/mac/mac_framework.h> - -/* - * SPX protocol implementation. - */ -static struct mtx spx_mtx; /* Protects only spx_iss. */ -static u_short spx_iss; -u_short spx_newchecks[50]; -static int spx_hardnosed; -static int traceallspxs = 0; -struct spx_istat spx_istat; - -#define SPX_LOCK_INIT() mtx_init(&spx_mtx, "spx_mtx", NULL, MTX_DEF) -#define SPX_LOCK() mtx_lock(&spx_mtx) -#define SPX_UNLOCK() mtx_unlock(&spx_mtx) - -static const int spx_backoff[SPX_MAXRXTSHIFT+1] = - { 1, 2, 4, 8, 16, 32, 64, 64, 64, 64, 64, 64, 64 }; - -static void spx_close(struct spxpcb *cb); -static void spx_disconnect(struct spxpcb *cb); -static void spx_drop(struct spxpcb *cb, int errno); -static void spx_setpersist(struct spxpcb *cb); -static void spx_template(struct spxpcb *cb); -static void spx_timers(struct spxpcb *cb, int timer); -static void spx_usrclosed(struct spxpcb *cb); - -static void spx_usr_abort(struct socket *so); -static int spx_accept(struct socket *so, struct sockaddr **nam); -static int spx_attach(struct socket *so, int proto, struct thread *td); -static int spx_bind(struct socket *so, struct sockaddr *nam, struct thread *td); -static void spx_usr_close(struct socket *so); -static int spx_connect(struct socket *so, struct sockaddr *nam, - struct thread *td); -static void spx_detach(struct socket *so); -static void spx_pcbdetach(struct ipxpcb *ipxp); -static int spx_usr_disconnect(struct socket *so); -static int spx_listen(struct socket *so, int backlog, struct thread *td); -static int spx_rcvd(struct socket *so, int flags); -static int spx_rcvoob(struct socket *so, struct mbuf *m, int flags); -static int spx_send(struct socket *so, int flags, struct mbuf *m, - struct sockaddr *addr, struct mbuf *control, - struct thread *td); -static int spx_shutdown(struct socket *so); -static int spx_sp_attach(struct socket *so, int proto, struct thread *td); - -struct pr_usrreqs spx_usrreqs = { - .pru_abort = spx_usr_abort, - .pru_accept = spx_accept, - .pru_attach = spx_attach, - .pru_bind = spx_bind, - .pru_connect = spx_connect, - .pru_control = ipx_control, - .pru_detach = spx_detach, - .pru_disconnect = spx_usr_disconnect, - .pru_listen = spx_listen, - .pru_peeraddr = ipx_peeraddr, - .pru_rcvd = spx_rcvd, - .pru_rcvoob = spx_rcvoob, - .pru_send = spx_send, - .pru_shutdown = spx_shutdown, - .pru_sockaddr = ipx_sockaddr, - .pru_close = spx_usr_close, -}; - -struct pr_usrreqs spx_usrreq_sps = { - .pru_abort = spx_usr_abort, - .pru_accept = spx_accept, - .pru_attach = spx_sp_attach, - .pru_bind = spx_bind, - .pru_connect = spx_connect, - .pru_control = ipx_control, - .pru_detach = spx_detach, - .pru_disconnect = spx_usr_disconnect, - .pru_listen = spx_listen, - .pru_peeraddr = ipx_peeraddr, - .pru_rcvd = spx_rcvd, - .pru_rcvoob = spx_rcvoob, - .pru_send = spx_send, - .pru_shutdown = spx_shutdown, - .pru_sockaddr = ipx_sockaddr, - .pru_close = spx_usr_close, -}; - -void -spx_init(void) -{ - - SPX_LOCK_INIT(); - spx_iss = 1; /* WRONG !! should fish it out of TODR */ -} - -void -spx_input(struct mbuf *m, struct ipxpcb *ipxp) -{ - struct spxpcb *cb; - struct spx *si = mtod(m, struct spx *); - struct socket *so; - struct spx spx_savesi; - int dropsocket = 0; - short ostate = 0; - - spxstat.spxs_rcvtotal++; - KASSERT(ipxp != NULL, ("spx_input: ipxpcb == NULL")); - - /* - * spx_input() assumes that the caller will hold both the pcb list - * lock and also the ipxp lock. spx_input() will release both before - * returning, and may in fact trade in the ipxp lock for another pcb - * lock following sonewconn(). - */ - IPX_LIST_LOCK_ASSERT(); - IPX_LOCK_ASSERT(ipxp); - - cb = ipxtospxpcb(ipxp); - KASSERT(cb != NULL, ("spx_input: cb == NULL")); - - if (ipxp->ipxp_flags & IPXP_DROPPED) - goto drop; - - if (m->m_len < sizeof(*si)) { - if ((m = m_pullup(m, sizeof(*si))) == NULL) { - IPX_UNLOCK(ipxp); - IPX_LIST_UNLOCK(); - spxstat.spxs_rcvshort++; - return; - } - si = mtod(m, struct spx *); - } - si->si_seq = ntohs(si->si_seq); - si->si_ack = ntohs(si->si_ack); - si->si_alo = ntohs(si->si_alo); - - so = ipxp->ipxp_socket; - KASSERT(so != NULL, ("spx_input: so == NULL")); - -#ifdef MAC - if (mac_socket_check_deliver(so, m) != 0) - goto drop; -#endif - - if (so->so_options & SO_DEBUG || traceallspxs) { - ostate = cb->s_state; - spx_savesi = *si; - } - if (so->so_options & SO_ACCEPTCONN) { - struct spxpcb *ocb = cb; - - so = sonewconn(so, 0); - if (so == NULL) - goto drop; - - /* - * This is ugly, but .... - * - * Mark socket as temporary until we're committed to keeping - * it. The code at ``drop'' and ``dropwithreset'' check the - * flag dropsocket to see if the temporary socket created - * here should be discarded. We mark the socket as - * discardable until we're committed to it below in - * TCPS_LISTEN. - * - * XXXRW: In the new world order of real kernel parallelism, - * temporarily allocating the socket when we're "not sure" - * seems like a bad idea, as we might race to remove it if - * the listen socket is closed...? - * - * We drop the lock of the listen socket ipxp, and acquire - * the lock of the new socket ippx. - */ - dropsocket++; - IPX_UNLOCK(ipxp); - ipxp = (struct ipxpcb *)so->so_pcb; - IPX_LOCK(ipxp); - ipxp->ipxp_laddr = si->si_dna; - cb = ipxtospxpcb(ipxp); - cb->s_mtu = ocb->s_mtu; /* preserve sockopts */ - cb->s_flags = ocb->s_flags; /* preserve sockopts */ - cb->s_flags2 = ocb->s_flags2; /* preserve sockopts */ - cb->s_state = TCPS_LISTEN; - } - IPX_LOCK_ASSERT(ipxp); - - /* - * Packet received on connection. Reset idle time and keep-alive - * timer. - */ - cb->s_idle = 0; - cb->s_timer[SPXT_KEEP] = SPXTV_KEEP; - - switch (cb->s_state) { - case TCPS_LISTEN:{ - struct sockaddr_ipx *sipx, ssipx; - struct ipx_addr laddr; - - /* - * If somebody here was carying on a conversation and went - * away, and his pen pal thinks he can still talk, we get the - * misdirected packet. - */ - if (spx_hardnosed && (si->si_did != 0 || si->si_seq != 0)) { - spx_istat.gonawy++; - goto dropwithreset; - } - sipx = &ssipx; - bzero(sipx, sizeof *sipx); - sipx->sipx_len = sizeof(*sipx); - sipx->sipx_family = AF_IPX; - sipx->sipx_addr = si->si_sna; - laddr = ipxp->ipxp_laddr; - if (ipx_nullhost(laddr)) - ipxp->ipxp_laddr = si->si_dna; - if (ipx_pcbconnect(ipxp, (struct sockaddr *)sipx, &thread0)) { - ipxp->ipxp_laddr = laddr; - spx_istat.noconn++; - goto drop; - } - spx_template(cb); - dropsocket = 0; /* committed to socket */ - cb->s_did = si->si_sid; - cb->s_rack = si->si_ack; - cb->s_ralo = si->si_alo; -#define THREEWAYSHAKE -#ifdef THREEWAYSHAKE - cb->s_state = TCPS_SYN_RECEIVED; - cb->s_force = 1 + SPXT_KEEP; - spxstat.spxs_accepts++; - cb->s_timer[SPXT_KEEP] = SPXTV_KEEP; - } - break; - - case TCPS_SYN_RECEIVED: { - /* - * This state means that we have heard a response to our - * acceptance of their connection. It is probably logically - * unnecessary in this implementation. - */ - if (si->si_did != cb->s_sid) { - spx_istat.wrncon++; - goto drop; - } -#endif - ipxp->ipxp_fport = si->si_sport; - cb->s_timer[SPXT_REXMT] = 0; - cb->s_timer[SPXT_KEEP] = SPXTV_KEEP; - soisconnected(so); - cb->s_state = TCPS_ESTABLISHED; - spxstat.spxs_accepts++; - } - break; - - case TCPS_SYN_SENT: - /* - * This state means that we have gotten a response to our - * attempt to establish a connection. We fill in the data - * from the other side, telling us which port to respond to, - * instead of the well-known one we might have sent to in the - * first place. We also require that this is a response to - * our connection id. - */ - if (si->si_did != cb->s_sid) { - spx_istat.notme++; - goto drop; - } - spxstat.spxs_connects++; - cb->s_did = si->si_sid; - cb->s_rack = si->si_ack; - cb->s_ralo = si->si_alo; - cb->s_dport = ipxp->ipxp_fport = si->si_sport; - cb->s_timer[SPXT_REXMT] = 0; - cb->s_flags |= SF_ACKNOW; - soisconnected(so); - cb->s_state = TCPS_ESTABLISHED; - - /* - * Use roundtrip time of connection request for initial rtt. - */ - if (cb->s_rtt) { - cb->s_srtt = cb->s_rtt << 3; - cb->s_rttvar = cb->s_rtt << 1; - SPXT_RANGESET(cb->s_rxtcur, - ((cb->s_srtt >> 2) + cb->s_rttvar) >> 1, - SPXTV_MIN, SPXTV_REXMTMAX); - cb->s_rtt = 0; - } - } - - if (so->so_options & SO_DEBUG || traceallspxs) - spx_trace(SA_INPUT, (u_char)ostate, cb, &spx_savesi, 0); - - m->m_len -= sizeof(struct ipx); - m->m_pkthdr.len -= sizeof(struct ipx); - m->m_data += sizeof(struct ipx); - - if (spx_reass(cb, m, si)) - m_freem(m); - if (cb->s_force || (cb->s_flags & (SF_ACKNOW|SF_WIN|SF_RXT))) - spx_output(cb, NULL); - cb->s_flags &= ~(SF_WIN|SF_RXT); - IPX_UNLOCK(ipxp); - IPX_LIST_UNLOCK(); - return; - -dropwithreset: - IPX_LOCK_ASSERT(ipxp); - if (cb == NULL || (cb->s_ipxpcb->ipxp_socket->so_options & SO_DEBUG || - traceallspxs)) - spx_trace(SA_DROP, (u_char)ostate, cb, &spx_savesi, 0); - IPX_UNLOCK(ipxp); - if (dropsocket) { - struct socket *head; - ACCEPT_LOCK(); - KASSERT((so->so_qstate & SQ_INCOMP) != 0, - ("spx_input: nascent socket not SQ_INCOMP on soabort()")); - head = so->so_head; - TAILQ_REMOVE(&head->so_incomp, so, so_list); - head->so_incqlen--; - so->so_qstate &= ~SQ_INCOMP; - so->so_head = NULL; - ACCEPT_UNLOCK(); - soabort(so); - } - IPX_LIST_UNLOCK(); - m_freem(m); - return; - -drop: - IPX_LOCK_ASSERT(ipxp); - if (cb->s_ipxpcb->ipxp_socket->so_options & SO_DEBUG || traceallspxs) - spx_trace(SA_DROP, (u_char)ostate, cb, &spx_savesi, 0); - IPX_UNLOCK(ipxp); - IPX_LIST_UNLOCK(); - m_freem(m); -} - -void -spx_ctlinput(int cmd, struct sockaddr *arg_as_sa, void *dummy) -{ - - /* Currently, nothing. */ -} - -int -spx_output(struct spxpcb *cb, struct mbuf *m0) -{ - struct socket *so = cb->s_ipxpcb->ipxp_socket; - struct mbuf *m = NULL; - struct spx *si = NULL; - struct sockbuf *sb = &so->so_snd; - int len = 0, win, rcv_win; - short span, off, recordp = 0; - u_short alo; - int error = 0, sendalot; -#ifdef notdef - int idle; -#endif - struct mbuf *mprev; - - IPX_LOCK_ASSERT(cb->s_ipxpcb); - - if (m0 != NULL) { - int mtu = cb->s_mtu; - int datalen; - - /* - * Make sure that packet isn't too big. - */ - for (m = m0; m != NULL; m = m->m_next) { - mprev = m; - len += m->m_len; - if (m->m_flags & M_EOR) - recordp = 1; - } - datalen = (cb->s_flags & SF_HO) ? - len - sizeof(struct spxhdr) : len; - if (datalen > mtu) { - if (cb->s_flags & SF_PI) { - m_freem(m0); - return (EMSGSIZE); - } else { - int oldEM = cb->s_cc & SPX_EM; - - cb->s_cc &= ~SPX_EM; - while (len > mtu) { - m = m_copym(m0, 0, mtu, M_NOWAIT); - if (m == NULL) { - cb->s_cc |= oldEM; - m_freem(m0); - return (ENOBUFS); - } - if (cb->s_flags & SF_NEWCALL) { - struct mbuf *mm = m; - spx_newchecks[7]++; - while (mm != NULL) { - mm->m_flags &= ~M_EOR; - mm = mm->m_next; - } - } - error = spx_output(cb, m); - if (error) { - cb->s_cc |= oldEM; - m_freem(m0); - return (error); - } - m_adj(m0, mtu); - len -= mtu; - } - cb->s_cc |= oldEM; - } - } - - /* - * Force length even, by adding a "garbage byte" if - * necessary. - */ - if (len & 1) { - m = mprev; - if (M_TRAILINGSPACE(m) >= 1) - m->m_len++; - else { - struct mbuf *m1 = m_get(M_NOWAIT, MT_DATA); - - if (m1 == NULL) { - m_freem(m0); - return (ENOBUFS); - } - m1->m_len = 1; - *(mtod(m1, u_char *)) = 0; - m->m_next = m1; - } - } - m = m_gethdr(M_NOWAIT, MT_DATA); - if (m == NULL) { - m_freem(m0); - return (ENOBUFS); - } - - /* - * Fill in mbuf with extended SP header and addresses and - * length put into network format. - */ - MH_ALIGN(m, sizeof(struct spx)); - m->m_len = sizeof(struct spx); - m->m_next = m0; - si = mtod(m, struct spx *); - si->si_i = cb->s_ipx; - si->si_s = cb->s_shdr; - if ((cb->s_flags & SF_PI) && (cb->s_flags & SF_HO)) { - struct spxhdr *sh; - if (m0->m_len < sizeof(*sh)) { - if((m0 = m_pullup(m0, sizeof(*sh))) == NULL) { - m_free(m); - m_freem(m0); - return (EINVAL); - } - m->m_next = m0; - } - sh = mtod(m0, struct spxhdr *); - si->si_dt = sh->spx_dt; - si->si_cc |= sh->spx_cc & SPX_EM; - m0->m_len -= sizeof(*sh); - m0->m_data += sizeof(*sh); - len -= sizeof(*sh); - } - len += sizeof(*si); - if ((cb->s_flags2 & SF_NEWCALL) && recordp) { - si->si_cc |= SPX_EM; - spx_newchecks[8]++; - } - if (cb->s_oobflags & SF_SOOB) { - /* - * Per jqj@cornell: Make sure OB packets convey - * exactly 1 byte. If the packet is 1 byte or - * larger, we have already guaranted there to be at - * least one garbage byte for the checksum, and extra - * bytes shouldn't hurt! - */ - if (len > sizeof(*si)) { - si->si_cc |= SPX_OB; - len = (1 + sizeof(*si)); - } - } - si->si_len = htons((u_short)len); - m->m_pkthdr.len = ((len - 1) | 1) + 1; - - /* - * Queue stuff up for output. - */ - sbappendrecord(sb, m); - cb->s_seq++; - } -#ifdef notdef - idle = (cb->s_smax == (cb->s_rack - 1)); -#endif -again: - sendalot = 0; - off = cb->s_snxt - cb->s_rack; - win = min(cb->s_swnd, (cb->s_cwnd / CUNIT)); - - /* - * If in persist timeout with window of 0, send a probe. Otherwise, - * if window is small but non-zero and timer expired, send what we - * can and go into transmit state. - */ - if (cb->s_force == 1 + SPXT_PERSIST) { - if (win != 0) { - cb->s_timer[SPXT_PERSIST] = 0; - cb->s_rxtshift = 0; - } - } - span = cb->s_seq - cb->s_rack; - len = min(span, win) - off; - - if (len < 0) { - /* - * Window shrank after we went into it. If window shrank to - * 0, cancel pending restransmission and pull s_snxt back to - * (closed) window. We will enter persist state below. If - * the widndow didn't close completely, just wait for an ACK. - */ - len = 0; - if (win == 0) { - cb->s_timer[SPXT_REXMT] = 0; - cb->s_snxt = cb->s_rack; - } - } - if (len > 1) - sendalot = 1; - rcv_win = sbspace(&so->so_rcv); - - /* - * Send if we owe peer an ACK. - */ - if (cb->s_oobflags & SF_SOOB) { - /* - * Must transmit this out of band packet. - */ - cb->s_oobflags &= ~ SF_SOOB; - sendalot = 1; - spxstat.spxs_sndurg++; - goto found; - } - if (cb->s_flags & SF_ACKNOW) - goto send; - if (cb->s_state < TCPS_ESTABLISHED) - goto send; - - /* - * Silly window can't happen in spx. Code from TCP deleted. - */ - if (len) - goto send; - - /* - * Compare available window to amount of window known to peer (as - * advertised window less next expected input.) If the difference is - * at least two packets or at least 35% of the mximum possible - * window, then want to send a window update to peer. - */ - if (rcv_win > 0) { - u_short delta = 1 + cb->s_alo - cb->s_ack; - int adv = rcv_win - (delta * cb->s_mtu); - - if ((so->so_rcv.sb_cc == 0 && adv >= (2 * cb->s_mtu)) || - (100 * adv / so->so_rcv.sb_hiwat >= 35)) { - spxstat.spxs_sndwinup++; - cb->s_flags |= SF_ACKNOW; - goto send; - } - - } - - /* - * Many comments from tcp_output.c are appropriate here including ... - * If send window is too small, there is data to transmit, and no - * retransmit or persist is pending, then go to persist state. If - * nothing happens soon, send when timer expires: if window is - * non-zero, transmit what we can, otherwise send a probe. - */ - if (so->so_snd.sb_cc && cb->s_timer[SPXT_REXMT] == 0 && - cb->s_timer[SPXT_PERSIST] == 0) { - cb->s_rxtshift = 0; - spx_setpersist(cb); - } - - /* - * No reason to send a packet, just return. - */ - cb->s_outx = 1; - return (0); - -send: - /* - * Find requested packet. - */ - si = NULL; - m = NULL; - if (len > 0) { - cb->s_want = cb->s_snxt; - for (m = sb->sb_mb; m != NULL; m = m->m_nextpkt) { - si = mtod(m, struct spx *); - if (SSEQ_LEQ(cb->s_snxt, si->si_seq)) - break; - } - found: - if (si != NULL) { - if (si->si_seq != cb->s_snxt) { - spxstat.spxs_sndvoid++; - si = NULL; - m = NULL; - } else - cb->s_snxt++; - } - } - - /* - * Update window. - */ - if (rcv_win < 0) - rcv_win = 0; - alo = cb->s_ack - 1 + (rcv_win / ((short)cb->s_mtu)); - if (SSEQ_LT(alo, cb->s_alo)) - alo = cb->s_alo; - - if (m != NULL) { - /* - * Must make a copy of this packet for ipx_output to monkey - * with. - */ - m = m_copy(m, 0, M_COPYALL); - if (m == NULL) - return (ENOBUFS); - si = mtod(m, struct spx *); - if (SSEQ_LT(si->si_seq, cb->s_smax)) - spxstat.spxs_sndrexmitpack++; - else - spxstat.spxs_sndpack++; - } else if (cb->s_force || cb->s_flags & SF_ACKNOW) { - /* - * Must send an acknowledgement or a probe. - */ - if (cb->s_force) - spxstat.spxs_sndprobe++; - if (cb->s_flags & SF_ACKNOW) - spxstat.spxs_sndacks++; - m = m_gethdr(M_NOWAIT, MT_DATA); - if (m == NULL) - return (ENOBUFS); - - /* - * Fill in mbuf with extended SP header and addresses and - * length put into network format. - */ - MH_ALIGN(m, sizeof(struct spx)); - m->m_len = sizeof(*si); - m->m_pkthdr.len = sizeof(*si); - si = mtod(m, struct spx *); - si->si_i = cb->s_ipx; - si->si_s = cb->s_shdr; - si->si_seq = cb->s_smax + 1; - si->si_len = htons(sizeof(*si)); - si->si_cc |= SPX_SP; - } else { - cb->s_outx = 3; - if (so->so_options & SO_DEBUG || traceallspxs) - spx_trace(SA_OUTPUT, cb->s_state, cb, si, 0); - return (0); - } - - /* - * Stuff checksum and output datagram. - */ - if ((si->si_cc & SPX_SP) == 0) { - if (cb->s_force != (1 + SPXT_PERSIST) || - cb->s_timer[SPXT_PERSIST] == 0) { - /* - * If this is a new packet and we are not currently - * timing anything, time this one. - */ - if (SSEQ_LT(cb->s_smax, si->si_seq)) { - cb->s_smax = si->si_seq; - if (cb->s_rtt == 0) { - spxstat.spxs_segstimed++; - cb->s_rtseq = si->si_seq; - cb->s_rtt = 1; - } - } - - /* - * Set rexmt timer if not currently set, initial - * value for retransmit timer is smoothed round-trip - * time + 2 * round-trip time variance. Initialize - * shift counter which is used for backoff of - * retransmit time. - */ - if (cb->s_timer[SPXT_REXMT] == 0 && - cb->s_snxt != cb->s_rack) { - cb->s_timer[SPXT_REXMT] = cb->s_rxtcur; - if (cb->s_timer[SPXT_PERSIST]) { - cb->s_timer[SPXT_PERSIST] = 0; - cb->s_rxtshift = 0; - } - } - } else if (SSEQ_LT(cb->s_smax, si->si_seq)) - cb->s_smax = si->si_seq; - } else if (cb->s_state < TCPS_ESTABLISHED) { - if (cb->s_rtt == 0) - cb->s_rtt = 1; /* Time initial handshake */ - if (cb->s_timer[SPXT_REXMT] == 0) - cb->s_timer[SPXT_REXMT] = cb->s_rxtcur; - } - - /* - * Do not request acks when we ack their data packets or when we do a - * gratuitous window update. - */ - if (((si->si_cc & SPX_SP) == 0) || cb->s_force) - si->si_cc |= SPX_SA; - si->si_seq = htons(si->si_seq); - si->si_alo = htons(alo); - si->si_ack = htons(cb->s_ack); - - if (ipxcksum) - si->si_sum = ipx_cksum(m, ntohs(si->si_len)); - else - si->si_sum = 0xffff; - - cb->s_outx = 4; - if (so->so_options & SO_DEBUG || traceallspxs) - spx_trace(SA_OUTPUT, cb->s_state, cb, si, 0); - -#ifdef MAC - mac_socket_create_mbuf(so, m); -#endif - - if (so->so_options & SO_DONTROUTE) - error = ipx_outputfl(m, NULL, IPX_ROUTETOIF); - else - error = ipx_outputfl(m, &cb->s_ipxpcb->ipxp_route, 0); - if (error) - return (error); - spxstat.spxs_sndtotal++; - - /* - * Data sent (as far as we can tell). If this advertises a larger - * window than any other segment, then remember the size of the - * advertized window. Any pending ACK has now been sent. - */ - cb->s_force = 0; - cb->s_flags &= ~(SF_ACKNOW|SF_DELACK); - if (SSEQ_GT(alo, cb->s_alo)) - cb->s_alo = alo; - if (sendalot) - goto again; - cb->s_outx = 5; - return (0); -} - -static int spx_do_persist_panics = 0; - -static void -spx_setpersist(struct spxpcb *cb) -{ - int t = ((cb->s_srtt >> 2) + cb->s_rttvar) >> 1; - - IPX_LOCK_ASSERT(cb->s_ipxpcb); - - if (cb->s_timer[SPXT_REXMT] && spx_do_persist_panics) - panic("spx_output REXMT"); - - /* - * Start/restart persistance timer. - */ - SPXT_RANGESET(cb->s_timer[SPXT_PERSIST], - t*spx_backoff[cb->s_rxtshift], - SPXTV_PERSMIN, SPXTV_PERSMAX); - if (cb->s_rxtshift < SPX_MAXRXTSHIFT) - cb->s_rxtshift++; -} - -int -spx_ctloutput(struct socket *so, struct sockopt *sopt) -{ - struct spxhdr spxhdr; - struct ipxpcb *ipxp; - struct spxpcb *cb; - int mask, error; - short soptval; - u_short usoptval; - int optval; - - ipxp = sotoipxpcb(so); - KASSERT(ipxp != NULL, ("spx_ctloutput: ipxp == NULL")); - - /* - * This will have to be changed when we do more general stacking of - * protocols. - */ - if (sopt->sopt_level != IPXPROTO_SPX) - return (ipx_ctloutput(so, sopt)); - - IPX_LOCK(ipxp); - if (ipxp->ipxp_flags & IPXP_DROPPED) { - IPX_UNLOCK(ipxp); - return (ECONNRESET); - } - - IPX_LOCK(ipxp); - cb = ipxtospxpcb(ipxp); - KASSERT(cb != NULL, ("spx_ctloutput: cb == NULL")); - - error = 0; - switch (sopt->sopt_dir) { - case SOPT_GET: - switch (sopt->sopt_name) { - case SO_HEADERS_ON_INPUT: - mask = SF_HI; - goto get_flags; - - case SO_HEADERS_ON_OUTPUT: - mask = SF_HO; - get_flags: - soptval = cb->s_flags & mask; - IPX_UNLOCK(ipxp); - error = sooptcopyout(sopt, &soptval, - sizeof(soptval)); - break; - - case SO_MTU: - usoptval = cb->s_mtu; - IPX_UNLOCK(ipxp); - error = sooptcopyout(sopt, &usoptval, - sizeof(usoptval)); - break; - - case SO_LAST_HEADER: - spxhdr = cb->s_rhdr; - IPX_UNLOCK(ipxp); - error = sooptcopyout(sopt, &spxhdr, sizeof(spxhdr)); - break; - - case SO_DEFAULT_HEADERS: - spxhdr = cb->s_shdr; - IPX_UNLOCK(ipxp); - error = sooptcopyout(sopt, &spxhdr, sizeof(spxhdr)); - break; - - default: - IPX_UNLOCK(ipxp); - error = ENOPROTOOPT; - } - break; - - case SOPT_SET: - /* - * XXX Why are these shorts on get and ints on set? That - * doesn't make any sense... - * - * XXXRW: Note, when we re-acquire the ipxp lock, we should - * re-check that it's not dropped. - */ - IPX_UNLOCK(ipxp); - switch (sopt->sopt_name) { - case SO_HEADERS_ON_INPUT: - mask = SF_HI; - goto set_head; - - case SO_HEADERS_ON_OUTPUT: - mask = SF_HO; - set_head: - error = sooptcopyin(sopt, &optval, sizeof optval, - sizeof optval); - if (error) - break; - - IPX_LOCK(ipxp); - if (cb->s_flags & SF_PI) { - if (optval) - cb->s_flags |= mask; - else - cb->s_flags &= ~mask; - } else error = EINVAL; - IPX_UNLOCK(ipxp); - break; - - case SO_MTU: - error = sooptcopyin(sopt, &usoptval, sizeof usoptval, - sizeof usoptval); - if (error) - break; - /* Unlocked write. */ - cb->s_mtu = usoptval; - break; - -#ifdef SF_NEWCALL - case SO_NEWCALL: - error = sooptcopyin(sopt, &optval, sizeof optval, - sizeof optval); - if (error) - break; - IPX_LOCK(ipxp); - if (optval) { - cb->s_flags2 |= SF_NEWCALL; - spx_newchecks[5]++; - } else { - cb->s_flags2 &= ~SF_NEWCALL; - spx_newchecks[6]++; - } - IPX_UNLOCK(ipxp); - break; -#endif - - case SO_DEFAULT_HEADERS: - { - struct spxhdr sp; - - error = sooptcopyin(sopt, &sp, sizeof sp, - sizeof sp); - if (error) - break; - IPX_LOCK(ipxp); - cb->s_dt = sp.spx_dt; - cb->s_cc = sp.spx_cc & SPX_EM; - IPX_UNLOCK(ipxp); - } - break; - - default: - error = ENOPROTOOPT; - } - break; - - default: - panic("spx_ctloutput: bad socket option direction"); - } - return (error); -} - -static void -spx_usr_abort(struct socket *so) -{ - struct ipxpcb *ipxp; - struct spxpcb *cb; - - ipxp = sotoipxpcb(so); - KASSERT(ipxp != NULL, ("spx_usr_abort: ipxp == NULL")); - - cb = ipxtospxpcb(ipxp); - KASSERT(cb != NULL, ("spx_usr_abort: cb == NULL")); - - IPX_LIST_LOCK(); - IPX_LOCK(ipxp); - spx_drop(cb, ECONNABORTED); - IPX_UNLOCK(ipxp); - IPX_LIST_UNLOCK(); -} - -/* - * Accept a connection. Essentially all the work is done at higher levels; - * just return the address of the peer, storing through addr. - */ -static int -spx_accept(struct socket *so, struct sockaddr **nam) -{ - struct ipxpcb *ipxp; - struct sockaddr_ipx *sipx, ssipx; - - ipxp = sotoipxpcb(so); - KASSERT(ipxp != NULL, ("spx_accept: ipxp == NULL")); - - sipx = &ssipx; - bzero(sipx, sizeof *sipx); - sipx->sipx_len = sizeof *sipx; - sipx->sipx_family = AF_IPX; - IPX_LOCK(ipxp); - sipx->sipx_addr = ipxp->ipxp_faddr; - IPX_UNLOCK(ipxp); - *nam = sodupsockaddr((struct sockaddr *)sipx, M_WAITOK); - return (0); -} - -static int -spx_attach(struct socket *so, int proto, struct thread *td) -{ - struct ipxpcb *ipxp; - struct spxpcb *cb; - struct mbuf *mm; - struct sockbuf *sb; - int error; - - ipxp = sotoipxpcb(so); - KASSERT(ipxp == NULL, ("spx_attach: ipxp != NULL")); - - if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) { - error = soreserve(so, (u_long) 3072, (u_long) 3072); - if (error) - return (error); - } - - cb = malloc(sizeof *cb, M_PCB, M_NOWAIT | M_ZERO); - if (cb == NULL) - return (ENOBUFS); - mm = m_getclr(M_NOWAIT, MT_DATA); - if (mm == NULL) { - free(cb, M_PCB); - return (ENOBUFS); - } - - IPX_LIST_LOCK(); - error = ipx_pcballoc(so, &ipxpcb_list, td); - if (error) { - IPX_LIST_UNLOCK(); - m_free(mm); - free(cb, M_PCB); - return (error); - } - ipxp = sotoipxpcb(so); - ipxp->ipxp_flags |= IPXP_SPX; - - cb->s_state = TCPS_LISTEN; - cb->s_smax = -1; - cb->s_swl1 = -1; - spx_reass_init(cb); - cb->s_ipxpcb = ipxp; - cb->s_mtu = 576 - sizeof(struct spx); - sb = &so->so_snd; - cb->s_cwnd = sbspace(sb) * CUNIT / cb->s_mtu; - cb->s_ssthresh = cb->s_cwnd; - cb->s_cwmx = sbspace(sb) * CUNIT / (2 * sizeof(struct spx)); - - /* - * Above is recomputed when connecting to account for changed - * buffering or mtu's. - */ - cb->s_rtt = SPXTV_SRTTBASE; - cb->s_rttvar = SPXTV_SRTTDFLT << 2; - SPXT_RANGESET(cb->s_rxtcur, - ((SPXTV_SRTTBASE >> 2) + (SPXTV_SRTTDFLT << 2)) >> 1, - SPXTV_MIN, SPXTV_REXMTMAX); - ipxp->ipxp_pcb = (caddr_t)cb; - IPX_LIST_UNLOCK(); - return (0); -} - -static void -spx_pcbdetach(struct ipxpcb *ipxp) -{ - struct spxpcb *cb; - - IPX_LOCK_ASSERT(ipxp); - - cb = ipxtospxpcb(ipxp); - KASSERT(cb != NULL, ("spx_pcbdetach: cb == NULL")); - - spx_reass_flush(cb); - free(cb, M_PCB); - ipxp->ipxp_pcb = NULL; -} - -static int -spx_bind(struct socket *so, struct sockaddr *nam, struct thread *td) -{ - struct ipxpcb *ipxp; - int error; - - ipxp = sotoipxpcb(so); - KASSERT(ipxp != NULL, ("spx_bind: ipxp == NULL")); - - IPX_LIST_LOCK(); - IPX_LOCK(ipxp); - if (ipxp->ipxp_flags & IPXP_DROPPED) { - error = EINVAL; - goto out; - } - error = ipx_pcbbind(ipxp, nam, td); -out: - IPX_UNLOCK(ipxp); - IPX_LIST_UNLOCK(); - return (error); -} - -static void -spx_usr_close(struct socket *so) -{ - struct ipxpcb *ipxp; - struct spxpcb *cb; - - ipxp = sotoipxpcb(so); - KASSERT(ipxp != NULL, ("spx_usr_close: ipxp == NULL")); - - cb = ipxtospxpcb(ipxp); - KASSERT(cb != NULL, ("spx_usr_close: cb == NULL")); - - IPX_LIST_LOCK(); - IPX_LOCK(ipxp); - if (cb->s_state > TCPS_LISTEN) - spx_disconnect(cb); - else - spx_close(cb); - IPX_UNLOCK(ipxp); - IPX_LIST_UNLOCK(); -} - -/* - * Initiate connection to peer. Enter SYN_SENT state, and mark socket as - * connecting. Start keep-alive timer, setup prototype header, send initial - * system packet requesting connection. - */ -static int -spx_connect(struct socket *so, struct sockaddr *nam, struct thread *td) -{ - struct ipxpcb *ipxp; - struct spxpcb *cb; - int error; - - ipxp = sotoipxpcb(so); - KASSERT(ipxp != NULL, ("spx_connect: ipxp == NULL")); - - cb = ipxtospxpcb(ipxp); - KASSERT(cb != NULL, ("spx_connect: cb == NULL")); - - IPX_LIST_LOCK(); - IPX_LOCK(ipxp); - if (ipxp->ipxp_flags & IPXP_DROPPED) { - error = EINVAL; - goto spx_connect_end; - } - if (ipxp->ipxp_lport == 0) { - error = ipx_pcbbind(ipxp, NULL, td); - if (error) - goto spx_connect_end; - } - error = ipx_pcbconnect(ipxp, nam, td); - if (error) - goto spx_connect_end; - soisconnecting(so); - spxstat.spxs_connattempt++; - cb->s_state = TCPS_SYN_SENT; - cb->s_did = 0; - spx_template(cb); - cb->s_timer[SPXT_KEEP] = SPXTV_KEEP; - cb->s_force = 1 + SPXTV_KEEP; - - /* - * Other party is required to respond to the port I send from, but he - * is not required to answer from where I am sending to, so allow - * wildcarding. Original port I am sending to is still saved in - * cb->s_dport. - */ - ipxp->ipxp_fport = 0; - error = spx_output(cb, NULL); -spx_connect_end: - IPX_UNLOCK(ipxp); - IPX_LIST_UNLOCK(); - return (error); -} - -static void -spx_detach(struct socket *so) -{ - struct ipxpcb *ipxp; - struct spxpcb *cb; - - /* - * XXXRW: Should assert appropriately detached. - */ - ipxp = sotoipxpcb(so); - KASSERT(ipxp != NULL, ("spx_detach: ipxp == NULL")); - - cb = ipxtospxpcb(ipxp); - KASSERT(cb != NULL, ("spx_detach: cb == NULL")); - - IPX_LIST_LOCK(); - IPX_LOCK(ipxp); - spx_pcbdetach(ipxp); - ipx_pcbdetach(ipxp); - ipx_pcbfree(ipxp); - IPX_LIST_UNLOCK(); -} - -/* - * We may decide later to implement connection closing handshaking at the spx - * level optionally. Here is the hook to do it: - */ -static int -spx_usr_disconnect(struct socket *so) -{ - struct ipxpcb *ipxp; - struct spxpcb *cb; - int error; - - ipxp = sotoipxpcb(so); - KASSERT(ipxp != NULL, ("spx_usr_disconnect: ipxp == NULL")); - - cb = ipxtospxpcb(ipxp); - KASSERT(cb != NULL, ("spx_usr_disconnect: cb == NULL")); - - IPX_LIST_LOCK(); - IPX_LOCK(ipxp); - if (ipxp->ipxp_flags & IPXP_DROPPED) { - error = EINVAL; - goto out; - } - spx_disconnect(cb); - error = 0; -out: - IPX_UNLOCK(ipxp); - IPX_LIST_UNLOCK(); - return (error); -} - -static int -spx_listen(struct socket *so, int backlog, struct thread *td) -{ - int error; - struct ipxpcb *ipxp; - struct spxpcb *cb; - - error = 0; - ipxp = sotoipxpcb(so); - KASSERT(ipxp != NULL, ("spx_listen: ipxp == NULL")); - - cb = ipxtospxpcb(ipxp); - KASSERT(cb != NULL, ("spx_listen: cb == NULL")); - - IPX_LIST_LOCK(); - IPX_LOCK(ipxp); - if (ipxp->ipxp_flags & IPXP_DROPPED) { - error = EINVAL; - goto out; - } - SOCK_LOCK(so); - error = solisten_proto_check(so); - if (error == 0 && ipxp->ipxp_lport == 0) - error = ipx_pcbbind(ipxp, NULL, td); - if (error == 0) { - cb->s_state = TCPS_LISTEN; - solisten_proto(so, backlog); - } - SOCK_UNLOCK(so); -out: - IPX_UNLOCK(ipxp); - IPX_LIST_UNLOCK(); - return (error); -} - -/* - * After a receive, possibly send acknowledgment updating allocation. - */ -static int -spx_rcvd(struct socket *so, int flags) -{ - struct ipxpcb *ipxp; - struct spxpcb *cb; - int error; - - ipxp = sotoipxpcb(so); - KASSERT(ipxp != NULL, ("spx_rcvd: ipxp == NULL")); - - cb = ipxtospxpcb(ipxp); - KASSERT(cb != NULL, ("spx_rcvd: cb == NULL")); - - IPX_LOCK(ipxp); - if (ipxp->ipxp_flags & IPXP_DROPPED) { - error = EINVAL; - goto out; - } - cb->s_flags |= SF_RVD; - spx_output(cb, NULL); - cb->s_flags &= ~SF_RVD; - error = 0; -out: - IPX_UNLOCK(ipxp); - return (error); -} - -static int -spx_rcvoob(struct socket *so, struct mbuf *m, int flags) -{ - struct ipxpcb *ipxp; - struct spxpcb *cb; - int error; - - ipxp = sotoipxpcb(so); - KASSERT(ipxp != NULL, ("spx_rcvoob: ipxp == NULL")); - - cb = ipxtospxpcb(ipxp); - KASSERT(cb != NULL, ("spx_rcvoob: cb == NULL")); - - IPX_LOCK(ipxp); - if (ipxp->ipxp_flags & IPXP_DROPPED) { - error = EINVAL; - goto out; - } - SOCKBUF_LOCK(&so->so_rcv); - if ((cb->s_oobflags & SF_IOOB) || so->so_oobmark || - (so->so_rcv.sb_state & SBS_RCVATMARK)) { - SOCKBUF_UNLOCK(&so->so_rcv); - m->m_len = 1; - *mtod(m, caddr_t) = cb->s_iobc; - error = 0; - goto out; - } - SOCKBUF_UNLOCK(&so->so_rcv); - error = EINVAL; -out: - IPX_UNLOCK(ipxp); - return (error); -} - -static int -spx_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr, - struct mbuf *controlp, struct thread *td) -{ - struct ipxpcb *ipxp; - struct spxpcb *cb; - int error; - - ipxp = sotoipxpcb(so); - KASSERT(ipxp != NULL, ("spx_send: ipxp == NULL")); - - cb = ipxtospxpcb(ipxp); - KASSERT(cb != NULL, ("spx_send: cb == NULL")); - - error = 0; - IPX_LOCK(ipxp); - if (ipxp->ipxp_flags & IPXP_DROPPED) { - error = ECONNRESET; - goto spx_send_end; - } - if (flags & PRUS_OOB) { - if (sbspace(&so->so_snd) < -512) { - error = ENOBUFS; - goto spx_send_end; - } - cb->s_oobflags |= SF_SOOB; - } - if (controlp != NULL) { - u_short *p = mtod(controlp, u_short *); - spx_newchecks[2]++; - if ((p[0] == 5) && (p[1] == 1)) { /* XXXX, for testing */ - cb->s_shdr.spx_dt = *(u_char *)(&p[2]); - spx_newchecks[3]++; - } - m_freem(controlp); - } - controlp = NULL; - error = spx_output(cb, m); - m = NULL; -spx_send_end: - IPX_UNLOCK(ipxp); - if (controlp != NULL) - m_freem(controlp); - if (m != NULL) - m_freem(m); - return (error); -} - -static int -spx_shutdown(struct socket *so) -{ - struct ipxpcb *ipxp; - struct spxpcb *cb; - int error; - - ipxp = sotoipxpcb(so); - KASSERT(ipxp != NULL, ("spx_shutdown: ipxp == NULL")); - - cb = ipxtospxpcb(ipxp); - KASSERT(cb != NULL, ("spx_shutdown: cb == NULL")); - - socantsendmore(so); - IPX_LIST_LOCK(); - IPX_LOCK(ipxp); - if (ipxp->ipxp_flags & IPXP_DROPPED) { - error = EINVAL; - goto out; - } - spx_usrclosed(cb); - error = 0; -out: - IPX_UNLOCK(ipxp); - IPX_LIST_UNLOCK(); - return (error); -} - -static int -spx_sp_attach(struct socket *so, int proto, struct thread *td) -{ - struct ipxpcb *ipxp; - struct spxpcb *cb; - int error; - - KASSERT(so->so_pcb == NULL, ("spx_sp_attach: so_pcb != NULL")); - - error = spx_attach(so, proto, td); - if (error) - return (error); - - ipxp = sotoipxpcb(so); - KASSERT(ipxp != NULL, ("spx_sp_attach: ipxp == NULL")); - - cb = ipxtospxpcb(ipxp); - KASSERT(cb != NULL, ("spx_sp_attach: cb == NULL")); - - IPX_LOCK(ipxp); - cb->s_flags |= (SF_HI | SF_HO | SF_PI); - IPX_UNLOCK(ipxp); - return (0); -} - -/* - * Create template to be used to send spx packets on a connection. Called - * after host entry created, fills in a skeletal spx header (choosing - * connection id), minimizing the amount of work necessary when the - * connection is used. - */ -static void -spx_template(struct spxpcb *cb) -{ - struct ipxpcb *ipxp = cb->s_ipxpcb; - struct sockbuf *sb = &(ipxp->ipxp_socket->so_snd); - - IPX_LOCK_ASSERT(ipxp); - - cb->s_ipx.ipx_pt = IPXPROTO_SPX; - cb->s_ipx.ipx_sna = ipxp->ipxp_laddr; - cb->s_ipx.ipx_dna = ipxp->ipxp_faddr; - SPX_LOCK(); - cb->s_sid = htons(spx_iss); - spx_iss += SPX_ISSINCR/2; - SPX_UNLOCK(); - cb->s_alo = 1; - cb->s_cwnd = (sbspace(sb) * CUNIT) / cb->s_mtu; - - /* - * Try to expand fast to full complement of large packets. - */ - cb->s_ssthresh = cb->s_cwnd; - cb->s_cwmx = (sbspace(sb) * CUNIT) / (2 * sizeof(struct spx)); - - /* - * But allow for lots of little packets as well. - */ - cb->s_cwmx = max(cb->s_cwmx, cb->s_cwnd); -} - -/* - * Close a SPIP control block. Wake up any sleepers. We used to free any - * queued packets, but now we defer that until the pcb is discarded. - */ -void -spx_close(struct spxpcb *cb) -{ - struct ipxpcb *ipxp = cb->s_ipxpcb; - struct socket *so = ipxp->ipxp_socket; - - KASSERT(ipxp != NULL, ("spx_close: ipxp == NULL")); - IPX_LIST_LOCK_ASSERT(); - IPX_LOCK_ASSERT(ipxp); - - ipxp->ipxp_flags |= IPXP_DROPPED; - soisdisconnected(so); - spxstat.spxs_closed++; -} - -/* - * Someday we may do level 3 handshaking to close a connection or send a - * xerox style error. For now, just close. cb will always be invalid after - * this call. - */ -static void -spx_usrclosed(struct spxpcb *cb) -{ - - IPX_LIST_LOCK_ASSERT(); - IPX_LOCK_ASSERT(cb->s_ipxpcb); - - spx_close(cb); -} - -/* - * cb will always be invalid after this call. - */ -static void -spx_disconnect(struct spxpcb *cb) -{ - - IPX_LIST_LOCK_ASSERT(); - IPX_LOCK_ASSERT(cb->s_ipxpcb); - - spx_close(cb); -} - -/* - * Drop connection, reporting the specified error. cb will always be invalid - * after this call. - */ -static void -spx_drop(struct spxpcb *cb, int errno) -{ - struct socket *so = cb->s_ipxpcb->ipxp_socket; - - IPX_LIST_LOCK_ASSERT(); - IPX_LOCK_ASSERT(cb->s_ipxpcb); - - /* - * Someday, in the xerox world we will generate error protocol - * packets announcing that the socket has gone away. - */ - if (TCPS_HAVERCVDSYN(cb->s_state)) { - spxstat.spxs_drops++; - cb->s_state = TCPS_CLOSED; - /*tcp_output(cb);*/ - } else - spxstat.spxs_conndrops++; - so->so_error = errno; - spx_close(cb); -} - -/* - * Fast timeout routine for processing delayed acks. - */ -void -spx_fasttimo(void) -{ - struct ipxpcb *ipxp; - struct spxpcb *cb; - - IPX_LIST_LOCK(); - LIST_FOREACH(ipxp, &ipxpcb_list, ipxp_list) { - IPX_LOCK(ipxp); - if (!(ipxp->ipxp_flags & IPXP_SPX) || - (ipxp->ipxp_flags & IPXP_DROPPED)) { - IPX_UNLOCK(ipxp); - continue; - } - cb = ipxtospxpcb(ipxp); - if (cb->s_flags & SF_DELACK) { - cb->s_flags &= ~SF_DELACK; - cb->s_flags |= SF_ACKNOW; - spxstat.spxs_delack++; - spx_output(cb, NULL); - } - IPX_UNLOCK(ipxp); - } - IPX_LIST_UNLOCK(); -} - -/* - * spx protocol timeout routine called every 500 ms. Updates the timers in - * all active pcb's and causes finite state machine actions if timers expire. - */ -void -spx_slowtimo(void) -{ - struct ipxpcb *ipxp; - struct spxpcb *cb; - int i; - - /* - * Search through tcb's and update active timers. Once, timers could - * free ipxp's, but now we do that only when detaching a socket. - */ - IPX_LIST_LOCK(); - LIST_FOREACH(ipxp, &ipxpcb_list, ipxp_list) { - IPX_LOCK(ipxp); - if (!(ipxp->ipxp_flags & IPXP_SPX) || - (ipxp->ipxp_flags & IPXP_DROPPED)) { - IPX_UNLOCK(ipxp); - continue; - } - - cb = (struct spxpcb *)ipxp->ipxp_pcb; - KASSERT(cb != NULL, ("spx_slowtimo: cb == NULL")); - for (i = 0; i < SPXT_NTIMERS; i++) { - if (cb->s_timer[i] && --cb->s_timer[i] == 0) { - spx_timers(cb, i); - if (ipxp->ipxp_flags & IPXP_DROPPED) - break; - } - } - if (!(ipxp->ipxp_flags & IPXP_DROPPED)) { - cb->s_idle++; - if (cb->s_rtt) - cb->s_rtt++; - } - IPX_UNLOCK(ipxp); - } - IPX_LIST_UNLOCK(); - SPX_LOCK(); - spx_iss += SPX_ISSINCR/PR_SLOWHZ; /* increment iss */ - SPX_UNLOCK(); -} - -/* - * SPX timer processing. - */ -static void -spx_timers(struct spxpcb *cb, int timer) -{ - long rexmt; - int win; - - IPX_LIST_LOCK_ASSERT(); - IPX_LOCK_ASSERT(cb->s_ipxpcb); - - cb->s_force = 1 + timer; - switch (timer) { - case SPXT_2MSL: - /* - * 2 MSL timeout in shutdown went off. TCP deletes - * connection control block. - */ - printf("spx: SPXT_2MSL went off for no reason\n"); - cb->s_timer[timer] = 0; - break; - - case SPXT_REXMT: - /* - * Retransmission timer went off. Message has not been acked - * within retransmit interval. Back off to a longer - * retransmit interval and retransmit one packet. - */ - if (++cb->s_rxtshift > SPX_MAXRXTSHIFT) { - cb->s_rxtshift = SPX_MAXRXTSHIFT; - spxstat.spxs_timeoutdrop++; - spx_drop(cb, ETIMEDOUT); - break; - } - spxstat.spxs_rexmttimeo++; - rexmt = ((cb->s_srtt >> 2) + cb->s_rttvar) >> 1; - rexmt *= spx_backoff[cb->s_rxtshift]; - SPXT_RANGESET(cb->s_rxtcur, rexmt, SPXTV_MIN, SPXTV_REXMTMAX); - cb->s_timer[SPXT_REXMT] = cb->s_rxtcur; - - /* - * If we have backed off fairly far, our srtt estimate is - * probably bogus. Clobber it so we'll take the next rtt - * measurement as our srtt; move the current srtt into rttvar - * to keep the current retransmit times until then. - */ - if (cb->s_rxtshift > SPX_MAXRXTSHIFT / 4 ) { - cb->s_rttvar += (cb->s_srtt >> 2); - cb->s_srtt = 0; - } - cb->s_snxt = cb->s_rack; - - /* - * If timing a packet, stop the timer. - */ - cb->s_rtt = 0; - - /* - * See very long discussion in tcp_timer.c about congestion - * window and sstrhesh. - */ - win = min(cb->s_swnd, (cb->s_cwnd/CUNIT)) / 2; - if (win < 2) - win = 2; - cb->s_cwnd = CUNIT; - cb->s_ssthresh = win * CUNIT; - spx_output(cb, NULL); - break; - - case SPXT_PERSIST: - /* - * Persistance timer into zero window. Force a probe to be - * sent. - */ - spxstat.spxs_persisttimeo++; - spx_setpersist(cb); - spx_output(cb, NULL); - break; - - case SPXT_KEEP: - /* - * Keep-alive timer went off; send something or drop - * connection if idle for too long. - */ - spxstat.spxs_keeptimeo++; - if (cb->s_state < TCPS_ESTABLISHED) - goto dropit; - if (cb->s_ipxpcb->ipxp_socket->so_options & SO_KEEPALIVE) { - if (cb->s_idle >= SPXTV_MAXIDLE) - goto dropit; - spxstat.spxs_keepprobe++; - spx_output(cb, NULL); - } else - cb->s_idle = 0; - cb->s_timer[SPXT_KEEP] = SPXTV_KEEP; - break; - - dropit: - spxstat.spxs_keepdrops++; - spx_drop(cb, ETIMEDOUT); - break; - - default: - panic("spx_timers: unknown timer %d", timer); - } -} diff --git a/sys/netipx/spx_var.h b/sys/netipx/spx_var.h deleted file mode 100644 index 96939f9..0000000 --- a/sys/netipx/spx_var.h +++ /dev/null @@ -1,160 +0,0 @@ -/*- - * 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. - * 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. - * - * Copyright (c) 1995, Mike Mitchell - * - * 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 - * - * $FreeBSD$ - */ - -#ifndef _NETIPX_SPX_VAR_H_ -#define _NETIPX_SPX_VAR_H_ - -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; -}; - -#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) - -#ifdef _KERNEL -/* Following was struct spxstat spxstat; */ -#ifndef spxstat -#define spxstat spx_istat.newstats -#endif -extern struct spx_istat spx_istat; -extern u_short spx_newchecks[50]; - -int spx_output(struct spxpcb *cb, struct mbuf *m0); -int spx_reass(struct spxpcb *cb, struct mbuf *msi, struct spx *si); -void spx_reass_flush(struct spxpcb *cb); -void spx_reass_init(struct spxpcb *cb); -#endif - -#endif /* !_NETIPX_SPX_VAR_H_ */ |