Yow! Completely change the way socket options are handled, eliminating
another specialized mbuf type in the process. Also clean up some of the cruft surrounding IPFW, multicast routing, RSVP, and other ill-explored corners.
This commit is contained in:
parent
bdad325c19
commit
cfe8b629f1
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=38482
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)uipc_proto.c 8.1 (Berkeley) 6/10/93
|
||||
* $Id: uipc_proto.c,v 1.15 1998/05/15 20:11:29 wollman Exp $
|
||||
* $Id: uipc_proto.c,v 1.16 1998/06/21 14:53:18 bde Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -41,6 +41,7 @@
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/un.h>
|
||||
#include <sys/unpcb.h>
|
||||
|
||||
#include <net/raw_cb.h>
|
||||
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)uipc_socket.c 8.3 (Berkeley) 4/15/94
|
||||
* $Id: uipc_socket.c,v 1.41 1998/07/06 19:27:14 fenner Exp $
|
||||
* $Id: uipc_socket.c,v 1.42 1998/07/18 18:48:45 fenner Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -898,31 +898,69 @@ sorflush(so)
|
||||
sbrelease(&asb);
|
||||
}
|
||||
|
||||
/*
|
||||
* Perhaps this routine, and sooptcopyout(), below, ought to come in
|
||||
* an additional variant to handle the case where the option value needs
|
||||
* to be some kind of integer, but not a specific size.
|
||||
* In addition to their use here, these functions are also called by the
|
||||
* protocol-level pr_ctloutput() routines.
|
||||
*/
|
||||
int
|
||||
sosetopt(so, level, optname, m0, p)
|
||||
register struct socket *so;
|
||||
int level, optname;
|
||||
struct mbuf *m0;
|
||||
struct proc *p;
|
||||
sooptcopyin(sopt, buf, len, minlen)
|
||||
struct sockopt *sopt;
|
||||
void *buf;
|
||||
size_t len;
|
||||
size_t minlen;
|
||||
{
|
||||
int error = 0;
|
||||
register struct mbuf *m = m0;
|
||||
size_t valsize;
|
||||
|
||||
if (level != SOL_SOCKET) {
|
||||
/*
|
||||
* If the user gives us more than we wanted, we ignore it,
|
||||
* but if we don't get the minimum length the caller
|
||||
* wants, we return EINVAL. On success, sopt->sopt_valsize
|
||||
* is set to however much we actually retrieved.
|
||||
*/
|
||||
if ((valsize = sopt->sopt_valsize) < minlen)
|
||||
return EINVAL;
|
||||
if (valsize > len)
|
||||
sopt->sopt_valsize = valsize = len;
|
||||
|
||||
if (sopt->sopt_p != 0)
|
||||
return (copyin(sopt->sopt_val, buf, valsize));
|
||||
|
||||
bcopy(sopt->sopt_val, buf, valsize);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
sosetopt(so, sopt)
|
||||
struct socket *so;
|
||||
struct sockopt *sopt;
|
||||
{
|
||||
int error, optval;
|
||||
struct linger l;
|
||||
struct timeval tv;
|
||||
short val;
|
||||
|
||||
error = 0;
|
||||
if (sopt->sopt_level != SOL_SOCKET) {
|
||||
if (so->so_proto && so->so_proto->pr_ctloutput)
|
||||
return ((*so->so_proto->pr_ctloutput)
|
||||
(PRCO_SETOPT, so, level, optname, &m0, p));
|
||||
(so, sopt));
|
||||
error = ENOPROTOOPT;
|
||||
} else {
|
||||
switch (optname) {
|
||||
|
||||
switch (sopt->sopt_name) {
|
||||
case SO_LINGER:
|
||||
if (m == NULL || m->m_len != sizeof (struct linger)) {
|
||||
error = EINVAL;
|
||||
error = sooptcopyin(sopt, &l, sizeof l, sizeof l);
|
||||
if (error)
|
||||
goto bad;
|
||||
}
|
||||
so->so_linger = mtod(m, struct linger *)->l_linger;
|
||||
/* fall thru... */
|
||||
|
||||
so->so_linger = l.l_linger;
|
||||
if (l.l_onoff)
|
||||
so->so_options |= SO_LINGER;
|
||||
else
|
||||
so->so_options &= ~SO_LINGER;
|
||||
break;
|
||||
|
||||
case SO_DEBUG:
|
||||
case SO_KEEPALIVE:
|
||||
@ -933,45 +971,40 @@ sosetopt(so, level, optname, m0, p)
|
||||
case SO_REUSEPORT:
|
||||
case SO_OOBINLINE:
|
||||
case SO_TIMESTAMP:
|
||||
if (m == NULL || m->m_len < sizeof (int)) {
|
||||
error = EINVAL;
|
||||
error = sooptcopyin(sopt, &optval, sizeof optval,
|
||||
sizeof optval);
|
||||
if (error)
|
||||
goto bad;
|
||||
}
|
||||
if (*mtod(m, int *))
|
||||
so->so_options |= optname;
|
||||
if (optval)
|
||||
so->so_options |= sopt->sopt_name;
|
||||
else
|
||||
so->so_options &= ~optname;
|
||||
so->so_options &= ~sopt->sopt_name;
|
||||
break;
|
||||
|
||||
case SO_SNDBUF:
|
||||
case SO_RCVBUF:
|
||||
case SO_SNDLOWAT:
|
||||
case SO_RCVLOWAT:
|
||||
{
|
||||
int optval;
|
||||
|
||||
if (m == NULL || m->m_len < sizeof (int)) {
|
||||
error = EINVAL;
|
||||
error = sooptcopyin(sopt, &optval, sizeof optval,
|
||||
sizeof optval);
|
||||
if (error)
|
||||
goto bad;
|
||||
}
|
||||
|
||||
/*
|
||||
* Values < 1 make no sense for any of these
|
||||
* options, so disallow them.
|
||||
*/
|
||||
optval = *mtod(m, int *);
|
||||
if (optval < 1) {
|
||||
error = EINVAL;
|
||||
goto bad;
|
||||
}
|
||||
|
||||
switch (optname) {
|
||||
|
||||
switch (sopt->sopt_name) {
|
||||
case SO_SNDBUF:
|
||||
case SO_RCVBUF:
|
||||
if (sbreserve(optname == SO_SNDBUF ?
|
||||
&so->so_snd : &so->so_rcv,
|
||||
(u_long) optval) == 0) {
|
||||
if (sbreserve(sopt->sopt_name == SO_SNDBUF ?
|
||||
&so->so_snd : &so->so_rcv,
|
||||
(u_long) optval) == 0) {
|
||||
error = ENOBUFS;
|
||||
goto bad;
|
||||
}
|
||||
@ -993,27 +1026,21 @@ sosetopt(so, level, optname, m0, p)
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SO_SNDTIMEO:
|
||||
case SO_RCVTIMEO:
|
||||
{
|
||||
struct timeval *tv;
|
||||
short val;
|
||||
|
||||
if (m == NULL || m->m_len < sizeof (*tv)) {
|
||||
error = EINVAL;
|
||||
error = sooptcopyin(sopt, &tv, sizeof tv,
|
||||
sizeof tv);
|
||||
if (error)
|
||||
goto bad;
|
||||
}
|
||||
tv = mtod(m, struct timeval *);
|
||||
if (tv->tv_sec > SHRT_MAX / hz - hz) {
|
||||
|
||||
if (tv.tv_sec > SHRT_MAX / hz - hz) {
|
||||
error = EDOM;
|
||||
goto bad;
|
||||
}
|
||||
val = tv->tv_sec * hz + tv->tv_usec / tick;
|
||||
|
||||
switch (optname) {
|
||||
val = tv.tv_sec * hz + tv.tv_usec / tick;
|
||||
|
||||
switch (sopt->sopt_name) {
|
||||
case SO_SNDTIMEO:
|
||||
so->so_snd.sb_timeo = val;
|
||||
break;
|
||||
@ -1022,7 +1049,6 @@ sosetopt(so, level, optname, m0, p)
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
error = ENOPROTOOPT;
|
||||
@ -1030,42 +1056,69 @@ sosetopt(so, level, optname, m0, p)
|
||||
}
|
||||
if (error == 0 && so->so_proto && so->so_proto->pr_ctloutput) {
|
||||
(void) ((*so->so_proto->pr_ctloutput)
|
||||
(PRCO_SETOPT, so, level, optname, &m0, p));
|
||||
m = NULL; /* freed by protocol */
|
||||
(so, sopt));
|
||||
}
|
||||
}
|
||||
bad:
|
||||
if (m)
|
||||
(void) m_free(m);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/* Helper routine for getsockopt */
|
||||
int
|
||||
sogetopt(so, level, optname, mp, p)
|
||||
register struct socket *so;
|
||||
int level, optname;
|
||||
struct mbuf **mp;
|
||||
struct proc *p;
|
||||
sooptcopyout(sopt, buf, len)
|
||||
struct sockopt *sopt;
|
||||
void *buf;
|
||||
size_t len;
|
||||
{
|
||||
register struct mbuf *m;
|
||||
int error;
|
||||
size_t valsize;
|
||||
|
||||
if (level != SOL_SOCKET) {
|
||||
error = 0;
|
||||
|
||||
/*
|
||||
* Documented get behavior is that we always return a value,
|
||||
* possibly truncated to fit in the user's buffer.
|
||||
* We leave the correct length in sopt->sopt_valsize,
|
||||
* to be copied out in getsockopt(). Note that this
|
||||
* interface is not idempotent; the entire answer must
|
||||
* generated ahead of time.
|
||||
*/
|
||||
valsize = len;
|
||||
if (sopt->sopt_valsize < valsize) {
|
||||
valsize = sopt->sopt_valsize;
|
||||
sopt->sopt_valsize = len;
|
||||
}
|
||||
if (sopt->sopt_val != 0) {
|
||||
if (sopt->sopt_p != 0)
|
||||
error = copyout(buf, sopt->sopt_val, valsize);
|
||||
else
|
||||
bcopy(buf, sopt->sopt_val, valsize);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
int
|
||||
sogetopt(so, sopt)
|
||||
struct socket *so;
|
||||
struct sockopt *sopt;
|
||||
{
|
||||
int error, optval;
|
||||
struct linger l;
|
||||
struct timeval tv;
|
||||
|
||||
error = 0;
|
||||
if (sopt->sopt_level != SOL_SOCKET) {
|
||||
if (so->so_proto && so->so_proto->pr_ctloutput) {
|
||||
return ((*so->so_proto->pr_ctloutput)
|
||||
(PRCO_GETOPT, so, level, optname, mp, p));
|
||||
(so, sopt));
|
||||
} else
|
||||
return (ENOPROTOOPT);
|
||||
} else {
|
||||
m = m_get(M_WAIT, MT_SOOPTS);
|
||||
m->m_len = sizeof (int);
|
||||
|
||||
switch (optname) {
|
||||
|
||||
switch (sopt->sopt_name) {
|
||||
case SO_LINGER:
|
||||
m->m_len = sizeof (struct linger);
|
||||
mtod(m, struct linger *)->l_onoff =
|
||||
so->so_options & SO_LINGER;
|
||||
mtod(m, struct linger *)->l_linger = so->so_linger;
|
||||
l.l_onoff = so->so_options & SO_LINGER;
|
||||
l.l_linger = so->so_linger;
|
||||
error = sooptcopyout(sopt, &l, sizeof l);
|
||||
break;
|
||||
|
||||
case SO_USELOOPBACK:
|
||||
@ -1077,53 +1130,51 @@ sogetopt(so, level, optname, mp, p)
|
||||
case SO_BROADCAST:
|
||||
case SO_OOBINLINE:
|
||||
case SO_TIMESTAMP:
|
||||
*mtod(m, int *) = so->so_options & optname;
|
||||
optval = so->so_options & sopt->sopt_name;
|
||||
integer:
|
||||
error = sooptcopyout(sopt, &optval, sizeof optval);
|
||||
break;
|
||||
|
||||
case SO_TYPE:
|
||||
*mtod(m, int *) = so->so_type;
|
||||
break;
|
||||
optval = so->so_type;
|
||||
goto integer;
|
||||
|
||||
case SO_ERROR:
|
||||
*mtod(m, int *) = so->so_error;
|
||||
optval = so->so_error;
|
||||
so->so_error = 0;
|
||||
break;
|
||||
goto integer;
|
||||
|
||||
case SO_SNDBUF:
|
||||
*mtod(m, int *) = so->so_snd.sb_hiwat;
|
||||
break;
|
||||
optval = so->so_snd.sb_hiwat;
|
||||
goto integer;
|
||||
|
||||
case SO_RCVBUF:
|
||||
*mtod(m, int *) = so->so_rcv.sb_hiwat;
|
||||
break;
|
||||
optval = so->so_rcv.sb_hiwat;
|
||||
goto integer;
|
||||
|
||||
case SO_SNDLOWAT:
|
||||
*mtod(m, int *) = so->so_snd.sb_lowat;
|
||||
break;
|
||||
optval = so->so_snd.sb_lowat;
|
||||
goto integer;
|
||||
|
||||
case SO_RCVLOWAT:
|
||||
*mtod(m, int *) = so->so_rcv.sb_lowat;
|
||||
break;
|
||||
optval = so->so_rcv.sb_lowat;
|
||||
goto integer;
|
||||
|
||||
case SO_SNDTIMEO:
|
||||
case SO_RCVTIMEO:
|
||||
{
|
||||
int val = (optname == SO_SNDTIMEO ?
|
||||
so->so_snd.sb_timeo : so->so_rcv.sb_timeo);
|
||||
optval = (sopt->sopt_name == SO_SNDTIMEO ?
|
||||
so->so_snd.sb_timeo : so->so_rcv.sb_timeo);
|
||||
|
||||
m->m_len = sizeof(struct timeval);
|
||||
mtod(m, struct timeval *)->tv_sec = val / hz;
|
||||
mtod(m, struct timeval *)->tv_usec =
|
||||
(val % hz) * tick;
|
||||
break;
|
||||
}
|
||||
tv.tv_sec = optval / hz;
|
||||
tv.tv_usec = (optval % hz) * tick;
|
||||
error = sooptcopyout(sopt, &tv, sizeof tv);
|
||||
break;
|
||||
|
||||
default:
|
||||
(void)m_free(m);
|
||||
return (ENOPROTOOPT);
|
||||
error = ENOPROTOOPT;
|
||||
break;
|
||||
}
|
||||
*mp = m;
|
||||
return (0);
|
||||
return (error);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)uipc_syscalls.c 8.4 (Berkeley) 2/21/94
|
||||
* $Id: uipc_syscalls.c,v 1.39 1998/04/14 06:24:43 phk Exp $
|
||||
* $Id: uipc_syscalls.c,v 1.40 1998/06/10 10:30:23 dfr Exp $
|
||||
*/
|
||||
|
||||
#include "opt_compat.h"
|
||||
@ -981,34 +981,26 @@ setsockopt(p, uap)
|
||||
} */ *uap;
|
||||
{
|
||||
struct file *fp;
|
||||
struct mbuf *m = NULL;
|
||||
struct sockopt sopt;
|
||||
int error;
|
||||
|
||||
if (uap->val == 0 && uap->valsize != 0)
|
||||
return (EFAULT);
|
||||
if (uap->valsize < 0)
|
||||
return (EINVAL);
|
||||
|
||||
error = getsock(p->p_fd, uap->s, &fp);
|
||||
if (error)
|
||||
return (error);
|
||||
if (uap->valsize > MCLBYTES)
|
||||
return (EINVAL);
|
||||
if (uap->val) {
|
||||
m = m_get(M_WAIT, MT_SOOPTS);
|
||||
if (m == NULL)
|
||||
return (ENOBUFS);
|
||||
if (uap->valsize > MLEN) {
|
||||
MCLGET(m, M_WAIT);
|
||||
if(!(m->m_flags & M_EXT)) {
|
||||
m_free(m);
|
||||
return (ENOBUFS);
|
||||
}
|
||||
}
|
||||
error = copyin(uap->val, mtod(m, caddr_t), (u_int)uap->valsize);
|
||||
if (error) {
|
||||
(void) m_free(m);
|
||||
return (error);
|
||||
}
|
||||
m->m_len = uap->valsize;
|
||||
}
|
||||
return (sosetopt((struct socket *)fp->f_data, uap->level,
|
||||
uap->name, m, p));
|
||||
|
||||
sopt.sopt_dir = SOPT_SET;
|
||||
sopt.sopt_level = uap->level;
|
||||
sopt.sopt_name = uap->name;
|
||||
sopt.sopt_val = uap->val;
|
||||
sopt.sopt_valsize = uap->valsize;
|
||||
sopt.sopt_p = p;
|
||||
|
||||
return (sosetopt((struct socket *)fp->f_data, &sopt));
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
@ -1023,9 +1015,9 @@ getsockopt(p, uap)
|
||||
int *avalsize;
|
||||
} */ *uap;
|
||||
{
|
||||
struct file *fp;
|
||||
struct mbuf *m = NULL, *m0;
|
||||
int op, i, valsize, error;
|
||||
int valsize, error;
|
||||
struct file *fp;
|
||||
struct sockopt sopt;
|
||||
|
||||
error = getsock(p->p_fd, uap->s, &fp);
|
||||
if (error)
|
||||
@ -1035,26 +1027,24 @@ getsockopt(p, uap)
|
||||
sizeof (valsize));
|
||||
if (error)
|
||||
return (error);
|
||||
if (valsize < 0)
|
||||
return (EINVAL);
|
||||
} else
|
||||
valsize = 0;
|
||||
if ((error = sogetopt((struct socket *)fp->f_data, uap->level,
|
||||
uap->name, &m, p)) == 0 && uap->val && valsize && m != NULL) {
|
||||
op = 0;
|
||||
while (m && !error && op < valsize) {
|
||||
i = min(m->m_len, (valsize - op));
|
||||
error = copyout(mtod(m, caddr_t), uap->val, (u_int)i);
|
||||
op += i;
|
||||
uap->val += i;
|
||||
m0 = m;
|
||||
MFREE(m0,m);
|
||||
}
|
||||
valsize = op;
|
||||
if (error == 0)
|
||||
error = copyout((caddr_t)&valsize,
|
||||
(caddr_t)uap->avalsize, sizeof (valsize));
|
||||
|
||||
sopt.sopt_dir = SOPT_GET;
|
||||
sopt.sopt_level = uap->level;
|
||||
sopt.sopt_name = uap->name;
|
||||
sopt.sopt_val = uap->val;
|
||||
sopt.sopt_valsize = (size_t)valsize; /* checked non-negative above */
|
||||
sopt.sopt_p = p;
|
||||
|
||||
error = sogetopt((struct socket *)fp->f_data, &sopt);
|
||||
if (error == 0) {
|
||||
valsize = sopt.sopt_valsize;
|
||||
error = copyout((caddr_t)&valsize,
|
||||
(caddr_t)uap->avalsize, sizeof (valsize));
|
||||
}
|
||||
if (m != NULL)
|
||||
(void) m_free(m);
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,7 @@
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: if_vlan.c,v 1.1 1998/03/18 01:40:12 wollman Exp $
|
||||
* $Id: if_vlan.c,v 1.2 1998/05/15 20:02:47 wollman Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -80,7 +80,7 @@ static struct ifvlan ifv_softc[NVLAN];
|
||||
|
||||
static void vlan_start(struct ifnet *ifp);
|
||||
static void vlan_ifinit(void *foo);
|
||||
static int vlan_ioctl(struct ifnet *ifp, int cmd, caddr_t addr);
|
||||
static int vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t addr);
|
||||
|
||||
static void
|
||||
vlaninit(void *dummy)
|
||||
@ -262,7 +262,7 @@ vlan_config(struct ifvlan *ifv, struct ifnet *p)
|
||||
}
|
||||
|
||||
static int
|
||||
vlan_ioctl(struct ifnet *ifp, int cmd, caddr_t data)
|
||||
vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
{
|
||||
struct ifaddr *ifa;
|
||||
struct ifnet *p;
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)in.h 8.3 (Berkeley) 1/3/94
|
||||
* $Id: in.h,v 1.35 1998/06/06 20:45:25 julian Exp $
|
||||
* $Id: in.h,v 1.36 1998/07/06 03:20:12 julian Exp $
|
||||
*/
|
||||
|
||||
#ifndef _NETINET_IN_H_
|
||||
@ -429,21 +429,6 @@ int in_cksum __P((struct mbuf *, int));
|
||||
int in_localaddr __P((struct in_addr));
|
||||
char *inet_ntoa __P((struct in_addr)); /* in libkern */
|
||||
|
||||
/* Firewall hooks */
|
||||
struct ip;
|
||||
typedef int ip_fw_chk_t __P((struct ip**, int, struct ifnet*, u_int16_t*, struct mbuf**, struct sockaddr_in**));
|
||||
typedef int ip_fw_ctl_t __P((int, struct mbuf**));
|
||||
extern ip_fw_chk_t *ip_fw_chk_ptr;
|
||||
extern ip_fw_ctl_t *ip_fw_ctl_ptr;
|
||||
|
||||
/* IP NAT hooks */
|
||||
typedef int ip_nat_t __P((struct ip**, struct mbuf**, struct ifnet*, int));
|
||||
typedef int ip_nat_ctl_t __P((int, struct mbuf**));
|
||||
extern ip_nat_t *ip_nat_ptr;
|
||||
extern ip_nat_ctl_t *ip_nat_ctl_ptr;
|
||||
#define IP_NAT_IN 0x00000001
|
||||
#define IP_NAT_OUT 0x00000002
|
||||
|
||||
#endif /* KERNEL */
|
||||
|
||||
#endif
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)in_proto.c 8.2 (Berkeley) 2/9/95
|
||||
* $Id: in_proto.c,v 1.45 1997/12/15 20:31:11 eivind Exp $
|
||||
* $Id: in_proto.c,v 1.46 1998/03/21 11:33:57 peter Exp $
|
||||
*/
|
||||
|
||||
#include "opt_ipdivert.h"
|
||||
@ -71,15 +71,6 @@
|
||||
#include <netns/ns_if.h>
|
||||
#endif
|
||||
|
||||
#ifdef TPIP
|
||||
void tpip_input(), tpip_ctlinput(), tp_init(), tp_slowtimo(), tp_drain();
|
||||
int tp_ctloutput(), tp_usrreq();
|
||||
#endif
|
||||
|
||||
#ifdef EON
|
||||
void eoninput(), eonctlinput(), eonprotoinit();
|
||||
#endif /* EON */
|
||||
|
||||
extern struct domain inetdomain;
|
||||
static struct pr_usrreqs nousrreqs;
|
||||
|
||||
|
@ -12,7 +12,7 @@
|
||||
*
|
||||
* This software is provided ``AS IS'' without any warranties of any kind.
|
||||
*
|
||||
* $Id: ip_fw.c,v 1.94 1998/08/03 17:23:37 dfr Exp $
|
||||
* $Id: ip_fw.c,v 1.95 1998/08/11 19:08:42 bde Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -34,6 +34,7 @@
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socketvar.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <net/if.h>
|
||||
#include <netinet/in.h>
|
||||
@ -60,6 +61,8 @@ static int fw_verbose_limit = IPFIREWALL_VERBOSE_LIMIT;
|
||||
static int fw_verbose_limit = 0;
|
||||
#endif
|
||||
|
||||
#define IPFW_DEFAULT_RULE ((u_int)(u_short)~0)
|
||||
|
||||
static LIST_HEAD (ip_fw_head, ip_fw_chain) ip_fw_chain;
|
||||
|
||||
static MALLOC_DEFINE(M_IPFW, "IpFw/IpAcct", "IpFw/IpAcct chain's");
|
||||
@ -83,9 +86,8 @@ SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, verbose_limit, CTLFLAG_RW, &fw_verbose_lim
|
||||
|
||||
static int add_entry __P((struct ip_fw_head *chainptr, struct ip_fw *frwl));
|
||||
static int del_entry __P((struct ip_fw_head *chainptr, u_short number));
|
||||
static int zero_entry __P((struct mbuf *m));
|
||||
static struct ip_fw *check_ipfw_struct __P((struct ip_fw *m));
|
||||
static struct ip_fw *check_ipfw_mbuf __P((struct mbuf *fw));
|
||||
static int zero_entry __P((struct ip_fw *));
|
||||
static int check_ipfw_struct __P((struct ip_fw *m));
|
||||
static __inline int
|
||||
iface_match __P((struct ifnet *ifp, union ip_fw_if *ifu,
|
||||
int byname));
|
||||
@ -106,7 +108,7 @@ static ip_fw_ctl_t *old_ctl_ptr;
|
||||
static int ip_fw_chk __P((struct ip **pip, int hlen,
|
||||
struct ifnet *oif, u_int16_t *cookie, struct mbuf **m,
|
||||
struct sockaddr_in **next_hop));
|
||||
static int ip_fw_ctl __P((int stage, struct mbuf **mm));
|
||||
static int ip_fw_ctl __P((struct sockopt *sopt));
|
||||
|
||||
static char err_prefix[] = "ip_fw_ctl:";
|
||||
|
||||
@ -424,7 +426,7 @@ ip_fw_chk(struct ip **pip, int hlen,
|
||||
*/
|
||||
chain = LIST_FIRST(&ip_fw_chain);
|
||||
if ( skipto ) {
|
||||
if (skipto >= 65535)
|
||||
if (skipto >= IPFW_DEFAULT_RULE)
|
||||
goto dropit;
|
||||
while (chain && (chain->rule->fw_number <= skipto)) {
|
||||
chain = LIST_NEXT(chain, chain);
|
||||
@ -645,7 +647,7 @@ ip_fw_chk(struct ip **pip, int hlen,
|
||||
}
|
||||
|
||||
#ifdef DIAGNOSTIC
|
||||
/* Rule 65535 should always be there and should always match */
|
||||
/* Rule IPFW_DEFAULT_RULE should always be there and should always match */
|
||||
if (!chain)
|
||||
panic("ip_fw: chain");
|
||||
#endif
|
||||
@ -734,16 +736,10 @@ add_entry(struct ip_fw_head *chainptr, struct ip_fw *frwl)
|
||||
|
||||
s = splnet();
|
||||
|
||||
if (!LIST_FIRST(chainptr)) {
|
||||
if (chainptr->lh_first == 0) {
|
||||
LIST_INSERT_HEAD(chainptr, fwc, chain);
|
||||
splx(s);
|
||||
return(0);
|
||||
} else if (ftmp->fw_number == (u_short)-1) {
|
||||
if (fwc) free(fwc, M_IPFW);
|
||||
if (ftmp) free(ftmp, M_IPFW);
|
||||
splx(s);
|
||||
dprintf(("%s bad rule number\n", err_prefix));
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
/* If entry number is 0, find highest numbered rule and add 100 */
|
||||
@ -754,7 +750,7 @@ add_entry(struct ip_fw_head *chainptr, struct ip_fw *frwl)
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (nbr < (u_short)-1 - 100)
|
||||
if (nbr < IPFW_DEFAULT_RULE - 100)
|
||||
nbr += 100;
|
||||
ftmp->fw_number = nbr;
|
||||
}
|
||||
@ -809,21 +805,12 @@ del_entry(struct ip_fw_head *chainptr, u_short number)
|
||||
}
|
||||
|
||||
static int
|
||||
zero_entry(struct mbuf *m)
|
||||
zero_entry(struct ip_fw *frwl)
|
||||
{
|
||||
struct ip_fw *frwl;
|
||||
struct ip_fw_chain *fcp;
|
||||
int s;
|
||||
int s, cleared;
|
||||
|
||||
if (m) {
|
||||
if (m->m_len != sizeof(struct ip_fw))
|
||||
return(EINVAL);
|
||||
frwl = mtod(m, struct ip_fw *);
|
||||
}
|
||||
else
|
||||
frwl = NULL;
|
||||
|
||||
if (!frwl) {
|
||||
if (frwl == 0) {
|
||||
s = splnet();
|
||||
for (fcp = LIST_FIRST(&ip_fw_chain); fcp; fcp = LIST_NEXT(fcp, chain)) {
|
||||
fcp->rule->fw_bcnt = fcp->rule->fw_pcnt = 0;
|
||||
@ -832,7 +819,7 @@ zero_entry(struct mbuf *m)
|
||||
splx(s);
|
||||
}
|
||||
else {
|
||||
int cleared = 0;
|
||||
cleared = 0;
|
||||
|
||||
/*
|
||||
* It's possible to insert multiple chain entries with the
|
||||
@ -851,8 +838,8 @@ zero_entry(struct mbuf *m)
|
||||
cleared = 1;
|
||||
break;
|
||||
}
|
||||
if (!cleared)
|
||||
return(EINVAL); /* we didn't find any matching rules */
|
||||
if (!cleared) /* we didn't find any matching rules */
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
if (fw_verbose) {
|
||||
@ -862,34 +849,22 @@ zero_entry(struct mbuf *m)
|
||||
printf("ipfw: Accounting cleared.\n");
|
||||
}
|
||||
|
||||
return(0);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static struct ip_fw *
|
||||
check_ipfw_mbuf(struct mbuf *m)
|
||||
{
|
||||
/* Check length */
|
||||
if (m->m_len != sizeof(struct ip_fw)) {
|
||||
dprintf(("%s len=%d, want %d\n", err_prefix, m->m_len,
|
||||
sizeof(struct ip_fw)));
|
||||
return (NULL);
|
||||
}
|
||||
return(check_ipfw_struct(mtod(m, struct ip_fw *)));
|
||||
}
|
||||
|
||||
static struct ip_fw *
|
||||
static int
|
||||
check_ipfw_struct(struct ip_fw *frwl)
|
||||
{
|
||||
/* Check for invalid flag bits */
|
||||
if ((frwl->fw_flg & ~IP_FW_F_MASK) != 0) {
|
||||
dprintf(("%s undefined flag bits set (flags=%x)\n",
|
||||
err_prefix, frwl->fw_flg));
|
||||
return (NULL);
|
||||
return (EINVAL);
|
||||
}
|
||||
/* Must apply to incoming or outgoing (or both) */
|
||||
if (!(frwl->fw_flg & (IP_FW_F_IN | IP_FW_F_OUT))) {
|
||||
dprintf(("%s neither in nor out\n", err_prefix));
|
||||
return (NULL);
|
||||
return (EINVAL);
|
||||
}
|
||||
/* Empty interface name is no good */
|
||||
if (((frwl->fw_flg & IP_FW_F_IIFNAME)
|
||||
@ -897,7 +872,7 @@ check_ipfw_struct(struct ip_fw *frwl)
|
||||
|| ((frwl->fw_flg & IP_FW_F_OIFNAME)
|
||||
&& !*frwl->fw_out_if.fu_via_if.name)) {
|
||||
dprintf(("%s empty interface name\n", err_prefix));
|
||||
return (NULL);
|
||||
return (EINVAL);
|
||||
}
|
||||
/* Sanity check interface matching */
|
||||
if ((frwl->fw_flg & IF_FW_F_VIAHACK) == IF_FW_F_VIAHACK) {
|
||||
@ -906,23 +881,23 @@ check_ipfw_struct(struct ip_fw *frwl)
|
||||
&& (frwl->fw_flg & IP_FW_F_OIFACE)) {
|
||||
dprintf(("%s outgoing interface check on incoming\n",
|
||||
err_prefix));
|
||||
return (NULL);
|
||||
return (EINVAL);
|
||||
}
|
||||
/* Sanity check port ranges */
|
||||
if ((frwl->fw_flg & IP_FW_F_SRNG) && IP_FW_GETNSRCP(frwl) < 2) {
|
||||
dprintf(("%s src range set but n_src_p=%d\n",
|
||||
err_prefix, IP_FW_GETNSRCP(frwl)));
|
||||
return (NULL);
|
||||
return (EINVAL);
|
||||
}
|
||||
if ((frwl->fw_flg & IP_FW_F_DRNG) && IP_FW_GETNDSTP(frwl) < 2) {
|
||||
dprintf(("%s dst range set but n_dst_p=%d\n",
|
||||
err_prefix, IP_FW_GETNDSTP(frwl)));
|
||||
return (NULL);
|
||||
return (EINVAL);
|
||||
}
|
||||
if (IP_FW_GETNSRCP(frwl) + IP_FW_GETNDSTP(frwl) > IP_FW_MAX_PORTS) {
|
||||
dprintf(("%s too many ports (%d+%d)\n",
|
||||
err_prefix, IP_FW_GETNSRCP(frwl), IP_FW_GETNDSTP(frwl)));
|
||||
return (NULL);
|
||||
return (EINVAL);
|
||||
}
|
||||
/*
|
||||
* Protocols other than TCP/UDP don't use port range
|
||||
@ -932,7 +907,7 @@ check_ipfw_struct(struct ip_fw *frwl)
|
||||
(IP_FW_GETNSRCP(frwl) || IP_FW_GETNDSTP(frwl))) {
|
||||
dprintf(("%s port(s) specified for non TCP/UDP rule\n",
|
||||
err_prefix));
|
||||
return(NULL);
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -943,19 +918,19 @@ check_ipfw_struct(struct ip_fw *frwl)
|
||||
if ((frwl->fw_src.s_addr & (~frwl->fw_smsk.s_addr)) ||
|
||||
(frwl->fw_dst.s_addr & (~frwl->fw_dmsk.s_addr))) {
|
||||
dprintf(("%s rule never matches\n", err_prefix));
|
||||
return(NULL);
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
if ((frwl->fw_flg & IP_FW_F_FRAG) &&
|
||||
(frwl->fw_prot == IPPROTO_UDP || frwl->fw_prot == IPPROTO_TCP)) {
|
||||
if (frwl->fw_nports) {
|
||||
dprintf(("%s cannot mix 'frag' and ports\n", err_prefix));
|
||||
return(NULL);
|
||||
return (EINVAL);
|
||||
}
|
||||
if (frwl->fw_prot == IPPROTO_TCP &&
|
||||
frwl->fw_tcpf != frwl->fw_tcpnf) {
|
||||
dprintf(("%s cannot mix 'frag' and TCP flags\n", err_prefix));
|
||||
return(NULL);
|
||||
return (EINVAL);
|
||||
}
|
||||
}
|
||||
|
||||
@ -967,14 +942,14 @@ check_ipfw_struct(struct ip_fw *frwl)
|
||||
&& !(frwl->fw_prot == IPPROTO_TCP
|
||||
&& frwl->fw_reject_code == IP_FW_REJECT_RST)) {
|
||||
dprintf(("%s unknown reject code\n", err_prefix));
|
||||
return(NULL);
|
||||
return (EINVAL);
|
||||
}
|
||||
break;
|
||||
case IP_FW_F_DIVERT: /* Diverting to port zero is invalid */
|
||||
case IP_FW_F_TEE:
|
||||
if (frwl->fw_divert_port == 0) {
|
||||
dprintf(("%s can't divert to port 0\n", err_prefix));
|
||||
return (NULL);
|
||||
return (EINVAL);
|
||||
}
|
||||
break;
|
||||
case IP_FW_F_DENY:
|
||||
@ -987,117 +962,102 @@ check_ipfw_struct(struct ip_fw *frwl)
|
||||
break;
|
||||
default:
|
||||
dprintf(("%s invalid command\n", err_prefix));
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
return frwl;
|
||||
}
|
||||
|
||||
static int
|
||||
ip_fw_ctl(int stage, struct mbuf **mm)
|
||||
{
|
||||
int error;
|
||||
/*
|
||||
* If we have any number of rules, then it's worth while
|
||||
* using clusters for this. The smaller case is rare.
|
||||
* Note that using clusters for setsockopt is only in 3.0 at this time.
|
||||
*/
|
||||
struct mbuf *m;
|
||||
|
||||
if (stage == IP_FW_GET) {
|
||||
/*
|
||||
* If we have any number of rules, then it's worth while
|
||||
* using clusters for this. The smaller case is rare.
|
||||
* Note that using clusters for setsockopt is only in
|
||||
* 3.0 at this time.
|
||||
*/
|
||||
struct ip_fw_chain *fcp = LIST_FIRST(&ip_fw_chain);
|
||||
*mm = m = m_get(M_WAIT, MT_SOOPTS);
|
||||
if (m == NULL)
|
||||
return (ENOBUFS);
|
||||
MCLGET(m, M_WAIT);
|
||||
if (!(m->m_flags & M_EXT)) {
|
||||
abort: m_freem(*mm);
|
||||
*mm = NULL;
|
||||
return (ENOBUFS);
|
||||
}
|
||||
m->m_len = 0;
|
||||
for (; fcp; fcp = LIST_NEXT(fcp, chain)) {
|
||||
/* Will we need a new cluster? */
|
||||
if ((m->m_len + sizeof *(fcp->rule)) > MCLBYTES) {
|
||||
m = m->m_next = m_get(M_WAIT, MT_SOOPTS);
|
||||
if (m == NULL) {
|
||||
goto abort;
|
||||
}
|
||||
MCLGET(m, M_WAIT);
|
||||
if (!(m->m_flags & M_EXT)) {
|
||||
goto abort;
|
||||
}
|
||||
m->m_len = 0;
|
||||
}
|
||||
memcpy(m->m_data + m->m_len, fcp->rule,
|
||||
sizeof *(fcp->rule));
|
||||
m->m_len += sizeof *(fcp->rule);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
m = *mm;
|
||||
/* only allow get calls if secure mode > 2 */
|
||||
if (securelevel > 2) {
|
||||
if (m) (void)m_free(m);
|
||||
return(EPERM);
|
||||
}
|
||||
if (stage == IP_FW_FLUSH) {
|
||||
while (LIST_FIRST(&ip_fw_chain) != NULL &&
|
||||
LIST_FIRST(&ip_fw_chain)->rule->fw_number != (u_short)-1) {
|
||||
struct ip_fw_chain *fcp = LIST_FIRST(&ip_fw_chain);
|
||||
int s = splnet();
|
||||
LIST_REMOVE(LIST_FIRST(&ip_fw_chain), chain);
|
||||
splx(s);
|
||||
free(fcp->rule, M_IPFW);
|
||||
free(fcp, M_IPFW);
|
||||
}
|
||||
if (m) (void)m_free(m);
|
||||
return (0);
|
||||
}
|
||||
if (stage == IP_FW_ZERO) {
|
||||
error = zero_entry(m);
|
||||
if (m) (void)m_free(m);
|
||||
return (error);
|
||||
}
|
||||
if (m == NULL) {
|
||||
printf("%s NULL mbuf ptr\n", err_prefix);
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
if (stage == IP_FW_ADD) {
|
||||
struct ip_fw *frwl = check_ipfw_mbuf(m);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!frwl)
|
||||
static int
|
||||
ip_fw_ctl(struct sockopt *sopt)
|
||||
{
|
||||
int error, s;
|
||||
size_t size;
|
||||
char *buf, *bp;
|
||||
struct ip_fw_chain *fcp;
|
||||
struct ip_fw frwl;
|
||||
|
||||
/* Disallow sets in really-really secure mode. */
|
||||
if (sopt->sopt_dir == SOPT_SET && securelevel >= 3)
|
||||
return (EPERM);
|
||||
error = 0;
|
||||
|
||||
switch (sopt->sopt_name) {
|
||||
case IP_FW_GET:
|
||||
for (fcp = LIST_FIRST(&ip_fw_chain), size = 0; fcp;
|
||||
fcp = LIST_NEXT(fcp, chain))
|
||||
size += sizeof *fcp->rule;
|
||||
buf = malloc(size, M_TEMP, M_WAITOK);
|
||||
if (buf == 0) {
|
||||
error = ENOBUFS;
|
||||
break;
|
||||
}
|
||||
|
||||
for (fcp = LIST_FIRST(&ip_fw_chain), bp = buf; fcp;
|
||||
fcp = LIST_NEXT(fcp, chain)) {
|
||||
bcopy(fcp->rule, bp, sizeof *fcp->rule);
|
||||
bp += sizeof *fcp->rule;
|
||||
}
|
||||
error = sooptcopyout(sopt, buf, size);
|
||||
FREE(buf, M_TEMP);
|
||||
break;
|
||||
|
||||
case IP_FW_FLUSH:
|
||||
for (fcp = ip_fw_chain.lh_first;
|
||||
fcp != 0 && fcp->rule->fw_number != IPFW_DEFAULT_RULE;
|
||||
fcp = ip_fw_chain.lh_first) {
|
||||
s = splnet();
|
||||
LIST_REMOVE(fcp, chain);
|
||||
FREE(fcp->rule, M_IPFW);
|
||||
FREE(fcp, M_IPFW);
|
||||
splx(s);
|
||||
}
|
||||
break;
|
||||
|
||||
case IP_FW_ZERO:
|
||||
if (sopt->sopt_val != 0) {
|
||||
error = sooptcopyin(sopt, &frwl, sizeof frwl,
|
||||
sizeof frwl);
|
||||
if (error || (error = zero_entry(&frwl)))
|
||||
break;
|
||||
} else {
|
||||
error = zero_entry(0);
|
||||
}
|
||||
break;
|
||||
|
||||
case IP_FW_ADD:
|
||||
error = sooptcopyin(sopt, &frwl, sizeof frwl, sizeof frwl);
|
||||
if (error || (error = check_ipfw_struct(&frwl)))
|
||||
break;
|
||||
|
||||
if (frwl.fw_number == IPFW_DEFAULT_RULE) {
|
||||
dprintf(("%s can't add rule %u\n", err_prefix,
|
||||
(unsigned)IPFW_DEFAULT_RULE));
|
||||
error = EINVAL;
|
||||
else
|
||||
error = add_entry(&ip_fw_chain, frwl);
|
||||
if (m) (void)m_free(m);
|
||||
return error;
|
||||
}
|
||||
if (stage == IP_FW_DEL) {
|
||||
if (m->m_len != sizeof(struct ip_fw)) {
|
||||
dprintf(("%s len=%d, want %d\n", err_prefix, m->m_len,
|
||||
sizeof(struct ip_fw)));
|
||||
} else {
|
||||
error = add_entry(&ip_fw_chain, &frwl);
|
||||
}
|
||||
break;
|
||||
|
||||
case IP_FW_DEL:
|
||||
error = sooptcopyin(sopt, &frwl, sizeof frwl, sizeof frwl);
|
||||
if (error)
|
||||
break;
|
||||
|
||||
if (frwl.fw_number == IPFW_DEFAULT_RULE) {
|
||||
dprintf(("%s can't delete rule %u\n", err_prefix,
|
||||
(unsigned)IPFW_DEFAULT_RULE));
|
||||
error = EINVAL;
|
||||
} else if (mtod(m, struct ip_fw *)->fw_number == (u_short)-1) {
|
||||
dprintf(("%s can't delete rule 65535\n", err_prefix));
|
||||
error = EINVAL;
|
||||
} else
|
||||
error = del_entry(&ip_fw_chain,
|
||||
mtod(m, struct ip_fw *)->fw_number);
|
||||
if (m) (void)m_free(m);
|
||||
return error;
|
||||
} else {
|
||||
error = del_entry(&ip_fw_chain, frwl.fw_number);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
panic("ip_fw_ctl");
|
||||
}
|
||||
|
||||
dprintf(("%s unknown request %d\n", err_prefix, stage));
|
||||
if (m) (void)m_free(m);
|
||||
return (EINVAL);
|
||||
return (error);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1111,14 +1071,14 @@ ip_fw_init(void)
|
||||
|
||||
bzero(&default_rule, sizeof default_rule);
|
||||
default_rule.fw_prot = IPPROTO_IP;
|
||||
default_rule.fw_number = (u_short)-1;
|
||||
default_rule.fw_number = IPFW_DEFAULT_RULE;
|
||||
#ifdef IPFIREWALL_DEFAULT_TO_ACCEPT
|
||||
default_rule.fw_flg |= IP_FW_F_ACCEPT;
|
||||
#else
|
||||
default_rule.fw_flg |= IP_FW_F_DENY;
|
||||
#endif
|
||||
default_rule.fw_flg |= IP_FW_F_IN | IP_FW_F_OUT;
|
||||
if (check_ipfw_struct(&default_rule) == NULL ||
|
||||
if (check_ipfw_struct(&default_rule) != 0 ||
|
||||
add_entry(&ip_fw_chain, &default_rule))
|
||||
panic("ip_fw_init");
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
*
|
||||
* This software is provided ``AS IS'' without any warranties of any kind.
|
||||
*
|
||||
* $Id: ip_fw.h,v 1.32 1998/02/03 22:15:03 bde Exp $
|
||||
* $Id: ip_fw.h,v 1.33 1998/07/06 03:20:15 julian Exp $
|
||||
*/
|
||||
|
||||
#ifndef _IP_FW_H
|
||||
@ -184,6 +184,23 @@ struct ip_fw_chain {
|
||||
*/
|
||||
void ip_fw_init __P((void));
|
||||
|
||||
/* Firewall hooks */
|
||||
struct ip;
|
||||
struct sockopt;
|
||||
typedef int ip_fw_chk_t __P((struct ip **, int, struct ifnet *, u_int16_t *,
|
||||
struct mbuf **, struct sockaddr_in **));
|
||||
typedef int ip_fw_ctl_t __P((struct sockopt *));
|
||||
extern ip_fw_chk_t *ip_fw_chk_ptr;
|
||||
extern ip_fw_ctl_t *ip_fw_ctl_ptr;
|
||||
|
||||
/* IP NAT hooks */
|
||||
typedef int ip_nat_t __P((struct ip **, struct mbuf **, struct ifnet *, int));
|
||||
typedef int ip_nat_ctl_t __P((struct sockopt *));
|
||||
extern ip_nat_t *ip_nat_ptr;
|
||||
extern ip_nat_ctl_t *ip_nat_ctl_ptr;
|
||||
#define IP_NAT_IN 0x00000001
|
||||
#define IP_NAT_OUT 0x00000002
|
||||
|
||||
#endif /* KERNEL */
|
||||
|
||||
#endif /* _IP_FW_H */
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)ip_input.c 8.2 (Berkeley) 1/4/94
|
||||
* $Id: ip_input.c,v 1.97 1998/07/13 12:12:24 bde Exp $
|
||||
* $Id: ip_input.c,v 1.98 1998/08/17 01:05:24 bde Exp $
|
||||
* $ANA: ip_input.c,v 1.5 1996/09/18 14:34:59 wollman Exp $
|
||||
*/
|
||||
|
||||
@ -142,6 +142,9 @@ SYSCTL_INT(_net_inet_ip, IPCTL_DEFMTU, mtu, CTLFLAG_RW,
|
||||
#endif
|
||||
|
||||
#ifdef COMPAT_IPFW
|
||||
|
||||
#include <netinet/ip_fw.h>
|
||||
|
||||
/* Firewall hooks */
|
||||
ip_fw_chk_t *ip_fw_chk_ptr;
|
||||
ip_fw_ctl_t *ip_fw_ctl_ptr;
|
||||
@ -1234,7 +1237,7 @@ ip_srcroute()
|
||||
|
||||
if (ip_nhops == 0)
|
||||
return ((struct mbuf *)0);
|
||||
m = m_get(M_DONTWAIT, MT_SOOPTS);
|
||||
m = m_get(M_DONTWAIT, MT_HEADER);
|
||||
if (m == 0)
|
||||
return ((struct mbuf *)0);
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
* Modified by Bill Fenner, PARC, April 1995
|
||||
*
|
||||
* MROUTING Revision: 3.5
|
||||
* $Id: ip_mroute.c,v 1.47 1998/06/30 10:56:31 phk Exp $
|
||||
* $Id: ip_mroute.c,v 1.48 1998/08/17 01:05:24 bde Exp $
|
||||
*/
|
||||
|
||||
#include "opt_mrouting.h"
|
||||
@ -54,10 +54,8 @@ extern u_long _ip_mcast_src __P((int vifi));
|
||||
extern int _ip_mforward __P((struct ip *ip, struct ifnet *ifp,
|
||||
struct mbuf *m, struct ip_moptions *imo));
|
||||
extern int _ip_mrouter_done __P((void));
|
||||
extern int _ip_mrouter_get __P((int cmd, struct socket *so,
|
||||
struct mbuf **m));
|
||||
extern int _ip_mrouter_set __P((int cmd, struct socket *so,
|
||||
struct mbuf *m));
|
||||
extern int _ip_mrouter_get __P((struct socket *so, struct sockopt *sopt));
|
||||
extern int _ip_mrouter_set __P((struct socket *so, struct sockopt *sopt));
|
||||
extern int _mrt_ioctl __P((int req, caddr_t data, struct proc *p));
|
||||
|
||||
/*
|
||||
@ -70,27 +68,25 @@ static struct mrtstat mrtstat;
|
||||
u_int rsvpdebug = 0;
|
||||
|
||||
int
|
||||
_ip_mrouter_set(cmd, so, m)
|
||||
int cmd;
|
||||
_ip_mrouter_set(so, sopt)
|
||||
struct socket *so;
|
||||
struct mbuf *m;
|
||||
struct sockopt *sopt;
|
||||
{
|
||||
return(EOPNOTSUPP);
|
||||
}
|
||||
|
||||
int (*ip_mrouter_set)(int, struct socket *, struct mbuf *) = _ip_mrouter_set;
|
||||
int (*ip_mrouter_set)(struct socket *, struct sockopt *) = _ip_mrouter_set;
|
||||
|
||||
|
||||
int
|
||||
_ip_mrouter_get(cmd, so, m)
|
||||
int cmd;
|
||||
_ip_mrouter_get(so, sopt)
|
||||
struct socket *so;
|
||||
struct mbuf **m;
|
||||
struct sockopt *sopt;
|
||||
{
|
||||
return(EOPNOTSUPP);
|
||||
}
|
||||
|
||||
int (*ip_mrouter_get)(int, struct socket *, struct mbuf **) = _ip_mrouter_get;
|
||||
int (*ip_mrouter_get)(struct socket *, struct sockopt *) = _ip_mrouter_get;
|
||||
|
||||
int
|
||||
_ip_mrouter_done()
|
||||
@ -161,17 +157,17 @@ _ip_mcast_src(int vifi) { return INADDR_ANY; }
|
||||
u_long (*ip_mcast_src)(int) = _ip_mcast_src;
|
||||
|
||||
int
|
||||
ip_rsvp_vif_init(so, m)
|
||||
ip_rsvp_vif_init(so, sopt)
|
||||
struct socket *so;
|
||||
struct mbuf *m;
|
||||
struct sockopt *sopt;
|
||||
{
|
||||
return(EINVAL);
|
||||
}
|
||||
|
||||
int
|
||||
ip_rsvp_vif_done(so, m)
|
||||
ip_rsvp_vif_done(so, sopt)
|
||||
struct socket *so;
|
||||
struct mbuf *m;
|
||||
struct sockopt *sopt;
|
||||
{
|
||||
return(EINVAL);
|
||||
}
|
||||
@ -279,22 +275,20 @@ static struct vif *last_encap_vif;
|
||||
static u_long X_ip_mcast_src __P((int vifi));
|
||||
static int X_ip_mforward __P((struct ip *ip, struct ifnet *ifp, struct mbuf *m, struct ip_moptions *imo));
|
||||
static int X_ip_mrouter_done __P((void));
|
||||
static int X_ip_mrouter_get __P((int cmd, struct socket *so, struct mbuf **m));
|
||||
static int X_ip_mrouter_set __P((int cmd, struct socket *so, struct mbuf *m));
|
||||
static int X_ip_mrouter_get __P((struct socket *so, struct sockopt *m));
|
||||
static int X_ip_mrouter_set __P((struct socket *so, struct sockopt *m));
|
||||
static int X_legal_vif_num __P((int vif));
|
||||
static int X_mrt_ioctl __P((int cmd, caddr_t data));
|
||||
|
||||
static int get_sg_cnt(struct sioc_sg_req *);
|
||||
static int get_vif_cnt(struct sioc_vif_req *);
|
||||
static int ip_mrouter_init(struct socket *, struct mbuf *);
|
||||
static int ip_mrouter_init(struct socket *, int);
|
||||
static int add_vif(struct vifctl *);
|
||||
static int del_vif(vifi_t *);
|
||||
static int del_vif(vifi_t);
|
||||
static int add_mfc(struct mfcctl *);
|
||||
static int del_mfc(struct mfcctl *);
|
||||
static int socket_send(struct socket *, struct mbuf *, struct sockaddr_in *);
|
||||
static int get_version(struct mbuf *);
|
||||
static int get_assert(struct mbuf *);
|
||||
static int set_assert(int *);
|
||||
static int set_assert(int);
|
||||
static void expire_upcalls(void *);
|
||||
static int ip_mdq(struct mbuf *, struct ifnet *, struct mfc *,
|
||||
vifi_t);
|
||||
@ -386,53 +380,102 @@ static void collate(struct timeval *);
|
||||
* Handle MRT setsockopt commands to modify the multicast routing tables.
|
||||
*/
|
||||
static int
|
||||
X_ip_mrouter_set(cmd, so, m)
|
||||
int cmd;
|
||||
struct socket *so;
|
||||
struct mbuf *m;
|
||||
X_ip_mrouter_set(so, sopt)
|
||||
struct socket *so;
|
||||
struct sockopt *sopt;
|
||||
{
|
||||
if (cmd != MRT_INIT && so != ip_mrouter) return EACCES;
|
||||
int error, optval;
|
||||
vifi_t vifi;
|
||||
struct vifctl vifc;
|
||||
struct mfcctl mfc;
|
||||
|
||||
switch (cmd) {
|
||||
case MRT_INIT: return ip_mrouter_init(so, m);
|
||||
case MRT_DONE: return ip_mrouter_done();
|
||||
case MRT_ADD_VIF: return add_vif (mtod(m, struct vifctl *));
|
||||
case MRT_DEL_VIF: return del_vif (mtod(m, vifi_t *));
|
||||
case MRT_ADD_MFC: return add_mfc (mtod(m, struct mfcctl *));
|
||||
case MRT_DEL_MFC: return del_mfc (mtod(m, struct mfcctl *));
|
||||
case MRT_ASSERT: return set_assert(mtod(m, int *));
|
||||
default: return EOPNOTSUPP;
|
||||
}
|
||||
if (so != ip_mrouter && sopt->sopt_name != MRT_INIT)
|
||||
return (EPERM);
|
||||
|
||||
error = 0;
|
||||
switch (sopt->sopt_name) {
|
||||
case MRT_INIT:
|
||||
error = sooptcopyin(sopt, &optval, sizeof optval,
|
||||
sizeof optval);
|
||||
if (error)
|
||||
break;
|
||||
error = ip_mrouter_init(so, optval);
|
||||
break;
|
||||
|
||||
case MRT_DONE:
|
||||
error = ip_mrouter_done();
|
||||
break;
|
||||
|
||||
case MRT_ADD_VIF:
|
||||
error = sooptcopyin(sopt, &vifc, sizeof vifc, sizeof vifc);
|
||||
if (error)
|
||||
break;
|
||||
error = add_vif(&vifc);
|
||||
break;
|
||||
|
||||
case MRT_DEL_VIF:
|
||||
error = sooptcopyin(sopt, &vifi, sizeof vifi, sizeof vifi);
|
||||
if (error)
|
||||
break;
|
||||
error = del_vif(vifi);
|
||||
break;
|
||||
|
||||
case MRT_ADD_MFC:
|
||||
case MRT_DEL_MFC:
|
||||
error = sooptcopyin(sopt, &mfc, sizeof mfc, sizeof mfc);
|
||||
if (error)
|
||||
break;
|
||||
if (sopt->sopt_name == MRT_ADD_MFC)
|
||||
error = add_mfc(&mfc);
|
||||
else
|
||||
error = del_mfc(&mfc);
|
||||
|
||||
case MRT_ASSERT:
|
||||
error = sooptcopyin(sopt, &optval, sizeof optval,
|
||||
sizeof optval);
|
||||
if (error)
|
||||
break;
|
||||
set_assert(optval);
|
||||
|
||||
default:
|
||||
error = EOPNOTSUPP;
|
||||
break;
|
||||
}
|
||||
return (error);
|
||||
}
|
||||
|
||||
#ifndef MROUTE_LKM
|
||||
int (*ip_mrouter_set)(int, struct socket *, struct mbuf *) = X_ip_mrouter_set;
|
||||
int (*ip_mrouter_set)(struct socket *, struct sockopt *) = X_ip_mrouter_set;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Handle MRT getsockopt commands
|
||||
*/
|
||||
static int
|
||||
X_ip_mrouter_get(cmd, so, m)
|
||||
int cmd;
|
||||
struct socket *so;
|
||||
struct mbuf **m;
|
||||
X_ip_mrouter_get(so, sopt)
|
||||
struct socket *so;
|
||||
struct sockopt *sopt;
|
||||
{
|
||||
struct mbuf *mb;
|
||||
int error;
|
||||
static int version = 0x0305; /* !!! why is this here? XXX */
|
||||
|
||||
if (so != ip_mrouter) return EACCES;
|
||||
switch (sopt->sopt_name) {
|
||||
case MRT_VERSION:
|
||||
error = sooptcopyout(sopt, &version, sizeof version);
|
||||
break;
|
||||
|
||||
*m = mb = m_get(M_WAIT, MT_SOOPTS);
|
||||
|
||||
switch (cmd) {
|
||||
case MRT_VERSION: return get_version(mb);
|
||||
case MRT_ASSERT: return get_assert(mb);
|
||||
default: return EOPNOTSUPP;
|
||||
}
|
||||
case MRT_ASSERT:
|
||||
error = sooptcopyout(sopt, &pim_assert, sizeof pim_assert);
|
||||
break;
|
||||
default:
|
||||
error = EOPNOTSUPP;
|
||||
break;
|
||||
}
|
||||
return (error);
|
||||
}
|
||||
|
||||
#ifndef MROUTE_LKM
|
||||
int (*ip_mrouter_get)(int, struct socket *, struct mbuf **) = X_ip_mrouter_get;
|
||||
int (*ip_mrouter_get)(struct socket *, struct sockopt *) = X_ip_mrouter_get;
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -509,9 +552,9 @@ get_vif_cnt(req)
|
||||
* Enable multicast routing
|
||||
*/
|
||||
static int
|
||||
ip_mrouter_init(so, m)
|
||||
ip_mrouter_init(so, version)
|
||||
struct socket *so;
|
||||
struct mbuf *m;
|
||||
int version;
|
||||
{
|
||||
int *v;
|
||||
|
||||
@ -522,11 +565,7 @@ ip_mrouter_init(so, m)
|
||||
if (so->so_type != SOCK_RAW ||
|
||||
so->so_proto->pr_protocol != IPPROTO_IGMP) return EOPNOTSUPP;
|
||||
|
||||
if (!m || (m->m_len != sizeof(int *)))
|
||||
return ENOPROTOOPT;
|
||||
|
||||
v = mtod(m, int *);
|
||||
if (*v != 1)
|
||||
if (version != 1)
|
||||
return ENOPROTOOPT;
|
||||
|
||||
if (ip_mrouter != NULL) return EADDRINUSE;
|
||||
@ -626,47 +665,17 @@ X_ip_mrouter_done()
|
||||
int (*ip_mrouter_done)(void) = X_ip_mrouter_done;
|
||||
#endif
|
||||
|
||||
static int
|
||||
get_version(mb)
|
||||
struct mbuf *mb;
|
||||
{
|
||||
int *v;
|
||||
|
||||
v = mtod(mb, int *);
|
||||
|
||||
*v = 0x0305; /* XXX !!!! */
|
||||
mb->m_len = sizeof(int);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set PIM assert processing global
|
||||
*/
|
||||
static int
|
||||
set_assert(i)
|
||||
int *i;
|
||||
int i;
|
||||
{
|
||||
if ((*i != 1) && (*i != 0))
|
||||
if ((i != 1) && (i != 0))
|
||||
return EINVAL;
|
||||
|
||||
pim_assert = *i;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get PIM assert processing global
|
||||
*/
|
||||
static int
|
||||
get_assert(m)
|
||||
struct mbuf *m;
|
||||
{
|
||||
int *i;
|
||||
|
||||
i = mtod(m, int *);
|
||||
|
||||
*i = pim_assert;
|
||||
pim_assert = i;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -777,17 +786,16 @@ add_vif(vifcp)
|
||||
* Delete a vif from the vif table
|
||||
*/
|
||||
static int
|
||||
del_vif(vifip)
|
||||
vifi_t *vifip;
|
||||
del_vif(vifi)
|
||||
vifi_t vifi;
|
||||
{
|
||||
register struct vif *vifp = viftable + *vifip;
|
||||
register vifi_t vifi;
|
||||
register struct vif *vifp = &viftable[vifi];
|
||||
register struct mbuf *m;
|
||||
struct ifnet *ifp;
|
||||
struct ifreq ifr;
|
||||
int s;
|
||||
|
||||
if (*vifip >= numvifs) return EINVAL;
|
||||
if (vifi >= numvifs) return EINVAL;
|
||||
if (vifp->v_lcl_addr.s_addr == 0) return EADDRNOTAVAIL;
|
||||
|
||||
s = splnet();
|
||||
@ -816,6 +824,9 @@ del_vif(vifip)
|
||||
bzero((caddr_t)vifp->v_tbf, sizeof(*(vifp->v_tbf)));
|
||||
bzero((caddr_t)vifp, sizeof (*vifp));
|
||||
|
||||
if (mrtdebug)
|
||||
log(LOG_DEBUG, "del_vif %d, numvifs %d\n", vifi, numvifs);
|
||||
|
||||
/* Adjust numvifs down */
|
||||
for (vifi = numvifs; vifi > 0; vifi--)
|
||||
if (viftable[vifi-1].v_lcl_addr.s_addr != 0) break;
|
||||
@ -823,9 +834,6 @@ del_vif(vifip)
|
||||
|
||||
splx(s);
|
||||
|
||||
if (mrtdebug)
|
||||
log(LOG_DEBUG, "del_vif %d, numvifs %d\n", *vifip, numvifs);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2009,12 +2017,11 @@ priority(vifp, ip)
|
||||
*/
|
||||
|
||||
int
|
||||
ip_rsvp_vif_init(so, m)
|
||||
struct socket *so;
|
||||
struct mbuf *m;
|
||||
ip_rsvp_vif_init(so, sopt)
|
||||
struct socket *so;
|
||||
struct sockopt *sopt;
|
||||
{
|
||||
int i;
|
||||
register int s;
|
||||
int error, i, s;
|
||||
|
||||
if (rsvpdebug)
|
||||
printf("ip_rsvp_vif_init: so_type = %d, pr_protocol = %d\n",
|
||||
@ -2024,13 +2031,12 @@ ip_rsvp_vif_init(so, m)
|
||||
return EOPNOTSUPP;
|
||||
|
||||
/* Check mbuf. */
|
||||
if (m == NULL || m->m_len != sizeof(int)) {
|
||||
return EINVAL;
|
||||
}
|
||||
i = *(mtod(m, int *));
|
||||
error = sooptcopyin(sopt, &i, sizeof i, sizeof i);
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
if (rsvpdebug)
|
||||
printf("ip_rsvp_vif_init: vif = %d rsvp_on = %d\n",i,rsvp_on);
|
||||
printf("ip_rsvp_vif_init: vif = %d rsvp_on = %d\n", i, rsvp_on);
|
||||
|
||||
s = splnet();
|
||||
|
||||
@ -2060,49 +2066,48 @@ ip_rsvp_vif_init(so, m)
|
||||
}
|
||||
|
||||
int
|
||||
ip_rsvp_vif_done(so, m)
|
||||
struct socket *so;
|
||||
struct mbuf *m;
|
||||
ip_rsvp_vif_done(so, sopt)
|
||||
struct socket *so;
|
||||
struct sockopt *sopt;
|
||||
{
|
||||
int i;
|
||||
register int s;
|
||||
int error, i, s;
|
||||
|
||||
if (rsvpdebug)
|
||||
printf("ip_rsvp_vif_done: so_type = %d, pr_protocol = %d\n",
|
||||
so->so_type, so->so_proto->pr_protocol);
|
||||
if (rsvpdebug)
|
||||
printf("ip_rsvp_vif_done: so_type = %d, pr_protocol = %d\n",
|
||||
so->so_type, so->so_proto->pr_protocol);
|
||||
|
||||
if (so->so_type != SOCK_RAW || so->so_proto->pr_protocol != IPPROTO_RSVP)
|
||||
return EOPNOTSUPP;
|
||||
if (so->so_type != SOCK_RAW ||
|
||||
so->so_proto->pr_protocol != IPPROTO_RSVP)
|
||||
return EOPNOTSUPP;
|
||||
|
||||
/* Check mbuf. */
|
||||
if (m == NULL || m->m_len != sizeof(int)) {
|
||||
return EINVAL;
|
||||
}
|
||||
i = *(mtod(m, int *));
|
||||
error = sooptcopyin(sopt, &i, sizeof i, sizeof i);
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
s = splnet();
|
||||
s = splnet();
|
||||
|
||||
/* Check vif. */
|
||||
if (!legal_vif_num(i)) {
|
||||
/* Check vif. */
|
||||
if (!legal_vif_num(i)) {
|
||||
splx(s);
|
||||
return EADDRNOTAVAIL;
|
||||
}
|
||||
|
||||
if (rsvpdebug)
|
||||
printf("ip_rsvp_vif_done: v_rsvpd = %p so = %p\n",
|
||||
viftable[i].v_rsvpd, so);
|
||||
|
||||
viftable[i].v_rsvpd = NULL;
|
||||
/*
|
||||
* This may seem silly, but we need to be sure we don't over-decrement
|
||||
* the RSVP counter, in case something slips up.
|
||||
*/
|
||||
if (viftable[i].v_rsvp_on) {
|
||||
viftable[i].v_rsvp_on = 0;
|
||||
rsvp_on--;
|
||||
}
|
||||
|
||||
splx(s);
|
||||
return EADDRNOTAVAIL;
|
||||
}
|
||||
|
||||
if (rsvpdebug)
|
||||
printf("ip_rsvp_vif_done: v_rsvpd = %p so = %p\n",
|
||||
viftable[i].v_rsvpd, so);
|
||||
|
||||
viftable[i].v_rsvpd = NULL;
|
||||
/* This may seem silly, but we need to be sure we don't over-decrement
|
||||
* the RSVP counter, in case something slips up.
|
||||
*/
|
||||
if (viftable[i].v_rsvp_on) {
|
||||
viftable[i].v_rsvp_on = 0;
|
||||
rsvp_on--;
|
||||
}
|
||||
|
||||
splx(s);
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -35,7 +35,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)ip_mroute.h 8.1 (Berkeley) 6/10/93
|
||||
* $Id$
|
||||
* $Id: ip_mroute.h,v 1.13 1997/02/22 09:41:35 peter Exp $
|
||||
*/
|
||||
|
||||
#ifndef _NETINET_IP_MROUTE_H_
|
||||
@ -248,8 +248,10 @@ struct tbf
|
||||
|
||||
#ifdef KERNEL
|
||||
|
||||
extern int (*ip_mrouter_set) __P((int, struct socket *, struct mbuf *));
|
||||
extern int (*ip_mrouter_get) __P((int, struct socket *, struct mbuf **));
|
||||
struct sockopt;
|
||||
|
||||
extern int (*ip_mrouter_set) __P((struct socket *, struct sockopt *));
|
||||
extern int (*ip_mrouter_get) __P((struct socket *, struct sockopt *));
|
||||
extern int (*ip_mrouter_done) __P((void));
|
||||
#ifdef MROUTING
|
||||
extern int (*mrt_ioctl) __P((int, caddr_t));
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)ip_output.c 8.3 (Berkeley) 1/21/94
|
||||
* $Id: ip_output.c,v 1.79 1998/07/13 12:12:25 bde Exp $
|
||||
* $Id: ip_output.c,v 1.80 1998/08/01 08:44:33 peter Exp $
|
||||
*/
|
||||
|
||||
#define _IP_VHL
|
||||
@ -72,6 +72,10 @@ static MALLOC_DEFINE(M_IPMOPTS, "ip_moptions", "internet multicast options");
|
||||
#undef COMPAT_IPFW
|
||||
#endif
|
||||
|
||||
#ifdef COMPAT_IPFW
|
||||
#include <netinet/ip_fw.h>
|
||||
#endif
|
||||
|
||||
#ifdef IPFIREWALL_FORWARD_DEBUG
|
||||
#define print_ip(a) printf("%ld.%ld.%ld.%ld",(ntohl(a.s_addr)>>24)&0xFF,\
|
||||
(ntohl(a.s_addr)>>16)&0xFF,\
|
||||
@ -85,10 +89,10 @@ static struct mbuf *ip_insertoptions __P((struct mbuf *, struct mbuf *, int *));
|
||||
static void ip_mloopback
|
||||
__P((struct ifnet *, struct mbuf *, struct sockaddr_in *, int));
|
||||
static int ip_getmoptions
|
||||
__P((int, struct ip_moptions *, struct mbuf **));
|
||||
static int ip_pcbopts __P((struct mbuf **, struct mbuf *));
|
||||
__P((struct sockopt *, struct ip_moptions *));
|
||||
static int ip_pcbopts __P((int, struct mbuf **, struct mbuf *));
|
||||
static int ip_setmoptions
|
||||
__P((int, struct ip_moptions **, struct mbuf *));
|
||||
__P((struct sockopt *, struct ip_moptions **));
|
||||
|
||||
#if defined(IPFILTER_LKM) || defined(IPFILTER)
|
||||
int ip_optcopy __P((struct ip *, struct ip *));
|
||||
@ -742,33 +746,43 @@ ip_optcopy(ip, jp)
|
||||
* IP socket option processing.
|
||||
*/
|
||||
int
|
||||
ip_ctloutput(op, so, level, optname, mp, p)
|
||||
int op;
|
||||
ip_ctloutput(so, sopt)
|
||||
struct socket *so;
|
||||
int level, optname;
|
||||
struct mbuf **mp;
|
||||
struct proc *p;
|
||||
struct sockopt *sopt;
|
||||
{
|
||||
register struct inpcb *inp = sotoinpcb(so);
|
||||
register struct mbuf *m = *mp;
|
||||
register int optval = 0;
|
||||
int error = 0;
|
||||
struct inpcb *inp = sotoinpcb(so);
|
||||
int error, optval;
|
||||
|
||||
if (level != IPPROTO_IP) {
|
||||
error = EINVAL;
|
||||
if (op == PRCO_SETOPT && *mp)
|
||||
(void) m_free(*mp);
|
||||
} else switch (op) {
|
||||
error = optval = 0;
|
||||
if (sopt->sopt_level != IPPROTO_IP) {
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
case PRCO_SETOPT:
|
||||
switch (optname) {
|
||||
switch (sopt->sopt_dir) {
|
||||
case SOPT_SET:
|
||||
switch (sopt->sopt_name) {
|
||||
case IP_OPTIONS:
|
||||
#ifdef notyet
|
||||
case IP_RETOPTS:
|
||||
return (ip_pcbopts(optname, &inp->inp_options, m));
|
||||
#else
|
||||
return (ip_pcbopts(&inp->inp_options, m));
|
||||
#endif
|
||||
{
|
||||
struct mbuf *m;
|
||||
if (sopt->sopt_valsize > MLEN) {
|
||||
error = EMSGSIZE;
|
||||
break;
|
||||
}
|
||||
MGET(m, sopt->sopt_p ? M_WAIT : M_DONTWAIT, MT_HEADER);
|
||||
if (m == 0) {
|
||||
error = ENOBUFS;
|
||||
break;
|
||||
}
|
||||
m->m_len = sopt->sopt_valsize;
|
||||
error = sooptcopyin(sopt, mtod(m, char *), m->m_len,
|
||||
m->m_len);
|
||||
|
||||
return (ip_pcbopts(sopt->sopt_name, &inp->inp_options,
|
||||
m));
|
||||
}
|
||||
|
||||
case IP_TOS:
|
||||
case IP_TTL:
|
||||
@ -776,41 +790,40 @@ ip_ctloutput(op, so, level, optname, mp, p)
|
||||
case IP_RECVRETOPTS:
|
||||
case IP_RECVDSTADDR:
|
||||
case IP_RECVIF:
|
||||
if (m == 0 || m->m_len != sizeof(int))
|
||||
error = EINVAL;
|
||||
else {
|
||||
optval = *mtod(m, int *);
|
||||
switch (optname) {
|
||||
error = sooptcopyin(sopt, &optval, sizeof optval,
|
||||
sizeof optval);
|
||||
if (error)
|
||||
break;
|
||||
|
||||
case IP_TOS:
|
||||
inp->inp_ip_tos = optval;
|
||||
break;
|
||||
switch (sopt->sopt_name) {
|
||||
case IP_TOS:
|
||||
inp->inp_ip_tos = optval;
|
||||
break;
|
||||
|
||||
case IP_TTL:
|
||||
inp->inp_ip_ttl = optval;
|
||||
break;
|
||||
case IP_TTL:
|
||||
inp->inp_ip_ttl = optval;
|
||||
break;
|
||||
#define OPTSET(bit) \
|
||||
if (optval) \
|
||||
inp->inp_flags |= bit; \
|
||||
else \
|
||||
inp->inp_flags &= ~bit;
|
||||
|
||||
case IP_RECVOPTS:
|
||||
OPTSET(INP_RECVOPTS);
|
||||
break;
|
||||
case IP_RECVOPTS:
|
||||
OPTSET(INP_RECVOPTS);
|
||||
break;
|
||||
|
||||
case IP_RECVRETOPTS:
|
||||
OPTSET(INP_RECVRETOPTS);
|
||||
break;
|
||||
case IP_RECVRETOPTS:
|
||||
OPTSET(INP_RECVRETOPTS);
|
||||
break;
|
||||
|
||||
case IP_RECVDSTADDR:
|
||||
OPTSET(INP_RECVDSTADDR);
|
||||
break;
|
||||
case IP_RECVDSTADDR:
|
||||
OPTSET(INP_RECVDSTADDR);
|
||||
break;
|
||||
|
||||
case IP_RECVIF:
|
||||
OPTSET(INP_RECVIF);
|
||||
break;
|
||||
}
|
||||
case IP_RECVIF:
|
||||
OPTSET(INP_RECVIF);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
#undef OPTSET
|
||||
@ -821,36 +834,34 @@ ip_ctloutput(op, so, level, optname, mp, p)
|
||||
case IP_MULTICAST_LOOP:
|
||||
case IP_ADD_MEMBERSHIP:
|
||||
case IP_DROP_MEMBERSHIP:
|
||||
error = ip_setmoptions(optname, &inp->inp_moptions, m);
|
||||
error = ip_setmoptions(sopt, &inp->inp_moptions);
|
||||
break;
|
||||
|
||||
case IP_PORTRANGE:
|
||||
if (m == 0 || m->m_len != sizeof(int))
|
||||
error = sooptcopyin(sopt, &optval, sizeof optval,
|
||||
sizeof optval);
|
||||
if (error)
|
||||
break;
|
||||
|
||||
switch (optval) {
|
||||
case IP_PORTRANGE_DEFAULT:
|
||||
inp->inp_flags &= ~(INP_LOWPORT);
|
||||
inp->inp_flags &= ~(INP_HIGHPORT);
|
||||
break;
|
||||
|
||||
case IP_PORTRANGE_HIGH:
|
||||
inp->inp_flags &= ~(INP_LOWPORT);
|
||||
inp->inp_flags |= INP_HIGHPORT;
|
||||
break;
|
||||
|
||||
case IP_PORTRANGE_LOW:
|
||||
inp->inp_flags &= ~(INP_HIGHPORT);
|
||||
inp->inp_flags |= INP_LOWPORT;
|
||||
break;
|
||||
|
||||
default:
|
||||
error = EINVAL;
|
||||
else {
|
||||
optval = *mtod(m, int *);
|
||||
|
||||
switch (optval) {
|
||||
|
||||
case IP_PORTRANGE_DEFAULT:
|
||||
inp->inp_flags &= ~(INP_LOWPORT);
|
||||
inp->inp_flags &= ~(INP_HIGHPORT);
|
||||
break;
|
||||
|
||||
case IP_PORTRANGE_HIGH:
|
||||
inp->inp_flags &= ~(INP_LOWPORT);
|
||||
inp->inp_flags |= INP_HIGHPORT;
|
||||
break;
|
||||
|
||||
case IP_PORTRANGE_LOW:
|
||||
inp->inp_flags &= ~(INP_HIGHPORT);
|
||||
inp->inp_flags |= INP_LOWPORT;
|
||||
break;
|
||||
|
||||
default:
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -858,21 +869,19 @@ ip_ctloutput(op, so, level, optname, mp, p)
|
||||
error = ENOPROTOOPT;
|
||||
break;
|
||||
}
|
||||
if (m)
|
||||
(void)m_free(m);
|
||||
break;
|
||||
|
||||
case PRCO_GETOPT:
|
||||
switch (optname) {
|
||||
case SOPT_GET:
|
||||
switch (sopt->sopt_name) {
|
||||
case IP_OPTIONS:
|
||||
case IP_RETOPTS:
|
||||
*mp = m = m_get(M_WAIT, MT_SOOPTS);
|
||||
if (inp->inp_options) {
|
||||
m->m_len = inp->inp_options->m_len;
|
||||
bcopy(mtod(inp->inp_options, void *),
|
||||
mtod(m, void *), m->m_len);
|
||||
} else
|
||||
m->m_len = 0;
|
||||
if (inp->inp_options)
|
||||
error = sooptcopyout(sopt,
|
||||
mtod(inp->inp_options,
|
||||
char *),
|
||||
inp->inp_options->m_len);
|
||||
else
|
||||
sopt->sopt_valsize = 0;
|
||||
break;
|
||||
|
||||
case IP_TOS:
|
||||
@ -881,9 +890,8 @@ ip_ctloutput(op, so, level, optname, mp, p)
|
||||
case IP_RECVRETOPTS:
|
||||
case IP_RECVDSTADDR:
|
||||
case IP_RECVIF:
|
||||
*mp = m = m_get(M_WAIT, MT_SOOPTS);
|
||||
m->m_len = sizeof(int);
|
||||
switch (optname) {
|
||||
case IP_PORTRANGE:
|
||||
switch (sopt->sopt_name) {
|
||||
|
||||
case IP_TOS:
|
||||
optval = inp->inp_ip_tos;
|
||||
@ -910,8 +918,17 @@ ip_ctloutput(op, so, level, optname, mp, p)
|
||||
case IP_RECVIF:
|
||||
optval = OPTBIT(INP_RECVIF);
|
||||
break;
|
||||
|
||||
case IP_PORTRANGE:
|
||||
if (inp->inp_flags & INP_HIGHPORT)
|
||||
optval = IP_PORTRANGE_HIGH;
|
||||
else if (inp->inp_flags & INP_LOWPORT)
|
||||
optval = IP_PORTRANGE_LOW;
|
||||
else
|
||||
optval = 0;
|
||||
break;
|
||||
}
|
||||
*mtod(m, int *) = optval;
|
||||
error = sooptcopyout(sopt, &optval, sizeof optval);
|
||||
break;
|
||||
|
||||
case IP_MULTICAST_IF:
|
||||
@ -920,21 +937,7 @@ ip_ctloutput(op, so, level, optname, mp, p)
|
||||
case IP_MULTICAST_LOOP:
|
||||
case IP_ADD_MEMBERSHIP:
|
||||
case IP_DROP_MEMBERSHIP:
|
||||
error = ip_getmoptions(optname, inp->inp_moptions, mp);
|
||||
break;
|
||||
|
||||
case IP_PORTRANGE:
|
||||
*mp = m = m_get(M_WAIT, MT_SOOPTS);
|
||||
m->m_len = sizeof(int);
|
||||
|
||||
if (inp->inp_flags & INP_HIGHPORT)
|
||||
optval = IP_PORTRANGE_HIGH;
|
||||
else if (inp->inp_flags & INP_LOWPORT)
|
||||
optval = IP_PORTRANGE_LOW;
|
||||
else
|
||||
optval = 0;
|
||||
|
||||
*mtod(m, int *) = optval;
|
||||
error = ip_getmoptions(sopt, inp->inp_moptions);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -952,12 +955,8 @@ ip_ctloutput(op, so, level, optname, mp, p)
|
||||
* with destination address if source routed.
|
||||
*/
|
||||
static int
|
||||
#ifdef notyet
|
||||
ip_pcbopts(optname, pcbopt, m)
|
||||
int optname;
|
||||
#else
|
||||
ip_pcbopts(pcbopt, m)
|
||||
#endif
|
||||
struct mbuf **pcbopt;
|
||||
register struct mbuf *m;
|
||||
{
|
||||
@ -1053,24 +1052,29 @@ ip_pcbopts(pcbopt, m)
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX
|
||||
* The whole multicast option thing needs to be re-thought.
|
||||
* Several of these options are equally applicable to non-multicast
|
||||
* transmission, and one (IP_MULTICAST_TTL) totally duplicates a
|
||||
* standard option (IP_TTL).
|
||||
*/
|
||||
/*
|
||||
* Set the IP multicast options in response to user setsockopt().
|
||||
*/
|
||||
static int
|
||||
ip_setmoptions(optname, imop, m)
|
||||
int optname;
|
||||
ip_setmoptions(sopt, imop)
|
||||
struct sockopt *sopt;
|
||||
struct ip_moptions **imop;
|
||||
struct mbuf *m;
|
||||
{
|
||||
register int error = 0;
|
||||
u_char loop;
|
||||
register int i;
|
||||
int error = 0;
|
||||
int i;
|
||||
struct in_addr addr;
|
||||
register struct ip_mreq *mreq;
|
||||
register struct ifnet *ifp;
|
||||
register struct ip_moptions *imo = *imop;
|
||||
struct ip_mreq mreq;
|
||||
struct ifnet *ifp;
|
||||
struct ip_moptions *imo = *imop;
|
||||
struct route ro;
|
||||
register struct sockaddr_in *dst;
|
||||
struct sockaddr_in *dst;
|
||||
int s;
|
||||
|
||||
if (imo == NULL) {
|
||||
@ -1091,18 +1095,16 @@ ip_setmoptions(optname, imop, m)
|
||||
imo->imo_num_memberships = 0;
|
||||
}
|
||||
|
||||
switch (optname) {
|
||||
switch (sopt->sopt_name) {
|
||||
/* store an index number for the vif you wanna use in the send */
|
||||
case IP_MULTICAST_VIF:
|
||||
if (!legal_vif_num) {
|
||||
if (legal_vif_num == 0) {
|
||||
error = EOPNOTSUPP;
|
||||
break;
|
||||
}
|
||||
if (m == NULL || m->m_len != sizeof(int)) {
|
||||
error = EINVAL;
|
||||
error = sooptcopyin(sopt, &i, sizeof i, sizeof i);
|
||||
if (error)
|
||||
break;
|
||||
}
|
||||
i = *(mtod(m, int *));
|
||||
if (!legal_vif_num(i) && (i != -1)) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
@ -1114,11 +1116,9 @@ ip_setmoptions(optname, imop, m)
|
||||
/*
|
||||
* Select the interface for outgoing multicast packets.
|
||||
*/
|
||||
if (m == NULL || m->m_len != sizeof(struct in_addr)) {
|
||||
error = EINVAL;
|
||||
error = sooptcopyin(sopt, &addr, sizeof addr, sizeof addr);
|
||||
if (error)
|
||||
break;
|
||||
}
|
||||
addr = *(mtod(m, struct in_addr *));
|
||||
/*
|
||||
* INADDR_ANY is used to remove a previous selection.
|
||||
* When no interface is selected, a default one is
|
||||
@ -1147,25 +1147,50 @@ ip_setmoptions(optname, imop, m)
|
||||
case IP_MULTICAST_TTL:
|
||||
/*
|
||||
* Set the IP time-to-live for outgoing multicast packets.
|
||||
* The original multicast API required a char argument,
|
||||
* which is inconsistent with the rest of the socket API.
|
||||
* We allow either a char or an int.
|
||||
*/
|
||||
if (m == NULL || m->m_len != 1) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
if (sopt->sopt_valsize == 1) {
|
||||
u_char ttl;
|
||||
error = sooptcopyin(sopt, &ttl, 1, 1);
|
||||
if (error)
|
||||
break;
|
||||
imo->imo_multicast_ttl = ttl;
|
||||
} else {
|
||||
u_int ttl;
|
||||
error = sooptcopyin(sopt, &ttl, sizeof ttl,
|
||||
sizeof ttl);
|
||||
if (error)
|
||||
break;
|
||||
if (ttl > 255)
|
||||
error = EINVAL;
|
||||
else
|
||||
imo->imo_multicast_ttl = ttl;
|
||||
}
|
||||
imo->imo_multicast_ttl = *(mtod(m, u_char *));
|
||||
break;
|
||||
|
||||
case IP_MULTICAST_LOOP:
|
||||
/*
|
||||
* Set the loopback flag for outgoing multicast packets.
|
||||
* Must be zero or one.
|
||||
* Must be zero or one. The original multicast API required a
|
||||
* char argument, which is inconsistent with the rest
|
||||
* of the socket API. We allow either a char or an int.
|
||||
*/
|
||||
if (m == NULL || m->m_len != 1 ||
|
||||
(loop = *(mtod(m, u_char *))) > 1) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
if (sopt->sopt_valsize == 1) {
|
||||
u_char loop;
|
||||
error = sooptcopyin(sopt, &loop, 1, 1);
|
||||
if (error)
|
||||
break;
|
||||
imo->imo_multicast_loop = !!loop;
|
||||
} else {
|
||||
u_int loop;
|
||||
error = sooptcopyin(sopt, &loop, sizeof loop,
|
||||
sizeof loop);
|
||||
if (error)
|
||||
break;
|
||||
imo->imo_multicast_loop = !!loop;
|
||||
}
|
||||
imo->imo_multicast_loop = loop;
|
||||
break;
|
||||
|
||||
case IP_ADD_MEMBERSHIP:
|
||||
@ -1173,12 +1198,11 @@ ip_setmoptions(optname, imop, m)
|
||||
* Add a multicast group membership.
|
||||
* Group must be a valid IP multicast address.
|
||||
*/
|
||||
if (m == NULL || m->m_len != sizeof(struct ip_mreq)) {
|
||||
error = EINVAL;
|
||||
error = sooptcopyin(sopt, &mreq, sizeof mreq, sizeof mreq);
|
||||
if (error)
|
||||
break;
|
||||
}
|
||||
mreq = mtod(m, struct ip_mreq *);
|
||||
if (!IN_MULTICAST(ntohl(mreq->imr_multiaddr.s_addr))) {
|
||||
|
||||
if (!IN_MULTICAST(ntohl(mreq.imr_multiaddr.s_addr))) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
@ -1187,12 +1211,12 @@ ip_setmoptions(optname, imop, m)
|
||||
* If no interface address was provided, use the interface of
|
||||
* the route to the given multicast address.
|
||||
*/
|
||||
if (mreq->imr_interface.s_addr == INADDR_ANY) {
|
||||
if (mreq.imr_interface.s_addr == INADDR_ANY) {
|
||||
bzero((caddr_t)&ro, sizeof(ro));
|
||||
dst = (struct sockaddr_in *)&ro.ro_dst;
|
||||
dst->sin_len = sizeof(*dst);
|
||||
dst->sin_family = AF_INET;
|
||||
dst->sin_addr = mreq->imr_multiaddr;
|
||||
dst->sin_addr = mreq.imr_multiaddr;
|
||||
rtalloc(&ro);
|
||||
if (ro.ro_rt == NULL) {
|
||||
error = EADDRNOTAVAIL;
|
||||
@ -1203,7 +1227,7 @@ ip_setmoptions(optname, imop, m)
|
||||
rtfree(ro.ro_rt);
|
||||
}
|
||||
else {
|
||||
INADDR_TO_IFP(mreq->imr_interface, ifp);
|
||||
INADDR_TO_IFP(mreq.imr_interface, ifp);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1222,7 +1246,7 @@ ip_setmoptions(optname, imop, m)
|
||||
for (i = 0; i < imo->imo_num_memberships; ++i) {
|
||||
if (imo->imo_membership[i]->inm_ifp == ifp &&
|
||||
imo->imo_membership[i]->inm_addr.s_addr
|
||||
== mreq->imr_multiaddr.s_addr)
|
||||
== mreq.imr_multiaddr.s_addr)
|
||||
break;
|
||||
}
|
||||
if (i < imo->imo_num_memberships) {
|
||||
@ -1240,7 +1264,7 @@ ip_setmoptions(optname, imop, m)
|
||||
* address list for the given interface.
|
||||
*/
|
||||
if ((imo->imo_membership[i] =
|
||||
in_addmulti(&mreq->imr_multiaddr, ifp)) == NULL) {
|
||||
in_addmulti(&mreq.imr_multiaddr, ifp)) == NULL) {
|
||||
error = ENOBUFS;
|
||||
splx(s);
|
||||
break;
|
||||
@ -1254,12 +1278,11 @@ ip_setmoptions(optname, imop, m)
|
||||
* Drop a multicast group membership.
|
||||
* Group must be a valid IP multicast address.
|
||||
*/
|
||||
if (m == NULL || m->m_len != sizeof(struct ip_mreq)) {
|
||||
error = EINVAL;
|
||||
error = sooptcopyin(sopt, &mreq, sizeof mreq, sizeof mreq);
|
||||
if (error)
|
||||
break;
|
||||
}
|
||||
mreq = mtod(m, struct ip_mreq *);
|
||||
if (!IN_MULTICAST(ntohl(mreq->imr_multiaddr.s_addr))) {
|
||||
|
||||
if (!IN_MULTICAST(ntohl(mreq.imr_multiaddr.s_addr))) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
@ -1269,10 +1292,10 @@ ip_setmoptions(optname, imop, m)
|
||||
* If an interface address was specified, get a pointer
|
||||
* to its ifnet structure.
|
||||
*/
|
||||
if (mreq->imr_interface.s_addr == INADDR_ANY)
|
||||
if (mreq.imr_interface.s_addr == INADDR_ANY)
|
||||
ifp = NULL;
|
||||
else {
|
||||
INADDR_TO_IFP(mreq->imr_interface, ifp);
|
||||
INADDR_TO_IFP(mreq.imr_interface, ifp);
|
||||
if (ifp == NULL) {
|
||||
error = EADDRNOTAVAIL;
|
||||
splx(s);
|
||||
@ -1286,7 +1309,7 @@ ip_setmoptions(optname, imop, m)
|
||||
if ((ifp == NULL ||
|
||||
imo->imo_membership[i]->inm_ifp == ifp) &&
|
||||
imo->imo_membership[i]->inm_addr.s_addr ==
|
||||
mreq->imr_multiaddr.s_addr)
|
||||
mreq.imr_multiaddr.s_addr)
|
||||
break;
|
||||
}
|
||||
if (i == imo->imo_num_memberships) {
|
||||
@ -1332,57 +1355,63 @@ ip_setmoptions(optname, imop, m)
|
||||
* Return the IP multicast options in response to user getsockopt().
|
||||
*/
|
||||
static int
|
||||
ip_getmoptions(optname, imo, mp)
|
||||
int optname;
|
||||
ip_getmoptions(sopt, imo)
|
||||
struct sockopt *sopt;
|
||||
register struct ip_moptions *imo;
|
||||
register struct mbuf **mp;
|
||||
{
|
||||
u_char *ttl;
|
||||
u_char *loop;
|
||||
struct in_addr *addr;
|
||||
struct in_addr addr;
|
||||
struct in_ifaddr *ia;
|
||||
int error, optval;
|
||||
u_char coptval;
|
||||
|
||||
*mp = m_get(M_WAIT, MT_SOOPTS);
|
||||
|
||||
switch (optname) {
|
||||
|
||||
error = 0;
|
||||
switch (sopt->sopt_name) {
|
||||
case IP_MULTICAST_VIF:
|
||||
if (imo != NULL)
|
||||
*(mtod(*mp, int *)) = imo->imo_multicast_vif;
|
||||
optval = imo->imo_multicast_vif;
|
||||
else
|
||||
*(mtod(*mp, int *)) = -1;
|
||||
(*mp)->m_len = sizeof(int);
|
||||
return(0);
|
||||
optval = -1;
|
||||
error = sooptcopyout(sopt, &optval, sizeof optval);
|
||||
break;
|
||||
|
||||
case IP_MULTICAST_IF:
|
||||
addr = mtod(*mp, struct in_addr *);
|
||||
(*mp)->m_len = sizeof(struct in_addr);
|
||||
if (imo == NULL || imo->imo_multicast_ifp == NULL)
|
||||
addr->s_addr = INADDR_ANY;
|
||||
addr.s_addr = INADDR_ANY;
|
||||
else {
|
||||
IFP_TO_IA(imo->imo_multicast_ifp, ia);
|
||||
addr->s_addr = (ia == NULL) ? INADDR_ANY
|
||||
: IA_SIN(ia)->sin_addr.s_addr;
|
||||
addr.s_addr = (ia == NULL) ? INADDR_ANY
|
||||
: IA_SIN(ia)->sin_addr.s_addr;
|
||||
}
|
||||
return (0);
|
||||
error = sooptcopyout(sopt, &addr, sizeof addr);
|
||||
break;
|
||||
|
||||
case IP_MULTICAST_TTL:
|
||||
ttl = mtod(*mp, u_char *);
|
||||
(*mp)->m_len = 1;
|
||||
*ttl = (imo == NULL) ? IP_DEFAULT_MULTICAST_TTL
|
||||
: imo->imo_multicast_ttl;
|
||||
return (0);
|
||||
if (imo == 0)
|
||||
optval = coptval = IP_DEFAULT_MULTICAST_TTL;
|
||||
else
|
||||
optval = coptval = imo->imo_multicast_ttl;
|
||||
if (sopt->sopt_valsize == 1)
|
||||
error = sooptcopyout(sopt, &coptval, 1);
|
||||
else
|
||||
error = sooptcopyout(sopt, &optval, sizeof optval);
|
||||
break;
|
||||
|
||||
case IP_MULTICAST_LOOP:
|
||||
loop = mtod(*mp, u_char *);
|
||||
(*mp)->m_len = 1;
|
||||
*loop = (imo == NULL) ? IP_DEFAULT_MULTICAST_LOOP
|
||||
: imo->imo_multicast_loop;
|
||||
return (0);
|
||||
if (imo == 0)
|
||||
optval = coptval = IP_DEFAULT_MULTICAST_LOOP;
|
||||
else
|
||||
optval = coptval = imo->imo_multicast_loop;
|
||||
if (sopt->sopt_valsize == 1)
|
||||
error = sooptcopyout(sopt, &coptval, 1);
|
||||
else
|
||||
error = sooptcopyout(sopt, &optval, sizeof optval);
|
||||
break;
|
||||
|
||||
default:
|
||||
return (EOPNOTSUPP);
|
||||
error = ENOPROTOOPT;
|
||||
break;
|
||||
}
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)ip_var.h 8.2 (Berkeley) 1/9/95
|
||||
* $Id: ip_var.h,v 1.42 1998/07/06 03:20:18 julian Exp $
|
||||
* $Id: ip_var.h,v 1.43 1998/07/13 12:20:07 bde Exp $
|
||||
*/
|
||||
|
||||
#ifndef _NETINET_IP_VAR_H_
|
||||
@ -160,8 +160,10 @@ struct ipstat {
|
||||
#define IP_ROUTETOIF SO_DONTROUTE /* bypass routing tables */
|
||||
#define IP_ALLOWBROADCAST SO_BROADCAST /* can send broadcast packets */
|
||||
|
||||
struct ip;
|
||||
struct inpcb;
|
||||
struct route;
|
||||
struct sockopt;
|
||||
|
||||
extern struct ipstat ipstat;
|
||||
extern u_short ip_id; /* ip packet ctr, for ids */
|
||||
@ -175,8 +177,7 @@ extern u_long (*ip_mcast_src) __P((int));
|
||||
extern int rsvp_on;
|
||||
extern struct pr_usrreqs rip_usrreqs;
|
||||
|
||||
int ip_ctloutput __P((int, struct socket *, int, int, struct mbuf **,
|
||||
struct proc *));
|
||||
int ip_ctloutput __P((struct socket *, struct sockopt *sopt));
|
||||
void ip_drain __P((void));
|
||||
void ip_freemoptions __P((struct ip_moptions *));
|
||||
void ip_init __P((void));
|
||||
@ -190,8 +191,7 @@ void ip_slowtimo __P((void));
|
||||
struct mbuf *
|
||||
ip_srcroute __P((void));
|
||||
void ip_stripoptions __P((struct mbuf *, struct mbuf *));
|
||||
int rip_ctloutput __P((int, struct socket *, int, int, struct mbuf **,
|
||||
struct proc *p));
|
||||
int rip_ctloutput __P((struct socket *, struct sockopt *));
|
||||
void rip_ctlinput __P((int, struct sockaddr *, void *));
|
||||
void rip_init __P((void));
|
||||
void rip_input __P((struct mbuf *, int));
|
||||
@ -200,8 +200,8 @@ void ipip_input __P((struct mbuf *, int));
|
||||
void rsvp_input __P((struct mbuf *, int));
|
||||
int ip_rsvp_init __P((struct socket *));
|
||||
int ip_rsvp_done __P((void));
|
||||
int ip_rsvp_vif_init __P((struct socket *, struct mbuf *));
|
||||
int ip_rsvp_vif_done __P((struct socket *, struct mbuf *));
|
||||
int ip_rsvp_vif_init __P((struct socket *, struct sockopt *));
|
||||
int ip_rsvp_vif_done __P((struct socket *, struct sockopt *));
|
||||
void ip_rsvp_force_done __P((struct socket *));
|
||||
|
||||
#ifdef IPDIVERT
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)raw_ip.c 8.7 (Berkeley) 5/15/95
|
||||
* $Id: raw_ip.c,v 1.53 1998/03/28 10:18:24 bde Exp $
|
||||
* $Id: raw_ip.c,v 1.54 1998/05/15 20:11:34 wollman Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -225,101 +225,127 @@ rip_output(m, so, dst)
|
||||
* Raw IP socket option processing.
|
||||
*/
|
||||
int
|
||||
rip_ctloutput(op, so, level, optname, m, p)
|
||||
int op;
|
||||
rip_ctloutput(so, sopt)
|
||||
struct socket *so;
|
||||
int level, optname;
|
||||
struct mbuf **m;
|
||||
struct proc *p;
|
||||
struct sockopt *sopt;
|
||||
{
|
||||
register struct inpcb *inp = sotoinpcb(so);
|
||||
register int error;
|
||||
struct inpcb *inp = sotoinpcb(so);
|
||||
int error, optval;
|
||||
|
||||
if (level != IPPROTO_IP) {
|
||||
if (op == PRCO_SETOPT && *m)
|
||||
(void)m_free(*m);
|
||||
if (sopt->sopt_level != IPPROTO_IP)
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
switch (optname) {
|
||||
error = 0;
|
||||
|
||||
case IP_HDRINCL:
|
||||
error = 0;
|
||||
if (op == PRCO_SETOPT) {
|
||||
if (m == 0 || *m == 0 || (*m)->m_len < sizeof (int))
|
||||
error = EINVAL;
|
||||
else if (*mtod(*m, int *))
|
||||
switch (sopt->sopt_dir) {
|
||||
case SOPT_GET:
|
||||
switch (sopt->sopt_name) {
|
||||
case IP_HDRINCL:
|
||||
optval = inp->inp_flags & INP_HDRINCL;
|
||||
error = sooptcopyout(sopt, &optval, sizeof optval);
|
||||
break;
|
||||
|
||||
#ifdef COMPAT_IPFW
|
||||
case IP_FW_GET:
|
||||
if (ip_fw_ctl_ptr == 0)
|
||||
error = ENOPROTOOPT;
|
||||
else
|
||||
error = ip_fw_ctl_ptr(sopt);
|
||||
break;
|
||||
|
||||
case IP_NAT:
|
||||
if (ip_nat_ctl_ptr == 0)
|
||||
error = ENOPROTOOPT;
|
||||
else
|
||||
error = ip_nat_ctl_ptr(sopt);
|
||||
break;
|
||||
#endif /* COMPAT_IPFW */
|
||||
|
||||
case MRT_INIT:
|
||||
case MRT_DONE:
|
||||
case MRT_ADD_VIF:
|
||||
case MRT_DEL_VIF:
|
||||
case MRT_ADD_MFC:
|
||||
case MRT_DEL_MFC:
|
||||
case MRT_VERSION:
|
||||
case MRT_ASSERT:
|
||||
error = ip_mrouter_get(so, sopt);
|
||||
break;
|
||||
|
||||
default:
|
||||
error = ip_ctloutput(so, sopt);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case SOPT_SET:
|
||||
switch (sopt->sopt_name) {
|
||||
case IP_HDRINCL:
|
||||
error = sooptcopyin(sopt, &optval, sizeof optval,
|
||||
sizeof optval);
|
||||
if (error)
|
||||
break;
|
||||
if (optval)
|
||||
inp->inp_flags |= INP_HDRINCL;
|
||||
else
|
||||
inp->inp_flags &= ~INP_HDRINCL;
|
||||
if (*m)
|
||||
(void)m_free(*m);
|
||||
} else {
|
||||
*m = m_get(M_WAIT, MT_SOOPTS);
|
||||
(*m)->m_len = sizeof (int);
|
||||
*mtod(*m, int *) = inp->inp_flags & INP_HDRINCL;
|
||||
}
|
||||
return (error);
|
||||
break;
|
||||
|
||||
#ifdef COMPAT_IPFW
|
||||
case IP_FW_GET:
|
||||
if (ip_fw_ctl_ptr == NULL || op == PRCO_SETOPT) {
|
||||
if (*m) (void)m_free(*m);
|
||||
return(EINVAL);
|
||||
}
|
||||
return (*ip_fw_ctl_ptr)(optname, m);
|
||||
case IP_FW_ADD:
|
||||
case IP_FW_DEL:
|
||||
case IP_FW_FLUSH:
|
||||
case IP_FW_ZERO:
|
||||
if (ip_fw_ctl_ptr == 0)
|
||||
error = ENOPROTOOPT;
|
||||
else
|
||||
error = ip_fw_ctl_ptr(sopt);
|
||||
break;
|
||||
|
||||
case IP_FW_ADD:
|
||||
case IP_FW_DEL:
|
||||
case IP_FW_FLUSH:
|
||||
case IP_FW_ZERO:
|
||||
if (ip_fw_ctl_ptr == NULL || op != PRCO_SETOPT) {
|
||||
if (*m) (void)m_free(*m);
|
||||
return(EINVAL);
|
||||
}
|
||||
return (*ip_fw_ctl_ptr)(optname, m);
|
||||
case IP_NAT:
|
||||
if (ip_nat_ctl_ptr == 0)
|
||||
error = ENOPROTOOPT;
|
||||
else
|
||||
error = ip_nat_ctl_ptr(sopt);
|
||||
break;
|
||||
#endif /* COMPAT_IPFW */
|
||||
|
||||
case IP_NAT:
|
||||
if (ip_nat_ctl_ptr == NULL) {
|
||||
if (*m) (void)m_free(*m);
|
||||
return(EINVAL);
|
||||
}
|
||||
return (*ip_nat_ctl_ptr)(op, m);
|
||||
case IP_RSVP_ON:
|
||||
error = ip_rsvp_init(so);
|
||||
break;
|
||||
|
||||
#endif
|
||||
case IP_RSVP_ON:
|
||||
return ip_rsvp_init(so);
|
||||
case IP_RSVP_OFF:
|
||||
error = ip_rsvp_done();
|
||||
break;
|
||||
|
||||
/* XXX - should be combined */
|
||||
case IP_RSVP_VIF_ON:
|
||||
error = ip_rsvp_vif_init(so, sopt);
|
||||
break;
|
||||
|
||||
case IP_RSVP_VIF_OFF:
|
||||
error = ip_rsvp_vif_done(so, sopt);
|
||||
break;
|
||||
|
||||
case MRT_INIT:
|
||||
case MRT_DONE:
|
||||
case MRT_ADD_VIF:
|
||||
case MRT_DEL_VIF:
|
||||
case MRT_ADD_MFC:
|
||||
case MRT_DEL_MFC:
|
||||
case MRT_VERSION:
|
||||
case MRT_ASSERT:
|
||||
error = ip_mrouter_set(so, sopt);
|
||||
break;
|
||||
|
||||
default:
|
||||
error = ip_ctloutput(so, sopt);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case IP_RSVP_OFF:
|
||||
return ip_rsvp_done();
|
||||
break;
|
||||
|
||||
case IP_RSVP_VIF_ON:
|
||||
return ip_rsvp_vif_init(so, *m);
|
||||
|
||||
case IP_RSVP_VIF_OFF:
|
||||
return ip_rsvp_vif_done(so, *m);
|
||||
|
||||
case MRT_INIT:
|
||||
case MRT_DONE:
|
||||
case MRT_ADD_VIF:
|
||||
case MRT_DEL_VIF:
|
||||
case MRT_ADD_MFC:
|
||||
case MRT_DEL_MFC:
|
||||
case MRT_VERSION:
|
||||
case MRT_ASSERT:
|
||||
if (op == PRCO_SETOPT) {
|
||||
error = ip_mrouter_set(optname, so, *m);
|
||||
if (*m)
|
||||
(void)m_free(*m);
|
||||
} else if (op == PRCO_GETOPT) {
|
||||
error = ip_mrouter_get(optname, so, m);
|
||||
} else
|
||||
error = EINVAL;
|
||||
return (error);
|
||||
}
|
||||
return (ip_ctloutput(op, so, level, optname, m, p));
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -340,7 +366,7 @@ rip_ctlinput(cmd, sa, vip)
|
||||
int err;
|
||||
int flags;
|
||||
|
||||
switch(cmd) {
|
||||
switch (cmd) {
|
||||
case PRC_IFDOWN:
|
||||
for (ia = in_ifaddrhead.tqh_first; ia;
|
||||
ia = ia->ia_link.tqe_next) {
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* From: @(#)tcp_usrreq.c 8.2 (Berkeley) 1/3/94
|
||||
* $Id: tcp_usrreq.c,v 1.36 1997/12/18 09:50:38 davidg Exp $
|
||||
* $Id: tcp_usrreq.c,v 1.37 1998/01/27 09:15:11 davidg Exp $
|
||||
*/
|
||||
|
||||
#include "opt_tcpdebug.h"
|
||||
@ -560,104 +560,107 @@ tcp_connect(tp, nam, p)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* The new sockopt interface makes it possible for us to block in the
|
||||
* copyin/out step (if we take a page fault). Taking a page fault at
|
||||
* splnet() is probably a Bad Thing. (Since sockets and pcbs both now
|
||||
* use TSM, there probably isn't any need for this function to run at
|
||||
* splnet() any more. This needs more examination.)
|
||||
*/
|
||||
int
|
||||
tcp_ctloutput(op, so, level, optname, mp, p)
|
||||
int op;
|
||||
tcp_ctloutput(so, sopt)
|
||||
struct socket *so;
|
||||
int level, optname;
|
||||
struct mbuf **mp;
|
||||
struct proc *p;
|
||||
struct sockopt *sopt;
|
||||
{
|
||||
int error = 0, s;
|
||||
struct inpcb *inp;
|
||||
register struct tcpcb *tp;
|
||||
register struct mbuf *m;
|
||||
register int i;
|
||||
int error, opt, optval, s;
|
||||
struct inpcb *inp;
|
||||
struct tcpcb *tp;
|
||||
struct mbuf *m;
|
||||
|
||||
s = splnet();
|
||||
error = 0;
|
||||
s = splnet(); /* XXX */
|
||||
inp = sotoinpcb(so);
|
||||
if (inp == NULL) {
|
||||
splx(s);
|
||||
if (op == PRCO_SETOPT && *mp)
|
||||
(void) m_free(*mp);
|
||||
return (ECONNRESET);
|
||||
}
|
||||
if (level != IPPROTO_TCP) {
|
||||
error = ip_ctloutput(op, so, level, optname, mp, p);
|
||||
if (sopt->sopt_level != IPPROTO_TCP) {
|
||||
error = ip_ctloutput(so, sopt);
|
||||
splx(s);
|
||||
return (error);
|
||||
}
|
||||
tp = intotcpcb(inp);
|
||||
|
||||
switch (op) {
|
||||
|
||||
case PRCO_SETOPT:
|
||||
m = *mp;
|
||||
switch (optname) {
|
||||
|
||||
switch (sopt->sopt_dir) {
|
||||
case SOPT_SET:
|
||||
switch (sopt->sopt_name) {
|
||||
case TCP_NODELAY:
|
||||
if (m == NULL || m->m_len < sizeof (int))
|
||||
error = EINVAL;
|
||||
else if (*mtod(m, int *))
|
||||
tp->t_flags |= TF_NODELAY;
|
||||
case TCP_NOOPT:
|
||||
case TCP_NOPUSH:
|
||||
error = sooptcopyin(sopt, &optval, sizeof optval,
|
||||
sizeof optval);
|
||||
if (error)
|
||||
break;
|
||||
|
||||
switch (sopt->sopt_name) {
|
||||
case TCP_NODELAY:
|
||||
opt = TF_NODELAY;
|
||||
break;
|
||||
case TCP_NOOPT:
|
||||
opt = TF_NOOPT;
|
||||
break;
|
||||
case TCP_NOPUSH:
|
||||
opt = TF_NOPUSH;
|
||||
break;
|
||||
default:
|
||||
opt = 0; /* dead code to fool gcc */
|
||||
break;
|
||||
}
|
||||
|
||||
if (optval)
|
||||
tp->t_flags |= opt;
|
||||
else
|
||||
tp->t_flags &= ~TF_NODELAY;
|
||||
tp->t_flags &= ~opt;
|
||||
break;
|
||||
|
||||
case TCP_MAXSEG:
|
||||
if (m && (i = *mtod(m, int *)) > 0 && i <= tp->t_maxseg)
|
||||
tp->t_maxseg = i;
|
||||
else
|
||||
error = EINVAL;
|
||||
break;
|
||||
error = sooptcopyin(sopt, &optval, sizeof optval,
|
||||
sizeof optval);
|
||||
if (error)
|
||||
break;
|
||||
|
||||
case TCP_NOOPT:
|
||||
if (m == NULL || m->m_len < sizeof (int))
|
||||
error = EINVAL;
|
||||
else if (*mtod(m, int *))
|
||||
tp->t_flags |= TF_NOOPT;
|
||||
if (optval > 0 && optval <= tp->t_maxseg)
|
||||
tp->t_maxseg = optval;
|
||||
else
|
||||
tp->t_flags &= ~TF_NOOPT;
|
||||
break;
|
||||
|
||||
case TCP_NOPUSH:
|
||||
if (m == NULL || m->m_len < sizeof (int))
|
||||
error = EINVAL;
|
||||
else if (*mtod(m, int *))
|
||||
tp->t_flags |= TF_NOPUSH;
|
||||
else
|
||||
tp->t_flags &= ~TF_NOPUSH;
|
||||
break;
|
||||
|
||||
default:
|
||||
error = ENOPROTOOPT;
|
||||
break;
|
||||
}
|
||||
if (m)
|
||||
(void) m_free(m);
|
||||
break;
|
||||
|
||||
case PRCO_GETOPT:
|
||||
*mp = m = m_get(M_WAIT, MT_SOOPTS);
|
||||
m->m_len = sizeof(int);
|
||||
|
||||
switch (optname) {
|
||||
case SOPT_GET:
|
||||
switch (sopt->sopt_name) {
|
||||
case TCP_NODELAY:
|
||||
*mtod(m, int *) = tp->t_flags & TF_NODELAY;
|
||||
optval = tp->t_flags & TF_NODELAY;
|
||||
break;
|
||||
case TCP_MAXSEG:
|
||||
*mtod(m, int *) = tp->t_maxseg;
|
||||
optval = tp->t_maxseg;
|
||||
break;
|
||||
case TCP_NOOPT:
|
||||
*mtod(m, int *) = tp->t_flags & TF_NOOPT;
|
||||
optval = tp->t_flags & TF_NOOPT;
|
||||
break;
|
||||
case TCP_NOPUSH:
|
||||
*mtod(m, int *) = tp->t_flags & TF_NOPUSH;
|
||||
optval = tp->t_flags & TF_NOPUSH;
|
||||
break;
|
||||
default:
|
||||
error = ENOPROTOOPT;
|
||||
break;
|
||||
}
|
||||
if (error == 0)
|
||||
error = sooptcopyout(sopt, &optval, sizeof optval);
|
||||
break;
|
||||
}
|
||||
splx(s);
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)tcp_var.h 8.4 (Berkeley) 5/24/95
|
||||
* $Id: tcp_var.h,v 1.45 1998/06/27 07:30:45 jhay Exp $
|
||||
* $Id: tcp_var.h,v 1.46 1998/07/13 11:09:52 bde Exp $
|
||||
*/
|
||||
|
||||
#ifndef _NETINET_TCP_VAR_H_
|
||||
@ -344,8 +344,7 @@ void tcp_canceltimers __P((struct tcpcb *));
|
||||
struct tcpcb *
|
||||
tcp_close __P((struct tcpcb *));
|
||||
void tcp_ctlinput __P((int, struct sockaddr *, void *));
|
||||
int tcp_ctloutput __P((int, struct socket *, int, int, struct mbuf **,
|
||||
struct proc *));
|
||||
int tcp_ctloutput __P((struct socket *, struct sockopt *));
|
||||
struct tcpcb *
|
||||
tcp_drop __P((struct tcpcb *, int));
|
||||
void tcp_drain __P((void));
|
||||
|
@ -33,7 +33,7 @@
|
||||
*
|
||||
* @(#)ipx_ip.c
|
||||
*
|
||||
* $Id: ipx_ip.c,v 1.20 1998/02/09 06:10:20 eivind Exp $
|
||||
* $Id: ipx_ip.c,v 1.21 1998/06/07 17:12:19 dfr Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -316,17 +316,23 @@ struct ifnet *ifp;
|
||||
static struct ifreq ifr_ipxip = {"ipxip0"};
|
||||
|
||||
int
|
||||
ipxip_route(so, m, p)
|
||||
ipxip_route(so, sopt)
|
||||
struct socket *so;
|
||||
register struct mbuf *m;
|
||||
struct proc *p;
|
||||
struct sockopt *sopt;
|
||||
{
|
||||
register struct ipxip_req *rq = mtod(m, struct ipxip_req *);
|
||||
struct sockaddr_ipx *ipx_dst = (struct sockaddr_ipx *)&rq->rq_ipx;
|
||||
struct sockaddr_in *ip_dst = (struct sockaddr_in *)&rq->rq_ip;
|
||||
struct route ro;
|
||||
int error;
|
||||
struct ifnet_en *ifn;
|
||||
struct sockaddr_in *src;
|
||||
struct ipxip_req rq;
|
||||
struct sockaddr_ipx *ipx_dst;
|
||||
struct sockaddr_in *ip_dst;
|
||||
struct route ro;
|
||||
|
||||
error = sooptcopyin(sopt, &rq, sizeof rq, sizeof rq);
|
||||
if (error)
|
||||
return (error);
|
||||
ipx_dst = (struct sockaddr_ipx *)&rq.rq_ipx;
|
||||
ip_dst = (struct sockaddr_in *)&rq.rq_ip;
|
||||
|
||||
/*
|
||||
* First, make sure we already have an IPX address:
|
||||
@ -387,14 +393,14 @@ ipxip_route(so, m, p)
|
||||
ifr_ipxip.ifr_name[4] = '0' + ipxipif.if_unit - 1;
|
||||
ifr_ipxip.ifr_dstaddr = *(struct sockaddr *)ipx_dst;
|
||||
ipx_control(so, (int)SIOCSIFDSTADDR, (caddr_t)&ifr_ipxip,
|
||||
(struct ifnet *)ifn, p);
|
||||
(struct ifnet *)ifn, sopt->sopt_p);
|
||||
|
||||
/* use any of our addresses */
|
||||
satoipx_addr(ifr_ipxip.ifr_addr).x_host =
|
||||
ipx_ifaddr->ia_addr.sipx_addr.x_host;
|
||||
|
||||
return (ipx_control(so, (int)SIOCSIFADDR, (caddr_t)&ifr_ipxip,
|
||||
(struct ifnet *)ifn, p));
|
||||
(struct ifnet *)ifn, sopt->sopt_p));
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -33,7 +33,7 @@
|
||||
*
|
||||
* @(#)ipxip.h
|
||||
*
|
||||
* $Id: ipx_ip.h,v 1.10 1997/05/10 09:58:53 jhay Exp $
|
||||
* $Id: ipx_ip.h,v 1.11 1997/06/26 19:35:50 jhay Exp $
|
||||
*/
|
||||
|
||||
#ifndef _NETIPX_IPXIP_H_
|
||||
@ -53,7 +53,7 @@ struct ifnet_en {
|
||||
|
||||
void ipxip_ctlinput __P((int cmd, struct sockaddr *sa, void *arg));
|
||||
void ipxip_input __P((struct mbuf *m, int hlen));
|
||||
int ipxip_route __P((struct socket *so, struct mbuf *m, struct proc *p));
|
||||
int ipxip_route __P((struct socket *so, struct sockopt *sopt));
|
||||
|
||||
#endif /* KERNEL */
|
||||
|
||||
|
@ -33,7 +33,7 @@
|
||||
*
|
||||
* @(#)ipx_usrreq.c
|
||||
*
|
||||
* $Id: ipx_usrreq.c,v 1.18 1997/12/15 20:31:15 eivind Exp $
|
||||
* $Id: ipx_usrreq.c,v 1.19 1998/02/09 06:10:25 eivind Exp $
|
||||
*/
|
||||
|
||||
#include "opt_ipx.h"
|
||||
@ -310,30 +310,23 @@ ipx_output(ipxp, m0)
|
||||
}
|
||||
|
||||
int
|
||||
ipx_ctloutput(req, so, level, name, value, p)
|
||||
int req, level;
|
||||
ipx_ctloutput(so, sopt)
|
||||
struct socket *so;
|
||||
int name;
|
||||
struct mbuf **value;
|
||||
struct proc *p;
|
||||
struct sockopt *sopt;
|
||||
{
|
||||
register struct mbuf *m;
|
||||
struct ipxpcb *ipxp = sotoipxpcb(so);
|
||||
int mask, error = 0;
|
||||
int mask, error, optval;
|
||||
short soptval;
|
||||
struct ipx ioptval;
|
||||
|
||||
error = 0;
|
||||
if (ipxp == NULL)
|
||||
return (EINVAL);
|
||||
|
||||
switch (req) {
|
||||
|
||||
case PRCO_GETOPT:
|
||||
if (value == NULL)
|
||||
return (EINVAL);
|
||||
m = m_get(M_DONTWAIT, MT_DATA);
|
||||
if (m == NULL)
|
||||
return (ENOBUFS);
|
||||
switch (name) {
|
||||
|
||||
switch (sopt->sopt_dir) {
|
||||
case SOPT_GET:
|
||||
switch (sopt->sopt_name) {
|
||||
case SO_ALL_PACKETS:
|
||||
mask = IPXP_ALL_PACKETS;
|
||||
goto get_flags;
|
||||
@ -345,38 +338,33 @@ ipx_ctloutput(req, so, level, name, value, p)
|
||||
case SO_HEADERS_ON_OUTPUT:
|
||||
mask = IPXP_RAWOUT;
|
||||
get_flags:
|
||||
m->m_len = sizeof(short);
|
||||
*mtod(m, short *) = ipxp->ipxp_flags & mask;
|
||||
soptval = ipxp->ipxp_flags & mask;
|
||||
error = sooptcopyout(sopt, &soptval, sizeof soptval);
|
||||
break;
|
||||
|
||||
case SO_DEFAULT_HEADERS:
|
||||
m->m_len = sizeof(struct ipx);
|
||||
{
|
||||
register struct ipx *ipx = mtod(m, struct ipx *);
|
||||
ipx->ipx_len = 0;
|
||||
ipx->ipx_sum = 0;
|
||||
ipx->ipx_tc = 0;
|
||||
ipx->ipx_pt = ipxp->ipxp_dpt;
|
||||
ipx->ipx_dna = ipxp->ipxp_faddr;
|
||||
ipx->ipx_sna = ipxp->ipxp_laddr;
|
||||
}
|
||||
ioptval.ipx_len = 0;
|
||||
ioptval.ipx_sum = 0;
|
||||
ioptval.ipx_tc = 0;
|
||||
ioptval.ipx_pt = ipxp->ipxp_dpt;
|
||||
ioptval.ipx_dna = ipxp->ipxp_faddr;
|
||||
ioptval.ipx_sna = ipxp->ipxp_laddr;
|
||||
error = sooptcopyout(sopt, &soptval, sizeof soptval);
|
||||
break;
|
||||
|
||||
case SO_SEQNO:
|
||||
m->m_len = sizeof(long);
|
||||
*mtod(m, long *) = ipx_pexseq++;
|
||||
error = sooptcopyout(sopt, &ipx_pexseq,
|
||||
sizeof ipx_pexseq);
|
||||
ipx_pexseq++;
|
||||
break;
|
||||
|
||||
default:
|
||||
error = EINVAL;
|
||||
}
|
||||
*value = m;
|
||||
break;
|
||||
|
||||
case PRCO_SETOPT:
|
||||
switch (name) {
|
||||
int *ok;
|
||||
|
||||
case SOPT_SET:
|
||||
switch (sopt->sopt_name) {
|
||||
case SO_ALL_PACKETS:
|
||||
mask = IPXP_ALL_PACKETS;
|
||||
goto set_head;
|
||||
@ -388,39 +376,38 @@ ipx_ctloutput(req, so, level, name, value, p)
|
||||
case SO_HEADERS_ON_OUTPUT:
|
||||
mask = IPXP_RAWOUT;
|
||||
set_head:
|
||||
if (value && *value) {
|
||||
ok = mtod(*value, int *);
|
||||
if (*ok)
|
||||
ipxp->ipxp_flags |= mask;
|
||||
else
|
||||
ipxp->ipxp_flags &= ~mask;
|
||||
} else error = EINVAL;
|
||||
error = sooptcopyin(sopt, &optval, sizeof optval,
|
||||
sizeof optval);
|
||||
if (error)
|
||||
break;
|
||||
if (optval)
|
||||
ipxp->ipxp_flags |= mask;
|
||||
else
|
||||
ipxp->ipxp_flags &= ~mask;
|
||||
break;
|
||||
|
||||
case SO_DEFAULT_HEADERS:
|
||||
{
|
||||
register struct ipx *ipx
|
||||
= mtod(*value, struct ipx *);
|
||||
ipxp->ipxp_dpt = ipx->ipx_pt;
|
||||
}
|
||||
error = sooptcopyin(sopt, &ioptval, sizeof ioptval,
|
||||
sizeof ioptval);
|
||||
if (error)
|
||||
break;
|
||||
ipxp->ipxp_dpt = ioptval.ipx_pt;
|
||||
break;
|
||||
#ifdef IPXIP
|
||||
case SO_IPXIP_ROUTE:
|
||||
error = ipxip_route(so, *value, p);
|
||||
error = ipxip_route(so, sopt);
|
||||
break;
|
||||
#endif /* IPXIP */
|
||||
#ifdef IPTUNNEL
|
||||
#if 0
|
||||
case SO_IPXTUNNEL_ROUTE:
|
||||
error = ipxtun_route(so, *value, p);
|
||||
error = ipxtun_route(so, sopt);
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
default:
|
||||
error = EINVAL;
|
||||
}
|
||||
if (value && *value)
|
||||
m_freem(*value);
|
||||
break;
|
||||
}
|
||||
return (error);
|
||||
|
@ -33,7 +33,7 @@
|
||||
*
|
||||
* @(#)ipx_var.h
|
||||
*
|
||||
* $Id: ipx_var.h,v 1.9 1998/02/01 20:08:34 bde Exp $
|
||||
* $Id: ipx_var.h,v 1.10 1998/06/07 17:12:20 dfr Exp $
|
||||
*/
|
||||
|
||||
#ifndef _NETIPX_IPX_VAR_H_
|
||||
@ -79,14 +79,14 @@ struct proc;
|
||||
struct route;
|
||||
struct sockaddr;
|
||||
struct socket;
|
||||
struct sockopt;
|
||||
|
||||
void ipx_abort __P((struct ipxpcb *ipxp));
|
||||
u_short ipx_cksum __P((struct mbuf *m, int len));
|
||||
int ipx_control __P((struct socket *so, u_long cmd, caddr_t data,
|
||||
struct ifnet *ifp, struct proc *p));
|
||||
void ipx_ctlinput __P((int cmd, struct sockaddr *arg_as_sa, void *dummy));
|
||||
int ipx_ctloutput __P((int req, struct socket *so, int level, int name,
|
||||
struct mbuf **value, struct proc *p));
|
||||
int ipx_ctloutput __P((struct socket *so, struct sockopt *sopt));
|
||||
void ipx_drop __P((struct ipxpcb *ipxp, int errno));
|
||||
void ipx_init __P((void));
|
||||
void ipx_input __P((struct mbuf *m, struct ipxpcb *ipxp));
|
||||
|
@ -33,7 +33,7 @@
|
||||
*
|
||||
* @(#)spx.h
|
||||
*
|
||||
* $Id: spx.h,v 1.12 1997/05/10 09:58:56 jhay Exp $
|
||||
* $Id: spx.h,v 1.13 1997/06/26 19:36:00 jhay Exp $
|
||||
*/
|
||||
|
||||
#ifndef _NETIPX_SPX_H_
|
||||
@ -173,8 +173,7 @@ extern struct pr_usrreqs spx_usrreqs;
|
||||
extern struct pr_usrreqs spx_usrreq_sps;
|
||||
|
||||
void spx_ctlinput __P((int cmd, struct sockaddr *arg_as_sa, void *dummy));
|
||||
int spx_ctloutput __P((int req, struct socket *so, int level, int name,
|
||||
struct mbuf **value, struct proc *p));
|
||||
int spx_ctloutput __P((struct socket *so, struct sockopt *sopt));
|
||||
void spx_fasttimo __P((void));
|
||||
void spx_init __P((void));
|
||||
void spx_input __P((struct mbuf *m, struct ipxpcb *ipxp));
|
||||
|
@ -33,7 +33,7 @@
|
||||
*
|
||||
* @(#)spx_usrreq.h
|
||||
*
|
||||
* $Id: spx_usrreq.c,v 1.18 1998/02/09 06:10:26 eivind Exp $
|
||||
* $Id: spx_usrreq.c,v 1.19 1998/05/01 18:30:02 bde Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -1154,39 +1154,33 @@ spx_setpersist(cb)
|
||||
}
|
||||
|
||||
int
|
||||
spx_ctloutput(req, so, level, name, value, p)
|
||||
int req;
|
||||
spx_ctloutput(so, sopt)
|
||||
struct socket *so;
|
||||
int level, name;
|
||||
struct mbuf **value;
|
||||
struct proc *p;
|
||||
struct sockopt *sopt;
|
||||
{
|
||||
register struct mbuf *m;
|
||||
struct ipxpcb *ipxp = sotoipxpcb(so);
|
||||
register struct spxpcb *cb;
|
||||
int mask, error = 0;
|
||||
int mask, error;
|
||||
short soptval;
|
||||
u_short usoptval;
|
||||
int optval;
|
||||
|
||||
if (level != IPXPROTO_SPX) {
|
||||
error = 0;
|
||||
|
||||
if (sopt->sopt_level != IPXPROTO_SPX) {
|
||||
/* This will have to be changed when we do more general
|
||||
stacking of protocols */
|
||||
return (ipx_ctloutput(req, so, level, name, value, p));
|
||||
return (ipx_ctloutput(so, sopt));
|
||||
}
|
||||
if (ipxp == NULL) {
|
||||
error = EINVAL;
|
||||
goto release;
|
||||
} else
|
||||
if (ipxp == NULL)
|
||||
return (EINVAL);
|
||||
else
|
||||
cb = ipxtospxpcb(ipxp);
|
||||
|
||||
switch (req) {
|
||||
|
||||
case PRCO_GETOPT:
|
||||
if (value == NULL)
|
||||
return (EINVAL);
|
||||
m = m_get(M_DONTWAIT, MT_DATA);
|
||||
if (m == NULL)
|
||||
return (ENOBUFS);
|
||||
switch (name) {
|
||||
|
||||
switch (sopt->sopt_dir) {
|
||||
case SOPT_GET:
|
||||
switch (sopt->sopt_name) {
|
||||
case SO_HEADERS_ON_INPUT:
|
||||
mask = SF_HI;
|
||||
goto get_flags;
|
||||
@ -1194,39 +1188,34 @@ spx_ctloutput(req, so, level, name, value, p)
|
||||
case SO_HEADERS_ON_OUTPUT:
|
||||
mask = SF_HO;
|
||||
get_flags:
|
||||
m->m_len = sizeof(short);
|
||||
*mtod(m, short *) = cb->s_flags & mask;
|
||||
soptval = cb->s_flags & mask;
|
||||
error = sooptcopyout(sopt, &soptval, sizeof soptval);
|
||||
break;
|
||||
|
||||
case SO_MTU:
|
||||
m->m_len = sizeof(u_short);
|
||||
*mtod(m, short *) = cb->s_mtu;
|
||||
usoptval = cb->s_mtu;
|
||||
error = sooptcopyout(sopt, &usoptval, sizeof usoptval);
|
||||
break;
|
||||
|
||||
case SO_LAST_HEADER:
|
||||
m->m_len = sizeof(struct spxhdr);
|
||||
*mtod(m, struct spxhdr *) = cb->s_rhdr;
|
||||
error = sooptcopyout(sopt, &cb->s_rhdr,
|
||||
sizeof cb->s_rhdr);
|
||||
break;
|
||||
|
||||
case SO_DEFAULT_HEADERS:
|
||||
m->m_len = sizeof(struct spx);
|
||||
*mtod(m, struct spxhdr *) = cb->s_shdr;
|
||||
error = sooptcopyout(sopt, &cb->s_shdr,
|
||||
sizeof cb->s_shdr);
|
||||
break;
|
||||
|
||||
default:
|
||||
error = EINVAL;
|
||||
error = ENOPROTOOPT;
|
||||
}
|
||||
*value = m;
|
||||
break;
|
||||
|
||||
case PRCO_SETOPT:
|
||||
if (value == 0 || *value == 0) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
switch (name) {
|
||||
int *ok;
|
||||
|
||||
case SOPT_SET:
|
||||
switch (sopt->sopt_name) {
|
||||
/* XXX why are these shorts on get and ints on set?
|
||||
that doesn't make any sense... */
|
||||
case SO_HEADERS_ON_INPUT:
|
||||
mask = SF_HI;
|
||||
goto set_head;
|
||||
@ -1234,9 +1223,13 @@ spx_ctloutput(req, so, level, name, value, p)
|
||||
case SO_HEADERS_ON_OUTPUT:
|
||||
mask = SF_HO;
|
||||
set_head:
|
||||
error = sooptcopyin(sopt, &optval, sizeof optval,
|
||||
sizeof optval);
|
||||
if (error)
|
||||
break;
|
||||
|
||||
if (cb->s_flags & SF_PI) {
|
||||
ok = mtod(*value, int *);
|
||||
if (*ok)
|
||||
if (optval)
|
||||
cb->s_flags |= mask;
|
||||
else
|
||||
cb->s_flags &= ~mask;
|
||||
@ -1244,13 +1237,20 @@ spx_ctloutput(req, so, level, name, value, p)
|
||||
break;
|
||||
|
||||
case SO_MTU:
|
||||
cb->s_mtu = *(mtod(*value, u_short *));
|
||||
error = sooptcopyin(sopt, &usoptval, sizeof usoptval,
|
||||
sizeof usoptval);
|
||||
if (error)
|
||||
break;
|
||||
cb->s_mtu = usoptval;
|
||||
break;
|
||||
|
||||
#ifdef SF_NEWCALL
|
||||
case SO_NEWCALL:
|
||||
ok = mtod(*value, int *);
|
||||
if (*ok) {
|
||||
error = sooptcopyin(sopt, &optval, sizeof optval,
|
||||
sizeof optval);
|
||||
if (error)
|
||||
break;
|
||||
if (optval) {
|
||||
cb->s_flags2 |= SF_NEWCALL;
|
||||
spx_newchecks[5]++;
|
||||
} else {
|
||||
@ -1262,21 +1262,23 @@ spx_ctloutput(req, so, level, name, value, p)
|
||||
|
||||
case SO_DEFAULT_HEADERS:
|
||||
{
|
||||
register struct spxhdr *sp
|
||||
= mtod(*value, struct spxhdr *);
|
||||
cb->s_dt = sp->spx_dt;
|
||||
cb->s_cc = sp->spx_cc & SPX_EM;
|
||||
struct spxhdr sp;
|
||||
|
||||
error = sooptcopyin(sopt, &sp, sizeof sp,
|
||||
sizeof sp);
|
||||
if (error)
|
||||
break;
|
||||
cb->s_dt = sp.spx_dt;
|
||||
cb->s_cc = sp.spx_cc & SPX_EM;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
error = EINVAL;
|
||||
error = ENOPROTOOPT;
|
||||
}
|
||||
m_freem(*value);
|
||||
break;
|
||||
}
|
||||
release:
|
||||
return (error);
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: bootp_subr.c,v 1.13 1998/03/30 09:53:38 phk Exp $ */
|
||||
/* $Id: bootp_subr.c,v 1.14 1998/08/18 00:32:47 bde Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1995 Gordon Ross, Adam Glass
|
||||
@ -264,8 +264,10 @@ bootpc_call(call,reply,procp)
|
||||
struct sockaddr_in *sin, sa;
|
||||
struct mbuf *m;
|
||||
struct uio auio;
|
||||
struct sockopt sopt;
|
||||
struct iovec aio;
|
||||
int error, rcvflg, timo, secs, len;
|
||||
struct timeval tv;
|
||||
int error, on, len, rcvflg, secs, timo;
|
||||
u_int tport;
|
||||
|
||||
/*
|
||||
@ -274,36 +276,26 @@ bootpc_call(call,reply,procp)
|
||||
if ((error = socreate(AF_INET, &so, SOCK_DGRAM, 0,procp)))
|
||||
goto out;
|
||||
|
||||
m = m_get(M_WAIT, MT_SOOPTS);
|
||||
if (m == NULL) {
|
||||
error = ENOBUFS;
|
||||
tv.tv_sec = 1;
|
||||
tv.tv_usec = 0;
|
||||
bzero(&sopt, sizeof sopt);
|
||||
sopt.sopt_level = SOL_SOCKET;
|
||||
sopt.sopt_name = SO_RCVTIMEO;
|
||||
sopt.sopt_val = &tv;
|
||||
sopt.sopt_valsize = sizeof tv;
|
||||
|
||||
if (error = sosetopt(so, &sopt))
|
||||
goto out;
|
||||
} else {
|
||||
struct timeval *tv;
|
||||
tv = mtod(m, struct timeval *);
|
||||
m->m_len = sizeof(*tv);
|
||||
tv->tv_sec = 1;
|
||||
tv->tv_usec = 0;
|
||||
if ((error = sosetopt(so, SOL_SOCKET, SO_RCVTIMEO, m, procp)))
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable broadcast.
|
||||
*/
|
||||
{
|
||||
int *on;
|
||||
m = m_get(M_WAIT, MT_SOOPTS);
|
||||
if (m == NULL) {
|
||||
error = ENOBUFS;
|
||||
goto out;
|
||||
}
|
||||
on = mtod(m, int *);
|
||||
m->m_len = sizeof(*on);
|
||||
*on = 1;
|
||||
if ((error = sosetopt(so, SOL_SOCKET, SO_BROADCAST, m, procp)))
|
||||
goto out;
|
||||
}
|
||||
on = 1;
|
||||
sopt.sopt_val = &on;
|
||||
sopt.sopt_valsize = sizeof on;
|
||||
sopt.sopt_name = SO_BROADCAST;
|
||||
if (error = sosetopt(so, &sopt))
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* Bind the local endpoint to a bootp client port.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* $NetBSD: krpc_subr.c,v 1.12.4.1 1996/06/07 00:52:26 cgd Exp $ */
|
||||
/* $Id: krpc_subr.c,v 1.9 1998/03/28 10:33:15 bde Exp $ */
|
||||
/* $Id: krpc_subr.c,v 1.10 1998/08/18 00:32:48 bde Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1995 Gordon Ross, Adam Glass
|
||||
@ -198,6 +198,8 @@ krpc_call(sa, prog, vers, func, data, from_p, procp)
|
||||
struct mbuf *m, *nam, *mhead;
|
||||
struct rpc_call *call;
|
||||
struct rpc_reply *reply;
|
||||
struct sockopt sopt;
|
||||
struct timeval tv;
|
||||
struct uio auio;
|
||||
int error, rcvflg, timo, secs, len;
|
||||
static u_int32_t xid = ~0xFF;
|
||||
@ -220,34 +222,26 @@ krpc_call(sa, prog, vers, func, data, from_p, procp)
|
||||
if ((error = socreate(AF_INET, &so, SOCK_DGRAM, 0, procp)))
|
||||
goto out;
|
||||
|
||||
m = m_get(M_WAIT, MT_SOOPTS);
|
||||
if (m == NULL) {
|
||||
error = ENOBUFS;
|
||||
tv.tv_sec = 1;
|
||||
tv.tv_usec = 0;
|
||||
bzero(&sopt, sizeof sopt);
|
||||
sopt.sopt_level = SOL_SOCKET;
|
||||
sopt.sopt_name = SO_RCVTIMEO;
|
||||
sopt.sopt_val = &tv;
|
||||
sopt.sopt_valsize = sizeof tv;
|
||||
|
||||
if (error = sosetopt(so, &sopt))
|
||||
goto out;
|
||||
} else {
|
||||
struct timeval *tv;
|
||||
tv = mtod(m, struct timeval *);
|
||||
m->m_len = sizeof(*tv);
|
||||
tv->tv_sec = 1;
|
||||
tv->tv_usec = 0;
|
||||
if ((error = sosetopt(so, SOL_SOCKET, SO_RCVTIMEO, m, procp)))
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable broadcast if necessary.
|
||||
*/
|
||||
if (from_p) {
|
||||
int32_t *on;
|
||||
m = m_get(M_WAIT, MT_SOOPTS);
|
||||
if (m == NULL) {
|
||||
error = ENOBUFS;
|
||||
goto out;
|
||||
}
|
||||
on = mtod(m, int32_t *);
|
||||
m->m_len = sizeof(*on);
|
||||
*on = 1;
|
||||
if ((error = sosetopt(so, SOL_SOCKET, SO_BROADCAST, m, procp)))
|
||||
int on = 1;
|
||||
sopt.sopt_name = SO_BROADCAST;
|
||||
sopt.sopt_val = &on;
|
||||
sopt.sopt_valsize = sizeof on;
|
||||
if (error = sosetopt(so, &sopt))
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)nfs.h 8.4 (Berkeley) 5/1/95
|
||||
* $Id: nfs.h,v 1.41 1998/06/30 03:01:37 jmg Exp $
|
||||
* $Id: nfs.h,v 1.42 1998/06/30 11:19:22 jmg Exp $
|
||||
*/
|
||||
|
||||
#ifndef _NFS_NFS_H_
|
||||
@ -722,7 +722,7 @@ int nfsrv_symlink __P((struct nfsrv_descript *nfsd,
|
||||
struct proc *procp, struct mbuf **mrq));
|
||||
int nfsrv_write __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
|
||||
struct proc *procp, struct mbuf **mrq));
|
||||
void nfsrv_rcv __P((struct socket *so, caddr_t arg, int waitflag));
|
||||
void nfsrv_rcv __P((struct socket *so, void *arg, int waitflag));
|
||||
void nfsrv_slpderef __P((struct nfssvc_sock *slp));
|
||||
#endif /* KERNEL */
|
||||
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)nfs_socket.c 8.5 (Berkeley) 3/30/95
|
||||
* $Id: nfs_socket.c,v 1.42 1998/07/15 02:32:24 bde Exp $
|
||||
* $Id: nfs_socket.c,v 1.43 1998/08/01 09:04:02 peter Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -282,16 +282,28 @@ nfs_connect(nmp, rep)
|
||||
if (nmp->nm_sotype != SOCK_STREAM)
|
||||
panic("nfscon sotype");
|
||||
if (so->so_proto->pr_flags & PR_CONNREQUIRED) {
|
||||
MGET(m, M_WAIT, MT_SOOPTS);
|
||||
*mtod(m, int32_t *) = 1;
|
||||
m->m_len = sizeof(int32_t);
|
||||
sosetopt(so, SOL_SOCKET, SO_KEEPALIVE, m, p);
|
||||
struct sockopt sopt;
|
||||
int val;
|
||||
|
||||
bzero(&sopt, sizeof sopt);
|
||||
sopt.sopt_level = SOL_SOCKET;
|
||||
sopt.sopt_name = SO_KEEPALIVE;
|
||||
sopt.sopt_val = &val;
|
||||
sopt.sopt_valsize = sizeof val;
|
||||
val = 1;
|
||||
sosetopt(so, &sopt);
|
||||
}
|
||||
if (so->so_proto->pr_protocol == IPPROTO_TCP) {
|
||||
MGET(m, M_WAIT, MT_SOOPTS);
|
||||
*mtod(m, int32_t *) = 1;
|
||||
m->m_len = sizeof(int32_t);
|
||||
sosetopt(so, IPPROTO_TCP, TCP_NODELAY, m, p);
|
||||
struct sockopt sopt;
|
||||
int val;
|
||||
|
||||
bzero(&sopt, sizeof sopt);
|
||||
sopt.sopt_level = IPPROTO_TCP;
|
||||
sopt.sopt_name = TCP_NODELAY;
|
||||
sopt.sopt_val = &val;
|
||||
sopt.sopt_valsize = sizeof val;
|
||||
val = 1;
|
||||
sosetopt(so, &sopt);
|
||||
}
|
||||
sndreserve = (nmp->nm_wsize + NFS_MAXPKTHDR +
|
||||
sizeof (u_int32_t)) * 2;
|
||||
@ -1952,7 +1964,7 @@ nfs_msg(p, server, msg)
|
||||
void
|
||||
nfsrv_rcv(so, arg, waitflag)
|
||||
struct socket *so;
|
||||
caddr_t arg;
|
||||
void *arg;
|
||||
int waitflag;
|
||||
{
|
||||
register struct nfssvc_sock *slp = (struct nfssvc_sock *)arg;
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)nfs_syscalls.c 8.5 (Berkeley) 3/30/95
|
||||
* $Id: nfs_syscalls.c,v 1.40 1998/05/31 18:46:06 peter Exp $
|
||||
* $Id: nfs_syscalls.c,v 1.41 1998/05/31 20:08:55 peter Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -400,17 +400,29 @@ nfssvc_addsock(fp, mynam, p)
|
||||
* repeatedly for the same socket, but that isn't harmful.
|
||||
*/
|
||||
if (so->so_type == SOCK_STREAM) {
|
||||
MGET(m, M_WAIT, MT_SOOPTS);
|
||||
*mtod(m, int32_t *) = 1;
|
||||
m->m_len = sizeof(int32_t);
|
||||
sosetopt(so, SOL_SOCKET, SO_KEEPALIVE, m, p);
|
||||
struct sockopt sopt;
|
||||
int val;
|
||||
|
||||
bzero(&sopt, sizeof sopt);
|
||||
sopt.sopt_level = SOL_SOCKET;
|
||||
sopt.sopt_name = SO_KEEPALIVE;
|
||||
sopt.sopt_val = &val;
|
||||
sopt.sopt_valsize = sizeof val;
|
||||
val = 1;
|
||||
sosetopt(so, &sopt);
|
||||
}
|
||||
if (so->so_proto->pr_domain->dom_family == AF_INET &&
|
||||
so->so_proto->pr_protocol == IPPROTO_TCP) {
|
||||
MGET(m, M_WAIT, MT_SOOPTS);
|
||||
*mtod(m, int32_t *) = 1;
|
||||
m->m_len = sizeof(int32_t);
|
||||
sosetopt(so, IPPROTO_TCP, TCP_NODELAY, m, p);
|
||||
struct sockopt sopt;
|
||||
int val;
|
||||
|
||||
bzero(&sopt, sizeof sopt);
|
||||
sopt.sopt_level = IPPROTO_TCP;
|
||||
sopt.sopt_name = TCP_NODELAY;
|
||||
sopt.sopt_val = &val;
|
||||
sopt.sopt_valsize = sizeof val;
|
||||
val = 1;
|
||||
sosetopt(so, &sopt);
|
||||
}
|
||||
so->so_rcv.sb_flags &= ~SB_NOINTR;
|
||||
so->so_rcv.sb_timeo = 0;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: bootp_subr.c,v 1.13 1998/03/30 09:53:38 phk Exp $ */
|
||||
/* $Id: bootp_subr.c,v 1.14 1998/08/18 00:32:47 bde Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1995 Gordon Ross, Adam Glass
|
||||
@ -264,8 +264,10 @@ bootpc_call(call,reply,procp)
|
||||
struct sockaddr_in *sin, sa;
|
||||
struct mbuf *m;
|
||||
struct uio auio;
|
||||
struct sockopt sopt;
|
||||
struct iovec aio;
|
||||
int error, rcvflg, timo, secs, len;
|
||||
struct timeval tv;
|
||||
int error, on, len, rcvflg, secs, timo;
|
||||
u_int tport;
|
||||
|
||||
/*
|
||||
@ -274,36 +276,26 @@ bootpc_call(call,reply,procp)
|
||||
if ((error = socreate(AF_INET, &so, SOCK_DGRAM, 0,procp)))
|
||||
goto out;
|
||||
|
||||
m = m_get(M_WAIT, MT_SOOPTS);
|
||||
if (m == NULL) {
|
||||
error = ENOBUFS;
|
||||
tv.tv_sec = 1;
|
||||
tv.tv_usec = 0;
|
||||
bzero(&sopt, sizeof sopt);
|
||||
sopt.sopt_level = SOL_SOCKET;
|
||||
sopt.sopt_name = SO_RCVTIMEO;
|
||||
sopt.sopt_val = &tv;
|
||||
sopt.sopt_valsize = sizeof tv;
|
||||
|
||||
if (error = sosetopt(so, &sopt))
|
||||
goto out;
|
||||
} else {
|
||||
struct timeval *tv;
|
||||
tv = mtod(m, struct timeval *);
|
||||
m->m_len = sizeof(*tv);
|
||||
tv->tv_sec = 1;
|
||||
tv->tv_usec = 0;
|
||||
if ((error = sosetopt(so, SOL_SOCKET, SO_RCVTIMEO, m, procp)))
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable broadcast.
|
||||
*/
|
||||
{
|
||||
int *on;
|
||||
m = m_get(M_WAIT, MT_SOOPTS);
|
||||
if (m == NULL) {
|
||||
error = ENOBUFS;
|
||||
goto out;
|
||||
}
|
||||
on = mtod(m, int *);
|
||||
m->m_len = sizeof(*on);
|
||||
*on = 1;
|
||||
if ((error = sosetopt(so, SOL_SOCKET, SO_BROADCAST, m, procp)))
|
||||
goto out;
|
||||
}
|
||||
on = 1;
|
||||
sopt.sopt_val = &on;
|
||||
sopt.sopt_valsize = sizeof on;
|
||||
sopt.sopt_name = SO_BROADCAST;
|
||||
if (error = sosetopt(so, &sopt))
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* Bind the local endpoint to a bootp client port.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* $NetBSD: krpc_subr.c,v 1.12.4.1 1996/06/07 00:52:26 cgd Exp $ */
|
||||
/* $Id: krpc_subr.c,v 1.9 1998/03/28 10:33:15 bde Exp $ */
|
||||
/* $Id: krpc_subr.c,v 1.10 1998/08/18 00:32:48 bde Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1995 Gordon Ross, Adam Glass
|
||||
@ -198,6 +198,8 @@ krpc_call(sa, prog, vers, func, data, from_p, procp)
|
||||
struct mbuf *m, *nam, *mhead;
|
||||
struct rpc_call *call;
|
||||
struct rpc_reply *reply;
|
||||
struct sockopt sopt;
|
||||
struct timeval tv;
|
||||
struct uio auio;
|
||||
int error, rcvflg, timo, secs, len;
|
||||
static u_int32_t xid = ~0xFF;
|
||||
@ -220,34 +222,26 @@ krpc_call(sa, prog, vers, func, data, from_p, procp)
|
||||
if ((error = socreate(AF_INET, &so, SOCK_DGRAM, 0, procp)))
|
||||
goto out;
|
||||
|
||||
m = m_get(M_WAIT, MT_SOOPTS);
|
||||
if (m == NULL) {
|
||||
error = ENOBUFS;
|
||||
tv.tv_sec = 1;
|
||||
tv.tv_usec = 0;
|
||||
bzero(&sopt, sizeof sopt);
|
||||
sopt.sopt_level = SOL_SOCKET;
|
||||
sopt.sopt_name = SO_RCVTIMEO;
|
||||
sopt.sopt_val = &tv;
|
||||
sopt.sopt_valsize = sizeof tv;
|
||||
|
||||
if (error = sosetopt(so, &sopt))
|
||||
goto out;
|
||||
} else {
|
||||
struct timeval *tv;
|
||||
tv = mtod(m, struct timeval *);
|
||||
m->m_len = sizeof(*tv);
|
||||
tv->tv_sec = 1;
|
||||
tv->tv_usec = 0;
|
||||
if ((error = sosetopt(so, SOL_SOCKET, SO_RCVTIMEO, m, procp)))
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable broadcast if necessary.
|
||||
*/
|
||||
if (from_p) {
|
||||
int32_t *on;
|
||||
m = m_get(M_WAIT, MT_SOOPTS);
|
||||
if (m == NULL) {
|
||||
error = ENOBUFS;
|
||||
goto out;
|
||||
}
|
||||
on = mtod(m, int32_t *);
|
||||
m->m_len = sizeof(*on);
|
||||
*on = 1;
|
||||
if ((error = sosetopt(so, SOL_SOCKET, SO_BROADCAST, m, procp)))
|
||||
int on = 1;
|
||||
sopt.sopt_name = SO_BROADCAST;
|
||||
sopt.sopt_val = &on;
|
||||
sopt.sopt_valsize = sizeof on;
|
||||
if (error = sosetopt(so, &sopt))
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)nfs.h 8.4 (Berkeley) 5/1/95
|
||||
* $Id: nfs.h,v 1.41 1998/06/30 03:01:37 jmg Exp $
|
||||
* $Id: nfs.h,v 1.42 1998/06/30 11:19:22 jmg Exp $
|
||||
*/
|
||||
|
||||
#ifndef _NFS_NFS_H_
|
||||
@ -722,7 +722,7 @@ int nfsrv_symlink __P((struct nfsrv_descript *nfsd,
|
||||
struct proc *procp, struct mbuf **mrq));
|
||||
int nfsrv_write __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
|
||||
struct proc *procp, struct mbuf **mrq));
|
||||
void nfsrv_rcv __P((struct socket *so, caddr_t arg, int waitflag));
|
||||
void nfsrv_rcv __P((struct socket *so, void *arg, int waitflag));
|
||||
void nfsrv_slpderef __P((struct nfssvc_sock *slp));
|
||||
#endif /* KERNEL */
|
||||
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)nfs_syscalls.c 8.5 (Berkeley) 3/30/95
|
||||
* $Id: nfs_syscalls.c,v 1.40 1998/05/31 18:46:06 peter Exp $
|
||||
* $Id: nfs_syscalls.c,v 1.41 1998/05/31 20:08:55 peter Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -400,17 +400,29 @@ nfssvc_addsock(fp, mynam, p)
|
||||
* repeatedly for the same socket, but that isn't harmful.
|
||||
*/
|
||||
if (so->so_type == SOCK_STREAM) {
|
||||
MGET(m, M_WAIT, MT_SOOPTS);
|
||||
*mtod(m, int32_t *) = 1;
|
||||
m->m_len = sizeof(int32_t);
|
||||
sosetopt(so, SOL_SOCKET, SO_KEEPALIVE, m, p);
|
||||
struct sockopt sopt;
|
||||
int val;
|
||||
|
||||
bzero(&sopt, sizeof sopt);
|
||||
sopt.sopt_level = SOL_SOCKET;
|
||||
sopt.sopt_name = SO_KEEPALIVE;
|
||||
sopt.sopt_val = &val;
|
||||
sopt.sopt_valsize = sizeof val;
|
||||
val = 1;
|
||||
sosetopt(so, &sopt);
|
||||
}
|
||||
if (so->so_proto->pr_domain->dom_family == AF_INET &&
|
||||
so->so_proto->pr_protocol == IPPROTO_TCP) {
|
||||
MGET(m, M_WAIT, MT_SOOPTS);
|
||||
*mtod(m, int32_t *) = 1;
|
||||
m->m_len = sizeof(int32_t);
|
||||
sosetopt(so, IPPROTO_TCP, TCP_NODELAY, m, p);
|
||||
struct sockopt sopt;
|
||||
int val;
|
||||
|
||||
bzero(&sopt, sizeof sopt);
|
||||
sopt.sopt_level = IPPROTO_TCP;
|
||||
sopt.sopt_name = TCP_NODELAY;
|
||||
sopt.sopt_val = &val;
|
||||
sopt.sopt_valsize = sizeof val;
|
||||
val = 1;
|
||||
sosetopt(so, &sopt);
|
||||
}
|
||||
so->so_rcv.sb_flags &= ~SB_NOINTR;
|
||||
so->so_rcv.sb_timeo = 0;
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)nfs_socket.c 8.5 (Berkeley) 3/30/95
|
||||
* $Id: nfs_socket.c,v 1.42 1998/07/15 02:32:24 bde Exp $
|
||||
* $Id: nfs_socket.c,v 1.43 1998/08/01 09:04:02 peter Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -282,16 +282,28 @@ nfs_connect(nmp, rep)
|
||||
if (nmp->nm_sotype != SOCK_STREAM)
|
||||
panic("nfscon sotype");
|
||||
if (so->so_proto->pr_flags & PR_CONNREQUIRED) {
|
||||
MGET(m, M_WAIT, MT_SOOPTS);
|
||||
*mtod(m, int32_t *) = 1;
|
||||
m->m_len = sizeof(int32_t);
|
||||
sosetopt(so, SOL_SOCKET, SO_KEEPALIVE, m, p);
|
||||
struct sockopt sopt;
|
||||
int val;
|
||||
|
||||
bzero(&sopt, sizeof sopt);
|
||||
sopt.sopt_level = SOL_SOCKET;
|
||||
sopt.sopt_name = SO_KEEPALIVE;
|
||||
sopt.sopt_val = &val;
|
||||
sopt.sopt_valsize = sizeof val;
|
||||
val = 1;
|
||||
sosetopt(so, &sopt);
|
||||
}
|
||||
if (so->so_proto->pr_protocol == IPPROTO_TCP) {
|
||||
MGET(m, M_WAIT, MT_SOOPTS);
|
||||
*mtod(m, int32_t *) = 1;
|
||||
m->m_len = sizeof(int32_t);
|
||||
sosetopt(so, IPPROTO_TCP, TCP_NODELAY, m, p);
|
||||
struct sockopt sopt;
|
||||
int val;
|
||||
|
||||
bzero(&sopt, sizeof sopt);
|
||||
sopt.sopt_level = IPPROTO_TCP;
|
||||
sopt.sopt_name = TCP_NODELAY;
|
||||
sopt.sopt_val = &val;
|
||||
sopt.sopt_valsize = sizeof val;
|
||||
val = 1;
|
||||
sosetopt(so, &sopt);
|
||||
}
|
||||
sndreserve = (nmp->nm_wsize + NFS_MAXPKTHDR +
|
||||
sizeof (u_int32_t)) * 2;
|
||||
@ -1952,7 +1964,7 @@ nfs_msg(p, server, msg)
|
||||
void
|
||||
nfsrv_rcv(so, arg, waitflag)
|
||||
struct socket *so;
|
||||
caddr_t arg;
|
||||
void *arg;
|
||||
int waitflag;
|
||||
{
|
||||
register struct nfssvc_sock *slp = (struct nfssvc_sock *)arg;
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)nfs.h 8.4 (Berkeley) 5/1/95
|
||||
* $Id: nfs.h,v 1.41 1998/06/30 03:01:37 jmg Exp $
|
||||
* $Id: nfs.h,v 1.42 1998/06/30 11:19:22 jmg Exp $
|
||||
*/
|
||||
|
||||
#ifndef _NFS_NFS_H_
|
||||
@ -722,7 +722,7 @@ int nfsrv_symlink __P((struct nfsrv_descript *nfsd,
|
||||
struct proc *procp, struct mbuf **mrq));
|
||||
int nfsrv_write __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
|
||||
struct proc *procp, struct mbuf **mrq));
|
||||
void nfsrv_rcv __P((struct socket *so, caddr_t arg, int waitflag));
|
||||
void nfsrv_rcv __P((struct socket *so, void *arg, int waitflag));
|
||||
void nfsrv_slpderef __P((struct nfssvc_sock *slp));
|
||||
#endif /* KERNEL */
|
||||
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)nfs.h 8.4 (Berkeley) 5/1/95
|
||||
* $Id: nfs.h,v 1.41 1998/06/30 03:01:37 jmg Exp $
|
||||
* $Id: nfs.h,v 1.42 1998/06/30 11:19:22 jmg Exp $
|
||||
*/
|
||||
|
||||
#ifndef _NFS_NFS_H_
|
||||
@ -722,7 +722,7 @@ int nfsrv_symlink __P((struct nfsrv_descript *nfsd,
|
||||
struct proc *procp, struct mbuf **mrq));
|
||||
int nfsrv_write __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
|
||||
struct proc *procp, struct mbuf **mrq));
|
||||
void nfsrv_rcv __P((struct socket *so, caddr_t arg, int waitflag));
|
||||
void nfsrv_rcv __P((struct socket *so, void *arg, int waitflag));
|
||||
void nfsrv_slpderef __P((struct nfssvc_sock *slp));
|
||||
#endif /* KERNEL */
|
||||
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)nfs.h 8.4 (Berkeley) 5/1/95
|
||||
* $Id: nfs.h,v 1.41 1998/06/30 03:01:37 jmg Exp $
|
||||
* $Id: nfs.h,v 1.42 1998/06/30 11:19:22 jmg Exp $
|
||||
*/
|
||||
|
||||
#ifndef _NFS_NFS_H_
|
||||
@ -722,7 +722,7 @@ int nfsrv_symlink __P((struct nfsrv_descript *nfsd,
|
||||
struct proc *procp, struct mbuf **mrq));
|
||||
int nfsrv_write __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
|
||||
struct proc *procp, struct mbuf **mrq));
|
||||
void nfsrv_rcv __P((struct socket *so, caddr_t arg, int waitflag));
|
||||
void nfsrv_rcv __P((struct socket *so, void *arg, int waitflag));
|
||||
void nfsrv_slpderef __P((struct nfssvc_sock *slp));
|
||||
#endif /* KERNEL */
|
||||
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)nfs_socket.c 8.5 (Berkeley) 3/30/95
|
||||
* $Id: nfs_socket.c,v 1.42 1998/07/15 02:32:24 bde Exp $
|
||||
* $Id: nfs_socket.c,v 1.43 1998/08/01 09:04:02 peter Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -282,16 +282,28 @@ nfs_connect(nmp, rep)
|
||||
if (nmp->nm_sotype != SOCK_STREAM)
|
||||
panic("nfscon sotype");
|
||||
if (so->so_proto->pr_flags & PR_CONNREQUIRED) {
|
||||
MGET(m, M_WAIT, MT_SOOPTS);
|
||||
*mtod(m, int32_t *) = 1;
|
||||
m->m_len = sizeof(int32_t);
|
||||
sosetopt(so, SOL_SOCKET, SO_KEEPALIVE, m, p);
|
||||
struct sockopt sopt;
|
||||
int val;
|
||||
|
||||
bzero(&sopt, sizeof sopt);
|
||||
sopt.sopt_level = SOL_SOCKET;
|
||||
sopt.sopt_name = SO_KEEPALIVE;
|
||||
sopt.sopt_val = &val;
|
||||
sopt.sopt_valsize = sizeof val;
|
||||
val = 1;
|
||||
sosetopt(so, &sopt);
|
||||
}
|
||||
if (so->so_proto->pr_protocol == IPPROTO_TCP) {
|
||||
MGET(m, M_WAIT, MT_SOOPTS);
|
||||
*mtod(m, int32_t *) = 1;
|
||||
m->m_len = sizeof(int32_t);
|
||||
sosetopt(so, IPPROTO_TCP, TCP_NODELAY, m, p);
|
||||
struct sockopt sopt;
|
||||
int val;
|
||||
|
||||
bzero(&sopt, sizeof sopt);
|
||||
sopt.sopt_level = IPPROTO_TCP;
|
||||
sopt.sopt_name = TCP_NODELAY;
|
||||
sopt.sopt_val = &val;
|
||||
sopt.sopt_valsize = sizeof val;
|
||||
val = 1;
|
||||
sosetopt(so, &sopt);
|
||||
}
|
||||
sndreserve = (nmp->nm_wsize + NFS_MAXPKTHDR +
|
||||
sizeof (u_int32_t)) * 2;
|
||||
@ -1952,7 +1964,7 @@ nfs_msg(p, server, msg)
|
||||
void
|
||||
nfsrv_rcv(so, arg, waitflag)
|
||||
struct socket *so;
|
||||
caddr_t arg;
|
||||
void *arg;
|
||||
int waitflag;
|
||||
{
|
||||
register struct nfssvc_sock *slp = (struct nfssvc_sock *)arg;
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)nfs_syscalls.c 8.5 (Berkeley) 3/30/95
|
||||
* $Id: nfs_syscalls.c,v 1.40 1998/05/31 18:46:06 peter Exp $
|
||||
* $Id: nfs_syscalls.c,v 1.41 1998/05/31 20:08:55 peter Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -400,17 +400,29 @@ nfssvc_addsock(fp, mynam, p)
|
||||
* repeatedly for the same socket, but that isn't harmful.
|
||||
*/
|
||||
if (so->so_type == SOCK_STREAM) {
|
||||
MGET(m, M_WAIT, MT_SOOPTS);
|
||||
*mtod(m, int32_t *) = 1;
|
||||
m->m_len = sizeof(int32_t);
|
||||
sosetopt(so, SOL_SOCKET, SO_KEEPALIVE, m, p);
|
||||
struct sockopt sopt;
|
||||
int val;
|
||||
|
||||
bzero(&sopt, sizeof sopt);
|
||||
sopt.sopt_level = SOL_SOCKET;
|
||||
sopt.sopt_name = SO_KEEPALIVE;
|
||||
sopt.sopt_val = &val;
|
||||
sopt.sopt_valsize = sizeof val;
|
||||
val = 1;
|
||||
sosetopt(so, &sopt);
|
||||
}
|
||||
if (so->so_proto->pr_domain->dom_family == AF_INET &&
|
||||
so->so_proto->pr_protocol == IPPROTO_TCP) {
|
||||
MGET(m, M_WAIT, MT_SOOPTS);
|
||||
*mtod(m, int32_t *) = 1;
|
||||
m->m_len = sizeof(int32_t);
|
||||
sosetopt(so, IPPROTO_TCP, TCP_NODELAY, m, p);
|
||||
struct sockopt sopt;
|
||||
int val;
|
||||
|
||||
bzero(&sopt, sizeof sopt);
|
||||
sopt.sopt_level = IPPROTO_TCP;
|
||||
sopt.sopt_name = TCP_NODELAY;
|
||||
sopt.sopt_val = &val;
|
||||
sopt.sopt_valsize = sizeof val;
|
||||
val = 1;
|
||||
sosetopt(so, &sopt);
|
||||
}
|
||||
so->so_rcv.sb_flags &= ~SB_NOINTR;
|
||||
so->so_rcv.sb_timeo = 0;
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)nfs.h 8.4 (Berkeley) 5/1/95
|
||||
* $Id: nfs.h,v 1.41 1998/06/30 03:01:37 jmg Exp $
|
||||
* $Id: nfs.h,v 1.42 1998/06/30 11:19:22 jmg Exp $
|
||||
*/
|
||||
|
||||
#ifndef _NFS_NFS_H_
|
||||
@ -722,7 +722,7 @@ int nfsrv_symlink __P((struct nfsrv_descript *nfsd,
|
||||
struct proc *procp, struct mbuf **mrq));
|
||||
int nfsrv_write __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
|
||||
struct proc *procp, struct mbuf **mrq));
|
||||
void nfsrv_rcv __P((struct socket *so, caddr_t arg, int waitflag));
|
||||
void nfsrv_rcv __P((struct socket *so, void *arg, int waitflag));
|
||||
void nfsrv_slpderef __P((struct nfssvc_sock *slp));
|
||||
#endif /* KERNEL */
|
||||
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)mbuf.h 8.5 (Berkeley) 2/19/95
|
||||
* $Id: mbuf.h,v 1.26 1997/12/28 01:04:47 bde Exp $
|
||||
* $Id: mbuf.h,v 1.27 1998/07/15 04:17:53 bde Exp $
|
||||
*/
|
||||
|
||||
#ifndef _SYS_MBUF_H_
|
||||
@ -138,7 +138,7 @@ struct mbuf {
|
||||
/*efine MT_HTABLE 6*/ /* IMP host tables */
|
||||
/*efine MT_ATABLE 7*/ /* address resolution tables */
|
||||
#define MT_SONAME 8 /* socket name */
|
||||
#define MT_SOOPTS 10 /* socket options */
|
||||
/*efine MT_SOOPTS 10*/ /* socket options */
|
||||
#define MT_FTABLE 11 /* fragment reassembly header */
|
||||
/*efine MT_RIGHTS 12*/ /* access rights */
|
||||
/*efine MT_IFADDR 13*/ /* interface address */
|
||||
@ -168,10 +168,10 @@ union mcluster {
|
||||
* drivers.
|
||||
*/
|
||||
#define MBUFLOCK(code) \
|
||||
{ int ms = splimp(); \
|
||||
do { int ms = splimp(); \
|
||||
{ code } \
|
||||
splx(ms); \
|
||||
}
|
||||
} while(0)
|
||||
|
||||
/*
|
||||
* mbuf allocation/deallocation macros:
|
||||
@ -348,10 +348,10 @@ union mcluster {
|
||||
}
|
||||
|
||||
/* change mbuf to new type */
|
||||
#define MCHTYPE(m, t) { \
|
||||
MBUFLOCK(mbstat.m_mtypes[(m)->m_type]--; mbstat.m_mtypes[t]++;) \
|
||||
#define MCHTYPE(m, t) do { \
|
||||
MBUFLOCK(mbstat.m_mtypes[(m)->m_type]--; mbstat.m_mtypes[t]++;); \
|
||||
(m)->m_type = t;\
|
||||
}
|
||||
} while(0)
|
||||
|
||||
/* length to m_copy to copy all */
|
||||
#define M_COPYALL 1000000000
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)protosw.h 8.1 (Berkeley) 6/2/93
|
||||
* $Id: protosw.h,v 1.23 1998/02/01 20:08:37 bde Exp $
|
||||
* $Id: protosw.h,v 1.24 1998/06/07 17:13:03 dfr Exp $
|
||||
*/
|
||||
|
||||
#ifndef _SYS_PROTOSW_H_
|
||||
@ -42,6 +42,7 @@ struct mbuf;
|
||||
struct proc;
|
||||
struct sockaddr;
|
||||
struct socket;
|
||||
struct sockopt;
|
||||
|
||||
/*#ifdef KERNEL*/
|
||||
/*
|
||||
@ -58,13 +59,13 @@ struct socket;
|
||||
*
|
||||
* Protocols pass data between themselves as chains of mbufs using
|
||||
* the pr_input and pr_output hooks. Pr_input passes data up (towards
|
||||
* UNIX) and pr_output passes it down (towards the imps); control
|
||||
* the users) and pr_output passes it down (towards the interfaces); control
|
||||
* information passes up and down on pr_ctlinput and pr_ctloutput.
|
||||
* The protocol is responsible for the space occupied by any the
|
||||
* arguments to these entries and must dispose it.
|
||||
*
|
||||
* The userreq routine interfaces protocols to the system and is
|
||||
* described below.
|
||||
* In retrospect, it would be a lot nicer to use an interface
|
||||
* similar to the vnode VOP interface.
|
||||
*/
|
||||
struct protosw {
|
||||
short pr_type; /* socket type used for */
|
||||
@ -78,8 +79,7 @@ struct protosw {
|
||||
/* output to protocol (from above) */
|
||||
void (*pr_ctlinput)__P((int, struct sockaddr *, void *));
|
||||
/* control input (from below) */
|
||||
int (*pr_ctloutput)__P((int, struct socket *, int, int,
|
||||
struct mbuf **, struct proc *));
|
||||
int (*pr_ctloutput)__P((struct socket *, struct sockopt *));
|
||||
/* control output (from above) */
|
||||
/* user-protocol hook */
|
||||
void *pr_ousrreq;
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)socketvar.h 8.3 (Berkeley) 2/19/95
|
||||
* $Id: socketvar.h,v 1.27 1998/05/31 18:37:22 peter Exp $
|
||||
* $Id: socketvar.h,v 1.28 1998/06/07 17:13:03 dfr Exp $
|
||||
*/
|
||||
|
||||
#ifndef _SYS_SOCKETVAR_H_
|
||||
@ -102,9 +102,10 @@ struct socket {
|
||||
#define SB_UPCALL 0x20 /* someone wants an upcall */
|
||||
#define SB_NOINTR 0x40 /* operations not interruptible */
|
||||
|
||||
void (*so_upcall) __P((struct socket *so, caddr_t arg, int waitf));
|
||||
caddr_t so_upcallarg; /* Arg for above */
|
||||
void (*so_upcall) __P((struct socket *, void *, int));
|
||||
void *so_upcallarg;
|
||||
uid_t so_uid; /* who opened the socket */
|
||||
/* NB: generation count must not be first; easiest to make it last. */
|
||||
so_gen_t so_gencnt; /* generation count */
|
||||
};
|
||||
|
||||
@ -119,7 +120,6 @@ struct socket {
|
||||
#define SS_CANTRCVMORE 0x0020 /* can't receive more data from peer */
|
||||
#define SS_RCVATMARK 0x0040 /* at mark on input */
|
||||
|
||||
/*efine SS_PRIV 0x0080 privileged for broadcast, raw... */
|
||||
#define SS_NBIO 0x0100 /* non-blocking ops */
|
||||
#define SS_ASYNC 0x0200 /* async i/o notify */
|
||||
#define SS_ISCONFIRMING 0x0400 /* deciding to accept connection req */
|
||||
@ -242,6 +242,20 @@ struct xsocket {
|
||||
|
||||
#ifdef KERNEL
|
||||
|
||||
/*
|
||||
* Argument structure for sosetopt et seq. This is in the KERNEL
|
||||
* section because it will never be visible to user code.
|
||||
*/
|
||||
enum sopt_dir { SOPT_GET, SOPT_SET };
|
||||
struct sockopt {
|
||||
enum sopt_dir sopt_dir; /* is this a get or a set? */
|
||||
int sopt_level; /* second arg of [gs]etsockopt */
|
||||
int sopt_name; /* third arg of [gs]etsockopt */
|
||||
void *sopt_val; /* fourth arg of [gs]etsockopt */
|
||||
size_t sopt_valsize; /* (almost) fifth arg of [gs]etsockopt */
|
||||
struct proc *sopt_p; /* calling process or null if kernel */
|
||||
};
|
||||
|
||||
#ifdef MALLOC_DECLARE
|
||||
MALLOC_DECLARE(M_PCB);
|
||||
MALLOC_DECLARE(M_SONAME);
|
||||
@ -309,8 +323,7 @@ int socreate __P((int dom, struct socket **aso, int type, int proto,
|
||||
void sodealloc __P((struct socket *so));
|
||||
int sodisconnect __P((struct socket *so));
|
||||
void sofree __P((struct socket *so));
|
||||
int sogetopt __P((struct socket *so, int level, int optname,
|
||||
struct mbuf **mp, struct proc *p));
|
||||
int sogetopt __P((struct socket *so, struct sockopt *sopt));
|
||||
void sohasoutofband __P((struct socket *so));
|
||||
void soisconnected __P((struct socket *so));
|
||||
void soisconnecting __P((struct socket *so));
|
||||
@ -321,6 +334,9 @@ struct socket *
|
||||
sodropablereq __P((struct socket *head));
|
||||
struct socket *
|
||||
sonewconn __P((struct socket *head, int connstatus));
|
||||
int sooptcopyin __P((struct sockopt *sopt, void *buf, size_t len,
|
||||
size_t minlen));
|
||||
int sooptcopyout __P((struct sockopt *sopt, void *buf, size_t len));
|
||||
int sopoll __P((struct socket *so, int events, struct ucred *cred,
|
||||
struct proc *p));
|
||||
int soreceive __P((struct socket *so, struct sockaddr **paddr,
|
||||
@ -331,8 +347,7 @@ void sorflush __P((struct socket *so));
|
||||
int sosend __P((struct socket *so, struct sockaddr *addr, struct uio *uio,
|
||||
struct mbuf *top, struct mbuf *control, int flags,
|
||||
struct proc *p));
|
||||
int sosetopt __P((struct socket *so, int level, int optname,
|
||||
struct mbuf *m0, struct proc *p));
|
||||
int sosetopt __P((struct socket *so, struct sockopt *sopt));
|
||||
int soshutdown __P((struct socket *so, int how));
|
||||
void sotoxsocket __P((struct socket *so, struct xsocket *xso));
|
||||
void sowakeup __P((struct socket *so, struct sockbuf *sb));
|
||||
|
Loading…
Reference in New Issue
Block a user