version 1.120, 2014/05/18 14:46:16 |
version 1.121, 2014/05/19 02:51:25 |
|
|
* @(#)raw_ip.c 8.7 (Berkeley) 5/15/95 |
* @(#)raw_ip.c 8.7 (Berkeley) 5/15/95 |
*/ |
*/ |
|
|
|
/* |
|
* Raw interface to IP protocol. |
|
*/ |
|
|
#include <sys/cdefs.h> |
#include <sys/cdefs.h> |
__KERNEL_RCSID(0, "$NetBSD$"); |
__KERNEL_RCSID(0, "$NetBSD$"); |
|
|
Line 120 static void sysctl_net_inet_raw_setup(st |
|
Line 124 static void sysctl_net_inet_raw_setup(st |
|
#define RIPSNDQ 8192 |
#define RIPSNDQ 8192 |
#define RIPRCVQ 8192 |
#define RIPRCVQ 8192 |
|
|
|
static u_long rip_sendspace = RIPSNDQ; |
|
static u_long rip_recvspace = RIPRCVQ; |
|
|
/* |
/* |
* Raw interface to IP protocol. |
* Raw interface to IP protocol. |
*/ |
*/ |
Line 507 rip_disconnect(struct inpcb *inp) |
|
Line 514 rip_disconnect(struct inpcb *inp) |
|
inp->inp_faddr = zeroin_addr; |
inp->inp_faddr = zeroin_addr; |
} |
} |
|
|
u_long rip_sendspace = RIPSNDQ; |
static int |
u_long rip_recvspace = RIPRCVQ; |
rip_attach(struct socket *so, int proto) |
|
{ |
|
struct inpcb *inp; |
|
int error; |
|
|
|
KASSERT(sotoinpcb(so) == NULL); |
|
sosetlock(so); |
|
|
/*ARGSUSED*/ |
if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) { |
int |
error = soreserve(so, rip_sendspace, rip_recvspace); |
rip_usrreq(struct socket *so, int req, |
if (error) { |
struct mbuf *m, struct mbuf *nam, struct mbuf *control, struct lwp *l) |
return error; |
|
} |
|
} |
|
|
|
error = in_pcballoc(so, &rawcbtable); |
|
if (error) { |
|
return error; |
|
} |
|
inp = sotoinpcb(so); |
|
inp->inp_ip.ip_p = proto; |
|
KASSERT(solocked(so)); |
|
|
|
return 0; |
|
} |
|
|
|
static void |
|
rip_detach(struct socket *so) |
{ |
{ |
struct inpcb *inp; |
struct inpcb *inp; |
int s; |
|
int error = 0; |
KASSERT(solocked(so)); |
|
inp = sotoinpcb(so); |
|
KASSERT(inp != NULL); |
|
|
#ifdef MROUTING |
#ifdef MROUTING |
extern struct socket *ip_mrouter; |
extern struct socket *ip_mrouter; |
|
if (so == ip_mrouter) { |
|
ip_mrouter_done(); |
|
} |
#endif |
#endif |
|
in_pcbdetach(inp); |
|
} |
|
|
if (req == PRU_CONTROL) |
int |
return in_control(so, (long)m, nam, (struct ifnet *)control, l); |
rip_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam, |
|
struct mbuf *control, struct lwp *l) |
|
{ |
|
struct inpcb *inp; |
|
int s, error = 0; |
|
|
s = splsoftnet(); |
KASSERT(req != PRU_ATTACH); |
|
KASSERT(req != PRU_DETACH); |
|
|
|
if (req == PRU_CONTROL) { |
|
return in_control(so, (long)m, nam, (ifnet_t *)control, l); |
|
} |
|
s = splsoftnet(); |
if (req == PRU_PURGEIF) { |
if (req == PRU_PURGEIF) { |
mutex_enter(softnet_lock); |
mutex_enter(softnet_lock); |
in_pcbpurgeif0(&rawcbtable, (struct ifnet *)control); |
in_pcbpurgeif0(&rawcbtable, (struct ifnet *)control); |
Line 534 rip_usrreq(struct socket *so, int req, |
|
Line 580 rip_usrreq(struct socket *so, int req, |
|
in_pcbpurgeif(&rawcbtable, (struct ifnet *)control); |
in_pcbpurgeif(&rawcbtable, (struct ifnet *)control); |
mutex_exit(softnet_lock); |
mutex_exit(softnet_lock); |
splx(s); |
splx(s); |
return (0); |
return 0; |
} |
} |
|
|
|
KASSERT(solocked(so)); |
inp = sotoinpcb(so); |
inp = sotoinpcb(so); |
#ifdef DIAGNOSTIC |
|
if (req != PRU_SEND && req != PRU_SENDOOB && control) |
KASSERT(!control || (req == PRU_SEND || req == PRU_SENDOOB)); |
panic("rip_usrreq: unexpected control mbuf"); |
if (inp == NULL) { |
#endif |
splx(s); |
if (inp == NULL && req != PRU_ATTACH) { |
return EINVAL; |
error = EINVAL; |
|
goto release; |
|
} |
} |
|
|
switch (req) { |
switch (req) { |
|
|
case PRU_ATTACH: |
|
sosetlock(so); |
|
if (inp != 0) { |
|
error = EISCONN; |
|
break; |
|
} |
|
|
|
if (l == NULL) { |
|
error = EACCES; |
|
break; |
|
} |
|
|
|
/* XXX: raw socket permissions are checked in socreate() */ |
|
|
|
if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) { |
|
error = soreserve(so, rip_sendspace, rip_recvspace); |
|
if (error) |
|
break; |
|
} |
|
error = in_pcballoc(so, &rawcbtable); |
|
if (error) |
|
break; |
|
inp = sotoinpcb(so); |
|
inp->inp_ip.ip_p = (long)nam; |
|
break; |
|
|
|
case PRU_DETACH: |
|
#ifdef MROUTING |
|
if (so == ip_mrouter) |
|
ip_mrouter_done(); |
|
#endif |
|
in_pcbdetach(inp); |
|
break; |
|
|
|
case PRU_BIND: |
case PRU_BIND: |
error = rip_bind(inp, nam); |
error = rip_bind(inp, nam); |
break; |
break; |
Line 681 rip_usrreq(struct socket *so, int req, |
|
Line 692 rip_usrreq(struct socket *so, int req, |
|
default: |
default: |
panic("rip_usrreq"); |
panic("rip_usrreq"); |
} |
} |
|
|
release: |
|
splx(s); |
splx(s); |
return (error); |
|
|
return error; |
} |
} |
|
|
PR_WRAP_USRREQ(rip_usrreq) |
PR_WRAP_USRREQ(rip_usrreq) |
Line 692 PR_WRAP_USRREQ(rip_usrreq) |
|
Line 702 PR_WRAP_USRREQ(rip_usrreq) |
|
#define rip_usrreq rip_usrreq_wrapper |
#define rip_usrreq rip_usrreq_wrapper |
|
|
const struct pr_usrreqs rip_usrreqs = { |
const struct pr_usrreqs rip_usrreqs = { |
|
.pr_attach = rip_attach, |
|
.pr_detach = rip_detach, |
.pr_generic = rip_usrreq, |
.pr_generic = rip_usrreq, |
}; |
}; |
|
|