version 1.116.2.1, 2013/07/17 03:16:31 |
version 1.116.2.4, 2014/05/18 17:46:13 |
Line 509 rip_bind(inpcb_t *inp, struct mbuf *nam) |
|
Line 509 rip_bind(inpcb_t *inp, struct mbuf *nam) |
|
struct sockaddr_in *addr = mtod(nam, struct sockaddr_in *); |
struct sockaddr_in *addr = mtod(nam, struct sockaddr_in *); |
|
|
if (nam->m_len != sizeof(*addr)) |
if (nam->m_len != sizeof(*addr)) |
return EINVAL; |
return (EINVAL); |
if (!IFNET_FIRST()) |
if (!IFNET_FIRST()) |
return EADDRNOTAVAIL; |
return (EADDRNOTAVAIL); |
if (addr->sin_family != AF_INET) |
if (addr->sin_family != AF_INET) |
return EAFNOSUPPORT; |
return EAFNOSUPPORT; |
if (!in_nullhost(addr->sin_addr) && !ifa_ifwithaddr(sintosa(addr))) |
if (!in_nullhost(addr->sin_addr) && !ifa_ifwithaddr(sintosa(addr))) |
Line 527 rip_connect(inpcb_t *inp, struct mbuf *n |
|
Line 527 rip_connect(inpcb_t *inp, struct mbuf *n |
|
struct sockaddr_in *addr = mtod(nam, struct sockaddr_in *); |
struct sockaddr_in *addr = mtod(nam, struct sockaddr_in *); |
|
|
if (nam->m_len != sizeof(*addr)) |
if (nam->m_len != sizeof(*addr)) |
return EINVAL; |
return (EINVAL); |
if (!IFNET_FIRST()) |
if (!IFNET_FIRST()) |
return EADDRNOTAVAIL; |
return (EADDRNOTAVAIL); |
if (addr->sin_family != AF_INET) |
if (addr->sin_family != AF_INET) |
return EAFNOSUPPORT; |
return EAFNOSUPPORT; |
|
|
Line 543 rip_disconnect(inpcb_t *inp) |
|
Line 543 rip_disconnect(inpcb_t *inp) |
|
inpcb_set_addrs(inp, NULL, &zeroin_addr); |
inpcb_set_addrs(inp, NULL, &zeroin_addr); |
} |
} |
|
|
int |
static int |
rip_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam, |
rip_attach(struct socket *so, int proto) |
struct mbuf *control, struct lwp *l) |
|
{ |
{ |
inpcb_t *inp; |
inpcb_t *inp; |
struct ip *ip; |
struct ip *ip; |
int error = 0; |
int error; |
|
|
|
KASSERT(sotoinpcb(so) == NULL); |
|
sosetlock(so); |
|
|
|
if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) { |
|
error = soreserve(so, rip_sendspace, rip_recvspace); |
|
if (error) { |
|
return error; |
|
} |
|
} |
|
|
|
solock(so); |
|
error = inpcb_create(so, rawcbtable); |
|
if (error) { |
|
sounlock(so); |
|
return error; |
|
} |
|
inp = sotoinpcb(so); |
|
ip = in_getiphdr(inp); |
|
ip->ip_p = proto; |
|
sounlock(so); |
|
|
|
return 0; |
|
} |
|
|
|
static void |
|
rip_detach(struct socket *so) |
|
{ |
|
inpcb_t *inp; |
|
|
|
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 |
|
inpcb_destroy(inp); |
|
} |
|
|
|
int |
|
rip_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam, |
|
struct mbuf *control, struct lwp *l) |
|
{ |
|
inpcb_t *inp; |
|
int error = 0; |
|
|
|
KASSERT(req != PRU_ATTACH); |
|
KASSERT(req != PRU_DETACH); |
|
|
if (req == PRU_CONTROL) { |
if (req == PRU_CONTROL) { |
return in_control(so, (long)m, nam, (ifnet_t *)control, l); |
return in_control(so, (long)m, nam, (ifnet_t *)control, l); |
Line 568 rip_usrreq(struct socket *so, int req, s |
|
Line 616 rip_usrreq(struct socket *so, int req, s |
|
return 0; |
return 0; |
} |
} |
|
|
KASSERT(req == PRU_ATTACH || solocked(so)); |
KASSERT(solocked(so)); |
inp = sotoinpcb(so); |
inp = sotoinpcb(so); |
|
|
KASSERT(!control || (req == PRU_SEND || req == PRU_SENDOOB)); |
KASSERT(!control || (req == PRU_SEND || req == PRU_SENDOOB)); |
if (inp == NULL && req != PRU_ATTACH) { |
if (inp == NULL) { |
return EINVAL; |
return EINVAL; |
} |
} |
|
|
switch (req) { |
switch (req) { |
case PRU_ATTACH: |
|
sosetlock(so); |
|
if (inp) { |
|
error = EISCONN; |
|
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 = inpcb_create(so, rawcbtable); |
|
if (error) |
|
break; |
|
inp = sotoinpcb(so); |
|
ip = in_getiphdr(inp); |
|
ip->ip_p = (long)nam; |
|
break; |
|
|
|
case PRU_DETACH: |
|
#ifdef MROUTING |
|
if (so == ip_mrouter) |
|
ip_mrouter_done(); |
|
#endif |
|
inpcb_destroy(inp); |
|
break; |
|
|
|
case PRU_BIND: |
case PRU_BIND: |
error = rip_bind(inp, nam); |
error = rip_bind(inp, nam); |
break; |
break; |
Line 699 rip_usrreq(struct socket *so, int req, s |
|
Line 717 rip_usrreq(struct socket *so, int req, s |
|
return error; |
return error; |
} |
} |
|
|
|
PR_WRAP_USRREQ(rip_usrreq) |
|
|
|
#define rip_usrreq rip_usrreq_wrapper |
|
|
|
const struct pr_usrreqs rip_usrreqs = { |
|
.pr_attach = rip_attach, |
|
.pr_detach = rip_detach, |
|
.pr_generic = rip_usrreq, |
|
}; |
|
|
static void |
static void |
sysctl_net_inet_raw_setup(struct sysctllog **clog) |
sysctl_net_inet_raw_setup(struct sysctllog **clog) |
{ |
{ |
sysctl_createv(clog, 0, NULL, NULL, |
sysctl_createv(clog, 0, NULL, NULL, |
CTLFLAG_PERMANENT, |
CTLFLAG_PERMANENT, |
CTLTYPE_NODE, "net", NULL, |
|
NULL, 0, NULL, 0, |
|
CTL_NET, CTL_EOL); |
|
sysctl_createv(clog, 0, NULL, NULL, |
|
CTLFLAG_PERMANENT, |
|
CTLTYPE_NODE, "inet", NULL, |
CTLTYPE_NODE, "inet", NULL, |
NULL, 0, NULL, 0, |
NULL, 0, NULL, 0, |
CTL_NET, PF_INET, CTL_EOL); |
CTL_NET, PF_INET, CTL_EOL); |