mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-06 13:09:50 +00:00
Change IPX to use the pr_usrreqs structure.
This commit is contained in:
parent
5a55bb419e
commit
583f1729d1
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=24659
@ -33,7 +33,7 @@
|
|||||||
*
|
*
|
||||||
* @(#)ipx.h
|
* @(#)ipx.h
|
||||||
*
|
*
|
||||||
* $Id$
|
* $Id: ipx.h,v 1.9 1997/02/22 09:41:52 peter Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _NETIPX_IPX_H_
|
#ifndef _NETIPX_IPX_H_
|
||||||
@ -158,6 +158,8 @@ struct ipx {
|
|||||||
|
|
||||||
#ifdef KERNEL
|
#ifdef KERNEL
|
||||||
|
|
||||||
|
extern struct pr_usrreqs ipx_usrreqs;
|
||||||
|
extern struct pr_usrreqs ripx_usrreqs;
|
||||||
extern int ipxcksum;
|
extern int ipxcksum;
|
||||||
extern struct domain ipxdomain;
|
extern struct domain ipxdomain;
|
||||||
extern struct sockaddr_ipx ipx_netmask;
|
extern struct sockaddr_ipx ipx_netmask;
|
||||||
@ -191,13 +193,12 @@ void ipx_input __P((struct mbuf *m, struct ipxpcb *ipxp));
|
|||||||
void ipxintr __P((void));
|
void ipxintr __P((void));
|
||||||
int ipx_output __P((struct ipxpcb *ipxp, struct mbuf *m0));
|
int ipx_output __P((struct ipxpcb *ipxp, struct mbuf *m0));
|
||||||
int ipx_outputfl __P((struct mbuf *m0, struct route *ro, int flags));
|
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));
|
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));
|
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
|
#else
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
*
|
*
|
||||||
* @(#)ipx_proto.c
|
* @(#)ipx_proto.c
|
||||||
*
|
*
|
||||||
* $Id$
|
* $Id: ipx_proto.c,v 1.7 1997/02/22 09:41:56 peter Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
@ -57,39 +57,45 @@ struct protosw ipxsw[] = {
|
|||||||
{ 0, &ipxdomain, 0, 0,
|
{ 0, &ipxdomain, 0, 0,
|
||||||
0, 0, 0, 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,
|
{ SOCK_DGRAM, &ipxdomain, 0, PR_ATOMIC|PR_ADDR,
|
||||||
0, 0, ipx_ctlinput, ipx_ctloutput,
|
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,
|
{ SOCK_STREAM, &ipxdomain, IPXPROTO_SPX, PR_CONNREQUIRED|PR_WANTRCVD,
|
||||||
0, 0, spx_ctlinput, spx_ctloutput,
|
0, 0, spx_ctlinput, spx_ctloutput,
|
||||||
spx_usrreq,
|
0,
|
||||||
spx_init, spx_fasttimo, spx_slowtimo, 0
|
spx_init, spx_fasttimo, spx_slowtimo, 0,
|
||||||
|
&spx_usrreqs
|
||||||
},
|
},
|
||||||
{ SOCK_SEQPACKET,&ipxdomain, IPXPROTO_SPX, PR_CONNREQUIRED|PR_WANTRCVD|PR_ATOMIC,
|
{ SOCK_SEQPACKET,&ipxdomain, IPXPROTO_SPX, PR_CONNREQUIRED|PR_WANTRCVD|PR_ATOMIC,
|
||||||
0, 0, spx_ctlinput, spx_ctloutput,
|
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,
|
{ SOCK_RAW, &ipxdomain, IPXPROTO_RAW, PR_ATOMIC|PR_ADDR,
|
||||||
0, 0, 0, ipx_ctloutput,
|
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,
|
{ SOCK_RAW, &ipxdomain, IPXPROTO_ERROR, PR_ATOMIC|PR_ADDR,
|
||||||
0, 0, 0, ipx_ctloutput,
|
0, 0, 0, ipx_ctloutput,
|
||||||
ipx_raw_usrreq,
|
0,
|
||||||
0, 0, 0, 0
|
0, 0, 0, 0,
|
||||||
|
&ripx_usrreqs
|
||||||
},
|
},
|
||||||
#ifdef IPTUNNEL
|
#ifdef IPTUNNEL
|
||||||
#if 0
|
#if 0
|
||||||
{ SOCK_RAW, &ipxdomain, IPPROTO_IPX, PR_ATOMIC|PR_ADDR,
|
{ SOCK_RAW, &ipxdomain, IPPROTO_IPX, PR_ATOMIC|PR_ADDR,
|
||||||
iptun_input, rip_output, iptun_ctlinput, 0,
|
iptun_input, rip_output, iptun_ctlinput, 0,
|
||||||
rip_usrreq,
|
0,
|
||||||
0, 0, 0, 0,
|
0, 0, 0, 0,
|
||||||
|
&rip_usrreqs
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
*
|
*
|
||||||
* @(#)ipx_usrreq.c
|
* @(#)ipx_usrreq.c
|
||||||
*
|
*
|
||||||
* $Id$
|
* $Id: ipx_usrreq.c,v 1.11 1997/02/22 09:41:57 peter Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
@ -74,6 +74,33 @@ int ipxrecvspace = IPXRCVQ;
|
|||||||
SYSCTL_INT(_net_ipx_ipx, OID_AUTO, ipxrecvspace, CTLFLAG_RW,
|
SYSCTL_INT(_net_ipx_ipx, OID_AUTO, ipxrecvspace, CTLFLAG_RW,
|
||||||
&ipxrecvspace, 0, "");
|
&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.
|
* This may also be called for raw listeners.
|
||||||
*/
|
*/
|
||||||
@ -399,202 +426,200 @@ ipx_ctloutput(req, so, level, name, value)
|
|||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*ARGSUSED*/
|
static int
|
||||||
int
|
ipx_usr_abort(so)
|
||||||
ipx_usrreq(so, req, m, nam, control)
|
|
||||||
struct socket *so;
|
struct socket *so;
|
||||||
int req;
|
{
|
||||||
struct mbuf *m, *nam, *control;
|
int s;
|
||||||
|
struct ipxpcb *ipxp = sotoipxpcb(so);
|
||||||
|
|
||||||
|
s = splnet();
|
||||||
|
ipx_pcbdetach(ipxp);
|
||||||
|
splx(s);
|
||||||
|
sofree(so);
|
||||||
|
soisdisconnected(so);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
ipx_attach(so, proto)
|
||||||
|
struct socket *so;
|
||||||
|
int proto;
|
||||||
|
{
|
||||||
|
int error;
|
||||||
|
int s;
|
||||||
|
struct ipxpcb *ipxp = sotoipxpcb(so);
|
||||||
|
|
||||||
|
if (ipxp != NULL)
|
||||||
|
return (EINVAL);
|
||||||
|
s = splnet();
|
||||||
|
error = ipx_pcballoc(so, &ipxpcb);
|
||||||
|
splx(s);
|
||||||
|
if (error == 0)
|
||||||
|
error = soreserve(so, ipxsendspace, ipxrecvspace);
|
||||||
|
return (error);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
ipx_bind(so, nam)
|
||||||
|
struct socket *so;
|
||||||
|
struct mbuf *nam;
|
||||||
{
|
{
|
||||||
struct ipxpcb *ipxp = sotoipxpcb(so);
|
struct ipxpcb *ipxp = sotoipxpcb(so);
|
||||||
int error = 0;
|
|
||||||
|
|
||||||
if (req == PRU_CONTROL)
|
return (ipx_pcbbind(ipxp, nam));
|
||||||
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:
|
static int
|
||||||
if (ipxp != NULL) {
|
ipx_connect(so, nam)
|
||||||
error = EINVAL;
|
struct socket *so;
|
||||||
break;
|
struct mbuf *nam;
|
||||||
}
|
{
|
||||||
error = ipx_pcballoc(so, &ipxpcb);
|
int error;
|
||||||
if (error)
|
int s;
|
||||||
break;
|
struct ipxpcb *ipxp = sotoipxpcb(so);
|
||||||
error = soreserve(so, ipxsendspace, ipxrecvspace);
|
|
||||||
if (error)
|
|
||||||
break;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PRU_DETACH:
|
if (!ipx_nullhost(ipxp->ipxp_faddr))
|
||||||
if (ipxp == NULL) {
|
return (EISCONN);
|
||||||
error = ENOTCONN;
|
s = splnet();
|
||||||
break;
|
error = ipx_pcbconnect(ipxp, nam);
|
||||||
}
|
splx(s);
|
||||||
ipx_pcbdetach(ipxp);
|
if (error == 0)
|
||||||
break;
|
soisconnected(so);
|
||||||
|
return (error);
|
||||||
|
}
|
||||||
|
|
||||||
case PRU_BIND:
|
static int
|
||||||
error = ipx_pcbbind(ipxp, nam);
|
ipx_detach(so)
|
||||||
break;
|
struct socket *so;
|
||||||
|
{
|
||||||
|
int s;
|
||||||
|
struct ipxpcb *ipxp = sotoipxpcb(so);
|
||||||
|
|
||||||
case PRU_LISTEN:
|
if (ipxp == NULL)
|
||||||
error = EOPNOTSUPP;
|
return (ENOTCONN);
|
||||||
break;
|
s = splnet();
|
||||||
|
ipx_pcbdetach(ipxp);
|
||||||
|
splx(s);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
case PRU_CONNECT:
|
static int
|
||||||
|
ipx_disconnect(so)
|
||||||
|
struct socket *so;
|
||||||
|
{
|
||||||
|
int s;
|
||||||
|
struct ipxpcb *ipxp = sotoipxpcb(so);
|
||||||
|
|
||||||
|
if (ipx_nullhost(ipxp->ipxp_faddr))
|
||||||
|
return (ENOTCONN);
|
||||||
|
s = splnet();
|
||||||
|
ipx_pcbdisconnect(ipxp);
|
||||||
|
splx(s);
|
||||||
|
soisdisconnected(so);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ipx_peeraddr(so, nam)
|
||||||
|
struct socket *so;
|
||||||
|
struct mbuf *nam;
|
||||||
|
{
|
||||||
|
struct ipxpcb *ipxp = sotoipxpcb(so);
|
||||||
|
|
||||||
|
ipx_setpeeraddr(ipxp, nam);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
if (nam) {
|
||||||
|
laddr = ipxp->ipxp_laddr;
|
||||||
if (!ipx_nullhost(ipxp->ipxp_faddr)) {
|
if (!ipx_nullhost(ipxp->ipxp_faddr)) {
|
||||||
error = EISCONN;
|
error = EISCONN;
|
||||||
break;
|
goto send_release;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* Must block input while temporarily connected.
|
||||||
|
*/
|
||||||
|
s = splnet();
|
||||||
error = ipx_pcbconnect(ipxp, nam);
|
error = ipx_pcbconnect(ipxp, nam);
|
||||||
if (error == 0)
|
if (error) {
|
||||||
soisconnected(so);
|
splx(s);
|
||||||
break;
|
goto send_release;
|
||||||
|
}
|
||||||
case PRU_CONNECT2:
|
} else {
|
||||||
error = EOPNOTSUPP;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PRU_ACCEPT:
|
|
||||||
error = EOPNOTSUPP;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PRU_DISCONNECT:
|
|
||||||
if (ipx_nullhost(ipxp->ipxp_faddr)) {
|
if (ipx_nullhost(ipxp->ipxp_faddr)) {
|
||||||
error = ENOTCONN;
|
error = ENOTCONN;
|
||||||
break;
|
goto send_release;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
error = ipx_output(ipxp, m);
|
||||||
|
m = NULL;
|
||||||
|
if (nam) {
|
||||||
ipx_pcbdisconnect(ipxp);
|
ipx_pcbdisconnect(ipxp);
|
||||||
soisdisconnected(so);
|
splx(s);
|
||||||
break;
|
ipxp->ipxp_laddr.x_host = laddr.x_host;
|
||||||
|
ipxp->ipxp_laddr.x_port = laddr.x_port;
|
||||||
case PRU_SHUTDOWN:
|
|
||||||
socantsendmore(so);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PRU_SEND:
|
|
||||||
{
|
|
||||||
struct ipx_addr laddr;
|
|
||||||
int s = 0;
|
|
||||||
|
|
||||||
if (nam) {
|
|
||||||
laddr = ipxp->ipxp_laddr;
|
|
||||||
if (!ipx_nullhost(ipxp->ipxp_faddr)) {
|
|
||||||
error = EISCONN;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* Must block input while temporarily connected.
|
|
||||||
*/
|
|
||||||
s = splnet();
|
|
||||||
error = ipx_pcbconnect(ipxp, nam);
|
|
||||||
if (error) {
|
|
||||||
splx(s);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (ipx_nullhost(ipxp->ipxp_faddr)) {
|
|
||||||
error = ENOTCONN;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
error = ipx_output(ipxp, m);
|
|
||||||
m = NULL;
|
|
||||||
if (nam) {
|
|
||||||
ipx_pcbdisconnect(ipxp);
|
|
||||||
splx(s);
|
|
||||||
ipxp->ipxp_laddr.x_host = laddr.x_host;
|
|
||||||
ipxp->ipxp_laddr.x_port = laddr.x_port;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
|
|
||||||
case PRU_ABORT:
|
send_release:
|
||||||
ipx_pcbdetach(ipxp);
|
|
||||||
sofree(so);
|
|
||||||
soisdisconnected(so);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PRU_SOCKADDR:
|
|
||||||
ipx_setsockaddr(ipxp, nam);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PRU_PEERADDR:
|
|
||||||
ipx_setpeeraddr(ipxp, nam);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PRU_SENSE:
|
|
||||||
/*
|
|
||||||
* stat: don't bother with a blocksize.
|
|
||||||
*/
|
|
||||||
return (0);
|
|
||||||
|
|
||||||
case PRU_SENDOOB:
|
|
||||||
case PRU_FASTTIMO:
|
|
||||||
case PRU_SLOWTIMO:
|
|
||||||
case PRU_PROTORCV:
|
|
||||||
case PRU_PROTOSEND:
|
|
||||||
error = EOPNOTSUPP;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PRU_CONTROL:
|
|
||||||
case PRU_RCVD:
|
|
||||||
case PRU_RCVOOB:
|
|
||||||
return (EOPNOTSUPP); /* do not free mbuf's */
|
|
||||||
|
|
||||||
default:
|
|
||||||
panic("ipx_usrreq");
|
|
||||||
}
|
|
||||||
release:
|
|
||||||
if (control != NULL)
|
|
||||||
m_freem(control);
|
|
||||||
if (m != NULL)
|
if (m != NULL)
|
||||||
m_freem(m);
|
m_freem(m);
|
||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*ARGSUSED*/
|
static int
|
||||||
int
|
ipx_shutdown(so)
|
||||||
ipx_raw_usrreq(so, req, m, nam, control)
|
|
||||||
struct socket *so;
|
struct socket *so;
|
||||||
int req;
|
|
||||||
struct mbuf *m, *nam, *control;
|
|
||||||
{
|
{
|
||||||
int error = 0;
|
socantsendmore(so);
|
||||||
struct ipxpcb *ipxp = sotoipxpcb(so);
|
return (0);
|
||||||
/*extern struct ipxpcb ipxrawpcb;*//*XXX*//*JRE*/
|
|
||||||
|
|
||||||
switch (req) {
|
|
||||||
|
|
||||||
case PRU_ATTACH:
|
|
||||||
|
|
||||||
if (!(so->so_state & SS_PRIV) || (ipxp != NULL)) {
|
|
||||||
error = EINVAL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
error = ipx_pcballoc(so, &ipxrawpcb);
|
|
||||||
if (error)
|
|
||||||
break;
|
|
||||||
error = soreserve(so, 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);
|
|
||||||
}
|
|
||||||
return (error);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ipx_sockaddr(so, nam)
|
||||||
|
struct socket *so;
|
||||||
|
struct mbuf *nam;
|
||||||
|
{
|
||||||
|
struct ipxpcb *ipxp = sotoipxpcb(so);
|
||||||
|
|
||||||
|
ipx_setsockaddr(ipxp, nam);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
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))
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
*
|
*
|
||||||
* @(#)spx.h
|
* @(#)spx.h
|
||||||
*
|
*
|
||||||
* $Id$
|
* $Id: spx.h,v 1.9 1997/02/22 09:41:58 peter Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _NETIPX_SPX_H_
|
#ifndef _NETIPX_SPX_H_
|
||||||
@ -169,6 +169,9 @@ struct spxpcb {
|
|||||||
|
|
||||||
#ifdef KERNEL
|
#ifdef KERNEL
|
||||||
|
|
||||||
|
extern struct pr_usrreqs spx_usrreqs;
|
||||||
|
extern struct pr_usrreqs spx_usrreq_sps;
|
||||||
|
|
||||||
void spx_abort __P((struct ipxpcb *ipxp));
|
void spx_abort __P((struct ipxpcb *ipxp));
|
||||||
struct spxpcb *
|
struct spxpcb *
|
||||||
spx_close __P((struct spxpcb *cb));
|
spx_close __P((struct spxpcb *cb));
|
||||||
@ -192,10 +195,6 @@ struct spxpcb *
|
|||||||
spx_timers __P((struct spxpcb *cb, int timer));
|
spx_timers __P((struct spxpcb *cb, int timer));
|
||||||
struct spxpcb *
|
struct spxpcb *
|
||||||
spx_usrclosed __P((struct spxpcb *cb));
|
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 */
|
#endif /* KERNEL */
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
*
|
*
|
||||||
* @(#)spx_usrreq.h
|
* @(#)spx_usrreq.h
|
||||||
*
|
*
|
||||||
* $Id$
|
* $Id: spx_usrreq.c,v 1.10 1997/02/22 09:42:00 peter Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
@ -72,6 +72,37 @@ u_short spx_newchecks[50];
|
|||||||
struct spx_istat spx_istat;
|
struct spx_istat spx_istat;
|
||||||
u_short spx_iss;
|
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
|
void
|
||||||
spx_init()
|
spx_init()
|
||||||
{
|
{
|
||||||
@ -1266,252 +1297,319 @@ spx_ctloutput(req, so, level, name, value)
|
|||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*ARGSUSED*/
|
static int
|
||||||
int
|
spx_usr_abort(so)
|
||||||
spx_usrreq(so, req, m, nam, controlp)
|
|
||||||
struct socket *so;
|
struct socket *so;
|
||||||
int req;
|
|
||||||
struct mbuf *m, *nam, *controlp;
|
|
||||||
{
|
{
|
||||||
struct ipxpcb *ipxp = sotoipxpcb(so);
|
int s;
|
||||||
register struct spxpcb *cb = NULL;
|
struct ipxpcb *ipxp;
|
||||||
int s = splnet();
|
struct spxpcb *cb;
|
||||||
int error = 0, ostate;
|
|
||||||
|
ipxp = sotoipxpcb(so);
|
||||||
|
cb = ipxtospxpcb(ipxp);
|
||||||
|
|
||||||
|
s = splnet();
|
||||||
|
spx_drop(cb, ECONNABORTED);
|
||||||
|
splx(s);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
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 mbuf *mm;
|
||||||
register struct sockbuf *sb;
|
struct sockbuf *sb;
|
||||||
|
|
||||||
if (req == PRU_CONTROL)
|
ipxp = sotoipxpcb(so);
|
||||||
return (ipx_control(so, (int)m, (caddr_t)nam,
|
cb = ipxtospxpcb(ipxp);
|
||||||
(struct ifnet *)controlp));
|
|
||||||
if (ipxp == NULL) {
|
|
||||||
if (req != PRU_ATTACH) {
|
|
||||||
error = EINVAL;
|
|
||||||
goto release;
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
cb = ipxtospxpcb(ipxp);
|
|
||||||
|
|
||||||
ostate = cb ? cb->s_state : 0;
|
if (ipxp != NULL)
|
||||||
|
return (EISCONN);
|
||||||
switch (req) {
|
s = splnet();
|
||||||
|
error = ipx_pcballoc(so, &ipxpcb);
|
||||||
case PRU_ATTACH:
|
if (error)
|
||||||
if (ipxp != NULL) {
|
goto spx_attach_end;
|
||||||
error = EISCONN;
|
if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) {
|
||||||
break;
|
error = soreserve(so, (u_long) 3072, (u_long) 3072);
|
||||||
}
|
|
||||||
error = ipx_pcballoc(so, &ipxpcb);
|
|
||||||
if (error)
|
if (error)
|
||||||
break;
|
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);
|
ipxp = sotoipxpcb(so);
|
||||||
if (error)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
ipxp = sotoipxpcb(so);
|
|
||||||
|
|
||||||
mm = m_getclr(M_DONTWAIT, MT_PCB);
|
mm = m_getclr(M_DONTWAIT, MT_PCB);
|
||||||
sb = &so->so_snd;
|
sb = &so->so_snd;
|
||||||
|
|
||||||
if (mm == NULL) {
|
if (mm == NULL) {
|
||||||
error = ENOBUFS;
|
error = ENOBUFS;
|
||||||
break;
|
goto spx_attach_end;
|
||||||
}
|
}
|
||||||
cb = mtod(mm, struct spxpcb *);
|
cb = mtod(mm, struct spxpcb *);
|
||||||
mm = m_getclr(M_DONTWAIT, MT_HEADER);
|
mm = m_getclr(M_DONTWAIT, MT_HEADER);
|
||||||
if (mm == NULL) {
|
if (mm == NULL) {
|
||||||
(void) m_free(dtom(m));
|
m_freem(dtom(cb));
|
||||||
error = ENOBUFS;
|
error = ENOBUFS;
|
||||||
break;
|
goto spx_attach_end;
|
||||||
}
|
}
|
||||||
cb->s_ipx = mtod(mm, struct ipx *);
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
spx_bind(so, nam)
|
||||||
|
struct socket *so;
|
||||||
|
struct mbuf *nam;
|
||||||
|
{
|
||||||
|
struct ipxpcb *ipxp;
|
||||||
|
|
||||||
|
ipxp = sotoipxpcb(so);
|
||||||
|
|
||||||
|
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;
|
||||||
|
/*
|
||||||
|
* 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);
|
||||||
|
spx_connect_end:
|
||||||
|
splx(s);
|
||||||
|
return (error);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
spx_detach(so)
|
||||||
|
struct socket *so;
|
||||||
|
{
|
||||||
|
int s;
|
||||||
|
struct ipxpcb *ipxp;
|
||||||
|
struct spxpcb *cb;
|
||||||
|
|
||||||
|
ipxp = sotoipxpcb(so);
|
||||||
|
cb = ipxtospxpcb(ipxp);
|
||||||
|
|
||||||
|
if (ipxp == NULL)
|
||||||
|
return (ENOTCONN);
|
||||||
|
s = splnet();
|
||||||
|
if (cb->s_state > TCPS_LISTEN)
|
||||||
|
spx_disconnect(cb);
|
||||||
|
else
|
||||||
|
spx_close(cb);
|
||||||
|
splx(s);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
ipxp = sotoipxpcb(so);
|
||||||
|
cb = ipxtospxpcb(ipxp);
|
||||||
|
|
||||||
|
s = splnet();
|
||||||
|
spx_disconnect(cb);
|
||||||
|
splx(s);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
spx_listen(so)
|
||||||
|
struct socket *so;
|
||||||
|
{
|
||||||
|
int error;
|
||||||
|
struct ipxpcb *ipxp;
|
||||||
|
struct spxpcb *cb;
|
||||||
|
|
||||||
|
error = 0;
|
||||||
|
ipxp = sotoipxpcb(so);
|
||||||
|
cb = ipxtospxpcb(ipxp);
|
||||||
|
|
||||||
|
if (ipxp->ipxp_lport == 0)
|
||||||
|
error = ipx_pcbbind(ipxp, (struct mbuf *)0);
|
||||||
|
if (error == 0)
|
||||||
cb->s_state = TCPS_LISTEN;
|
cb->s_state = TCPS_LISTEN;
|
||||||
cb->s_smax = -1;
|
return (error);
|
||||||
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;
|
|
||||||
|
|
||||||
case PRU_DETACH:
|
/*
|
||||||
if (ipxp == NULL) {
|
* After a receive, possibly send acknowledgment
|
||||||
error = ENOTCONN;
|
* updating allocation.
|
||||||
break;
|
*/
|
||||||
}
|
static int
|
||||||
if (cb->s_state > TCPS_LISTEN)
|
spx_rcvd(so, flags)
|
||||||
cb = spx_disconnect(cb);
|
struct socket *so;
|
||||||
else
|
int flags;
|
||||||
cb = spx_close(cb);
|
{
|
||||||
break;
|
int s;
|
||||||
|
struct ipxpcb *ipxp;
|
||||||
|
struct spxpcb *cb;
|
||||||
|
|
||||||
case PRU_BIND:
|
ipxp = sotoipxpcb(so);
|
||||||
error = ipx_pcbbind(ipxp, nam);
|
cb = ipxtospxpcb(ipxp);
|
||||||
break;
|
|
||||||
|
|
||||||
case PRU_LISTEN:
|
s = splnet();
|
||||||
if (ipxp->ipxp_lport == 0)
|
cb->s_flags |= SF_RVD;
|
||||||
error = ipx_pcbbind(ipxp, (struct mbuf *)0);
|
spx_output(cb, (struct mbuf *) 0);
|
||||||
if (error == 0)
|
cb->s_flags &= ~SF_RVD;
|
||||||
cb->s_state = TCPS_LISTEN;
|
splx(s);
|
||||||
break;
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
static int
|
||||||
* Initiate connection to peer.
|
spx_rcvoob(so, m, flags)
|
||||||
* Enter SYN_SENT state, and mark socket as connecting.
|
struct socket *so;
|
||||||
* Start keep-alive timer, setup prototype header,
|
struct mbuf *m;
|
||||||
* Send initial system packet requesting connection.
|
int flags;
|
||||||
*/
|
{
|
||||||
case PRU_CONNECT:
|
struct ipxpcb *ipxp;
|
||||||
if (ipxp->ipxp_lport == 0) {
|
struct spxpcb *cb;
|
||||||
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;
|
|
||||||
|
|
||||||
case PRU_CONNECT2:
|
ipxp = sotoipxpcb(so);
|
||||||
error = EOPNOTSUPP;
|
cb = ipxtospxpcb(ipxp);
|
||||||
break;
|
|
||||||
|
|
||||||
/*
|
if ((cb->s_oobflags & SF_IOOB) || so->so_oobmark ||
|
||||||
* We may decide later to implement connection closing
|
(so->so_state & SS_RCVATMARK)) {
|
||||||
* handshaking at the spx level optionally.
|
m->m_len = 1;
|
||||||
* here is the hook to do it:
|
*mtod(m, caddr_t) = cb->s_iobc;
|
||||||
*/
|
return (0);
|
||||||
case PRU_DISCONNECT:
|
}
|
||||||
cb = spx_disconnect(cb);
|
return (EINVAL);
|
||||||
break;
|
}
|
||||||
|
|
||||||
/*
|
static int
|
||||||
* Accept a connection. Essentially all the work is
|
spx_send(so, flags, m, addr, controlp)
|
||||||
* done at higher levels; just return the address
|
struct socket *so;
|
||||||
* of the peer, storing through addr.
|
int flags;
|
||||||
*/
|
struct mbuf *m;
|
||||||
case PRU_ACCEPT: {
|
struct mbuf *addr;
|
||||||
struct sockaddr_ipx *sipx = mtod(nam, struct sockaddr_ipx *);
|
struct mbuf *controlp;
|
||||||
|
{
|
||||||
|
int error;
|
||||||
|
int s;
|
||||||
|
struct ipxpcb *ipxp;
|
||||||
|
struct spxpcb *cb;
|
||||||
|
|
||||||
nam->m_len = sizeof (struct sockaddr_ipx);
|
error = 0;
|
||||||
sipx->sipx_family = AF_IPX;
|
ipxp = sotoipxpcb(so);
|
||||||
sipx->sipx_addr = ipxp->ipxp_faddr;
|
cb = ipxtospxpcb(ipxp);
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case PRU_SHUTDOWN:
|
s = splnet();
|
||||||
socantsendmore(so);
|
if (flags & PRUS_OOB) {
|
||||||
cb = spx_usrclosed(cb);
|
|
||||||
if (cb)
|
|
||||||
error = spx_output(cb, (struct mbuf *) 0);
|
|
||||||
break;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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;
|
|
||||||
|
|
||||||
case PRU_ABORT:
|
|
||||||
(void) spx_drop(cb, ECONNABORTED);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PRU_SENSE:
|
|
||||||
case PRU_CONTROL:
|
|
||||||
m = NULL;
|
|
||||||
error = EOPNOTSUPP;
|
|
||||||
break;
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
case PRU_SENDOOB:
|
|
||||||
if (sbspace(&so->so_snd) < -512) {
|
if (sbspace(&so->so_snd) < -512) {
|
||||||
error = ENOBUFS;
|
error = ENOBUFS;
|
||||||
break;
|
goto spx_send_end;
|
||||||
}
|
}
|
||||||
cb->s_oobflags |= SF_SOOB;
|
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;
|
|
||||||
|
|
||||||
case PRU_SOCKADDR:
|
|
||||||
ipx_setsockaddr(ipxp, nam);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PRU_PEERADDR:
|
|
||||||
ipx_setpeeraddr(ipxp, nam);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PRU_SLOWTIMO:
|
|
||||||
cb = spx_timers(cb, (int)nam);
|
|
||||||
req |= ((int)nam) << 8;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PRU_FASTTIMO:
|
|
||||||
case PRU_PROTORCV:
|
|
||||||
case PRU_PROTOSEND:
|
|
||||||
error = EOPNOTSUPP;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
panic("spx_usrreq");
|
|
||||||
}
|
}
|
||||||
if (cb && (so->so_options & SO_DEBUG || traceallspxs))
|
if (controlp) {
|
||||||
spx_trace(SA_USER, (u_char)ostate, cb, (struct spx *)0, req);
|
u_short *p = mtod(controlp, u_short *);
|
||||||
release:
|
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)
|
if (controlp != NULL)
|
||||||
m_freem(controlp);
|
m_freem(controlp);
|
||||||
if (m != NULL)
|
if (m != NULL)
|
||||||
@ -1520,16 +1618,40 @@ spx_usrreq(so, req, m, nam, controlp)
|
|||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
static int
|
||||||
spx_usrreq_sp(so, req, m, nam, controlp)
|
spx_shutdown(so)
|
||||||
struct socket *so;
|
struct socket *so;
|
||||||
int req;
|
|
||||||
struct mbuf *m, *nam, *controlp;
|
|
||||||
{
|
{
|
||||||
int error = spx_usrreq(so, req, m, nam, controlp);
|
int error;
|
||||||
|
int s;
|
||||||
|
struct ipxpcb *ipxp;
|
||||||
|
struct spxpcb *cb;
|
||||||
|
|
||||||
if (req == PRU_ATTACH && error == 0) {
|
error = 0;
|
||||||
struct ipxpcb *ipxp = sotoipxpcb(so);
|
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 proto;
|
||||||
|
{
|
||||||
|
int error;
|
||||||
|
struct ipxpcb *ipxp;
|
||||||
|
struct spxpcb *cb;
|
||||||
|
|
||||||
|
error = spx_attach(so, proto);
|
||||||
|
if (error == 0) {
|
||||||
|
ipxp = sotoipxpcb(so);
|
||||||
((struct spxpcb *)ipxp->ipxp_pcb)->s_flags |=
|
((struct spxpcb *)ipxp->ipxp_pcb)->s_flags |=
|
||||||
(SF_HI | SF_HO | SF_PI);
|
(SF_HI | SF_HO | SF_PI);
|
||||||
}
|
}
|
||||||
@ -1698,9 +1820,7 @@ spx_slowtimo()
|
|||||||
goto tpgone;
|
goto tpgone;
|
||||||
for (i = 0; i < SPXT_NTIMERS; i++) {
|
for (i = 0; i < SPXT_NTIMERS; i++) {
|
||||||
if (cb->s_timer[i] && --cb->s_timer[i] == 0) {
|
if (cb->s_timer[i] && --cb->s_timer[i] == 0) {
|
||||||
(void) spx_usrreq(cb->s_ipxpcb->ipxp_socket,
|
spx_timers(cb, i);
|
||||||
PRU_SLOWTIMO, (struct mbuf *)0,
|
|
||||||
(struct mbuf *)i, (struct mbuf *)0);
|
|
||||||
if (ipnxt->ipxp_prev != ip)
|
if (ipnxt->ipxp_prev != ip)
|
||||||
goto tpgone;
|
goto tpgone;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user