summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/netipx/ipx.h11
-rw-r--r--sys/netipx/ipx_proto.c32
-rw-r--r--sys/netipx/ipx_usrreq.c355
-rw-r--r--sys/netipx/spx.h9
-rw-r--r--sys/netipx/spx_usrreq.c572
5 files changed, 565 insertions, 414 deletions
diff --git a/sys/netipx/ipx.h b/sys/netipx/ipx.h
index c309c54..db04b80 100644
--- a/sys/netipx/ipx.h
+++ b/sys/netipx/ipx.h
@@ -33,7 +33,7 @@
*
* @(#)ipx.h
*
- * $Id$
+ * $Id: ipx.h,v 1.9 1997/02/22 09:41:52 peter Exp $
*/
#ifndef _NETIPX_IPX_H_
@@ -158,6 +158,8 @@ struct ipx {
#ifdef KERNEL
+extern struct pr_usrreqs ipx_usrreqs;
+extern struct pr_usrreqs ripx_usrreqs;
extern int ipxcksum;
extern struct domain ipxdomain;
extern struct sockaddr_ipx ipx_netmask;
@@ -191,13 +193,12 @@ void ipx_input __P((struct mbuf *m, struct ipxpcb *ipxp));
void ipxintr __P((void));
int ipx_output __P((struct ipxpcb *ipxp, struct mbuf *m0));
int ipx_outputfl __P((struct mbuf *m0, struct route *ro, int flags));
-int ipx_raw_usrreq __P((struct socket *so, int req, struct mbuf *m,
- struct mbuf *nam, struct mbuf *control));
void ipx_undo_route __P((struct route *ro));
-int ipx_usrreq __P((struct socket *so, int req, struct mbuf *m,
- struct mbuf *nam, struct mbuf *control));
void ipx_watch_output __P((struct mbuf *m, struct ifnet *ifp));
+int ipx_peeraddr __P((struct socket *so, struct mbuf *nam));
+int ipx_sockaddr __P((struct socket *so, struct mbuf *nam));
+
#else
#include <sys/cdefs.h>
diff --git a/sys/netipx/ipx_proto.c b/sys/netipx/ipx_proto.c
index bb3a850..110135e 100644
--- a/sys/netipx/ipx_proto.c
+++ b/sys/netipx/ipx_proto.c
@@ -33,7 +33,7 @@
*
* @(#)ipx_proto.c
*
- * $Id$
+ * $Id: ipx_proto.c,v 1.7 1997/02/22 09:41:56 peter Exp $
*/
#include <sys/param.h>
@@ -57,39 +57,45 @@ struct protosw ipxsw[] = {
{ 0, &ipxdomain, 0, 0,
0, 0, 0, 0,
0,
- ipx_init, 0, 0, 0
+ ipx_init, 0, 0, 0,
},
{ SOCK_DGRAM, &ipxdomain, 0, PR_ATOMIC|PR_ADDR,
0, 0, ipx_ctlinput, ipx_ctloutput,
- ipx_usrreq,
- 0, 0, 0, 0
+ 0,
+ 0, 0, 0, 0,
+ &ipx_usrreqs
},
{ SOCK_STREAM, &ipxdomain, IPXPROTO_SPX, PR_CONNREQUIRED|PR_WANTRCVD,
0, 0, spx_ctlinput, spx_ctloutput,
- spx_usrreq,
- spx_init, spx_fasttimo, spx_slowtimo, 0
+ 0,
+ spx_init, spx_fasttimo, spx_slowtimo, 0,
+ &spx_usrreqs
},
{ SOCK_SEQPACKET,&ipxdomain, IPXPROTO_SPX, PR_CONNREQUIRED|PR_WANTRCVD|PR_ATOMIC,
0, 0, spx_ctlinput, spx_ctloutput,
- spx_usrreq_sp,
- 0, 0, 0, 0
+ 0,
+ 0, 0, 0, 0,
+ &spx_usrreq_sps
},
{ SOCK_RAW, &ipxdomain, IPXPROTO_RAW, PR_ATOMIC|PR_ADDR,
0, 0, 0, ipx_ctloutput,
- ipx_raw_usrreq,
- 0, 0, 0, 0
+ 0,
+ 0, 0, 0, 0,
+ &ripx_usrreqs
},
{ SOCK_RAW, &ipxdomain, IPXPROTO_ERROR, PR_ATOMIC|PR_ADDR,
0, 0, 0, ipx_ctloutput,
- ipx_raw_usrreq,
- 0, 0, 0, 0
+ 0,
+ 0, 0, 0, 0,
+ &ripx_usrreqs
},
#ifdef IPTUNNEL
#if 0
{ SOCK_RAW, &ipxdomain, IPPROTO_IPX, PR_ATOMIC|PR_ADDR,
iptun_input, rip_output, iptun_ctlinput, 0,
- rip_usrreq,
+ 0,
0, 0, 0, 0,
+ &rip_usrreqs
},
#endif
#endif
diff --git a/sys/netipx/ipx_usrreq.c b/sys/netipx/ipx_usrreq.c
index e0ff42a..f6fbaaa 100644
--- a/sys/netipx/ipx_usrreq.c
+++ b/sys/netipx/ipx_usrreq.c
@@ -33,7 +33,7 @@
*
* @(#)ipx_usrreq.c
*
- * $Id$
+ * $Id: ipx_usrreq.c,v 1.11 1997/02/22 09:41:57 peter Exp $
*/
#include <sys/param.h>
@@ -74,6 +74,33 @@ int ipxrecvspace = IPXRCVQ;
SYSCTL_INT(_net_ipx_ipx, OID_AUTO, ipxrecvspace, CTLFLAG_RW,
&ipxrecvspace, 0, "");
+static int ipx_usr_abort(struct socket *so);
+static int ipx_attach(struct socket *so, int proto);
+static int ipx_bind(struct socket *so, struct mbuf *nam);
+static int ipx_connect(struct socket *so, struct mbuf *nam);
+static int 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 mbuf *addr, struct mbuf *control);
+static int ipx_shutdown(struct socket *so);
+static int ripx_attach(struct socket *so, int proto);
+
+struct pr_usrreqs ipx_usrreqs = {
+ ipx_usr_abort, pru_accept_notsupp, ipx_attach, ipx_bind,
+ ipx_connect, pru_connect2_notsupp, ipx_control, ipx_detach,
+ ipx_disconnect, pru_listen_notsupp, ipx_peeraddr, pru_rcvd_notsupp,
+ pru_rcvoob_notsupp, ipx_send, pru_sense_null, ipx_shutdown,
+ ipx_sockaddr
+};
+
+struct pr_usrreqs ripx_usrreqs = {
+ ipx_usr_abort, pru_accept_notsupp, ripx_attach, ipx_bind,
+ ipx_connect, pru_connect2_notsupp, ipx_control, ipx_detach,
+ ipx_disconnect, pru_listen_notsupp, ipx_peeraddr, pru_rcvd_notsupp,
+ pru_rcvoob_notsupp, ipx_send, pru_sense_null, ipx_shutdown,
+ ipx_sockaddr
+};
+
/*
* This may also be called for raw listeners.
*/
@@ -399,202 +426,200 @@ ipx_ctloutput(req, so, level, name, value)
return (error);
}
-/*ARGSUSED*/
-int
-ipx_usrreq(so, req, m, nam, control)
+static int
+ipx_usr_abort(so)
struct socket *so;
- int req;
- struct mbuf *m, *nam, *control;
{
+ int s;
struct ipxpcb *ipxp = sotoipxpcb(so);
- int error = 0;
-
- if (req == PRU_CONTROL)
- return (ipx_control(so, (int)m, (caddr_t)nam,
- (struct ifnet *)control));
- if (control && control->m_len) {
- error = EINVAL;
- goto release;
- }
- if (ipxp == NULL && req != PRU_ATTACH) {
- error = EINVAL;
- goto release;
- }
- switch (req) {
- case PRU_ATTACH:
- if (ipxp != NULL) {
- error = EINVAL;
- break;
- }
- error = ipx_pcballoc(so, &ipxpcb);
- if (error)
- break;
- error = soreserve(so, ipxsendspace, ipxrecvspace);
- if (error)
- break;
- break;
+ s = splnet();
+ ipx_pcbdetach(ipxp);
+ splx(s);
+ sofree(so);
+ soisdisconnected(so);
+ return (0);
+}
- case PRU_DETACH:
- if (ipxp == NULL) {
- error = ENOTCONN;
- break;
- }
- ipx_pcbdetach(ipxp);
- break;
+static int
+ipx_attach(so, proto)
+ struct socket *so;
+ int proto;
+{
+ int error;
+ int s;
+ struct ipxpcb *ipxp = sotoipxpcb(so);
- case PRU_BIND:
- error = ipx_pcbbind(ipxp, nam);
- break;
+ if (ipxp != NULL)
+ return (EINVAL);
+ s = splnet();
+ error = ipx_pcballoc(so, &ipxpcb);
+ splx(s);
+ if (error == 0)
+ error = soreserve(so, ipxsendspace, ipxrecvspace);
+ return (error);
+}
- case PRU_LISTEN:
- error = EOPNOTSUPP;
- break;
+static int
+ipx_bind(so, nam)
+ struct socket *so;
+ struct mbuf *nam;
+{
+ struct ipxpcb *ipxp = sotoipxpcb(so);
- case PRU_CONNECT:
- if (!ipx_nullhost(ipxp->ipxp_faddr)) {
- error = EISCONN;
- break;
- }
- error = ipx_pcbconnect(ipxp, nam);
- if (error == 0)
- soisconnected(so);
- break;
+ return (ipx_pcbbind(ipxp, nam));
+}
- case PRU_CONNECT2:
- error = EOPNOTSUPP;
- break;
+static int
+ipx_connect(so, nam)
+ struct socket *so;
+ struct mbuf *nam;
+{
+ int error;
+ int s;
+ struct ipxpcb *ipxp = sotoipxpcb(so);
- case PRU_ACCEPT:
- error = EOPNOTSUPP;
- break;
+ if (!ipx_nullhost(ipxp->ipxp_faddr))
+ return (EISCONN);
+ s = splnet();
+ error = ipx_pcbconnect(ipxp, nam);
+ splx(s);
+ if (error == 0)
+ soisconnected(so);
+ return (error);
+}
- case PRU_DISCONNECT:
- if (ipx_nullhost(ipxp->ipxp_faddr)) {
- error = ENOTCONN;
- break;
- }
- ipx_pcbdisconnect(ipxp);
- soisdisconnected(so);
- break;
+static int
+ipx_detach(so)
+ struct socket *so;
+{
+ int s;
+ struct ipxpcb *ipxp = sotoipxpcb(so);
- case PRU_SHUTDOWN:
- socantsendmore(so);
- break;
+ if (ipxp == NULL)
+ return (ENOTCONN);
+ s = splnet();
+ ipx_pcbdetach(ipxp);
+ splx(s);
+ return (0);
+}
- case PRU_SEND:
- {
- struct ipx_addr laddr;
- int s = 0;
+static int
+ipx_disconnect(so)
+ struct socket *so;
+{
+ int s;
+ struct ipxpcb *ipxp = sotoipxpcb(so);
- if (nam) {
- laddr = ipxp->ipxp_laddr;
- if (!ipx_nullhost(ipxp->ipxp_faddr)) {
- error = EISCONN;
- break;
- }
- /*
- * Must block input while temporarily connected.
- */
- s = splnet();
- error = ipx_pcbconnect(ipxp, nam);
- if (error) {
- splx(s);
- break;
- }
- } else {
- if (ipx_nullhost(ipxp->ipxp_faddr)) {
- error = ENOTCONN;
- break;
- }
- }
- error = ipx_output(ipxp, m);
- m = NULL;
- if (nam) {
- ipx_pcbdisconnect(ipxp);
- splx(s);
- ipxp->ipxp_laddr.x_host = laddr.x_host;
- ipxp->ipxp_laddr.x_port = laddr.x_port;
- }
- }
- break;
+ if (ipx_nullhost(ipxp->ipxp_faddr))
+ return (ENOTCONN);
+ s = splnet();
+ ipx_pcbdisconnect(ipxp);
+ splx(s);
+ soisdisconnected(so);
+ return (0);
+}
- case PRU_ABORT:
- ipx_pcbdetach(ipxp);
- sofree(so);
- soisdisconnected(so);
- break;
+int
+ipx_peeraddr(so, nam)
+ struct socket *so;
+ struct mbuf *nam;
+{
+ struct ipxpcb *ipxp = sotoipxpcb(so);
- case PRU_SOCKADDR:
- ipx_setsockaddr(ipxp, nam);
- break;
+ ipx_setpeeraddr(ipxp, nam);
+ return (0);
+}
- case PRU_PEERADDR:
- ipx_setpeeraddr(ipxp, nam);
- break;
+static int
+ipx_send(so, flags, m, nam, control)
+ struct socket *so;
+ int flags;
+ struct mbuf *m;
+ struct mbuf *nam;
+ struct mbuf *control;
+{
+ int error;
+ struct ipxpcb *ipxp = sotoipxpcb(so);
+ struct ipx_addr laddr;
+ int s = 0;
- case PRU_SENSE:
+ if (nam) {
+ laddr = ipxp->ipxp_laddr;
+ if (!ipx_nullhost(ipxp->ipxp_faddr)) {
+ error = EISCONN;
+ goto send_release;
+ }
/*
- * stat: don't bother with a blocksize.
+ * Must block input while temporarily connected.
*/
- return (0);
-
- case PRU_SENDOOB:
- case PRU_FASTTIMO:
- case PRU_SLOWTIMO:
- case PRU_PROTORCV:
- case PRU_PROTOSEND:
- error = EOPNOTSUPP;
- break;
-
- case PRU_CONTROL:
- case PRU_RCVD:
- case PRU_RCVOOB:
- return (EOPNOTSUPP); /* do not free mbuf's */
-
- default:
- panic("ipx_usrreq");
+ s = splnet();
+ error = ipx_pcbconnect(ipxp, nam);
+ if (error) {
+ splx(s);
+ goto send_release;
+ }
+ } else {
+ if (ipx_nullhost(ipxp->ipxp_faddr)) {
+ error = ENOTCONN;
+ goto send_release;
+ }
+ }
+ error = ipx_output(ipxp, m);
+ m = NULL;
+ if (nam) {
+ ipx_pcbdisconnect(ipxp);
+ splx(s);
+ ipxp->ipxp_laddr.x_host = laddr.x_host;
+ ipxp->ipxp_laddr.x_port = laddr.x_port;
}
-release:
- if (control != NULL)
- m_freem(control);
+
+send_release:
if (m != NULL)
m_freem(m);
return (error);
}
-/*ARGSUSED*/
+static int
+ipx_shutdown(so)
+ struct socket *so;
+{
+ socantsendmore(so);
+ return (0);
+}
+
int
-ipx_raw_usrreq(so, req, m, nam, control)
+ipx_sockaddr(so, nam)
struct socket *so;
- int req;
- struct mbuf *m, *nam, *control;
+ struct mbuf *nam;
{
- int error = 0;
struct ipxpcb *ipxp = sotoipxpcb(so);
- /*extern struct ipxpcb ipxrawpcb;*//*XXX*//*JRE*/
- switch (req) {
+ ipx_setsockaddr(ipxp, nam);
+ return (0);
+}
- case PRU_ATTACH:
+static int
+ripx_attach(so, proto)
+ struct socket *so;
+ int proto;
+{
+ int error = 0;
+ int s;
+ struct ipxpcb *ipxp = sotoipxpcb(so);
- if (!(so->so_state & SS_PRIV) || (ipxp != NULL)) {
- error = EINVAL;
- break;
- }
- error = ipx_pcballoc(so, &ipxrawpcb);
- if (error)
- break;
- error = soreserve(so, ipxsendspace, ipxrecvspace);
- if (error)
- break;
- ipxp = sotoipxpcb(so);
- ipxp->ipxp_faddr.x_host = ipx_broadhost;
- ipxp->ipxp_flags = IPXP_RAWIN | IPXP_RAWOUT;
- break;
- default:
- error = ipx_usrreq(so, req, m, nam, control);
- }
+ if (!(so->so_state & SS_PRIV) || (ipxp != NULL))
+ return (EINVAL);
+ s = splnet();
+ error = ipx_pcballoc(so, &ipxrawpcb);
+ splx(s);
+ if (error)
+ return (error);
+ error = soreserve(so, ipxsendspace, ipxrecvspace);
+ if (error)
+ return (error);
+ ipxp = sotoipxpcb(so);
+ ipxp->ipxp_faddr.x_host = ipx_broadhost;
+ ipxp->ipxp_flags = IPXP_RAWIN | IPXP_RAWOUT;
return (error);
}
-
diff --git a/sys/netipx/spx.h b/sys/netipx/spx.h
index b3e8e9b..da3e70f 100644
--- a/sys/netipx/spx.h
+++ b/sys/netipx/spx.h
@@ -33,7 +33,7 @@
*
* @(#)spx.h
*
- * $Id$
+ * $Id: spx.h,v 1.9 1997/02/22 09:41:58 peter Exp $
*/
#ifndef _NETIPX_SPX_H_
@@ -169,6 +169,9 @@ struct spxpcb {
#ifdef KERNEL
+extern struct pr_usrreqs spx_usrreqs;
+extern struct pr_usrreqs spx_usrreq_sps;
+
void spx_abort __P((struct ipxpcb *ipxp));
struct spxpcb *
spx_close __P((struct spxpcb *cb));
@@ -192,10 +195,6 @@ struct spxpcb *
spx_timers __P((struct spxpcb *cb, int timer));
struct spxpcb *
spx_usrclosed __P((struct spxpcb *cb));
-int spx_usrreq __P((struct socket *so, int req, struct mbuf *m,
- struct mbuf *nam, struct mbuf *controlp));
-int spx_usrreq_sp __P((struct socket *so, int req, struct mbuf *m,
- struct mbuf *nam, struct mbuf *controlp));
#endif /* KERNEL */
diff --git a/sys/netipx/spx_usrreq.c b/sys/netipx/spx_usrreq.c
index 555d45d..bb62f51 100644
--- a/sys/netipx/spx_usrreq.c
+++ b/sys/netipx/spx_usrreq.c
@@ -33,7 +33,7 @@
*
* @(#)spx_usrreq.h
*
- * $Id$
+ * $Id: spx_usrreq.c,v 1.10 1997/02/22 09:42:00 peter Exp $
*/
#include <sys/param.h>
@@ -72,6 +72,37 @@ u_short spx_newchecks[50];
struct spx_istat spx_istat;
u_short spx_iss;
+static int spx_usr_abort(struct socket *so);
+static int spx_accept(struct socket *so, struct mbuf *nam);
+static int spx_attach(struct socket *so, int proto);
+static int spx_bind(struct socket *so, struct mbuf *nam);
+static int spx_connect(struct socket *so, struct mbuf *nam);
+static int spx_detach(struct socket *so);
+static int spx_usr_disconnect(struct socket *so);
+static int spx_listen(struct socket *so);
+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 mbuf *addr, struct mbuf *control);
+static int spx_shutdown(struct socket *so);
+static int spx_sp_attach(struct socket *so, int proto);
+
+struct pr_usrreqs spx_usrreqs = {
+ spx_usr_abort, spx_accept, spx_attach, spx_bind,
+ spx_connect, pru_connect2_notsupp, ipx_control, spx_detach,
+ spx_usr_disconnect, spx_listen, ipx_peeraddr, spx_rcvd,
+ spx_rcvoob, spx_send, pru_sense_null, spx_shutdown,
+ ipx_sockaddr
+};
+
+struct pr_usrreqs spx_usrreq_sps = {
+ spx_usr_abort, spx_accept, spx_sp_attach, spx_bind,
+ spx_connect, pru_connect2_notsupp, ipx_control, spx_detach,
+ spx_usr_disconnect, spx_listen, ipx_peeraddr, spx_rcvd,
+ spx_rcvoob, spx_send, pru_sense_null, spx_shutdown,
+ ipx_sockaddr
+};
+
void
spx_init()
{
@@ -1266,252 +1297,319 @@ spx_ctloutput(req, so, level, name, value)
return (error);
}
-/*ARGSUSED*/
-int
-spx_usrreq(so, req, m, nam, controlp)
+static int
+spx_usr_abort(so)
struct socket *so;
- int req;
- struct mbuf *m, *nam, *controlp;
{
- struct ipxpcb *ipxp = sotoipxpcb(so);
- register struct spxpcb *cb = NULL;
- int s = splnet();
- int error = 0, ostate;
- struct mbuf *mm;
- register struct sockbuf *sb;
+ int s;
+ struct ipxpcb *ipxp;
+ struct spxpcb *cb;
- if (req == PRU_CONTROL)
- return (ipx_control(so, (int)m, (caddr_t)nam,
- (struct ifnet *)controlp));
- if (ipxp == NULL) {
- if (req != PRU_ATTACH) {
- error = EINVAL;
- goto release;
- }
- } else
- cb = ipxtospxpcb(ipxp);
+ ipxp = sotoipxpcb(so);
+ cb = ipxtospxpcb(ipxp);
- ostate = cb ? cb->s_state : 0;
+ s = splnet();
+ spx_drop(cb, ECONNABORTED);
+ splx(s);
+ return (0);
+}
- switch (req) {
+/*
+ * 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(so, nam)
+ struct socket *so;
+ struct mbuf *nam;
+{
+ struct ipxpcb *ipxp;
+ struct sockaddr_ipx *sipx;
- case PRU_ATTACH:
- if (ipxp != NULL) {
- error = EISCONN;
- break;
- }
- error = ipx_pcballoc(so, &ipxpcb);
+ ipxp = sotoipxpcb(so);
+ sipx = mtod(nam, struct sockaddr_ipx *);
+
+ nam->m_len = sizeof (struct sockaddr_ipx);
+ sipx->sipx_family = AF_IPX;
+ sipx->sipx_addr = ipxp->ipxp_faddr;
+ return (0);
+}
+
+static int
+spx_attach(so, proto)
+ struct socket *so;
+ int proto;
+{
+ int error;
+ int s;
+ struct ipxpcb *ipxp;
+ struct spxpcb *cb;
+ struct mbuf *mm;
+ struct sockbuf *sb;
+
+ ipxp = sotoipxpcb(so);
+ cb = ipxtospxpcb(ipxp);
+
+ if (ipxp != NULL)
+ return (EISCONN);
+ s = splnet();
+ error = ipx_pcballoc(so, &ipxpcb);
+ if (error)
+ goto spx_attach_end;
+ if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) {
+ error = soreserve(so, (u_long) 3072, (u_long) 3072);
if (error)
- break;
- if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) {
- error = soreserve(so, (u_long) 3072, (u_long) 3072);
- if (error)
- break;
- }
- ipxp = sotoipxpcb(so);
+ goto spx_attach_end;
+ }
+ ipxp = sotoipxpcb(so);
- mm = m_getclr(M_DONTWAIT, MT_PCB);
- sb = &so->so_snd;
+ mm = m_getclr(M_DONTWAIT, MT_PCB);
+ sb = &so->so_snd;
- if (mm == NULL) {
- error = ENOBUFS;
- break;
- }
- cb = mtod(mm, struct spxpcb *);
- mm = m_getclr(M_DONTWAIT, MT_HEADER);
- if (mm == NULL) {
- (void) m_free(dtom(m));
- error = ENOBUFS;
- break;
- }
- cb->s_ipx = mtod(mm, struct ipx *);
- cb->s_state = TCPS_LISTEN;
- cb->s_smax = -1;
- cb->s_swl1 = -1;
- cb->s_q.si_next = cb->s_q.si_prev = &cb->s_q;
- cb->s_ipxpcb = ipxp;
- cb->s_mtu = 576 - sizeof (struct spx);
- 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;
- break;
+ if (mm == NULL) {
+ error = ENOBUFS;
+ goto spx_attach_end;
+ }
+ cb = mtod(mm, struct spxpcb *);
+ mm = m_getclr(M_DONTWAIT, MT_HEADER);
+ if (mm == NULL) {
+ m_freem(dtom(cb));
+ error = ENOBUFS;
+ goto spx_attach_end;
+ }
+ cb->s_ipx = mtod(mm, struct ipx *);
+ cb->s_state = TCPS_LISTEN;
+ cb->s_smax = -1;
+ cb->s_swl1 = -1;
+ cb->s_q.si_next = cb->s_q.si_prev = &cb->s_q;
+ cb->s_ipxpcb = ipxp;
+ cb->s_mtu = 576 - sizeof (struct spx);
+ 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;
+spx_attach_end:
+ splx(s);
+ return (error);
+}
- case PRU_DETACH:
- if (ipxp == NULL) {
- error = ENOTCONN;
- break;
- }
- if (cb->s_state > TCPS_LISTEN)
- cb = spx_disconnect(cb);
- else
- cb = spx_close(cb);
- break;
+static int
+spx_bind(so, nam)
+ struct socket *so;
+ struct mbuf *nam;
+{
+ struct ipxpcb *ipxp;
- case PRU_BIND:
- error = ipx_pcbbind(ipxp, nam);
- break;
+ ipxp = sotoipxpcb(so);
- case PRU_LISTEN:
- if (ipxp->ipxp_lport == 0)
- error = ipx_pcbbind(ipxp, (struct mbuf *)0);
- if (error == 0)
- cb->s_state = TCPS_LISTEN;
- break;
+ return (ipx_pcbbind(ipxp, nam));
+}
+
+/*
+ * 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(so, nam)
+ struct socket *so;
+ struct mbuf *nam;
+{
+ int error;
+ int s;
+ struct ipxpcb *ipxp;
+ struct spxpcb *cb;
+
+ ipxp = sotoipxpcb(so);
+ cb = ipxtospxpcb(ipxp);
+ s = splnet();
+ if (ipxp->ipxp_lport == 0) {
+ error = ipx_pcbbind(ipxp, (struct mbuf *)0);
+ if (error)
+ goto spx_connect_end;
+ }
+ error = ipx_pcbconnect(ipxp, nam);
+ 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;
/*
- * 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.
+ * 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.
*/
- case PRU_CONNECT:
- if (ipxp->ipxp_lport == 0) {
- error = ipx_pcbbind(ipxp, (struct mbuf *)0);
- if (error)
- break;
- }
- error = ipx_pcbconnect(ipxp, nam);
- if (error)
- break;
- 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, (struct mbuf *) 0);
- break;
+ ipxp->ipxp_fport = 0;
+ error = spx_output(cb, (struct mbuf *) 0);
+spx_connect_end:
+ splx(s);
+ return (error);
+}
- case PRU_CONNECT2:
- error = EOPNOTSUPP;
- break;
+static int
+spx_detach(so)
+ struct socket *so;
+{
+ int s;
+ struct ipxpcb *ipxp;
+ struct spxpcb *cb;
- /*
- * We may decide later to implement connection closing
- * handshaking at the spx level optionally.
- * here is the hook to do it:
- */
- case PRU_DISCONNECT:
- cb = spx_disconnect(cb);
- break;
+ ipxp = sotoipxpcb(so);
+ cb = ipxtospxpcb(ipxp);
- /*
- * Accept a connection. Essentially all the work is
- * done at higher levels; just return the address
- * of the peer, storing through addr.
- */
- case PRU_ACCEPT: {
- struct sockaddr_ipx *sipx = mtod(nam, struct sockaddr_ipx *);
+ if (ipxp == NULL)
+ return (ENOTCONN);
+ s = splnet();
+ if (cb->s_state > TCPS_LISTEN)
+ spx_disconnect(cb);
+ else
+ spx_close(cb);
+ splx(s);
+ return (0);
+}
- nam->m_len = sizeof (struct sockaddr_ipx);
- sipx->sipx_family = AF_IPX;
- sipx->sipx_addr = ipxp->ipxp_faddr;
- break;
- }
+/*
+ * 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(so)
+ struct socket *so;
+{
+ int s;
+ struct ipxpcb *ipxp;
+ struct spxpcb *cb;
- case PRU_SHUTDOWN:
- socantsendmore(so);
- cb = spx_usrclosed(cb);
- if (cb)
- error = spx_output(cb, (struct mbuf *) 0);
- break;
+ ipxp = sotoipxpcb(so);
+ cb = ipxtospxpcb(ipxp);
- /*
- * After a receive, possibly send acknowledgment
- * updating allocation.
- */
- case PRU_RCVD:
- cb->s_flags |= SF_RVD;
- (void) spx_output(cb, (struct mbuf *) 0);
- cb->s_flags &= ~SF_RVD;
- break;
+ s = splnet();
+ spx_disconnect(cb);
+ splx(s);
+ return (0);
+}
- case PRU_ABORT:
- (void) spx_drop(cb, ECONNABORTED);
- break;
+static int
+spx_listen(so)
+ struct socket *so;
+{
+ int error;
+ struct ipxpcb *ipxp;
+ struct spxpcb *cb;
- case PRU_SENSE:
- case PRU_CONTROL:
- m = NULL;
- error = EOPNOTSUPP;
- break;
+ error = 0;
+ ipxp = sotoipxpcb(so);
+ cb = ipxtospxpcb(ipxp);
- case PRU_RCVOOB:
- if ((cb->s_oobflags & SF_IOOB) || so->so_oobmark ||
- (so->so_state & SS_RCVATMARK)) {
- m->m_len = 1;
- *mtod(m, caddr_t) = cb->s_iobc;
- break;
- }
- error = EINVAL;
- break;
+ if (ipxp->ipxp_lport == 0)
+ error = ipx_pcbbind(ipxp, (struct mbuf *)0);
+ if (error == 0)
+ cb->s_state = TCPS_LISTEN;
+ return (error);
+}
- case PRU_SENDOOB:
- if (sbspace(&so->so_snd) < -512) {
- error = ENOBUFS;
- break;
- }
- cb->s_oobflags |= SF_SOOB;
- /* fall into */
- case PRU_SEND:
- if (controlp) {
- 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;
- break;
+/*
+ * After a receive, possibly send acknowledgment
+ * updating allocation.
+ */
+static int
+spx_rcvd(so, flags)
+ struct socket *so;
+ int flags;
+{
+ int s;
+ struct ipxpcb *ipxp;
+ struct spxpcb *cb;
- case PRU_SOCKADDR:
- ipx_setsockaddr(ipxp, nam);
- break;
+ ipxp = sotoipxpcb(so);
+ cb = ipxtospxpcb(ipxp);
- case PRU_PEERADDR:
- ipx_setpeeraddr(ipxp, nam);
- break;
+ s = splnet();
+ cb->s_flags |= SF_RVD;
+ spx_output(cb, (struct mbuf *) 0);
+ cb->s_flags &= ~SF_RVD;
+ splx(s);
+ return (0);
+}
- case PRU_SLOWTIMO:
- cb = spx_timers(cb, (int)nam);
- req |= ((int)nam) << 8;
- break;
+static int
+spx_rcvoob(so, m, flags)
+ struct socket *so;
+ struct mbuf *m;
+ int flags;
+{
+ struct ipxpcb *ipxp;
+ struct spxpcb *cb;
- case PRU_FASTTIMO:
- case PRU_PROTORCV:
- case PRU_PROTOSEND:
- error = EOPNOTSUPP;
- break;
+ ipxp = sotoipxpcb(so);
+ cb = ipxtospxpcb(ipxp);
- default:
- panic("spx_usrreq");
+ if ((cb->s_oobflags & SF_IOOB) || so->so_oobmark ||
+ (so->so_state & SS_RCVATMARK)) {
+ m->m_len = 1;
+ *mtod(m, caddr_t) = cb->s_iobc;
+ return (0);
}
- if (cb && (so->so_options & SO_DEBUG || traceallspxs))
- spx_trace(SA_USER, (u_char)ostate, cb, (struct spx *)0, req);
-release:
+ return (EINVAL);
+}
+
+static int
+spx_send(so, flags, m, addr, controlp)
+ struct socket *so;
+ int flags;
+ struct mbuf *m;
+ struct mbuf *addr;
+ struct mbuf *controlp;
+{
+ int error;
+ int s;
+ struct ipxpcb *ipxp;
+ struct spxpcb *cb;
+
+ error = 0;
+ ipxp = sotoipxpcb(so);
+ cb = ipxtospxpcb(ipxp);
+
+ s = splnet();
+ if (flags & PRUS_OOB) {
+ if (sbspace(&so->so_snd) < -512) {
+ error = ENOBUFS;
+ goto spx_send_end;
+ }
+ cb->s_oobflags |= SF_SOOB;
+ }
+ if (controlp) {
+ 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:
if (controlp != NULL)
m_freem(controlp);
if (m != NULL)
@@ -1520,16 +1618,40 @@ release:
return (error);
}
-int
-spx_usrreq_sp(so, req, m, nam, controlp)
+static int
+spx_shutdown(so)
+ struct socket *so;
+{
+ int error;
+ int s;
+ struct ipxpcb *ipxp;
+ struct spxpcb *cb;
+
+ error = 0;
+ ipxp = sotoipxpcb(so);
+ cb = ipxtospxpcb(ipxp);
+
+ s = splnet();
+ socantsendmore(so);
+ cb = spx_usrclosed(cb);
+ if (cb)
+ error = spx_output(cb, (struct mbuf *) 0);
+ splx(s);
+ return (error);
+}
+
+static int
+spx_sp_attach(so, proto)
struct socket *so;
- int req;
- struct mbuf *m, *nam, *controlp;
+ int proto;
{
- int error = spx_usrreq(so, req, m, nam, controlp);
+ int error;
+ struct ipxpcb *ipxp;
+ struct spxpcb *cb;
- if (req == PRU_ATTACH && error == 0) {
- struct ipxpcb *ipxp = sotoipxpcb(so);
+ error = spx_attach(so, proto);
+ if (error == 0) {
+ ipxp = sotoipxpcb(so);
((struct spxpcb *)ipxp->ipxp_pcb)->s_flags |=
(SF_HI | SF_HO | SF_PI);
}
@@ -1698,9 +1820,7 @@ spx_slowtimo()
goto tpgone;
for (i = 0; i < SPXT_NTIMERS; i++) {
if (cb->s_timer[i] && --cb->s_timer[i] == 0) {
- (void) spx_usrreq(cb->s_ipxpcb->ipxp_socket,
- PRU_SLOWTIMO, (struct mbuf *)0,
- (struct mbuf *)i, (struct mbuf *)0);
+ spx_timers(cb, i);
if (ipnxt->ipxp_prev != ip)
goto tpgone;
}
OpenPOWER on IntegriCloud